fnf@unisoft.UUCP (Fred Fish) (01/25/85)
[...........] Another cute little program from an old DECUS C distribution. This one puts out something of the form: "Today is Thursday, the twenty-fourth day of January, nineteen eighty-five. The time is twelve minutes and forty seconds after seven PM, Daylight Savings Time. The moon is new." --Fred #--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory for the files. # # 2) Write a file, such as "file.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting Makefile: sed 's/^Z//' >Makefile <<\STUNKYFLUFF Z# Z# Makefile for very verbose date command (today). Z ZOBJ = datetx.o moontx.o nbrtxt.o timetx.o today.o Z Ztoday: $(OBJ) Z $(CC) -o $@ $(OBJ) Z STUNKYFLUFF set `sum Makefile` if test 62527 != $1 then echo Makefile: Checksum error. Is: $1, should be: 62527. fi # # echo Extracting datetx.c: sed 's/^Z//' >datetx.c <<\STUNKYFLUFF Z# Z/* Z * Convert Date to Readable Format. Z * Z * Synopsis: Z * Z * char *datetxt(buffer, year, month, day); Z * char *buffer; -- Output string goes here Z * int year; -- Year, 1979 = 1979 Z * int month; -- Month, January = 1 Z * int day; -- Day, 1 = 1 Z * Z * The readable date will be written into the outpub buffer, terminated by Z * a null byte. datetxt returns a pointer to the null byte. Z * Z * External routines called: Z * Z * nbrtxt (Number to ascii conversion) Z * copyst (String copy routine) Z */ Z Zextern char *nbrtxt(); Zextern char *copyst(); Zextern char *datetxt(); Z Zstatic char *daynames[] = { Z "Sunday", /* Sunday is day zero */ Z "Monday", Z "Tuesday", Z "Wednesday", Z "Thursday", Z "Friday", Z "Saturday", Z}; Z Zstatic char *monthnames[] = { Z "?Nomember?", /* Illegal month */ Z "January", Z "February", Z "March", Z "April", Z "May", Z "June", Z "July", Z "August", Z "September", Z "October", Z "November", Z "December", Z}; Z Zchar *datetxt(buffer, year, month, day) Zchar *buffer; /* Output goes here */ Zint year; /* Year, 1979 = 1979 */ Zint month; /* Month of year, Jan = 1 */ Zint day; /* Day in the month 1 = 1 */ Z/* Z * Output the date in readable format: Z * Tuesday, the third of October Z */ Z{ Z register char *op; /* Output pointer */ Z Z op = buffer; /* Setup output pointer */ Z op = copyst(op, daynames[dayofweek(year, month, day)]); Z op = copyst(op, ", the "); Z op = nbrtxt(op, day, 1); Z op = copyst(op, " day of "); Z op = copyst(op, monthnames[(month < 0 || month > 12) ? 0 : month]); Z op = copyst(op, ", "); Z if (year < 1000 || year >= 2000) Z return(nbrtxt(op, year, 0)); Z else { Z op = nbrtxt(op, year/100, 0); Z op = copyst(op, " "); Z if ((year = year % 100) == 0) Z return(copyst(op, "hundred")); Z else Z return(nbrtxt(op, year, 0)); Z } Z} Z Zdayofweek(year, month, day) Zint year; /* Year, 1978 = 1978 */ Zint month; /* Month, January = 1 */ Zint day; /* Day of month, 1 = 1 */ Z/* Z * Return the day of the week on which this date falls: Sunday = 0. Z * Note, this routine is valid only for the Gregorian calender. Z */ Z{ Z register int yearfactor; Z Z yearfactor = year + (month - 14)/12; Z return (( (13 * (month + 10 - (month + 10)/13*12) - 1)/5 Z + day + 77 + 5 * (yearfactor % 100)/4 Z + yearfactor / 400 Z - yearfactor / 100 * 2) % 7); Z} STUNKYFLUFF set `sum datetx.c` if test 65180 != $1 then echo datetx.c: Checksum error. Is: $1, should be: 65180. fi # # echo Extracting moontx.c: sed 's/^Z//' >moontx.c <<\STUNKYFLUFF Z# Z/* Z * Phase of the Moon Conversion. Z * Z * Synopsis Z * Z * char *moontxt(buffer, year, month, day) Z * char *buffer; -- Output goes here. Z * int year; -- Year 1979 = 1979 Z * int month; -- Month Jan. = 1 Z * int day; -- Day 1 = 1 Z * Z * The phase of the moon (in readable ascii) is written into the buffer, Z * followed by a null. The routine returns a pointer to the trailing null. Z * Z * External routines called: Z * Z * copyst (String copy routine) Z */ Z Zextern char *copyst(); /* String output routine */ Z Zstatic char *phasetxt[] = { Z "new", Z "waxing crescent", Z "in its first quarter", Z "waxing gibbous", Z "full", Z "waning gibbous", Z "in its last quarter", Z "waning crescent" Z}; Z Zstatic int day_year[] = { /* Days in year for each month */ Z -1, -1, 30, 58, 89, 119, 150, 180, 211, 241, 272, 303, 333 Z}; /* Note: Jan. 1 will equal zero */ Z Zchar *moontxt(buffer, year, month, day) Zchar *buffer; /* Where to put the text */ Zint year; /* Year, 1978 = 1978 */ Zint month; /* Month, Jan = 1 */ Zint day; /* Day, 1 = 1 */ Z/* Z * Output the phase of the moon for the given year, month, day. Z * The routine calculates the year's epact (the age of the moon on Jan 1.), Z * adds this to the number of days in the year, and calculates the phase Z * of the moon for this date. Z * Z * In the algorithm: Z * Z * diy Is the day of the year - 1 (i.e., Jan 1 is day 0). Z * Z * golden Is the number of the year in the Mentonic cycle, used to Z * determine the position of the calender moon. Z * Z * epact Is the age of the calender moon (in days) at the beginning Z * of the year. To calculate epact, two century-based Z * corrections are applied: Z * Gregorian: (3 * cent)/4 - 12 Z * is the number of years such as 1700, 1800 when Z * leap year was not held. Z * Clavian: (((8 * cent) + 5) / 25) - 5 Z * is a correction to the Mentonic cycle of about Z * 8 days evry 2500 years. Note that this will Z * overflow 16 bits in the year 409600. Beware. Z * Z * The algorithm is accurate for the Gregorian calender only. Z * Z * The magic numbers used in the phase calculation are as follows: Z * 29.5 The moon's period in days. Z * 177 29.5 scaled by 6 Z * 22 (29.5 / 8) scaled by 6 (this gets the phase) Z * 11 ((29.5 / 8) / 2) scaled by 6 Z * Z * Theoretically, this should yield a number in the range 0 .. 7. However, Z * two days per year, things don't work out too well. Z * Z * Epact is calculated by the algorithm given in Knuth vol. 1 (calculation Z * of Easter). See also the article on Calenders in the Encyclopaedia Z * Britannica and Knuth's algorithm in CACM April 1962, page 209. Z */ Z{ Z int phase; /* Moon phase */ Z register int cent; /* Century number (1979 = 20) */ Z register int epact; /* Age of the moon on Jan. 1 */ Z register int diy; /* Day in the year */ Z int golden; /* Moon's golden number */ Z Z if (month < 0 || month > 12) month = 0; /* Just in case */ Z diy = day + day_year[month]; /* Day in the year */ Z if ((month > 2) && ((year % 4 == 0) && Z ((year % 400 == 0) || (year % 100 != 0)))) Z diy++; /* Leapyear fixup */ Z cent = (year / 100) + 1; /* Century number */ Z golden = (year % 19) + 1; /* Golden number */ Z epact = ((11 * golden) + 20 /* Golden number */ Z + (((8 * cent) + 5) / 25) - 5 /* 400 year cycle */ Z - (((3 * cent) / 4) - 12)) % 30;/* Leap year correction */ Z if (epact <= 0) Z epact += 30; /* Age range is 1 .. 30 */ Z if ((epact == 25 && golden > 11) || epact == 24) Z epact++; Z /* Z * Calculate the phase, using the magic numbers defined above. Z * Note that (phase and 7) is equivalent to (phase mod 8) and Z * is needed on two days per year (when the algorithm yields 8). Z */ Z phase = (((((diy + epact) * 6) + 11) % 177) / 22) & 7; Z return(copyst(buffer, phasetxt[phase])); Z} STUNKYFLUFF set `sum moontx.c` if test 12622 != $1 then echo moontx.c: Checksum error. Is: $1, should be: 12622. fi # # echo Extracting nbrtxt.c: sed 's/^Z//' >nbrtxt.c <<\STUNKYFLUFF Z# Z/* Z * Integer to Readable ASCII Conversion Routine. Z * Z * Synopsis: Z * Z * char *nbrtxt(buffer, value, ordinal) Z * char *buffer; -- The output buffer Z * int value; -- The number to output Z * int ordinal; -- Non-zero for ordinal number Z * Z * Z * The value is converted to a readable number and put in the output Z * buffer (null-terminated). A pointer to the first free location Z * in the buffer (i.e., the null) is returned. The ordinal Z * flag distinguishes between cardinal and ordinal numbers: Z * Z * nbrtxt(buffer, 1, 0) = "one" Z * nbrtxt(buffer, 1, 1) = "first" Z * Z * The longest output string is: Z * Z * Twenty-seven thousand, three hundred and seventy-seventh. Z * Z * Z * Z * Copy a String Z * Z * Synopsis Z * Z * char *copyst(out, in) Z * char *out; -- The output string Z * char *in; -- The input string Z * Z * The input string is copied into the output string. Copyst returns Z * a pointer to the null trailer. Z * Z */ Z Zextern char *nbrtxt(); Zextern char *copyst(); Z Zstatic char *cardinal[] = { Z "zero", Z "one", Z "two", Z "three", Z "four", Z "five", Z "six", Z "seven", Z "eight", Z "nine", Z "ten", Z "eleven", Z "twelve", Z "thirteen", Z "fourteen", Z "fifteen", Z "sixteen", Z "seventeen", Z "eighteen", Z "nineteen" Z}; Z Zstatic char *ordinal[] = { Z "zeroth", Z "first", Z "second", Z "third", Z "fourth", Z "fifth", Z "sixth", Z "seventh", Z "eighth", Z "ninth", Z "tenth", Z "eleventh", Z "twelfth" Z}; Z Zstatic char *twenties[] = { Z "twen", Z "thir", Z "for", Z "fif", Z "six", Z "seven", Z "eigh", Z "nine" Z}; Z Zchar *nbrtxt(buffer, datum, ordflag) Zchar *buffer; /* Output string buffer */ Zint datum; /* what to translate */ Zint ordflag; /* 0 if cardinal, 1 if ordinal */ Z/* Z * Translate a number to a readable text string, punctuation and all. Z * If ordflag is non-zero, ordinal numbers ("first, second") will Z * be generated, rather than cardinal ("one, two"). Z * Note: nbrtxt() is recursive. Z */ Z{ Z Z register int value; Z register char *op; Z Z op = buffer; Z value = datum; Z if (value < 0) { Z op = copyst(op, "minus "); Z value = (-value); Z if (value < 0) { /* Hack -32768 */ Z op = copyst(op, twenties[1]); Z value = 2768; Z } Z } Z if (value >= 1000) { Z op = nbrtxt(op, value/1000, 0); Z op = copyst(op, " thousand"); Z value = value % 1000; Z if (value == 0) goto exit; Z op = copyst(op, (value >= 100) ? ", " : " and "); Z } Z if (value >= 100) { Z op = copyst(op, cardinal[value/100]); Z op = copyst(op, " hundred"); Z value = value % 100; Z if (value == 0) goto exit; Z op = copyst(op, " "); Z } Z if (value >= 20) { Z if (value == 90 && ordflag) Z return(copyst(op, "nintieth")); Z op = copyst(op, twenties[(value-20) / 10]); Z value = value % 10; Z if (value == 0) { Z return(copyst(op, (ordflag) ? "tieth" : "ty")); Z } Z op = copyst(op, "ty-"); Z } Z if (value <= 12) { Z return(copyst(op, Z (ordflag) ? ordinal[value] : cardinal[value])); Z } Z op = copyst(op, cardinal[value]); /* fourteen, fourteenth */ Z /* Z * Here on 100, 14000, etc. Z */ Zexit: if (ordflag) op = copyst(op, "th"); Z return(op); Z} Z Zchar * Zcopyst(buffer, string) Zchar *buffer; Zchar *string; Z/* Z * Copy a string into buffer. Return the free pointer. Z */ Z{ Z register char *ip; Z register char *op; Z Z ip = string; Z op = buffer; Z Z while ((*op = *ip++)) op++; Z return (op); Z} STUNKYFLUFF set `sum nbrtxt.c` if test 30886 != $1 then echo nbrtxt.c: Checksum error. Is: $1, should be: 30886. fi # # echo Extracting timetx.c: sed 's/^Z//' >timetx.c <<\STUNKYFLUFF Z# Z/* Z * Convert Time to a Readable Format. Z * Z * Synopsis: Z * Z * char *timetxt(buffer, hour, minute, second, daylight); Z * char *buffer; -- Where output goes Z * int hour; -- Hour, range is 0 to 24 Z * int minute; -- Minute, range is -1 to 59 Z * int second; -- Seconds, range is -1 to 59 Z * int daylight; -- Daylight savings time if non-zero. Z * Z * Note: if minute or second is less than zero, the value is not calculated. Z * This distinguishes between "unknown seconds" and "exactly no seconds." Z * If hour is less than zero, a null string is returned. Z * Timetxt converts the time to a null-trailed string. It returns a pointer Z * to the first free byte (i.e. the null); Z * Z * The output follows the syntax of Robert J. Lurtsema, and includes: Z * Z * In twenty-five seconds, the time will be ten minutes before noon. Z * Z * Z * External routines called: Z * Z * nbrtxt (Number to ascii conversion) Z * copyst (String copy routine) Z */ Z Zextern char *nbrtxt(); Zextern char *copyst(); Z Zchar *timetxt(buffer, hour, minute, second, daylight) Zchar *buffer; /* Output buffer */ Zint hour; /* Hours 00 - 23 */ Zint minute; /* Minutes */ Zint second; /* Seconds */ Zint daylight; /* Non-zero if savings time */ Z/* Z * Output time of day. Z */ Z{ Z char *op; /* Output pointer */ Z register int late; /* after hour or afternoon */ Z register int sec; /* Seconds temp */ Z char *stuff(); /* Buffer stuffer */ Z Z op = buffer; /* Setup buffer pointer */ Z if (hour < 0) { /* If it's a dummy call, */ Z *op = 0; /* Return a null string */ Z return(op); Z } Z if (daylight == 0101010) { /* Secret flag */ Z op = copyst(op, "The big hand is on the "); Z op = nbrtxt(op, (((minute + 2 + second/30)/5 + 11)%12)+1, 0); Z op = copyst(op," and the little hand is on the "); Z op = nbrtxt(op, ((hour + 11) % 12) + 1, 0); Z return(copyst(op, ". ")); Z } Z /* Z * Check if the time is more than 30 minutes past the hour. Z * If so, output the time before the next hour. Z */ Z if (minute < 0) second = (-2); /* No minutes means no seconds */ Z else if ((late = (minute > 30 || (minute == 30 && second > 0)))) { Z if (second > 0) { /* Before next hour */ Z second = 60 - second; Z minute += 1; /* Diddle the minute, too */ Z } Z minute = 60 - minute; /* Minutes before next hour */ Z hour += 1; /* Frobozz next hour getter */ Z } Z /* Z * Decisions, decisions: Z * Minutes Seconds => Z * 00 00 Exactly Noon Z * 00 01 One second after noon Z * 01 00 Exactly one minute after noon Z * 30 00 Exactly half past noon Z * 59 00 Exactly one minute before noon Z * 59 59 In one second, the time will be noon Z */ Z if (late && second > 0) { /* Respectfully dedicated to */ Z /* Robert J. Lurtsema */ Z op = stuff(op, second, 1, "In ", " second"); Z op = copyst(op, ", the time will be "); Z sec = -2; /* We've done seconds already */ Z } Z else { Z op = copyst(op, "The time is "); Z sec = second; /* Seconds still to be done */ Z } Z if (sec == 0) { Z op = copyst(op, "exactly "); Z if (minute == 30) Z op = copyst(op, "half past "); Z else op = stuff(op, minute, 1, " ", " minute"); Z } Z else { /* Non exact or missing seconds */ Z op = stuff(op, minute, 0, " ", " minute"); Z op = stuff(op, sec, (minute > 0), " and ", " second"); Z } Z op = copyst(op, (minute < 0 || (minute == 0 && late) Z || (second == 0 Z && ((minute == 0 && late == 0) Z || minute == 30))) ? " " Z : (late) ? " before " : " after "); Z /* Z * Hours are not quite so bad Z */ Z if (hour == 0 || hour == 24) Z op = copyst(op, "midnight"); Z else if (hour == 12) Z op = copyst(op, "noon"); Z else { Z if (late = (hour > 12)) Z hour = hour - 12; Z op = nbrtxt(op, hour, 0); Z op = copyst(op, (late) ? " PM" : " AM"); Z } Z return(copyst(op, (daylight) Z ? ", Daylight Savings Time. " Z : ", Digital Standard Time. ")); Z} Z Zstatic char * Zstuff(buffer, value, flag, leading, trailing) Zchar *buffer; /* Output goes here */ Zint value; /* The value to print if > 0 */ Zint flag; /* flag is set to print leading */ Zchar *leading; /* preceeded by ... */ Zchar *trailing; /* and followed by ... */ Z/* Z * If value <= zero, output nothing. Else, output "leading" value "trailing". Z * Note: leading is output only if flag is set. Z * If value is not one, output an "s", too. Z */ Z{ Z register char *op; /* Output pointer */ Z Z op = buffer; /* Setup buffer pointer */ Z if (value > 0) { Z if (flag) Z op = copyst(op, leading); Z op = nbrtxt(op, value, 0); Z op = copyst(op, trailing); Z if (value != 1) Z op = copyst(op, "s"); Z } Z return(op); Z} STUNKYFLUFF set `sum timetx.c` if test 32974 != $1 then echo timetx.c: Checksum error. Is: $1, should be: 32974. fi # # echo Extracting today.c: sed 's/^Z//' >today.c <<\STUNKYFLUFF Z# Z/* Z * T O D A Y Z * Z * time of day Z * Z * Define UNIX for "native" Unix Z */ Z Z/*)BUILD $(PROGRAM) = today Z $(FILES) = { today datetx timetx nbrtxt moontx } Z $(TKBOPTIONS) = { Z TASK = ...TOD Z } Z*/ Z Z#ifdef DOCUMENTATION Z Ztitle today Date and Time in English Zindex Date and Time in English Z Zsynopsis Z Z today [-] [x] | [date] Z Zdescription Z Z Today prints the date, time, and phase of the moon in English. Z The following options are available: Z .lm +8 Z .s.i -8;- or x Read date strings from the standard input file. Z .s.i -8;date Print information for the indicated date. Z .s.lm -8 Z Date and time information is given in ISO numeric notation. For Z example, November 6, 1980 would be represented as "801106". If Z a time is needed, it would be appended to the date, using 24-hour Z notation: "801106110402" would be a time which is exact to the Z second. To specify the century, the two-digit century number Z may be preceeded by '+' as in "+18801106". Z .s Z Non-numeric separators between the various fields are permitted: Z "+1776.07.04-11:15:21". Note that the full two digit entry must be Z given. Z .s Z If no parameter is given, today outputs the current date and time. Z Zdiagnostics Z Z .lm +8 Z .s.i -8;Bad parameters or date out of range in ... Z .s Z An input date or time is incorrect. Z .lm -8 Z Zauthor Z Z Martin Minow Z Zbugs Z Z The algorithm is only valid for the Gregorian calender. Z Z#endif Z Z#define APRIL_FOOLS Z Zint __narg = 1; /* No prompt if no args */ Z#define LINEWIDTH 72 /* Width of line */ Z Z#include <stdio.h> Z#include <time.h> Z#ifdef unix Z#include <ctype.h> Z#undef NULL Z#endif Z Z#define NULL 0 Z#define EOS 0 Z#define FALSE 0 Z#define TRUE 1 Z Zint day_month[] = { /* Needed for dotexttime() */ Z 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 Z}; Zint ccpos; /* Current line position */ Zchar lastbyte; /* Memory for output() */ Zchar line[100]; /* Data line for input function */ Zchar *valptr; /* Needed for number converter */ Zchar wordbuffer[LINEWIDTH]; /* Buffer for output function */ Zchar *wordptr = wordbuffer; /* Free byte in wordbuffer */ Zchar linebuffer[LINEWIDTH+2]; /* Output text buffer */ Zchar *lineptr = linebuffer; /* Free byte in linebuffer */ Zint polish; /* Funny mode flag */ Z Zextern char *datetxt(); /* Date getter */ Zextern char *timetxt(); /* Time of day getter */ Zextern char *moontxt(); /* Phase of the moon getter */ Z Zmain(argc, argv) Zint argc; Zchar *argv[]; Z/* Z * Driver for time routines. Usage: Z * Z * today Prints current time of day in readable form, Z * followed by a cookie. Z * Z * today {+cc}yymmddhhmmss Prints indicated time of day. Z * Note, hh, mm, ss may be omitted. Z * For example: Z * today 401106 = Nov. 6, 1940 Z * today +19401106 = Nov. 6, 1940 Z * today 4011061015 = Nov. 6, 1940 10:15 AM Z * Z * today - Data is read from the standard input and Z * today x output as needed. The format of each Z * line is identical to the command format. Z * ("today x" is needed for vms.) Z */ Z Z{ Z ccpos = 0; /* New line now */ Z wordptr = wordbuffer; /* Nothing buffered */ Z lineptr = linebuffer; /* Nothing in output buffer too */ Z polish = 0; /* Normal mode */ Z if (argc > 1 && tolower(argv[1][0]) == 'p') { Z polish = 1; Z argc--; Z argv++; Z } Z if (argc == 2 && ((argv[1][0] == '-') || (argv[1][0] | 040) == 'x')) { Z while (!getline()) { /* Read and print times */ Z dotexttime(line); Z } Z return; Z } Z else if (argc > 1) { Z if (dotexttime(argv[1]) == 0) Z return; Z } Z /* Z * Here if no parameters or an error in the parameter field. Z */ Z dotime(); /* Print the time. */ Z output("\n"); /* Space before cookie */ Z#ifdef UNIX Z execl(COOKIEPROGRAM, "cookie", 0); Z#endif Z} Z Zdotime() Z/* Z * Print the time of day for Unix or VMS native mode. Z */ Z{ Z int tvec[2]; /* Buffer for time function */ Z struct tm *localtime(); /* Unix time decompile function */ Z struct tm *p; /* Local pointer to time of day */ Z int year; Z int month; Z Z time(tvec); /* Get the time of day */ Z p = localtime(tvec); /* Make it more understandable */ Z year = p->tm_year + 1900; Z month = p->tm_mon + 1; Z#ifdef APRIL_FOOLS Z if (month == 4 && p->tm_mday == 1) Z polish = !polish; Z#endif Z process(year, month, p->tm_mday, p->tm_hour, Z p->tm_min, p->tm_sec, p->tm_wday); Z} Z Zdotexttime(text) Zchar *text; /* Time text */ Z/* Z * Create the time values and print them, return 1 on error. Z */ Z Z{ Z int epoch; /* Which century */ Z int year; Z int month; Z int day; Z int hour; Z int minute; Z int second; Z int leapyear; Z Z valptr = text; /* Setup for getval() */ Z while (*valptr == ' ') valptr++; /* Leading blanks skip */ Z if (*valptr != '+') Z epoch = 1900; /* Default for now */ Z else { Z valptr++; Z if ((epoch = getval(-1, 00, 99)) < 0) goto bad; Z epoch *= 100; /* Make it a real epoch */ Z } Z Z if ((year = getval(-1, 00, 99)) < 0) goto bad; Z year += epoch; Z leapyear = ((year%4) == 0) && (((year%400) == 0) || (year%100 != 0)); Z if ((month = getval(-1, 1, 12)) < 0) goto bad; Z if ((day = getval(-1, 1, Z (month == 2 && leapyear) ? 29 : day_month[month])) < 0) Z goto bad; Z if ((hour = getval(-2, 0, 23)) == -1) goto bad; Z if ((minute = getval(-2, 0, 59)) == -1) goto bad; Z if ((second = getval(-2, 0, 59)) == -1) goto bad; Z process(year, month, day, hour, minute, second, 0); Z return(0); /* Normal exit */ Z Zbad: output("Bad parameters or date out of range in \""); Z output(text); Z output("\" after scanning \""); Z *valptr = '\0'; Z output(text); Z output("\".\n"); Z return(1); /* Error exit */ Z} Z Zstatic char outline[500]; /* Output buffer */ Z Zprocess(year, month, day, hour, minute, second, daylight) Zint year; /* Year 1900 = 1900 */ Zint month; /* Month January = 1 */ Zint day; /* Day 1 = 1 */ Zint hour; /* Hour 0 .. 23 */ Zint minute; /* Minute 0 .. 59 */ Zint second; /* Second 0 .. 59 */ Zint daylight; /* Daylight savings time if 1 */ Z/* Z * Output the information. Note that the parameters are within range. Z */ Z{ Z Z output("Today is "); Z datetxt(outline, year, month, day); Z output(outline); Z output(". "); Z timetxt(outline, hour, minute, second, Z (polish) ? 0101010 : daylight); Z output(outline); Z output("The moon is "); Z moontxt(outline, year, month, day); Z output(outline); Z output(". \n"); Z} Z Z Zoutput(text) Zchar *text; /* What to print */ Z/* Z * Output routine. Text is output using put() so that lines are Z * not more than LINEWIDTH bytes long. Current position is in global ccpos. Z * (put is equivalent to putchar() except that it is locally buffered.) Z */ Z{ Z register char *in; /* Current pos. in scan */ Z register char c; /* Current character */ Z register char *wp; /* Word pointer */ Z Z in = text; Z while (c = *in++) { Z switch (c) { Z case '\n': /* Force new line */ Z case ' ': /* or a space seen */ Z if ((wordptr-wordbuffer) + ccpos >= LINEWIDTH) { Z put('\n'); /* Current word */ Z ccpos = 0; /* won't fit, dump it. */ Z } Z if (wordptr > wordbuffer) { Z if (ccpos) { /* Leading space needed */ Z put(' '); Z ccpos++; Z } Z for (wp = wordbuffer; wp < wordptr;) { Z put(*wp++); Z } Z ccpos += (wordptr - wordbuffer); Z wordptr = wordbuffer; /* Empty buffer */ Z } Z if (c == '\n') { Z put('\n'); /* Print a newline */ Z ccpos = 0; /* and reset the cursor */ Z } Z break; Z Z default: Z *wordptr++ = c; /* Save piece of word */ Z } Z } Z} Z Zput(c) Zregister char c; Z/* Z * Actual output routine Z */ Z{ Z if (c == '\n' || (lineptr - linebuffer) >= LINEWIDTH) { Z *lineptr = EOS; Z puts(linebuffer); Z lineptr = linebuffer; Z if (c == '\n') Z return; Z } Z *lineptr++ = c; Z} Z Zgetline() Z/* Z * Read text to global line[]. Return 1 on end of file, zero on ok. Z */ Z{ Z register char *t; Z Z return (gets(line) == NULL); Z} Z Zgetval(flag, low, high) Zint flag; Zint low; Zint high; Z/* Z * Global valptr points to a 2-digit positive decimal integer. Z * Skip over leading non-numbers and return the value. Z * Return flag if text[0] == '\0'. Return -1 if the text is bad, Z * or if the value is out of the low:high range. Z */ Z{ Z register int value; Z register int i; Z register int temp; Z Z if (*valptr == '\0') return(flag); /* Default? */ Z while (*valptr && (*valptr < '0' || *valptr > '9')) *valptr++; Z /* The above allows for 78.04.22 format */ Z for (value = i = 0; i < 2; i++) { Z temp = *valptr++ - '0'; Z if (temp < 0 || temp > 9) return(-1); Z value = (value*10) + temp; Z } Z return((value >= low && value <= high) ? value : -1); Z} Z STUNKYFLUFF set `sum today.c` if test 43354 != $1 then echo today.c: Checksum error. Is: $1, should be: 43354. fi echo ALL DONE BUNKY! exit 0
avolio@grendel.UUCP (Frederick M. Avolio) (01/30/85)
Yes, it is "cute." I believe there is one mistake. The pointer to the
day of the week is passed in today to process when the daylight savings
flag is needed. (Sorry if this has already been reported.)
new vs. old:
171c171
< p->tm_min, p->tm_sec, p->tm_isdst);
---
> p->tm_min, p->tm_sec, p->tm_wday);
--
Fred Avolio {seismo,decvax}!grendel!avolio 301/731-4100 x4227