[hackers] [sbase] Make date(1) compatible to GNU date(1). || Christoph Lohmann

From: <git_AT_suckless.org>
Date: Wed, 19 Jun 2013 22:12:09 +0200

commit b10b1da57d4d573647d1a528efaecfc54dea8073
Author: Christoph Lohmann <20h_AT_r-36.net>
Date: Wed Jun 19 22:10:26 2013 +0200

    Make date(1) compatible to GNU date(1).
    
    We have variable first day of weeks now! My week starts on Wednesday!

diff --git a/cal.1 b/cal.1
index 2ac26ce..a679350 100644
--- a/cal.1
+++ b/cal.1
_AT_@ -3,13 +3,20 @@
 cal \- print calendar
 .SH SYNOPSIS
 .B cal
+.RB [ \-1 ]
+.RB [ \-3 ]
+.RB [ \-m ]
+.RB [ \-s ]
+.RB [ \-y ]
 .RB [ \-c
 .IR columns ]
-.RB [ \-m
-.IR month ]
+.RB [ \-f
+.IR firstday ]
 .RB [ \-n
-.IR number ]
-.RB [ \-y
+.IR nmonths ]
+.RB [ [ [
+.IR day ]
+.IR month ]
 .IR year ]
 .SH DESCRIPTION
 Beginning with
_AT_@ -20,23 +27,34 @@ print
 .IR number
 of calendars side by side. Each row of calendars contains at most
 .IR columns
-number of calendars.
+number of calendars. The defaults are obtained using
+.IR localtime (3).
 .SH OPTIONS
 .TP
+.B \-1
+Print one single month.
+.TP
+.B \-3
+Print prev/current/nexth month.
+.TP
+.B \-m
+Print Monday as first day of week.
+.TP
+.B \-s
+Print Sunday as first day of week.
+.TP
+.B \-y
+Print a calendar of the current year.
+.TP
 .BI \-c " columns"
-print
+Print
 .IR columns
-number of calendars in a row. default is 3
+number of calendars in a row. The default is 3.
 .TP
-.BI \-m " month"
-starting month. default is obtained from
-.IR localtime (3)
+.BI \-f " firstday"
+Specify the first day of the week. 0 is Sunday and 6 is Saturday.
 .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)
+.BI \-n " nmonths"
+Specify the number months to print. The default is 1.
 .SH SEE ALSO
 .IR localtime (3)
diff --git a/cal.c b/cal.c
index 84da106..b32caf3 100644
--- a/cal.c
+++ b/cal.c
_AT_@ -7,29 +7,30 @@
 
 #define MONTHMAX 100
 
-static void drawcal(int, int, int, int, int);
-static int dayofweek(int, int, int);
+static void drawcal(int, int, int, int, int, int);
+static int dayofweek(int, int, int, int);
 static bool isleap(int);
 static void usage(void);
 
 static void
