/[dtapublic]/projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tcldate.c
ViewVC logotype

Annotation of /projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tcldate.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (hide annotations) (download)
Fri Oct 14 01:50:00 2016 UTC (7 years, 1 month ago) by dashley
Original Path: projs/trunk/shared_source/tcl_base/tcldate.c
File MIME type: text/plain
File size: 57952 byte(s)
Move shared source code to commonize.
1 dashley 25 /* $Header: /cvsroot/esrg/sfesrg/esrgpcpj/shared/tcl_base/tcldate.c,v 1.1.1.1 2001/06/13 04:36:47 dtashley Exp $ */
2    
3     /*
4     * tclDate.c --
5     *
6     * This file is generated from a yacc grammar defined in
7     * the file tclGetDate.y. It should not be edited directly.
8     *
9     * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
10     * Copyright (c) 1995-1997 Sun Microsystems, Inc.
11     *
12     * See the file "license.terms" for information on usage and redistribution
13     * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14     *
15     * RCS: @(#) $Id: tcldate.c,v 1.1.1.1 2001/06/13 04:36:47 dtashley Exp $
16     */
17    
18     #include "tclInt.h"
19     #include "tclPort.h"
20    
21     #ifdef MAC_TCL
22     # define EPOCH 1904
23     # define START_OF_TIME 1904
24     # define END_OF_TIME 2039
25     #else
26     # define EPOCH 1970
27     # define START_OF_TIME 1902
28     # define END_OF_TIME 2037
29     #endif
30    
31     /*
32     * The offset of tm_year of struct tm returned by localtime, gmtime, etc.
33     * I don't know how universal this is; K&R II, the NetBSD manpages, and
34     * ../compat/strftime.c all agree that tm_year is the year-1900. However,
35     * some systems may have a different value. This #define should be the
36     * same as in ../compat/strftime.c.
37     */
38     #define TM_YEAR_BASE 1900
39    
40     #define HOUR(x) ((int) (60 * x))
41     #define SECSPERDAY (24L * 60L * 60L)
42     #define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
43    
44     /*
45     * An entry in the lexical lookup table.
46     */
47     typedef struct _TABLE {
48     char *name;
49     int type;
50     time_t value;
51     } TABLE;
52    
53    
54     /*
55     * Daylight-savings mode: on, off, or not yet known.
56     */
57     typedef enum _DSTMODE {
58     DSTon, DSToff, DSTmaybe
59     } DSTMODE;
60    
61     /*
62     * Meridian: am, pm, or 24-hour style.
63     */
64     typedef enum _MERIDIAN {
65     MERam, MERpm, MER24
66     } MERIDIAN;
67    
68    
69     /*
70     * Global variables. We could get rid of most of these by using a good
71     * union as the yacc stack. (This routine was originally written before
72     * yacc had the %union construct.) Maybe someday; right now we only use
73     * the %union very rarely.
74     */
75     static char *TclDateInput;
76     static DSTMODE TclDateDSTmode;
77     static time_t TclDateDayOrdinal;
78     static time_t TclDateDayNumber;
79     static time_t TclDateMonthOrdinal;
80     static int TclDateHaveDate;
81     static int TclDateHaveDay;
82     static int TclDateHaveOrdinalMonth;
83     static int TclDateHaveRel;
84     static int TclDateHaveTime;
85     static int TclDateHaveZone;
86     static time_t TclDateTimezone;
87     static time_t TclDateDay;
88     static time_t TclDateHour;
89     static time_t TclDateMinutes;
90     static time_t TclDateMonth;
91     static time_t TclDateSeconds;
92     static time_t TclDateYear;
93     static MERIDIAN TclDateMeridian;
94     static time_t TclDateRelMonth;
95     static time_t TclDateRelDay;
96     static time_t TclDateRelSeconds;
97     static time_t *TclDateRelPointer;
98    
99     /*
100     * Prototypes of internal functions.
101     */
102     static void TclDateerror _ANSI_ARGS_((char *s));
103     static time_t ToSeconds _ANSI_ARGS_((time_t Hours, time_t Minutes,
104     time_t Seconds, MERIDIAN Meridian));
105     static int Convert _ANSI_ARGS_((time_t Month, time_t Day, time_t Year,
106     time_t Hours, time_t Minutes, time_t Seconds,
107     MERIDIAN Meridia, DSTMODE DSTmode, time_t *TimePtr));
108     static time_t DSTcorrect _ANSI_ARGS_((time_t Start, time_t Future));
109     static time_t NamedDay _ANSI_ARGS_((time_t Start, time_t DayOrdinal,
110     time_t DayNumber));
111     static time_t NamedMonth _ANSI_ARGS_((time_t Start, time_t MonthOrdinal,
112     time_t MonthNumber));
113     static int RelativeMonth _ANSI_ARGS_((time_t Start, time_t RelMonth,
114     time_t *TimePtr));
115     static int RelativeDay _ANSI_ARGS_((time_t Start, time_t RelDay,
116     time_t *TimePtr));
117     static int LookupWord _ANSI_ARGS_((char *buff));
118     static int TclDatelex _ANSI_ARGS_((void));
119    
120     int
121     TclDateparse _ANSI_ARGS_((void));
122     typedef union
123     #ifdef __cplusplus
124     YYSTYPE
125     #endif
126     {
127     time_t Number;
128     enum _MERIDIAN Meridian;
129     } YYSTYPE;
130     # define tAGO 257
131     # define tDAY 258
132     # define tDAYZONE 259
133     # define tID 260
134     # define tMERIDIAN 261
135     # define tMINUTE_UNIT 262
136     # define tMONTH 263
137     # define tMONTH_UNIT 264
138     # define tSTARDATE 265
139     # define tSEC_UNIT 266
140     # define tSNUMBER 267
141     # define tUNUMBER 268
142     # define tZONE 269
143     # define tEPOCH 270
144     # define tDST 271
145     # define tISOBASE 272
146     # define tDAY_UNIT 273
147     # define tNEXT 274
148    
149    
150    
151    
152     #if defined(__cplusplus) || defined(__STDC__)
153    
154     #if defined(__cplusplus) && defined(__EXTERN_C__)
155     extern "C" {
156     #endif
157     #ifndef TclDateerror
158     #if defined(__cplusplus)
159     void TclDateerror(CONST char *);
160     #endif
161     #endif
162     #ifndef TclDatelex
163     int TclDatelex(void);
164     #endif
165     int TclDateparse(void);
166     #if defined(__cplusplus) && defined(__EXTERN_C__)
167     }
168     #endif
169    
170     #endif
171    
172     #define TclDateclearin TclDatechar = -1
173     #define TclDateerrok TclDateerrflag = 0
174     extern int TclDatechar;
175     extern int TclDateerrflag;
176     YYSTYPE TclDatelval;
177     YYSTYPE TclDateval;
178     typedef int TclDatetabelem;
179     #ifndef YYMAXDEPTH
180     #define YYMAXDEPTH 150
181     #endif
182     #if YYMAXDEPTH > 0
183     int TclDate_TclDates[YYMAXDEPTH], *TclDates = TclDate_TclDates;
184     YYSTYPE TclDate_TclDatev[YYMAXDEPTH], *TclDatev = TclDate_TclDatev;
185     #else /* user does initial allocation */
186     int *TclDates;
187     YYSTYPE *TclDatev;
188     #endif
189     static int TclDatemaxdepth = YYMAXDEPTH;
190     # define YYERRCODE 256
191    
192    
193     /*
194     * Month and day table.
195     */
196     static TABLE MonthDayTable[] = {
197     { "january", tMONTH, 1 },
198     { "february", tMONTH, 2 },
199     { "march", tMONTH, 3 },
200     { "april", tMONTH, 4 },
201     { "may", tMONTH, 5 },
202     { "june", tMONTH, 6 },
203     { "july", tMONTH, 7 },
204     { "august", tMONTH, 8 },
205     { "september", tMONTH, 9 },
206     { "sept", tMONTH, 9 },
207     { "october", tMONTH, 10 },
208     { "november", tMONTH, 11 },
209     { "december", tMONTH, 12 },
210     { "sunday", tDAY, 0 },
211     { "monday", tDAY, 1 },
212     { "tuesday", tDAY, 2 },
213     { "tues", tDAY, 2 },
214     { "wednesday", tDAY, 3 },
215     { "wednes", tDAY, 3 },
216     { "thursday", tDAY, 4 },
217     { "thur", tDAY, 4 },
218     { "thurs", tDAY, 4 },
219     { "friday", tDAY, 5 },
220     { "saturday", tDAY, 6 },
221     { NULL }
222     };
223    
224     /*
225     * Time units table.
226     */
227     static TABLE UnitsTable[] = {
228     { "year", tMONTH_UNIT, 12 },
229     { "month", tMONTH_UNIT, 1 },
230     { "fortnight", tDAY_UNIT, 14 },
231     { "week", tDAY_UNIT, 7 },
232     { "day", tDAY_UNIT, 1 },
233     { "hour", tSEC_UNIT, 60 * 60 },
234     { "minute", tSEC_UNIT, 60 },
235     { "min", tSEC_UNIT, 60 },
236     { "second", tSEC_UNIT, 1 },
237     { "sec", tSEC_UNIT, 1 },
238     { NULL }
239     };
240    
241     /*
242     * Assorted relative-time words.
243     */
244     static TABLE OtherTable[] = {
245     { "tomorrow", tDAY_UNIT, 1 },
246     { "yesterday", tDAY_UNIT, -1 },
247     { "today", tDAY_UNIT, 0 },
248     { "now", tSEC_UNIT, 0 },
249     { "last", tUNUMBER, -1 },
250     { "this", tSEC_UNIT, 0 },
251     { "next", tNEXT, 1 },
252     #if 0
253     { "first", tUNUMBER, 1 },
254     { "second", tUNUMBER, 2 },
255     { "third", tUNUMBER, 3 },
256     { "fourth", tUNUMBER, 4 },
257     { "fifth", tUNUMBER, 5 },
258     { "sixth", tUNUMBER, 6 },
259     { "seventh", tUNUMBER, 7 },
260     { "eighth", tUNUMBER, 8 },
261     { "ninth", tUNUMBER, 9 },
262     { "tenth", tUNUMBER, 10 },
263     { "eleventh", tUNUMBER, 11 },
264     { "twelfth", tUNUMBER, 12 },
265     #endif
266     { "ago", tAGO, 1 },
267     { "epoch", tEPOCH, 0 },
268     { "stardate", tSTARDATE, 0},
269     { NULL }
270     };
271    
272     /*
273     * The timezone table. (Note: This table was modified to not use any floating
274     * point constants to work around an SGI compiler bug).
275     */
276     static TABLE TimezoneTable[] = {
277     { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
278     { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
279     { "utc", tZONE, HOUR( 0) },
280     { "uct", tZONE, HOUR( 0) }, /* Universal Coordinated Time */
281     { "wet", tZONE, HOUR( 0) }, /* Western European */
282     { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
283     { "wat", tZONE, HOUR( 1) }, /* West Africa */
284     { "at", tZONE, HOUR( 2) }, /* Azores */
285     #if 0
286     /* For completeness. BST is also British Summer, and GST is
287     * also Guam Standard. */
288     { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
289     { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
290     #endif
291     { "nft", tZONE, HOUR( 7/2) }, /* Newfoundland */
292     { "nst", tZONE, HOUR( 7/2) }, /* Newfoundland Standard */
293     { "ndt", tDAYZONE, HOUR( 7/2) }, /* Newfoundland Daylight */
294     { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
295     { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
296     { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
297     { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
298     { "cst", tZONE, HOUR( 6) }, /* Central Standard */
299     { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
300     { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
301     { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
302     { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
303     { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
304     { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
305     { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
306     { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
307     { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
308     { "cat", tZONE, HOUR(10) }, /* Central Alaska */
309     { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
310     { "nt", tZONE, HOUR(11) }, /* Nome */
311     { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
312     { "cet", tZONE, -HOUR( 1) }, /* Central European */
313     { "cest", tDAYZONE, -HOUR( 1) }, /* Central European Summer */
314     { "met", tZONE, -HOUR( 1) }, /* Middle European */
315     { "mewt", tZONE, -HOUR( 1) }, /* Middle European Winter */
316     { "mest", tDAYZONE, -HOUR( 1) }, /* Middle European Summer */
317     { "swt", tZONE, -HOUR( 1) }, /* Swedish Winter */
318     { "sst", tDAYZONE, -HOUR( 1) }, /* Swedish Summer */
319     { "fwt", tZONE, -HOUR( 1) }, /* French Winter */
320     { "fst", tDAYZONE, -HOUR( 1) }, /* French Summer */
321     { "eet", tZONE, -HOUR( 2) }, /* Eastern Europe, USSR Zone 1 */
322     { "bt", tZONE, -HOUR( 3) }, /* Baghdad, USSR Zone 2 */
323     { "it", tZONE, -HOUR( 7/2) }, /* Iran */
324     { "zp4", tZONE, -HOUR( 4) }, /* USSR Zone 3 */
325     { "zp5", tZONE, -HOUR( 5) }, /* USSR Zone 4 */
326     { "ist", tZONE, -HOUR(11/2) }, /* Indian Standard */
327     { "zp6", tZONE, -HOUR( 6) }, /* USSR Zone 5 */
328     #if 0
329     /* For completeness. NST is also Newfoundland Stanard, nad SST is
330     * also Swedish Summer. */
331     { "nst", tZONE, -HOUR(13/2) }, /* North Sumatra */
332     { "sst", tZONE, -HOUR( 7) }, /* South Sumatra, USSR Zone 6 */
333     #endif /* 0 */
334     { "wast", tZONE, -HOUR( 7) }, /* West Australian Standard */
335     { "wadt", tDAYZONE, -HOUR( 7) }, /* West Australian Daylight */
336     { "jt", tZONE, -HOUR(15/2) }, /* Java (3pm in Cronusland!) */
337     { "cct", tZONE, -HOUR( 8) }, /* China Coast, USSR Zone 7 */
338     { "jst", tZONE, -HOUR( 9) }, /* Japan Standard, USSR Zone 8 */
339     { "cast", tZONE, -HOUR(19/2) }, /* Central Australian Standard */
340     { "cadt", tDAYZONE, -HOUR(19/2) }, /* Central Australian Daylight */
341     { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
342     { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
343     { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
344     { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
345     { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
346     { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
347     { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
348     /* ADDED BY Marco Nijdam */
349     { "dst", tDST, HOUR( 0) }, /* DST on (hour is ignored) */
350     /* End ADDED */
351     { NULL }
352     };
353    
354     /*
355     * Military timezone table.
356     */
357     static TABLE MilitaryTable[] = {
358     { "a", tZONE, HOUR( 1) },
359     { "b", tZONE, HOUR( 2) },
360     { "c", tZONE, HOUR( 3) },
361     { "d", tZONE, HOUR( 4) },
362     { "e", tZONE, HOUR( 5) },
363     { "f", tZONE, HOUR( 6) },
364     { "g", tZONE, HOUR( 7) },
365     { "h", tZONE, HOUR( 8) },
366     { "i", tZONE, HOUR( 9) },
367     { "k", tZONE, HOUR( 10) },
368     { "l", tZONE, HOUR( 11) },
369     { "m", tZONE, HOUR( 12) },
370     { "n", tZONE, HOUR(- 1) },
371     { "o", tZONE, HOUR(- 2) },
372     { "p", tZONE, HOUR(- 3) },
373     { "q", tZONE, HOUR(- 4) },
374     { "r", tZONE, HOUR(- 5) },
375     { "s", tZONE, HOUR(- 6) },
376     { "t", tZONE, HOUR(- 7) },
377     { "u", tZONE, HOUR(- 8) },
378     { "v", tZONE, HOUR(- 9) },
379     { "w", tZONE, HOUR(-10) },
380     { "x", tZONE, HOUR(-11) },
381     { "y", tZONE, HOUR(-12) },
382     { "z", tZONE, HOUR( 0) },
383     { NULL }
384     };
385    
386    
387     /*
388     * Dump error messages in the bit bucket.
389     */
390     static void
391     TclDateerror(s)
392     char *s;
393     {
394     }
395    
396    
397     static time_t
398     ToSeconds(Hours, Minutes, Seconds, Meridian)
399     time_t Hours;
400     time_t Minutes;
401     time_t Seconds;
402     MERIDIAN Meridian;
403     {
404     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
405     return -1;
406     switch (Meridian) {
407     case MER24:
408     if (Hours < 0 || Hours > 23)
409     return -1;
410     return (Hours * 60L + Minutes) * 60L + Seconds;
411     case MERam:
412     if (Hours < 1 || Hours > 12)
413     return -1;
414     return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
415     case MERpm:
416     if (Hours < 1 || Hours > 12)
417     return -1;
418     return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
419     }
420     return -1; /* Should never be reached */
421     }
422    
423     /*
424     *-----------------------------------------------------------------------------
425     *
426     * Convert --
427     *
428     * Convert a {month, day, year, hours, minutes, seconds, meridian, dst}
429     * tuple into a clock seconds value.
430     *
431     * Results:
432     * 0 or -1 indicating success or failure.
433     *
434     * Side effects:
435     * Fills TimePtr with the computed value.
436     *
437     *-----------------------------------------------------------------------------
438     */
439     static int
440     Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode, TimePtr)
441     time_t Month;
442     time_t Day;
443     time_t Year;
444     time_t Hours;
445     time_t Minutes;
446     time_t Seconds;
447     MERIDIAN Meridian;
448     DSTMODE DSTmode;
449     time_t *TimePtr;
450     {
451     static int DaysInMonth[12] = {
452     31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
453     };
454     time_t tod;
455     time_t Julian;
456     int i;
457    
458     /* Figure out how many days are in February for the given year.
459     * Every year divisible by 4 is a leap year.
460     * But, every year divisible by 100 is not a leap year.
461     * But, every year divisible by 400 is a leap year after all.
462     */
463     DaysInMonth[1] = IsLeapYear(Year) ? 29 : 28;
464    
465     /* Check the inputs for validity */
466     if (Month < 1 || Month > 12
467     || Year < START_OF_TIME || Year > END_OF_TIME
468     || Day < 1 || Day > DaysInMonth[(int)--Month])
469     return -1;
470    
471     /* Start computing the value. First determine the number of days
472     * represented by the date, then multiply by the number of seconds/day.
473     */
474     for (Julian = Day - 1, i = 0; i < Month; i++)
475     Julian += DaysInMonth[i];
476     if (Year >= EPOCH) {
477     for (i = EPOCH; i < Year; i++)
478     Julian += 365 + IsLeapYear(i);
479     } else {
480     for (i = Year; i < EPOCH; i++)
481     Julian -= 365 + IsLeapYear(i);
482     }
483     Julian *= SECSPERDAY;
484    
485     /* Add the timezone offset ?? */
486     Julian += TclDateTimezone * 60L;
487    
488     /* Add the number of seconds represented by the time component */
489     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
490     return -1;
491     Julian += tod;
492    
493     /* Perform a preliminary DST compensation ?? */
494     if (DSTmode == DSTon
495     || (DSTmode == DSTmaybe && TclpGetDate((TclpTime_t)&Julian, 0)->tm_isdst))
496     Julian -= 60 * 60;
497     *TimePtr = Julian;
498     return 0;
499     }
500    
501    
502     static time_t
503     DSTcorrect(Start, Future)
504     time_t Start;
505     time_t Future;
506     {
507     time_t StartDay;
508     time_t FutureDay;
509     StartDay = (TclpGetDate((TclpTime_t)&Start, 0)->tm_hour + 1) % 24;
510     FutureDay = (TclpGetDate((TclpTime_t)&Future, 0)->tm_hour + 1) % 24;
511     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
512     }
513    
514    
515     static time_t
516     NamedDay(Start, DayOrdinal, DayNumber)
517     time_t Start;
518     time_t DayOrdinal;
519     time_t DayNumber;
520     {
521     struct tm *tm;
522     time_t now;
523    
524     now = Start;
525     tm = TclpGetDate((TclpTime_t)&now, 0);
526     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
527     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
528     return DSTcorrect(Start, now);
529     }
530    
531     static time_t
532     NamedMonth(Start, MonthOrdinal, MonthNumber)
533     time_t Start;
534     time_t MonthOrdinal;
535     time_t MonthNumber;
536     {
537     struct tm *tm;
538     time_t now;
539     int result;
540    
541     now = Start;
542     tm = TclpGetDate((TclpTime_t)&now, 0);
543     /* To compute the next n'th month, we use this alg:
544     * add n to year value
545     * if currentMonth < requestedMonth decrement year value by 1 (so that
546     * doing next february from january gives us february of the current year)
547     * set day to 1, time to 0
548     */
549     tm->tm_year += MonthOrdinal;
550     if (tm->tm_mon < MonthNumber - 1) {
551     tm->tm_year--;
552     }
553     result = Convert(MonthNumber, (time_t) 1, tm->tm_year + TM_YEAR_BASE,
554     (time_t) 0, (time_t) 0, (time_t) 0, MER24, DSTmaybe, &now);
555     if (result < 0) {
556     return 0;
557     }
558     return DSTcorrect(Start, now);
559     }
560    
561     static int
562     RelativeMonth(Start, RelMonth, TimePtr)
563     time_t Start;
564     time_t RelMonth;
565     time_t *TimePtr;
566     {
567     struct tm *tm;
568     time_t Month;
569     time_t Year;
570     time_t Julian;
571     int result;
572    
573     if (RelMonth == 0) {
574     *TimePtr = 0;
575     return 0;
576     }
577     tm = TclpGetDate((TclpTime_t)&Start, 0);
578     Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
579     Year = Month / 12;
580     Month = Month % 12 + 1;
581     result = Convert(Month, (time_t) tm->tm_mday, Year,
582     (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
583     MER24, DSTmaybe, &Julian);
584     /*
585     * The following iteration takes into account the case were we jump
586     * into a "short month". Far example, "one month from Jan 31" will
587     * fail because there is no Feb 31. The code below will reduce the
588     * day and try converting the date until we succed or the date equals
589     * 28 (which always works unless the date is bad in another way).
590     */
591    
592     while ((result != 0) && (tm->tm_mday > 28)) {
593     tm->tm_mday--;
594     result = Convert(Month, (time_t) tm->tm_mday, Year,
595     (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
596     MER24, DSTmaybe, &Julian);
597     }
598     if (result != 0) {
599     return -1;
600     }
601     *TimePtr = DSTcorrect(Start, Julian);
602     return 0;
603     }
604    
605    
606     /*
607     *-----------------------------------------------------------------------------
608     *
609     * RelativeDay --
610     *
611     * Given a starting time and a number of days before or after, compute the
612     * DST corrected difference between those dates.
613     *
614     * Results:
615     * 1 or -1 indicating success or failure.
616     *
617     * Side effects:
618     * Fills TimePtr with the computed value.
619     *
620     *-----------------------------------------------------------------------------
621     */
622    
623     static int
624     RelativeDay(Start, RelDay, TimePtr)
625     time_t Start;
626     time_t RelDay;
627     time_t *TimePtr;
628     {
629     time_t new;
630    
631     new = Start + (RelDay * 60 * 60 * 24);
632     *TimePtr = DSTcorrect(Start, new);
633     return 1;
634     }
635    
636     static int
637     LookupWord(buff)
638     char *buff;
639     {
640     register char *p;
641     register char *q;
642     register TABLE *tp;
643     int i;
644     int abbrev;
645    
646     /*
647     * Make it lowercase.
648     */
649    
650     Tcl_UtfToLower(buff);
651    
652     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
653     TclDatelval.Meridian = MERam;
654     return tMERIDIAN;
655     }
656     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
657     TclDatelval.Meridian = MERpm;
658     return tMERIDIAN;
659     }
660    
661     /*
662     * See if we have an abbreviation for a month.
663     */
664     if (strlen(buff) == 3) {
665     abbrev = 1;
666     } else if (strlen(buff) == 4 && buff[3] == '.') {
667     abbrev = 1;
668     buff[3] = '\0';
669     } else {
670     abbrev = 0;
671     }
672    
673     for (tp = MonthDayTable; tp->name; tp++) {
674     if (abbrev) {
675     if (strncmp(buff, tp->name, 3) == 0) {
676     TclDatelval.Number = tp->value;
677     return tp->type;
678     }
679     } else if (strcmp(buff, tp->name) == 0) {
680     TclDatelval.Number = tp->value;
681     return tp->type;
682     }
683     }
684    
685     for (tp = TimezoneTable; tp->name; tp++) {
686     if (strcmp(buff, tp->name) == 0) {
687     TclDatelval.Number = tp->value;
688     return tp->type;
689     }
690     }
691    
692     for (tp = UnitsTable; tp->name; tp++) {
693     if (strcmp(buff, tp->name) == 0) {
694     TclDatelval.Number = tp->value;
695     return tp->type;
696     }
697     }
698    
699     /*
700     * Strip off any plural and try the units table again.
701     */
702     i = strlen(buff) - 1;
703     if (buff[i] == 's') {
704     buff[i] = '\0';
705     for (tp = UnitsTable; tp->name; tp++) {
706     if (strcmp(buff, tp->name) == 0) {
707     TclDatelval.Number = tp->value;
708     return tp->type;
709     }
710     }
711     }
712    
713     for (tp = OtherTable; tp->name; tp++) {
714     if (strcmp(buff, tp->name) == 0) {
715     TclDatelval.Number = tp->value;
716     return tp->type;
717     }
718     }
719    
720     /*
721     * Military timezones.
722     */
723     if (buff[1] == '\0' && !(*buff & 0x80)
724     && isalpha(UCHAR(*buff))) { /* INTL: ISO only */
725     for (tp = MilitaryTable; tp->name; tp++) {
726     if (strcmp(buff, tp->name) == 0) {
727     TclDatelval.Number = tp->value;
728     return tp->type;
729     }
730     }
731     }
732    
733     /*
734     * Drop out any periods and try the timezone table again.
735     */
736     for (i = 0, p = q = buff; *q; q++)
737     if (*q != '.') {
738     *p++ = *q;
739     } else {
740     i++;
741     }
742     *p = '\0';
743     if (i) {
744     for (tp = TimezoneTable; tp->name; tp++) {
745     if (strcmp(buff, tp->name) == 0) {
746     TclDatelval.Number = tp->value;
747     return tp->type;
748     }
749     }
750     }
751    
752     return tID;
753     }
754    
755    
756     static int
757     TclDatelex()
758     {
759     register char c;
760     register char *p;
761     char buff[20];
762     int Count;
763    
764     for ( ; ; ) {
765     while (isspace(UCHAR(*TclDateInput))) {
766     TclDateInput++;
767     }
768    
769     if (isdigit(UCHAR(c = *TclDateInput))) { /* INTL: digit */
770     /* convert the string into a number; count the number of digits */
771     Count = 0;
772     for (TclDatelval.Number = 0;
773     isdigit(UCHAR(c = *TclDateInput++)); ) { /* INTL: digit */
774     TclDatelval.Number = 10 * TclDatelval.Number + c - '0';
775     Count++;
776     }
777     TclDateInput--;
778     /* A number with 6 or more digits is considered an ISO 8601 base */
779     if (Count >= 6) {
780     return tISOBASE;
781     } else {
782     return tUNUMBER;
783     }
784     }
785     if (!(c & 0x80) && isalpha(UCHAR(c))) { /* INTL: ISO only. */
786     for (p = buff; isalpha(UCHAR(c = *TclDateInput++)) /* INTL: ISO only. */
787     || c == '.'; ) {
788     if (p < &buff[sizeof buff - 1]) {
789     *p++ = c;
790     }
791     }
792     *p = '\0';
793     TclDateInput--;
794     return LookupWord(buff);
795     }
796     if (c != '(') {
797     return *TclDateInput++;
798     }
799     Count = 0;
800     do {
801     c = *TclDateInput++;
802     if (c == '\0') {
803     return c;
804     } else if (c == '(') {
805     Count++;
806     } else if (c == ')') {
807     Count--;
808     }
809     } while (Count > 0);
810     }
811     }
812    
813     /*
814     * Specify zone is of -50000 to force GMT. (This allows BST to work).
815     */
816    
817     int
818     TclGetDate(p, now, zone, timePtr)
819     char *p;
820     unsigned long now;
821     long zone;
822     unsigned long *timePtr;
823     {
824     struct tm *tm;
825     time_t Start;
826     time_t Time;
827     time_t tod;
828     int thisyear;
829    
830     TclDateInput = p;
831     /* now has to be cast to a time_t for 64bit compliance */
832     Start = now;
833     tm = TclpGetDate((TclpTime_t) &Start, 0);
834     thisyear = tm->tm_year + TM_YEAR_BASE;
835     TclDateYear = thisyear;
836     TclDateMonth = tm->tm_mon + 1;
837     TclDateDay = tm->tm_mday;
838     TclDateTimezone = zone;
839     if (zone == -50000) {
840     TclDateDSTmode = DSToff; /* assume GMT */
841     TclDateTimezone = 0;
842     } else {
843     TclDateDSTmode = DSTmaybe;
844     }
845     TclDateHour = 0;
846     TclDateMinutes = 0;
847     TclDateSeconds = 0;
848     TclDateMeridian = MER24;
849     TclDateRelSeconds = 0;
850     TclDateRelMonth = 0;
851     TclDateRelDay = 0;
852     TclDateRelPointer = NULL;
853    
854     TclDateHaveDate = 0;
855     TclDateHaveDay = 0;
856     TclDateHaveOrdinalMonth = 0;
857     TclDateHaveRel = 0;
858     TclDateHaveTime = 0;
859     TclDateHaveZone = 0;
860    
861     if (TclDateparse() || TclDateHaveTime > 1 || TclDateHaveZone > 1 || TclDateHaveDate > 1 ||
862     TclDateHaveDay > 1 || TclDateHaveOrdinalMonth > 1) {
863     return -1;
864     }
865    
866     if (TclDateHaveDate || TclDateHaveTime || TclDateHaveDay) {
867     if (TclDateYear < 0) {
868     TclDateYear = -TclDateYear;
869     }
870     /*
871     * The following line handles years that are specified using
872     * only two digits. The line of code below implements a policy
873     * defined by the X/Open workgroup on the millinium rollover.
874     * Note: some of those dates may not actually be valid on some
875     * platforms. The POSIX standard startes that the dates 70-99
876     * shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.
877     * This later definition should work on all platforms.
878     */
879    
880     if (TclDateYear < 100) {
881     if (TclDateYear >= 69) {
882     TclDateYear += 1900;
883     } else {
884     TclDateYear += 2000;
885     }
886     }
887     if (Convert(TclDateMonth, TclDateDay, TclDateYear, TclDateHour, TclDateMinutes, TclDateSeconds,
888     TclDateMeridian, TclDateDSTmode, &Start) < 0) {
889     return -1;
890     }
891     } else {
892     Start = now;
893     if (!TclDateHaveRel) {
894     Start -= ((tm->tm_hour * 60L * 60L) +
895     tm->tm_min * 60L) + tm->tm_sec;
896     }
897     }
898    
899     Start += TclDateRelSeconds;
900     if (RelativeMonth(Start, TclDateRelMonth, &Time) < 0) {
901     return -1;
902     }
903     Start += Time;
904    
905     if (RelativeDay(Start, TclDateRelDay, &Time) < 0) {
906     return -1;
907     }
908     Start += Time;
909    
910     if (TclDateHaveDay && !TclDateHaveDate) {
911     tod = NamedDay(Start, TclDateDayOrdinal, TclDateDayNumber);
912     Start += tod;
913     }
914    
915     if (TclDateHaveOrdinalMonth) {
916     tod = NamedMonth(Start, TclDateMonthOrdinal, TclDateMonth);
917     Start += tod;
918     }
919    
920     *timePtr = Start;
921     return 0;
922     }
923     static CONST TclDatetabelem TclDateexca[] ={
924     -1, 1,
925     0, -1,
926     -2, 0,
927     };
928     # define YYNPROD 56
929     # define YYLAST 261
930     static CONST TclDatetabelem TclDateact[]={
931    
932     24, 39, 23, 35, 55, 83, 40, 27, 54, 25,
933     36, 41, 59, 37, 57, 27, 26, 25, 27, 32,
934     25, 31, 62, 50, 26, 82, 78, 26, 51, 77,
935     76, 75, 29, 74, 73, 72, 70, 52, 49, 48,
936     47, 44, 38, 63, 80, 46, 45, 81, 69, 21,
937     66, 61, 68, 67, 56, 43, 64, 11, 10, 9,
938     8, 7, 34, 6, 5, 4, 3, 2, 42, 1,
939     20, 0, 0, 0, 0, 0, 0, 0, 0, 0,
940     0, 53, 0, 0, 0, 0, 0, 0, 0, 0,
941     0, 58, 0, 0, 60, 0, 0, 79, 0, 0,
942     0, 0, 0, 0, 0, 0, 0, 71, 0, 0,
943     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
944     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
945     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
946     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
947     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
948     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
949     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
952     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
953     0, 0, 0, 0, 0, 19, 14, 0, 0, 0,
954     16, 27, 22, 25, 0, 12, 13, 17, 0, 15,
955     26, 18, 30, 0, 0, 28, 0, 33, 27, 0,
956     25, 0, 0, 0, 0, 0, 0, 26, 0, 0,
957     0, 0, 0, 0, 0, 0, 0, 0, 0, 65,
958     65 };
959     static CONST TclDatetabelem TclDatepact[]={
960    
961     -10000000, -43,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,
962     -10000000,-10000000, -26, -268,-10000000, -259, -226,-10000000, -257, 11,
963     -227, -212, -228,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000, -229,
964     -10000000, -230, -240, -231, -212,-10000000, -264,-10000000, 10,-10000000,
965     -10000000, -249,-10000000,-10000000, -246,-10000000,-10000000, 5, -2, 3,
966     8, 7,-10000000,-10000000,-10000000, -10, -232,-10000000,-10000000,-10000000,
967     -212, -233,-10000000, -234, -235,-10000000, -237, -238, -239, -242,
968     -10000000,-10000000,-10000000,-10000000, -1,-10000000,-10000000,-10000000, -11,-10000000,
969     -243, -263,-10000000,-10000000 };
970     static CONST TclDatetabelem TclDatepgo[]={
971    
972     0, 49, 46, 70, 22, 69, 67, 66, 65, 64,
973     63, 61, 60, 59, 58, 57 };
974     static CONST TclDatetabelem TclDater1[]={
975    
976     0, 5, 5, 6, 6, 6, 6, 6, 6, 6,
977     6, 6, 7, 7, 7, 7, 7, 8, 8, 8,
978     11, 11, 11, 11, 11, 9, 9, 9, 9, 9,
979     9, 9, 9, 9, 9, 10, 10, 13, 13, 13,
980     14, 12, 12, 12, 12, 12, 3, 3, 1, 1,
981     1, 2, 2, 15, 4, 4 };
982     static CONST TclDatetabelem TclDater2[]={
983    
984     0, 0, 4, 3, 3, 3, 3, 3, 3, 3,
985     3, 2, 5, 9, 11, 13, 15, 5, 3, 3,
986     3, 5, 5, 7, 5, 7, 11, 3, 11, 11,
987     5, 9, 5, 3, 7, 5, 7, 7, 15, 5,
988     9, 9, 7, 5, 7, 5, 3, 3, 3, 3,
989     3, 3, 1, 3, 1, 3 };
990     static CONST TclDatetabelem TclDatechk[]={
991    
992     -10000000, -5, -6, -7, -8, -9, -10, -11, -12, -13,
993     -14, -15, 268, 269, 259, 272, 263, 270, 274, 258,
994     -3, -1, 265, 45, 43, 266, 273, 264, 261, 58,
995     258, 47, 45, 263, -1, 271, 269, 272, 268, 258,
996     263, 268, -1, 44, 268, -2, 257, 268, 268, 268,
997     263, 268, 268, -2, 272, 268, 44, 263, -1, 258,
998     -1, 46, -4, 45, 58, 261, 47, 45, 45, 58,
999     268, -2, 268, 268, 268, 268, 268, 268, 268, -4,
1000     45, 58, 268, 268 };
1001     static CONST TclDatetabelem TclDatedef[]={
1002    
1003     1, -2, 2, 3, 4, 5, 6, 7, 8, 9,
1004     10, 11, 53, 18, 19, 27, 0, 33, 0, 20,
1005     0, 52, 0, 46, 47, 48, 49, 50, 12, 0,
1006     22, 0, 0, 32, 52, 17, 0, 39, 30, 24,
1007     35, 0, 43, 21, 0, 45, 51, 0, 54, 25,
1008     0, 0, 34, 42, 37, 0, 0, 36, 44, 23,
1009     52, 0, 13, 0, 0, 55, 0, 0, 0, 0,
1010     31, 41, 40, 14, 54, 26, 28, 29, 0, 15,
1011     0, 0, 16, 38 };
1012     typedef struct
1013     #ifdef __cplusplus
1014     TclDatetoktype
1015     #endif
1016     { char *t_name; int t_val; } TclDatetoktype;
1017     #ifndef YYDEBUG
1018     # define YYDEBUG 0 /* don't allow debugging */
1019     #endif
1020    
1021     #if YYDEBUG
1022    
1023     TclDatetoktype TclDatetoks[] =
1024     {
1025     "tAGO", 257,
1026     "tDAY", 258,
1027     "tDAYZONE", 259,
1028     "tID", 260,
1029     "tMERIDIAN", 261,
1030     "tMINUTE_UNIT", 262,
1031     "tMONTH", 263,
1032     "tMONTH_UNIT", 264,
1033     "tSTARDATE", 265,
1034     "tSEC_UNIT", 266,
1035     "tSNUMBER", 267,
1036     "tUNUMBER", 268,
1037     "tZONE", 269,
1038     "tEPOCH", 270,
1039     "tDST", 271,
1040     "tISOBASE", 272,
1041     "tDAY_UNIT", 273,
1042     "tNEXT", 274,
1043     "-unknown-", -1 /* ends search */
1044     };
1045    
1046     char * TclDatereds[] =
1047     {
1048     "-no such reduction-",
1049     "spec : /* empty */",
1050     "spec : spec item",
1051     "item : time",
1052     "item : zone",
1053     "item : date",
1054     "item : ordMonth",
1055     "item : day",
1056     "item : relspec",
1057     "item : iso",
1058     "item : trek",
1059     "item : number",
1060     "time : tUNUMBER tMERIDIAN",
1061     "time : tUNUMBER ':' tUNUMBER o_merid",
1062     "time : tUNUMBER ':' tUNUMBER '-' tUNUMBER",
1063     "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
1064     "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER",
1065     "zone : tZONE tDST",
1066     "zone : tZONE",
1067     "zone : tDAYZONE",
1068     "day : tDAY",
1069     "day : tDAY ','",
1070     "day : tUNUMBER tDAY",
1071     "day : sign tUNUMBER tDAY",
1072     "day : tNEXT tDAY",
1073     "date : tUNUMBER '/' tUNUMBER",
1074     "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
1075     "date : tISOBASE",
1076     "date : tUNUMBER '-' tMONTH '-' tUNUMBER",
1077     "date : tUNUMBER '-' tUNUMBER '-' tUNUMBER",
1078     "date : tMONTH tUNUMBER",
1079     "date : tMONTH tUNUMBER ',' tUNUMBER",
1080     "date : tUNUMBER tMONTH",
1081     "date : tEPOCH",
1082     "date : tUNUMBER tMONTH tUNUMBER",
1083     "ordMonth : tNEXT tMONTH",
1084     "ordMonth : tNEXT tUNUMBER tMONTH",
1085     "iso : tISOBASE tZONE tISOBASE",
1086     "iso : tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER",
1087     "iso : tISOBASE tISOBASE",
1088     "trek : tSTARDATE tUNUMBER '.' tUNUMBER",
1089     "relspec : sign tUNUMBER unit ago",
1090     "relspec : tUNUMBER unit ago",
1091     "relspec : tNEXT unit",
1092     "relspec : tNEXT tUNUMBER unit",
1093     "relspec : unit ago",
1094     "sign : '-'",
1095     "sign : '+'",
1096     "unit : tSEC_UNIT",
1097     "unit : tDAY_UNIT",
1098     "unit : tMONTH_UNIT",
1099     "ago : tAGO",
1100     "ago : /* empty */",
1101     "number : tUNUMBER",
1102     "o_merid : /* empty */",
1103     "o_merid : tMERIDIAN",
1104     };
1105     #endif /* YYDEBUG */
1106     /*
1107     * Copyright (c) 1993 by Sun Microsystems, Inc.
1108     */
1109    
1110    
1111     /*
1112     ** Skeleton parser driver for yacc output
1113     */
1114    
1115     /*
1116     ** yacc user known macros and defines
1117     */
1118     #define YYERROR goto TclDateerrlab
1119     #define YYACCEPT return(0)
1120     #define YYABORT return(1)
1121     #define YYBACKUP( newtoken, newvalue )\
1122     {\
1123     if ( TclDatechar >= 0 || ( TclDater2[ TclDatetmp ] >> 1 ) != 1 )\
1124     {\
1125     TclDateerror( "syntax error - cannot backup" );\
1126     goto TclDateerrlab;\
1127     }\
1128     TclDatechar = newtoken;\
1129     TclDatestate = *TclDateps;\
1130     TclDatelval = newvalue;\
1131     goto TclDatenewstate;\
1132     }
1133     #define YYRECOVERING() (!!TclDateerrflag)
1134     #define YYNEW(type) malloc(sizeof(type) * TclDatenewmax)
1135     #define YYCOPY(to, from, type) \
1136     (type *) memcpy(to, (char *) from, TclDatemaxdepth * sizeof (type))
1137     #define YYENLARGE( from, type) \
1138     (type *) realloc((char *) from, TclDatenewmax * sizeof(type))
1139     #ifndef YYDEBUG
1140     # define YYDEBUG 1 /* make debugging available */
1141     #endif
1142    
1143     /*
1144     ** user known globals
1145     */
1146     int TclDatedebug; /* set to 1 to get debugging */
1147    
1148     /*
1149     ** driver internal defines
1150     */
1151     #define YYFLAG (-10000000)
1152    
1153     /*
1154     ** global variables used by the parser
1155     */
1156     YYSTYPE *TclDatepv; /* top of value stack */
1157     int *TclDateps; /* top of state stack */
1158    
1159     int TclDatestate; /* current state */
1160     int TclDatetmp; /* extra var (lasts between blocks) */
1161    
1162     int TclDatenerrs; /* number of errors */
1163     int TclDateerrflag; /* error recovery flag */
1164     int TclDatechar; /* current input token number */
1165    
1166    
1167    
1168     #ifdef YYNMBCHARS
1169     #define YYLEX() TclDatecvtok(TclDatelex())
1170     /*
1171     ** TclDatecvtok - return a token if i is a wchar_t value that exceeds 255.
1172     ** If i<255, i itself is the token. If i>255 but the neither
1173     ** of the 30th or 31st bit is on, i is already a token.
1174     */
1175     #if defined(__STDC__) || defined(__cplusplus)
1176     int TclDatecvtok(int i)
1177     #else
1178     int TclDatecvtok(i) int i;
1179     #endif
1180     {
1181     int first = 0;
1182     int last = YYNMBCHARS - 1;
1183     int mid;
1184     wchar_t j;
1185    
1186     if(i&0x60000000){/*Must convert to a token. */
1187     if( TclDatembchars[last].character < i ){
1188     return i;/*Giving up*/
1189     }
1190     while ((last>=first)&&(first>=0)) {/*Binary search loop*/
1191     mid = (first+last)/2;
1192     j = TclDatembchars[mid].character;
1193     if( j==i ){/*Found*/
1194     return TclDatembchars[mid].tvalue;
1195     }else if( j<i ){
1196     first = mid + 1;
1197     }else{
1198     last = mid -1;
1199     }
1200     }
1201     /*No entry in the table.*/
1202     return i;/* Giving up.*/
1203     }else{/* i is already a token. */
1204     return i;
1205     }
1206     }
1207     #else/*!YYNMBCHARS*/
1208     #define YYLEX() TclDatelex()
1209     #endif/*!YYNMBCHARS*/
1210    
1211     /*
1212     ** TclDateparse - return 0 if worked, 1 if syntax error not recovered from
1213     */
1214     #if defined(__STDC__) || defined(__cplusplus)
1215     int TclDateparse(void)
1216     #else
1217     int TclDateparse()
1218     #endif
1219     {
1220     register YYSTYPE *TclDatepvt = 0; /* top of value stack for $vars */
1221    
1222     #if defined(__cplusplus) || defined(lint)
1223     /*
1224     hacks to please C++ and lint - goto's inside
1225     switch should never be executed
1226     */
1227     static int __yaccpar_lint_hack__ = 0;
1228     switch (__yaccpar_lint_hack__)
1229     {
1230     case 1: goto TclDateerrlab;
1231     case 2: goto TclDatenewstate;
1232     }
1233     #endif
1234    
1235     /*
1236     ** Initialize externals - TclDateparse may be called more than once
1237     */
1238     TclDatepv = &TclDatev[-1];
1239     TclDateps = &TclDates[-1];
1240     TclDatestate = 0;
1241     TclDatetmp = 0;
1242     TclDatenerrs = 0;
1243     TclDateerrflag = 0;
1244     TclDatechar = -1;
1245    
1246     #if YYMAXDEPTH <= 0
1247     if (TclDatemaxdepth <= 0)
1248     {
1249     if ((TclDatemaxdepth = YYEXPAND(0)) <= 0)
1250     {
1251     TclDateerror("yacc initialization error");
1252     YYABORT;
1253     }
1254     }
1255     #endif
1256    
1257     {
1258     register YYSTYPE *TclDate_pv; /* top of value stack */
1259     register int *TclDate_ps; /* top of state stack */
1260     register int TclDate_state; /* current state */
1261     register int TclDate_n; /* internal state number info */
1262     goto TclDatestack; /* moved from 6 lines above to here to please C++ */
1263    
1264     /*
1265     ** get globals into registers.
1266     ** branch to here only if YYBACKUP was called.
1267     */
1268     TclDate_pv = TclDatepv;
1269     TclDate_ps = TclDateps;
1270     TclDate_state = TclDatestate;
1271     goto TclDate_newstate;
1272    
1273     /*
1274     ** get globals into registers.
1275     ** either we just started, or we just finished a reduction
1276     */
1277     TclDatestack:
1278     TclDate_pv = TclDatepv;
1279     TclDate_ps = TclDateps;
1280     TclDate_state = TclDatestate;
1281    
1282     /*
1283     ** top of for (;;) loop while no reductions done
1284     */
1285     TclDate_stack:
1286     /*
1287     ** put a state and value onto the stacks
1288     */
1289     #if YYDEBUG
1290     /*
1291     ** if debugging, look up token value in list of value vs.
1292     ** name pairs. 0 and negative (-1) are special values.
1293     ** Note: linear search is used since time is not a real
1294     ** consideration while debugging.
1295     */
1296     if ( TclDatedebug )
1297     {
1298     register int TclDate_i;
1299    
1300     printf( "State %d, token ", TclDate_state );
1301     if ( TclDatechar == 0 )
1302     printf( "end-of-file\n" );
1303     else if ( TclDatechar < 0 )
1304     printf( "-none-\n" );
1305     else
1306     {
1307     for ( TclDate_i = 0; TclDatetoks[TclDate_i].t_val >= 0;
1308     TclDate_i++ )
1309     {
1310     if ( TclDatetoks[TclDate_i].t_val == TclDatechar )
1311     break;
1312     }
1313     printf( "%s\n", TclDatetoks[TclDate_i].t_name );
1314     }
1315     }
1316     #endif /* YYDEBUG */
1317     if ( ++TclDate_ps >= &TclDates[ TclDatemaxdepth ] ) /* room on stack? */
1318     {
1319     /*
1320     ** reallocate and recover. Note that pointers
1321     ** have to be reset, or bad things will happen
1322     */
1323     long TclDateps_index = (TclDate_ps - TclDates);
1324     long TclDatepv_index = (TclDate_pv - TclDatev);
1325     long TclDatepvt_index = (TclDatepvt - TclDatev);
1326     int TclDatenewmax;
1327     #ifdef YYEXPAND
1328     TclDatenewmax = YYEXPAND(TclDatemaxdepth);
1329     #else
1330     TclDatenewmax = 2 * TclDatemaxdepth; /* double table size */
1331     if (TclDatemaxdepth == YYMAXDEPTH) /* first time growth */
1332     {
1333     char *newTclDates = (char *)YYNEW(int);
1334     char *newTclDatev = (char *)YYNEW(YYSTYPE);
1335     if (newTclDates != 0 && newTclDatev != 0)
1336     {
1337     TclDates = YYCOPY(newTclDates, TclDates, int);
1338     TclDatev = YYCOPY(newTclDatev, TclDatev, YYSTYPE);
1339     }
1340     else
1341     TclDatenewmax = 0; /* failed */
1342     }
1343     else /* not first time */
1344     {
1345     TclDates = YYENLARGE(TclDates, int);
1346     TclDatev = YYENLARGE(TclDatev, YYSTYPE);
1347     if (TclDates == 0 || TclDatev == 0)
1348     TclDatenewmax = 0; /* failed */
1349     }
1350     #endif
1351     if (TclDatenewmax <= TclDatemaxdepth) /* tables not expanded */
1352     {
1353     TclDateerror( "yacc stack overflow" );
1354     YYABORT;
1355     }
1356     TclDatemaxdepth = TclDatenewmax;
1357    
1358     TclDate_ps = TclDates + TclDateps_index;
1359     TclDate_pv = TclDatev + TclDatepv_index;
1360     TclDatepvt = TclDatev + TclDatepvt_index;
1361     }
1362     *TclDate_ps = TclDate_state;
1363     *++TclDate_pv = TclDateval;
1364    
1365     /*
1366     ** we have a new state - find out what to do
1367     */
1368     TclDate_newstate:
1369     if ( ( TclDate_n = TclDatepact[ TclDate_state ] ) <= YYFLAG )
1370     goto TclDatedefault; /* simple state */
1371     #if YYDEBUG
1372     /*
1373     ** if debugging, need to mark whether new token grabbed
1374     */
1375     TclDatetmp = TclDatechar < 0;
1376     #endif
1377     if ( ( TclDatechar < 0 ) && ( ( TclDatechar = YYLEX() ) < 0 ) )
1378     TclDatechar = 0; /* reached EOF */
1379     #if YYDEBUG
1380     if ( TclDatedebug && TclDatetmp )
1381     {
1382     register int TclDate_i;
1383    
1384     printf( "Received token " );
1385     if ( TclDatechar == 0 )
1386     printf( "end-of-file\n" );
1387     else if ( TclDatechar < 0 )
1388     printf( "-none-\n" );
1389     else
1390     {
1391     for ( TclDate_i = 0; TclDatetoks[TclDate_i].t_val >= 0;
1392     TclDate_i++ )
1393     {
1394     if ( TclDatetoks[TclDate_i].t_val == TclDatechar )
1395     break;
1396     }
1397     printf( "%s\n", TclDatetoks[TclDate_i].t_name );
1398     }
1399     }
1400     #endif /* YYDEBUG */
1401     if ( ( ( TclDate_n += TclDatechar ) < 0 ) || ( TclDate_n >= YYLAST ) )
1402     goto TclDatedefault;
1403     if ( TclDatechk[ TclDate_n = TclDateact[ TclDate_n ] ] == TclDatechar ) /*valid shift*/
1404     {
1405     TclDatechar = -1;
1406     TclDateval = TclDatelval;
1407     TclDate_state = TclDate_n;
1408     if ( TclDateerrflag > 0 )
1409     TclDateerrflag--;
1410     goto TclDate_stack;
1411     }
1412    
1413     TclDatedefault:
1414     if ( ( TclDate_n = TclDatedef[ TclDate_state ] ) == -2 )
1415     {
1416     #if YYDEBUG
1417     TclDatetmp = TclDatechar < 0;
1418     #endif
1419     if ( ( TclDatechar < 0 ) && ( ( TclDatechar = YYLEX() ) < 0 ) )
1420     TclDatechar = 0; /* reached EOF */
1421     #if YYDEBUG
1422     if ( TclDatedebug && TclDatetmp )
1423     {
1424     register int TclDate_i;
1425    
1426     printf( "Received token " );
1427     if ( TclDatechar == 0 )
1428     printf( "end-of-file\n" );
1429     else if ( TclDatechar < 0 )
1430     printf( "-none-\n" );
1431     else
1432     {
1433     for ( TclDate_i = 0;
1434     TclDatetoks[TclDate_i].t_val >= 0;
1435     TclDate_i++ )
1436     {
1437     if ( TclDatetoks[TclDate_i].t_val
1438     == TclDatechar )
1439     {
1440     break;
1441     }
1442     }
1443     printf( "%s\n", TclDatetoks[TclDate_i].t_name );
1444     }
1445     }
1446     #endif /* YYDEBUG */
1447     /*
1448     ** look through exception table
1449     */
1450     {
1451     register CONST int *TclDatexi = TclDateexca;
1452    
1453     while ( ( *TclDatexi != -1 ) ||
1454     ( TclDatexi[1] != TclDate_state ) )
1455     {
1456     TclDatexi += 2;
1457     }
1458     while ( ( *(TclDatexi += 2) >= 0 ) &&
1459     ( *TclDatexi != TclDatechar ) )
1460     ;
1461     if ( ( TclDate_n = TclDatexi[1] ) < 0 )
1462     YYACCEPT;
1463     }
1464     }
1465    
1466     /*
1467     ** check for syntax error
1468     */
1469     if ( TclDate_n == 0 ) /* have an error */
1470     {
1471     /* no worry about speed here! */
1472     switch ( TclDateerrflag )
1473     {
1474     case 0: /* new error */
1475     TclDateerror( "syntax error" );
1476     goto skip_init;
1477     /*
1478     ** get globals into registers.
1479     ** we have a user generated syntax type error
1480     */
1481     TclDate_pv = TclDatepv;
1482     TclDate_ps = TclDateps;
1483     TclDate_state = TclDatestate;
1484     skip_init:
1485     TclDatenerrs++;
1486     /* FALLTHRU */
1487     case 1:
1488     case 2: /* incompletely recovered error */
1489     /* try again... */
1490     TclDateerrflag = 3;
1491     /*
1492     ** find state where "error" is a legal
1493     ** shift action
1494     */
1495     while ( TclDate_ps >= TclDates )
1496     {
1497     TclDate_n = TclDatepact[ *TclDate_ps ] + YYERRCODE;
1498     if ( TclDate_n >= 0 && TclDate_n < YYLAST &&
1499     TclDatechk[TclDateact[TclDate_n]] == YYERRCODE) {
1500     /*
1501     ** simulate shift of "error"
1502     */
1503     TclDate_state = TclDateact[ TclDate_n ];
1504     goto TclDate_stack;
1505     }
1506     /*
1507     ** current state has no shift on
1508     ** "error", pop stack
1509     */
1510     #if YYDEBUG
1511     # define _POP_ "Error recovery pops state %d, uncovers state %d\n"
1512     if ( TclDatedebug )
1513     printf( _POP_, *TclDate_ps,
1514     TclDate_ps[-1] );
1515     # undef _POP_
1516     #endif
1517     TclDate_ps--;
1518     TclDate_pv--;
1519     }
1520     /*
1521     ** there is no state on stack with "error" as
1522     ** a valid shift. give up.
1523     */
1524     YYABORT;
1525     case 3: /* no shift yet; eat a token */
1526     #if YYDEBUG
1527     /*
1528     ** if debugging, look up token in list of
1529     ** pairs. 0 and negative shouldn't occur,
1530     ** but since timing doesn't matter when
1531     ** debugging, it doesn't hurt to leave the
1532     ** tests here.
1533     */
1534     if ( TclDatedebug )
1535     {
1536     register int TclDate_i;
1537    
1538     printf( "Error recovery discards " );
1539     if ( TclDatechar == 0 )
1540     printf( "token end-of-file\n" );
1541     else if ( TclDatechar < 0 )
1542     printf( "token -none-\n" );
1543     else
1544     {
1545     for ( TclDate_i = 0;
1546     TclDatetoks[TclDate_i].t_val >= 0;
1547     TclDate_i++ )
1548     {
1549     if ( TclDatetoks[TclDate_i].t_val
1550     == TclDatechar )
1551     {
1552     break;
1553     }
1554     }
1555     printf( "token %s\n",
1556     TclDatetoks[TclDate_i].t_name );
1557     }
1558     }
1559     #endif /* YYDEBUG */
1560     if ( TclDatechar == 0 ) /* reached EOF. quit */
1561     YYABORT;
1562     TclDatechar = -1;
1563     goto TclDate_newstate;
1564     }
1565     }/* end if ( TclDate_n == 0 ) */
1566     /*
1567     ** reduction by production TclDate_n
1568     ** put stack tops, etc. so things right after switch
1569     */
1570     #if YYDEBUG
1571     /*
1572     ** if debugging, print the string that is the user's
1573     ** specification of the reduction which is just about
1574     ** to be done.
1575     */
1576     if ( TclDatedebug )
1577     printf( "Reduce by (%d) \"%s\"\n",
1578     TclDate_n, TclDatereds[ TclDate_n ] );
1579     #endif
1580     TclDatetmp = TclDate_n; /* value to switch over */
1581     TclDatepvt = TclDate_pv; /* $vars top of value stack */
1582     /*
1583     ** Look in goto table for next state
1584     ** Sorry about using TclDate_state here as temporary
1585     ** register variable, but why not, if it works...
1586     ** If TclDater2[ TclDate_n ] doesn't have the low order bit
1587     ** set, then there is no action to be done for
1588     ** this reduction. So, no saving & unsaving of
1589     ** registers done. The only difference between the
1590     ** code just after the if and the body of the if is
1591     ** the goto TclDate_stack in the body. This way the test
1592     ** can be made before the choice of what to do is needed.
1593     */
1594     {
1595     /* length of production doubled with extra bit */
1596     register int TclDate_len = TclDater2[ TclDate_n ];
1597    
1598     if ( !( TclDate_len & 01 ) )
1599     {
1600     TclDate_len >>= 1;
1601     TclDateval = ( TclDate_pv -= TclDate_len )[1]; /* $$ = $1 */
1602     TclDate_state = TclDatepgo[ TclDate_n = TclDater1[ TclDate_n ] ] +
1603     *( TclDate_ps -= TclDate_len ) + 1;
1604     if ( TclDate_state >= YYLAST ||
1605     TclDatechk[ TclDate_state =
1606     TclDateact[ TclDate_state ] ] != -TclDate_n )
1607     {
1608     TclDate_state = TclDateact[ TclDatepgo[ TclDate_n ] ];
1609     }
1610     goto TclDate_stack;
1611     }
1612     TclDate_len >>= 1;
1613     TclDateval = ( TclDate_pv -= TclDate_len )[1]; /* $$ = $1 */
1614     TclDate_state = TclDatepgo[ TclDate_n = TclDater1[ TclDate_n ] ] +
1615     *( TclDate_ps -= TclDate_len ) + 1;
1616     if ( TclDate_state >= YYLAST ||
1617     TclDatechk[ TclDate_state = TclDateact[ TclDate_state ] ] != -TclDate_n )
1618     {
1619     TclDate_state = TclDateact[ TclDatepgo[ TclDate_n ] ];
1620     }
1621     }
1622     /* save until reenter driver code */
1623     TclDatestate = TclDate_state;
1624     TclDateps = TclDate_ps;
1625     TclDatepv = TclDate_pv;
1626     }
1627     /*
1628     ** code supplied by user is placed in this switch
1629     */
1630     switch( TclDatetmp )
1631     {
1632    
1633     case 3:{
1634     TclDateHaveTime++;
1635     } break;
1636     case 4:{
1637     TclDateHaveZone++;
1638     } break;
1639     case 5:{
1640     TclDateHaveDate++;
1641     } break;
1642     case 6:{
1643     TclDateHaveOrdinalMonth++;
1644     } break;
1645     case 7:{
1646     TclDateHaveDay++;
1647     } break;
1648     case 8:{
1649     TclDateHaveRel++;
1650     } break;
1651     case 9:{
1652     TclDateHaveTime++;
1653     TclDateHaveDate++;
1654     } break;
1655     case 10:{
1656     TclDateHaveTime++;
1657     TclDateHaveDate++;
1658     TclDateHaveRel++;
1659     } break;
1660     case 12:{
1661     TclDateHour = TclDatepvt[-1].Number;
1662     TclDateMinutes = 0;
1663     TclDateSeconds = 0;
1664     TclDateMeridian = TclDatepvt[-0].Meridian;
1665     } break;
1666     case 13:{
1667     TclDateHour = TclDatepvt[-3].Number;
1668     TclDateMinutes = TclDatepvt[-1].Number;
1669     TclDateSeconds = 0;
1670     TclDateMeridian = TclDatepvt[-0].Meridian;
1671     } break;
1672     case 14:{
1673     TclDateHour = TclDatepvt[-4].Number;
1674     TclDateMinutes = TclDatepvt[-2].Number;
1675     TclDateMeridian = MER24;
1676     TclDateDSTmode = DSToff;
1677     TclDateTimezone = (TclDatepvt[-0].Number % 100 + (TclDatepvt[-0].Number / 100) * 60);
1678     } break;
1679     case 15:{
1680     TclDateHour = TclDatepvt[-5].Number;
1681     TclDateMinutes = TclDatepvt[-3].Number;
1682     TclDateSeconds = TclDatepvt[-1].Number;
1683     TclDateMeridian = TclDatepvt[-0].Meridian;
1684     } break;
1685     case 16:{
1686     TclDateHour = TclDatepvt[-6].Number;
1687     TclDateMinutes = TclDatepvt[-4].Number;
1688     TclDateSeconds = TclDatepvt[-2].Number;
1689     TclDateMeridian = MER24;
1690     TclDateDSTmode = DSToff;
1691     TclDateTimezone = (TclDatepvt[-0].Number % 100 + (TclDatepvt[-0].Number / 100) * 60);
1692     } break;
1693     case 17:{
1694     TclDateTimezone = TclDatepvt[-1].Number;
1695     TclDateDSTmode = DSTon;
1696     } break;
1697     case 18:{
1698     TclDateTimezone = TclDatepvt[-0].Number;
1699     TclDateDSTmode = DSToff;
1700     } break;
1701     case 19:{
1702     TclDateTimezone = TclDatepvt[-0].Number;
1703     TclDateDSTmode = DSTon;
1704     } break;
1705     case 20:{
1706     TclDateDayOrdinal = 1;
1707     TclDateDayNumber = TclDatepvt[-0].Number;
1708     } break;
1709     case 21:{
1710     TclDateDayOrdinal = 1;
1711     TclDateDayNumber = TclDatepvt[-1].Number;
1712     } break;
1713     case 22:{
1714     TclDateDayOrdinal = TclDatepvt[-1].Number;
1715     TclDateDayNumber = TclDatepvt[-0].Number;
1716     } break;
1717     case 23:{
1718     TclDateDayOrdinal = TclDatepvt[-2].Number * TclDatepvt[-1].Number;
1719     TclDateDayNumber = TclDatepvt[-0].Number;
1720     } break;
1721     case 24:{
1722     TclDateDayOrdinal = 2;
1723     TclDateDayNumber = TclDatepvt[-0].Number;
1724     } break;
1725     case 25:{
1726     TclDateMonth = TclDatepvt[-2].Number;
1727     TclDateDay = TclDatepvt[-0].Number;
1728     } break;
1729     case 26:{
1730     TclDateMonth = TclDatepvt[-4].Number;
1731     TclDateDay = TclDatepvt[-2].Number;
1732     TclDateYear = TclDatepvt[-0].Number;
1733     } break;
1734     case 27:{
1735     TclDateYear = TclDatepvt[-0].Number / 10000;
1736     TclDateMonth = (TclDatepvt[-0].Number % 10000)/100;
1737     TclDateDay = TclDatepvt[-0].Number % 100;
1738     } break;
1739     case 28:{
1740     TclDateDay = TclDatepvt[-4].Number;
1741     TclDateMonth = TclDatepvt[-2].Number;
1742     TclDateYear = TclDatepvt[-0].Number;
1743     } break;
1744     case 29:{
1745     TclDateMonth = TclDatepvt[-2].Number;
1746     TclDateDay = TclDatepvt[-0].Number;
1747     TclDateYear = TclDatepvt[-4].Number;
1748     } break;
1749     case 30:{
1750     TclDateMonth = TclDatepvt[-1].Number;
1751     TclDateDay = TclDatepvt[-0].Number;
1752     } break;
1753     case 31:{
1754     TclDateMonth = TclDatepvt[-3].Number;
1755     TclDateDay = TclDatepvt[-2].Number;
1756     TclDateYear = TclDatepvt[-0].Number;
1757     } break;
1758     case 32:{
1759     TclDateMonth = TclDatepvt[-0].Number;
1760     TclDateDay = TclDatepvt[-1].Number;
1761     } break;
1762     case 33:{
1763     TclDateMonth = 1;
1764     TclDateDay = 1;
1765     TclDateYear = EPOCH;
1766     } break;
1767     case 34:{
1768     TclDateMonth = TclDatepvt[-1].Number;
1769     TclDateDay = TclDatepvt[-2].Number;
1770     TclDateYear = TclDatepvt[-0].Number;
1771     } break;
1772     case 35:{
1773     TclDateMonthOrdinal = 1;
1774     TclDateMonth = TclDatepvt[-0].Number;
1775     } break;
1776     case 36:{
1777     TclDateMonthOrdinal = TclDatepvt[-1].Number;
1778     TclDateMonth = TclDatepvt[-0].Number;
1779     } break;
1780     case 37:{
1781     if (TclDatepvt[-1].Number != HOUR(- 7)) YYABORT;
1782     TclDateYear = TclDatepvt[-2].Number / 10000;
1783     TclDateMonth = (TclDatepvt[-2].Number % 10000)/100;
1784     TclDateDay = TclDatepvt[-2].Number % 100;
1785     TclDateHour = TclDatepvt[-0].Number / 10000;
1786     TclDateMinutes = (TclDatepvt[-0].Number % 10000)/100;
1787     TclDateSeconds = TclDatepvt[-0].Number % 100;
1788     } break;
1789     case 38:{
1790     if (TclDatepvt[-5].Number != HOUR(- 7)) YYABORT;
1791     TclDateYear = TclDatepvt[-6].Number / 10000;
1792     TclDateMonth = (TclDatepvt[-6].Number % 10000)/100;
1793     TclDateDay = TclDatepvt[-6].Number % 100;
1794     TclDateHour = TclDatepvt[-4].Number;
1795     TclDateMinutes = TclDatepvt[-2].Number;
1796     TclDateSeconds = TclDatepvt[-0].Number;
1797     } break;
1798     case 39:{
1799     TclDateYear = TclDatepvt[-1].Number / 10000;
1800     TclDateMonth = (TclDatepvt[-1].Number % 10000)/100;
1801     TclDateDay = TclDatepvt[-1].Number % 100;
1802     TclDateHour = TclDatepvt[-0].Number / 10000;
1803     TclDateMinutes = (TclDatepvt[-0].Number % 10000)/100;
1804     TclDateSeconds = TclDatepvt[-0].Number % 100;
1805     } break;
1806     case 40:{
1807     /*
1808     * Offset computed year by -377 so that the returned years will
1809     * be in a range accessible with a 32 bit clock seconds value
1810     */
1811     TclDateYear = TclDatepvt[-2].Number/1000 + 2323 - 377;
1812     TclDateDay = 1;
1813     TclDateMonth = 1;
1814     TclDateRelDay += ((TclDatepvt[-2].Number%1000)*(365 + IsLeapYear(TclDateYear)))/1000;
1815     TclDateRelSeconds += TclDatepvt[-0].Number * 144 * 60;
1816     } break;
1817     case 41:{ *TclDateRelPointer += TclDatepvt[-3].Number * TclDatepvt[-2].Number * TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1818     case 42:{ *TclDateRelPointer += TclDatepvt[-2].Number * TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1819     case 43:{ *TclDateRelPointer += TclDatepvt[-0].Number; } break;
1820     case 44:{ *TclDateRelPointer += TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1821     case 45:{ *TclDateRelPointer += TclDatepvt[-1].Number * TclDatepvt[-0].Number; } break;
1822     case 46:{ TclDateval.Number = -1; } break;
1823     case 47:{ TclDateval.Number = 1; } break;
1824     case 48:{ TclDateval.Number = TclDatepvt[-0].Number; TclDateRelPointer = &TclDateRelSeconds; } break;
1825     case 49:{ TclDateval.Number = TclDatepvt[-0].Number; TclDateRelPointer = &TclDateRelDay; } break;
1826     case 50:{ TclDateval.Number = TclDatepvt[-0].Number; TclDateRelPointer = &TclDateRelMonth; } break;
1827     case 51:{ TclDateval.Number = -1; } break;
1828     case 52:{ TclDateval.Number = 1; } break;
1829     case 53:{
1830     if (TclDateHaveTime && TclDateHaveDate && !TclDateHaveRel) {
1831     TclDateYear = TclDatepvt[-0].Number;
1832     } else {
1833     TclDateHaveTime++;
1834     if (TclDatepvt[-0].Number < 100) {
1835     TclDateHour = TclDatepvt[-0].Number;
1836     TclDateMinutes = 0;
1837     } else {
1838     TclDateHour = TclDatepvt[-0].Number / 100;
1839     TclDateMinutes = TclDatepvt[-0].Number % 100;
1840     }
1841     TclDateSeconds = 0;
1842     TclDateMeridian = MER24;
1843     }
1844     } break;
1845     case 54:{
1846     TclDateval.Meridian = MER24;
1847     } break;
1848     case 55:{
1849     TclDateval.Meridian = TclDatepvt[-0].Meridian;
1850     } break;
1851     }
1852     goto TclDatestack; /* reset registers in driver code */
1853     }
1854    
1855    
1856     /* $History: tcldate.c $
1857     *
1858     * ***************** Version 1 *****************
1859     * User: Dtashley Date: 1/02/01 Time: 1:27a
1860     * Created in $/IjuScripter, IjuConsole/Source/Tcl Base
1861     * Initial check-in.
1862     */
1863    
1864     /* End of TCLDATE.C */

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25