os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclGetDate.y
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclGetDate.y	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1159 @@
     1.4 +/* 
     1.5 + * tclGetDate.y --
     1.6 + *
     1.7 + *	Contains yacc grammar for parsing date and time strings.
     1.8 + *	The output of this file should be the file tclDate.c which
     1.9 + *	is used directly in the Tcl sources.
    1.10 + *
    1.11 + * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
    1.12 + * Copyright (c) 1995-1997 Sun Microsystems, Inc.
    1.13 + *
    1.14 + * See the file "license.terms" for information on usage and redistribution
    1.15 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    1.16 + *
    1.17 + * RCS: @(#) $Id: tclGetDate.y,v 1.18.4.2 2005/11/04 20:15:09 kennykb Exp $
    1.18 + */
    1.19 +
    1.20 +%{
    1.21 +/* 
    1.22 + * tclDate.c --
    1.23 + *
    1.24 + *	This file is generated from a yacc grammar defined in
    1.25 + *	the file tclGetDate.y.  It should not be edited directly.
    1.26 + *
    1.27 + * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
    1.28 + * Copyright (c) 1995-1997 Sun Microsystems, Inc.
    1.29 + *
    1.30 + * See the file "license.terms" for information on usage and redistribution
    1.31 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    1.32 + *
    1.33 + * SCCSID
    1.34 + */
    1.35 +
    1.36 +#include "tclInt.h"
    1.37 +#include "tclPort.h"
    1.38 +
    1.39 +#if defined(MAC_TCL) && !defined(TCL_MAC_USE_MSL_EPOCH)
    1.40 +#   define EPOCH           1904
    1.41 +#   define START_OF_TIME   1904
    1.42 +#   define END_OF_TIME     2039
    1.43 +#else
    1.44 +#   define EPOCH           1970
    1.45 +#   define START_OF_TIME   1902
    1.46 +#   define END_OF_TIME     2037
    1.47 +#endif
    1.48 +
    1.49 +/*
    1.50 + * The offset of tm_year of struct tm returned by localtime, gmtime, etc.
    1.51 + * I don't know how universal this is; K&R II, the NetBSD manpages, and
    1.52 + * ../compat/strftime.c all agree that tm_year is the year-1900.  However,
    1.53 + * some systems may have a different value.  This #define should be the
    1.54 + * same as in ../compat/strftime.c.
    1.55 + */
    1.56 +#define TM_YEAR_BASE 1900
    1.57 +
    1.58 +#define HOUR(x)         ((int) (60 * x))
    1.59 +#define SECSPERDAY      (24L * 60L * 60L)
    1.60 +#define IsLeapYear(x)   ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
    1.61 +
    1.62 +/*
    1.63 + *  An entry in the lexical lookup table.
    1.64 + */
    1.65 +typedef struct _TABLE {
    1.66 +    char        *name;
    1.67 +    int         type;
    1.68 +    time_t      value;
    1.69 +} TABLE;
    1.70 +
    1.71 +
    1.72 +/*
    1.73 + *  Daylight-savings mode:  on, off, or not yet known.
    1.74 + */
    1.75 +typedef enum _DSTMODE {
    1.76 +    DSTon, DSToff, DSTmaybe
    1.77 +} DSTMODE;
    1.78 +
    1.79 +/*
    1.80 + *  Meridian:  am, pm, or 24-hour style.
    1.81 + */
    1.82 +typedef enum _MERIDIAN {
    1.83 +    MERam, MERpm, MER24
    1.84 +} MERIDIAN;
    1.85 +
    1.86 +
    1.87 +/*
    1.88 + *  Global variables.  We could get rid of most of these by using a good
    1.89 + *  union as the yacc stack.  (This routine was originally written before
    1.90 + *  yacc had the %union construct.)  Maybe someday; right now we only use
    1.91 + *  the %union very rarely.
    1.92 + */
    1.93 +static char     *yyInput;
    1.94 +static DSTMODE  yyDSTmode;
    1.95 +static time_t   yyDayOrdinal;
    1.96 +static time_t   yyDayNumber;
    1.97 +static time_t   yyMonthOrdinal;
    1.98 +static int      yyHaveDate;
    1.99 +static int      yyHaveDay;
   1.100 +static int      yyHaveOrdinalMonth;
   1.101 +static int      yyHaveRel;
   1.102 +static int      yyHaveTime;
   1.103 +static int      yyHaveZone;
   1.104 +static time_t   yyTimezone;
   1.105 +static time_t   yyDay;
   1.106 +static time_t   yyHour;
   1.107 +static time_t   yyMinutes;
   1.108 +static time_t   yyMonth;
   1.109 +static time_t   yySeconds;
   1.110 +static time_t   yyYear;
   1.111 +static MERIDIAN yyMeridian;
   1.112 +static time_t   yyRelMonth;
   1.113 +static time_t   yyRelDay;
   1.114 +static time_t   yyRelSeconds;
   1.115 +static time_t  *yyRelPointer;
   1.116 +
   1.117 +/*
   1.118 + * Prototypes of internal functions.
   1.119 + */
   1.120 +static void	yyerror _ANSI_ARGS_((char *s));
   1.121 +static time_t	ToSeconds _ANSI_ARGS_((time_t Hours, time_t Minutes,
   1.122 +		    time_t Seconds, MERIDIAN Meridian));
   1.123 +static int	Convert _ANSI_ARGS_((time_t Month, time_t Day, time_t Year,
   1.124 +		    time_t Hours, time_t Minutes, time_t Seconds,
   1.125 +		    MERIDIAN Meridia, DSTMODE DSTmode, time_t *TimePtr));
   1.126 +static time_t	DSTcorrect _ANSI_ARGS_((time_t Start, time_t Future));
   1.127 +static time_t	NamedDay _ANSI_ARGS_((time_t Start, time_t DayOrdinal,
   1.128 +		    time_t DayNumber));
   1.129 +static time_t   NamedMonth _ANSI_ARGS_((time_t Start, time_t MonthOrdinal,
   1.130 +                    time_t MonthNumber));
   1.131 +static int	RelativeMonth _ANSI_ARGS_((time_t Start, time_t RelMonth,
   1.132 +		    time_t *TimePtr));
   1.133 +static int	RelativeDay _ANSI_ARGS_((time_t Start, time_t RelDay,
   1.134 +		    time_t *TimePtr));
   1.135 +static int	LookupWord _ANSI_ARGS_((char *buff));
   1.136 +static int	yylex _ANSI_ARGS_((void));
   1.137 +
   1.138 +int
   1.139 +yyparse _ANSI_ARGS_((void));
   1.140 +%}
   1.141 +
   1.142 +%union {
   1.143 +    time_t              Number;
   1.144 +    enum _MERIDIAN      Meridian;
   1.145 +}
   1.146 +
   1.147 +%token  tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
   1.148 +%token  tSTARDATE tSEC_UNIT tSNUMBER tUNUMBER tZONE tEPOCH tDST tISOBASE
   1.149 +%token  tDAY_UNIT tNEXT
   1.150 +
   1.151 +%type   <Number>        tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT tDST
   1.152 +%type   <Number>        tSEC_UNIT tSNUMBER tUNUMBER tZONE tISOBASE tDAY_UNIT
   1.153 +%type   <Number>        unit sign tNEXT tSTARDATE
   1.154 +%type   <Meridian>      tMERIDIAN o_merid
   1.155 +
   1.156 +%%
   1.157 +
   1.158 +spec    : /* NULL */
   1.159 +        | spec item
   1.160 +        ;
   1.161 +
   1.162 +item    : time {
   1.163 +            yyHaveTime++;
   1.164 +        }
   1.165 +        | zone {
   1.166 +            yyHaveZone++;
   1.167 +        }
   1.168 +        | date {
   1.169 +            yyHaveDate++;
   1.170 +        }
   1.171 +        | ordMonth {
   1.172 +            yyHaveOrdinalMonth++;
   1.173 +        }
   1.174 +        | day {
   1.175 +            yyHaveDay++;
   1.176 +        }
   1.177 +        | relspec {
   1.178 +            yyHaveRel++;
   1.179 +        }
   1.180 +        | iso {
   1.181 +	    yyHaveTime++;
   1.182 +	    yyHaveDate++;
   1.183 +	}
   1.184 +        | trek {
   1.185 +	    yyHaveTime++;
   1.186 +	    yyHaveDate++;
   1.187 +	    yyHaveRel++;
   1.188 +        }
   1.189 +        | number
   1.190 +        ;
   1.191 +
   1.192 +time    : tUNUMBER tMERIDIAN {
   1.193 +            yyHour = $1;
   1.194 +            yyMinutes = 0;
   1.195 +            yySeconds = 0;
   1.196 +            yyMeridian = $2;
   1.197 +        }
   1.198 +        | tUNUMBER ':' tUNUMBER o_merid {
   1.199 +            yyHour = $1;
   1.200 +            yyMinutes = $3;
   1.201 +            yySeconds = 0;
   1.202 +            yyMeridian = $4;
   1.203 +        }
   1.204 +        | tUNUMBER ':' tUNUMBER '-' tUNUMBER {
   1.205 +            yyHour = $1;
   1.206 +            yyMinutes = $3;
   1.207 +            yyMeridian = MER24;
   1.208 +            yyDSTmode = DSToff;
   1.209 +            yyTimezone = ($5 % 100 + ($5 / 100) * 60);
   1.210 +        }
   1.211 +        | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
   1.212 +            yyHour = $1;
   1.213 +            yyMinutes = $3;
   1.214 +            yySeconds = $5;
   1.215 +            yyMeridian = $6;
   1.216 +        }
   1.217 +        | tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER {
   1.218 +            yyHour = $1;
   1.219 +            yyMinutes = $3;
   1.220 +            yySeconds = $5;
   1.221 +            yyMeridian = MER24;
   1.222 +            yyDSTmode = DSToff;
   1.223 +            yyTimezone = ($7 % 100 + ($7 / 100) * 60);
   1.224 +        }
   1.225 +        ;
   1.226 +
   1.227 +zone    : tZONE tDST {
   1.228 +            yyTimezone = $1;
   1.229 +            yyDSTmode = DSTon;
   1.230 +        }
   1.231 +        | tZONE {
   1.232 +            yyTimezone = $1;
   1.233 +            yyDSTmode = DSToff;
   1.234 +        }
   1.235 +        | tDAYZONE {
   1.236 +            yyTimezone = $1;
   1.237 +            yyDSTmode = DSTon;
   1.238 +        }
   1.239 +        ;
   1.240 +
   1.241 +day     : tDAY {
   1.242 +            yyDayOrdinal = 1;
   1.243 +            yyDayNumber = $1;
   1.244 +        }
   1.245 +        | tDAY ',' {
   1.246 +            yyDayOrdinal = 1;
   1.247 +            yyDayNumber = $1;
   1.248 +        }
   1.249 +        | tUNUMBER tDAY {
   1.250 +            yyDayOrdinal = $1;
   1.251 +            yyDayNumber = $2;
   1.252 +        }
   1.253 +        | sign tUNUMBER tDAY {
   1.254 +            yyDayOrdinal = $1 * $2;
   1.255 +            yyDayNumber = $3;
   1.256 +        }
   1.257 +        | tNEXT tDAY {
   1.258 +            yyDayOrdinal = 2;
   1.259 +            yyDayNumber = $2;
   1.260 +        }
   1.261 +        ;
   1.262 +
   1.263 +date    : tUNUMBER '/' tUNUMBER {
   1.264 +            yyMonth = $1;
   1.265 +            yyDay = $3;
   1.266 +        }
   1.267 +        | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
   1.268 +            yyMonth = $1;
   1.269 +            yyDay = $3;
   1.270 +            yyYear = $5;
   1.271 +        }
   1.272 +        | tISOBASE {
   1.273 +	    yyYear = $1 / 10000;
   1.274 +	    yyMonth = ($1 % 10000)/100;
   1.275 +	    yyDay = $1 % 100;
   1.276 +	}
   1.277 +        | tUNUMBER '-' tMONTH '-' tUNUMBER {
   1.278 +	    yyDay = $1;
   1.279 +	    yyMonth = $3;
   1.280 +	    yyYear = $5;
   1.281 +	}
   1.282 +        | tUNUMBER '-' tUNUMBER '-' tUNUMBER {
   1.283 +            yyMonth = $3;
   1.284 +            yyDay = $5;
   1.285 +            yyYear = $1;
   1.286 +        }
   1.287 +        | tMONTH tUNUMBER {
   1.288 +            yyMonth = $1;
   1.289 +            yyDay = $2;
   1.290 +        }
   1.291 +        | tMONTH tUNUMBER ',' tUNUMBER {
   1.292 +            yyMonth = $1;
   1.293 +            yyDay = $2;
   1.294 +            yyYear = $4;
   1.295 +        }
   1.296 +        | tUNUMBER tMONTH {
   1.297 +            yyMonth = $2;
   1.298 +            yyDay = $1;
   1.299 +        }
   1.300 +        | tEPOCH {
   1.301 +	    yyMonth = 1;
   1.302 +	    yyDay = 1;
   1.303 +	    yyYear = EPOCH;
   1.304 +	}
   1.305 +        | tUNUMBER tMONTH tUNUMBER {
   1.306 +            yyMonth = $2;
   1.307 +            yyDay = $1;
   1.308 +            yyYear = $3;
   1.309 +        }
   1.310 +        ;
   1.311 +
   1.312 +ordMonth: tNEXT tMONTH {
   1.313 +	    yyMonthOrdinal = 1;
   1.314 +	    yyMonth = $2;
   1.315 +	}
   1.316 +        | tNEXT tUNUMBER tMONTH {
   1.317 +	    yyMonthOrdinal = $2;
   1.318 +	    yyMonth = $3;
   1.319 +	}
   1.320 +        ;
   1.321 +
   1.322 +iso     : tISOBASE tZONE tISOBASE {
   1.323 +            if ($2 != HOUR(- 7)) YYABORT;
   1.324 +	    yyYear = $1 / 10000;
   1.325 +	    yyMonth = ($1 % 10000)/100;
   1.326 +	    yyDay = $1 % 100;
   1.327 +	    yyHour = $3 / 10000;
   1.328 +	    yyMinutes = ($3 % 10000)/100;
   1.329 +	    yySeconds = $3 % 100;
   1.330 +        }
   1.331 +        | tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER {
   1.332 +            if ($2 != HOUR(- 7)) YYABORT;
   1.333 +	    yyYear = $1 / 10000;
   1.334 +	    yyMonth = ($1 % 10000)/100;
   1.335 +	    yyDay = $1 % 100;
   1.336 +	    yyHour = $3;
   1.337 +	    yyMinutes = $5;
   1.338 +	    yySeconds = $7;
   1.339 +        }
   1.340 +	| tISOBASE tISOBASE {
   1.341 +	    yyYear = $1 / 10000;
   1.342 +	    yyMonth = ($1 % 10000)/100;
   1.343 +	    yyDay = $1 % 100;
   1.344 +	    yyHour = $2 / 10000;
   1.345 +	    yyMinutes = ($2 % 10000)/100;
   1.346 +	    yySeconds = $2 % 100;
   1.347 +        }
   1.348 +        ;
   1.349 +
   1.350 +trek    : tSTARDATE tUNUMBER '.' tUNUMBER {
   1.351 +            /*
   1.352 +	     * Offset computed year by -377 so that the returned years will
   1.353 +	     * be in a range accessible with a 32 bit clock seconds value
   1.354 +	     */
   1.355 +            yyYear = $2/1000 + 2323 - 377;
   1.356 +            yyDay  = 1;
   1.357 +	    yyMonth = 1;
   1.358 +	    yyRelDay += (($2%1000)*(365 + IsLeapYear(yyYear)))/1000;
   1.359 +	    yyRelSeconds += $4 * 144 * 60;
   1.360 +        }
   1.361 +        ;
   1.362 +
   1.363 +relspec : relunits tAGO {
   1.364 +	    yyRelSeconds *= -1;
   1.365 +	    yyRelMonth *= -1;
   1.366 +	    yyRelDay *= -1;
   1.367 +	}
   1.368 +	| relunits
   1.369 +	;
   1.370 +relunits : sign tUNUMBER unit  { *yyRelPointer += $1 * $2 * $3; }
   1.371 +        | tUNUMBER unit        { *yyRelPointer += $1 * $2; }
   1.372 +        | tNEXT unit           { *yyRelPointer += $2; }
   1.373 +        | tNEXT tUNUMBER unit  { *yyRelPointer += $2 * $3; }
   1.374 +        | unit                 { *yyRelPointer += $1; }
   1.375 +        ;
   1.376 +sign    : '-'            { $$ = -1; }
   1.377 +        | '+'            { $$ =  1; }
   1.378 +        ;
   1.379 +unit    : tSEC_UNIT      { $$ = $1; yyRelPointer = &yyRelSeconds; }
   1.380 +        | tDAY_UNIT      { $$ = $1; yyRelPointer = &yyRelDay; }
   1.381 +        | tMONTH_UNIT    { $$ = $1; yyRelPointer = &yyRelMonth; }
   1.382 +        ;
   1.383 +
   1.384 +number  : tUNUMBER
   1.385 +    {
   1.386 +	if (yyHaveTime && yyHaveDate && !yyHaveRel) {
   1.387 +	    yyYear = $1;
   1.388 +	} else {
   1.389 +	    yyHaveTime++;
   1.390 +	    if ($1 < 100) {
   1.391 +		yyHour = $1;
   1.392 +		yyMinutes = 0;
   1.393 +	    } else {
   1.394 +		yyHour = $1 / 100;
   1.395 +		yyMinutes = $1 % 100;
   1.396 +	    }
   1.397 +	    yySeconds = 0;
   1.398 +	    yyMeridian = MER24;
   1.399 +	}
   1.400 +    }
   1.401 +;
   1.402 +
   1.403 +o_merid : /* NULL */ {
   1.404 +            $$ = MER24;
   1.405 +        }
   1.406 +        | tMERIDIAN {
   1.407 +            $$ = $1;
   1.408 +        }
   1.409 +        ;
   1.410 +
   1.411 +%%
   1.412 +
   1.413 +/*
   1.414 + * Month and day table.
   1.415 + */
   1.416 +static TABLE    MonthDayTable[] = {
   1.417 +    { "january",        tMONTH,  1 },
   1.418 +    { "february",       tMONTH,  2 },
   1.419 +    { "march",          tMONTH,  3 },
   1.420 +    { "april",          tMONTH,  4 },
   1.421 +    { "may",            tMONTH,  5 },
   1.422 +    { "june",           tMONTH,  6 },
   1.423 +    { "july",           tMONTH,  7 },
   1.424 +    { "august",         tMONTH,  8 },
   1.425 +    { "september",      tMONTH,  9 },
   1.426 +    { "sept",           tMONTH,  9 },
   1.427 +    { "october",        tMONTH, 10 },
   1.428 +    { "november",       tMONTH, 11 },
   1.429 +    { "december",       tMONTH, 12 },
   1.430 +    { "sunday",         tDAY, 0 },
   1.431 +    { "monday",         tDAY, 1 },
   1.432 +    { "tuesday",        tDAY, 2 },
   1.433 +    { "tues",           tDAY, 2 },
   1.434 +    { "wednesday",      tDAY, 3 },
   1.435 +    { "wednes",         tDAY, 3 },
   1.436 +    { "thursday",       tDAY, 4 },
   1.437 +    { "thur",           tDAY, 4 },
   1.438 +    { "thurs",          tDAY, 4 },
   1.439 +    { "friday",         tDAY, 5 },
   1.440 +    { "saturday",       tDAY, 6 },
   1.441 +    { NULL }
   1.442 +};
   1.443 +
   1.444 +/*
   1.445 + * Time units table.
   1.446 + */
   1.447 +static TABLE    UnitsTable[] = {
   1.448 +    { "year",           tMONTH_UNIT,    12 },
   1.449 +    { "month",          tMONTH_UNIT,     1 },
   1.450 +    { "fortnight",      tDAY_UNIT,      14 },
   1.451 +    { "week",           tDAY_UNIT,       7 },
   1.452 +    { "day",            tDAY_UNIT,       1 },
   1.453 +    { "hour",           tSEC_UNIT, 60 * 60 },
   1.454 +    { "minute",         tSEC_UNIT,      60 },
   1.455 +    { "min",            tSEC_UNIT,      60 },
   1.456 +    { "second",         tSEC_UNIT,       1 },
   1.457 +    { "sec",            tSEC_UNIT,       1 },
   1.458 +    { NULL }
   1.459 +};
   1.460 +
   1.461 +/*
   1.462 + * Assorted relative-time words.
   1.463 + */
   1.464 +static TABLE    OtherTable[] = {
   1.465 +    { "tomorrow",       tDAY_UNIT,      1 },
   1.466 +    { "yesterday",      tDAY_UNIT,     -1 },
   1.467 +    { "today",          tDAY_UNIT,      0 },
   1.468 +    { "now",            tSEC_UNIT,      0 },
   1.469 +    { "last",           tUNUMBER,      -1 },
   1.470 +    { "this",           tSEC_UNIT,      0 },
   1.471 +    { "next",           tNEXT,          1 },
   1.472 +#if 0
   1.473 +    { "first",          tUNUMBER,       1 },
   1.474 +    { "second",         tUNUMBER,       2 },
   1.475 +    { "third",          tUNUMBER,       3 },
   1.476 +    { "fourth",         tUNUMBER,       4 },
   1.477 +    { "fifth",          tUNUMBER,       5 },
   1.478 +    { "sixth",          tUNUMBER,       6 },
   1.479 +    { "seventh",        tUNUMBER,       7 },
   1.480 +    { "eighth",         tUNUMBER,       8 },
   1.481 +    { "ninth",          tUNUMBER,       9 },
   1.482 +    { "tenth",          tUNUMBER,       10 },
   1.483 +    { "eleventh",       tUNUMBER,       11 },
   1.484 +    { "twelfth",        tUNUMBER,       12 },
   1.485 +#endif
   1.486 +    { "ago",            tAGO,   1 },
   1.487 +    { "epoch",          tEPOCH,   0 },
   1.488 +    { "stardate",       tSTARDATE, 0},
   1.489 +    { NULL }
   1.490 +};
   1.491 +
   1.492 +/*
   1.493 + * The timezone table.  (Note: This table was modified to not use any floating
   1.494 + * point constants to work around an SGI compiler bug).
   1.495 + */
   1.496 +static TABLE    TimezoneTable[] = {
   1.497 +    { "gmt",    tZONE,     HOUR( 0) },      /* Greenwich Mean */
   1.498 +    { "ut",     tZONE,     HOUR( 0) },      /* Universal (Coordinated) */
   1.499 +    { "utc",    tZONE,     HOUR( 0) },
   1.500 +    { "uct",    tZONE,     HOUR( 0) },      /* Universal Coordinated Time */
   1.501 +    { "wet",    tZONE,     HOUR( 0) },      /* Western European */
   1.502 +    { "bst",    tDAYZONE,  HOUR( 0) },      /* British Summer */
   1.503 +    { "wat",    tZONE,     HOUR( 1) },      /* West Africa */
   1.504 +    { "at",     tZONE,     HOUR( 2) },      /* Azores */
   1.505 +#if     0
   1.506 +    /* For completeness.  BST is also British Summer, and GST is
   1.507 +     * also Guam Standard. */
   1.508 +    { "bst",    tZONE,     HOUR( 3) },      /* Brazil Standard */
   1.509 +    { "gst",    tZONE,     HOUR( 3) },      /* Greenland Standard */
   1.510 +#endif
   1.511 +    { "nft",    tZONE,     HOUR( 7/2) },    /* Newfoundland */
   1.512 +    { "nst",    tZONE,     HOUR( 7/2) },    /* Newfoundland Standard */
   1.513 +    { "ndt",    tDAYZONE,  HOUR( 7/2) },    /* Newfoundland Daylight */
   1.514 +    { "ast",    tZONE,     HOUR( 4) },      /* Atlantic Standard */
   1.515 +    { "adt",    tDAYZONE,  HOUR( 4) },      /* Atlantic Daylight */
   1.516 +    { "est",    tZONE,     HOUR( 5) },      /* Eastern Standard */
   1.517 +    { "edt",    tDAYZONE,  HOUR( 5) },      /* Eastern Daylight */
   1.518 +    { "cst",    tZONE,     HOUR( 6) },      /* Central Standard */
   1.519 +    { "cdt",    tDAYZONE,  HOUR( 6) },      /* Central Daylight */
   1.520 +    { "mst",    tZONE,     HOUR( 7) },      /* Mountain Standard */
   1.521 +    { "mdt",    tDAYZONE,  HOUR( 7) },      /* Mountain Daylight */
   1.522 +    { "pst",    tZONE,     HOUR( 8) },      /* Pacific Standard */
   1.523 +    { "pdt",    tDAYZONE,  HOUR( 8) },      /* Pacific Daylight */
   1.524 +    { "yst",    tZONE,     HOUR( 9) },      /* Yukon Standard */
   1.525 +    { "ydt",    tDAYZONE,  HOUR( 9) },      /* Yukon Daylight */
   1.526 +    { "hst",    tZONE,     HOUR(10) },      /* Hawaii Standard */
   1.527 +    { "hdt",    tDAYZONE,  HOUR(10) },      /* Hawaii Daylight */
   1.528 +    { "cat",    tZONE,     HOUR(10) },      /* Central Alaska */
   1.529 +    { "ahst",   tZONE,     HOUR(10) },      /* Alaska-Hawaii Standard */
   1.530 +    { "nt",     tZONE,     HOUR(11) },      /* Nome */
   1.531 +    { "idlw",   tZONE,     HOUR(12) },      /* International Date Line West */
   1.532 +    { "cet",    tZONE,    -HOUR( 1) },      /* Central European */
   1.533 +    { "cest",   tDAYZONE, -HOUR( 1) },      /* Central European Summer */
   1.534 +    { "met",    tZONE,    -HOUR( 1) },      /* Middle European */
   1.535 +    { "mewt",   tZONE,    -HOUR( 1) },      /* Middle European Winter */
   1.536 +    { "mest",   tDAYZONE, -HOUR( 1) },      /* Middle European Summer */
   1.537 +    { "swt",    tZONE,    -HOUR( 1) },      /* Swedish Winter */
   1.538 +    { "sst",    tDAYZONE, -HOUR( 1) },      /* Swedish Summer */
   1.539 +    { "fwt",    tZONE,    -HOUR( 1) },      /* French Winter */
   1.540 +    { "fst",    tDAYZONE, -HOUR( 1) },      /* French Summer */
   1.541 +    { "eet",    tZONE,    -HOUR( 2) },      /* Eastern Europe, USSR Zone 1 */
   1.542 +    { "bt",     tZONE,    -HOUR( 3) },      /* Baghdad, USSR Zone 2 */
   1.543 +    { "it",     tZONE,    -HOUR( 7/2) },    /* Iran */
   1.544 +    { "zp4",    tZONE,    -HOUR( 4) },      /* USSR Zone 3 */
   1.545 +    { "zp5",    tZONE,    -HOUR( 5) },      /* USSR Zone 4 */
   1.546 +    { "ist",    tZONE,    -HOUR(11/2) },    /* Indian Standard */
   1.547 +    { "zp6",    tZONE,    -HOUR( 6) },      /* USSR Zone 5 */
   1.548 +#if     0
   1.549 +    /* For completeness.  NST is also Newfoundland Stanard, nad SST is
   1.550 +     * also Swedish Summer. */
   1.551 +    { "nst",    tZONE,    -HOUR(13/2) },    /* North Sumatra */
   1.552 +    { "sst",    tZONE,    -HOUR( 7) },      /* South Sumatra, USSR Zone 6 */
   1.553 +#endif  /* 0 */
   1.554 +    { "wast",   tZONE,    -HOUR( 7) },      /* West Australian Standard */
   1.555 +    { "wadt",   tDAYZONE, -HOUR( 7) },      /* West Australian Daylight */
   1.556 +    { "jt",     tZONE,    -HOUR(15/2) },    /* Java (3pm in Cronusland!) */
   1.557 +    { "cct",    tZONE,    -HOUR( 8) },      /* China Coast, USSR Zone 7 */
   1.558 +    { "jst",    tZONE,    -HOUR( 9) },      /* Japan Standard, USSR Zone 8 */
   1.559 +    { "jdt",    tDAYZONE, -HOUR( 9) },      /* Japan Daylight */
   1.560 +    { "kst",    tZONE,    -HOUR( 9) },      /* Korea Standard */
   1.561 +    { "kdt",    tDAYZONE, -HOUR( 9) },      /* Korea Daylight */
   1.562 +    { "cast",   tZONE,    -HOUR(19/2) },    /* Central Australian Standard */
   1.563 +    { "cadt",   tDAYZONE, -HOUR(19/2) },    /* Central Australian Daylight */
   1.564 +    { "east",   tZONE,    -HOUR(10) },      /* Eastern Australian Standard */
   1.565 +    { "eadt",   tDAYZONE, -HOUR(10) },      /* Eastern Australian Daylight */
   1.566 +    { "gst",    tZONE,    -HOUR(10) },      /* Guam Standard, USSR Zone 9 */
   1.567 +    { "nzt",    tZONE,    -HOUR(12) },      /* New Zealand */
   1.568 +    { "nzst",   tZONE,    -HOUR(12) },      /* New Zealand Standard */
   1.569 +    { "nzdt",   tDAYZONE, -HOUR(12) },      /* New Zealand Daylight */
   1.570 +    { "idle",   tZONE,    -HOUR(12) },      /* International Date Line East */
   1.571 +    /* ADDED BY Marco Nijdam */
   1.572 +    { "dst",    tDST,     HOUR( 0) },       /* DST on (hour is ignored) */
   1.573 +    /* End ADDED */
   1.574 +    {  NULL  }
   1.575 +};
   1.576 +
   1.577 +/*
   1.578 + * Military timezone table.
   1.579 + */
   1.580 +static TABLE    MilitaryTable[] = {
   1.581 +    { "a",      tZONE,  HOUR(  1) },
   1.582 +    { "b",      tZONE,  HOUR(  2) },
   1.583 +    { "c",      tZONE,  HOUR(  3) },
   1.584 +    { "d",      tZONE,  HOUR(  4) },
   1.585 +    { "e",      tZONE,  HOUR(  5) },
   1.586 +    { "f",      tZONE,  HOUR(  6) },
   1.587 +    { "g",      tZONE,  HOUR(  7) },
   1.588 +    { "h",      tZONE,  HOUR(  8) },
   1.589 +    { "i",      tZONE,  HOUR(  9) },
   1.590 +    { "k",      tZONE,  HOUR( 10) },
   1.591 +    { "l",      tZONE,  HOUR( 11) },
   1.592 +    { "m",      tZONE,  HOUR( 12) },
   1.593 +    { "n",      tZONE,  HOUR(- 1) },
   1.594 +    { "o",      tZONE,  HOUR(- 2) },
   1.595 +    { "p",      tZONE,  HOUR(- 3) },
   1.596 +    { "q",      tZONE,  HOUR(- 4) },
   1.597 +    { "r",      tZONE,  HOUR(- 5) },
   1.598 +    { "s",      tZONE,  HOUR(- 6) },
   1.599 +    { "t",      tZONE,  HOUR(- 7) },
   1.600 +    { "u",      tZONE,  HOUR(- 8) },
   1.601 +    { "v",      tZONE,  HOUR(- 9) },
   1.602 +    { "w",      tZONE,  HOUR(-10) },
   1.603 +    { "x",      tZONE,  HOUR(-11) },
   1.604 +    { "y",      tZONE,  HOUR(-12) },
   1.605 +    { "z",      tZONE,  HOUR(  0) },
   1.606 +    { NULL }
   1.607 +};
   1.608 +
   1.609 +
   1.610 +/*
   1.611 + * Dump error messages in the bit bucket.
   1.612 + */
   1.613 +static void
   1.614 +yyerror(s)
   1.615 +    char  *s;
   1.616 +{
   1.617 +}
   1.618 +
   1.619 +
   1.620 +static time_t
   1.621 +ToSeconds(Hours, Minutes, Seconds, Meridian)
   1.622 +    time_t      Hours;
   1.623 +    time_t      Minutes;
   1.624 +    time_t      Seconds;
   1.625 +    MERIDIAN    Meridian;
   1.626 +{
   1.627 +    if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
   1.628 +        return -1;
   1.629 +    switch (Meridian) {
   1.630 +    case MER24:
   1.631 +        if (Hours < 0 || Hours > 23)
   1.632 +            return -1;
   1.633 +        return (Hours * 60L + Minutes) * 60L + Seconds;
   1.634 +    case MERam:
   1.635 +        if (Hours < 1 || Hours > 12)
   1.636 +            return -1;
   1.637 +        return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
   1.638 +    case MERpm:
   1.639 +        if (Hours < 1 || Hours > 12)
   1.640 +            return -1;
   1.641 +        return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
   1.642 +    }
   1.643 +    return -1;  /* Should never be reached */
   1.644 +}
   1.645 +
   1.646 +/*
   1.647 + *-----------------------------------------------------------------------------
   1.648 + *
   1.649 + * Convert --
   1.650 + *
   1.651 + *      Convert a {month, day, year, hours, minutes, seconds, meridian, dst}
   1.652 + *      tuple into a clock seconds value.
   1.653 + *
   1.654 + * Results:
   1.655 + *      0 or -1 indicating success or failure.
   1.656 + *
   1.657 + * Side effects:
   1.658 + *      Fills TimePtr with the computed value.
   1.659 + *
   1.660 + *-----------------------------------------------------------------------------
   1.661 + */
   1.662 +static int
   1.663 +Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode, TimePtr)
   1.664 +    time_t      Month;
   1.665 +    time_t      Day;
   1.666 +    time_t      Year;
   1.667 +    time_t      Hours;
   1.668 +    time_t      Minutes;
   1.669 +    time_t      Seconds;
   1.670 +    MERIDIAN    Meridian;
   1.671 +    DSTMODE     DSTmode;
   1.672 +    time_t     *TimePtr;
   1.673 +{
   1.674 +    static int  DaysInMonth[12] = {
   1.675 +        31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
   1.676 +    };
   1.677 +    time_t tod;
   1.678 +    time_t Julian;
   1.679 +    int i;
   1.680 +
   1.681 +    /* Figure out how many days are in February for the given year.
   1.682 +     * Every year divisible by 4 is a leap year.
   1.683 +     * But, every year divisible by 100 is not a leap year.
   1.684 +     * But, every year divisible by 400 is a leap year after all.
   1.685 +     */
   1.686 +    DaysInMonth[1] = IsLeapYear(Year) ? 29 : 28;
   1.687 +
   1.688 +    /* Check the inputs for validity */
   1.689 +    if (Month < 1 || Month > 12
   1.690 +	    || Year < START_OF_TIME || Year > END_OF_TIME
   1.691 +	    || Day < 1 || Day > DaysInMonth[(int)--Month])
   1.692 +        return -1;
   1.693 +
   1.694 +    /* Start computing the value.  First determine the number of days
   1.695 +     * represented by the date, then multiply by the number of seconds/day.
   1.696 +     */
   1.697 +    for (Julian = Day - 1, i = 0; i < Month; i++)
   1.698 +        Julian += DaysInMonth[i];
   1.699 +    if (Year >= EPOCH) {
   1.700 +        for (i = EPOCH; i < Year; i++)
   1.701 +            Julian += 365 + IsLeapYear(i);
   1.702 +    } else {
   1.703 +        for (i = Year; i < EPOCH; i++)
   1.704 +            Julian -= 365 + IsLeapYear(i);
   1.705 +    }
   1.706 +    Julian *= SECSPERDAY;
   1.707 +
   1.708 +    /* Add the timezone offset ?? */
   1.709 +    Julian += yyTimezone * 60L;
   1.710 +
   1.711 +    /* Add the number of seconds represented by the time component */
   1.712 +    if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
   1.713 +        return -1;
   1.714 +    Julian += tod;
   1.715 +
   1.716 +    /* Perform a preliminary DST compensation ?? */
   1.717 +    if (DSTmode == DSTon
   1.718 +     || (DSTmode == DSTmaybe && TclpGetDate((TclpTime_t)&Julian, 0)->tm_isdst))
   1.719 +        Julian -= 60 * 60;
   1.720 +    *TimePtr = Julian;
   1.721 +    return 0;
   1.722 +}
   1.723 +
   1.724 +
   1.725 +static time_t
   1.726 +DSTcorrect(Start, Future)
   1.727 +    time_t      Start;
   1.728 +    time_t      Future;
   1.729 +{
   1.730 +    time_t      StartDay;
   1.731 +    time_t      FutureDay;
   1.732 +    StartDay = (TclpGetDate((TclpTime_t)&Start, 0)->tm_hour + 1) % 24;
   1.733 +    FutureDay = (TclpGetDate((TclpTime_t)&Future, 0)->tm_hour + 1) % 24;
   1.734 +    return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
   1.735 +}
   1.736 +
   1.737 +
   1.738 +static time_t
   1.739 +NamedDay(Start, DayOrdinal, DayNumber)
   1.740 +    time_t      Start;
   1.741 +    time_t      DayOrdinal;
   1.742 +    time_t      DayNumber;
   1.743 +{
   1.744 +    struct tm   *tm;
   1.745 +    time_t      now;
   1.746 +
   1.747 +    now = Start;
   1.748 +    tm = TclpGetDate((TclpTime_t)&now, 0);
   1.749 +    now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
   1.750 +    now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
   1.751 +    return DSTcorrect(Start, now);
   1.752 +}
   1.753 +
   1.754 +static time_t
   1.755 +NamedMonth(Start, MonthOrdinal, MonthNumber)
   1.756 +    time_t Start;
   1.757 +    time_t MonthOrdinal;
   1.758 +    time_t MonthNumber;
   1.759 +{
   1.760 +    struct tm *tm;
   1.761 +    time_t now;
   1.762 +    int result;
   1.763 +    
   1.764 +    now = Start;
   1.765 +    tm = TclpGetDate((TclpTime_t)&now, 0);
   1.766 +    /* To compute the next n'th month, we use this alg:
   1.767 +     * add n to year value
   1.768 +     * if currentMonth < requestedMonth decrement year value by 1 (so that
   1.769 +     *  doing next february from january gives us february of the current year)
   1.770 +     * set day to 1, time to 0
   1.771 +     */
   1.772 +    tm->tm_year += MonthOrdinal;
   1.773 +    if (tm->tm_mon < MonthNumber - 1) {
   1.774 +	tm->tm_year--;
   1.775 +    }
   1.776 +    result = Convert(MonthNumber, (time_t) 1, tm->tm_year + TM_YEAR_BASE,
   1.777 +	    (time_t) 0, (time_t) 0, (time_t) 0, MER24, DSTmaybe, &now);
   1.778 +    if (result < 0) {
   1.779 +	return 0;
   1.780 +    }
   1.781 +    return DSTcorrect(Start, now);
   1.782 +}
   1.783 +
   1.784 +static int
   1.785 +RelativeMonth(Start, RelMonth, TimePtr)
   1.786 +    time_t Start;
   1.787 +    time_t RelMonth;
   1.788 +    time_t *TimePtr;
   1.789 +{
   1.790 +    struct tm *tm;
   1.791 +    time_t Month;
   1.792 +    time_t Year;
   1.793 +    time_t Julian;
   1.794 +    int result;
   1.795 +
   1.796 +    if (RelMonth == 0) {
   1.797 +        *TimePtr = 0;
   1.798 +        return 0;
   1.799 +    }
   1.800 +    tm = TclpGetDate((TclpTime_t)&Start, 0);
   1.801 +    Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
   1.802 +    Year = Month / 12;
   1.803 +    Month = Month % 12 + 1;
   1.804 +    result = Convert(Month, (time_t) tm->tm_mday, Year,
   1.805 +	    (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
   1.806 +	    MER24, DSTmaybe, &Julian);
   1.807 +
   1.808 +    /*
   1.809 +     * The Julian time returned above is behind by one day, if "month" 
   1.810 +     * or "year" is used to specify relative time and the GMT flag is true.
   1.811 +     * This problem occurs only when the current time is closer to
   1.812 +     * midnight, the difference being not more than its time difference
   1.813 +     * with GMT. For example, in US/Pacific time zone, the problem occurs
   1.814 +     * whenever the current time is between midnight to 8:00am or 7:00amDST.
   1.815 +     * See Bug# 413397 for more details and sample script.
   1.816 +     * To resolve this bug, we simply add the number of seconds corresponding
   1.817 +     * to timezone difference with GMT to Julian time, if GMT flag is true.
   1.818 +     */
   1.819 +
   1.820 +    if (TclDateTimezone == 0) {
   1.821 +        Julian += TclpGetTimeZone((unsigned long) Start) * 60L;
   1.822 +    }
   1.823 +
   1.824 +    /*
   1.825 +     * The following iteration takes into account the case were we jump
   1.826 +     * into a "short month".  Far example, "one month from Jan 31" will
   1.827 +     * fail because there is no Feb 31.  The code below will reduce the
   1.828 +     * day and try converting the date until we succed or the date equals
   1.829 +     * 28 (which always works unless the date is bad in another way).
   1.830 +     */
   1.831 +
   1.832 +    while ((result != 0) && (tm->tm_mday > 28)) {
   1.833 +	tm->tm_mday--;
   1.834 +	result = Convert(Month, (time_t) tm->tm_mday, Year,
   1.835 +		(time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
   1.836 +		MER24, DSTmaybe, &Julian);
   1.837 +    }
   1.838 +    if (result != 0) {
   1.839 +	return -1;
   1.840 +    }
   1.841 +    *TimePtr = DSTcorrect(Start, Julian);
   1.842 +    return 0;
   1.843 +}
   1.844 +
   1.845 +
   1.846 +/*
   1.847 + *-----------------------------------------------------------------------------
   1.848 + *
   1.849 + * RelativeDay --
   1.850 + *
   1.851 + *      Given a starting time and a number of days before or after, compute the
   1.852 + *      DST corrected difference between those dates.
   1.853 + *
   1.854 + * Results:
   1.855 + *     1 or -1 indicating success or failure.
   1.856 + *
   1.857 + * Side effects:
   1.858 + *      Fills TimePtr with the computed value.
   1.859 + *
   1.860 + *-----------------------------------------------------------------------------
   1.861 + */
   1.862 +
   1.863 +static int
   1.864 +RelativeDay(Start, RelDay, TimePtr)
   1.865 +    time_t Start;
   1.866 +    time_t RelDay;
   1.867 +    time_t *TimePtr;
   1.868 +{
   1.869 +    time_t new;
   1.870 +
   1.871 +    new = Start + (RelDay * 60 * 60 * 24);
   1.872 +    *TimePtr = DSTcorrect(Start, new);
   1.873 +    return 1;
   1.874 +}
   1.875 +
   1.876 +static int
   1.877 +LookupWord(buff)
   1.878 +    char                *buff;
   1.879 +{
   1.880 +    register char *p;
   1.881 +    register char *q;
   1.882 +    register TABLE *tp;
   1.883 +    int i;
   1.884 +    int abbrev;
   1.885 +
   1.886 +    /*
   1.887 +     * Make it lowercase.
   1.888 +     */
   1.889 +
   1.890 +    Tcl_UtfToLower(buff);
   1.891 +
   1.892 +    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
   1.893 +        yylval.Meridian = MERam;
   1.894 +        return tMERIDIAN;
   1.895 +    }
   1.896 +    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
   1.897 +        yylval.Meridian = MERpm;
   1.898 +        return tMERIDIAN;
   1.899 +    }
   1.900 +
   1.901 +    /*
   1.902 +     * See if we have an abbreviation for a month.
   1.903 +     */
   1.904 +    if (strlen(buff) == 3) {
   1.905 +        abbrev = 1;
   1.906 +    } else if (strlen(buff) == 4 && buff[3] == '.') {
   1.907 +        abbrev = 1;
   1.908 +        buff[3] = '\0';
   1.909 +    } else {
   1.910 +        abbrev = 0;
   1.911 +    }
   1.912 +
   1.913 +    for (tp = MonthDayTable; tp->name; tp++) {
   1.914 +        if (abbrev) {
   1.915 +            if (strncmp(buff, tp->name, 3) == 0) {
   1.916 +                yylval.Number = tp->value;
   1.917 +                return tp->type;
   1.918 +            }
   1.919 +        } else if (strcmp(buff, tp->name) == 0) {
   1.920 +            yylval.Number = tp->value;
   1.921 +            return tp->type;
   1.922 +        }
   1.923 +    }
   1.924 +
   1.925 +    for (tp = TimezoneTable; tp->name; tp++) {
   1.926 +        if (strcmp(buff, tp->name) == 0) {
   1.927 +            yylval.Number = tp->value;
   1.928 +            return tp->type;
   1.929 +        }
   1.930 +    }
   1.931 +
   1.932 +    for (tp = UnitsTable; tp->name; tp++) {
   1.933 +        if (strcmp(buff, tp->name) == 0) {
   1.934 +            yylval.Number = tp->value;
   1.935 +            return tp->type;
   1.936 +        }
   1.937 +    }
   1.938 +
   1.939 +    /*
   1.940 +     * Strip off any plural and try the units table again.
   1.941 +     */
   1.942 +    i = strlen(buff) - 1;
   1.943 +    if (buff[i] == 's') {
   1.944 +        buff[i] = '\0';
   1.945 +        for (tp = UnitsTable; tp->name; tp++) {
   1.946 +            if (strcmp(buff, tp->name) == 0) {
   1.947 +                yylval.Number = tp->value;
   1.948 +                return tp->type;
   1.949 +            }
   1.950 +	}
   1.951 +    }
   1.952 +
   1.953 +    for (tp = OtherTable; tp->name; tp++) {
   1.954 +        if (strcmp(buff, tp->name) == 0) {
   1.955 +            yylval.Number = tp->value;
   1.956 +            return tp->type;
   1.957 +        }
   1.958 +    }
   1.959 +
   1.960 +    /*
   1.961 +     * Military timezones.
   1.962 +     */
   1.963 +    if (buff[1] == '\0' && !(*buff & 0x80)
   1.964 +	    && isalpha(UCHAR(*buff))) {	/* INTL: ISO only */
   1.965 +        for (tp = MilitaryTable; tp->name; tp++) {
   1.966 +            if (strcmp(buff, tp->name) == 0) {
   1.967 +                yylval.Number = tp->value;
   1.968 +                return tp->type;
   1.969 +            }
   1.970 +	}
   1.971 +    }
   1.972 +
   1.973 +    /*
   1.974 +     * Drop out any periods and try the timezone table again.
   1.975 +     */
   1.976 +    for (i = 0, p = q = buff; *q; q++)
   1.977 +        if (*q != '.') {
   1.978 +            *p++ = *q;
   1.979 +        } else {
   1.980 +            i++;
   1.981 +	}
   1.982 +    *p = '\0';
   1.983 +    if (i) {
   1.984 +        for (tp = TimezoneTable; tp->name; tp++) {
   1.985 +            if (strcmp(buff, tp->name) == 0) {
   1.986 +                yylval.Number = tp->value;
   1.987 +                return tp->type;
   1.988 +            }
   1.989 +	}
   1.990 +    }
   1.991 +    
   1.992 +    return tID;
   1.993 +}
   1.994 +
   1.995 +
   1.996 +static int
   1.997 +yylex()
   1.998 +{
   1.999 +    register char       c;
  1.1000 +    register char       *p;
  1.1001 +    char                buff[20];
  1.1002 +    int                 Count;
  1.1003 +
  1.1004 +    for ( ; ; ) {
  1.1005 +        while (isspace(UCHAR(*yyInput))) {
  1.1006 +            yyInput++;
  1.1007 +	}
  1.1008 +
  1.1009 +        if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */
  1.1010 +	    /* convert the string into a number; count the number of digits */
  1.1011 +	    Count = 0;
  1.1012 +            for (yylval.Number = 0;
  1.1013 +		    isdigit(UCHAR(c = *yyInput++)); ) { /* INTL: digit */
  1.1014 +                yylval.Number = 10 * yylval.Number + c - '0';
  1.1015 +		Count++;
  1.1016 +	    }
  1.1017 +            yyInput--;
  1.1018 +	    /* A number with 6 or more digits is considered an ISO 8601 base */
  1.1019 +	    if (Count >= 6) {
  1.1020 +		return tISOBASE;
  1.1021 +	    } else {
  1.1022 +		return tUNUMBER;
  1.1023 +	    }
  1.1024 +        }
  1.1025 +        if (!(c & 0x80) && isalpha(UCHAR(c))) {	/* INTL: ISO only. */
  1.1026 +            for (p = buff; isalpha(UCHAR(c = *yyInput++)) /* INTL: ISO only. */
  1.1027 +		     || c == '.'; ) {
  1.1028 +                if (p < &buff[sizeof buff - 1]) {
  1.1029 +                    *p++ = c;
  1.1030 +		}
  1.1031 +	    }
  1.1032 +            *p = '\0';
  1.1033 +            yyInput--;
  1.1034 +            return LookupWord(buff);
  1.1035 +        }
  1.1036 +        if (c != '(') {
  1.1037 +            return *yyInput++;
  1.1038 +	}
  1.1039 +        Count = 0;
  1.1040 +        do {
  1.1041 +            c = *yyInput++;
  1.1042 +            if (c == '\0') {
  1.1043 +                return c;
  1.1044 +	    } else if (c == '(') {
  1.1045 +                Count++;
  1.1046 +	    } else if (c == ')') {
  1.1047 +                Count--;
  1.1048 +	    }
  1.1049 +        } while (Count > 0);
  1.1050 +    }
  1.1051 +}
  1.1052 +
  1.1053 +/*
  1.1054 + * Specify zone is of -50000 to force GMT.  (This allows BST to work).
  1.1055 + */
  1.1056 +
  1.1057 +int
  1.1058 +TclGetDate(p, now, zone, timePtr)
  1.1059 +    char *p;
  1.1060 +    Tcl_WideInt now;
  1.1061 +    long zone;
  1.1062 +    Tcl_WideInt *timePtr;
  1.1063 +{
  1.1064 +    struct tm *tm;
  1.1065 +    time_t Start;
  1.1066 +    time_t Time;
  1.1067 +    time_t tod;
  1.1068 +    int thisyear;
  1.1069 +
  1.1070 +    yyInput = p;
  1.1071 +    /* now has to be cast to a time_t for 64bit compliance */
  1.1072 +    Start = (time_t) now;
  1.1073 +    tm = TclpGetDate((TclpTime_t) &Start, (zone == -50000));
  1.1074 +    thisyear = tm->tm_year + TM_YEAR_BASE;
  1.1075 +    yyYear = thisyear;
  1.1076 +    yyMonth = tm->tm_mon + 1;
  1.1077 +    yyDay = tm->tm_mday;
  1.1078 +    yyTimezone = zone;
  1.1079 +    if (zone == -50000) {
  1.1080 +        yyDSTmode = DSToff;  /* assume GMT */
  1.1081 +        yyTimezone = 0;
  1.1082 +    } else {
  1.1083 +        yyDSTmode = DSTmaybe;
  1.1084 +    }
  1.1085 +    yyHour = 0;
  1.1086 +    yyMinutes = 0;
  1.1087 +    yySeconds = 0;
  1.1088 +    yyMeridian = MER24;
  1.1089 +    yyRelSeconds = 0;
  1.1090 +    yyRelMonth = 0;
  1.1091 +    yyRelDay = 0;
  1.1092 +    yyRelPointer = NULL;
  1.1093 +
  1.1094 +    yyHaveDate = 0;
  1.1095 +    yyHaveDay = 0;
  1.1096 +    yyHaveOrdinalMonth = 0;
  1.1097 +    yyHaveRel = 0;
  1.1098 +    yyHaveTime = 0;
  1.1099 +    yyHaveZone = 0;
  1.1100 +
  1.1101 +    if (yyparse() || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 ||
  1.1102 +	    yyHaveDay > 1 || yyHaveOrdinalMonth > 1) {
  1.1103 +        return -1;
  1.1104 +    }
  1.1105 +    
  1.1106 +    if (yyHaveDate || yyHaveTime || yyHaveDay) {
  1.1107 +	if (TclDateYear < 0) {
  1.1108 +	    TclDateYear = -TclDateYear;
  1.1109 +	}
  1.1110 +	/*
  1.1111 +	 * The following line handles years that are specified using
  1.1112 +	 * only two digits.  The line of code below implements a policy
  1.1113 +	 * defined by the X/Open workgroup on the millinium rollover.
  1.1114 +	 * Note: some of those dates may not actually be valid on some
  1.1115 +	 * platforms.  The POSIX standard startes that the dates 70-99
  1.1116 +	 * shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.
  1.1117 +	 * This later definition should work on all platforms.
  1.1118 +	 */
  1.1119 +
  1.1120 +	if (TclDateYear < 100) {
  1.1121 +	    if (TclDateYear >= 69) {
  1.1122 +		TclDateYear += 1900;
  1.1123 +	    } else {
  1.1124 +		TclDateYear += 2000;
  1.1125 +	    }
  1.1126 +	}
  1.1127 +	if (Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
  1.1128 +		yyMeridian, yyDSTmode, &Start) < 0) {
  1.1129 +            return -1;
  1.1130 +	}
  1.1131 +    } else {
  1.1132 +        Start = (time_t) now;
  1.1133 +        if (!yyHaveRel) {
  1.1134 +            Start -= ((tm->tm_hour * 60L * 60L) +
  1.1135 +		    tm->tm_min * 60L) +	tm->tm_sec;
  1.1136 +	}
  1.1137 +    }
  1.1138 +
  1.1139 +    Start += yyRelSeconds;
  1.1140 +    if (RelativeMonth(Start, yyRelMonth, &Time) < 0) {
  1.1141 +        return -1;
  1.1142 +    }
  1.1143 +    Start += Time;
  1.1144 +
  1.1145 +    if (RelativeDay(Start, yyRelDay, &Time) < 0) {
  1.1146 +	return -1;
  1.1147 +    }
  1.1148 +    Start += Time;
  1.1149 +    
  1.1150 +    if (yyHaveDay && !yyHaveDate) {
  1.1151 +        tod = NamedDay(Start, yyDayOrdinal, yyDayNumber);
  1.1152 +        Start += tod;
  1.1153 +    }
  1.1154 +
  1.1155 +    if (yyHaveOrdinalMonth) {
  1.1156 +	tod = NamedMonth(Start, yyMonthOrdinal, yyMonth);
  1.1157 +	Start += tod;
  1.1158 +    }
  1.1159 +    
  1.1160 +    *timePtr = Start;
  1.1161 +    return 0;
  1.1162 +}