-drawcal(int year, int month, int day, int ncols, int nmons)
+drawcal(int year, int month, int day, int ncols, int nmons, int fday)
 {
         char str[21];
         int count[MONTHMAX];
- int d, i, r;
+ int d, i, r, j;
         int moff, yoff, cur, last, ndays, day1;
- char *smon[]= {
+ 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;
+ char *days[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", };
 
- while (nmons > 0) {
+ while(nmons > 0) {
                 last = MIN(nmons, ncols);
- for (i = 0; i < last; i++) {
+ for(i = 0; i < last; i++) {
                         moff = month + ncols * row + i - 1;
                         cur = moff % 12;
                         yoff = year + moff / 12;
_AT_@ -40,24 +41,30 @@ drawcal(int year, int month, int day, int ncols, int nmons)
                 }
                 printf("
");
 
- for (i = 0; i < last; i++)
- printf("Su M Tu W Th F Sa ");
+ for(i = 0; i < last; i++) {
+ for(j = fday; j < LEN(days); j++)
+ printf("%s ", days[j]);
+ for(j = 0; j < fday; j++)
+ printf("%s ", days[j]);
+ printf(" ");
+ }
                 printf("
");
 
- for (r = 0; r < 6; r++) {
- for (i = 0; i < last; i++) {
+ 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);
+ day1 = dayofweek(year, cur, 1, fday);
 
- for (d = 0; d < 7; d++)
- if ((r || d >= day1) && count[i] <= ndays)
+ for(d = 0; d < 7; d++) {
+ if((r || d >= day1) && count[i] <= ndays)
                                                 printf("%2d ", count[i]++);
                                         else
                                                 printf(" ");
+ }
                                 printf(" ");
                         }
                         printf("
");
_AT_@ -67,32 +74,19 @@ drawcal(int year, int month, int day, int ncols, int nmons)
         }
 }
 
-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)
+dayofweek(int year, int month, int day, int fday)
 {
- int a, y, m;
+ int a, y, m, d;
 
         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;
+ m = month + 12 * a - 3;
+ d = (day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y \
+ / 400 - 32045 + 1) % 7;
+ return (fday > d)? (7 - d) : (d - fday);
 }
 
 static bool
_AT_@ -100,9 +94,12 @@ isleap(int year)
 {
         bool leap = false;
 
- if (year % 4 == 0) leap = true;
- if (year % 100 == 0) leap = false;
- if (year % 400 == 0) leap = true;
+ if(year % 4 == 0)
+ leap = true;
+ if(year % 100 == 0)
+ leap = false;
+ if(year % 400 == 0)
+ leap = true;
         return leap;
 }
 
_AT_@ -110,38 +107,85 @@ isleap(int year)
 static void
 usage(void)
 {
- eprintf("usage: %s [-c columns] [-m month] [-n number] [-y year]
", argv0);
- exit(1);
+ eprintf("usage: %s [-c columns] [-m month] [-n number] [-y year]
",
+ argv0);
 }
 
 int
 main(int argc, char *argv[])
 {
- int year, month, day, ncols, nmons;
+ int year, month, day, ncols, nmons, fday;
+ struct tm *ltime;
+ time_t now;
+
+ now = time(NULL);
+ ltime = localtime(&now);
+ year = ltime->tm_year + 1900;
+ month = ltime->tm_mon + 1;
+ day = ltime->tm_mday;
+ fday = 0;
 
- defaults(&year, &month, &day, &ncols, &nmons);
+ ncols = 3;
+ nmons = 1;
 
         ARGBEGIN {
+ case '1':
+ nmons = 1;
+ break;
+ case '3':
+ nmons = 3;
+ month -= 1;
+ if(month == 0) {
+ month = 12;
+ year--;
+ }
+ break;
         case 'c':
- ncols = (int) estrtol(EARGF(usage()), 0);
+ ncols = estrtol(EARGF(usage()), 0);
                 break;
- case 'm':
- month = (int) estrtol(EARGF(usage()), 0);
+ case 'f':
+ fday = estrtol(EARGF(usage()), 0);
+ break;
+ case 'm': /* Monday */
+ fday = 1;
                 break;
         case 'n':
- nmons = (int) estrtol(EARGF(usage()), 0);
+ nmons = estrtol(EARGF(usage()), 0);
+ break;
+ case 's': /* Sunday */
+ fday = 0;
                 break;
         case 'y':
- year = (int) estrtol(EARGF(usage()), 0);
+ month = 1;
+ nmons = 12;
                 break;
         default:
                 usage();
         } ARGEND;
 
- if (ncols < 0 || ncols > MONTHMAX || month < 1 || month > 12 || nmons < 1 || year > 9999)
+ switch(argc) {
+ case 3:
+ day = estrtol(argv[0], 0);
+ argv++;
+ case 2:
+ month = estrtol(argv[0], 0);
+ argv++;
+ case 1:
+ year = estrtol(argv[0], 0);
+ break;
+ case 0:
+ break;
+ default:
+ usage();
+ }
+
+ if(ncols < 0 || ncols > MONTHMAX || month < 1 || month > 12 \
+ || nmons < 1 || fday < 0 || fday > 6) {
                 usage();
+ }
+
+ drawcal(year, month, day, ncols, nmons, fday);
 
- drawcal(year, month, day, ncols, nmons);
         exit(0);
 }
 
Received on Wed Jun 19 2013 - 22:12:09 CEST

This archive was generated by hypermail 2.3.0 : Wed Jun 19 2013 - 22:24:18 CEST