X-Git-Url: http://www.andromeda.nl/gitweb/?a=blobdiff_plain;f=src%2Fparsedate.c;fp=src%2Fparsedate.c;h=0000000000000000000000000000000000000000;hb=446d39140f5a32d04d9a5a05620a9bb2eb816de1;hp=dd83de43950b33b4d28597f3d00d9021c2ee6982;hpb=35089ead71590d9055a7d83f1b63772f5d4fbbf0;p=AXE.git diff --git a/src/parsedate.c b/src/parsedate.c deleted file mode 100644 index dd83de4..0000000 --- a/src/parsedate.c +++ /dev/null @@ -1,374 +0,0 @@ - -/* - * - * Purpose: - * - * Manipulate character strings representing dates. - * - * Usage: - * - * #include - * - * char date; - * struct parseddate *pd; - * - * pd = parsedate (date); - * - * compute_unixtime (pd); - * - * break_down_unixtime (pd); - * - * date = mail_date_string (pd); - * - * date = uucp_date_string (pd); - * - * Notes: - * - * The returned value from "parsedate", "mail_date_string", or - * "uucp_date_string" points to static data whose contents are - * overwritten by the next call to the same routine. - * - * "compute_unixtime" is implicitly called by "parsedate". - * - * Global contents: - * - * struct parseddate *parsedate (date) char *date; - * Parse a character string representing a date and time into - * individual values in a "struct parseddate" data structure. - * - * compute_unixtime (pd) struct parseddate *pd; - * Given a mostly filled-in "struct parseddate", compute the day - * of the week and the internal UNIX representation of the date. - * - * break_down_unixtime (pd) struct parseddate *pd; - * Compute the date and time corresponding to the "unixtime" and - * "zone" values in a "struct parseddate". - * - * char *mail_date_string (pd) struct parseddate *pd; - * Generate a character string representing a date and time in - * the RFC822 (ARPANET mail standard) format. - * - * char *uucp_date_string (pd) struct parseddate *pd; - * Generate a character string representing a date and time in - * the UUCP mail format. - * - * Local contents: - * - * None. - */ - -#include -#include -#include "parsedate.h" - -static char *RCSID = "$Id: parsedate.c,v 1.2 2002-09-28 06:58:45 arjen Exp $"; - -extern int yyparse(); - -void compute_unixtime (register struct parseddate *pd); - -/* Number of seconds in various time intervals. */ -#define SEC_PER_MIN 60 -#define SEC_PER_HOUR (60*SEC_PER_MIN) -#define SEC_PER_DAY (24*SEC_PER_HOUR) -#define SEC_PER_YEAR (365*SEC_PER_DAY) - -/* Number of days in each month. */ -static int monthsize[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; - -/* Three-letter abbreviations of month and day names. */ -static char monthname[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; -static char dayname[] = "SunMonTueWedThuFriSat"; - -/* struct parseddate *parsedate (date) char *date; - * Analyze a character string representing a date and time. The - * returned value points to a data structure with the desired - * information. (NOTE: The returned value points to static data - * whose contents are overwritten by each call.) - */ -struct parseddate * parsedate (char *date) -{ register char *c; - register int year_save; - extern struct parseddate yyans; - extern char *yyinbuf; - - /* Initialize the returned-value structure. */ - yyans.unixtime = -1; - yyans.year = -1; - yyans.month = -1; - yyans.day = -1; - yyans.hour = -1; - yyans.minute = -1; - yyans.second = -1; - yyans.zone = -1; - yyans.dst = -1; - yyans.weekday = -1; - yyans.c_weekday = -1; - yyans.error = NULL; - - /* Parse the argument string. */ - yyinbuf = date; - - if (yyparse () != 0 && yyans.error == NULL) - yyans.error = yyinbuf; - - /* Validate the day of the month, compute/validate the day of the - * week, and compute the internal UNIX form of the time. See if - * "compute_unixtime" found fault with the year or the day of the - * month. (Note that we have to remember the original "year" value - * because it might legitimately have been -1 to begin with.) - */ - year_save = yyans.year; compute_unixtime (&yyans); - if (yyans.error == NULL - && (yyans.year != year_save - || (yyans.month > 0 && yyans.day < 0) - || (yyans.month < 0 && yyans.day > 0))) - yyans.error = yyinbuf; - - return &yyans; -} - -/* compute_unixtime (pd) struct parseddate *pd; - * Given a mostly filled-in "struct parseddate", compute the day of - * the week and the internal UNIX representation of the date. - * - * A year before 1600 will be rejected and replaced with -1. A - * date from 1600 on which falls outside the range representable in - * internal UNIX form will still have the correct day of the week - * computed. - * - * The day of the week is always computed on the assumption that the - * Gregorian calendar is in use. Days of the week for dates in the - * far future may turn out to be incorrect if any changes are made - * to the calendar between now and then. - */ -void compute_unixtime (register struct parseddate *pd) -{ - register int weekday, n, l, a; - - /* Validate the year. */ - if (pd->year >= 0 && pd->year < 1600) pd->year = -1; - - /* Validate the day of the month. Also calculate the number of days - * in February (even if this is not February, we will need the num- - * ber of days in February later on when computing the UNIX time). - */ - if (pd->month > 0) - { if (pd->year < 0) monthsize[2] = 29; - else if (pd->year % 4 != 0) monthsize[2] = 28; - else if (pd->year % 100 != 0) monthsize[2] = 29; - else if (pd->year % 400 != 0) monthsize[2] = 28; - else monthsize[2] = 29; - if (pd->day <= 0 || pd->day > monthsize[pd->month]) - pd->day = -1; - } - - /* Compute the day of the week. The next several lines constitute a - * perpetual-calendar formula. Note, of course, that the "claimed" - * day of the week (pd->c_weekday) is ignored here. - */ - if (pd->year > 0 && pd->month > 0 && pd->day > 0) - { if (pd->month >= 3) n = pd->year / 100, - l = pd->year % 100; - else n = (pd->year-1) / 100, - l = (pd->year-1) % 100; - a = (26 * ((pd->month+9)%12 + 1) - 2) / 10; - weekday = (a+(l>>2)+(n>>2)+l-(n+n)+pd->day); - while (weekday < 0) weekday += 7; - pd->weekday = weekday % 7; - } - - /* Figure out the internal UNIX form of the date. */ - if (pd->year >= 1969 && pd->year <= 2038 - && pd->month > 0 && pd->day > 0 - && pd->hour >= 0 && pd->minute >= 0 - && pd->zone != -1 && pd->zone > -1440 && pd->zone < 1440) - { pd->unixtime = - SEC_PER_YEAR * (pd->year - 1970) - + SEC_PER_DAY * ((pd->year - 1969) / 4) - /* month is taken care of later */ - + SEC_PER_DAY * (pd->day - 1) - + SEC_PER_HOUR * pd->hour - + SEC_PER_MIN * pd->minute - /* seconds are taken care of later */ - - SEC_PER_MIN * pd->zone; - if (pd->second >= 0) - pd->unixtime += pd->second; - for (n = pd->month - 1; n > 0; n--) - pd->unixtime += SEC_PER_DAY * monthsize[n]; - if (pd->unixtime < 0) pd->unixtime = -1; - } - else pd->unixtime = -1; -} - -/* break_down_unixtime (pd) struct parseddate *pd; - * Given the "unixtime" and "zone" fields of a "struct parseddate", - * compute the values of the "year", "month", "day", "hour", "min- - * ute", "second", and "weekday" fields. The "dst" and "error" - * fields of the structure are not used or modified. - */ -void break_down_unixtime (pd) - register struct parseddate *pd; -{ register unsigned long timevalue; - register int m, n; - - /* Validate the "unixtime" and "zone" fields. */ - if (pd->unixtime < 0 - || pd->zone == -1 || pd->zone <= -1440 || pd->zone >= 1440) - { /* Sorry, can't do it. */ - pd->year = -1; pd->month = -1; pd->day = -1; - pd->hour = -1; pd->minute = -1; pd->second = -1; - pd->weekday = -1; - return; - } - - /* Even though "pd->unixtime" must be non-negative, and thus cannot - * indicate a time earlier than 1970, a negative "pd->zone" could - * cause the local date to be Wednesday, 31 December 1969. Such a - * date requires special handling. - * - * A local date earlier than 31 December 1969 is impossible because - * "pd->zone" must represent a time-zone shift of less than a day. - */ - if (pd->zone < 0 && pd->unixtime + SEC_PER_MIN * pd->zone < 0) - { pd->year = 1969; pd->month = 12; pd->day = 31; - pd->weekday = 3; /* Wednesday */ - timevalue = pd->unixtime + SEC_PER_MIN * pd->zone + SEC_PER_DAY; - /* Note: 0 <= timevalue < SEC_PER_DAY */ - pd->hour = timevalue / SEC_PER_HOUR; - pd->minute = (timevalue % SEC_PER_HOUR) / SEC_PER_MIN; - pd->second = timevalue % SEC_PER_MIN; - return; - } - - /* Handle the general case (local time is 1970 or later). */ - timevalue = pd->unixtime + SEC_PER_MIN * pd->zone; - - /* day of the week (1 January 1970 was a Thursday) . . . */ - pd->weekday = (timevalue/SEC_PER_DAY + 4 /* Thursday */) % 7; - - /* year (note that the only possible century year here is 2000, - * a leap year -- hence no special tests for century years are - * needed) . . . - */ - for (m = 1970; ; m++) - { n = (m%4==0) ? SEC_PER_YEAR+SEC_PER_DAY : SEC_PER_YEAR; - if (n > timevalue) break; - timevalue -= n; - } - pd->year = m; - monthsize[2] = (m%4==0) ? 29 : 28; - - /* month . . . */ - for (m = 1; ; m++) - { n = SEC_PER_DAY * monthsize[m]; - if (n > timevalue) break; - timevalue -= n; - } - pd->month = m; - - /* day, hour, minute, and second . . . */ - pd->day = (timevalue / SEC_PER_DAY) + 1; - pd->hour = (timevalue % SEC_PER_DAY) / SEC_PER_HOUR; - pd->minute = (timevalue % SEC_PER_HOUR) / SEC_PER_MIN; - pd->second = timevalue % SEC_PER_MIN; -} - -/* char *mail_date_string (pd) struct parseddate *pd; - * Generate a character string representing a date and time in the - * RFC822 (ARPANET mail standard) format. A value of NULL is re- - * turned if "pd" does not contain all necessary data fields. - * (NOTE: The returned value points to static data whose contents - * are overwritten by each call.) - */ -char * -mail_date_string (pd) - register struct parseddate *pd; -{ register char *c; - static char answer[50]; - - /* Check the day of the month and compute the day of the week. */ - compute_unixtime (pd); - - /* Make sure all required fields are present. */ - if (pd->year < 0 || pd->month < 0 || pd->day < 0 - || pd->hour < 0 || pd->minute < 0 - || pd->zone == -1 || pd->zone <= -1440 || pd->zone >= 1440) - return NULL; /* impossible to generate string */ - - /* Generate the answer string. */ - sprintf (answer, - "%.3s, %d %.3s %d %02d:%02d", - dayname + 3*pd->weekday, - pd->day, monthname + 3*(pd->month-1), - (pd->year >= 1960 && pd->year <= 1999) - ? pd->year - 1900 : pd->year, - pd->hour, pd->minute); - c = answer + strlen (answer); - if (pd->second >= 0) sprintf (c, ":%02d", pd->second), c += 3; - *c++ = ' '; - switch (pd->zone) - { /* NOTE: Only zone abbreviations in RFC822 are used here. */ - case 0: strcpy (c, pd->dst ? "+0000" : "GMT"); break; - case -240: strcpy (c, pd->dst ? "EDT" : "-0400"); break; - case -300: strcpy (c, pd->dst ? "CDT" : "EST"); break; - case -360: strcpy (c, pd->dst ? "MDT" : "CST"); break; - case -420: strcpy (c, pd->dst ? "PDT" : "MST"); break; - case -480: strcpy (c, pd->dst ? "-0800" : "PST"); break; - default: - if (pd->zone >= 0) - sprintf (c, "+%02d%02d", pd->zone/60, pd->zone%60); - else sprintf (c, "-%02d%02d", -pd->zone/60, -pd->zone%60); - } - - return answer; -} - -/* char *uucp_date_string (pd) struct parseddate *pd; - * Generate a character string representing a date and time in the - * UUCP mail format. A value of NULL is returned if "pd" does not - * contain all necessary data fields. (NOTE: The returned value - * points to static data whose contents are overwritten by each - * call.) - */ -char * -uucp_date_string (pd) - register struct parseddate *pd; -{ register char *c; - static char answer[50]; - - /* Check the day of the month and compute the day of the week. */ - compute_unixtime (pd); - - /* Make sure all required fields are present. */ - if (pd->year < 0 || pd->month < 0 || pd->day < 0 - || pd->hour < 0 || pd->minute < 0 - || pd->zone == -1 || pd->zone <= -1440 || pd->zone >= 1440) - return NULL; /* impossible to generate string */ - - /* Generate the answer string. */ - sprintf (answer, - "%.3s %.3s %d %02d:%02d", - dayname + 3*pd->weekday, - monthname + 3*(pd->month-1), pd->day, - pd->hour, pd->minute); - c = answer + strlen (answer); - if (pd->second >= 0) sprintf (c, ":%02d", pd->second), c += 3; - switch (pd->zone) - { /* NOTE: Only zone abbreviations in RFC822 are used here. */ - case 0: strcpy (c, pd->dst ? "+0000" : "-GMT"); break; - case -240: strcpy (c, pd->dst ? "-EDT" : "-0400"); break; - case -300: strcpy (c, pd->dst ? "-CDT" : "-EST"); break; - case -360: strcpy (c, pd->dst ? "-MDT" : "-CST"); break; - case -420: strcpy (c, pd->dst ? "-PDT" : "-MST"); break; - case -480: strcpy (c, pd->dst ? "-0800" : "-PST"); break; - default: - if (pd->zone >= 0) - sprintf (c, "+%02d%02d", pd->zone/60, pd->zone%60); - else sprintf (c, "-%02d%02d", -pd->zone/60, -pd->zone%60); - } - c = answer + strlen (answer); - sprintf (c, " %d", pd->year); - - return answer; -}