os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclDate.c
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclDate.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1875 @@
1.4 +/*
1.5 + * tclDate.c --
1.6 + *
1.7 + * This file is generated from a yacc grammar defined in
1.8 + * the file tclGetDate.y. It should not be edited directly.
1.9 + *
1.10 + * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
1.11 + * Copyright (c) 1995-1997 Sun Microsystems, Inc.
1.12 + *
1.13 + * See the file "license.terms" for information on usage and redistribution
1.14 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
1.15 + *
1.16 + * RCS: @(#) $Id: tclDate.c,v 1.20.4.3 2006/06/14 15:21:14 patthoyts Exp $
1.17 + */
1.18 +
1.19 +#include "tclInt.h"
1.20 +#include "tclPort.h"
1.21 +
1.22 +#if defined(MAC_TCL) && !defined(TCL_MAC_USE_MSL_EPOCH)
1.23 +# define EPOCH 1904
1.24 +# define START_OF_TIME 1904
1.25 +# define END_OF_TIME 2039
1.26 +#else
1.27 +# define EPOCH 1970
1.28 +# define START_OF_TIME 1902
1.29 +# define END_OF_TIME 2037
1.30 +#endif
1.31 +
1.32 +/*
1.33 + * The offset of tm_year of struct tm returned by localtime, gmtime, etc.
1.34 + * I don't know how universal this is; K&R II, the NetBSD manpages, and
1.35 + * ../compat/strftime.c all agree that tm_year is the year-1900. However,
1.36 + * some systems may have a different value. This #define should be the
1.37 + * same as in ../compat/strftime.c.
1.38 + */
1.39 +#define TM_YEAR_BASE 1900
1.40 +
1.41 +#define HOUR(x) ((int) (60 * x))
1.42 +#define SECSPERDAY (24L * 60L * 60L)
1.43 +#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
1.44 +
1.45 +/*
1.46 + * An entry in the lexical lookup table.
1.47 + */
1.48 +typedef struct _TABLE {
1.49 + char *name;
1.50 + int type;
1.51 + time_t value;
1.52 +} TABLE;
1.53 +
1.54 +
1.55 +/*
1.56 + * Daylight-savings mode: on, off, or not yet known.
1.57 + */
1.58 +typedef enum _DSTMODE {
1.59 + DSTon, DSToff, DSTmaybe
1.60 +} DSTMODE;
1.61 +
1.62 +/*
1.63 + * Meridian: am, pm, or 24-hour style.
1.64 + */
1.65 +typedef enum _MERIDIAN {
1.66 + MERam, MERpm, MER24
1.67 +} MERIDIAN;
1.68 +
1.69 +
1.70 +/*
1.71 + * Global variables. We could get rid of most of these by using a good
1.72 + * union as the yacc stack. (This routine was originally written before
1.73 + * yacc had the %union construct.) Maybe someday; right now we only use
1.74 + * the %union very rarely.
1.75 + */
1.76 +static char *TclDateInput;
1.77 +static DSTMODE TclDateDSTmode;
1.78 +static time_t TclDateDayOrdinal;
1.79 +static time_t TclDateDayNumber;
1.80 +static time_t TclDateMonthOrdinal;
1.81 +static int TclDateHaveDate;
1.82 +static int TclDateHaveDay;
1.83 +static int TclDateHaveOrdinalMonth;
1.84 +static int TclDateHaveRel;
1.85 +static int TclDateHaveTime;
1.86 +static int TclDateHaveZone;
1.87 +static time_t TclDateTimezone;
1.88 +static time_t TclDateDay;
1.89 +static time_t TclDateHour;
1.90 +static time_t TclDateMinutes;
1.91 +static time_t TclDateMonth;
1.92 +static time_t TclDateSeconds;
1.93 +static time_t TclDateYear;
1.94 +static MERIDIAN TclDateMeridian;
1.95 +static time_t TclDateRelMonth;
1.96 +static time_t TclDateRelDay;
1.97 +static time_t TclDateRelSeconds;
1.98 +static time_t *TclDateRelPointer;
1.99 +
1.100 +/*
1.101 + * Prototypes of internal functions.
1.102 + */
1.103 +static void TclDateerror _ANSI_ARGS_((char *s));
1.104 +static time_t ToSeconds _ANSI_ARGS_((time_t Hours, time_t Minutes,
1.105 + time_t Seconds, MERIDIAN Meridian));
1.106 +static int Convert _ANSI_ARGS_((time_t Month, time_t Day, time_t Year,
1.107 + time_t Hours, time_t Minutes, time_t Seconds,
1.108 + MERIDIAN Meridia, DSTMODE DSTmode, time_t *TimePtr));
1.109 +static time_t DSTcorrect _ANSI_ARGS_((time_t Start, time_t Future));
1.110 +static time_t NamedDay _ANSI_ARGS_((time_t Start, time_t DayOrdinal,
1.111 + time_t DayNumber));
1.112 +static time_t NamedMonth _ANSI_ARGS_((time_t Start, time_t MonthOrdinal,
1.113 + time_t MonthNumber));
1.114 +static int RelativeMonth _ANSI_ARGS_((time_t Start, time_t RelMonth,
1.115 + time_t *TimePtr));
1.116 +static int RelativeDay _ANSI_ARGS_((time_t Start, time_t RelDay,
1.117 + time_t *TimePtr));
1.118 +static int LookupWord _ANSI_ARGS_((char *buff));
1.119 +static int TclDatelex _ANSI_ARGS_((void));
1.120 +
1.121 +int
1.122 +TclDateparse _ANSI_ARGS_((void));
1.123 +typedef union
1.124 +#ifdef __cplusplus
1.125 + YYSTYPE
1.126 +#endif
1.127 + {
1.128 + time_t Number;
1.129 + enum _MERIDIAN Meridian;
1.130 +} YYSTYPE;
1.131 +# define tAGO 257
1.132 +# define tDAY 258
1.133 +# define tDAYZONE 259
1.134 +# define tID 260
1.135 +# define tMERIDIAN 261
1.136 +# define tMINUTE_UNIT 262
1.137 +# define tMONTH 263
1.138 +# define tMONTH_UNIT 264
1.139 +# define tSTARDATE 265
1.140 +# define tSEC_UNIT 266
1.141 +# define tSNUMBER 267
1.142 +# define tUNUMBER 268
1.143 +# define tZONE 269
1.144 +# define tEPOCH 270
1.145 +# define tDST 271
1.146 +# define tISOBASE 272
1.147 +# define tDAY_UNIT 273
1.148 +# define tNEXT 274
1.149 +
1.150 +
1.151 +
1.152 +
1.153 +#if defined(__cplusplus) || defined(__STDC__)
1.154 +
1.155 +#if defined(__cplusplus) && defined(__EXTERN_C__)
1.156 +extern "C" {
1.157 +#endif
1.158 +#ifndef TclDateerror
1.159 +#if defined(__cplusplus)
1.160 + void TclDateerror(CONST char *);
1.161 +#endif
1.162 +#endif
1.163 +#ifndef TclDatelex
1.164 + int TclDatelex(void);
1.165 +#endif
1.166 + int TclDateparse(void);
1.167 +#if defined(__cplusplus) && defined(__EXTERN_C__)
1.168 +}
1.169 +#endif
1.170 +
1.171 +#endif
1.172 +
1.173 +#define TclDateclearin TclDatechar = -1
1.174 +#define TclDateerrok TclDateerrflag = 0
1.175 +extern int TclDatechar;
1.176 +extern int TclDateerrflag;
1.177 +YYSTYPE TclDatelval;
1.178 +YYSTYPE TclDateval;
1.179 +typedef int TclDatetabelem;
1.180 +#ifndef YYMAXDEPTH
1.181 +#define YYMAXDEPTH 150
1.182 +#endif
1.183 +#if YYMAXDEPTH > 0
1.184 +int TclDate_TclDates[YYMAXDEPTH], *TclDates = TclDate_TclDates;
1.185 +YYSTYPE TclDate_TclDatev[YYMAXDEPTH], *TclDatev = TclDate_TclDatev;
1.186 +#else /* user does initial allocation */
1.187 +int *TclDates;
1.188 +YYSTYPE *TclDatev;
1.189 +#endif
1.190 +static int TclDatemaxdepth = YYMAXDEPTH;
1.191 +# define YYERRCODE 256
1.192 +
1.193 +
1.194 +/*
1.195 + * Month and day table.
1.196 + */
1.197 +static TABLE MonthDayTable[] = {
1.198 + { "january", tMONTH, 1 },
1.199 + { "february", tMONTH, 2 },
1.200 + { "march", tMONTH, 3 },
1.201 + { "april", tMONTH, 4 },
1.202 + { "may", tMONTH, 5 },
1.203 + { "june", tMONTH, 6 },
1.204 + { "july", tMONTH, 7 },
1.205 + { "august", tMONTH, 8 },
1.206 + { "september", tMONTH, 9 },
1.207 + { "sept", tMONTH, 9 },
1.208 + { "october", tMONTH, 10 },
1.209 + { "november", tMONTH, 11 },
1.210 + { "december", tMONTH, 12 },
1.211 + { "sunday", tDAY, 0 },
1.212 + { "monday", tDAY, 1 },
1.213 + { "tuesday", tDAY, 2 },
1.214 + { "tues", tDAY, 2 },
1.215 + { "wednesday", tDAY, 3 },
1.216 + { "wednes", tDAY, 3 },
1.217 + { "thursday", tDAY, 4 },
1.218 + { "thur", tDAY, 4 },
1.219 + { "thurs", tDAY, 4 },
1.220 + { "friday", tDAY, 5 },
1.221 + { "saturday", tDAY, 6 },
1.222 + { NULL }
1.223 +};
1.224 +
1.225 +/*
1.226 + * Time units table.
1.227 + */
1.228 +static TABLE UnitsTable[] = {
1.229 + { "year", tMONTH_UNIT, 12 },
1.230 + { "month", tMONTH_UNIT, 1 },
1.231 + { "fortnight", tDAY_UNIT, 14 },
1.232 + { "week", tDAY_UNIT, 7 },
1.233 + { "day", tDAY_UNIT, 1 },
1.234 + { "hour", tSEC_UNIT, 60 * 60 },
1.235 + { "minute", tSEC_UNIT, 60 },
1.236 + { "min", tSEC_UNIT, 60 },
1.237 + { "second", tSEC_UNIT, 1 },
1.238 + { "sec", tSEC_UNIT, 1 },
1.239 + { NULL }
1.240 +};
1.241 +
1.242 +/*
1.243 + * Assorted relative-time words.
1.244 + */
1.245 +static TABLE OtherTable[] = {
1.246 + { "tomorrow", tDAY_UNIT, 1 },
1.247 + { "yesterday", tDAY_UNIT, -1 },
1.248 + { "today", tDAY_UNIT, 0 },
1.249 + { "now", tSEC_UNIT, 0 },
1.250 + { "last", tUNUMBER, -1 },
1.251 + { "this", tSEC_UNIT, 0 },
1.252 + { "next", tNEXT, 1 },
1.253 +#if 0
1.254 + { "first", tUNUMBER, 1 },
1.255 + { "second", tUNUMBER, 2 },
1.256 + { "third", tUNUMBER, 3 },
1.257 + { "fourth", tUNUMBER, 4 },
1.258 + { "fifth", tUNUMBER, 5 },
1.259 + { "sixth", tUNUMBER, 6 },
1.260 + { "seventh", tUNUMBER, 7 },
1.261 + { "eighth", tUNUMBER, 8 },
1.262 + { "ninth", tUNUMBER, 9 },
1.263 + { "tenth", tUNUMBER, 10 },
1.264 + { "eleventh", tUNUMBER, 11 },
1.265 + { "twelfth", tUNUMBER, 12 },
1.266 +#endif
1.267 + { "ago", tAGO, 1 },
1.268 + { "epoch", tEPOCH, 0 },
1.269 + { "stardate", tSTARDATE, 0},
1.270 + { NULL }
1.271 +};
1.272 +
1.273 +/*
1.274 + * The timezone table. (Note: This table was modified to not use any floating
1.275 + * point constants to work around an SGI compiler bug).
1.276 + */
1.277 +static TABLE TimezoneTable[] = {
1.278 + { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
1.279 + { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
1.280 + { "utc", tZONE, HOUR( 0) },
1.281 + { "uct", tZONE, HOUR( 0) }, /* Universal Coordinated Time */
1.282 + { "wet", tZONE, HOUR( 0) }, /* Western European */
1.283 + { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
1.284 + { "wat", tZONE, HOUR( 1) }, /* West Africa */
1.285 + { "at", tZONE, HOUR( 2) }, /* Azores */
1.286 +#if 0
1.287 + /* For completeness. BST is also British Summer, and GST is
1.288 + * also Guam Standard. */
1.289 + { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
1.290 + { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
1.291 +#endif
1.292 + { "nft", tZONE, HOUR( 7/2) }, /* Newfoundland */
1.293 + { "nst", tZONE, HOUR( 7/2) }, /* Newfoundland Standard */
1.294 + { "ndt", tDAYZONE, HOUR( 7/2) }, /* Newfoundland Daylight */
1.295 + { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
1.296 + { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
1.297 + { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
1.298 + { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
1.299 + { "cst", tZONE, HOUR( 6) }, /* Central Standard */
1.300 + { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
1.301 + { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
1.302 + { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
1.303 + { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
1.304 + { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
1.305 + { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
1.306 + { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
1.307 + { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
1.308 + { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
1.309 + { "cat", tZONE, HOUR(10) }, /* Central Alaska */
1.310 + { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
1.311 + { "nt", tZONE, HOUR(11) }, /* Nome */
1.312 + { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
1.313 + { "cet", tZONE, -HOUR( 1) }, /* Central European */
1.314 + { "cest", tDAYZONE, -HOUR( 1) }, /* Central European Summer */
1.315 + { "met", tZONE, -HOUR( 1) }, /* Middle European */
1.316 + { "mewt", tZONE, -HOUR( 1) }, /* Middle European Winter */
1.317 + { "mest", tDAYZONE, -HOUR( 1) }, /* Middle European Summer */
1.318 + { "swt", tZONE, -HOUR( 1) }, /* Swedish Winter */
1.319 + { "sst", tDAYZONE, -HOUR( 1) }, /* Swedish Summer */
1.320 + { "fwt", tZONE, -HOUR( 1) }, /* French Winter */
1.321 + { "fst", tDAYZONE, -HOUR( 1) }, /* French Summer */
1.322 + { "eet", tZONE, -HOUR( 2) }, /* Eastern Europe, USSR Zone 1 */
1.323 + { "bt", tZONE, -HOUR( 3) }, /* Baghdad, USSR Zone 2 */
1.324 + { "it", tZONE, -HOUR( 7/2) }, /* Iran */
1.325 + { "zp4", tZONE, -HOUR( 4) }, /* USSR Zone 3 */
1.326 + { "zp5", tZONE, -HOUR( 5) }, /* USSR Zone 4 */
1.327 + { "ist", tZONE, -HOUR(11/2) }, /* Indian Standard */
1.328 + { "zp6", tZONE, -HOUR( 6) }, /* USSR Zone 5 */
1.329 +#if 0
1.330 + /* For completeness. NST is also Newfoundland Stanard, nad SST is
1.331 + * also Swedish Summer. */
1.332 + { "nst", tZONE, -HOUR(13/2) }, /* North Sumatra */
1.333 + { "sst", tZONE, -HOUR( 7) }, /* South Sumatra, USSR Zone 6 */
1.334 +#endif /* 0 */
1.335 + { "wast", tZONE, -HOUR( 7) }, /* West Australian Standard */
1.336 + { "wadt", tDAYZONE, -HOUR( 7) }, /* West Australian Daylight */
1.337 + { "jt", tZONE, -HOUR(15/2) }, /* Java (3pm in Cronusland!) */
1.338 + { "cct", tZONE, -HOUR( 8) }, /* China Coast, USSR Zone 7 */
1.339 + { "jst", tZONE, -HOUR( 9) }, /* Japan Standard, USSR Zone 8 */
1.340 + { "jdt", tDAYZONE, -HOUR( 9) }, /* Japan Daylight */
1.341 + { "kst", tZONE, -HOUR( 9) }, /* Korea Standard */
1.342 + { "kdt", tDAYZONE, -HOUR( 9) }, /* Korea Daylight */
1.343 + { "cast", tZONE, -HOUR(19/2) }, /* Central Australian Standard */
1.344 + { "cadt", tDAYZONE, -HOUR(19/2) }, /* Central Australian Daylight */
1.345 + { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
1.346 + { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
1.347 + { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
1.348 + { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
1.349 + { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
1.350 + { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
1.351 + { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
1.352 + /* ADDED BY Marco Nijdam */
1.353 + { "dst", tDST, HOUR( 0) }, /* DST on (hour is ignored) */
1.354 + /* End ADDED */
1.355 + { NULL }
1.356 +};
1.357 +
1.358 +/*
1.359 + * Military timezone table.
1.360 + */
1.361 +static TABLE MilitaryTable[] = {
1.362 + { "a", tZONE, HOUR( 1) },
1.363 + { "b", tZONE, HOUR( 2) },
1.364 + { "c", tZONE, HOUR( 3) },
1.365 + { "d", tZONE, HOUR( 4) },
1.366 + { "e", tZONE, HOUR( 5) },
1.367 + { "f", tZONE, HOUR( 6) },
1.368 + { "g", tZONE, HOUR( 7) },
1.369 + { "h", tZONE, HOUR( 8) },
1.370 + { "i", tZONE, HOUR( 9) },
1.371 + { "k", tZONE, HOUR( 10) },
1.372 + { "l", tZONE, HOUR( 11) },
1.373 + { "m", tZONE, HOUR( 12) },
1.374 + { "n", tZONE, HOUR(- 1) },
1.375 + { "o", tZONE, HOUR(- 2) },
1.376 + { "p", tZONE, HOUR(- 3) },
1.377 + { "q", tZONE, HOUR(- 4) },
1.378 + { "r", tZONE, HOUR(- 5) },
1.379 + { "s", tZONE, HOUR(- 6) },
1.380 + { "t", tZONE, HOUR(- 7) },
1.381 + { "u", tZONE, HOUR(- 8) },
1.382 + { "v", tZONE, HOUR(- 9) },
1.383 + { "w", tZONE, HOUR(-10) },
1.384 + { "x", tZONE, HOUR(-11) },
1.385 + { "y", tZONE, HOUR(-12) },
1.386 + { "z", tZONE, HOUR( 0) },
1.387 + { NULL }
1.388 +};
1.389 +
1.390 +
1.391 +/*
1.392 + * Dump error messages in the bit bucket.
1.393 + */
1.394 +static void
1.395 +TclDateerror(s)
1.396 + char *s;
1.397 +{
1.398 +}
1.399 +
1.400 +
1.401 +static time_t
1.402 +ToSeconds(Hours, Minutes, Seconds, Meridian)
1.403 + time_t Hours;
1.404 + time_t Minutes;
1.405 + time_t Seconds;
1.406 + MERIDIAN Meridian;
1.407 +{
1.408 + if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
1.409 + return -1;
1.410 + switch (Meridian) {
1.411 + case MER24:
1.412 + if (Hours < 0 || Hours > 23)
1.413 + return -1;
1.414 + return (Hours * 60L + Minutes) * 60L + Seconds;
1.415 + case MERam:
1.416 + if (Hours < 1 || Hours > 12)
1.417 + return -1;
1.418 + return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
1.419 + case MERpm:
1.420 + if (Hours < 1 || Hours > 12)
1.421 + return -1;
1.422 + return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
1.423 + }
1.424 + return -1; /* Should never be reached */
1.425 +}
1.426 +
1.427 +/*
1.428 + *-----------------------------------------------------------------------------
1.429 + *
1.430 + * Convert --
1.431 + *
1.432 + * Convert a {month, day, year, hours, minutes, seconds, meridian, dst}
1.433 + * tuple into a clock seconds value.
1.434 + *
1.435 + * Results:
1.436 + * 0 or -1 indicating success or failure.
1.437 + *
1.438 + * Side effects:
1.439 + * Fills TimePtr with the computed value.
1.440 + *
1.441 + *-----------------------------------------------------------------------------
1.442 + */
1.443 +static int
1.444 +Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode, TimePtr)
1.445 + time_t Month;
1.446 + time_t Day;
1.447 + time_t Year;
1.448 + time_t Hours;
1.449 + time_t Minutes;
1.450 + time_t Seconds;
1.451 + MERIDIAN Meridian;
1.452 + DSTMODE DSTmode;
1.453 + time_t *TimePtr;
1.454 +{
1.455 + static int DaysInMonth[12] = {
1.456 + 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1.457 + };
1.458 + time_t tod;
1.459 + time_t Julian;
1.460 + int i;
1.461 +
1.462 + /* Figure out how many days are in February for the given year.
1.463 + * Every year divisible by 4 is a leap year.
1.464 + * But, every year divisible by 100 is not a leap year.
1.465 + * But, every year divisible by 400 is a leap year after all.
1.466 + */
1.467 + DaysInMonth[1] = IsLeapYear(Year) ? 29 : 28;
1.468 +
1.469 + /* Check the inputs for validity */
1.470 + if (Month < 1 || Month > 12
1.471 + || Year < START_OF_TIME || Year > END_OF_TIME
1.472 + || Day < 1 || Day > DaysInMonth[(int)--Month])
1.473 + return -1;
1.474 +
1.475 + /* Start computing the value. First determine the number of days
1.476 + * represented by the date, then multiply by the number of seconds/day.
1.477 + */
1.478 + for (Julian = Day - 1, i = 0; i < Month; i++)
1.479 + Julian += DaysInMonth[i];
1.480 + if (Year >= EPOCH) {
1.481 + for (i = EPOCH; i < Year; i++)
1.482 + Julian += 365 + IsLeapYear(i);
1.483 + } else {
1.484 + for (i = (int)Year; i < EPOCH; i++)
1.485 + Julian -= 365 + IsLeapYear(i);
1.486 + }
1.487 + Julian *= SECSPERDAY;
1.488 +
1.489 + /* Add the timezone offset ?? */
1.490 + Julian += TclDateTimezone * 60L;
1.491 +
1.492 + /* Add the number of seconds represented by the time component */
1.493 + if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1.494 + return -1;
1.495 + Julian += tod;
1.496 +
1.497 + /* Perform a preliminary DST compensation ?? */
1.498 + if (DSTmode == DSTon
1.499 + || (DSTmode == DSTmaybe && TclpGetDate((TclpTime_t)&Julian, 0)->tm_isdst))
1.500 + Julian -= 60 * 60;
1.501 + *TimePtr = Julian;
1.502 + return 0;
1.503 +}
1.504 +
1.505 +
1.506 +static time_t
1.507 +DSTcorrect(Start, Future)
1.508 + time_t Start;
1.509 + time_t Future;
1.510 +{
1.511 + time_t StartDay;
1.512 + time_t FutureDay;
1.513 + StartDay = (TclpGetDate((TclpTime_t)&Start, 0)->tm_hour + 1) % 24;
1.514 + FutureDay = (TclpGetDate((TclpTime_t)&Future, 0)->tm_hour + 1) % 24;
1.515 + return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
1.516 +}
1.517 +
1.518 +
1.519 +static time_t
1.520 +NamedDay(Start, DayOrdinal, DayNumber)
1.521 + time_t Start;
1.522 + time_t DayOrdinal;
1.523 + time_t DayNumber;
1.524 +{
1.525 + struct tm *tm;
1.526 + time_t now;
1.527 +
1.528 + now = Start;
1.529 + tm = TclpGetDate((TclpTime_t)&now, 0);
1.530 + now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
1.531 + now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
1.532 + return DSTcorrect(Start, now);
1.533 +}
1.534 +
1.535 +static time_t
1.536 +NamedMonth(Start, MonthOrdinal, MonthNumber)
1.537 + time_t Start;
1.538 + time_t MonthOrdinal;
1.539 + time_t MonthNumber;
1.540 +{
1.541 + struct tm *tm;
1.542 + time_t now;
1.543 + int result;
1.544 +
1.545 + now = Start;
1.546 + tm = TclpGetDate((TclpTime_t)&now, 0);
1.547 + /* To compute the next n'th month, we use this alg:
1.548 + * add n to year value
1.549 + * if currentMonth < requestedMonth decrement year value by 1 (so that
1.550 + * doing next february from january gives us february of the current year)
1.551 + * set day to 1, time to 0
1.552 + */
1.553 + tm->tm_year += (int)MonthOrdinal;
1.554 + if (tm->tm_mon < MonthNumber - 1) {
1.555 + tm->tm_year--;
1.556 + }
1.557 + result = Convert(MonthNumber, (time_t) 1, tm->tm_year + TM_YEAR_BASE,
1.558 + (time_t) 0, (time_t) 0, (time_t) 0, MER24, DSTmaybe, &now);
1.559 + if (result < 0) {
1.560 + return 0;
1.561 + }
1.562 + return DSTcorrect(Start, now);
1.563 +}
1.564 +
1.565 +static int
1.566 +RelativeMonth(Start, RelMonth, TimePtr)
1.567 + time_t Start;
1.568 + time_t RelMonth;
1.569 + time_t *TimePtr;
1.570 +{
1.571 + struct tm *tm;
1.572 + time_t Month;
1.573 + time_t Year;
1.574 + time_t Julian;
1.575 + int result;
1.576 +
1.577 + if (RelMonth == 0) {
1.578 + *TimePtr = 0;
1.579 + return 0;
1.580 + }
1.581 + tm = TclpGetDate((TclpTime_t)&Start, 0);
1.582 + Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
1.583 + Year = Month / 12;
1.584 + Month = Month % 12 + 1;
1.585 + result = Convert(Month, (time_t) tm->tm_mday, Year,
1.586 + (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
1.587 + MER24, DSTmaybe, &Julian);
1.588 +
1.589 + /*
1.590 + * The Julian time returned above is behind by one day, if "month"
1.591 + * or "year" is used to specify relative time and the GMT flag is true.
1.592 + * This problem occurs only when the current time is closer to
1.593 + * midnight, the difference being not more than its time difference
1.594 + * with GMT. For example, in US/Pacific time zone, the problem occurs
1.595 + * whenever the current time is between midnight to 8:00am or 7:00amDST.
1.596 + * See Bug# 413397 for more details and sample script.
1.597 + * To resolve this bug, we simply add the number of seconds corresponding
1.598 + * to timezone difference with GMT to Julian time, if GMT flag is true.
1.599 + */
1.600 +
1.601 + if (TclDateTimezone == 0) {
1.602 + Julian += TclpGetTimeZone((unsigned long) Start) * 60L;
1.603 + }
1.604 +
1.605 + /*
1.606 + * The following iteration takes into account the case were we jump
1.607 + * into a "short month". Far example, "one month from Jan 31" will
1.608 + * fail because there is no Feb 31. The code below will reduce the
1.609 + * day and try converting the date until we succed or the date equals
1.610 + * 28 (which always works unless the date is bad in another way).
1.611 + */
1.612 +
1.613 + while ((result != 0) && (tm->tm_mday > 28)) {
1.614 + tm->tm_mday--;
1.615 + result = Convert(Month, (time_t) tm->tm_mday, Year,
1.616 + (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
1.617 + MER24, DSTmaybe, &Julian);
1.618 + }
1.619 + if (result != 0) {
1.620 + return -1;
1.621 + }
1.622 + *TimePtr = DSTcorrect(Start, Julian);
1.623 + return 0;
1.624 +}
1.625 +
1.626 +
1.627 +/*
1.628 + *-----------------------------------------------------------------------------
1.629 + *
1.630 + * RelativeDay --
1.631 + *
1.632 + * Given a starting time and a number of days before or after, compute the
1.633 + * DST corrected difference between those dates.
1.634 + *
1.635 + * Results:
1.636 + * 1 or -1 indicating success or failure.
1.637 + *
1.638 + * Side effects:
1.639 + * Fills TimePtr with the computed value.
1.640 + *
1.641 + *-----------------------------------------------------------------------------
1.642 + */
1.643 +
1.644 +static int
1.645 +RelativeDay(Start, RelDay, TimePtr)
1.646 + time_t Start;
1.647 + time_t RelDay;
1.648 + time_t *TimePtr;
1.649 +{
1.650 + time_t new;
1.651 +
1.652 + new = Start + (RelDay * 60 * 60 * 24);
1.653 + *TimePtr = DSTcorrect(Start, new);
1.654 + return 1;
1.655 +}
1.656 +
1.657 +static int
1.658 +LookupWord(buff)
1.659 + char *buff;
1.660 +{
1.661 + register char *p;
1.662 + register char *q;
1.663 + register TABLE *tp;
1.664 + int i;
1.665 + int abbrev;
1.666 +
1.667 + /*
1.668 + * Make it lowercase.
1.669 + */
1.670 +
1.671 + Tcl_UtfToLower(buff);
1.672 +
1.673 + if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
1.674 + TclDatelval.Meridian = MERam;
1.675 + return tMERIDIAN;
1.676 + }
1.677 + if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
1.678 + TclDatelval.Meridian = MERpm;
1.679 + return tMERIDIAN;
1.680 + }
1.681 +
1.682 + /*
1.683 + * See if we have an abbreviation for a month.
1.684 + */
1.685 + if (strlen(buff) == 3) {
1.686 + abbrev = 1;
1.687 + } else if (strlen(buff) == 4 && buff[3] == '.') {
1.688 + abbrev = 1;
1.689 + buff[3] = '\0';
1.690 + } else {
1.691 + abbrev = 0;
1.692 + }
1.693 +
1.694 + for (tp = MonthDayTable; tp->name; tp++) {
1.695 + if (abbrev) {
1.696 + if (strncmp(buff, tp->name, 3) == 0) {
1.697 + TclDatelval.Number = tp->value;
1.698 + return tp->type;
1.699 + }
1.700 + } else if (strcmp(buff, tp->name) == 0) {
1.701 + TclDatelval.Number = tp->value;
1.702 + return tp->type;
1.703 + }
1.704 + }
1.705 +
1.706 + for (tp = TimezoneTable; tp->name; tp++) {
1.707 + if (strcmp(buff, tp->name) == 0) {
1.708 + TclDatelval.Number = tp->value;
1.709 + return tp->type;
1.710 + }
1.711 + }
1.712 +
1.713 + for (tp = UnitsTable; tp->name; tp++) {
1.714 + if (strcmp(buff, tp->name) == 0) {
1.715 + TclDatelval.Number = tp->value;
1.716 + return tp->type;
1.717 + }
1.718 + }
1.719 +
1.720 + /*
1.721 + * Strip off any plural and try the units table again.
1.722 + */
1.723 + i = strlen(buff) - 1;
1.724 + if (buff[i] == 's') {
1.725 + buff[i] = '\0';
1.726 + for (tp = UnitsTable; tp->name; tp++) {
1.727 + if (strcmp(buff, tp->name) == 0) {
1.728 + TclDatelval.Number = tp->value;
1.729 + return tp->type;
1.730 + }
1.731 + }
1.732 + }
1.733 +
1.734 + for (tp = OtherTable; tp->name; tp++) {
1.735 + if (strcmp(buff, tp->name) == 0) {
1.736 + TclDatelval.Number = tp->value;
1.737 + return tp->type;
1.738 + }
1.739 + }
1.740 +
1.741 + /*
1.742 + * Military timezones.
1.743 + */
1.744 + if (buff[1] == '\0' && !(*buff & 0x80)
1.745 + && isalpha(UCHAR(*buff))) { /* INTL: ISO only */
1.746 + for (tp = MilitaryTable; tp->name; tp++) {
1.747 + if (strcmp(buff, tp->name) == 0) {
1.748 + TclDatelval.Number = tp->value;
1.749 + return tp->type;
1.750 + }
1.751 + }
1.752 + }
1.753 +
1.754 + /*
1.755 + * Drop out any periods and try the timezone table again.
1.756 + */
1.757 + for (i = 0, p = q = buff; *q; q++)
1.758 + if (*q != '.') {
1.759 + *p++ = *q;
1.760 + } else {
1.761 + i++;
1.762 + }
1.763 + *p = '\0';
1.764 + if (i) {
1.765 + for (tp = TimezoneTable; tp->name; tp++) {
1.766 + if (strcmp(buff, tp->name) == 0) {
1.767 + TclDatelval.Number = tp->value;
1.768 + return tp->type;
1.769 + }
1.770 + }
1.771 + }
1.772 +
1.773 + return tID;
1.774 +}
1.775 +
1.776 +
1.777 +static int
1.778 +TclDatelex()
1.779 +{
1.780 + register char c;
1.781 + register char *p;
1.782 + char buff[20];
1.783 + int Count;
1.784 +
1.785 + for ( ; ; ) {
1.786 + while (isspace(UCHAR(*TclDateInput))) {
1.787 + TclDateInput++;
1.788 + }
1.789 +
1.790 + if (isdigit(UCHAR(c = *TclDateInput))) { /* INTL: digit */
1.791 + /* convert the string into a number; count the number of digits */
1.792 + Count = 0;
1.793 + for (TclDatelval.Number = 0;
1.794 + isdigit(UCHAR(c = *TclDateInput++)); ) { /* INTL: digit */
1.795 + TclDatelval.Number = 10 * TclDatelval.Number + c - '0';
1.796 + Count++;
1.797 + }
1.798 + TclDateInput--;
1.799 + /* A number with 6 or more digits is considered an ISO 8601 base */
1.800 + if (Count >= 6) {
1.801 + return tISOBASE;
1.802 + } else {
1.803 + return tUNUMBER;
1.804 + }
1.805 + }
1.806 + if (!(c & 0x80) && isalpha(UCHAR(c))) { /* INTL: ISO only. */
1.807 + for (p = buff; isalpha(UCHAR(c = *TclDateInput++)) /* INTL: ISO only. */
1.808 + || c == '.'; ) {
1.809 + if (p < &buff[sizeof buff - 1]) {
1.810 + *p++ = c;
1.811 + }
1.812 + }
1.813 + *p = '\0';
1.814 + TclDateInput--;
1.815 + return LookupWord(buff);
1.816 + }
1.817 + if (c != '(') {
1.818 + return *TclDateInput++;
1.819 + }
1.820 + Count = 0;
1.821 + do {
1.822 + c = *TclDateInput++;
1.823 + if (c == '\0') {
1.824 + return c;
1.825 + } else if (c == '(') {
1.826 + Count++;
1.827 + } else if (c == ')') {
1.828 + Count--;
1.829 + }
1.830 + } while (Count > 0);
1.831 + }
1.832 +}
1.833 +
1.834 +/*
1.835 + * Specify zone is of -50000 to force GMT. (This allows BST to work).
1.836 + */
1.837 +
1.838 +int
1.839 +TclGetDate(p, now, zone, timePtr)
1.840 + char *p;
1.841 + Tcl_WideInt now;
1.842 + long zone;
1.843 + Tcl_WideInt *timePtr;
1.844 +{
1.845 + struct tm *tm;
1.846 + time_t Start;
1.847 + time_t Time;
1.848 + time_t tod;
1.849 + int thisyear;
1.850 +
1.851 + TclDateInput = p;
1.852 + /* now has to be cast to a time_t for 64bit compliance */
1.853 + Start = (time_t) now;
1.854 + tm = TclpGetDate((TclpTime_t) &Start, (zone == -50000));
1.855 + thisyear = tm->tm_year + TM_YEAR_BASE;
1.856 + TclDateYear = thisyear;
1.857 + TclDateMonth = tm->tm_mon + 1;
1.858 + TclDateDay = tm->tm_mday;
1.859 + TclDateTimezone = zone;
1.860 + if (zone == -50000) {
1.861 + TclDateDSTmode = DSToff; /* assume GMT */
1.862 + TclDateTimezone = 0;
1.863 + } else {
1.864 + TclDateDSTmode = DSTmaybe;
1.865 + }
1.866 + TclDateHour = 0;
1.867 + TclDateMinutes = 0;
1.868 + TclDateSeconds = 0;
1.869 + TclDateMeridian = MER24;
1.870 + TclDateRelSeconds = 0;
1.871 + TclDateRelMonth = 0;
1.872 + TclDateRelDay = 0;
1.873 + TclDateRelPointer = NULL;
1.874 +
1.875 + TclDateHaveDate = 0;
1.876 + TclDateHaveDay = 0;
1.877 + TclDateHaveOrdinalMonth = 0;
1.878 + TclDateHaveRel = 0;
1.879 + TclDateHaveTime = 0;
1.880 + TclDateHaveZone = 0;
1.881 +
1.882 + if (TclDateparse() || TclDateHaveTime > 1 || TclDateHaveZone > 1 || TclDateHaveDate > 1 ||
1.883 + TclDateHaveDay > 1 || TclDateHaveOrdinalMonth > 1) {
1.884 + return -1;
1.885 + }
1.886 +
1.887 + if (TclDateHaveDate || TclDateHaveTime || TclDateHaveDay) {
1.888 + if (TclDateYear < 0) {
1.889 + TclDateYear = -TclDateYear;
1.890 + }
1.891 + /*
1.892 + * The following line handles years that are specified using
1.893 + * only two digits. The line of code below implements a policy
1.894 + * defined by the X/Open workgroup on the millinium rollover.
1.895 + * Note: some of those dates may not actually be valid on some
1.896 + * platforms. The POSIX standard startes that the dates 70-99
1.897 + * shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.
1.898 + * This later definition should work on all platforms.
1.899 + */
1.900 +
1.901 + if (TclDateYear < 100) {
1.902 + if (TclDateYear >= 69) {
1.903 + TclDateYear += 1900;
1.904 + } else {
1.905 + TclDateYear += 2000;
1.906 + }
1.907 + }
1.908 + if (Convert(TclDateMonth, TclDateDay, TclDateYear, TclDateHour, TclDateMinutes, TclDateSeconds,
1.909 + TclDateMeridian, TclDateDSTmode, &Start) < 0) {
1.910 + return -1;
1.911 + }
1.912 + } else {
1.913 + Start = (time_t) now;
1.914 + if (!TclDateHaveRel) {
1.915 + Start -= ((tm->tm_hour * 60L * 60L) +
1.916 + tm->tm_min * 60L) + tm->tm_sec;
1.917 + }
1.918 + }
1.919 +
1.920 + Start += TclDateRelSeconds;
1.921 + if (RelativeMonth(Start, TclDateRelMonth, &Time) < 0) {
1.922 + return -1;
1.923 + }
1.924 + Start += Time;
1.925 +
1.926 + if (RelativeDay(Start, TclDateRelDay, &Time) < 0) {
1.927 + return -1;
1.928 + }
1.929 + Start += Time;
1.930 +
1.931 + if (TclDateHaveDay && !TclDateHaveDate) {
1.932 + tod = NamedDay(Start, TclDateDayOrdinal, TclDateDayNumber);
1.933 + Start += tod;
1.934 + }
1.935 +
1.936 + if (TclDateHaveOrdinalMonth) {
1.937 + tod = NamedMonth(Start, TclDateMonthOrdinal, TclDateMonth);
1.938 + Start += tod;
1.939 + }
1.940 +
1.941 + *timePtr = Start;
1.942 + return 0;
1.943 +}
1.944 +static CONST TclDatetabelem TclDateexca[] ={
1.945 +-1, 1,
1.946 + 0, -1,
1.947 + -2, 0,
1.948 + };
1.949 +# define YYNPROD 56
1.950 +# define YYLAST 261
1.951 +static CONST TclDatetabelem TclDateact[]={
1.952 +
1.953 + 24, 40, 23, 36, 54, 81, 41, 28, 53, 26,
1.954 + 37, 42, 58, 38, 56, 28, 27, 26, 28, 33,
1.955 + 26, 32, 61, 50, 27, 80, 76, 27, 51, 75,
1.956 + 74, 73, 30, 72, 71, 70, 69, 52, 49, 48,
1.957 + 47, 45, 39, 62, 78, 46, 79, 68, 25, 65,
1.958 + 60, 67, 66, 55, 44, 21, 63, 11, 10, 9,
1.959 + 8, 35, 7, 6, 5, 4, 3, 43, 2, 1,
1.960 + 20, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.961 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.962 + 0, 57, 0, 0, 59, 77, 0, 0, 0, 0,
1.963 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.964 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.965 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.966 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.967 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.968 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.969 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.970 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.971 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.972 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.973 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.974 + 0, 0, 0, 0, 0, 19, 14, 0, 0, 0,
1.975 + 16, 28, 22, 26, 0, 12, 13, 17, 0, 15,
1.976 + 27, 18, 31, 0, 0, 29, 0, 34, 28, 0,
1.977 + 26, 0, 0, 0, 0, 0, 0, 27, 0, 0,
1.978 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,
1.979 + 64 };
1.980 +static CONST TclDatetabelem TclDatepact[]={
1.981 +
1.982 +-10000000, -43,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,
1.983 +-10000000,-10000000, -26, -268,-10000000, -259, -226,-10000000, -257, 10,
1.984 + -227, -212, -228,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,
1.985 + -229,-10000000, -230, -240, -231,-10000000,-10000000, -264,-10000000, 9,
1.986 +-10000000,-10000000, -249,-10000000,-10000000, -246,-10000000, 4, -2, 2,
1.987 + 7, 6,-10000000,-10000000, -11, -232,-10000000,-10000000,-10000000,-10000000,
1.988 + -233,-10000000, -234, -235,-10000000, -237, -238, -239, -242,-10000000,
1.989 +-10000000,-10000000, -1,-10000000,-10000000,-10000000, -12,-10000000, -243, -263,
1.990 +-10000000,-10000000 };
1.991 +static CONST TclDatetabelem TclDatepgo[]={
1.992 +
1.993 + 0, 48, 70, 22, 69, 68, 66, 65, 64, 63,
1.994 + 62, 60, 59, 58, 57, 55 };
1.995 +static CONST TclDatetabelem TclDater1[]={
1.996 +
1.997 + 0, 4, 4, 5, 5, 5, 5, 5, 5, 5,
1.998 + 5, 5, 6, 6, 6, 6, 6, 7, 7, 7,
1.999 + 10, 10, 10, 10, 10, 8, 8, 8, 8, 8,
1.1000 + 8, 8, 8, 8, 8, 9, 9, 12, 12, 12,
1.1001 + 13, 11, 11, 15, 15, 15, 15, 15, 2, 2,
1.1002 + 1, 1, 1, 14, 3, 3 };
1.1003 +static CONST TclDatetabelem TclDater2[]={
1.1004 +
1.1005 + 0, 0, 4, 3, 3, 3, 3, 3, 3, 3,
1.1006 + 3, 2, 5, 9, 11, 13, 15, 5, 3, 3,
1.1007 + 3, 5, 5, 7, 5, 7, 11, 3, 11, 11,
1.1008 + 5, 9, 5, 3, 7, 5, 7, 7, 15, 5,
1.1009 + 9, 5, 2, 7, 5, 5, 7, 3, 3, 3,
1.1010 + 3, 3, 3, 3, 1, 3 };
1.1011 +static CONST TclDatetabelem TclDatechk[]={
1.1012 +
1.1013 +-10000000, -4, -5, -6, -7, -8, -9, -10, -11, -12,
1.1014 + -13, -14, 268, 269, 259, 272, 263, 270, 274, 258,
1.1015 + -2, -15, 265, 45, 43, -1, 266, 273, 264, 261,
1.1016 + 58, 258, 47, 45, 263, -1, 271, 269, 272, 268,
1.1017 + 258, 263, 268, -1, 44, 268, 257, 268, 268, 268,
1.1018 + 263, 268, 268, 272, 268, 44, 263, -1, 258, -1,
1.1019 + 46, -3, 45, 58, 261, 47, 45, 45, 58, 268,
1.1020 + 268, 268, 268, 268, 268, 268, 268, -3, 45, 58,
1.1021 + 268, 268 };
1.1022 +static CONST TclDatetabelem TclDatedef[]={
1.1023 +
1.1024 + 1, -2, 2, 3, 4, 5, 6, 7, 8, 9,
1.1025 + 10, 11, 53, 18, 19, 27, 0, 33, 0, 20,
1.1026 + 0, 42, 0, 48, 49, 47, 50, 51, 52, 12,
1.1027 + 0, 22, 0, 0, 32, 44, 17, 0, 39, 30,
1.1028 + 24, 35, 0, 45, 21, 0, 41, 0, 54, 25,
1.1029 + 0, 0, 34, 37, 0, 0, 36, 46, 23, 43,
1.1030 + 0, 13, 0, 0, 55, 0, 0, 0, 0, 31,
1.1031 + 40, 14, 54, 26, 28, 29, 0, 15, 0, 0,
1.1032 + 16, 38 };
1.1033 +typedef struct
1.1034 +#ifdef __cplusplus
1.1035 + TclDatetoktype
1.1036 +#endif
1.1037 +{ char *t_name; int t_val; } TclDatetoktype;
1.1038 +#ifndef YYDEBUG
1.1039 +# define YYDEBUG 0 /* don't allow debugging */
1.1040 +#endif
1.1041 +
1.1042 +#if YYDEBUG
1.1043 +
1.1044 +TclDatetoktype TclDatetoks[] =
1.1045 +{
1.1046 + "tAGO", 257,
1.1047 + "tDAY", 258,
1.1048 + "tDAYZONE", 259,
1.1049 + "tID", 260,
1.1050 + "tMERIDIAN", 261,
1.1051 + "tMINUTE_UNIT", 262,
1.1052 + "tMONTH", 263,
1.1053 + "tMONTH_UNIT", 264,
1.1054 + "tSTARDATE", 265,
1.1055 + "tSEC_UNIT", 266,
1.1056 + "tSNUMBER", 267,
1.1057 + "tUNUMBER", 268,
1.1058 + "tZONE", 269,
1.1059 + "tEPOCH", 270,
1.1060 + "tDST", 271,
1.1061 + "tISOBASE", 272,
1.1062 + "tDAY_UNIT", 273,
1.1063 + "tNEXT", 274,
1.1064 + "-unknown-", -1 /* ends search */
1.1065 +};
1.1066 +
1.1067 +char * TclDatereds[] =
1.1068 +{
1.1069 + "-no such reduction-",
1.1070 + "spec : /* empty */",
1.1071 + "spec : spec item",
1.1072 + "item : time",
1.1073 + "item : zone",
1.1074 + "item : date",
1.1075 + "item : ordMonth",
1.1076 + "item : day",
1.1077 + "item : relspec",
1.1078 + "item : iso",
1.1079 + "item : trek",
1.1080 + "item : number",
1.1081 + "time : tUNUMBER tMERIDIAN",
1.1082 + "time : tUNUMBER ':' tUNUMBER o_merid",
1.1083 + "time : tUNUMBER ':' tUNUMBER '-' tUNUMBER",
1.1084 + "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
1.1085 + "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER",
1.1086 + "zone : tZONE tDST",
1.1087 + "zone : tZONE",
1.1088 + "zone : tDAYZONE",
1.1089 + "day : tDAY",
1.1090 + "day : tDAY ','",
1.1091 + "day : tUNUMBER tDAY",
1.1092 + "day : sign tUNUMBER tDAY",
1.1093 + "day : tNEXT tDAY",
1.1094 + "date : tUNUMBER '/' tUNUMBER",
1.1095 + "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
1.1096 + "date : tISOBASE",
1.1097 + "date : tUNUMBER '-' tMONTH '-' tUNUMBER",
1.1098 + "date : tUNUMBER '-' tUNUMBER '-' tUNUMBER",
1.1099 + "date : tMONTH tUNUMBER",
1.1100 + "date : tMONTH tUNUMBER ',' tUNUMBER",
1.1101 + "date : tUNUMBER tMONTH",
1.1102 + "date : tEPOCH",
1.1103 + "date : tUNUMBER tMONTH tUNUMBER",
1.1104 + "ordMonth : tNEXT tMONTH",
1.1105 + "ordMonth : tNEXT tUNUMBER tMONTH",
1.1106 + "iso : tISOBASE tZONE tISOBASE",
1.1107 + "iso : tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER",
1.1108 + "iso : tISOBASE tISOBASE",
1.1109 + "trek : tSTARDATE tUNUMBER '.' tUNUMBER",
1.1110 + "relspec : relunits tAGO",
1.1111 + "relspec : relunits",
1.1112 + "relunits : sign tUNUMBER unit",
1.1113 + "relunits : tUNUMBER unit",
1.1114 + "relunits : tNEXT unit",
1.1115 + "relunits : tNEXT tUNUMBER unit",
1.1116 + "relunits : unit",
1.1117 + "sign : '-'",
1.1118 + "sign : '+'",
1.1119 + "unit : tSEC_UNIT",
1.1120 + "unit : tDAY_UNIT",
1.1121 + "unit : tMONTH_UNIT",
1.1122 + "number : tUNUMBER",
1.1123 + "o_merid : /* empty */",
1.1124 + "o_merid : tMERIDIAN",
1.1125 +};
1.1126 +#endif /* YYDEBUG */
1.1127 +/*
1.1128 + * Copyright (c) 1993 by Sun Microsystems, Inc.
1.1129 + */
1.1130 +
1.1131 +
1.1132 +/*
1.1133 +** Skeleton parser driver for yacc output
1.1134 +*/
1.1135 +
1.1136 +/*
1.1137 +** yacc user known macros and defines
1.1138 +*/
1.1139 +#define YYERROR goto TclDateerrlab
1.1140 +#define YYACCEPT return(0)
1.1141 +#define YYABORT return(1)
1.1142 +#define YYBACKUP( newtoken, newvalue )\
1.1143 +{\
1.1144 + if ( TclDatechar >= 0 || ( TclDater2[ TclDatetmp ] >> 1 ) != 1 )\
1.1145 + {\
1.1146 + TclDateerror( "syntax error - cannot backup" );\
1.1147 + goto TclDateerrlab;\
1.1148 + }\
1.1149 + TclDatechar = newtoken;\
1.1150 + TclDatestate = *TclDateps;\
1.1151 + TclDatelval = newvalue;\
1.1152 + goto TclDatenewstate;\
1.1153 +}
1.1154 +#define YYRECOVERING() (!!TclDateerrflag)
1.1155 +#define YYNEW(type) malloc(sizeof(type) * TclDatenewmax)
1.1156 +#define YYCOPY(to, from, type) \
1.1157 + (type *) memcpy(to, (char *) from, TclDatemaxdepth * sizeof (type))
1.1158 +#define YYENLARGE( from, type) \
1.1159 + (type *) realloc((char *) from, TclDatenewmax * sizeof(type))
1.1160 +#ifndef YYDEBUG
1.1161 +# define YYDEBUG 1 /* make debugging available */
1.1162 +#endif
1.1163 +
1.1164 +/*
1.1165 +** user known globals
1.1166 +*/
1.1167 +int TclDatedebug; /* set to 1 to get debugging */
1.1168 +
1.1169 +/*
1.1170 +** driver internal defines
1.1171 +*/
1.1172 +#define YYFLAG (-10000000)
1.1173 +
1.1174 +/*
1.1175 +** global variables used by the parser
1.1176 +*/
1.1177 +YYSTYPE *TclDatepv; /* top of value stack */
1.1178 +int *TclDateps; /* top of state stack */
1.1179 +
1.1180 +int TclDatestate; /* current state */
1.1181 +int TclDatetmp; /* extra var (lasts between blocks) */
1.1182 +
1.1183 +int TclDatenerrs; /* number of errors */
1.1184 +int TclDateerrflag; /* error recovery flag */
1.1185 +int TclDatechar; /* current input token number */
1.1186 +
1.1187 +
1.1188 +
1.1189 +#ifdef YYNMBCHARS
1.1190 +#define YYLEX() TclDatecvtok(TclDatelex())
1.1191 +/*
1.1192 +** TclDatecvtok - return a token if i is a wchar_t value that exceeds 255.
1.1193 +** If i<255, i itself is the token. If i>255 but the neither
1.1194 +** of the 30th or 31st bit is on, i is already a token.
1.1195 +*/
1.1196 +#if defined(__STDC__) || defined(__cplusplus)
1.1197 +int TclDatecvtok(int i)
1.1198 +#else
1.1199 +int TclDatecvtok(i) int i;
1.1200 +#endif
1.1201 +{
1.1202 + int first = 0;
1.1203 + int last = YYNMBCHARS - 1;
1.1204 + int mid;
1.1205 + wchar_t j;
1.1206 +
1.1207 + if(i&0x60000000){/*Must convert to a token. */
1.1208 + if( TclDatembchars[last].character < i ){
1.1209 + return i;/*Giving up*/
1.1210 + }
1.1211 + while ((last>=first)&&(first>=0)) {/*Binary search loop*/
1.1212 + mid = (first+last)/2;
1.1213 + j = TclDatembchars[mid].character;
1.1214 + if( j==i ){/*Found*/
1.1215 + return TclDatembchars[mid].tvalue;
1.1216 + }else if( j<i ){
1.1217 + first = mid + 1;
1.1218 + }else{
1.1219 + last = mid -1;
1.1220 + }
1.1221 + }
1.1222 + /*No entry in the table.*/
1.1223 + return i;/* Giving up.*/
1.1224 + }else{/* i is already a token. */
1.1225 + return i;
1.1226 + }
1.1227 +}
1.1228 +#else/*!YYNMBCHARS*/
1.1229 +#define YYLEX() TclDatelex()
1.1230 +#endif/*!YYNMBCHARS*/
1.1231 +
1.1232 +/*
1.1233 +** TclDateparse - return 0 if worked, 1 if syntax error not recovered from
1.1234 +*/
1.1235 +#if defined(__STDC__) || defined(__cplusplus)
1.1236 +int TclDateparse(void)
1.1237 +#else
1.1238 +int TclDateparse()
1.1239 +#endif
1.1240 +{
1.1241 + register YYSTYPE *TclDatepvt = 0; /* top of value stack for $vars */
1.1242 +
1.1243 +#if defined(__cplusplus) || defined(lint)
1.1244 +/*
1.1245 + hacks to please C++ and lint - goto's inside
1.1246 + switch should never be executed
1.1247 +*/
1.1248 + static int __yaccpar_lint_hack__ = 0;
1.1249 + switch (__yaccpar_lint_hack__)
1.1250 + {
1.1251 + case 1: goto TclDateerrlab;
1.1252 + case 2: goto TclDatenewstate;
1.1253 + }
1.1254 +#endif
1.1255 +
1.1256 + /*
1.1257 + ** Initialize externals - TclDateparse may be called more than once
1.1258 + */
1.1259 + TclDatepv = &TclDatev[-1];
1.1260 + TclDateps = &TclDates[-1];
1.1261 + TclDatestate = 0;
1.1262 + TclDatetmp = 0;
1.1263 + TclDatenerrs = 0;
1.1264 + TclDateerrflag = 0;
1.1265 + TclDatechar = -1;
1.1266 +
1.1267 +#if YYMAXDEPTH <= 0
1.1268 + if (TclDatemaxdepth <= 0)
1.1269 + {
1.1270 + if ((TclDatemaxdepth = YYEXPAND(0)) <= 0)
1.1271 + {
1.1272 + TclDateerror("yacc initialization error");
1.1273 + YYABORT;
1.1274 + }
1.1275 + }
1.1276 +#endif
1.1277 +
1.1278 + {
1.1279 + register YYSTYPE *TclDate_pv; /* top of value stack */
1.1280 + register int *TclDate_ps; /* top of state stack */
1.1281 + register int TclDate_state; /* current state */
1.1282 + register int TclDate_n; /* internal state number info */
1.1283 + goto TclDatestack; /* moved from 6 lines above to here to please C++ */
1.1284 +
1.1285 + /*
1.1286 + ** get globals into registers.
1.1287 + ** branch to here only if YYBACKUP was called.
1.1288 + */
1.1289 + TclDate_pv = TclDatepv;
1.1290 + TclDate_ps = TclDateps;
1.1291 + TclDate_state = TclDatestate;
1.1292 + goto TclDate_newstate;
1.1293 +
1.1294 + /*
1.1295 + ** get globals into registers.
1.1296 + ** either we just started, or we just finished a reduction
1.1297 + */
1.1298 + TclDatestack:
1.1299 + TclDate_pv = TclDatepv;
1.1300 + TclDate_ps = TclDateps;
1.1301 + TclDate_state = TclDatestate;
1.1302 +
1.1303 + /*
1.1304 + ** top of for (;;) loop while no reductions done
1.1305 + */
1.1306 + TclDate_stack:
1.1307 + /*
1.1308 + ** put a state and value onto the stacks
1.1309 + */
1.1310 +#if YYDEBUG
1.1311 + /*
1.1312 + ** if debugging, look up token value in list of value vs.
1.1313 + ** name pairs. 0 and negative (-1) are special values.
1.1314 + ** Note: linear search is used since time is not a real
1.1315 + ** consideration while debugging.
1.1316 + */
1.1317 + if ( TclDatedebug )
1.1318 + {
1.1319 + register int TclDate_i;
1.1320 +
1.1321 + printf( "State %d, token ", TclDate_state );
1.1322 + if ( TclDatechar == 0 )
1.1323 + printf( "end-of-file\n" );
1.1324 + else if ( TclDatechar < 0 )
1.1325 + printf( "-none-\n" );
1.1326 + else
1.1327 + {
1.1328 + for ( TclDate_i = 0; TclDatetoks[TclDate_i].t_val >= 0;
1.1329 + TclDate_i++ )
1.1330 + {
1.1331 + if ( TclDatetoks[TclDate_i].t_val == TclDatechar )
1.1332 + break;
1.1333 + }
1.1334 + printf( "%s\n", TclDatetoks[TclDate_i].t_name );
1.1335 + }
1.1336 + }
1.1337 +#endif /* YYDEBUG */
1.1338 + if ( ++TclDate_ps >= &TclDates[ TclDatemaxdepth ] ) /* room on stack? */
1.1339 + {
1.1340 + /*
1.1341 + ** reallocate and recover. Note that pointers
1.1342 + ** have to be reset, or bad things will happen
1.1343 + */
1.1344 + long TclDateps_index = (TclDate_ps - TclDates);
1.1345 + long TclDatepv_index = (TclDate_pv - TclDatev);
1.1346 + long TclDatepvt_index = (TclDatepvt - TclDatev);
1.1347 + int TclDatenewmax;
1.1348 +#ifdef YYEXPAND
1.1349 + TclDatenewmax = YYEXPAND(TclDatemaxdepth);
1.1350 +#else
1.1351 + TclDatenewmax = 2 * TclDatemaxdepth; /* double table size */
1.1352 + if (TclDatemaxdepth == YYMAXDEPTH) /* first time growth */
1.1353 + {
1.1354 + char *newTclDates = (char *)YYNEW(int);
1.1355 + char *newTclDatev = (char *)YYNEW(YYSTYPE);
1.1356 + if (newTclDates != 0 && newTclDatev != 0)
1.1357 + {
1.1358 + TclDates = YYCOPY(newTclDates, TclDates, int);
1.1359 + TclDatev = YYCOPY(newTclDatev, TclDatev, YYSTYPE);
1.1360 + }
1.1361 + else
1.1362 + TclDatenewmax = 0; /* failed */
1.1363 + }
1.1364 + else /* not first time */
1.1365 + {
1.1366 + TclDates = YYENLARGE(TclDates, int);
1.1367 + TclDatev = YYENLARGE(TclDatev, YYSTYPE);
1.1368 + if (TclDates == 0 || TclDatev == 0)
1.1369 + TclDatenewmax = 0; /* failed */
1.1370 + }
1.1371 +#endif
1.1372 + if (TclDatenewmax <= TclDatemaxdepth) /* tables not expanded */
1.1373 + {
1.1374 + TclDateerror( "yacc stack overflow" );
1.1375 + YYABORT;
1.1376 + }
1.1377 + TclDatemaxdepth = TclDatenewmax;
1.1378 +
1.1379 + TclDate_ps = TclDates + TclDateps_index;
1.1380 + TclDate_pv = TclDatev + TclDatepv_index;
1.1381 + TclDatepvt = TclDatev + TclDatepvt_index;
1.1382 + }
1.1383 + *TclDate_ps = TclDate_state;
1.1384 + *++TclDate_pv = TclDateval;
1.1385 +
1.1386 + /*
1.1387 + ** we have a new state - find out what to do
1.1388 + */
1.1389 + TclDate_newstate:
1.1390 + if ( ( TclDate_n = TclDatepact[ TclDate_state ] ) <= YYFLAG )
1.1391 + goto TclDatedefault; /* simple state */
1.1392 +#if YYDEBUG
1.1393 + /*
1.1394 + ** if debugging, need to mark whether new token grabbed
1.1395 + */
1.1396 + TclDatetmp = TclDatechar < 0;
1.1397 +#endif
1.1398 + if ( ( TclDatechar < 0 ) && ( ( TclDatechar = YYLEX() ) < 0 ) )
1.1399 + TclDatechar = 0; /* reached EOF */
1.1400 +#if YYDEBUG
1.1401 + if ( TclDatedebug && TclDatetmp )
1.1402 + {
1.1403 + register int TclDate_i;
1.1404 +
1.1405 + printf( "Received token " );
1.1406 + if ( TclDatechar == 0 )
1.1407 + printf( "end-of-file\n" );
1.1408 + else if ( TclDatechar < 0 )
1.1409 + printf( "-none-\n" );
1.1410 + else
1.1411 + {
1.1412 + for ( TclDate_i = 0; TclDatetoks[TclDate_i].t_val >= 0;
1.1413 + TclDate_i++ )
1.1414 + {
1.1415 + if ( TclDatetoks[TclDate_i].t_val == TclDatechar )
1.1416 + break;
1.1417 + }
1.1418 + printf( "%s\n", TclDatetoks[TclDate_i].t_name );
1.1419 + }
1.1420 + }
1.1421 +#endif /* YYDEBUG */
1.1422 + if ( ( ( TclDate_n += TclDatechar ) < 0 ) || ( TclDate_n >= YYLAST ) )
1.1423 + goto TclDatedefault;
1.1424 + if ( TclDatechk[ TclDate_n = TclDateact[ TclDate_n ] ] == TclDatechar ) /*valid shift*/
1.1425 + {
1.1426 + TclDatechar = -1;
1.1427 + TclDateval = TclDatelval;
1.1428 + TclDate_state = TclDate_n;
1.1429 + if ( TclDateerrflag > 0 )
1.1430 + TclDateerrflag--;
1.1431 + goto TclDate_stack;
1.1432 + }
1.1433 +
1.1434 + TclDatedefault:
1.1435 + if ( ( TclDate_n = TclDatedef[ TclDate_state ] ) == -2 )
1.1436 + {
1.1437 +#if YYDEBUG
1.1438 + TclDatetmp = TclDatechar < 0;
1.1439 +#endif
1.1440 + if ( ( TclDatechar < 0 ) && ( ( TclDatechar = YYLEX() ) < 0 ) )
1.1441 + TclDatechar = 0; /* reached EOF */
1.1442 +#if YYDEBUG
1.1443 + if ( TclDatedebug && TclDatetmp )
1.1444 + {
1.1445 + register int TclDate_i;
1.1446 +
1.1447 + printf( "Received token " );
1.1448 + if ( TclDatechar == 0 )
1.1449 + printf( "end-of-file\n" );
1.1450 + else if ( TclDatechar < 0 )
1.1451 + printf( "-none-\n" );
1.1452 + else
1.1453 + {
1.1454 + for ( TclDate_i = 0;
1.1455 + TclDatetoks[TclDate_i].t_val >= 0;
1.1456 + TclDate_i++ )
1.1457 + {
1.1458 + if ( TclDatetoks[TclDate_i].t_val
1.1459 + == TclDatechar )
1.1460 + {
1.1461 + break;
1.1462 + }
1.1463 + }
1.1464 + printf( "%s\n", TclDatetoks[TclDate_i].t_name );
1.1465 + }
1.1466 + }
1.1467 +#endif /* YYDEBUG */
1.1468 + /*
1.1469 + ** look through exception table
1.1470 + */
1.1471 + {
1.1472 + register CONST int *TclDatexi = TclDateexca;
1.1473 +
1.1474 + while ( ( *TclDatexi != -1 ) ||
1.1475 + ( TclDatexi[1] != TclDate_state ) )
1.1476 + {
1.1477 + TclDatexi += 2;
1.1478 + }
1.1479 + while ( ( *(TclDatexi += 2) >= 0 ) &&
1.1480 + ( *TclDatexi != TclDatechar ) )
1.1481 + ;
1.1482 + if ( ( TclDate_n = TclDatexi[1] ) < 0 )
1.1483 + YYACCEPT;
1.1484 + }
1.1485 + }
1.1486 +
1.1487 + /*
1.1488 + ** check for syntax error
1.1489 + */
1.1490 + if ( TclDate_n == 0 ) /* have an error */
1.1491 + {
1.1492 + /* no worry about speed here! */
1.1493 + switch ( TclDateerrflag )
1.1494 + {
1.1495 + case 0: /* new error */
1.1496 + TclDateerror( "syntax error" );
1.1497 + goto skip_init;
1.1498 + /*
1.1499 + ** get globals into registers.
1.1500 + ** we have a user generated syntax type error
1.1501 + */
1.1502 + TclDate_pv = TclDatepv;
1.1503 + TclDate_ps = TclDateps;
1.1504 + TclDate_state = TclDatestate;
1.1505 + skip_init:
1.1506 + TclDatenerrs++;
1.1507 + /* FALLTHRU */
1.1508 + case 1:
1.1509 + case 2: /* incompletely recovered error */
1.1510 + /* try again... */
1.1511 + TclDateerrflag = 3;
1.1512 + /*
1.1513 + ** find state where "error" is a legal
1.1514 + ** shift action
1.1515 + */
1.1516 + while ( TclDate_ps >= TclDates )
1.1517 + {
1.1518 + TclDate_n = TclDatepact[ *TclDate_ps ] + YYERRCODE;
1.1519 + if ( TclDate_n >= 0 && TclDate_n < YYLAST &&
1.1520 + TclDatechk[TclDateact[TclDate_n]] == YYERRCODE) {
1.1521 + /*
1.1522 + ** simulate shift of "error"
1.1523 + */
1.1524 + TclDate_state = TclDateact[ TclDate_n ];
1.1525 + goto TclDate_stack;
1.1526 + }
1.1527 + /*
1.1528 + ** current state has no shift on
1.1529 + ** "error", pop stack
1.1530 + */
1.1531 +#if YYDEBUG
1.1532 +# define _POP_ "Error recovery pops state %d, uncovers state %d\n"
1.1533 + if ( TclDatedebug )
1.1534 + printf( _POP_, *TclDate_ps,
1.1535 + TclDate_ps[-1] );
1.1536 +# undef _POP_
1.1537 +#endif
1.1538 + TclDate_ps--;
1.1539 + TclDate_pv--;
1.1540 + }
1.1541 + /*
1.1542 + ** there is no state on stack with "error" as
1.1543 + ** a valid shift. give up.
1.1544 + */
1.1545 + YYABORT;
1.1546 + case 3: /* no shift yet; eat a token */
1.1547 +#if YYDEBUG
1.1548 + /*
1.1549 + ** if debugging, look up token in list of
1.1550 + ** pairs. 0 and negative shouldn't occur,
1.1551 + ** but since timing doesn't matter when
1.1552 + ** debugging, it doesn't hurt to leave the
1.1553 + ** tests here.
1.1554 + */
1.1555 + if ( TclDatedebug )
1.1556 + {
1.1557 + register int TclDate_i;
1.1558 +
1.1559 + printf( "Error recovery discards " );
1.1560 + if ( TclDatechar == 0 )
1.1561 + printf( "token end-of-file\n" );
1.1562 + else if ( TclDatechar < 0 )
1.1563 + printf( "token -none-\n" );
1.1564 + else
1.1565 + {
1.1566 + for ( TclDate_i = 0;
1.1567 + TclDatetoks[TclDate_i].t_val >= 0;
1.1568 + TclDate_i++ )
1.1569 + {
1.1570 + if ( TclDatetoks[TclDate_i].t_val
1.1571 + == TclDatechar )
1.1572 + {
1.1573 + break;
1.1574 + }
1.1575 + }
1.1576 + printf( "token %s\n",
1.1577 + TclDatetoks[TclDate_i].t_name );
1.1578 + }
1.1579 + }
1.1580 +#endif /* YYDEBUG */
1.1581 + if ( TclDatechar == 0 ) /* reached EOF. quit */
1.1582 + YYABORT;
1.1583 + TclDatechar = -1;
1.1584 + goto TclDate_newstate;
1.1585 + }
1.1586 + }/* end if ( TclDate_n == 0 ) */
1.1587 + /*
1.1588 + ** reduction by production TclDate_n
1.1589 + ** put stack tops, etc. so things right after switch
1.1590 + */
1.1591 +#if YYDEBUG
1.1592 + /*
1.1593 + ** if debugging, print the string that is the user's
1.1594 + ** specification of the reduction which is just about
1.1595 + ** to be done.
1.1596 + */
1.1597 + if ( TclDatedebug )
1.1598 + printf( "Reduce by (%d) \"%s\"\n",
1.1599 + TclDate_n, TclDatereds[ TclDate_n ] );
1.1600 +#endif
1.1601 + TclDatetmp = TclDate_n; /* value to switch over */
1.1602 + TclDatepvt = TclDate_pv; /* $vars top of value stack */
1.1603 + /*
1.1604 + ** Look in goto table for next state
1.1605 + ** Sorry about using TclDate_state here as temporary
1.1606 + ** register variable, but why not, if it works...
1.1607 + ** If TclDater2[ TclDate_n ] doesn't have the low order bit
1.1608 + ** set, then there is no action to be done for
1.1609 + ** this reduction. So, no saving & unsaving of
1.1610 + ** registers done. The only difference between the
1.1611 + ** code just after the if and the body of the if is
1.1612 + ** the goto TclDate_stack in the body. This way the test
1.1613 + ** can be made before the choice of what to do is needed.
1.1614 + */
1.1615 + {
1.1616 + /* length of production doubled with extra bit */
1.1617 + register int TclDate_len = TclDater2[ TclDate_n ];
1.1618 +
1.1619 + if ( !( TclDate_len & 01 ) )
1.1620 + {
1.1621 + TclDate_len >>= 1;
1.1622 + TclDateval = ( TclDate_pv -= TclDate_len )[1]; /* $$ = $1 */
1.1623 + TclDate_state = TclDatepgo[ TclDate_n = TclDater1[ TclDate_n ] ] +
1.1624 + *( TclDate_ps -= TclDate_len ) + 1;
1.1625 + if ( TclDate_state >= YYLAST ||
1.1626 + TclDatechk[ TclDate_state =
1.1627 + TclDateact[ TclDate_state ] ] != -TclDate_n )
1.1628 + {
1.1629 + TclDate_state = TclDateact[ TclDatepgo[ TclDate_n ] ];
1.1630 + }
1.1631 + goto TclDate_stack;
1.1632 + }
1.1633 + TclDate_len >>= 1;
1.1634 + TclDateval = ( TclDate_pv -= TclDate_len )[1]; /* $$ = $1 */
1.1635 + TclDate_state = TclDatepgo[ TclDate_n = TclDater1[ TclDate_n ] ] +
1.1636 + *( TclDate_ps -= TclDate_len ) + 1;
1.1637 + if ( TclDate_state >= YYLAST ||
1.1638 + TclDatechk[ TclDate_state = TclDateact[ TclDate_state ] ] != -TclDate_n )
1.1639 + {
1.1640 + TclDate_state = TclDateact[ TclDatepgo[ TclDate_n ] ];
1.1641 + }
1.1642 + }
1.1643 + /* save until reenter driver code */
1.1644 + TclDatestate = TclDate_state;
1.1645 + TclDateps = TclDate_ps;
1.1646 + TclDatepv = TclDate_pv;
1.1647 + }
1.1648 + /*
1.1649 + ** code supplied by user is placed in this switch
1.1650 + */
1.1651 + switch( TclDatetmp )
1.1652 + {
1.1653 +
1.1654 +case 3:{
1.1655 + TclDateHaveTime++;
1.1656 + } break;
1.1657 +case 4:{
1.1658 + TclDateHaveZone++;
1.1659 + } break;
1.1660 +case 5:{
1.1661 + TclDateHaveDate++;
1.1662 + } break;
1.1663 +case 6:{
1.1664 + TclDateHaveOrdinalMonth++;
1.1665 + } break;
1.1666 +case 7:{
1.1667 + TclDateHaveDay++;
1.1668 + } break;
1.1669 +case 8:{
1.1670 + TclDateHaveRel++;
1.1671 + } break;
1.1672 +case 9:{
1.1673 + TclDateHaveTime++;
1.1674 + TclDateHaveDate++;
1.1675 + } break;
1.1676 +case 10:{
1.1677 + TclDateHaveTime++;
1.1678 + TclDateHaveDate++;
1.1679 + TclDateHaveRel++;
1.1680 + } break;
1.1681 +case 12:{
1.1682 + TclDateHour = TclDatepvt[-1].Number;
1.1683 + TclDateMinutes = 0;
1.1684 + TclDateSeconds = 0;
1.1685 + TclDateMeridian = TclDatepvt[-0].Meridian;
1.1686 + } break;
1.1687 +case 13:{
1.1688 + TclDateHour = TclDatepvt[-3].Number;
1.1689 + TclDateMinutes = TclDatepvt[-1].Number;
1.1690 + TclDateSeconds = 0;
1.1691 + TclDateMeridian = TclDatepvt[-0].Meridian;
1.1692 + } break;
1.1693 +case 14:{
1.1694 + TclDateHour = TclDatepvt[-4].Number;
1.1695 + TclDateMinutes = TclDatepvt[-2].Number;
1.1696 + TclDateMeridian = MER24;
1.1697 + TclDateDSTmode = DSToff;
1.1698 + TclDateTimezone = (TclDatepvt[-0].Number % 100 + (TclDatepvt[-0].Number / 100) * 60);
1.1699 + } break;
1.1700 +case 15:{
1.1701 + TclDateHour = TclDatepvt[-5].Number;
1.1702 + TclDateMinutes = TclDatepvt[-3].Number;
1.1703 + TclDateSeconds = TclDatepvt[-1].Number;
1.1704 + TclDateMeridian = TclDatepvt[-0].Meridian;
1.1705 + } break;
1.1706 +case 16:{
1.1707 + TclDateHour = TclDatepvt[-6].Number;
1.1708 + TclDateMinutes = TclDatepvt[-4].Number;
1.1709 + TclDateSeconds = TclDatepvt[-2].Number;
1.1710 + TclDateMeridian = MER24;
1.1711 + TclDateDSTmode = DSToff;
1.1712 + TclDateTimezone = (TclDatepvt[-0].Number % 100 + (TclDatepvt[-0].Number / 100) * 60);
1.1713 + } break;
1.1714 +case 17:{
1.1715 + TclDateTimezone = TclDatepvt[-1].Number;
1.1716 + TclDateDSTmode = DSTon;
1.1717 + } break;
1.1718 +case 18:{
1.1719 + TclDateTimezone = TclDatepvt[-0].Number;
1.1720 + TclDateDSTmode = DSToff;
1.1721 + } break;
1.1722 +case 19:{
1.1723 + TclDateTimezone = TclDatepvt[-0].Number;
1.1724 + TclDateDSTmode = DSTon;
1.1725 + } break;
1.1726 +case 20:{
1.1727 + TclDateDayOrdinal = 1;
1.1728 + TclDateDayNumber = TclDatepvt[-0].Number;
1.1729 + } break;
1.1730 +case 21:{
1.1731 + TclDateDayOrdinal = 1;
1.1732 + TclDateDayNumber = TclDatepvt[-1].Number;
1.1733 + } break;
1.1734 +case 22:{
1.1735 + TclDateDayOrdinal = TclDatepvt[-1].Number;
1.1736 + TclDateDayNumber = TclDatepvt[-0].Number;
1.1737 + } break;
1.1738 +case 23:{
1.1739 + TclDateDayOrdinal = TclDatepvt[-2].Number * TclDatepvt[-1].Number;
1.1740 + TclDateDayNumber = TclDatepvt[-0].Number;
1.1741 + } break;
1.1742 +case 24:{
1.1743 + TclDateDayOrdinal = 2;
1.1744 + TclDateDayNumber = TclDatepvt[-0].Number;
1.1745 + } break;
1.1746 +case 25:{
1.1747 + TclDateMonth = TclDatepvt[-2].Number;
1.1748 + TclDateDay = TclDatepvt[-0].Number;
1.1749 + } break;
1.1750 +case 26:{
1.1751 + TclDateMonth = TclDatepvt[-4].Number;
1.1752 + TclDateDay = TclDatepvt[-2].Number;
1.1753 + TclDateYear = TclDatepvt[-0].Number;
1.1754 + } break;
1.1755 +case 27:{
1.1756 + TclDateYear = TclDatepvt[-0].Number / 10000;
1.1757 + TclDateMonth = (TclDatepvt[-0].Number % 10000)/100;
1.1758 + TclDateDay = TclDatepvt[-0].Number % 100;
1.1759 + } break;
1.1760 +case 28:{
1.1761 + TclDateDay = TclDatepvt[-4].Number;
1.1762 + TclDateMonth = TclDatepvt[-2].Number;
1.1763 + TclDateYear = TclDatepvt[-0].Number;
1.1764 + } break;
1.1765 +case 29:{
1.1766 + TclDateMonth = TclDatepvt[-2].Number;
1.1767 + TclDateDay = TclDatepvt[-0].Number;
1.1768 + TclDateYear = TclDatepvt[-4].Number;
1.1769 + } break;
1.1770 +case 30:{
1.1771 + TclDateMonth = TclDatepvt[-1].Number;
1.1772 + TclDateDay = TclDatepvt[-0].Number;
1.1773 + } break;
1.1774 +case 31:{
1.1775 + TclDateMonth = TclDatepvt[-3].Number;
1.1776 + TclDateDay = TclDatepvt[-2].Number;
1.1777 + TclDateYear = TclDatepvt[-0].Number;
1.1778 + } break;
1.1779 +case 32:{
1.1780 + TclDateMonth = TclDatepvt[-0].Number;
1.1781 + TclDateDay = TclDatepvt[-1].Number;
1.1782 + } break;
1.1783 +case 33:{
1.1784 + TclDateMonth = 1;
1.1785 + TclDateDay = 1;
1.1786 + TclDateYear = EPOCH;
1.1787 + } break;
1.1788 +case 34:{
1.1789 + TclDateMonth = TclDatepvt[-1].Number;
1.1790 + TclDateDay = TclDatepvt[-2].Number;
1.1791 + TclDateYear = TclDatepvt[-0].Number;
1.1792 + } break;
1.1793 +case 35:{
1.1794 + TclDateMonthOrdinal = 1;
1.1795 + TclDateMonth = TclDatepvt[-0].Number;
1.1796 + } break;
1.1797 +case 36:{
1.1798 + TclDateMonthOrdinal = TclDatepvt[-1].Number;
1.1799 + TclDateMonth = TclDatepvt[-0].Number;
1.1800 + } break;
1.1801 +case 37:{
1.1802 + if (TclDatepvt[-1].Number != HOUR(- 7)) YYABORT;
1.1803 + TclDateYear = TclDatepvt[-2].Number / 10000;
1.1804 + TclDateMonth = (TclDatepvt[-2].Number % 10000)/100;
1.1805 + TclDateDay = TclDatepvt[-2].Number % 100;
1.1806 + TclDateHour = TclDatepvt[-0].Number / 10000;
1.1807 + TclDateMinutes = (TclDatepvt[-0].Number % 10000)/100;
1.1808 + TclDateSeconds = TclDatepvt[-0].Number % 100;
1.1809 + } break;
1.1810 +case 38:{
1.1811 + if (TclDatepvt[-5].Number != HOUR(- 7)) YYABORT;
1.1812 + TclDateYear = TclDatepvt[-6].Number / 10000;
1.1813 + TclDateMonth = (TclDatepvt[-6].Number % 10000)/100;
1.1814 + TclDateDay = TclDatepvt[-6].Number % 100;
1.1815 + TclDateHour = TclDatepvt[-4].Number;
1.1816 + TclDateMinutes = TclDatepvt[-2].Number;
1.1817 + TclDateSeconds = TclDatepvt[-0].Number;
1.1818 + } break;
1.1819 +case 39:{
1.1820 + TclDateYear = TclDatepvt[-1].Number / 10000;
1.1821 + TclDateMonth = (TclDatepvt[-1].Number % 10000)/100;
1.1822 + TclDateDay = TclDatepvt[-1].Number % 100;
1.1823 + TclDateHour = TclDatepvt[-0].Number / 10000;
1.1824 + TclDateMinutes = (TclDatepvt[-0].Number % 10000)/100;
1.1825 + TclDateSeconds = TclDatepvt[-0].Number % 100;
1.1826 + } break;
1.1827 +case 40:{
1.1828 + /*
1.1829 + * Offset computed year by -377 so that the returned years will
1.1830 + * be in a range accessible with a 32 bit clock seconds value
1.1831 + */
1.1832 + TclDateYear = TclDatepvt[-2].Number/1000 + 2323 - 377;
1.1833 + TclDateDay = 1;
1.1834 + TclDateMonth = 1;
1.1835 + TclDateRelDay += ((TclDatepvt[-2].Number%1000)*(365 + IsLeapYear(TclDateYear)))/1000;
1.1836 + TclDateRelSeconds += TclDatepvt[-0].Number * 144 * 60;
1.1837 + } break;
1.1838 +case 41:{
1.1839 + TclDateRelSeconds *= -1;
1.1840 + TclDateRelMonth *= -1;
1.1841 + TclDateRelDay *= -1;
1.1842 + } break;
1.1843 +case 43:{ *TclDateRelPointer += TclDatepvt[-2].Number * TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1.1844 +case 44:{ *TclDateRelPointer += TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1.1845 +case 45:{ *TclDateRelPointer += TclDatepvt[-0].Number; } break;
1.1846 +case 46:{ *TclDateRelPointer += TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1.1847 +case 47:{ *TclDateRelPointer += TclDatepvt[-0].Number; } break;
1.1848 +case 48:{ TclDateval.Number = -1; } break;
1.1849 +case 49:{ TclDateval.Number = 1; } break;
1.1850 +case 50:{ TclDateval.Number = TclDatepvt[-0].Number; TclDateRelPointer = &TclDateRelSeconds; } break;
1.1851 +case 51:{ TclDateval.Number = TclDatepvt[-0].Number; TclDateRelPointer = &TclDateRelDay; } break;
1.1852 +case 52:{ TclDateval.Number = TclDatepvt[-0].Number; TclDateRelPointer = &TclDateRelMonth; } break;
1.1853 +case 53:{
1.1854 + if (TclDateHaveTime && TclDateHaveDate && !TclDateHaveRel) {
1.1855 + TclDateYear = TclDatepvt[-0].Number;
1.1856 + } else {
1.1857 + TclDateHaveTime++;
1.1858 + if (TclDatepvt[-0].Number < 100) {
1.1859 + TclDateHour = TclDatepvt[-0].Number;
1.1860 + TclDateMinutes = 0;
1.1861 + } else {
1.1862 + TclDateHour = TclDatepvt[-0].Number / 100;
1.1863 + TclDateMinutes = TclDatepvt[-0].Number % 100;
1.1864 + }
1.1865 + TclDateSeconds = 0;
1.1866 + TclDateMeridian = MER24;
1.1867 + }
1.1868 + } break;
1.1869 +case 54:{
1.1870 + TclDateval.Meridian = MER24;
1.1871 + } break;
1.1872 +case 55:{
1.1873 + TclDateval.Meridian = TclDatepvt[-0].Meridian;
1.1874 + } break;
1.1875 + }
1.1876 + goto TclDatestack; /* reset registers in driver code */
1.1877 +}
1.1878 +