Added cal and updated Makefile

Signed-off-by: Christoph Lohmann <20h@r-36.net>
This commit is contained in:
Jesse Ogle 2013-06-19 14:13:50 -04:00 committed by Christoph Lohmann
parent 7f88cf7021
commit 0f523ec9c6
3 changed files with 190 additions and 0 deletions

View File

@ -21,6 +21,7 @@ LIB = \
SRC = \
basename.c \
cal.c \
cat.c \
chgrp.c \
chmod.c \

42
cal.1 Normal file
View File

@ -0,0 +1,42 @@
.TH CAL 1 sbase\-VERSION
.SH NAME
cal \- print calendar
.SH SYNOPSIS
.B cal
.RB [ \-c
.IR columns ]
.RB [ \-m
.IR month ]
.RB [ \-n
.IR number ]
.RB [ \-y
.IR year ]
.SH DESCRIPTION
Beginning with
.IR month
and
.IR year
print
.IR number
of calendars side by side. Each row of calendars contains at most
.IR columns
number of calendars.
.SH OPTIONS
.TP
.BI \-c " columns"
print
.IR columns
number of calendars in a row. default is 3
.TP
.BI \-m " month"
starting month. default is obtained from
.IR localtime (3)
.TP
.BI \-n " number"
number of calendars to print. default is 1
.TP
.BI \-y " year"
starting year. default is obtained from
.IR localtime (3)
.SH SEE ALSO
.IR localtime (3)

147
cal.c Normal file
View File

@ -0,0 +1,147 @@
/* See LICENSE file for copyright and license details. */
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "util.h"
#define MONTHMAX 100
static void drawcal(int, int, int, int, int);
static int dayofweek(int, int, int);
static bool isleap(int);
static void usage(void);
static void
drawcal(int year, int month, int day, int ncols, int nmons)
{
char str[21];
int count[MONTHMAX];
int d, i, r;
int moff, yoff, cur, last, ndays, day1;
char *smon[]= {
" January", " February", " March",
" April", " May", " June",
" July", " August", " September",
" October", " November", " December" };
int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int row = 0;
while (nmons > 0) {
last = MIN(nmons, ncols);
for (i = 0; i < last; i++) {
moff = month + ncols * row + i - 1;
cur = moff % 12;
yoff = year + moff / 12;
sprintf(str, "%s %d", smon[cur], yoff);
printf("%-20s ", str);
count[i] = 1;
}
printf("\n");
for (i = 0; i < last; i++)
printf("Su M Tu W Th F Sa ");
printf("\n");
for (r = 0; r < 6; r++) {
for (i = 0; i < last; i++) {
moff = month + ncols * row + i - 1;
cur = moff % 12;
yoff = year + moff / 12;
ndays = mdays[cur] + ((cur == 1) & isleap(yoff));
day1 = dayofweek(year, cur, 1);
for (d = 0; d < 7; d++)
if ((r || d >= day1) && count[i] <= ndays)
printf("%2d ", count[i]++);
else
printf(" ");
printf(" ");
}
printf("\n");
}
nmons -= ncols;
row++;
}
}
static void
defaults(int *year, int *month, int *day, int *ncols, int *nmons)
{
time_t now;
struct tm *ltime;
now = time(NULL);
ltime = localtime(&now);
*year = ltime->tm_year + 1900;
*month = ltime->tm_mon + 1;
*day = ltime->tm_mday;
*ncols = 3;
*nmons = 1;
}
static int
dayofweek(int year, int month, int day)
{
int a, y, m;
month++;
a = (14 - month) / 12;
y = year + 4800 - a;
m = month + 12 * a -3;
return (day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045 + 1) % 7;
}
static bool
isleap(int year)
{
bool leap = false;
if (year % 4 == 0) leap = true;
if (year % 100 == 0) leap = false;
if (year % 400 == 0) leap = true;
return leap;
}
static void
usage(void)
{
eprintf("usage: %s [-c columns] [-m month] [-n number] [-y year]\n", argv0);
exit(1);
}
int
main(int argc, char *argv[])
{
int year, month, day, ncols, nmons;
defaults(&year, &month, &day, &ncols, &nmons);
ARGBEGIN {
case 'c':
ncols = (int) estrtol(EARGF(usage()), 0);
break;
case 'm':
month = (int) estrtol(EARGF(usage()), 0);
break;
case 'n':
nmons = (int) estrtol(EARGF(usage()), 0);
break;
case 'y':
year = (int) estrtol(EARGF(usage()), 0);
break;
default:
usage();
} ARGEND;
if (ncols < 0 || ncols > MONTHMAX || month < 1 || month > 12 || nmons < 1 || year > 9999)
usage();
drawcal(year, month, day, ncols, nmons);
exit(0);
}