PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/jni/tcl8.6a3/generic/tclGetDate.y

https://github.com/LeifAndersen/TuxRider
Happy | 1042 lines | 939 code | 103 blank | 0 comment | 0 complexity | 05351d9c3c35af2ceb72ff9671648827 MD5 | raw file
Possible License(s): AGPL-3.0, GPL-2.0
  1. /*
  2. * tclGetDate.y --
  3. *
  4. * Contains yacc grammar for parsing date and time strings. The output of
  5. * this file should be the file tclDate.c which is used directly in the
  6. * Tcl sources. Note that this file is largely obsolete in Tcl 8.5; it is
  7. * only used when doing free-form date parsing, an ill-defined process
  8. * anyway.
  9. *
  10. * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
  11. * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  12. *
  13. * See the file "license.terms" for information on usage and redistribution of
  14. * this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15. *
  16. * RCS: @(#) $Id: tclGetDate.y,v 1.38 2007/12/13 15:23:17 dgp Exp $
  17. */
  18. %{
  19. /*
  20. * tclDate.c --
  21. *
  22. * This file is generated from a yacc grammar defined in the file
  23. * tclGetDate.y. It should not be edited directly.
  24. *
  25. * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
  26. * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  27. *
  28. * See the file "license.terms" for information on usage and redistribution of
  29. * this file, and for a DISCLAIMER OF ALL WARRANTIES.
  30. *
  31. */
  32. #include "tclInt.h"
  33. /*
  34. * Bison generates several labels that happen to be unused. MS Visual C++
  35. * doesn't like that, and complains. Tell it to shut up.
  36. */
  37. #ifdef _MSC_VER
  38. #pragma warning( disable : 4102 )
  39. #endif /* _MSC_VER */
  40. /*
  41. * yyparse will accept a 'struct DateInfo' as its parameter; that's where the
  42. * parsed fields will be returned.
  43. */
  44. typedef struct DateInfo {
  45. time_t dateYear;
  46. time_t dateMonth;
  47. time_t dateDay;
  48. int dateHaveDate;
  49. time_t dateHour;
  50. time_t dateMinutes;
  51. time_t dateSeconds;
  52. int dateMeridian;
  53. int dateHaveTime;
  54. time_t dateTimezone;
  55. int dateDSTmode;
  56. int dateHaveZone;
  57. time_t dateRelMonth;
  58. time_t dateRelDay;
  59. time_t dateRelSeconds;
  60. int dateHaveRel;
  61. time_t dateMonthOrdinal;
  62. int dateHaveOrdinalMonth;
  63. time_t dateDayOrdinal;
  64. time_t dateDayNumber;
  65. int dateHaveDay;
  66. char *dateInput;
  67. time_t *dateRelPointer;
  68. int dateDigitCount;
  69. } DateInfo;
  70. #define YYPARSE_PARAM info
  71. #define YYLEX_PARAM info
  72. #define YYMALLOC ckalloc
  73. #define YYFREE(x) (ckfree((void*) (x)))
  74. #define yyDSTmode (((DateInfo *) info)->dateDSTmode)
  75. #define yyDayOrdinal (((DateInfo *) info)->dateDayOrdinal)
  76. #define yyDayNumber (((DateInfo *) info)->dateDayNumber)
  77. #define yyMonthOrdinal (((DateInfo *) info)->dateMonthOrdinal)
  78. #define yyHaveDate (((DateInfo *) info)->dateHaveDate)
  79. #define yyHaveDay (((DateInfo *) info)->dateHaveDay)
  80. #define yyHaveOrdinalMonth (((DateInfo *) info)->dateHaveOrdinalMonth)
  81. #define yyHaveRel (((DateInfo *) info)->dateHaveRel)
  82. #define yyHaveTime (((DateInfo *) info)->dateHaveTime)
  83. #define yyHaveZone (((DateInfo *) info)->dateHaveZone)
  84. #define yyTimezone (((DateInfo *) info)->dateTimezone)
  85. #define yyDay (((DateInfo *) info)->dateDay)
  86. #define yyMonth (((DateInfo *) info)->dateMonth)
  87. #define yyYear (((DateInfo *) info)->dateYear)
  88. #define yyHour (((DateInfo *) info)->dateHour)
  89. #define yyMinutes (((DateInfo *) info)->dateMinutes)
  90. #define yySeconds (((DateInfo *) info)->dateSeconds)
  91. #define yyMeridian (((DateInfo *) info)->dateMeridian)
  92. #define yyRelMonth (((DateInfo *) info)->dateRelMonth)
  93. #define yyRelDay (((DateInfo *) info)->dateRelDay)
  94. #define yyRelSeconds (((DateInfo *) info)->dateRelSeconds)
  95. #define yyRelPointer (((DateInfo *) info)->dateRelPointer)
  96. #define yyInput (((DateInfo *) info)->dateInput)
  97. #define yyDigitCount (((DateInfo *) info)->dateDigitCount)
  98. #define EPOCH 1970
  99. #define START_OF_TIME 1902
  100. #define END_OF_TIME 2037
  101. /*
  102. * The offset of tm_year of struct tm returned by localtime, gmtime, etc.
  103. * Posix requires 1900.
  104. */
  105. #define TM_YEAR_BASE 1900
  106. #define HOUR(x) ((int) (60 * x))
  107. #define SECSPERDAY (24L * 60L * 60L)
  108. #define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
  109. /*
  110. * An entry in the lexical lookup table.
  111. */
  112. typedef struct _TABLE {
  113. char *name;
  114. int type;
  115. time_t value;
  116. } TABLE;
  117. /*
  118. * Daylight-savings mode: on, off, or not yet known.
  119. */
  120. typedef enum _DSTMODE {
  121. DSTon, DSToff, DSTmaybe
  122. } DSTMODE;
  123. /*
  124. * Meridian: am, pm, or 24-hour style.
  125. */
  126. typedef enum _MERIDIAN {
  127. MERam, MERpm, MER24
  128. } MERIDIAN;
  129. /*
  130. * Prototypes of internal functions.
  131. */
  132. static int LookupWord(char *buff);
  133. static void TclDateerror(char *s);
  134. static int TclDatelex(void *info);
  135. static time_t ToSeconds(time_t Hours, time_t Minutes,
  136. time_t Seconds, MERIDIAN Meridian);
  137. MODULE_SCOPE int yyparse(void *);
  138. %}
  139. %union {
  140. time_t Number;
  141. enum _MERIDIAN Meridian;
  142. }
  143. %token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
  144. %token tSTARDATE tSEC_UNIT tSNUMBER tUNUMBER tZONE tEPOCH tDST tISOBASE
  145. %token tDAY_UNIT tNEXT
  146. %type <Number> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT tDST
  147. %type <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE tISOBASE tDAY_UNIT
  148. %type <Number> unit sign tNEXT tSTARDATE
  149. %type <Meridian> tMERIDIAN o_merid
  150. %%
  151. spec : /* NULL */
  152. | spec item
  153. ;
  154. item : time {
  155. yyHaveTime++;
  156. }
  157. | zone {
  158. yyHaveZone++;
  159. }
  160. | date {
  161. yyHaveDate++;
  162. }
  163. | ordMonth {
  164. yyHaveOrdinalMonth++;
  165. }
  166. | day {
  167. yyHaveDay++;
  168. }
  169. | relspec {
  170. yyHaveRel++;
  171. }
  172. | iso {
  173. yyHaveTime++;
  174. yyHaveDate++;
  175. }
  176. | trek {
  177. yyHaveTime++;
  178. yyHaveDate++;
  179. yyHaveRel++;
  180. }
  181. | number
  182. ;
  183. time : tUNUMBER tMERIDIAN {
  184. yyHour = $1;
  185. yyMinutes = 0;
  186. yySeconds = 0;
  187. yyMeridian = $2;
  188. }
  189. | tUNUMBER ':' tUNUMBER o_merid {
  190. yyHour = $1;
  191. yyMinutes = $3;
  192. yySeconds = 0;
  193. yyMeridian = $4;
  194. }
  195. | tUNUMBER ':' tUNUMBER '-' tUNUMBER {
  196. yyHour = $1;
  197. yyMinutes = $3;
  198. yyMeridian = MER24;
  199. yyDSTmode = DSToff;
  200. yyTimezone = ($5 % 100 + ($5 / 100) * 60);
  201. ++yyHaveZone;
  202. }
  203. | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
  204. yyHour = $1;
  205. yyMinutes = $3;
  206. yySeconds = $5;
  207. yyMeridian = $6;
  208. }
  209. | tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER {
  210. yyHour = $1;
  211. yyMinutes = $3;
  212. yySeconds = $5;
  213. yyMeridian = MER24;
  214. yyDSTmode = DSToff;
  215. yyTimezone = ($7 % 100 + ($7 / 100) * 60);
  216. ++yyHaveZone;
  217. }
  218. ;
  219. zone : tZONE tDST {
  220. yyTimezone = $1;
  221. yyDSTmode = DSTon;
  222. }
  223. | tZONE {
  224. yyTimezone = $1;
  225. yyDSTmode = DSToff;
  226. }
  227. | tDAYZONE {
  228. yyTimezone = $1;
  229. yyDSTmode = DSTon;
  230. }
  231. ;
  232. day : tDAY {
  233. yyDayOrdinal = 1;
  234. yyDayNumber = $1;
  235. }
  236. | tDAY ',' {
  237. yyDayOrdinal = 1;
  238. yyDayNumber = $1;
  239. }
  240. | tUNUMBER tDAY {
  241. yyDayOrdinal = $1;
  242. yyDayNumber = $2;
  243. }
  244. | sign tUNUMBER tDAY {
  245. yyDayOrdinal = $1 * $2;
  246. yyDayNumber = $3;
  247. }
  248. | tNEXT tDAY {
  249. yyDayOrdinal = 2;
  250. yyDayNumber = $2;
  251. }
  252. ;
  253. date : tUNUMBER '/' tUNUMBER {
  254. yyMonth = $1;
  255. yyDay = $3;
  256. }
  257. | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
  258. yyMonth = $1;
  259. yyDay = $3;
  260. yyYear = $5;
  261. }
  262. | tISOBASE {
  263. yyYear = $1 / 10000;
  264. yyMonth = ($1 % 10000)/100;
  265. yyDay = $1 % 100;
  266. }
  267. | tUNUMBER '-' tMONTH '-' tUNUMBER {
  268. yyDay = $1;
  269. yyMonth = $3;
  270. yyYear = $5;
  271. }
  272. | tUNUMBER '-' tUNUMBER '-' tUNUMBER {
  273. yyMonth = $3;
  274. yyDay = $5;
  275. yyYear = $1;
  276. }
  277. | tMONTH tUNUMBER {
  278. yyMonth = $1;
  279. yyDay = $2;
  280. }
  281. | tMONTH tUNUMBER ',' tUNUMBER {
  282. yyMonth = $1;
  283. yyDay = $2;
  284. yyYear = $4;
  285. }
  286. | tUNUMBER tMONTH {
  287. yyMonth = $2;
  288. yyDay = $1;
  289. }
  290. | tEPOCH {
  291. yyMonth = 1;
  292. yyDay = 1;
  293. yyYear = EPOCH;
  294. }
  295. | tUNUMBER tMONTH tUNUMBER {
  296. yyMonth = $2;
  297. yyDay = $1;
  298. yyYear = $3;
  299. }
  300. ;
  301. ordMonth: tNEXT tMONTH {
  302. yyMonthOrdinal = 1;
  303. yyMonth = $2;
  304. }
  305. | tNEXT tUNUMBER tMONTH {
  306. yyMonthOrdinal = $2;
  307. yyMonth = $3;
  308. }
  309. ;
  310. iso : tISOBASE tZONE tISOBASE {
  311. if ($2 != HOUR( 7)) YYABORT;
  312. yyYear = $1 / 10000;
  313. yyMonth = ($1 % 10000)/100;
  314. yyDay = $1 % 100;
  315. yyHour = $3 / 10000;
  316. yyMinutes = ($3 % 10000)/100;
  317. yySeconds = $3 % 100;
  318. }
  319. | tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER {
  320. if ($2 != HOUR( 7)) YYABORT;
  321. yyYear = $1 / 10000;
  322. yyMonth = ($1 % 10000)/100;
  323. yyDay = $1 % 100;
  324. yyHour = $3;
  325. yyMinutes = $5;
  326. yySeconds = $7;
  327. }
  328. | tISOBASE tISOBASE {
  329. yyYear = $1 / 10000;
  330. yyMonth = ($1 % 10000)/100;
  331. yyDay = $1 % 100;
  332. yyHour = $2 / 10000;
  333. yyMinutes = ($2 % 10000)/100;
  334. yySeconds = $2 % 100;
  335. }
  336. ;
  337. trek : tSTARDATE tUNUMBER '.' tUNUMBER {
  338. /*
  339. * Offset computed year by -377 so that the returned years will be
  340. * in a range accessible with a 32 bit clock seconds value.
  341. */
  342. yyYear = $2/1000 + 2323 - 377;
  343. yyDay = 1;
  344. yyMonth = 1;
  345. yyRelDay += (($2%1000)*(365 + IsLeapYear(yyYear)))/1000;
  346. yyRelSeconds += $4 * 144 * 60;
  347. }
  348. ;
  349. relspec : relunits tAGO {
  350. yyRelSeconds *= -1;
  351. yyRelMonth *= -1;
  352. yyRelDay *= -1;
  353. }
  354. | relunits
  355. ;
  356. relunits : sign tUNUMBER unit {
  357. *yyRelPointer += $1 * $2 * $3;
  358. }
  359. | tUNUMBER unit {
  360. *yyRelPointer += $1 * $2;
  361. }
  362. | tNEXT unit {
  363. *yyRelPointer += $2;
  364. }
  365. | tNEXT tUNUMBER unit {
  366. *yyRelPointer += $2 * $3;
  367. }
  368. | unit {
  369. *yyRelPointer += $1;
  370. }
  371. ;
  372. sign : '-' {
  373. $$ = -1;
  374. }
  375. | '+' {
  376. $$ = 1;
  377. }
  378. ;
  379. unit : tSEC_UNIT {
  380. $$ = $1;
  381. yyRelPointer = &yyRelSeconds;
  382. }
  383. | tDAY_UNIT {
  384. $$ = $1;
  385. yyRelPointer = &yyRelDay;
  386. }
  387. | tMONTH_UNIT {
  388. $$ = $1;
  389. yyRelPointer = &yyRelMonth;
  390. }
  391. ;
  392. number : tUNUMBER {
  393. if (yyHaveTime && yyHaveDate && !yyHaveRel) {
  394. yyYear = $1;
  395. } else {
  396. yyHaveTime++;
  397. if (yyDigitCount <= 2) {
  398. yyHour = $1;
  399. yyMinutes = 0;
  400. } else {
  401. yyHour = $1 / 100;
  402. yyMinutes = $1 % 100;
  403. }
  404. yySeconds = 0;
  405. yyMeridian = MER24;
  406. }
  407. }
  408. ;
  409. o_merid : /* NULL */ {
  410. $$ = MER24;
  411. }
  412. | tMERIDIAN {
  413. $$ = $1;
  414. }
  415. ;
  416. %%
  417. MODULE_SCOPE int yychar;
  418. MODULE_SCOPE YYSTYPE yylval;
  419. MODULE_SCOPE int yynerrs;
  420. /*
  421. * Month and day table.
  422. */
  423. static TABLE MonthDayTable[] = {
  424. { "january", tMONTH, 1 },
  425. { "february", tMONTH, 2 },
  426. { "march", tMONTH, 3 },
  427. { "april", tMONTH, 4 },
  428. { "may", tMONTH, 5 },
  429. { "june", tMONTH, 6 },
  430. { "july", tMONTH, 7 },
  431. { "august", tMONTH, 8 },
  432. { "september", tMONTH, 9 },
  433. { "sept", tMONTH, 9 },
  434. { "october", tMONTH, 10 },
  435. { "november", tMONTH, 11 },
  436. { "december", tMONTH, 12 },
  437. { "sunday", tDAY, 0 },
  438. { "monday", tDAY, 1 },
  439. { "tuesday", tDAY, 2 },
  440. { "tues", tDAY, 2 },
  441. { "wednesday", tDAY, 3 },
  442. { "wednes", tDAY, 3 },
  443. { "thursday", tDAY, 4 },
  444. { "thur", tDAY, 4 },
  445. { "thurs", tDAY, 4 },
  446. { "friday", tDAY, 5 },
  447. { "saturday", tDAY, 6 },
  448. { NULL }
  449. };
  450. /*
  451. * Time units table.
  452. */
  453. static TABLE UnitsTable[] = {
  454. { "year", tMONTH_UNIT, 12 },
  455. { "month", tMONTH_UNIT, 1 },
  456. { "fortnight", tDAY_UNIT, 14 },
  457. { "week", tDAY_UNIT, 7 },
  458. { "day", tDAY_UNIT, 1 },
  459. { "hour", tSEC_UNIT, 60 * 60 },
  460. { "minute", tSEC_UNIT, 60 },
  461. { "min", tSEC_UNIT, 60 },
  462. { "second", tSEC_UNIT, 1 },
  463. { "sec", tSEC_UNIT, 1 },
  464. { NULL }
  465. };
  466. /*
  467. * Assorted relative-time words.
  468. */
  469. static TABLE OtherTable[] = {
  470. { "tomorrow", tDAY_UNIT, 1 },
  471. { "yesterday", tDAY_UNIT, -1 },
  472. { "today", tDAY_UNIT, 0 },
  473. { "now", tSEC_UNIT, 0 },
  474. { "last", tUNUMBER, -1 },
  475. { "this", tSEC_UNIT, 0 },
  476. { "next", tNEXT, 1 },
  477. #if 0
  478. { "first", tUNUMBER, 1 },
  479. { "second", tUNUMBER, 2 },
  480. { "third", tUNUMBER, 3 },
  481. { "fourth", tUNUMBER, 4 },
  482. { "fifth", tUNUMBER, 5 },
  483. { "sixth", tUNUMBER, 6 },
  484. { "seventh", tUNUMBER, 7 },
  485. { "eighth", tUNUMBER, 8 },
  486. { "ninth", tUNUMBER, 9 },
  487. { "tenth", tUNUMBER, 10 },
  488. { "eleventh", tUNUMBER, 11 },
  489. { "twelfth", tUNUMBER, 12 },
  490. #endif
  491. { "ago", tAGO, 1 },
  492. { "epoch", tEPOCH, 0 },
  493. { "stardate", tSTARDATE, 0 },
  494. { NULL }
  495. };
  496. /*
  497. * The timezone table. (Note: This table was modified to not use any floating
  498. * point constants to work around an SGI compiler bug).
  499. */
  500. static TABLE TimezoneTable[] = {
  501. { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
  502. { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
  503. { "utc", tZONE, HOUR( 0) },
  504. { "uct", tZONE, HOUR( 0) }, /* Universal Coordinated Time */
  505. { "wet", tZONE, HOUR( 0) }, /* Western European */
  506. { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
  507. { "wat", tZONE, HOUR( 1) }, /* West Africa */
  508. { "at", tZONE, HOUR( 2) }, /* Azores */
  509. #if 0
  510. /* For completeness. BST is also British Summer, and GST is
  511. * also Guam Standard. */
  512. { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
  513. { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
  514. #endif
  515. { "nft", tZONE, HOUR( 7/2) }, /* Newfoundland */
  516. { "nst", tZONE, HOUR( 7/2) }, /* Newfoundland Standard */
  517. { "ndt", tDAYZONE, HOUR( 7/2) }, /* Newfoundland Daylight */
  518. { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
  519. { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
  520. { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
  521. { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
  522. { "cst", tZONE, HOUR( 6) }, /* Central Standard */
  523. { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
  524. { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
  525. { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
  526. { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
  527. { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
  528. { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
  529. { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
  530. { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
  531. { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
  532. { "cat", tZONE, HOUR(10) }, /* Central Alaska */
  533. { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
  534. { "nt", tZONE, HOUR(11) }, /* Nome */
  535. { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
  536. { "cet", tZONE, -HOUR( 1) }, /* Central European */
  537. { "cest", tDAYZONE, -HOUR( 1) }, /* Central European Summer */
  538. { "met", tZONE, -HOUR( 1) }, /* Middle European */
  539. { "mewt", tZONE, -HOUR( 1) }, /* Middle European Winter */
  540. { "mest", tDAYZONE, -HOUR( 1) }, /* Middle European Summer */
  541. { "swt", tZONE, -HOUR( 1) }, /* Swedish Winter */
  542. { "sst", tDAYZONE, -HOUR( 1) }, /* Swedish Summer */
  543. { "fwt", tZONE, -HOUR( 1) }, /* French Winter */
  544. { "fst", tDAYZONE, -HOUR( 1) }, /* French Summer */
  545. { "eet", tZONE, -HOUR( 2) }, /* Eastern Europe, USSR Zone 1 */
  546. { "bt", tZONE, -HOUR( 3) }, /* Baghdad, USSR Zone 2 */
  547. { "it", tZONE, -HOUR( 7/2) }, /* Iran */
  548. { "zp4", tZONE, -HOUR( 4) }, /* USSR Zone 3 */
  549. { "zp5", tZONE, -HOUR( 5) }, /* USSR Zone 4 */
  550. { "ist", tZONE, -HOUR(11/2) }, /* Indian Standard */
  551. { "zp6", tZONE, -HOUR( 6) }, /* USSR Zone 5 */
  552. #if 0
  553. /* For completeness. NST is also Newfoundland Stanard, nad SST is
  554. * also Swedish Summer. */
  555. { "nst", tZONE, -HOUR(13/2) }, /* North Sumatra */
  556. { "sst", tZONE, -HOUR( 7) }, /* South Sumatra, USSR Zone 6 */
  557. #endif /* 0 */
  558. { "wast", tZONE, -HOUR( 7) }, /* West Australian Standard */
  559. { "wadt", tDAYZONE, -HOUR( 7) }, /* West Australian Daylight */
  560. { "jt", tZONE, -HOUR(15/2) }, /* Java (3pm in Cronusland!) */
  561. { "cct", tZONE, -HOUR( 8) }, /* China Coast, USSR Zone 7 */
  562. { "jst", tZONE, -HOUR( 9) }, /* Japan Standard, USSR Zone 8 */
  563. { "jdt", tDAYZONE, -HOUR( 9) }, /* Japan Daylight */
  564. { "kst", tZONE, -HOUR( 9) }, /* Korea Standard */
  565. { "kdt", tDAYZONE, -HOUR( 9) }, /* Korea Daylight */
  566. { "cast", tZONE, -HOUR(19/2) }, /* Central Australian Standard */
  567. { "cadt", tDAYZONE, -HOUR(19/2) }, /* Central Australian Daylight */
  568. { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
  569. { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
  570. { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
  571. { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
  572. { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
  573. { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
  574. { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
  575. /* ADDED BY Marco Nijdam */
  576. { "dst", tDST, HOUR( 0) }, /* DST on (hour is ignored) */
  577. /* End ADDED */
  578. { NULL }
  579. };
  580. /*
  581. * Military timezone table.
  582. */
  583. static TABLE MilitaryTable[] = {
  584. { "a", tZONE, -HOUR( 1) },
  585. { "b", tZONE, -HOUR( 2) },
  586. { "c", tZONE, -HOUR( 3) },
  587. { "d", tZONE, -HOUR( 4) },
  588. { "e", tZONE, -HOUR( 5) },
  589. { "f", tZONE, -HOUR( 6) },
  590. { "g", tZONE, -HOUR( 7) },
  591. { "h", tZONE, -HOUR( 8) },
  592. { "i", tZONE, -HOUR( 9) },
  593. { "k", tZONE, -HOUR(10) },
  594. { "l", tZONE, -HOUR(11) },
  595. { "m", tZONE, -HOUR(12) },
  596. { "n", tZONE, HOUR( 1) },
  597. { "o", tZONE, HOUR( 2) },
  598. { "p", tZONE, HOUR( 3) },
  599. { "q", tZONE, HOUR( 4) },
  600. { "r", tZONE, HOUR( 5) },
  601. { "s", tZONE, HOUR( 6) },
  602. { "t", tZONE, HOUR( 7) },
  603. { "u", tZONE, HOUR( 8) },
  604. { "v", tZONE, HOUR( 9) },
  605. { "w", tZONE, HOUR( 10) },
  606. { "x", tZONE, HOUR( 11) },
  607. { "y", tZONE, HOUR( 12) },
  608. { "z", tZONE, HOUR( 0) },
  609. { NULL }
  610. };
  611. /*
  612. * Dump error messages in the bit bucket.
  613. */
  614. static void
  615. TclDateerror(
  616. char *s)
  617. {
  618. }
  619. static time_t
  620. ToSeconds(
  621. time_t Hours,
  622. time_t Minutes,
  623. time_t Seconds,
  624. MERIDIAN Meridian)
  625. {
  626. if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) {
  627. return -1;
  628. }
  629. switch (Meridian) {
  630. case MER24:
  631. if (Hours < 0 || Hours > 23) {
  632. return -1;
  633. }
  634. return (Hours * 60L + Minutes) * 60L + Seconds;
  635. case MERam:
  636. if (Hours < 1 || Hours > 12) {
  637. return -1;
  638. }
  639. return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
  640. case MERpm:
  641. if (Hours < 1 || Hours > 12) {
  642. return -1;
  643. }
  644. return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
  645. }
  646. return -1; /* Should never be reached */
  647. }
  648. static int
  649. LookupWord(
  650. char *buff)
  651. {
  652. register char *p;
  653. register char *q;
  654. register TABLE *tp;
  655. int i, abbrev;
  656. /*
  657. * Make it lowercase.
  658. */
  659. Tcl_UtfToLower(buff);
  660. if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
  661. yylval.Meridian = MERam;
  662. return tMERIDIAN;
  663. }
  664. if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
  665. yylval.Meridian = MERpm;
  666. return tMERIDIAN;
  667. }
  668. /*
  669. * See if we have an abbreviation for a month.
  670. */
  671. if (strlen(buff) == 3) {
  672. abbrev = 1;
  673. } else if (strlen(buff) == 4 && buff[3] == '.') {
  674. abbrev = 1;
  675. buff[3] = '\0';
  676. } else {
  677. abbrev = 0;
  678. }
  679. for (tp = MonthDayTable; tp->name; tp++) {
  680. if (abbrev) {
  681. if (strncmp(buff, tp->name, 3) == 0) {
  682. yylval.Number = tp->value;
  683. return tp->type;
  684. }
  685. } else if (strcmp(buff, tp->name) == 0) {
  686. yylval.Number = tp->value;
  687. return tp->type;
  688. }
  689. }
  690. for (tp = TimezoneTable; tp->name; tp++) {
  691. if (strcmp(buff, tp->name) == 0) {
  692. yylval.Number = tp->value;
  693. return tp->type;
  694. }
  695. }
  696. for (tp = UnitsTable; tp->name; tp++) {
  697. if (strcmp(buff, tp->name) == 0) {
  698. yylval.Number = tp->value;
  699. return tp->type;
  700. }
  701. }
  702. /*
  703. * Strip off any plural and try the units table again.
  704. */
  705. i = strlen(buff) - 1;
  706. if (i > 0 && buff[i] == 's') {
  707. buff[i] = '\0';
  708. for (tp = UnitsTable; tp->name; tp++) {
  709. if (strcmp(buff, tp->name) == 0) {
  710. yylval.Number = tp->value;
  711. return tp->type;
  712. }
  713. }
  714. }
  715. for (tp = OtherTable; tp->name; tp++) {
  716. if (strcmp(buff, tp->name) == 0) {
  717. yylval.Number = tp->value;
  718. return tp->type;
  719. }
  720. }
  721. /*
  722. * Military timezones.
  723. */
  724. if (buff[1] == '\0' && !(*buff & 0x80)
  725. && isalpha(UCHAR(*buff))) { /* INTL: ISO only */
  726. for (tp = MilitaryTable; tp->name; tp++) {
  727. if (strcmp(buff, tp->name) == 0) {
  728. yylval.Number = tp->value;
  729. return tp->type;
  730. }
  731. }
  732. }
  733. /*
  734. * Drop out any periods and try the timezone table again.
  735. */
  736. for (i = 0, p = q = buff; *q; q++) {
  737. if (*q != '.') {
  738. *p++ = *q;
  739. } else {
  740. i++;
  741. }
  742. }
  743. *p = '\0';
  744. if (i) {
  745. for (tp = TimezoneTable; tp->name; tp++) {
  746. if (strcmp(buff, tp->name) == 0) {
  747. yylval.Number = tp->value;
  748. return tp->type;
  749. }
  750. }
  751. }
  752. return tID;
  753. }
  754. static int
  755. TclDatelex(
  756. void *info)
  757. {
  758. register char c;
  759. register char *p;
  760. char buff[20];
  761. int Count;
  762. for ( ; ; ) {
  763. while (isspace(UCHAR(*yyInput))) {
  764. yyInput++;
  765. }
  766. if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */
  767. /*
  768. * Convert the string into a number; count the number of digits.
  769. */
  770. Count = 0;
  771. for (yylval.Number = 0;
  772. isdigit(UCHAR(c = *yyInput++)); ) { /* INTL: digit */
  773. yylval.Number = 10 * yylval.Number + c - '0';
  774. Count++;
  775. }
  776. yyInput--;
  777. yyDigitCount = Count;
  778. /*
  779. * A number with 6 or more digits is considered an ISO 8601 base.
  780. */
  781. if (Count >= 6) {
  782. return tISOBASE;
  783. } else {
  784. return tUNUMBER;
  785. }
  786. }
  787. if (!(c & 0x80) && isalpha(UCHAR(c))) { /* INTL: ISO only. */
  788. for (p = buff; isalpha(UCHAR(c = *yyInput++)) /* INTL: ISO only. */
  789. || c == '.'; ) {
  790. if (p < &buff[sizeof buff - 1]) {
  791. *p++ = c;
  792. }
  793. }
  794. *p = '\0';
  795. yyInput--;
  796. return LookupWord(buff);
  797. }
  798. if (c != '(') {
  799. return *yyInput++;
  800. }
  801. Count = 0;
  802. do {
  803. c = *yyInput++;
  804. if (c == '\0') {
  805. return c;
  806. } else if (c == '(') {
  807. Count++;
  808. } else if (c == ')') {
  809. Count--;
  810. }
  811. } while (Count > 0);
  812. }
  813. }
  814. int
  815. TclClockOldscanObjCmd(
  816. ClientData clientData, /* Unused */
  817. Tcl_Interp *interp, /* Tcl interpreter */
  818. int objc, /* Count of paraneters */
  819. Tcl_Obj *CONST *objv) /* Parameters */
  820. {
  821. Tcl_Obj *result, *resultElement;
  822. int yr, mo, da;
  823. DateInfo dateInfo;
  824. void *info = (void *) &dateInfo;
  825. if (objc != 5) {
  826. Tcl_WrongNumArgs(interp, 1, objv,
  827. "stringToParse baseYear baseMonth baseDay" );
  828. return TCL_ERROR;
  829. }
  830. yyInput = Tcl_GetString( objv[1] );
  831. yyHaveDate = 0;
  832. if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK
  833. || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK
  834. || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) {
  835. return TCL_ERROR;
  836. }
  837. yyYear = yr; yyMonth = mo; yyDay = da;
  838. yyHaveTime = 0;
  839. yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24;
  840. yyHaveZone = 0;
  841. yyTimezone = 0; yyDSTmode = DSTmaybe;
  842. yyHaveOrdinalMonth = 0;
  843. yyMonthOrdinal = 0;
  844. yyHaveDay = 0;
  845. yyDayOrdinal = 0; yyDayNumber = 0;
  846. yyHaveRel = 0;
  847. yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL;
  848. if (yyparse(info)) {
  849. Tcl_SetObjResult(interp, Tcl_NewStringObj("syntax error", -1));
  850. return TCL_ERROR;
  851. }
  852. if (yyHaveDate > 1) {
  853. Tcl_SetObjResult(interp,
  854. Tcl_NewStringObj("more than one date in string", -1));
  855. return TCL_ERROR;
  856. }
  857. if (yyHaveTime > 1) {
  858. Tcl_SetObjResult(interp,
  859. Tcl_NewStringObj("more than one time of day in string", -1));
  860. return TCL_ERROR;
  861. }
  862. if (yyHaveZone > 1) {
  863. Tcl_SetObjResult(interp,
  864. Tcl_NewStringObj("more than one time zone in string", -1));
  865. return TCL_ERROR;
  866. }
  867. if (yyHaveDay > 1) {
  868. Tcl_SetObjResult(interp,
  869. Tcl_NewStringObj("more than one weekday in string", -1));
  870. return TCL_ERROR;
  871. }
  872. if (yyHaveOrdinalMonth > 1) {
  873. Tcl_SetObjResult(interp,
  874. Tcl_NewStringObj("more than one ordinal month in string", -1));
  875. return TCL_ERROR;
  876. }
  877. result = Tcl_NewObj();
  878. resultElement = Tcl_NewObj();
  879. if (yyHaveDate) {
  880. Tcl_ListObjAppendElement(interp, resultElement,
  881. Tcl_NewIntObj((int) yyYear));
  882. Tcl_ListObjAppendElement(interp, resultElement,
  883. Tcl_NewIntObj((int) yyMonth));
  884. Tcl_ListObjAppendElement(interp, resultElement,
  885. Tcl_NewIntObj((int) yyDay));
  886. }
  887. Tcl_ListObjAppendElement(interp, result, resultElement);
  888. if (yyHaveTime) {
  889. Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj((int)
  890. ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian)));
  891. } else {
  892. Tcl_ListObjAppendElement(interp, result, Tcl_NewObj());
  893. }
  894. resultElement = Tcl_NewObj();
  895. if (yyHaveZone) {
  896. Tcl_ListObjAppendElement(interp, resultElement,
  897. Tcl_NewIntObj((int) -yyTimezone));
  898. Tcl_ListObjAppendElement(interp, resultElement,
  899. Tcl_NewIntObj(1 - yyDSTmode));
  900. }
  901. Tcl_ListObjAppendElement(interp, result, resultElement);
  902. resultElement = Tcl_NewObj();
  903. if (yyHaveRel) {
  904. Tcl_ListObjAppendElement(interp, resultElement,
  905. Tcl_NewIntObj((int) yyRelMonth));
  906. Tcl_ListObjAppendElement(interp, resultElement,
  907. Tcl_NewIntObj((int) yyRelDay));
  908. Tcl_ListObjAppendElement(interp, resultElement,
  909. Tcl_NewIntObj((int) yyRelSeconds));
  910. }
  911. Tcl_ListObjAppendElement(interp, result, resultElement);
  912. resultElement = Tcl_NewObj();
  913. if (yyHaveDay && !yyHaveDate) {
  914. Tcl_ListObjAppendElement(interp, resultElement,
  915. Tcl_NewIntObj((int) yyDayOrdinal));
  916. Tcl_ListObjAppendElement(interp, resultElement,
  917. Tcl_NewIntObj((int) yyDayNumber));
  918. }
  919. Tcl_ListObjAppendElement(interp, result, resultElement);
  920. resultElement = Tcl_NewObj();
  921. if (yyHaveOrdinalMonth) {
  922. Tcl_ListObjAppendElement(interp, resultElement,
  923. Tcl_NewIntObj((int) yyMonthOrdinal));
  924. Tcl_ListObjAppendElement(interp, resultElement,
  925. Tcl_NewIntObj((int) yyMonth));
  926. }
  927. Tcl_ListObjAppendElement(interp, result, resultElement);
  928. Tcl_SetObjResult(interp, result);
  929. return TCL_OK;
  930. }
  931. /*
  932. * Local Variables:
  933. * mode: c
  934. * c-basic-offset: 4
  935. * fill-column: 78
  936. * End:
  937. */