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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25