vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| >>> Ted Unangst 28-Jun-05 04:12 >>> > > drop in parsemonth from freebsd. > use it to parse month, so "cal june 2005" works as expected. if only > one arg is given, see if it could be a month (without interfering if > it's a year). > > there's plenty more cleanup to do, but this at least makes it a bit > more convenient to use. Ted I've been running with the diff below for nearly a year. Gives an extra parameter -m (to start on Mondays, which is what I prefer - since the "weekend" should be at the end of the week!): June 2005 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 allows 'cal [-m] july' July 2005 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 and 'cal [-m] aug 2005' August 2005 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 I haven't put it forward because of Marc's i18n work, thinking we might want to internationalise it, but if we're going to be able to say "cal july 2005", we might as well be able to say "cal july", and I really want -m Thanks Tom Index: usr.bin/cal/cal.1 ================================================== ================= RCS file: /home/OpenBSD/cvs/src/usr.bin/cal/cal.1,v retrieving revision 1.12 diff -u -r1.12 cal.1 --- usr.bin/cal/cal.1 13 Jul 2003 18:35:00 -0000 1.12 +++ usr.bin/cal/cal.1 28 Jun 2004 16:45:49 -0000 @@ -41,11 +41,14 @@ .Nd displays a calendar .Sh SYNOPSIS .Nm cal -.Op Fl jy +.Op Fl jmy .Oo .Op Ar month .Ar year .Oc +.Nm cal +.Op Fl jmy +.Ar month_name .Sh DESCRIPTION .Nm displays a simple calendar. @@ -56,17 +59,23 @@ .Bl -tag -width Ds .It Fl j Display Julian dates (days one-based, numbered from January 1). +.It Fl m +Start each week on Monday, so that the whole weekend (Saturday and Sunday) +falls at the end of the week. .It Fl y Display a calendar for the current year. .El .Pp -A single parameter specifies the year (1 - 9999) to be displayed; -note the year must be fully specified: +A single parameter specifies either the name of the month to be displayed, +or the year (1 - 9999) for which a complete calendar should be shown. +Note that the year must be fully specified: .Dq Li cal 89 will .Em not display a calendar for 1989. -Two parameters denote the month (1 - 12) and year. +Two parameters denote the month +(1 - 12, or a month name or 3-character abbreviation thereof in English) +and year. If no parameters are specified, the current month's calendar is displayed. .Pp Index: usr.bin/cal/cal.c ================================================== ================= RCS file: /home/OpenBSD/cvs/src/usr.bin/cal/cal.c,v retrieving revision 1.10 diff -u -r1.10 cal.c --- usr.bin/cal/cal.c 10 Jun 2003 22:20:45 -0000 1.10 +++ usr.bin/cal/cal.c 28 Jun 2004 17:19:10 -0000 @@ -72,20 +72,34 @@ {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, }; -int sep1752[MAXDAYS] = { +int sep1752s[MAXDAYS] = { SPACE, SPACE, 1, 2, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, -}, j_sep1752[MAXDAYS] = { +}, sep1752m[MAXDAYS] = { + SPACE, 1, 2, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, SPACE, + SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, + SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, + SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, +}, j_sep1752s[MAXDAYS] = { SPACE, SPACE, 245, 246, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, +}, j_sep1752m[MAXDAYS] = { + SPACE, 245, 246, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, SPACE, + SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, + SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, + SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, }, empty[MAXDAYS] = { SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, @@ -95,11 +109,17 @@ SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, }; +int *sep1752 = sep1752s; +int *j_sep1752 = j_sep1752s; + char *month_names[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", }; +int thursday = THURSDAY; +int saturday = SATURDAY; + char *day_headings = "Su Mo Tu We Th Fr Sa"; char *j_day_headings = " Su Mo Tu We Th Fr Sa"; @@ -122,6 +142,7 @@ int julian; +int ismonth(char *); void ascii_day(char *, int); void center(char *, int, int); void day_array(int, int, int *); @@ -138,14 +159,22 @@ { struct tm *local_time; time_t now; - int ch, month, year, yflag; + int ch, m, month, year, yflag; yflag = year = 0; - while ((ch = getopt(argc, argv, "jy")) != -1) + while ((ch = getopt(argc, argv, "jmy")) != -1) switch(ch) { case 'j': julian = 1; break; + case 'm': + day_headings = "Mo Tu We Th Fr Sa Su"; + j_day_headings = " Mo Tu We Th Fr Sa Su"; + sep1752 = sep1752m; + j_sep1752 = j_sep1752m; + thursday = THURSDAY - 1; + saturday = SATURDAY - 1; + break; case 'y': yflag = 1; break; @@ -156,19 +185,31 @@ argc -= optind; argv += optind; + (void)time(&now); + local_time = localtime(&now); + month = 0; + switch(argc) { case 2: - if ((month = atoi(*argv++)) < 1 || month > 12) - errx(1, "illegal month value: use 1-12"); + if ((m = ismonth(*argv)) != 0) { + month = m; + } else { + if ((month = atoi(*argv)) < 1 || month > 12) + errx(1, "illegal month value: use 1-12"); + } + argv++; /* FALLTHROUGH */ case 1: - if ((year = atoi(*argv)) < 1 || year > 9999) - errx(1, "illegal year value: use 1-9999"); + if ((m = ismonth(*argv)) != 0) { + month = m; + year = local_time->tm_year + TM_YEAR_BASE; + } else { + if ((year = atoi(*argv)) < 1 || year > 9999) + errx(1, "illegal year value: use 1-9999"); + } break; case 0: - (void)time(&now); - local_time = localtime(&now); year = local_time->tm_year + TM_YEAR_BASE; if (!yflag) month = local_time->tm_mon + 1; @@ -186,6 +227,28 @@ exit(0); } +int +ismonth(char *s) +{ + char *p, *q; + int short_form; + int m; + + short_form = (strlen(s) == 3) ? 1 : 0; + + for (m = 0; m < sizeof(month_names) / sizeof(month_names[0]); m++) { + if (short_form) { + if (strncasecmp(s, month_names[m], 3) == 0) + return m + 1; + } else { + if (strcasecmp(s, month_names[m]) == 0) + return m + 1; + } + } + + return 0; +} + #define DAY_LEN 3 /* 3 spaces per day */ #define J_DAY_LEN 4 /* 4 spaces per day */ #define WEEK_LEN 20 /* 7 * 3 - one space at the end */ @@ -326,7 +389,7 @@ /* * day_in_week - * return the 0 based day number for any date from 1 Jan. 1 to + * return the 0-based day number for any date from 1 Jan. 1 to * 31 Dec. 9999. Assumes the Gregorian reformation eliminates * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all * missing days. @@ -339,10 +402,10 @@ temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) + day_in_year(day, month, year); if (temp < FIRST_MISSING_DAY) - return ((temp - 1 + SATURDAY) % 7); + return ((temp - 1 + saturday) % 7); if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) - return (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); - return (THURSDAY); + return (((temp - 1 + saturday) - NUMBER_MISSING_DAYS) % 7); + return (thursday); } void @@ -413,6 +476,6 @@ usage(void) { - (void)fprintf(stderr, "usage: cal [-jy] [[month] year]\n"); + (void)fprintf(stderr, "usage: cal [-jmy] [[month] year]\n"); exit(1); } |