PageRenderTime 58ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/opensource.apple.com/source/tcl/tcl-95/tcl/tcl/generic/tclGetDate.y

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