page%rishathra@Sun.COM (Bob Page) (05/03/89)
Submitted-by: brant@uf.msc.umn.edu (Gary Brant) Posting-number: Volume 89, Issue 111 Archive-name: unix/cal.1 This is my clone of the *nix cal program. It has been in gestation for about six months waiting for my inspiration at handling the Sep. 1752 discontinuity. Well, it's a hack but it gives the same results as the *nix version. [uuencoded executable included. ..bob] # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # README # cal.doc # cal.c # makefile # cal.uu # This is archive 1 of a 1-part kit. # This archive created: Tue May 2 23:43:50 1989 echo "extracting README" sed 's/^X//' << \SHAR_EOF > README XThis is a calendar program based on one seen on a local *nix machine. XI made the interface a little more friendly by adding 1900 to years Xless than 100 and allowing for spelling month names (3 char. significance) X XThis program is freely distributable, as long as you leave my name in Xthe source & don't sell it for a profit. X X X Gary Brant X X US mail: 1355 Eustis St. #1 X St. Paul, MN 55108 X X ARPA: brant@uf.msc.umn.edu X SHAR_EOF echo "extracting cal.doc" sed 's/^X//' << \SHAR_EOF > cal.doc X XCAL USER COMMANDS CAL X X X XNAME X cal - display calendar X XSYNOPSIS X cal [ month ] [ year ] X XDESCRIPTION X Cal displays a calendar for the specified year. If a month X is also specified, a calendar for that month only is X displayed. If neither is specified, a calendar for the X present month is printed. X X Year can be between 100 and 9999. If you specify a year less X than 100, the year is incremented by 1900. Also, the year is X always considered to start in January, even though this X is historically naive. X X month is a number between 1 and 12, or one of {Jan, Feb, ...} X case is insignificant. X X The calendar produced is that for England and her colonies. X X Try September 1752. SHAR_EOF echo "extracting cal.c" sed 's/^X//' << \SHAR_EOF > cal.c X/* cal.c - print calendar for one month or one year X * X * cal [month] [year] X * X * cal (C) 1988 by Gary L. Brant X */ X X#include <stdio.h> X#include <fcntl.h> X X#define DPY 365L /* days per year */ X#define FUDGE1 1 /* needed to make day of week come out right */ X#define FUDGE2 6 /* for old style (Julian) calendar */ X Xint days[12] = { X 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 X}; Xint mdays[13] = { X 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 X}; Xchar *months[12] = { X "January", "February", "March", "April", "May", "June", X "July" , "August" , "September", "October", "November", "December" X}; Xchar dayline[] = " S M Tu W Th F S\n"; Xchar line[8][68]; /* line buffer */ Xint multi = 0; Xextern struct _dev *_devtab; Xstruct FileHandle *err, *out, *Output (); X X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int m, d, y, i, k; X X out = Output (); X getdate (&m, &d, &y); X if (argc == 1) { X fixtab (&y); X printmonth (m, y); X exit (0); X } X X if ((k = convert (argv[1])) == 0) { X m = 0; X for (i = 0; i < 12; i++) X if (cmpmonth (argv[1], months[i]) == 0) { X m = i + 1; X break; X } X if (m == 0) { X badarg (argv[1]); X } X } X X if (argc == 2) { X if (k == 0) { X fixtab (&y); X printmonth (m, y); X } else { X multi = 1; X fixtab (&k); X for (m = 1; m < 13; m++) X printmonth (m, k); X } X exit (0); X } X X if (k > 0 && k < 13) X m = k; X else if (m == 0 || k != 0) { X badarg (argv[1]); X } X X if (argc == 3) { X if ((y = convert (argv[2])) == 0) { X badarg (argv[2]); X } X } X fixtab (&y); X printmonth (m, y); X} X X X/* printmonth () - either prints an entire month at a time or multiplexes X * a month into a buffer, dumping the buffer after the third call. X */ Xprintmonth (m, y) Xregister int m; Xint y; X{ X int dow; /* day of week for first day of month */ X register int first, last; X register int index, l, p; X static int q = 0, maxl = 0; X int i, mday[32]; /* table of day numbers for month */ X X if (multi) { X q++; X if (q > 3) { X maxl = 0; X q = 1; X } X } else X q = 1; X p = 22 * (q - 1); /* character position of line in buffer */ X first = 4; X last = strlen (months[--m]) + first; X blank (&line[0][p], first); X X strcpy (&line[0][p+first], months[m]); /* copy month name into buf */ X itoa (y, &line[0][p+last], 5); /* encode year */ X if (multi && q != 3) X blank (&line[0][p+last+5], 22 - last - 5); X else { X line[0][p+last+5] = '\n'; X line[0][p+last+6] = '\0'; X puts (line[0]); X puts (line[1]); X } X X dow = weekday (m, y); X index = 3 * dow; X blank (&line[2][p], index); X last = 7 - dow; X first = 1; X l = 2; X X for (i = 1; i <= days[m]; i++) /* fill day numbers table */ X mday[i] = i; X if ((y == 1752) && (m == 8)) /* special case Sep. 1752 */ X for (i = 3; i <= days[m]; i++) X mday[i] += 11; X while (first <= days[m]) { /* loop thru month one week per line */ X while (first <= last) { /* for each day in week encode day of month */ X itoa (mday[first++], &line[l][p+index], 3); X index += 3; X } X if (multi && q != 3) { X blank (&line[l][p+index], 22 - index); X if (l > maxl) X maxl = l; X } else { X line[l][p+index++] = '\n'; X line[l][p+index] = '\0'; X puts (line[l]); X } X last = (last + 7) > days[m] ? days[m] : last + 7; X l++; X index = 0; X } X X if (multi) X if (q != 3) /* blank fill remaining lines this month */ X while (l < 8) X blank (&line[l++][p], 22); X else /* determine if any lines remain to be written */ X while (l <= maxl) { X line[l][p] = '\n'; X line[l][p+1] = '\0'; X puts (line[l++]); X } X} X X Xblank (line, num) Xregister char line[]; Xregister int num; X{ X while (num >= 0) X line[num--] = ' '; X} X X X/* itoa - integer to ascii conversion, with leading blanks. X */ Xitoa (num, str, ndig) Xregister int num, ndig; Xregister char str[3]; X{ X register int i, rmd; X X while (ndig-- > 0) { X i = num / 10; X rmd = num - 10 * i; X str[ndig] = (num > 0) ? '0' + rmd : ' '; X num = i; X } X} X X X/* getdate - return month, day, year. Valid through: 02/28/2100. X */ X Xgetdate (m, d, y) Xint *m, *d, *y; X{ X int i, j, k, z; X long l, clock[3], ndays; X X DateStamp (clock); /* get system datestamp */ X ndays = clock[0]; /* days since 01/01/1978 */ X k = (++ndays + DPY) / DPY; X do { X j = k >> 2; X i = ndays - DPY * --k; X } while (j >= i); X ndays = ndays - DPY * k - ((k+1) >> 2); X *y = k + 1978; X z = ((*y % 4) == 0 && (ndays+3)>>5 > 0) ? 1 : 0; X *m = (mdays[i=(ndays>>5)+1]+z >= ndays) ? i : i + 1; X *d = ndays - mdays[*m-1] - z; X} X X X/* fixtab - correct for leapyears; also replicate day-of-week line. X */ Xfixtab (y) Xregister int *y; X{ X register int i; X X if (*y < 100) /* a civility - not really interested in years */ X *y += 1900; /* 1st century AD */ X if ((*y % 4) == 0) { X if (((*y % 100) != 0) || ((*y % 400) == 0) || (*y < 1753)) { X days[1] = 29; X for (i = 2; i < 13; i++) X mdays[i]++; X if (*y == 1752) X days[8] -= 11; X } X } X if (multi) { X for (i = 0; i < 66; i += 22) X strcpy (&line[1][i], dayline); X line[1][21] = ' '; X line[1][43] = ' '; X } else X strcpy (&line[1][0], dayline); X} X X X/* convert () - convert string from ascii to binary integer X */ Xconvert (string) Xchar string[]; X{ X register int c, i, result; X X i = result = 0; X while (string[i] != '\0') { X if ((c = string[i++] - '0') < 0 || c > 9) X return (0); X else { X result *= 10; X result += c; X } X } X return (result); X} X X X/* puts () - write string to standard output X */ Xputs (string) Xchar string[]; X{ X Write (out, string, (long) strlen (string)); X} X X X/* weekday - return day-of-week for first day of month. X */ Xweekday (m, y) Xregister int m, y; X{ X if (y > 1752 || (y == 1752 && m > 8)) X return (mdays[m] + y + --y / 4 - y / 100 + y / 400 + FUDGE1) % 7; X else X return (mdays[m] + y + --y / 4 + FUDGE2) % 7; X} X X X Xbadarg (string) Xchar string[]; X{ X err = _devtab[2].fd; X Write (err, string, (long) strlen(string)); X Write (err, " bad argument\n", 14L); X exit (10); X} X X X/* cmpmonth () - compare month argument entered by user with month name. X * The comparison will be made case insensitive. X */ Xcmpmonth (str1, str2) Xregister char str1[], str2[]; X{ X register int j; X X if ((j = (toupper(str1[0])-str2[0])) != 0) X return (j); X else if ((j = tolower(str1[1])-str2[1]) != 0) X return (j); X else X return (tolower(str1[2])-str2[2]); X} X X X/* _wb_parse () - just to keep down the size of the executable X */ X_wb_parse () X{ X} SHAR_EOF echo "extracting makefile" sed 's/^X//' << \SHAR_EOF > makefile XCFLAGS=-n X Xcal: cal.o X ln -g cal.o -lc X Xcal.o: cal.c X SHAR_EOF echo "extracting cal.uu" sed 's/^X//' << \SHAR_EOF > cal.uu X Xbegin 777 cal XM```#\P`````````#``````````(```04````OP````$```/I```$%$[Z"7A*J XM86YU87)Y`$9E8G)U87)Y`$UA<F-H`$%P<FEL`$UA>0!*=6YE`$IU;'D`075GM XM=7-T`%-E<'1E;6)E<@!/8W1O8F5R`$YO=F5M8F5R`$1E8V5M8F5R`$Y5__9., XMN@](*4""LDAM__I(;?_\2&W__DZZ!1I/[P`,#&T``0`(9B!(;?_Z3KH&&%A/R XM/RW_^C\M__Y.N@%*6$]"9TZZ#4I43R!M``HO*``$3KH&L%A/.T#_]F960FW_D XM_D)M__@P+?_X2,#E@$'L@#0O,`@`(&T`"B\H``1.N@?B4$]*0&8,,"W_^%)`1 XM.T#__F`,4FW_^`QM``S_^&W&2FW__F8.(&T`"B\H``1.N@=46$\,;0`"``AF6 XM6$IM__9F&DAM__I.N@6`6$\_+?_Z/RW__DZZ`+)83V`P.7P``8!\2&W_]DZZ) XM!6!83SM\``'__C\M__8_+?_^3KH`C%A/4FW__@QM``W__FWF0F=.N@R`5$]*" XM;?_V;Q`,;0`-__9L"#MM__;__F`:2FW__F<&2FW_]F<.(&T`"B\H``1.N@;$J XM6$\,;0`#``AF(B!M``HO*``(3KH%KEA/.T#_^F8.(&T`"B\H``A.N@::6$](` XM;?_Z3KH$U%A//RW_^C\M__YA!EA/3EU.=4Y5_[Q(YP\P."T`"$IL@'QG&%)L? XM@'X,;``#@'YO"D)L@(`Y?``!@'Y@!CE\``&`?C`L@'Y30,'\`!8V0'H$4T0PG XM!$C`Y8!![(`T+S`(`$ZZ!PA83SP`W$4_!3`+2,!![(".T(@O`$ZZ`M)<3S`$8 XM2,#E@$'L@#0O,`@`,`O014C`0>R`CM"(+P!.N@:^4$\_/``%,`O01DC`0>R`` XMCM"(+P`_+0`*3KH"O%!/2FR`?&<H#&P``X!^9R!P%I!&6T`_`#`+T$9:0$C`: XM0>R`CM"(+P!.N@)H7$]@,C`+T$9:0$'L@(X1O``*```P"]!&7$!![(".0C``( XM`$AL@(Y.N@3*6$](;(#23KH$P%A//RT`"C\$3KH$VEA/.T#__CXM__[/_``#L XM/P<P"TC`0>R!%M"(+P!.N@((7$]\!YQM__YZ`31\``([?``!__Q@%C`M__Q(0 XMP..`0>W_O#&M__P(`%)M__PP!$C`XX!![(`",BW__+)P"`!OU@QM!M@`"F8X] XMN'P`"&8R.WP``__\8!8P+?_\2,#C@$'M_[S1P`90``M2;?_\,`1(P..`0>R`C XM`C(M__RR<`@`;]8P!$C`XX!![(`"NG`(`&X``.ZZ1FXT/SP``S`*P?P`1#(+_ XMTD=(P="!0>R`CM"(+P`P!5)%2,#C@$'M_[P_,`@`3KH!;%!/5D=@R$IL@'QG^ XM-@QL``.`?F<N<!:01S\`,`K!_`!$,@O21TC!T(%![(".T(@O`$ZZ`1!<3[3LQ XM@(!O!#E*@(!@1#`*P?P`1#('4D?22TC!T(%![(".$;P`"@@`,`K!_`!$,@O2" XM1TC!T(%![(".0C`(`#`*P?P`1$'L@([0B"\`3KH#3%A/,`9>0#($2,'C@4'LU XM@`*P<!@`;Q(P!$C`XX!![(`"(@`P,!@`8`0P!EY`/`!22GX`8`#_!$IL@'QGM XM>@QL``.`?F<HM/P`"&P@/SP`%C`*4DK!_`!$,@M(P="!0>R`CM"(+P!A6%Q/K XM8-I@2K3L@(!N1#`*P?P`1#(+2,'0@4'L@(X1O``*"``P"L'\`$0R"U)!2,'0& XM@4'L@(Y",`@`,`I22L'\`$1![(".T(@O`$ZZ`II83V"V3-\,\$Y=3G5.50``H XM2.<(("1M``@X+0`,2D1M##`$4T05O``@``!@\$S?!!!.74YU3E4``$CG#R`X: XM+0`()&T`"CHM``XP!5-%2D!O*#P$2,:-_``*,`;!_``*/@2>0$I$;P@P!]!\Y XM`#!@`G`@%8!0`#@&8-!,WP3P3EU.=4Y5_^1(;?_H3KH)[EA/*VW_Z/_D4JW_J XMY"`M_^30O````6TB/````6U.N@>(.T#_^C`M__KD0#M`__Q3;?_Z,"W_^L'\A XM`6TB+?_DDH`[0?_^,"W__+!M__YLUC`M__K!_`%M(BW_Y)*`,"W_^E)`Y$!(X XMP)*`*T'_Y"!M`!`P+?_ZT'P'NC"`(&T`$#`02,"!_``$2$!*0&80("W_Y%:`% XMZH!*@&\$<`%@`G``.T#_^"`M_^3J@%*`.T#__DC`XX!![(`:,C`(`-)M__A(: XMP;*M_^1M!C`M__Y@!C`M__Y20"!M``@P@"!M``@P$%-`2,#C@$'L@!HR,`@`K XM2,$@+?_DD($R+?_X2,&0@2!M``PP@$Y=3G5.50``2.<(("1M``@,4@!D;`0&\ XM4@=L,!)(P('\``1(0$I`9DPP$DC`@?P`9$A`2D!F%#`22,"!_`&02$!*0&<&B XM#%(&V6PJ.7P`'8`$>`(P!$C`XX!![(`:4G`(`%)$N'P`#6WJ#%(&V&8&!&P`9 XM"X`22FR`?&<P>`!(;(!D,`1(P$'L@-+0B"\`3KH!_E!/V'P`%KA\`$)MX!E\@ XM`""`YQE\`""`_6`.2&R`9$AL@-).N@'84$],WP003EU.=4Y5``!(YPX`?``Z( XM!B!M``A*,%``9S`P!5)%(&T`"!(P``!(@3@!F'P`,$I$;0:X?``);PIP`$S?W XM`'!.74YUS?P`"MQ$8,8P!F#L3E4``"\M``A.N@&(6$](P"\`+RT`""\L@K).P XMN@@"3^\`#$Y=3G5.50``2.<,`#@M``@Z+0`*NGP&V&X,NGP&V&9*N'P`"&]$Y XM,`1(P..`0>R`&B(`,#`8`%-%,@5(P8/\``300=!%,@5(P8/\`&2003(%2,&#X XM_`&0T$%20$C`@?P`!TA`3-\`,$Y=3G4P!$C`XX!![(`:(@`P,!@`4T4R!4C!E XM@_P`!-!!T$5<0$C`@?P`!TA`8,Y.50``(&R"MBEH``R"KB\M``A.N@#(6$](> XMP"\`+RT`""\L@JY.N@="3^\`#$AX``Y(>@`<+RR"KDZZ!RY/[P`,/SP`"DZZ$ XM!4943TY=3G4@8F%D(&%R9W5M96YT"@``3E4``$CG"#`D;0`()FT`#!`22(`_; XM`$ZZ`'A43Q(32($X`)A!9PHP!$S?#!!.74YU$"H``4B`/P!.N@!N5$\2*P`!5 XM2($X`)A!9P0P!&#:$"H``DB`/P!.N@!05$\2*P`"2(&006#"3E4``$Y=3G4@= XM;P`$(`@B;P`($-EF_$YU(&\`!"`(2AAF_)'`(`A3@$YU<``0+P`%L#P`8&,*] XML#P`>F($D#P`($YU<``0+P`%L#P`0&,*L#P`6F($T#P`($YU87!#[(".1>R`B XMCK7)9@XR/`";:PAT`"+"4<G__"E/@KHL>``$*4Z"ODCG@(`(+@`$`2EG$$OZ+ XM``A.KO_B8`9"I_-?3G-#^@`@3J[^:"E`@L)F#"X\``.`!TZN_Y1@!$ZZ`!I0^ XM3TYU9&]S+FQI8G)A<GD`2?D``'_^3G5.50``+PI(>0`!```P+(""P?P`!B\`K XM3KH%[BE`@K903V840J=(>0`!``!.N@6V4$\N;(*Z3G4@;(*V0F@`!"!L@K8Q" XM?``!`!`@;(*V,7P``0`*(&R"NB`L@KJ0J``$4(`I0(+&(&R"QB"\34%.6$*GC XM3KH%HB1`2JH`K%A/9RXO+0`,+RT`""\*3KH`KCE\``&"RB!L@K8`:(````0@\ XM;(*V`&B````*3^\`#&!"2&H`7$ZZ!9Y(:@!<3KH%?BE`@LP@;(+,2J@`)%!/: XM9Q`@;(+,(F@`)"\13KH$KEA/+RR"S"\*3KK^2"EL@LR"T%!/3KH$KB!L@K8@" XM@$ZZ!+X@;(*V(4``!F<62'@#[4AZ`"I.N@26(&R"MB%```Q03R\L@M`_+(+4N XM3KKU0$)G3KH"R%!/)%].74YU*@!.50``2.<,,"1M`!`@;0`(2J@`K&<8(&T`@ XM""`H`*SE@"@`($0@*``0Y8`F0&`$)FR`A!`32(!(P-"M``Q4@#E`@M9"IS`LP XM@M9(P"\`3KH$@"E`@MA03V8(3-\,,$Y=3G40$TB`.@`_!2!+4H@O""\L@MA.H XMN@%^,`5(P"!`T>R"V$/Z`400V6;\/RT`#B\*+RR"V$ZZ`3H@;(+80C!0`#E\" XM``&"U#`%2,#0K(+8)D!2BR1+3^\`%!`32(`Z`+!\`"!G&+I\``EG$KI\``QG_ XM#+I\``UG!KI\``IF!%*+8-@,$P`@;7H,$P`B9BY2BR!+4HL0$$B`.@!G'B!*L XM4HH0A;I\`")F$`P3`")F!%*+8`9"*O__8`)@UF`X($M2BQ`02(`Z`&<FNGP`T XM(&<@NGP`"6<:NGP`#&<4NGP`#6<.NGP`"F<(($I2BA"%8,X@2E**0A!*168"C XM4XM2;(+48`#_6D(20J<P+(+44D!(P.6`+P!.N@->*4""T%!/9@A";(+48`#^; XMV'H`)FR"V&`D,`5(P.6`(&R"T"&+"``@2R`(2AAF_)'`4X@P"%)`2,#7P%)%Y XMNFR"U&W6,`5(P.6`(&R"T$*P"`!@`/Z4(``P/'__8`0P+P`,(&\`!$H89OQ3N XM2")O``A30!#95\C__&<"0A`@+P`$3G5,[P,```0@"#(O``Q@`A#95\G__&<&R XM4D%@`D(84<G__$YU2.=(`$*$2H!J!$2`4D1*@6H&1($*1``!83Y*1&<"1(!,K XMWP`22H!.=4CG2`!"A$J`:@1$@%)$2H%J`D2!81H@`6#8+P%A$B`!(A]*@$YUO XM+P%A!B(?2H!.=4CG,`!(04I!9B!(038!-`!"0$A`@,,B`$A`,@*"PS`!0D%(^ XM04S?``Q.=4A!)@$B`$)!2$%(0$)`=`_0@-.!MH%B!)*#4D!1RO_R3-\`#$YU4 XM3E4``$JL@MQG!B!L@MQ.D#\M``A.N@`(5$].74YU3E7__"\$,"T`"$C`*T#_I XM_$JL@K9G*'@`8`H_!$ZZ`/Y43U)$N&R`@FWP,"R`@L'\``8O`"\L@K9.N@'<H XM4$]*K(+@9P8@;(+@3I!*K("(9PHO+("(3KH!6%A/2JR"Y&<((&R"Y""L@NA*' XMK(+L9PHO+(+L3KH!=%A/2JR"\&<*+RR"\$ZZ`6183TJL@O1G"B\L@O1.N@%4] XM6$]*K(+X9PHO+(+X3KH!1%A/+'@`!`@N``0!*6<4+PU+^@`*3J[_XBI?8`9"Q XMI_-?3G-*K(+,9C!*K(+89R@P+(+62,`O`"\L@MA.N@$T,"R"U%)`2,#E@"\`P XM+RR"T$ZZ`2!/[P`08`Y.N@$.+RR"S$ZZ`2I83R`M__PN;(*Z3G4H'TY=3G5.0 XM50``2.<.(#@M``@P!,'\``8D0-7L@K9*1&T*N&R`@FP$2I)F$#E\``*"_'#_$ XM3-\$<$Y=3G4(*@`'``1F""\23KH`"EA/0I)P`&#B(B\`!"QL@L).[O_<(B\`1 XM!"QL@L).[O^"(B\`!"QL@L).[O]`+&R"PD[N_\I,[P`&``0L;(+"3N[_XD[ZP XM``(L;(+"3N[_Q$[Z``(B+P`$+&R"PD[N_Z9.^@`"3.\`#@`$+&R"PD[N_]!(_ XMYP$$3.\@@``,+&R"ODZN_Y1,WR"`3G4B;P`$+&R"OD[N_F),[P`#``0L;(*^K XM3N[_.B)O``0L;(*^3N[^VBQL@KY.[O]\(F\`!"`O``@L;(*^3N[_+B!O``0LQ XM;(*^3N[^C")O``0L;(*^3N[^AB!O``0L;(*^3N[^@````^P````!`````0``U XM">X````````#\@```^H````C`!\`'``?`!X`'P`>`!\`'P`>`!\`'@`?````I XM'P`[`%H`>`"7`+4`U`#S`1$!,`%.`6T````$````#````!4````;````(0``@ XM`"4````J````+P```#8```!`````2````%$@(%,@($T@5'4@(%<@5&@@($8@O XM(%,*````````````%`````````````````/L````#``````````R````-@``T XM`#H````^````0@```$8```!*````3@```%(```!6````6@```%X````````#[ X-\@```^L````!```#\D8`< X`` Xend Xsize 4468 SHAR_EOF echo "End of archive 1 (of 1)" # if you want to concatenate archives, remove anything after this line exit