home *** CD-ROM | disk | FTP | other *** search
- /*
- * getabsdate - parse almost any absolute date getdate(3) can (& some it can't)
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/timeb.h>
- #include "dateconv.h"
- #include "datetok.h"
-
- #define MAXDATEFIELDS 25
-
- /* imports */
- extern int parsetime();
-
- /* forwards */
- int prsabsdate();
-
- /* exports */
- extern int dtok_numparsed;
-
- /*
- * parse and convert absolute date in timestr (the normal interface)
- */
- time_t
- getabsdate(timestr, now)
- char *timestr;
- struct timeb *now;
- {
- int tz = 0;
- struct tm date;
-
- return prsabsdate(timestr, now, &date, &tz) < 0? -1:
- dateconv(&date, tz);
- }
-
- /*
- * just parse the absolute date in timestr and get back a broken-out date.
- */
- int
- prsabsdate(timestr, now, tm, tzp)
- char *timestr;
- struct timeb *now;
- register struct tm *tm;
- int *tzp;
- {
- register int nf;
- char *fields[MAXDATEFIELDS];
- static char delims[] = "- \t\n/,";
-
- nf = split(timestr, fields, MAXDATEFIELDS, delims+1);
- if (nf > MAXDATEFIELDS)
- return -1;
- if (tryabsdate(fields, nf, now, tm, tzp) < 0) {
- register char *p = timestr;
-
- /*
- * could be a DEC-date; glue it all back together, split it
- * with dash as a delimiter and try again. Yes, this is a
- * hack, but so are DEC-dates.
- */
- while (--nf > 0) {
- while (*p++ != '\0')
- ;
- p[-1] = ' ';
- }
- nf = split(timestr, fields, MAXDATEFIELDS, delims);
- if (nf > MAXDATEFIELDS)
- return -1;
- if (tryabsdate(fields, nf, now, tm, tzp) < 0)
- return -1;
- }
- return 0;
- }
-
- /*
- * try to parse pre-split timestr as an absolute date
- */
- int
- tryabsdate(fields, nf, now, tm, tzp)
- char *fields[];
- int nf;
- struct timeb *now;
- register struct tm *tm;
- int *tzp;
- {
- register int i;
- register datetkn *tp;
- register long flg = 0, ty;
- int mer = HR24, bigval = -1;
- struct timeb ftz;
-
- if (now == NULL) { /* default to local time (zone) */
- now = &ftz;
- (void) ftime(now);
- }
- *tzp = now->timezone;
-
- tm->tm_mday = tm->tm_mon = tm->tm_year = -1; /* mandatory */
- tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
- tm->tm_isdst = 0;
- dtok_numparsed = 0;
-
- for (i = 0; i < nf; i++) {
- if (fields[i][0] == '\0')
- continue;
- tp = datetoktype(fields[i], &bigval);
- ty = (1L << tp->type) & ~(1L << IGNORE);
- if (flg&ty)
- return -1; /* repeated type */
- flg |= ty;
- switch (tp->type) {
- case YEAR:
- tm->tm_year = bigval;
- /* convert 4-digit year to 1900 origin */
- if (tm->tm_year >= 1900)
- tm->tm_year -= 1900;
- break;
- case DAY:
- tm->tm_mday = bigval;
- break;
- case MONTH:
- tm->tm_mon = tp->value - 1; /* convert to zero-origin */
- break;
- case TIME:
- if (parsetime(fields[i], tm) < 0)
- return -1;
- break;
- case DTZ:
- #if 0
- tm->tm_isdst++;
- #endif
- /* FALLTHROUGH */
- case TZ:
- *tzp = FROMVAL(tp);
- break;
- case IGNORE:
- break;
- case AMPM:
- mer = tp->value;
- break;
- default:
- return -1; /* bad token type: CANTHAPPEN */
- }
- }
- if (tm->tm_year == -1 || tm->tm_mon == -1 || tm->tm_mday == -1)
- return -1; /* missing component */
- if (mer == PM)
- tm->tm_hour += 12;
- return 0;
- }
-