cvs: /php3 Makefile.in /php3/functions parsedate.y

From: Date: Mon, 12 Jul 1999 17:15:12 +0000
Subject: cvs: /php3 Makefile.in /php3/functions parsedate.y
Groups: php.dev 
Request: Send a blank email to php-dev+get-8418@lists.php.net to get a copy of this message
andrey Mon Jul 12 17:15:12 1999 EDT Modified files: /php3 Makefile.in /php3/functions parsedate.y Log: Changed parsedate.y to the latest version from INN. Bison gurus, please look at the generated warning messages. Index: php3/Makefile.in diff -u php3/Makefile.in:1.340 php3/Makefile.in:1.341 --- php3/Makefile.in:1.340 Mon Jul 12 15:23:29 1999 +++ php3/Makefile.in Mon Jul 12 17:15:10 1999 @@ -24,7 +24,7 @@ # +----------------------------------------------------------------------+ # -# $Id: Makefile.in,v 1.340 1999/07/12 19:23:29 andrey Exp $ +# $Id: Makefile.in,v 1.341 1999/07/12 21:15:10 andrey Exp $ # prefix = @prefix@ @@ -143,7 +143,7 @@ @IFX_C_MAKE@ functions/parsedate.h functions/parsedate.c: functions/parsedate.y - bison -p date -v -d functions/parsedate.y -o functions/parsedate.c + bison -v -d functions/parsedate.y -o functions/parsedate.c language-parser.tab.h language-parser.tab.c: $(srcdir)/language-parser.y bison -p php -v -d $(srcdir)/language-parser.y -o language-parser.tab.c Index: php3/functions/parsedate.y diff -u php3/functions/parsedate.y:1.4 php3/functions/parsedate.y:1.5 --- php3/functions/parsedate.y:1.4 Mon Jul 12 15:53:56 1999 +++ php3/functions/parsedate.y Mon Jul 12 17:15:12 1999 @@ -1,217 +1,41 @@ %{ - /* Originally from: Steven M. Bellovin (unc!smb) */ - /* Dept. of Computer Science */ - /* University of North Carolina at Chapel Hill */ - /* @(#)getdate.y 2.20 9/1/89 */ +/* $Revision: 1.5 $ +** +** Originally written by Steven M. Bellovin <smb@research.att.com> while +** at the University of North Carolina at Chapel Hill. Later tweaked by +** a couple of people on Usenet. Completely overhauled by Rich $alz +** <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990. +** Further revised (removed obsolete constructs and cleaned up timezone +** names) in August, 1991, by Rich. Paul Eggert <eggert@twinsun.com> +** helped in September, 1992. +** +** This grammar has six shift/reduce conflicts. +** +** This code is in the public domain and has no copyright. +*/ +/* SUPPRESS 530 *//* Empty body for statement */ +/* SUPPRESS 593 on yyerrlab *//* Label was not used */ +/* SUPPRESS 593 on yynewstate *//* Label was not used */ +/* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */ -#include "php.h" +#include <stdio.h> #include <sys/types.h> -#define BSD4_2 - -#undef YYSTYPE -#define YYSTYPE int - -#ifdef USG -struct timeb -{ - time_t time; - unsigned short millitm; - short timezone; - short dstflag; -}; -#else +/* +#include "configdata.h" +#include "clibrary.h"*/ +#if defined(DO_NEED_TIME) +#include <time.h> +#endif /* defined(DO_NEED_TIME) */ +#ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif #include <ctype.h> - -#define NULL 0 -#define daysec (24L*60L*60L) - static int timeflag, zoneflag, dateflag, dayflag, relflag; - static time_t relsec, relmonth; - static int hh, mm, ss, merid, daylight; - static int dayord, dayreq; - static int month, day, year; - static int ourzone; -#define AM 1 -#define PM 2 -#define DAYLIGHT 1 -#define STANDARD 2 -#define MAYBE 3 - -static int mdays[12] = - {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -#define epoch 1970 - -struct table { - char *name; - int type; - long value; -}; +/*#include "libinn.h" +#include "macros.h"*/ -struct table mdtab[] = { - {"january", MONTH, 1}, - {"february", MONTH, 2}, - {"march", MONTH, 3}, - {"april", MONTH, 4}, - {"may", MONTH, 5}, - {"june", MONTH, 6}, - {"july", MONTH, 7}, - {"august", MONTH, 8}, - {"september", MONTH, 9}, - {"sept", MONTH, 9}, - {"october", MONTH, 10}, - {"november", MONTH, 11}, - {"december", MONTH, 12}, - - {"sunday", DAY, 0}, - {"monday", DAY, 1}, - {"tuesday", DAY, 2}, - {"tues", DAY, 2}, - {"wednesday", DAY, 3}, - {"wednes", DAY, 3}, - {"thursday", DAY, 4}, - {"thur", DAY, 4}, - {"thurs", DAY, 4}, - {"friday", DAY, 5}, - {"saturday", DAY, 6}, - {0, 0, 0}}; - -#define HRS *60 -#define HALFHR 30 -struct table mztab[] = { - {"a.m.", MERIDIAN, AM}, - {"am", MERIDIAN, AM}, - {"p.m.", MERIDIAN, PM}, - {"pm", MERIDIAN, PM}, - {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */ - {"n.s.t.", ZONE, 3 HRS + HALFHR}, - {"ast", ZONE, 4 HRS}, /* Atlantic */ - {"a.s.t.", ZONE, 4 HRS}, - {"adt", DAYZONE, 4 HRS}, - {"a.d.t.", DAYZONE, 4 HRS}, - {"est", ZONE, 5 HRS}, /* Eastern */ - {"e.s.t.", ZONE, 5 HRS}, - {"edt", DAYZONE, 5 HRS}, - {"e.d.t.", DAYZONE, 5 HRS}, - {"cst", ZONE, 6 HRS}, /* Central */ - {"c.s.t.", ZONE, 6 HRS}, - {"cdt", DAYZONE, 6 HRS}, - {"c.d.t.", DAYZONE, 6 HRS}, - {"mst", ZONE, 7 HRS}, /* Mountain */ - {"m.s.t.", ZONE, 7 HRS}, - {"mdt", DAYZONE, 7 HRS}, - {"m.d.t.", DAYZONE, 7 HRS}, - {"pst", ZONE, 8 HRS}, /* Pacific */ - {"p.s.t.", ZONE, 8 HRS}, - {"pdt", DAYZONE, 8 HRS}, - {"p.d.t.", DAYZONE, 8 HRS}, - {"yst", ZONE, 9 HRS}, /* Yukon */ - {"y.s.t.", ZONE, 9 HRS}, - {"ydt", DAYZONE, 9 HRS}, - {"y.d.t.", DAYZONE, 9 HRS}, - {"hst", ZONE, 10 HRS}, /* Hawaii */ - {"h.s.t.", ZONE, 10 HRS}, - {"hdt", DAYZONE, 10 HRS}, - {"h.d.t.", DAYZONE, 10 HRS}, - - {"gmt", ZONE, 0 HRS}, - {"g.m.t.", ZONE, 0 HRS}, - {"bst", DAYZONE, 0 HRS}, /* British Summer Time */ - {"b.s.t.", DAYZONE, 0 HRS}, - {"eet", ZONE, 0 HRS}, /* European Eastern Time */ - {"e.e.t.", ZONE, 0 HRS}, - {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */ - {"e.e.s.t.", DAYZONE, 0 HRS}, - {"met", ZONE, -1 HRS}, /* Middle European Time */ - {"m.e.t.", ZONE, -1 HRS}, - {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */ - {"m.e.s.t.", DAYZONE, -1 HRS}, - {"wet", ZONE, -2 HRS }, /* Western European Time */ - {"w.e.t.", ZONE, -2 HRS }, - {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */ - {"w.e.s.t.", DAYZONE, -2 HRS}, - - {"jst", ZONE, -9 HRS}, /* Japan Standard Time */ - {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */ - /* No daylight savings time */ - - {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */ - {"a.e.s.t.", ZONE, -10 HRS}, - {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */ - {"a.e.s.s.t.", DAYZONE, -10 HRS}, - {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */ - {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)}, - {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */ - {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)}, - {"awst", ZONE, -8 HRS}, /* Australian Western Time */ - {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */ - {0, 0, 0}}; - -struct table unittb[] = { - {"year", MUNIT, 12}, - {"month", MUNIT, 1}, - {"fortnight", UNIT, 14*24*60}, - {"week", UNIT, 7*24*60}, - {"day", UNIT, 1*24*60}, - {"hour", UNIT, 60}, - {"minute", UNIT, 1}, - {"min", UNIT, 1}, - {"second", SUNIT, 1}, - {"sec", SUNIT, 1}, - {0, 0, 0}}; - -struct table othertb[] = { - {"tomorrow", UNIT, 1*24*60}, - {"yesterday", UNIT, -1*24*60}, - {"today", UNIT, 0}, - {"now", UNIT, 0}, - {"last", UNUMBER, -1}, - {"this", UNIT, 0}, - {"next", UNUMBER, 2}, - {"first", UNUMBER, 1}, - /* {"second", UNUMBER, 2}, */ - {"third", UNUMBER, 3}, - {"fourth", UNUMBER, 4}, - {"fifth", UNUMBER, 5}, - {"sixth", UNUMBER, 6}, - {"seventh", UNUMBER, 7}, - {"eighth", UNUMBER, 8}, - {"ninth", UNUMBER, 9}, - {"tenth", UNUMBER, 10}, - {"eleventh", UNUMBER, 11}, - {"twelfth", UNUMBER, 12}, - {"ago", AGO, 1}, - {0, 0, 0}}; - -struct table milzone[] = { - {"a", ZONE, 1 HRS}, - {"b", ZONE, 2 HRS}, - {"c", ZONE, 3 HRS}, - {"d", ZONE, 4 HRS}, - {"e", ZONE, 5 HRS}, - {"f", ZONE, 6 HRS}, - {"g", ZONE, 7 HRS}, - {"h", ZONE, 8 HRS}, - {"i", ZONE, 9 HRS}, - {"k", ZONE, 10 HRS}, - {"l", ZONE, 11 HRS}, - {"m", ZONE, 12 HRS}, - {"n", ZONE, -1 HRS}, - {"o", ZONE, -2 HRS}, - {"p", ZONE, -3 HRS}, - {"q", ZONE, -4 HRS}, - {"r", ZONE, -5 HRS}, - {"s", ZONE, -6 HRS}, - {"t", ZONE, -7 HRS}, - {"u", ZONE, -8 HRS}, - {"v", ZONE, -9 HRS}, - {"w", ZONE, -10 HRS}, - {"x", ZONE, -11 HRS}, - {"y", ZONE, -12 HRS}, - {"z", ZONE, 0 HRS}, - {0, 0, 0}}; - -extern struct tm *localtime(); +#if defined(_HPUX_SOURCE) +#include <alloca.h> +#endif #ifndef HAVE_TM_ZONE #ifndef _TIMEZONE @@ -219,397 +43,864 @@ #endif #endif -static time_t -timeconv(hh, mm, ss, mer) -register int hh, mm, ss, mer; -{ - if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1); - switch (mer) { - case AM: if (hh < 1 || hh > 12) return(-1); - return (60L * ((hh%12)*60L + mm)+ss); - case PM: if (hh < 1 || hh > 12) return(-1); - return (60L * ((hh%12 +12)*60L + mm)+ss); - case 24: if (hh < 0 || hh > 23) return (-1); - return (60L * (hh*60L + mm)+ss); - default: return (-1); - } -} +#define yylhs date_yylhs +#define yylen date_yylen +#define yydefred date_yydefred +#define yydgoto date_yydgoto +#define yysindex date_yysindex +#define yyrindex date_yyrindex +#define yygindex date_yygindex +#define yytable date_yytable +#define yycheck date_yycheck +#define yyparse date_parse +#define yylex date_lex +#define yyerror date_error + + + /* See the LeapYears table in Convert. */ +#define EPOCH 1970 +#define END_OF_TIME 2038 + /* Constants for general time calculations. */ +#define DST_OFFSET 1 +#define SECSPERDAY (24L * 60L * 60L) + /* Readability for TABLE stuff. */ +#define HOUR(x) (x * 60) + +#define LPAREN '(' +#define RPAREN ')' +#define IS7BIT(x) ((unsigned int)(x) < 0200) -static time_t -dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag) -int mm, dd, yy, h, m, s, mer, zone, dayflag; -{ - time_t tod, jdate; - register int i; +/* +** Get the number of elements in a fixed-size array, or a pointer just +** past the end of it. +*/ +#define SIZEOF(array) ((int)(sizeof array / sizeof array[0])) +#define ENDOF(array) (&array[SIZEOF(array)]) +#define CTYPE(isXXXXX, c) ((isascii((c)) && isXXXXX((c)))) + +typedef struct _TIMEINFO { + time_t time; + long usec; + long tzone; +} TIMEINFO; - if (yy < 0) yy = -yy; - if (yy < 70) yy += 2000; - if (yy < 100) yy += 1900; - mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0)); - if (yy < epoch || yy > 2099 || mm < 1 || mm > 12 || - dd < 1 || dd > mdays[--mm]) return (-1); - jdate = dd-1; - for (i=0; i<mm; i++) jdate += mdays[i]; - for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0); - jdate *= daysec; - jdate += zone * 60L; - if ((tod = timeconv(h, m, s, mer)) < 0) return (-1); - jdate += tod; - if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst)) - jdate += -1*60*60; - return (jdate); -} +typedef char const *STRING; +typedef char * const CSTRING; -static time_t -daylcorr(future, now) -time_t future, now; -{ - int fdayl, nowdayl; +/* +** An entry in the lexical lookup table. +*/ +typedef struct _TABLE { + STRING name; + int type; + time_t value; +} TABLE; - nowdayl = (localtime(&now)->tm_hour+1) % 24; - fdayl = (localtime(&future)->tm_hour+1) % 24; - return (future-now) + 60L*60L*(nowdayl-fdayl); -} +/* +** Daylight-savings mode: on, off, or not yet known. +*/ +typedef enum _DSTMODE { + DSTon, DSToff, DSTmaybe +} DSTMODE; -static time_t -dayconv(ord, day, now) -int ord, day; time_t now; -{ - register struct tm *loctime; - time_t tod; +/* +** Meridian: am, pm, or 24-hour style. +*/ +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; - tod = now; - loctime = localtime(&tod); - tod += daysec * ((day - loctime->tm_wday + 7) % 7); - tod += 7*daysec*(ord<=0?ord:ord-1); - return daylcorr(tod, now); -} -static time_t -monthadd(sdate, relmonth) -time_t sdate, relmonth; -{ - struct tm *ltime; - time_t dateconv(); - time_t daylcorr(); - int mm, yy; - - if (relmonth == 0) return 0; - ltime = localtime(&sdate); - mm = 12*ltime->tm_year + ltime->tm_mon + relmonth; - yy = mm/12; - mm = mm%12 + 1; - return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour, - ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate); +/* +** Global variables. We could get rid of most of them by using a yacc +** union, but this is more efficient. (This routine predates the +** yacc %union construct.) +*/ +static char *yyInput; +static DSTMODE yyDSTmode; +static int yyHaveDate; +static int yyHaveRel; +static int yyHaveTime; +static time_t yyTimezone; +static time_t yyDay; +static time_t yyHour; +static time_t yyMinutes; +static time_t yyMonth; +static time_t yySeconds; +static time_t yyYear; +static MERIDIAN yyMeridian; +static time_t yyRelMonth; +static time_t yyRelSeconds; + + +extern struct tm *localtime(); + +static void date_error(); +%} + +%union { + time_t Number; + enum _MERIDIAN Meridian; } -static int lookup(char *id) -{ -#define gotit (yylval=i->value, i->type) - extern int yylval; - char idvar[128]; - register char *j, *k; - register struct table *i; - int abbrev; - - (void) strcpy(idvar, id); - j = idvar; - k = id - 1; - while (*++k) - *j++ = isupper((int)*k) ? tolower((int)*k) : *k; - *j = '\0'; +%token tDAY tDAYZONE tMERIDIAN tMONTH tMONTH_UNIT tSEC_UNIT tSNUMBER +%token tUNUMBER tZONE - if (strlen(idvar) == 3) - abbrev = 1; - else - if (strlen(idvar) == 4 && idvar[3] == '.') { - abbrev = 1; - idvar[3] = '\0'; +%type <Number> tDAYZONE tMONTH tMONTH_UNIT tSEC_UNIT +%type <Number> tSNUMBER tUNUMBER tZONE numzone zone +%type <Meridian> tMERIDIAN o_merid + +%% + +spec : /* NULL */ + | spec item + ; + +item : time { + yyHaveTime++; +#if defined(lint) + /* I am compulsive about lint natterings... */ + if (yyHaveTime == -1) { + YYERROR; + } +#endif /* defined(lint) */ + } + | time zone { + yyHaveTime++; + yyTimezone = $2; + } + | date { + yyHaveDate++; + } + | rel { + yyHaveRel = 1; + } + ; + +time : tUNUMBER o_merid { + if ($1 < 100) { + yyHour = $1; + yyMinutes = 0; + } + else { + yyHour = $1 / 100; + yyMinutes = $1 % 100; + } + yySeconds = 0; + yyMeridian = $2; + } + | tUNUMBER ':' tUNUMBER o_merid { + yyHour = $1; + yyMinutes = $3; + yySeconds = 0; + yyMeridian = $4; + } + | tUNUMBER ':' tUNUMBER numzone { + yyHour = $1; + yyMinutes = $3; + yyTimezone = $4; + yyMeridian = MER24; + yyDSTmode = DSToff; + } + | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { + yyHour = $1; + yyMinutes = $3; + yySeconds = $5; + yyMeridian = $6; + } + | tUNUMBER ':' tUNUMBER ':' tUNUMBER numzone { + yyHour = $1; + yyMinutes = $3; + yySeconds = $5; + yyTimezone = $6; + yyMeridian = MER24; + yyDSTmode = DSToff; + } + ; + +zone : tZONE { + $$ = $1; + yyDSTmode = DSToff; + } + | tDAYZONE { + $$ = $1; + yyDSTmode = DSTon; + } + | tZONE numzone { + /* Only allow "GMT+300" and "GMT-0800" */ + if ($1 != 0) { + YYABORT; + } + $$ = $2; + yyDSTmode = DSToff; + } + | numzone { + $$ = $1; + yyDSTmode = DSToff; + } + ; + +numzone : tSNUMBER { + int i; + + /* Unix and GMT and numeric timezones -- a little confusing. */ + if ($1 < 0) { + /* Don't work with negative modulus. */ + $1 = -$1; + if ($1 > 9999 || (i = $1 % 100) >= 60) { + YYABORT; } - else - abbrev = 0; + $$ = ($1 / 100) * 60 + i; + } + else { + if ($1 > 9999 || (i = $1 % 100) >= 60) { + YYABORT; + } + $$ = -(($1 / 100) * 60 + i); + } + } + ; - for (i = mdtab; i->name; i++) { - k = idvar; - for (j = i->name; *j++ == *k++;) { - if (abbrev && j == i->name+3) - return gotit; - if (j[-1] == 0) - return gotit; +date : tUNUMBER '/' tUNUMBER { + yyMonth = $1; + yyDay = $3; + } + | tUNUMBER '/' tUNUMBER '/' tUNUMBER { + if ($1 > 100) { + /* assume YYYY/MM/DD format, so need not to add 1900 */ + yyYear = $1; + yyMonth = $3; + yyDay = $5; + } + else { + /* assume MM/DD/YY* format */ + yyMonth = $1; + yyDay = $3; + if ($5 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $5; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $5 + 1900; } + } + } + | tMONTH tUNUMBER { + yyMonth = $1; + yyDay = $2; } + | tMONTH tUNUMBER ',' tUNUMBER { + yyMonth = $1; + yyDay = $2; + if ($4 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $4; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $4 + 1900; + } + } + | tUNUMBER tMONTH { + yyDay = $1; + yyMonth = $2; + } + | tUNUMBER tMONTH tUNUMBER { + yyDay = $1; + yyMonth = $2; + if ($3 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $3; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $3 + 1900; + } + } + | tDAY ',' tUNUMBER tMONTH tUNUMBER { + yyDay = $3; + yyMonth = $4; + if ($5 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $5; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $5 + 1900; + } + } + ; + +rel : tSNUMBER tSEC_UNIT { + yyRelSeconds += $1 * $2; + } + | tUNUMBER tSEC_UNIT { + yyRelSeconds += $1 * $2; + } + | tSNUMBER tMONTH_UNIT { + yyRelMonth += $1 * $2; + } + | tUNUMBER tMONTH_UNIT { + yyRelMonth += $1 * $2; + } + ; + +o_merid : /* NULL */ { + $$ = MER24; + } + | tMERIDIAN { + $$ = $1; + } + ; - for (i = mztab; i->name; i++) - if (strcmp(i->name, idvar) == 0) - return gotit; +%% - for (i=mztab; i->name; i++) - if (strcmp(i->name, idvar) == 0) - return gotit; +/* Month and day table. */ +static TABLE MonthDayTable[] = { + { "january", tMONTH, 1 }, + { "february", tMONTH, 2 }, + { "march", tMONTH, 3 }, + { "april", tMONTH, 4 }, + { "may", tMONTH, 5 }, + { "june", tMONTH, 6 }, + { "july", tMONTH, 7 }, + { "august", tMONTH, 8 }, + { "september", tMONTH, 9 }, + { "october", tMONTH, 10 }, + { "november", tMONTH, 11 }, + { "december", tMONTH, 12 }, + /* The value of the day isn't used... */ + { "sunday", tDAY, 0 }, + { "monday", tDAY, 0 }, + { "tuesday", tDAY, 0 }, + { "wednesday", tDAY, 0 }, + { "thursday", tDAY, 0 }, + { "friday", tDAY, 0 }, + { "saturday", tDAY, 0 }, +}; - for (i=unittb; i->name; i++) - if (strcmp(i->name, idvar) == 0) - return gotit; +/* Time units table. */ +static TABLE UnitsTable[] = { + { "year", tMONTH_UNIT, 12 }, + { "month", tMONTH_UNIT, 1 }, + { "week", tSEC_UNIT, 7 * 24 * 60 * 60 }, + { "day", tSEC_UNIT, 1 * 24 * 60 * 60 }, + { "hour", tSEC_UNIT, 60 * 60 }, + { "minute", tSEC_UNIT, 60 }, + { "min", tSEC_UNIT, 60 }, + { "second", tSEC_UNIT, 1 }, + { "sec", tSEC_UNIT, 1 }, +}; - if (idvar[strlen(idvar)-1] == 's') - idvar[strlen(idvar)-1] = '\0'; +/* Timezone table. */ +static TABLE TimezoneTable[] = { + { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ + { "ut", tZONE, HOUR( 0) }, /* Universal */ + { "utc", tZONE, HOUR( 0) }, /* Universal Coordinated */ + { "cut", tZONE, HOUR( 0) }, /* Coordinated Universal */ + { "z", tZONE, HOUR( 0) }, /* Greenwich Mean */ + { "wet", tZONE, HOUR( 0) }, /* Western European */ + { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ + { "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */ + { "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */ + { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ + { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ + { "est", tZONE, HOUR( 5) }, /* Eastern Standard */ + { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ + { "cst", tZONE, HOUR( 6) }, /* Central Standard */ + { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ + { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ + { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ + { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ + { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ + { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ + { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ + { "akst", tZONE, HOUR( 9) }, /* Alaska Standard */ + { "akdt", tDAYZONE, HOUR( 9) }, /* Alaska Daylight */ + { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ + { "hast", tZONE, HOUR(10) }, /* Hawaii-Aleutian Standard */ + { "hadt", tDAYZONE, HOUR(10) }, /* Hawaii-Aleutian Daylight */ + { "ces", tDAYZONE, -HOUR(1) }, /* Central European Summer */ + { "cest", tDAYZONE, -HOUR(1) }, /* Central European Summer */ + { "mez", tZONE, -HOUR(1) }, /* Middle European */ + { "mezt", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ + { "cet", tZONE, -HOUR(1) }, /* Central European */ + { "met", tZONE, -HOUR(1) }, /* Middle European */ + { "eet", tZONE, -HOUR(2) }, /* Eastern Europe */ + { "msk", tZONE, -HOUR(3) }, /* Moscow Winter */ + { "msd", tDAYZONE, -HOUR(3) }, /* Moscow Summer */ + { "wast", tZONE, -HOUR(8) }, /* West Australian Standard */ + { "wadt", tDAYZONE, -HOUR(8) }, /* West Australian Daylight */ + { "hkt", tZONE, -HOUR(8) }, /* Hong Kong */ + { "cct", tZONE, -HOUR(8) }, /* China Coast */ + { "jst", tZONE, -HOUR(9) }, /* Japan Standard */ + { "kst", tZONE, -HOUR(9) }, /* Korean Standard */ + { "kdt", tZONE, -HOUR(9) }, /* Korean Daylight */ + { "cast", tZONE, -(HOUR(9)+30) }, /* Central Australian Standard */ + { "cadt", tDAYZONE, -(HOUR(9)+30) }, /* Central Australian Daylight */ + { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ + { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ + { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ + { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ + + /* For completeness we include the following entries. */ +#if 0 + + /* Duplicate names. Either they conflict with a zone listed above + * (which is either more likely to be seen or just been in circulation + * longer), or they conflict with another zone in this section and + * we could not reasonably choose one over the other. */ + { "fst", tZONE, HOUR( 2) }, /* Fernando De Noronha Standard */ + { "fdt", tDAYZONE, HOUR( 2) }, /* Fernando De Noronha Daylight */ + { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */ + { "est", tZONE, HOUR( 3) }, /* Eastern Standard (Brazil) */ + { "edt", tDAYZONE, HOUR( 3) }, /* Eastern Daylight (Brazil) */ + { "wst", tZONE, HOUR( 4) }, /* Western Standard (Brazil) */ + { "wdt", tDAYZONE, HOUR( 4) }, /* Western Daylight (Brazil) */ + { "cst", tZONE, HOUR( 5) }, /* Chile Standard */ + { "cdt", tDAYZONE, HOUR( 5) }, /* Chile Daylight */ + { "ast", tZONE, HOUR( 5) }, /* Acre Standard */ + { "adt", tDAYZONE, HOUR( 5) }, /* Acre Daylight */ + { "cst", tZONE, HOUR( 5) }, /* Cuba Standard */ + { "cdt", tDAYZONE, HOUR( 5) }, /* Cuba Daylight */ + { "est", tZONE, HOUR( 6) }, /* Easter Island Standard */ + { "edt", tDAYZONE, HOUR( 6) }, /* Easter Island Daylight */ + { "sst", tZONE, HOUR(11) }, /* Samoa Standard */ + { "ist", tZONE, -HOUR(2) }, /* Israel Standard */ + { "idt", tDAYZONE, -HOUR(2) }, /* Israel Daylight */ + { "idt", tDAYZONE, -(HOUR(3)+30) }, /* Iran Daylight */ + { "ist", tZONE, -(HOUR(3)+30) }, /* Iran Standard */ + { "cst", tZONE, -HOUR(8) }, /* China Standard */ + { "cdt", tDAYZONE, -HOUR(8) }, /* China Daylight */ + { "sst", tZONE, -HOUR(8) }, /* Singapore Standard */ + + /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */ + { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */ + { "wat", tZONE, -HOUR(1) }, /* West Africa */ + { "at", tZONE, HOUR( 2) }, /* Azores */ + { "gst", tZONE, -HOUR(10) }, /* Guam Standard */ + { "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */ + { "idlw", tZONE, HOUR(12) }, /* International Date Line West */ + { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ + { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ + { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ + { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ + { "fwt", tZONE, -HOUR(1) }, /* French Winter */ + { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ + { "bt", tZONE, -HOUR(3) }, /* Baghdad */ + { "it", tZONE, -(HOUR(3)+30) }, /* Iran */ + { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ + { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ + { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */ + { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ + { "nst", tZONE, -HOUR(7) }, /* North Sumatra */ + { "sst", tZONE, -HOUR(7) }, /* South Sumatra */ + { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */ + { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ + { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ + { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */ + { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */ + { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */ + { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */ +#endif /* 0 */ +}; - for (i=unittb; i->name; i++) - if (strcmp(i->name, idvar) == 0) - return gotit; + + +/* ARGSUSED */ +static void +date_error(s) + char *s; +{ + /* NOTREACHED */ +} + +int GetTimeInfo(TIMEINFO *Now) +{ + static time_t NextHour; + static long LastTzone; + struct tm *tm; + int secondsUntilNextHour; +#if defined(HAVE_GETTIMEOFDAY) + struct timeval tv; +#endif /* defined(HAVE_GETTIMEOFDAY) */ +#if !defined(HAVE_TM_GMTOFF) + struct tm local; + struct tm gmt; +#endif /* !defined(HAVE_TM_GMTOFF) */ + + /* Get the basic time. */ +#if defined(HAVE_GETTIMEOFDAY) + if (gettimeofday(&tv, (struct timezone *)NULL) == -1) + return -1; + Now->time = tv.tv_sec; + Now->usec = tv.tv_usec; +#else + /* Can't check for -1 since that might be a time, I guess. */ + (void)time(&Now->time); + Now->usec = 0; +#endif /* defined(HAVE_GETTIMEOFDAY) */ + + /* Now get the timezone if the last time < HH:00:00 <= now for some HH. */ + if (NextHour <= Now->time) { + if ((tm = localtime(&Now->time)) == NULL) + return -1; + secondsUntilNextHour = 60 * (60 - tm->tm_min) - tm->tm_sec; +#if !defined(HAVE_TM_GMTOFF) + /* To get the timezone, compare localtime with GMT. */ + local = *tm; + if ((tm = gmtime(&Now->time)) == NULL) + return -1; + gmt = *tm; + + /* Assume we are never more than 24 hours away. */ + LastTzone = gmt.tm_yday - local.tm_yday; + if (LastTzone > 1) + LastTzone = -24; + else if (LastTzone < -1) + LastTzone = 24; + else + LastTzone *= 24; + + /* Scale in the hours and minutes; ignore seconds. */ + LastTzone += gmt.tm_hour - local.tm_hour; + LastTzone *= 60; + LastTzone += gmt.tm_min - local.tm_min; +#else + LastTzone = (0 - tm->tm_gmtoff) / 60; +#endif /* defined(HAVE_TM_GMTOFF) */ + NextHour = Now->time + secondsUntilNextHour; + } + Now->tzone = LastTzone; + return 0; +} + + +static time_t +ToSeconds(Hours, Minutes, Seconds, Meridian) + time_t Hours; + time_t Minutes; + time_t Seconds; + MERIDIAN Meridian; +{ + if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61) + return -1; + if (Meridian == MER24) { + if (Hours < 0 || Hours > 23) + return -1; + } + else { + if (Hours < 1 || Hours > 12) + return -1; + if (Hours == 12) + Hours = 0; + if (Meridian == MERpm) + Hours += 12; + } + return (Hours * 60L + Minutes) * 60L + Seconds; +} - for (i = othertb; i->name; i++) - if (strcmp(i->name, idvar) == 0) - return gotit; - if (strlen(idvar) == 1 && isalpha((int)*idvar)) { - for (i = milzone; i->name; i++) - if (strcmp(i->name, idvar) == 0) - return gotit; +static time_t +Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, dst) + time_t Month; + time_t Day; + time_t Year; + time_t Hours; + time_t Minutes; + time_t Seconds; + MERIDIAN Meridian; + DSTMODE dst; +{ + static int DaysNormal[13] = { + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static int DaysLeap[13] = { + 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static int LeapYears[] = { + 1972, 1976, 1980, 1984, 1988, 1992, 1996, + 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036 + }; + int *yp; + int *mp; + time_t Julian; + int i; + time_t tod; + + /* Year should not be passed as a relative value, but absolute one. + so this should not happen, but just ensure it */ + if (Year < 0) + Year = -Year; + if (Year < 100) + Year += 1900; + if (Year < EPOCH) + Year += 100; + for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++) + if (Year == *yp) { + mp = DaysLeap; + break; } + if (Year < EPOCH || Year > END_OF_TIME + || Month < 1 || Month > 12 + /* NOSTRICT *//* conversion from long may lose accuracy */ + || Day < 1 || Day > mp[(int)Month]) + return -1; + + Julian = Day - 1 + (Year - EPOCH) * 365; + for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++) + if (Year <= *yp) + break; + for (i = 1; i < Month; i++) + Julian += *++mp; + Julian *= SECSPERDAY; + Julian += yyTimezone * 60L; + if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) + return -1; + Julian += tod; + tod = Julian; + if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst)) + Julian -= DST_OFFSET * 60 * 60; + return Julian; +} + - return ID; +static time_t +DSTcorrect(Start, Future) + time_t Start; + time_t Future; +{ + time_t StartDay; + time_t FutureDay; + + StartDay = (localtime(&Start)->tm_hour + 1) % 24; + FutureDay = (localtime(&Future)->tm_hour + 1) % 24; + return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60 * 60; } -static char *lptr; -static int yylex() +static time_t +RelativeMonth(Start, RelMonth) + time_t Start; + time_t RelMonth; { - extern int yylval; - int sign = 0; - register char c; - register char *p; - char idbuf[20]; - int pcnt; - - for (;;) { - while (isspace((int)*lptr)) - lptr++; - - if (isdigit((int)(c = *lptr)) || c == '-' || c == '+') { - if (c== '-' || c == '+') { - if (c=='-') sign = -1; - else sign = 1; - if (!isdigit((int)(*++lptr))) { - /* yylval = sign; return (UNUMBER); */ - return yylex(); /* skip the '-' sign */ - } - } - yylval = 0; - while (isdigit((int)(c = *lptr++))) - yylval = 10*yylval + c - '0'; - lptr--; - if (sign < 0) - yylval = -yylval; - if (sign != 0) - return SNUMBER; - else - return UNUMBER; - - } else if (isalpha((int)c)) { - p = idbuf; - while (isalpha((int)(c = *lptr++)) || c=='.') - if (p < &idbuf[sizeof(idbuf)-1]) *p++ = c; - *p = '\0'; - lptr--; - return (lookup(idbuf)); - } + struct tm *tm; + time_t Month; + time_t Year; + + tm = localtime(&Start); + Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; + Year = Month / 12; + Year += 1900; + Month = Month % 12 + 1; + return DSTcorrect(Start, + Convert(Month, (time_t)tm->tm_mday, Year, + (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, + MER24, DSTmaybe)); +} - else if (c == '(') { - pcnt = 0; - do { - c = *lptr++; - if (c == '\0') return(c); - else if (c == '(') pcnt++; - else if (c == ')') pcnt--; - } while (pcnt > 0); - } + +static int LookupWord(char *buff, int length) +{ + char *p; + STRING q; + TABLE *tp; + int c; + + p = buff; + c = p[0]; + + /* See if we have an abbreviation for a month. */ + if (length == 3 || (length == 4 && p[3] == '.')) + for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) { + q = tp->name; + if (c == q[0] && p[1] == q[1] && p[2] == q[2]) { + yylval.Number = tp->value; + return tp->type; + } + } + else + for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) + if (c == tp->name[0] && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + /* Try for a timezone. */ + for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) + if (c == tp->name[0] && p[1] == tp->name[1] + && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } - else return (*lptr++); + /* Try the units table. */ + for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) + if (c == tp->name[0] && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; } + + /* Strip off any plural and try the units table again. */ + if (--length > 0 && p[length] == 's') { + p[length] = '\0'; + for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) + if (c == tp->name[0] && strcmp(p, tp->name) == 0) { + p[length] = 's'; + yylval.Number = tp->value; + return tp->type; + } + p[length] = 's'; + } + length++; + + /* Drop out any periods. */ + for (p = buff, q = (STRING)buff; *q; q++) + if (*q != '.') + *p++ = *q; + *p = '\0'; + + /* Try the meridians. */ + if (buff[1] == 'm' && buff[2] == '\0') { + if (buff[0] == 'a') { + yylval.Meridian = MERam; + return tMERIDIAN; + } + if (buff[0] == 'p') { + yylval.Meridian = MERpm; + return tMERIDIAN; + } + } + + /* If we saw any periods, try the timezones again. */ + if (p - buff != length) { + c = buff[0]; + for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) + if (c == tp->name[0] && p[1] == tp->name[1] + && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + } + + /* Unknown word -- assume GMT timezone. */ + yylval.Number = 0; + return tZONE; } -static void yyerror(char *s) -{} -%} +static int date_lex(void) +{ + char c; + char *p; + char buff[20]; + int sign; + int i; + int nesting; + + for ( ; ; ) { + /* Get first character after the whitespace. */ + for ( ; ; ) { + while (CTYPE(isspace, (int)*yyInput)) + yyInput++; + c = *yyInput; + + /* Ignore RFC 822 comments, typically time zone names. */ + if (c != LPAREN) + break; + for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; ) + if (c == LPAREN) + nesting++; + else if (!IS7BIT(c) || c == '\0' || c == '\r' + || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c)))) + /* Lexical error: bad comment. */ + return '?'; + yyInput++; + } -%token ID -%token MONTH -%token DAY -%token MERIDIAN -%token SNUMBER -%token UNUMBER -%token UNIT -%token MUNIT -%token SUNIT -%token ZONE -%token DAYZONE -%token AGO + /* A number? */ + if (CTYPE(isdigit, (int)c) || c == '-' || c == '+') { + if (c == '-' || c == '+') { + sign = c == '-' ? -1 : 1; + yyInput++; + if (!CTYPE(isdigit, (int)*yyInput)) + /* Skip the plus or minus sign. */ + continue; + } + else + sign = 0; + for (i = 0; (c = *yyInput++) != '\0' && CTYPE(isdigit, (int)c); ) + i = 10 * i + c - '0'; + yyInput--; + yylval.Number = sign < 0 ? -i : i; + return sign ? tSNUMBER : tUNUMBER; + } -%% -timedate: /* empty */ - | timedate item -; - -item: tspec = - {timeflag++;} - | zone = - {zoneflag++;} - | dtspec = - {dateflag++;} - | dyspec = - {dayflag++;} - | rspec = - {relflag++;} - | nspec -; - -nspec: UNUMBER = - {if (timeflag && dateflag && !relflag) year = $1; - else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}} -; - -tspec: UNUMBER MERIDIAN = - {hh = $1; mm = 0; ss = 0; merid = $2;} - | UNUMBER ':' UNUMBER = - {hh = $1; mm = $3; merid = 24;} - | UNUMBER ':' UNUMBER MERIDIAN = - {hh = $1; mm = $3; merid = $4;} - | UNUMBER ':' UNUMBER SNUMBER = - {hh = $1; mm = $3; merid = 24; - daylight = STANDARD; ourzone = -($4%100 + 60*($4/100));} - | UNUMBER ':' UNUMBER ':' UNUMBER = - {hh = $1; mm = $3; ss = $5; merid = 24;} - | UNUMBER ':' UNUMBER ':' UNUMBER MERIDIAN = - {hh = $1; mm = $3; ss = $5; merid = $6;} - | UNUMBER ':' UNUMBER ':' UNUMBER SNUMBER = - {hh = $1; mm = $3; ss = $5; merid = 24; - daylight = STANDARD; ourzone = -($6%100 + 60*($6/100));} -; - -zone: ZONE = - {ourzone = $1; daylight = STANDARD;} - | DAYZONE = - {ourzone = $1; daylight = DAYLIGHT;} -; - -dyspec: DAY = - {dayord = 1; dayreq = $1;} - | DAY ',' = - {dayord = 1; dayreq = $1;} - | UNUMBER DAY = - {dayord = $1; dayreq = $2;} -; - -dtspec: UNUMBER '/' UNUMBER = - {month = $1; day = $3;} - | UNUMBER '/' UNUMBER '/' UNUMBER = - {month = $1; day = $3; year = $5;} - | MONTH UNUMBER = - {month = $1; day = $2;} - | MONTH UNUMBER ',' UNUMBER = - {month = $1; day = $2; year = $4;} - | UNUMBER MONTH = - {month = $2; day = $1;} - | UNUMBER MONTH UNUMBER = - {month = $2; day = $1; year = $3;} -; - -rspec: SNUMBER UNIT = - {relsec += 60L * $1 * $2;} - | UNUMBER UNIT = - {relsec += 60L * $1 * $2;} - | SNUMBER MUNIT = - {relmonth += $1 * $2;} - | UNUMBER MUNIT = - {relmonth += $1 * $2;} - | SNUMBER SUNIT = - {relsec += $1;} - | UNUMBER SUNIT = - {relsec += $1;} - | UNIT = - {relsec += 60L * $1;} - | MUNIT = - {relmonth += $1;} - | SUNIT = - {relsec++;} - | rspec AGO = - {relsec = -relsec; relmonth = -relmonth;} -; + /* A word? */ + if (CTYPE(isalpha, (int)c)) { + for (p = buff; (c = *yyInput++) == '.' || CTYPE(isalpha, (int)c); ) + if (p < &buff[sizeof buff - 1]) + *p++ = CTYPE(isupper, (int)c) ? tolower(c) : c; + *p = '\0'; + yyInput--; + return LookupWord(buff, p - buff); + } -%% + return *yyInput++; + } +} + -PHPAPI time_t -parsedate(p, now) -char *p; -struct timeval *now; +time_t parsedate(char *p, TIMEINFO *now) { -#define mcheck(f) if (f>1) err++ - int err; - struct tm *lt; - struct timeval ftz; - - time_t sdate, tod; - - lptr = p; - gettimeofday(&ftz, NULL); - if (now == ((struct timeval *) NULL)) { - now = &ftz; - } - lt = localtime(&now->tv_sec); - year = lt->tm_year; - month = lt->tm_mon+1; - day = lt->tm_mday; - relsec = 0; relmonth = 0; - timeflag=zoneflag=dateflag=dayflag=relflag=0; + extern int date_parse(); + struct tm *tm; + TIMEINFO ti; + time_t Start; + + yyInput = p; + if (now == NULL) { + now = &ti; + (void)GetTimeInfo(&ti); + } + + tm = localtime(&now->time); + yyYear = tm->tm_year + 1900; + yyMonth = tm->tm_mon + 1; + yyDay = tm->tm_mday; #ifdef HAVE_TM_GMTOFF - ourzone = lt->tm_gmtoff/60; + yyTimezone = now->tm_gmtoff/60; #else - ourzone = timezone/60; + yyTimezone = timezone/60; #endif - daylight = MAYBE; - hh = mm = ss = 0; - merid = 24; - - if (err = yyparse()) return (-1); - - mcheck(timeflag); - mcheck(zoneflag); - mcheck(dateflag); - mcheck(dayflag); - - if (err) return (-1); - if (dateflag || timeflag || dayflag) { - sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight); - if (sdate < 0) return -1; - } - else { - sdate = now->tv_sec; - if (relflag == 0) - sdate -= (lt->tm_sec + lt->tm_min*60 + - lt->tm_hour*(60L*60L)); - } - - sdate += relsec; - sdate += monthadd(sdate, relmonth); - - if (dayflag && !dateflag) { - tod = dayconv(dayord, dayreq, sdate); - sdate += tod; - } - - /* - ** Have to do *something* with a legitimate -1 so it's distinguishable - ** from the error return value. (Alternately could set errno on error.) - */ - return (sdate == -1) ? 0 : sdate; + yyDSTmode = DSTmaybe; + yyHour = 0; + yyMinutes = 0; + yySeconds = 0; + yyMeridian = MER24; + yyRelSeconds = 0; + yyRelMonth = 0; + yyHaveDate = 0; + yyHaveRel = 0; + yyHaveTime = 0; + + if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1) + return -1; + + if (yyHaveDate || yyHaveTime) { + Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, + yyMeridian, yyDSTmode); + if (Start < 0) + return -1; + } + else { + Start = now->time; + if (!yyHaveRel) + Start -= (tm->tm_hour * 60L + tm->tm_min) * 60L + tm->tm_sec; + } + + Start += yyRelSeconds; + if (yyRelMonth) + Start += RelativeMonth(Start, yyRelMonth); + + /* Have to do *something* with a legitimate -1 so it's distinguishable + * from the error return value. (Alternately could set errno on error.) */ + return Start == -1 ? 0 : Start; } - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */

« previous php.dev (#8418) next »