os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclGetDate.y
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 +}