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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.64  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25