From 0f523ec9c6c36a768a36eba39db223617772179c Mon Sep 17 00:00:00 2001 From: Jesse Ogle Date: Wed, 19 Jun 2013 14:13:50 -0400 Subject: [PATCH] Added cal and updated Makefile Signed-off-by: Christoph Lohmann <20h@r-36.net> --- Makefile | 1 + cal.1 | 42 ++++++++++++++++ cal.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 cal.1 create mode 100644 cal.c diff --git a/Makefile b/Makefile index 65473a3..9aeb5c4 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ LIB = \ SRC = \ basename.c \ + cal.c \ cat.c \ chgrp.c \ chmod.c \ diff --git a/cal.1 b/cal.1 new file mode 100644 index 0000000..2ac26ce --- /dev/null +++ b/cal.1 @@ -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) diff --git a/cal.c b/cal.c new file mode 100644 index 0000000..84da106 --- /dev/null +++ b/cal.c @@ -0,0 +1,147 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#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); +} +