Re: notmuch-tree display
[notmuch-archives.git] / 55 / 47848433edffdcd70aa9626adf2cda8da470d5
1 Return-Path: <jani@nikula.org>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id A79F6429E32\r
6         for <notmuch@notmuchmail.org>; Wed, 10 Aug 2011 03:24:12 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
9 X-Spam-Flag: NO\r
10 X-Spam-Score: -0.7\r
11 X-Spam-Level: \r
12 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
13         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
14 Received: from olra.theworths.org ([127.0.0.1])\r
15         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
16         with ESMTP id xnBI7q+EKNjw for <notmuch@notmuchmail.org>;\r
17         Wed, 10 Aug 2011 03:23:38 -0700 (PDT)\r
18 Received: from mail-qw0-f53.google.com (mail-qw0-f53.google.com\r
19         [209.85.216.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
20         (No client certificate requested)\r
21         by olra.theworths.org (Postfix) with ESMTPS id C5CA4429E30\r
22         for <notmuch@notmuchmail.org>; Wed, 10 Aug 2011 03:23:35 -0700 (PDT)\r
23 Received: by mail-qw0-f53.google.com with SMTP id 7so539114qwb.26\r
24         for <notmuch@notmuchmail.org>; Wed, 10 Aug 2011 03:22:16 -0700 (PDT)\r
25 Received: by 10.229.66.222 with SMTP id o30mr6166147qci.189.1312971735811;\r
26         Wed, 10 Aug 2011 03:22:15 -0700 (PDT)\r
27 Received: from localhost (nikula.org [92.243.24.172])\r
28         by mx.google.com with ESMTPS id m7sm714311qct.17.2011.08.10.03.22.12\r
29         (version=TLSv1/SSLv3 cipher=OTHER);\r
30         Wed, 10 Aug 2011 03:22:14 -0700 (PDT)\r
31 From: Jani Nikula <jani@nikula.org>\r
32 To: notmuch@notmuchmail.org\r
33 Subject: [RFC PATCH 1/3] Import date/time parser from GNU coreutils\r
34 Date: Wed, 10 Aug 2011 10:22:05 +0000\r
35 Message-Id:\r
36  <92e838734a58ff6d89c8ce47a32aa1c33e31cc3e.1312964528.git.jani@nikula.org>\r
37 X-Mailer: git-send-email 1.7.1\r
38 In-Reply-To: <cover.1312964528.git.jani@nikula.org>\r
39 References: <cover.1312964528.git.jani@nikula.org>\r
40 In-Reply-To: <cover.1312964528.git.jani@nikula.org>\r
41 References: <cover.1312964528.git.jani@nikula.org>\r
42 X-Mailman-Approved-At: Wed, 24 Aug 2011 16:29:30 -0700\r
43 Cc: amdragon@mit.edu\r
44 X-BeenThere: notmuch@notmuchmail.org\r
45 X-Mailman-Version: 2.1.13\r
46 Precedence: list\r
47 List-Id: "Use and development of the notmuch mail system."\r
48         <notmuch.notmuchmail.org>\r
49 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
50         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
51 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
52 List-Post: <mailto:notmuch@notmuchmail.org>\r
53 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
54 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
55         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
56 X-List-Received-Date: Wed, 10 Aug 2011 10:24:13 -0000\r
57 \r
58 From: Michal Sojka <sojkam1@fel.cvut.cz>\r
59 \r
60 This function have quite a lot dependencies. We may reduce them later it\r
61 it is a problem.\r
62 ---\r
63  lib/c-ctype.c  |  398 +++++++\r
64  lib/c-ctype.h  |  297 +++++\r
65  lib/getdate.c  | 3497 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
66  lib/getdate.h  |   22 +\r
67  lib/getdate.y  | 1572 +++++++++++++++++++++++++\r
68  lib/gettime.c  |   48 +\r
69  lib/intprops.h |   83 ++\r
70  lib/timespec.h |   39 +\r
71  lib/verify.h   |  140 +++\r
72  9 files changed, 6096 insertions(+), 0 deletions(-)\r
73  create mode 100644 lib/c-ctype.c\r
74  create mode 100644 lib/c-ctype.h\r
75  create mode 100644 lib/getdate.c\r
76  create mode 100644 lib/getdate.h\r
77  create mode 100644 lib/getdate.y\r
78  create mode 100644 lib/gettime.c\r
79  create mode 100644 lib/gettime.h\r
80  create mode 100644 lib/intprops.h\r
81  create mode 100644 lib/timespec.h\r
82  create mode 100644 lib/verify.h\r
83 \r
84 diff --git a/lib/c-ctype.c b/lib/c-ctype.c\r
85 new file mode 100644\r
86 index 0000000..48baa72\r
87 --- /dev/null\r
88 +++ b/lib/c-ctype.c\r
89 @@ -0,0 +1,398 @@\r
90 +/* -*- buffer-read-only: t -*- vi: set ro: */\r
91 +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\r
92 +/* Character handling in C locale.\r
93 +\r
94 +   Copyright 2000-2003, 2006, 2009-2010 Free Software Foundation, Inc.\r
95 +\r
96 +This program is free software; you can redistribute it and/or modify\r
97 +it under the terms of the GNU General Public License as published by\r
98 +the Free Software Foundation; either version 3 of the License, or\r
99 +(at your option) any later version.\r
100 +\r
101 +This program is distributed in the hope that it will be useful,\r
102 +but WITHOUT ANY WARRANTY; without even the implied warranty of\r
103 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
104 +GNU General Public License for more details.\r
105 +\r
106 +You should have received a copy of the GNU General Public License\r
107 +along with this program; if not, write to the Free Software Foundation,\r
108 +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */\r
109 +\r
110 +#include <config.h>\r
111 +\r
112 +/* Specification.  */\r
113 +#define NO_C_CTYPE_MACROS\r
114 +#include "c-ctype.h"\r
115 +\r
116 +/* The function isascii is not locale dependent. Its use in EBCDIC is\r
117 +   questionable. */\r
118 +bool\r
119 +c_isascii (int c)\r
120 +{\r
121 +  return (c >= 0x00 && c <= 0x7f);\r
122 +}\r
123 +\r
124 +bool\r
125 +c_isalnum (int c)\r
126 +{\r
127 +#if C_CTYPE_CONSECUTIVE_DIGITS \\r
128 +    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
129 +#if C_CTYPE_ASCII\r
130 +  return ((c >= '0' && c <= '9')\r
131 +          || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'));\r
132 +#else\r
133 +  return ((c >= '0' && c <= '9')\r
134 +          || (c >= 'A' && c <= 'Z')\r
135 +          || (c >= 'a' && c <= 'z'));\r
136 +#endif\r
137 +#else\r
138 +  switch (c)\r
139 +    {\r
140 +    case '0': case '1': case '2': case '3': case '4': case '5':\r
141 +    case '6': case '7': case '8': case '9':\r
142 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
143 +    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\r
144 +    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\r
145 +    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
146 +    case 'Y': case 'Z':\r
147 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
148 +    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
149 +    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\r
150 +    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
151 +    case 'y': case 'z':\r
152 +      return 1;\r
153 +    default:\r
154 +      return 0;\r
155 +    }\r
156 +#endif\r
157 +}\r
158 +\r
159 +bool\r
160 +c_isalpha (int c)\r
161 +{\r
162 +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
163 +#if C_CTYPE_ASCII\r
164 +  return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z');\r
165 +#else\r
166 +  return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));\r
167 +#endif\r
168 +#else\r
169 +  switch (c)\r
170 +    {\r
171 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
172 +    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\r
173 +    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\r
174 +    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
175 +    case 'Y': case 'Z':\r
176 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
177 +    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
178 +    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\r
179 +    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
180 +    case 'y': case 'z':\r
181 +      return 1;\r
182 +    default:\r
183 +      return 0;\r
184 +    }\r
185 +#endif\r
186 +}\r
187 +\r
188 +bool\r
189 +c_isblank (int c)\r
190 +{\r
191 +  return (c == ' ' || c == '\t');\r
192 +}\r
193 +\r
194 +bool\r
195 +c_iscntrl (int c)\r
196 +{\r
197 +#if C_CTYPE_ASCII\r
198 +  return ((c & ~0x1f) == 0 || c == 0x7f);\r
199 +#else\r
200 +  switch (c)\r
201 +    {\r
202 +    case ' ': case '!': case '"': case '#': case '$': case '%':\r
203 +    case '&': case '\'': case '(': case ')': case '*': case '+':\r
204 +    case ',': case '-': case '.': case '/':\r
205 +    case '0': case '1': case '2': case '3': case '4': case '5':\r
206 +    case '6': case '7': case '8': case '9':\r
207 +    case ':': case ';': case '<': case '=': case '>': case '?':\r
208 +    case '@':\r
209 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
210 +    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\r
211 +    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\r
212 +    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
213 +    case 'Y': case 'Z':\r
214 +    case '[': case '\\': case ']': case '^': case '_': case '`':\r
215 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
216 +    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
217 +    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\r
218 +    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
219 +    case 'y': case 'z':\r
220 +    case '{': case '|': case '}': case '~':\r
221 +      return 0;\r
222 +    default:\r
223 +      return 1;\r
224 +    }\r
225 +#endif\r
226 +}\r
227 +\r
228 +bool\r
229 +c_isdigit (int c)\r
230 +{\r
231 +#if C_CTYPE_CONSECUTIVE_DIGITS\r
232 +  return (c >= '0' && c <= '9');\r
233 +#else\r
234 +  switch (c)\r
235 +    {\r
236 +    case '0': case '1': case '2': case '3': case '4': case '5':\r
237 +    case '6': case '7': case '8': case '9':\r
238 +      return 1;\r
239 +    default:\r
240 +      return 0;\r
241 +    }\r
242 +#endif\r
243 +}\r
244 +\r
245 +bool\r
246 +c_islower (int c)\r
247 +{\r
248 +#if C_CTYPE_CONSECUTIVE_LOWERCASE\r
249 +  return (c >= 'a' && c <= 'z');\r
250 +#else\r
251 +  switch (c)\r
252 +    {\r
253 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
254 +    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
255 +    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\r
256 +    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
257 +    case 'y': case 'z':\r
258 +      return 1;\r
259 +    default:\r
260 +      return 0;\r
261 +    }\r
262 +#endif\r
263 +}\r
264 +\r
265 +bool\r
266 +c_isgraph (int c)\r
267 +{\r
268 +#if C_CTYPE_ASCII\r
269 +  return (c >= '!' && c <= '~');\r
270 +#else\r
271 +  switch (c)\r
272 +    {\r
273 +    case '!': case '"': case '#': case '$': case '%': case '&':\r
274 +    case '\'': case '(': case ')': case '*': case '+': case ',':\r
275 +    case '-': case '.': case '/':\r
276 +    case '0': case '1': case '2': case '3': case '4': case '5':\r
277 +    case '6': case '7': case '8': case '9':\r
278 +    case ':': case ';': case '<': case '=': case '>': case '?':\r
279 +    case '@':\r
280 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
281 +    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\r
282 +    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\r
283 +    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
284 +    case 'Y': case 'Z':\r
285 +    case '[': case '\\': case ']': case '^': case '_': case '`':\r
286 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
287 +    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
288 +    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\r
289 +    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
290 +    case 'y': case 'z':\r
291 +    case '{': case '|': case '}': case '~':\r
292 +      return 1;\r
293 +    default:\r
294 +      return 0;\r
295 +    }\r
296 +#endif\r
297 +}\r
298 +\r
299 +bool\r
300 +c_isprint (int c)\r
301 +{\r
302 +#if C_CTYPE_ASCII\r
303 +  return (c >= ' ' && c <= '~');\r
304 +#else\r
305 +  switch (c)\r
306 +    {\r
307 +    case ' ': case '!': case '"': case '#': case '$': case '%':\r
308 +    case '&': case '\'': case '(': case ')': case '*': case '+':\r
309 +    case ',': case '-': case '.': case '/':\r
310 +    case '0': case '1': case '2': case '3': case '4': case '5':\r
311 +    case '6': case '7': case '8': case '9':\r
312 +    case ':': case ';': case '<': case '=': case '>': case '?':\r
313 +    case '@':\r
314 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
315 +    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\r
316 +    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\r
317 +    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
318 +    case 'Y': case 'Z':\r
319 +    case '[': case '\\': case ']': case '^': case '_': case '`':\r
320 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
321 +    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\r
322 +    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\r
323 +    case 's': case 't': case 'u': case 'v': case 'w': case 'x':\r
324 +    case 'y': case 'z':\r
325 +    case '{': case '|': case '}': case '~':\r
326 +      return 1;\r
327 +    default:\r
328 +      return 0;\r
329 +    }\r
330 +#endif\r
331 +}\r
332 +\r
333 +bool\r
334 +c_ispunct (int c)\r
335 +{\r
336 +#if C_CTYPE_ASCII\r
337 +  return ((c >= '!' && c <= '~')\r
338 +          && !((c >= '0' && c <= '9')\r
339 +               || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')));\r
340 +#else\r
341 +  switch (c)\r
342 +    {\r
343 +    case '!': case '"': case '#': case '$': case '%': case '&':\r
344 +    case '\'': case '(': case ')': case '*': case '+': case ',':\r
345 +    case '-': case '.': case '/':\r
346 +    case ':': case ';': case '<': case '=': case '>': case '?':\r
347 +    case '@':\r
348 +    case '[': case '\\': case ']': case '^': case '_': case '`':\r
349 +    case '{': case '|': case '}': case '~':\r
350 +      return 1;\r
351 +    default:\r
352 +      return 0;\r
353 +    }\r
354 +#endif\r
355 +}\r
356 +\r
357 +bool\r
358 +c_isspace (int c)\r
359 +{\r
360 +  return (c == ' ' || c == '\t'\r
361 +          || c == '\n' || c == '\v' || c == '\f' || c == '\r');\r
362 +}\r
363 +\r
364 +bool\r
365 +c_isupper (int c)\r
366 +{\r
367 +#if C_CTYPE_CONSECUTIVE_UPPERCASE\r
368 +  return (c >= 'A' && c <= 'Z');\r
369 +#else\r
370 +  switch (c)\r
371 +    {\r
372 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
373 +    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\r
374 +    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\r
375 +    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\r
376 +    case 'Y': case 'Z':\r
377 +      return 1;\r
378 +    default:\r
379 +      return 0;\r
380 +    }\r
381 +#endif\r
382 +}\r
383 +\r
384 +bool\r
385 +c_isxdigit (int c)\r
386 +{\r
387 +#if C_CTYPE_CONSECUTIVE_DIGITS \\r
388 +    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
389 +#if C_CTYPE_ASCII\r
390 +  return ((c >= '0' && c <= '9')\r
391 +          || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F'));\r
392 +#else\r
393 +  return ((c >= '0' && c <= '9')\r
394 +          || (c >= 'A' && c <= 'F')\r
395 +          || (c >= 'a' && c <= 'f'));\r
396 +#endif\r
397 +#else\r
398 +  switch (c)\r
399 +    {\r
400 +    case '0': case '1': case '2': case '3': case '4': case '5':\r
401 +    case '6': case '7': case '8': case '9':\r
402 +    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
403 +    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
404 +      return 1;\r
405 +    default:\r
406 +      return 0;\r
407 +    }\r
408 +#endif\r
409 +}\r
410 +\r
411 +int\r
412 +c_tolower (int c)\r
413 +{\r
414 +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
415 +  return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c);\r
416 +#else\r
417 +  switch (c)\r
418 +    {\r
419 +    case 'A': return 'a';\r
420 +    case 'B': return 'b';\r
421 +    case 'C': return 'c';\r
422 +    case 'D': return 'd';\r
423 +    case 'E': return 'e';\r
424 +    case 'F': return 'f';\r
425 +    case 'G': return 'g';\r
426 +    case 'H': return 'h';\r
427 +    case 'I': return 'i';\r
428 +    case 'J': return 'j';\r
429 +    case 'K': return 'k';\r
430 +    case 'L': return 'l';\r
431 +    case 'M': return 'm';\r
432 +    case 'N': return 'n';\r
433 +    case 'O': return 'o';\r
434 +    case 'P': return 'p';\r
435 +    case 'Q': return 'q';\r
436 +    case 'R': return 'r';\r
437 +    case 'S': return 's';\r
438 +    case 'T': return 't';\r
439 +    case 'U': return 'u';\r
440 +    case 'V': return 'v';\r
441 +    case 'W': return 'w';\r
442 +    case 'X': return 'x';\r
443 +    case 'Y': return 'y';\r
444 +    case 'Z': return 'z';\r
445 +    default: return c;\r
446 +    }\r
447 +#endif\r
448 +}\r
449 +\r
450 +int\r
451 +c_toupper (int c)\r
452 +{\r
453 +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
454 +  return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c);\r
455 +#else\r
456 +  switch (c)\r
457 +    {\r
458 +    case 'a': return 'A';\r
459 +    case 'b': return 'B';\r
460 +    case 'c': return 'C';\r
461 +    case 'd': return 'D';\r
462 +    case 'e': return 'E';\r
463 +    case 'f': return 'F';\r
464 +    case 'g': return 'G';\r
465 +    case 'h': return 'H';\r
466 +    case 'i': return 'I';\r
467 +    case 'j': return 'J';\r
468 +    case 'k': return 'K';\r
469 +    case 'l': return 'L';\r
470 +    case 'm': return 'M';\r
471 +    case 'n': return 'N';\r
472 +    case 'o': return 'O';\r
473 +    case 'p': return 'P';\r
474 +    case 'q': return 'Q';\r
475 +    case 'r': return 'R';\r
476 +    case 's': return 'S';\r
477 +    case 't': return 'T';\r
478 +    case 'u': return 'U';\r
479 +    case 'v': return 'V';\r
480 +    case 'w': return 'W';\r
481 +    case 'x': return 'X';\r
482 +    case 'y': return 'Y';\r
483 +    case 'z': return 'Z';\r
484 +    default: return c;\r
485 +    }\r
486 +#endif\r
487 +}\r
488 diff --git a/lib/c-ctype.h b/lib/c-ctype.h\r
489 new file mode 100644\r
490 index 0000000..26c89b8\r
491 --- /dev/null\r
492 +++ b/lib/c-ctype.h\r
493 @@ -0,0 +1,297 @@\r
494 +/* -*- buffer-read-only: t -*- vi: set ro: */\r
495 +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\r
496 +/* Character handling in C locale.\r
497 +\r
498 +   These functions work like the corresponding functions in <ctype.h>,\r
499 +   except that they have the C (POSIX) locale hardwired, whereas the\r
500 +   <ctype.h> functions' behaviour depends on the current locale set via\r
501 +   setlocale.\r
502 +\r
503 +   Copyright (C) 2000-2003, 2006, 2008-2010 Free Software Foundation, Inc.\r
504 +\r
505 +This program is free software; you can redistribute it and/or modify\r
506 +it under the terms of the GNU General Public License as published by\r
507 +the Free Software Foundation; either version 3 of the License, or\r
508 +(at your option) any later version.\r
509 +\r
510 +This program is distributed in the hope that it will be useful,\r
511 +but WITHOUT ANY WARRANTY; without even the implied warranty of\r
512 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
513 +GNU General Public License for more details.\r
514 +\r
515 +You should have received a copy of the GNU General Public License\r
516 +along with this program; if not, write to the Free Software Foundation,\r
517 +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */\r
518 +\r
519 +#ifndef C_CTYPE_H\r
520 +#define C_CTYPE_H\r
521 +\r
522 +#include <stdbool.h>\r
523 +\r
524 +\r
525 +#ifdef __cplusplus\r
526 +extern "C" {\r
527 +#endif\r
528 +\r
529 +\r
530 +/* The functions defined in this file assume the "C" locale and a character\r
531 +   set without diacritics (ASCII-US or EBCDIC-US or something like that).\r
532 +   Even if the "C" locale on a particular system is an extension of the ASCII\r
533 +   character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it\r
534 +   is ISO-8859-1), the functions in this file recognize only the ASCII\r
535 +   characters.  */\r
536 +\r
537 +\r
538 +/* Check whether the ASCII optimizations apply. */\r
539 +\r
540 +/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that\r
541 +   '0', '1', ..., '9' have consecutive integer values.  */\r
542 +#define C_CTYPE_CONSECUTIVE_DIGITS 1\r
543 +\r
544 +#if ('A' <= 'Z') \\r
545 +    && ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \\r
546 +    && ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \\r
547 +    && ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \\r
548 +    && ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \\r
549 +    && ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \\r
550 +    && ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \\r
551 +    && ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \\r
552 +    && ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \\r
553 +    && ('Y' + 1 == 'Z')\r
554 +#define C_CTYPE_CONSECUTIVE_UPPERCASE 1\r
555 +#endif\r
556 +\r
557 +#if ('a' <= 'z') \\r
558 +    && ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \\r
559 +    && ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \\r
560 +    && ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \\r
561 +    && ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \\r
562 +    && ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \\r
563 +    && ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \\r
564 +    && ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \\r
565 +    && ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \\r
566 +    && ('y' + 1 == 'z')\r
567 +#define C_CTYPE_CONSECUTIVE_LOWERCASE 1\r
568 +#endif\r
569 +\r
570 +#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \\r
571 +    && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \\r
572 +    && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \\r
573 +    && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \\r
574 +    && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \\r
575 +    && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \\r
576 +    && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \\r
577 +    && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \\r
578 +    && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \\r
579 +    && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \\r
580 +    && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \\r
581 +    && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \\r
582 +    && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \\r
583 +    && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \\r
584 +    && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \\r
585 +    && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \\r
586 +    && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \\r
587 +    && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \\r
588 +    && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \\r
589 +    && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \\r
590 +    && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \\r
591 +    && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \\r
592 +    && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)\r
593 +/* The character set is ASCII or one of its variants or extensions, not EBCDIC.\r
594 +   Testing the value of '\n' and '\r' is not relevant.  */\r
595 +#define C_CTYPE_ASCII 1\r
596 +#endif\r
597 +\r
598 +\r
599 +/* Function declarations. */\r
600 +\r
601 +/* Unlike the functions in <ctype.h>, which require an argument in the range\r
602 +   of the 'unsigned char' type, the functions here operate on values that are\r
603 +   in the 'unsigned char' range or in the 'char' range.  In other words,\r
604 +   when you have a 'char' value, you need to cast it before using it as\r
605 +   argument to a <ctype.h> function:\r
606 +\r
607 +         const char *s = ...;\r
608 +         if (isalpha ((unsigned char) *s)) ...\r
609 +\r
610 +   but you don't need to cast it for the functions defined in this file:\r
611 +\r
612 +         const char *s = ...;\r
613 +         if (c_isalpha (*s)) ...\r
614 + */\r
615 +\r
616 +extern bool c_isascii (int c); /* not locale dependent */\r
617 +\r
618 +extern bool c_isalnum (int c);\r
619 +extern bool c_isalpha (int c);\r
620 +extern bool c_isblank (int c);\r
621 +extern bool c_iscntrl (int c);\r
622 +extern bool c_isdigit (int c);\r
623 +extern bool c_islower (int c);\r
624 +extern bool c_isgraph (int c);\r
625 +extern bool c_isprint (int c);\r
626 +extern bool c_ispunct (int c);\r
627 +extern bool c_isspace (int c);\r
628 +extern bool c_isupper (int c);\r
629 +extern bool c_isxdigit (int c);\r
630 +\r
631 +extern int c_tolower (int c);\r
632 +extern int c_toupper (int c);\r
633 +\r
634 +\r
635 +#if defined __GNUC__ && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS\r
636 +\r
637 +/* ASCII optimizations. */\r
638 +\r
639 +#undef c_isascii\r
640 +#define c_isascii(c) \\r
641 +  ({ int __c = (c); \\r
642 +     (__c >= 0x00 && __c <= 0x7f); \\r
643 +   })\r
644 +\r
645 +#if C_CTYPE_CONSECUTIVE_DIGITS \\r
646 +    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
647 +#if C_CTYPE_ASCII\r
648 +#undef c_isalnum\r
649 +#define c_isalnum(c) \\r
650 +  ({ int __c = (c); \\r
651 +     ((__c >= '0' && __c <= '9') \\r
652 +      || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \\r
653 +   })\r
654 +#else\r
655 +#undef c_isalnum\r
656 +#define c_isalnum(c) \\r
657 +  ({ int __c = (c); \\r
658 +     ((__c >= '0' && __c <= '9') \\r
659 +      || (__c >= 'A' && __c <= 'Z') \\r
660 +      || (__c >= 'a' && __c <= 'z')); \\r
661 +   })\r
662 +#endif\r
663 +#endif\r
664 +\r
665 +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
666 +#if C_CTYPE_ASCII\r
667 +#undef c_isalpha\r
668 +#define c_isalpha(c) \\r
669 +  ({ int __c = (c); \\r
670 +     ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \\r
671 +   })\r
672 +#else\r
673 +#undef c_isalpha\r
674 +#define c_isalpha(c) \\r
675 +  ({ int __c = (c); \\r
676 +     ((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \\r
677 +   })\r
678 +#endif\r
679 +#endif\r
680 +\r
681 +#undef c_isblank\r
682 +#define c_isblank(c) \\r
683 +  ({ int __c = (c); \\r
684 +     (__c == ' ' || __c == '\t'); \\r
685 +   })\r
686 +\r
687 +#if C_CTYPE_ASCII\r
688 +#undef c_iscntrl\r
689 +#define c_iscntrl(c) \\r
690 +  ({ int __c = (c); \\r
691 +     ((__c & ~0x1f) == 0 || __c == 0x7f); \\r
692 +   })\r
693 +#endif\r
694 +\r
695 +#if C_CTYPE_CONSECUTIVE_DIGITS\r
696 +#undef c_isdigit\r
697 +#define c_isdigit(c) \\r
698 +  ({ int __c = (c); \\r
699 +     (__c >= '0' && __c <= '9'); \\r
700 +   })\r
701 +#endif\r
702 +\r
703 +#if C_CTYPE_CONSECUTIVE_LOWERCASE\r
704 +#undef c_islower\r
705 +#define c_islower(c) \\r
706 +  ({ int __c = (c); \\r
707 +     (__c >= 'a' && __c <= 'z'); \\r
708 +   })\r
709 +#endif\r
710 +\r
711 +#if C_CTYPE_ASCII\r
712 +#undef c_isgraph\r
713 +#define c_isgraph(c) \\r
714 +  ({ int __c = (c); \\r
715 +     (__c >= '!' && __c <= '~'); \\r
716 +   })\r
717 +#endif\r
718 +\r
719 +#if C_CTYPE_ASCII\r
720 +#undef c_isprint\r
721 +#define c_isprint(c) \\r
722 +  ({ int __c = (c); \\r
723 +     (__c >= ' ' && __c <= '~'); \\r
724 +   })\r
725 +#endif\r
726 +\r
727 +#if C_CTYPE_ASCII\r
728 +#undef c_ispunct\r
729 +#define c_ispunct(c) \\r
730 +  ({ int _c = (c); \\r
731 +     (c_isgraph (_c) && ! c_isalnum (_c)); \\r
732 +   })\r
733 +#endif\r
734 +\r
735 +#undef c_isspace\r
736 +#define c_isspace(c) \\r
737 +  ({ int __c = (c); \\r
738 +     (__c == ' ' || __c == '\t' \\r
739 +      || __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \\r
740 +   })\r
741 +\r
742 +#if C_CTYPE_CONSECUTIVE_UPPERCASE\r
743 +#undef c_isupper\r
744 +#define c_isupper(c) \\r
745 +  ({ int __c = (c); \\r
746 +     (__c >= 'A' && __c <= 'Z'); \\r
747 +   })\r
748 +#endif\r
749 +\r
750 +#if C_CTYPE_CONSECUTIVE_DIGITS \\r
751 +    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
752 +#if C_CTYPE_ASCII\r
753 +#undef c_isxdigit\r
754 +#define c_isxdigit(c) \\r
755 +  ({ int __c = (c); \\r
756 +     ((__c >= '0' && __c <= '9') \\r
757 +      || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \\r
758 +   })\r
759 +#else\r
760 +#undef c_isxdigit\r
761 +#define c_isxdigit(c) \\r
762 +  ({ int __c = (c); \\r
763 +     ((__c >= '0' && __c <= '9') \\r
764 +      || (__c >= 'A' && __c <= 'F') \\r
765 +      || (__c >= 'a' && __c <= 'f')); \\r
766 +   })\r
767 +#endif\r
768 +#endif\r
769 +\r
770 +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE\r
771 +#undef c_tolower\r
772 +#define c_tolower(c) \\r
773 +  ({ int __c = (c); \\r
774 +     (__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \\r
775 +   })\r
776 +#undef c_toupper\r
777 +#define c_toupper(c) \\r
778 +  ({ int __c = (c); \\r
779 +     (__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \\r
780 +   })\r
781 +#endif\r
782 +\r
783 +#endif /* optimizing for speed */\r
784 +\r
785 +\r
786 +#ifdef __cplusplus\r
787 +}\r
788 +#endif\r
789 +\r
790 +#endif /* C_CTYPE_H */\r
791 diff --git a/lib/getdate.c b/lib/getdate.c\r
792 new file mode 100644\r
793 index 0000000..5b20eeb\r
794 --- /dev/null\r
795 +++ b/lib/getdate.c\r
796 @@ -0,0 +1,3497 @@\r
797 +\r
798 +/* A Bison parser, made by GNU Bison 2.4.1.  */\r
799 +\r
800 +/* Skeleton implementation for Bison's Yacc-like parsers in C\r
801 +   \r
802 +      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\r
803 +   Free Software Foundation, Inc.\r
804 +   \r
805 +   This program is free software: you can redistribute it and/or modify\r
806 +   it under the terms of the GNU General Public License as published by\r
807 +   the Free Software Foundation, either version 3 of the License, or\r
808 +   (at your option) any later version.\r
809 +   \r
810 +   This program is distributed in the hope that it will be useful,\r
811 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
812 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
813 +   GNU General Public License for more details.\r
814 +   \r
815 +   You should have received a copy of the GNU General Public License\r
816 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
817 +\r
818 +/* As a special exception, you may create a larger work that contains\r
819 +   part or all of the Bison parser skeleton and distribute that work\r
820 +   under terms of your choice, so long as that work isn't itself a\r
821 +   parser generator using the skeleton or a modified version thereof\r
822 +   as a parser skeleton.  Alternatively, if you modify or redistribute\r
823 +   the parser skeleton itself, you may (at your option) remove this\r
824 +   special exception, which will cause the skeleton and the resulting\r
825 +   Bison output files to be licensed under the GNU General Public\r
826 +   License without this special exception.\r
827 +   \r
828 +   This special exception was added by the Free Software Foundation in\r
829 +   version 2.2 of Bison.  */\r
830 +\r
831 +/* C LALR(1) parser skeleton written by Richard Stallman, by\r
832 +   simplifying the original so-called "semantic" parser.  */\r
833 +\r
834 +/* All symbols defined below should begin with yy or YY, to avoid\r
835 +   infringing on user name space.  This should be done even for local\r
836 +   variables, as they might otherwise be expanded by user macros.\r
837 +   There are some unavoidable exceptions within include files to\r
838 +   define necessary library symbols; they are noted "INFRINGES ON\r
839 +   USER NAME SPACE" below.  */\r
840 +\r
841 +/* Identify Bison output.  */\r
842 +#define YYBISON 1\r
843 +\r
844 +/* Bison version.  */\r
845 +#define YYBISON_VERSION "2.4.1"\r
846 +\r
847 +/* Skeleton name.  */\r
848 +#define YYSKELETON_NAME "yacc.c"\r
849 +\r
850 +/* Pure parsers.  */\r
851 +#define YYPURE 1\r
852 +\r
853 +/* Push parsers.  */\r
854 +#define YYPUSH 0\r
855 +\r
856 +/* Pull parsers.  */\r
857 +#define YYPULL 1\r
858 +\r
859 +/* Using locations.  */\r
860 +#define YYLSP_NEEDED 0\r
861 +\r
862 +\r
863 +\r
864 +/* Copy the first part of user declarations.  */\r
865 +\r
866 +/* Line 189 of yacc.c  */\r
867 +#line 1 "getdate.y"\r
868 +\r
869 +/* Parse a string into an internal time stamp.\r
870 +\r
871 +   Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,\r
872 +   2010 Free Software Foundation, Inc.\r
873 +\r
874 +   This program is free software: you can redistribute it and/or modify\r
875 +   it under the terms of the GNU General Public License as published by\r
876 +   the Free Software Foundation; either version 3 of the License, or\r
877 +   (at your option) any later version.\r
878 +\r
879 +   This program is distributed in the hope that it will be useful,\r
880 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
881 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
882 +   GNU General Public License for more details.\r
883 +\r
884 +   You should have received a copy of the GNU General Public License\r
885 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
886 +\r
887 +/* Originally written by Steven M. Bellovin <smb@research.att.com> while\r
888 +   at the University of North Carolina at Chapel Hill.  Later tweaked by\r
889 +   a couple of people on Usenet.  Completely overhauled by Rich $alz\r
890 +   <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.\r
891 +\r
892 +   Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do\r
893 +   the right thing about local DST.  Also modified by Paul Eggert\r
894 +   <eggert@cs.ucla.edu> in February 2004 to support\r
895 +   nanosecond-resolution time stamps, and in October 2004 to support\r
896 +   TZ strings in dates.  */\r
897 +\r
898 +/* FIXME: Check for arithmetic overflow in all cases, not just\r
899 +   some of them.  */\r
900 +\r
901 +#include <config.h>\r
902 +\r
903 +#include "getdate.h"\r
904 +\r
905 +#include "intprops.h"\r
906 +#include "timespec.h"\r
907 +#include "verify.h"\r
908 +\r
909 +/* There's no need to extend the stack, so there's no need to involve\r
910 +   alloca.  */\r
911 +#define YYSTACK_USE_ALLOCA 0\r
912 +\r
913 +/* Tell Bison how much stack space is needed.  20 should be plenty for\r
914 +   this grammar, which is not right recursive.  Beware setting it too\r
915 +   high, since that might cause problems on machines whose\r
916 +   implementations have lame stack-overflow checking.  */\r
917 +#define YYMAXDEPTH 20\r
918 +#define YYINITDEPTH YYMAXDEPTH\r
919 +\r
920 +/* Since the code of getdate.y is not included in the Emacs executable\r
921 +   itself, there is no need to #define static in this file.  Even if\r
922 +   the code were included in the Emacs executable, it probably\r
923 +   wouldn't do any harm to #undef it here; this will only cause\r
924 +   problems if we try to write to a static variable, which I don't\r
925 +   think this code needs to do.  */\r
926 +#ifdef emacs\r
927 +# undef static\r
928 +#endif\r
929 +\r
930 +#include <c-ctype.h>\r
931 +#include <limits.h>\r
932 +#include <stdio.h>\r
933 +#include <stdlib.h>\r
934 +#include <string.h>\r
935 +\r
936 +#include "xalloc.h"\r
937 +\r
938 +\r
939 +/* ISDIGIT differs from isdigit, as follows:\r
940 +   - Its arg may be any int or unsigned int; it need not be an unsigned char\r
941 +     or EOF.\r
942 +   - It's typically faster.\r
943 +   POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to\r
944 +   isdigit unless it's important to use the locale's definition\r
945 +   of `digit' even when the host does not conform to POSIX.  */\r
946 +#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)\r
947 +\r
948 +/* Shift A right by B bits portably, by dividing A by 2**B and\r
949 +   truncating towards minus infinity.  A and B should be free of side\r
950 +   effects, and B should be in the range 0 <= B <= INT_BITS - 2, where\r
951 +   INT_BITS is the number of useful bits in an int.  GNU code can\r
952 +   assume that INT_BITS is at least 32.\r
953 +\r
954 +   ISO C99 says that A >> B is implementation-defined if A < 0.  Some\r
955 +   implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift\r
956 +   right in the usual way when A < 0, so SHR falls back on division if\r
957 +   ordinary A >> B doesn't seem to be the usual signed shift.  */\r
958 +#define SHR(a, b)       \\r
959 +  (-1 >> 1 == -1        \\r
960 +   ? (a) >> (b)         \\r
961 +   : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))\r
962 +\r
963 +#define EPOCH_YEAR 1970\r
964 +#define TM_YEAR_BASE 1900\r
965 +\r
966 +#define HOUR(x) ((x) * 60)\r
967 +\r
968 +/* long_time_t is a signed integer type that contains all time_t values.  */\r
969 +verify (TYPE_IS_INTEGER (time_t));\r
970 +#if TIME_T_FITS_IN_LONG_INT\r
971 +typedef long int long_time_t;\r
972 +#else\r
973 +typedef time_t long_time_t;\r
974 +#endif\r
975 +\r
976 +/* Lots of this code assumes time_t and time_t-like values fit into\r
977 +   long_time_t.  */\r
978 +verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t)\r
979 +        && TYPE_MAXIMUM (time_t) <= TYPE_MAXIMUM (long_time_t));\r
980 +\r
981 +/* FIXME: It also assumes that signed integer overflow silently wraps around,\r
982 +   but this is not true any more with recent versions of GCC 4.  */\r
983 +\r
984 +/* An integer value, and the number of digits in its textual\r
985 +   representation.  */\r
986 +typedef struct\r
987 +{\r
988 +  bool negative;\r
989 +  long int value;\r
990 +  size_t digits;\r
991 +} textint;\r
992 +\r
993 +/* An entry in the lexical lookup table.  */\r
994 +typedef struct\r
995 +{\r
996 +  char const *name;\r
997 +  int type;\r
998 +  int value;\r
999 +} table;\r
1000 +\r
1001 +/* Meridian: am, pm, or 24-hour style.  */\r
1002 +enum { MERam, MERpm, MER24 };\r
1003 +\r
1004 +enum { BILLION = 1000000000, LOG10_BILLION = 9 };\r
1005 +\r
1006 +/* Relative times.  */\r
1007 +typedef struct\r
1008 +{\r
1009 +  /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */\r
1010 +  long int year;\r
1011 +  long int month;\r
1012 +  long int day;\r
1013 +  long int hour;\r
1014 +  long int minutes;\r
1015 +  long_time_t seconds;\r
1016 +  long int ns;\r
1017 +} relative_time;\r
1018 +\r
1019 +#if HAVE_COMPOUND_LITERALS\r
1020 +# define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 })\r
1021 +#else\r
1022 +static relative_time const RELATIVE_TIME_0;\r
1023 +#endif\r
1024 +\r
1025 +/* Information passed to and from the parser.  */\r
1026 +typedef struct\r
1027 +{\r
1028 +  /* The input string remaining to be parsed. */\r
1029 +  const char *input;\r
1030 +\r
1031 +  /* N, if this is the Nth Tuesday.  */\r
1032 +  long int day_ordinal;\r
1033 +\r
1034 +  /* Day of week; Sunday is 0.  */\r
1035 +  int day_number;\r
1036 +\r
1037 +  /* tm_isdst flag for the local zone.  */\r
1038 +  int local_isdst;\r
1039 +\r
1040 +  /* Time zone, in minutes east of UTC.  */\r
1041 +  long int time_zone;\r
1042 +\r
1043 +  /* Style used for time.  */\r
1044 +  int meridian;\r
1045 +\r
1046 +  /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds.  */\r
1047 +  textint year;\r
1048 +  long int month;\r
1049 +  long int day;\r
1050 +  long int hour;\r
1051 +  long int minutes;\r
1052 +  struct timespec seconds; /* includes nanoseconds */\r
1053 +\r
1054 +  /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */\r
1055 +  relative_time rel;\r
1056 +\r
1057 +  /* Presence or counts of nonterminals of various flavors parsed so far.  */\r
1058 +  bool timespec_seen;\r
1059 +  bool rels_seen;\r
1060 +  size_t dates_seen;\r
1061 +  size_t days_seen;\r
1062 +  size_t local_zones_seen;\r
1063 +  size_t dsts_seen;\r
1064 +  size_t times_seen;\r
1065 +  size_t zones_seen;\r
1066 +\r
1067 +  /* Table of local time zone abbrevations, terminated by a null entry.  */\r
1068 +  table local_time_zone_table[3];\r
1069 +} parser_control;\r
1070 +\r
1071 +union YYSTYPE;\r
1072 +static int yylex (union YYSTYPE *, parser_control *);\r
1073 +static int yyerror (parser_control const *, char const *);\r
1074 +static long int time_zone_hhmm (parser_control *, textint, long int);\r
1075 +\r
1076 +/* Extract into *PC any date and time info from a string of digits\r
1077 +   of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,\r
1078 +   YYYY, ...).  */\r
1079 +static void\r
1080 +digits_to_date_time (parser_control *pc, textint text_int)\r
1081 +{\r
1082 +  if (pc->dates_seen && ! pc->year.digits\r
1083 +      && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))\r
1084 +    pc->year = text_int;\r
1085 +  else\r
1086 +    {\r
1087 +      if (4 < text_int.digits)\r
1088 +        {\r
1089 +          pc->dates_seen++;\r
1090 +          pc->day = text_int.value % 100;\r
1091 +          pc->month = (text_int.value / 100) % 100;\r
1092 +          pc->year.value = text_int.value / 10000;\r
1093 +          pc->year.digits = text_int.digits - 4;\r
1094 +        }\r
1095 +      else\r
1096 +        {\r
1097 +          pc->times_seen++;\r
1098 +          if (text_int.digits <= 2)\r
1099 +            {\r
1100 +              pc->hour = text_int.value;\r
1101 +              pc->minutes = 0;\r
1102 +            }\r
1103 +          else\r
1104 +            {\r
1105 +              pc->hour = text_int.value / 100;\r
1106 +              pc->minutes = text_int.value % 100;\r
1107 +            }\r
1108 +          pc->seconds.tv_sec = 0;\r
1109 +          pc->seconds.tv_nsec = 0;\r
1110 +          pc->meridian = MER24;\r
1111 +        }\r
1112 +    }\r
1113 +}\r
1114 +\r
1115 +/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1).  */\r
1116 +static void\r
1117 +apply_relative_time (parser_control *pc, relative_time rel, int factor)\r
1118 +{\r
1119 +  pc->rel.ns += factor * rel.ns;\r
1120 +  pc->rel.seconds += factor * rel.seconds;\r
1121 +  pc->rel.minutes += factor * rel.minutes;\r
1122 +  pc->rel.hour += factor * rel.hour;\r
1123 +  pc->rel.day += factor * rel.day;\r
1124 +  pc->rel.month += factor * rel.month;\r
1125 +  pc->rel.year += factor * rel.year;\r
1126 +  pc->rels_seen = true;\r
1127 +}\r
1128 +\r
1129 +/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments.  */\r
1130 +static void\r
1131 +set_hhmmss (parser_control *pc, long int hour, long int minutes,\r
1132 +            time_t sec, long int nsec)\r
1133 +{\r
1134 +  pc->hour = hour;\r
1135 +  pc->minutes = minutes;\r
1136 +  pc->seconds.tv_sec = sec;\r
1137 +  pc->seconds.tv_nsec = nsec;\r
1138 +}\r
1139 +\r
1140 +\r
1141 +\r
1142 +/* Line 189 of yacc.c  */\r
1143 +#line 348 "getdate.c"\r
1144 +\r
1145 +/* Enabling traces.  */\r
1146 +#ifndef YYDEBUG\r
1147 +# define YYDEBUG 0\r
1148 +#endif\r
1149 +\r
1150 +/* Enabling verbose error messages.  */\r
1151 +#ifdef YYERROR_VERBOSE\r
1152 +# undef YYERROR_VERBOSE\r
1153 +# define YYERROR_VERBOSE 1\r
1154 +#else\r
1155 +# define YYERROR_VERBOSE 0\r
1156 +#endif\r
1157 +\r
1158 +/* Enabling the token table.  */\r
1159 +#ifndef YYTOKEN_TABLE\r
1160 +# define YYTOKEN_TABLE 0\r
1161 +#endif\r
1162 +\r
1163 +\r
1164 +/* Tokens.  */\r
1165 +#ifndef YYTOKENTYPE\r
1166 +# define YYTOKENTYPE\r
1167 +   /* Put the tokens into the symbol table, so that GDB and other debuggers\r
1168 +      know about them.  */\r
1169 +   enum yytokentype {\r
1170 +     tAGO = 258,\r
1171 +     tDST = 259,\r
1172 +     tYEAR_UNIT = 260,\r
1173 +     tMONTH_UNIT = 261,\r
1174 +     tHOUR_UNIT = 262,\r
1175 +     tMINUTE_UNIT = 263,\r
1176 +     tSEC_UNIT = 264,\r
1177 +     tDAY_UNIT = 265,\r
1178 +     tDAY_SHIFT = 266,\r
1179 +     tDAY = 267,\r
1180 +     tDAYZONE = 268,\r
1181 +     tLOCAL_ZONE = 269,\r
1182 +     tMERIDIAN = 270,\r
1183 +     tMONTH = 271,\r
1184 +     tORDINAL = 272,\r
1185 +     tZONE = 273,\r
1186 +     tSNUMBER = 274,\r
1187 +     tUNUMBER = 275,\r
1188 +     tSDECIMAL_NUMBER = 276,\r
1189 +     tUDECIMAL_NUMBER = 277\r
1190 +   };\r
1191 +#endif\r
1192 +/* Tokens.  */\r
1193 +#define tAGO 258\r
1194 +#define tDST 259\r
1195 +#define tYEAR_UNIT 260\r
1196 +#define tMONTH_UNIT 261\r
1197 +#define tHOUR_UNIT 262\r
1198 +#define tMINUTE_UNIT 263\r
1199 +#define tSEC_UNIT 264\r
1200 +#define tDAY_UNIT 265\r
1201 +#define tDAY_SHIFT 266\r
1202 +#define tDAY 267\r
1203 +#define tDAYZONE 268\r
1204 +#define tLOCAL_ZONE 269\r
1205 +#define tMERIDIAN 270\r
1206 +#define tMONTH 271\r
1207 +#define tORDINAL 272\r
1208 +#define tZONE 273\r
1209 +#define tSNUMBER 274\r
1210 +#define tUNUMBER 275\r
1211 +#define tSDECIMAL_NUMBER 276\r
1212 +#define tUDECIMAL_NUMBER 277\r
1213 +\r
1214 +\r
1215 +\r
1216 +\r
1217 +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\r
1218 +typedef union YYSTYPE\r
1219 +{\r
1220 +\r
1221 +/* Line 214 of yacc.c  */\r
1222 +#line 285 "getdate.y"\r
1223 +\r
1224 +  long int intval;\r
1225 +  textint textintval;\r
1226 +  struct timespec timespec;\r
1227 +  relative_time rel;\r
1228 +\r
1229 +\r
1230 +\r
1231 +/* Line 214 of yacc.c  */\r
1232 +#line 437 "getdate.c"\r
1233 +} YYSTYPE;\r
1234 +# define YYSTYPE_IS_TRIVIAL 1\r
1235 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */\r
1236 +# define YYSTYPE_IS_DECLARED 1\r
1237 +#endif\r
1238 +\r
1239 +\r
1240 +/* Copy the second part of user declarations.  */\r
1241 +\r
1242 +\r
1243 +/* Line 264 of yacc.c  */\r
1244 +#line 449 "getdate.c"\r
1245 +\r
1246 +#ifdef short\r
1247 +# undef short\r
1248 +#endif\r
1249 +\r
1250 +#ifdef YYTYPE_UINT8\r
1251 +typedef YYTYPE_UINT8 yytype_uint8;\r
1252 +#else\r
1253 +typedef unsigned char yytype_uint8;\r
1254 +#endif\r
1255 +\r
1256 +#ifdef YYTYPE_INT8\r
1257 +typedef YYTYPE_INT8 yytype_int8;\r
1258 +#elif (defined __STDC__ || defined __C99__FUNC__ \\r
1259 +     || defined __cplusplus || defined _MSC_VER)\r
1260 +typedef signed char yytype_int8;\r
1261 +#else\r
1262 +typedef short int yytype_int8;\r
1263 +#endif\r
1264 +\r
1265 +#ifdef YYTYPE_UINT16\r
1266 +typedef YYTYPE_UINT16 yytype_uint16;\r
1267 +#else\r
1268 +typedef unsigned short int yytype_uint16;\r
1269 +#endif\r
1270 +\r
1271 +#ifdef YYTYPE_INT16\r
1272 +typedef YYTYPE_INT16 yytype_int16;\r
1273 +#else\r
1274 +typedef short int yytype_int16;\r
1275 +#endif\r
1276 +\r
1277 +#ifndef YYSIZE_T\r
1278 +# ifdef __SIZE_TYPE__\r
1279 +#  define YYSIZE_T __SIZE_TYPE__\r
1280 +# elif defined size_t\r
1281 +#  define YYSIZE_T size_t\r
1282 +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \\r
1283 +     || defined __cplusplus || defined _MSC_VER)\r
1284 +#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */\r
1285 +#  define YYSIZE_T size_t\r
1286 +# else\r
1287 +#  define YYSIZE_T unsigned int\r
1288 +# endif\r
1289 +#endif\r
1290 +\r
1291 +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)\r
1292 +\r
1293 +#ifndef YY_\r
1294 +# if YYENABLE_NLS\r
1295 +#  if ENABLE_NLS\r
1296 +#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */\r
1297 +#   define YY_(msgid) dgettext ("bison-runtime", msgid)\r
1298 +#  endif\r
1299 +# endif\r
1300 +# ifndef YY_\r
1301 +#  define YY_(msgid) msgid\r
1302 +# endif\r
1303 +#endif\r
1304 +\r
1305 +/* Suppress unused-variable warnings by "using" E.  */\r
1306 +#if ! defined lint || defined __GNUC__\r
1307 +# define YYUSE(e) ((void) (e))\r
1308 +#else\r
1309 +# define YYUSE(e) /* empty */\r
1310 +#endif\r
1311 +\r
1312 +/* Identity function, used to suppress warnings about constant conditions.  */\r
1313 +#ifndef lint\r
1314 +# define YYID(n) (n)\r
1315 +#else\r
1316 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
1317 +     || defined __cplusplus || defined _MSC_VER)\r
1318 +static int\r
1319 +YYID (int yyi)\r
1320 +#else\r
1321 +static int\r
1322 +YYID (yyi)\r
1323 +    int yyi;\r
1324 +#endif\r
1325 +{\r
1326 +  return yyi;\r
1327 +}\r
1328 +#endif\r
1329 +\r
1330 +#if ! defined yyoverflow || YYERROR_VERBOSE\r
1331 +\r
1332 +/* The parser invokes alloca or malloc; define the necessary symbols.  */\r
1333 +\r
1334 +# ifdef YYSTACK_USE_ALLOCA\r
1335 +#  if YYSTACK_USE_ALLOCA\r
1336 +#   ifdef __GNUC__\r
1337 +#    define YYSTACK_ALLOC __builtin_alloca\r
1338 +#   elif defined __BUILTIN_VA_ARG_INCR\r
1339 +#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */\r
1340 +#   elif defined _AIX\r
1341 +#    define YYSTACK_ALLOC __alloca\r
1342 +#   elif defined _MSC_VER\r
1343 +#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */\r
1344 +#    define alloca _alloca\r
1345 +#   else\r
1346 +#    define YYSTACK_ALLOC alloca\r
1347 +#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\r
1348 +     || defined __cplusplus || defined _MSC_VER)\r
1349 +#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\r
1350 +#     ifndef _STDLIB_H\r
1351 +#      define _STDLIB_H 1\r
1352 +#     endif\r
1353 +#    endif\r
1354 +#   endif\r
1355 +#  endif\r
1356 +# endif\r
1357 +\r
1358 +# ifdef YYSTACK_ALLOC\r
1359 +   /* Pacify GCC's `empty if-body' warning.  */\r
1360 +#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))\r
1361 +#  ifndef YYSTACK_ALLOC_MAXIMUM\r
1362 +    /* The OS might guarantee only one guard page at the bottom of the stack,\r
1363 +       and a page size can be as small as 4096 bytes.  So we cannot safely\r
1364 +       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number\r
1365 +       to allow for a few compiler-allocated temporary stack slots.  */\r
1366 +#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */\r
1367 +#  endif\r
1368 +# else\r
1369 +#  define YYSTACK_ALLOC YYMALLOC\r
1370 +#  define YYSTACK_FREE YYFREE\r
1371 +#  ifndef YYSTACK_ALLOC_MAXIMUM\r
1372 +#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM\r
1373 +#  endif\r
1374 +#  if (defined __cplusplus && ! defined _STDLIB_H \\r
1375 +       && ! ((defined YYMALLOC || defined malloc) \\r
1376 +            && (defined YYFREE || defined free)))\r
1377 +#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\r
1378 +#   ifndef _STDLIB_H\r
1379 +#    define _STDLIB_H 1\r
1380 +#   endif\r
1381 +#  endif\r
1382 +#  ifndef YYMALLOC\r
1383 +#   define YYMALLOC malloc\r
1384 +#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\r
1385 +     || defined __cplusplus || defined _MSC_VER)\r
1386 +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */\r
1387 +#   endif\r
1388 +#  endif\r
1389 +#  ifndef YYFREE\r
1390 +#   define YYFREE free\r
1391 +#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\r
1392 +     || defined __cplusplus || defined _MSC_VER)\r
1393 +void free (void *); /* INFRINGES ON USER NAME SPACE */\r
1394 +#   endif\r
1395 +#  endif\r
1396 +# endif\r
1397 +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */\r
1398 +\r
1399 +\r
1400 +#if (! defined yyoverflow \\r
1401 +     && (! defined __cplusplus \\r
1402 +        || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))\r
1403 +\r
1404 +/* A type that is properly aligned for any stack member.  */\r
1405 +union yyalloc\r
1406 +{\r
1407 +  yytype_int16 yyss_alloc;\r
1408 +  YYSTYPE yyvs_alloc;\r
1409 +};\r
1410 +\r
1411 +/* The size of the maximum gap between one aligned stack and the next.  */\r
1412 +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)\r
1413 +\r
1414 +/* The size of an array large to enough to hold all stacks, each with\r
1415 +   N elements.  */\r
1416 +# define YYSTACK_BYTES(N) \\r
1417 +     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \\r
1418 +      + YYSTACK_GAP_MAXIMUM)\r
1419 +\r
1420 +/* Copy COUNT objects from FROM to TO.  The source and destination do\r
1421 +   not overlap.  */\r
1422 +# ifndef YYCOPY\r
1423 +#  if defined __GNUC__ && 1 < __GNUC__\r
1424 +#   define YYCOPY(To, From, Count) \\r
1425 +      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))\r
1426 +#  else\r
1427 +#   define YYCOPY(To, From, Count)             \\r
1428 +      do                                       \\r
1429 +       {                                       \\r
1430 +         YYSIZE_T yyi;                         \\r
1431 +         for (yyi = 0; yyi < (Count); yyi++)   \\r
1432 +           (To)[yyi] = (From)[yyi];            \\r
1433 +       }                                       \\r
1434 +      while (YYID (0))\r
1435 +#  endif\r
1436 +# endif\r
1437 +\r
1438 +/* Relocate STACK from its old location to the new one.  The\r
1439 +   local variables YYSIZE and YYSTACKSIZE give the old and new number of\r
1440 +   elements in the stack, and YYPTR gives the new location of the\r
1441 +   stack.  Advance YYPTR to a properly aligned location for the next\r
1442 +   stack.  */\r
1443 +# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \\r
1444 +    do                                                                 \\r
1445 +      {                                                                        \\r
1446 +       YYSIZE_T yynewbytes;                                            \\r
1447 +       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \\r
1448 +       Stack = &yyptr->Stack_alloc;                                    \\r
1449 +       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \\r
1450 +       yyptr += yynewbytes / sizeof (*yyptr);                          \\r
1451 +      }                                                                        \\r
1452 +    while (YYID (0))\r
1453 +\r
1454 +#endif\r
1455 +\r
1456 +/* YYFINAL -- State number of the termination state.  */\r
1457 +#define YYFINAL  12\r
1458 +/* YYLAST -- Last index in YYTABLE.  */\r
1459 +#define YYLAST   98\r
1460 +\r
1461 +/* YYNTOKENS -- Number of terminals.  */\r
1462 +#define YYNTOKENS  27\r
1463 +/* YYNNTS -- Number of nonterminals.  */\r
1464 +#define YYNNTS  21\r
1465 +/* YYNRULES -- Number of rules.  */\r
1466 +#define YYNRULES  82\r
1467 +/* YYNRULES -- Number of states.  */\r
1468 +#define YYNSTATES  100\r
1469 +\r
1470 +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */\r
1471 +#define YYUNDEFTOK  2\r
1472 +#define YYMAXUTOK   277\r
1473 +\r
1474 +#define YYTRANSLATE(YYX)                                               \\r
1475 +  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)\r
1476 +\r
1477 +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */\r
1478 +static const yytype_uint8 yytranslate[] =\r
1479 +{\r
1480 +       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1481 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1482 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1483 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1484 +       2,     2,     2,     2,    25,     2,     2,    26,     2,     2,\r
1485 +       2,     2,     2,     2,     2,     2,     2,     2,    24,     2,\r
1486 +       2,     2,     2,     2,    23,     2,     2,     2,     2,     2,\r
1487 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1488 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1489 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1490 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1491 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1492 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1493 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1494 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1495 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1496 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1497 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1498 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1499 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1500 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1501 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1502 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1503 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1504 +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
1505 +       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\r
1506 +       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,\r
1507 +      15,    16,    17,    18,    19,    20,    21,    22\r
1508 +};\r
1509 +\r
1510 +#if YYDEBUG\r
1511 +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in\r
1512 +   YYRHS.  */\r
1513 +static const yytype_uint8 yyprhs[] =\r
1514 +{\r
1515 +       0,     0,     3,     5,     7,    10,    11,    14,    16,    18,\r
1516 +      20,    22,    24,    26,    28,    30,    33,    38,    44,    51,\r
1517 +      59,    61,    64,    66,    69,    73,    75,    78,    80,    83,\r
1518 +      86,    89,    93,    99,   103,   107,   111,   114,   119,   122,\r
1519 +     126,   129,   131,   133,   136,   139,   141,   144,   147,   149,\r
1520 +     152,   155,   157,   160,   163,   165,   168,   171,   173,   176,\r
1521 +     179,   182,   185,   187,   189,   192,   195,   198,   201,   204,\r
1522 +     207,   209,   211,   213,   215,   217,   219,   221,   223,   226,\r
1523 +     227,   230,   231\r
1524 +};\r
1525 +\r
1526 +/* YYRHS -- A `-1'-separated list of the rules' RHS.  */\r
1527 +static const yytype_int8 yyrhs[] =\r
1528 +{\r
1529 +      28,     0,    -1,    29,    -1,    30,    -1,    23,    41,    -1,\r
1530 +      -1,    30,    31,    -1,    32,    -1,    33,    -1,    34,    -1,\r
1531 +      36,    -1,    35,    -1,    37,    -1,    44,    -1,    45,    -1,\r
1532 +      20,    15,    -1,    20,    24,    20,    47,    -1,    20,    24,\r
1533 +      20,    19,    46,    -1,    20,    24,    20,    24,    43,    47,\r
1534 +      -1,    20,    24,    20,    24,    43,    19,    46,    -1,    14,\r
1535 +      -1,    14,     4,    -1,    18,    -1,    18,    39,    -1,    18,\r
1536 +      19,    46,    -1,    13,    -1,    18,     4,    -1,    12,    -1,\r
1537 +      12,    25,    -1,    17,    12,    -1,    20,    12,    -1,    20,\r
1538 +      26,    20,    -1,    20,    26,    20,    26,    20,    -1,    20,\r
1539 +      19,    19,    -1,    20,    16,    19,    -1,    16,    19,    19,\r
1540 +      -1,    16,    20,    -1,    16,    20,    25,    20,    -1,    20,\r
1541 +      16,    -1,    20,    16,    20,    -1,    38,     3,    -1,    38,\r
1542 +      -1,    40,    -1,    17,     5,    -1,    20,     5,    -1,     5,\r
1543 +      -1,    17,     6,    -1,    20,     6,    -1,     6,    -1,    17,\r
1544 +      10,    -1,    20,    10,    -1,    10,    -1,    17,     7,    -1,\r
1545 +      20,     7,    -1,     7,    -1,    17,     8,    -1,    20,     8,\r
1546 +      -1,     8,    -1,    17,     9,    -1,    20,     9,    -1,    21,\r
1547 +       9,    -1,    22,     9,    -1,     9,    -1,    39,    -1,    19,\r
1548 +       5,    -1,    19,     6,    -1,    19,    10,    -1,    19,     7,\r
1549 +      -1,    19,     8,    -1,    19,     9,    -1,    11,    -1,    42,\r
1550 +      -1,    43,    -1,    21,    -1,    19,    -1,    22,    -1,    20,\r
1551 +      -1,    20,    -1,    20,    39,    -1,    -1,    24,    20,    -1,\r
1552 +      -1,    15,    -1\r
1553 +};\r
1554 +\r
1555 +/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */\r
1556 +static const yytype_uint16 yyrline[] =\r
1557 +{\r
1558 +       0,   311,   311,   312,   316,   323,   325,   329,   331,   333,\r
1559 +     335,   337,   339,   340,   341,   345,   350,   355,   362,   367,\r
1560 +     377,   382,   390,   392,   395,   397,   399,   404,   409,   414,\r
1561 +     419,   427,   432,   452,   459,   467,   475,   480,   486,   491,\r
1562 +     500,   502,   504,   509,   511,   513,   515,   517,   519,   521,\r
1563 +     523,   525,   527,   529,   531,   533,   535,   537,   539,   541,\r
1564 +     543,   545,   547,   549,   553,   555,   557,   559,   561,   563,\r
1565 +     568,   572,   572,   575,   576,   581,   582,   587,   592,   603,\r
1566 +     604,   610,   611\r
1567 +};\r
1568 +#endif\r
1569 +\r
1570 +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE\r
1571 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\r
1572 +   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */\r
1573 +static const char *const yytname[] =\r
1574 +{\r
1575 +  "$end", "error", "$undefined", "tAGO", "tDST", "tYEAR_UNIT",\r
1576 +  "tMONTH_UNIT", "tHOUR_UNIT", "tMINUTE_UNIT", "tSEC_UNIT", "tDAY_UNIT",\r
1577 +  "tDAY_SHIFT", "tDAY", "tDAYZONE", "tLOCAL_ZONE", "tMERIDIAN", "tMONTH",\r
1578 +  "tORDINAL", "tZONE", "tSNUMBER", "tUNUMBER", "tSDECIMAL_NUMBER",\r
1579 +  "tUDECIMAL_NUMBER", "'@'", "':'", "','", "'/'", "$accept", "spec",\r
1580 +  "timespec", "items", "item", "time", "local_zone", "zone", "day", "date",\r
1581 +  "rel", "relunit", "relunit_snumber", "dayshift", "seconds",\r
1582 +  "signed_seconds", "unsigned_seconds", "number", "hybrid",\r
1583 +  "o_colon_minutes", "o_merid", 0\r
1584 +};\r
1585 +#endif\r
1586 +\r
1587 +# ifdef YYPRINT\r
1588 +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to\r
1589 +   token YYLEX-NUM.  */\r
1590 +static const yytype_uint16 yytoknum[] =\r
1591 +{\r
1592 +       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,\r
1593 +     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,\r
1594 +     275,   276,   277,    64,    58,    44,    47\r
1595 +};\r
1596 +# endif\r
1597 +\r
1598 +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */\r
1599 +static const yytype_uint8 yyr1[] =\r
1600 +{\r
1601 +       0,    27,    28,    28,    29,    30,    30,    31,    31,    31,\r
1602 +      31,    31,    31,    31,    31,    32,    32,    32,    32,    32,\r
1603 +      33,    33,    34,    34,    34,    34,    34,    35,    35,    35,\r
1604 +      35,    36,    36,    36,    36,    36,    36,    36,    36,    36,\r
1605 +      37,    37,    37,    38,    38,    38,    38,    38,    38,    38,\r
1606 +      38,    38,    38,    38,    38,    38,    38,    38,    38,    38,\r
1607 +      38,    38,    38,    38,    39,    39,    39,    39,    39,    39,\r
1608 +      40,    41,    41,    42,    42,    43,    43,    44,    45,    46,\r
1609 +      46,    47,    47\r
1610 +};\r
1611 +\r
1612 +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */\r
1613 +static const yytype_uint8 yyr2[] =\r
1614 +{\r
1615 +       0,     2,     1,     1,     2,     0,     2,     1,     1,     1,\r
1616 +       1,     1,     1,     1,     1,     2,     4,     5,     6,     7,\r
1617 +       1,     2,     1,     2,     3,     1,     2,     1,     2,     2,\r
1618 +       2,     3,     5,     3,     3,     3,     2,     4,     2,     3,\r
1619 +       2,     1,     1,     2,     2,     1,     2,     2,     1,     2,\r
1620 +       2,     1,     2,     2,     1,     2,     2,     1,     2,     2,\r
1621 +       2,     2,     1,     1,     2,     2,     2,     2,     2,     2,\r
1622 +       1,     1,     1,     1,     1,     1,     1,     1,     2,     0,\r
1623 +       2,     0,     1\r
1624 +};\r
1625 +\r
1626 +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state\r
1627 +   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero\r
1628 +   means the default is an error.  */\r
1629 +static const yytype_uint8 yydefact[] =\r
1630 +{\r
1631 +       5,     0,     0,     2,     3,    74,    76,    73,    75,     4,\r
1632 +      71,    72,     1,    45,    48,    54,    57,    62,    51,    70,\r
1633 +      27,    25,    20,     0,     0,    22,     0,    77,     0,     0,\r
1634 +       6,     7,     8,     9,    11,    10,    12,    41,    63,    42,\r
1635 +      13,    14,    28,    21,     0,    36,    43,    46,    52,    55,\r
1636 +      58,    49,    29,    26,    79,    23,    64,    65,    67,    68,\r
1637 +      69,    66,    44,    47,    53,    56,    59,    50,    30,    15,\r
1638 +      38,     0,     0,     0,    78,    60,    61,    40,    35,     0,\r
1639 +       0,    24,    34,    39,    33,    81,    31,    37,    80,    82,\r
1640 +      79,     0,    16,     0,    17,    81,    32,    79,    18,    19\r
1641 +};\r
1642 +\r
1643 +/* YYDEFGOTO[NTERM-NUM].  */\r
1644 +static const yytype_int8 yydefgoto[] =\r
1645 +{\r
1646 +      -1,     2,     3,     4,    30,    31,    32,    33,    34,    35,\r
1647 +      36,    37,    38,    39,     9,    10,    11,    40,    41,    81,\r
1648 +      92\r
1649 +};\r
1650 +\r
1651 +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\r
1652 +   STATE-NUM.  */\r
1653 +#define YYPACT_NINF -82\r
1654 +static const yytype_int8 yypact[] =\r
1655 +{\r
1656 +     -17,    56,    15,   -82,    26,   -82,   -82,   -82,   -82,   -82,\r
1657 +     -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,\r
1658 +      36,   -82,    68,    10,    50,     9,    59,    -5,    72,    73,\r
1659 +     -82,   -82,   -82,   -82,   -82,   -82,   -82,    80,   -82,   -82,\r
1660 +     -82,   -82,   -82,   -82,    65,    61,   -82,   -82,   -82,   -82,\r
1661 +     -82,   -82,   -82,   -82,    17,   -82,   -82,   -82,   -82,   -82,\r
1662 +     -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,\r
1663 +      60,    44,    67,    69,   -82,   -82,   -82,   -82,   -82,    70,\r
1664 +      71,   -82,   -82,   -82,   -82,    -7,    62,   -82,   -82,   -82,\r
1665 +      74,    -2,   -82,    75,   -82,    55,   -82,    74,   -82,   -82\r
1666 +};\r
1667 +\r
1668 +/* YYPGOTO[NTERM-NUM].  */\r
1669 +static const yytype_int8 yypgoto[] =\r
1670 +{\r
1671 +     -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,   -82,\r
1672 +     -82,   -82,    46,   -82,   -82,   -82,    -6,   -82,   -82,   -81,\r
1673 +      -3\r
1674 +};\r
1675 +\r
1676 +/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If\r
1677 +   positive, shift that token.  If negative, reduce the rule which\r
1678 +   number is the opposite.  If zero, do what YYDEFACT says.\r
1679 +   If YYTABLE_NINF, syntax error.  */\r
1680 +#define YYTABLE_NINF -1\r
1681 +static const yytype_uint8 yytable[] =\r
1682 +{\r
1683 +      62,    63,    64,    65,    66,    67,     1,    68,    89,    94,\r
1684 +      69,    70,    90,    53,    71,    12,    99,    91,     6,    72,\r
1685 +       8,    73,    56,    57,    58,    59,    60,    61,    54,    44,\r
1686 +      45,    13,    14,    15,    16,    17,    18,    19,    20,    21,\r
1687 +      22,    80,    23,    24,    25,    26,    27,    28,    29,    56,\r
1688 +      57,    58,    59,    60,    61,    46,    47,    48,    49,    50,\r
1689 +      51,    42,    52,    84,    56,    57,    58,    59,    60,    61,\r
1690 +      89,    55,    43,    74,    97,     5,     6,     7,     8,    82,\r
1691 +      83,    75,    76,    77,    78,    95,    79,    85,    93,    86,\r
1692 +      87,    88,    98,     0,     0,    96,     0,     0,    80\r
1693 +};\r
1694 +\r
1695 +static const yytype_int8 yycheck[] =\r
1696 +{\r
1697 +       5,     6,     7,     8,     9,    10,    23,    12,    15,    90,\r
1698 +      15,    16,    19,     4,    19,     0,    97,    24,    20,    24,\r
1699 +      22,    26,     5,     6,     7,     8,     9,    10,    19,    19,\r
1700 +      20,     5,     6,     7,     8,     9,    10,    11,    12,    13,\r
1701 +      14,    24,    16,    17,    18,    19,    20,    21,    22,     5,\r
1702 +       6,     7,     8,     9,    10,     5,     6,     7,     8,     9,\r
1703 +      10,    25,    12,    19,     5,     6,     7,     8,     9,    10,\r
1704 +      15,    25,     4,    27,    19,    19,    20,    21,    22,    19,\r
1705 +      20,     9,     9,     3,    19,    91,    25,    20,    26,    20,\r
1706 +      20,    20,    95,    -1,    -1,    20,    -1,    -1,    24\r
1707 +};\r
1708 +\r
1709 +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing\r
1710 +   symbol of state STATE-NUM.  */\r
1711 +static const yytype_uint8 yystos[] =\r
1712 +{\r
1713 +       0,    23,    28,    29,    30,    19,    20,    21,    22,    41,\r
1714 +      42,    43,     0,     5,     6,     7,     8,     9,    10,    11,\r
1715 +      12,    13,    14,    16,    17,    18,    19,    20,    21,    22,\r
1716 +      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,\r
1717 +      44,    45,    25,     4,    19,    20,     5,     6,     7,     8,\r
1718 +       9,    10,    12,     4,    19,    39,     5,     6,     7,     8,\r
1719 +       9,    10,     5,     6,     7,     8,     9,    10,    12,    15,\r
1720 +      16,    19,    24,    26,    39,     9,     9,     3,    19,    25,\r
1721 +      24,    46,    19,    20,    19,    20,    20,    20,    20,    15,\r
1722 +      19,    24,    47,    26,    46,    43,    20,    19,    47,    46\r
1723 +};\r
1724 +\r
1725 +#define yyerrok                (yyerrstatus = 0)\r
1726 +#define yyclearin      (yychar = YYEMPTY)\r
1727 +#define YYEMPTY                (-2)\r
1728 +#define YYEOF          0\r
1729 +\r
1730 +#define YYACCEPT       goto yyacceptlab\r
1731 +#define YYABORT                goto yyabortlab\r
1732 +#define YYERROR                goto yyerrorlab\r
1733 +\r
1734 +\r
1735 +/* Like YYERROR except do call yyerror.  This remains here temporarily\r
1736 +   to ease the transition to the new meaning of YYERROR, for GCC.\r
1737 +   Once GCC version 2 has supplanted version 1, this can go.  */\r
1738 +\r
1739 +#define YYFAIL         goto yyerrlab\r
1740 +\r
1741 +#define YYRECOVERING()  (!!yyerrstatus)\r
1742 +\r
1743 +#define YYBACKUP(Token, Value)                                 \\r
1744 +do                                                             \\r
1745 +  if (yychar == YYEMPTY && yylen == 1)                         \\r
1746 +    {                                                          \\r
1747 +      yychar = (Token);                                                \\r
1748 +      yylval = (Value);                                                \\r
1749 +      yytoken = YYTRANSLATE (yychar);                          \\r
1750 +      YYPOPSTACK (1);                                          \\r
1751 +      goto yybackup;                                           \\r
1752 +    }                                                          \\r
1753 +  else                                                         \\r
1754 +    {                                                          \\r
1755 +      yyerror (pc, YY_("syntax error: cannot back up")); \\r
1756 +      YYERROR;                                                 \\r
1757 +    }                                                          \\r
1758 +while (YYID (0))\r
1759 +\r
1760 +\r
1761 +#define YYTERROR       1\r
1762 +#define YYERRCODE      256\r
1763 +\r
1764 +\r
1765 +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].\r
1766 +   If N is 0, then set CURRENT to the empty location which ends\r
1767 +   the previous symbol: RHS[0] (always defined).  */\r
1768 +\r
1769 +#define YYRHSLOC(Rhs, K) ((Rhs)[K])\r
1770 +#ifndef YYLLOC_DEFAULT\r
1771 +# define YYLLOC_DEFAULT(Current, Rhs, N)                               \\r
1772 +    do                                                                 \\r
1773 +      if (YYID (N))                                                    \\r
1774 +       {                                                               \\r
1775 +         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \\r
1776 +         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \\r
1777 +         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \\r
1778 +         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \\r
1779 +       }                                                               \\r
1780 +      else                                                             \\r
1781 +       {                                                               \\r
1782 +         (Current).first_line   = (Current).last_line   =              \\r
1783 +           YYRHSLOC (Rhs, 0).last_line;                                \\r
1784 +         (Current).first_column = (Current).last_column =              \\r
1785 +           YYRHSLOC (Rhs, 0).last_column;                              \\r
1786 +       }                                                               \\r
1787 +    while (YYID (0))\r
1788 +#endif\r
1789 +\r
1790 +\r
1791 +/* YY_LOCATION_PRINT -- Print the location on the stream.\r
1792 +   This macro was not mandated originally: define only if we know\r
1793 +   we won't break user code: when these are the locations we know.  */\r
1794 +\r
1795 +#ifndef YY_LOCATION_PRINT\r
1796 +# if YYLTYPE_IS_TRIVIAL\r
1797 +#  define YY_LOCATION_PRINT(File, Loc)                 \\r
1798 +     fprintf (File, "%d.%d-%d.%d",                     \\r
1799 +             (Loc).first_line, (Loc).first_column,     \\r
1800 +             (Loc).last_line,  (Loc).last_column)\r
1801 +# else\r
1802 +#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)\r
1803 +# endif\r
1804 +#endif\r
1805 +\r
1806 +\r
1807 +/* YYLEX -- calling `yylex' with the right arguments.  */\r
1808 +\r
1809 +#ifdef YYLEX_PARAM\r
1810 +# define YYLEX yylex (&yylval, YYLEX_PARAM)\r
1811 +#else\r
1812 +# define YYLEX yylex (&yylval, pc)\r
1813 +#endif\r
1814 +\r
1815 +/* Enable debugging if requested.  */\r
1816 +#if YYDEBUG\r
1817 +\r
1818 +# ifndef YYFPRINTF\r
1819 +#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */\r
1820 +#  define YYFPRINTF fprintf\r
1821 +# endif\r
1822 +\r
1823 +# define YYDPRINTF(Args)                       \\r
1824 +do {                                           \\r
1825 +  if (yydebug)                                 \\r
1826 +    YYFPRINTF Args;                            \\r
1827 +} while (YYID (0))\r
1828 +\r
1829 +# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \\r
1830 +do {                                                                     \\r
1831 +  if (yydebug)                                                           \\r
1832 +    {                                                                    \\r
1833 +      YYFPRINTF (stderr, "%s ", Title);                                          \\r
1834 +      yy_symbol_print (stderr,                                           \\r
1835 +                 Type, Value, pc); \\r
1836 +      YYFPRINTF (stderr, "\n");                                                  \\r
1837 +    }                                                                    \\r
1838 +} while (YYID (0))\r
1839 +\r
1840 +\r
1841 +/*--------------------------------.\r
1842 +| Print this symbol on YYOUTPUT.  |\r
1843 +`--------------------------------*/\r
1844 +\r
1845 +/*ARGSUSED*/\r
1846 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
1847 +     || defined __cplusplus || defined _MSC_VER)\r
1848 +static void\r
1849 +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc)\r
1850 +#else\r
1851 +static void\r
1852 +yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc)\r
1853 +    FILE *yyoutput;\r
1854 +    int yytype;\r
1855 +    YYSTYPE const * const yyvaluep;\r
1856 +    parser_control *pc;\r
1857 +#endif\r
1858 +{\r
1859 +  if (!yyvaluep)\r
1860 +    return;\r
1861 +  YYUSE (pc);\r
1862 +# ifdef YYPRINT\r
1863 +  if (yytype < YYNTOKENS)\r
1864 +    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);\r
1865 +# else\r
1866 +  YYUSE (yyoutput);\r
1867 +# endif\r
1868 +  switch (yytype)\r
1869 +    {\r
1870 +      default:\r
1871 +       break;\r
1872 +    }\r
1873 +}\r
1874 +\r
1875 +\r
1876 +/*--------------------------------.\r
1877 +| Print this symbol on YYOUTPUT.  |\r
1878 +`--------------------------------*/\r
1879 +\r
1880 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
1881 +     || defined __cplusplus || defined _MSC_VER)\r
1882 +static void\r
1883 +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc)\r
1884 +#else\r
1885 +static void\r
1886 +yy_symbol_print (yyoutput, yytype, yyvaluep, pc)\r
1887 +    FILE *yyoutput;\r
1888 +    int yytype;\r
1889 +    YYSTYPE const * const yyvaluep;\r
1890 +    parser_control *pc;\r
1891 +#endif\r
1892 +{\r
1893 +  if (yytype < YYNTOKENS)\r
1894 +    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);\r
1895 +  else\r
1896 +    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);\r
1897 +\r
1898 +  yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc);\r
1899 +  YYFPRINTF (yyoutput, ")");\r
1900 +}\r
1901 +\r
1902 +/*------------------------------------------------------------------.\r
1903 +| yy_stack_print -- Print the state stack from its BOTTOM up to its |\r
1904 +| TOP (included).                                                   |\r
1905 +`------------------------------------------------------------------*/\r
1906 +\r
1907 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
1908 +     || defined __cplusplus || defined _MSC_VER)\r
1909 +static void\r
1910 +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)\r
1911 +#else\r
1912 +static void\r
1913 +yy_stack_print (yybottom, yytop)\r
1914 +    yytype_int16 *yybottom;\r
1915 +    yytype_int16 *yytop;\r
1916 +#endif\r
1917 +{\r
1918 +  YYFPRINTF (stderr, "Stack now");\r
1919 +  for (; yybottom <= yytop; yybottom++)\r
1920 +    {\r
1921 +      int yybot = *yybottom;\r
1922 +      YYFPRINTF (stderr, " %d", yybot);\r
1923 +    }\r
1924 +  YYFPRINTF (stderr, "\n");\r
1925 +}\r
1926 +\r
1927 +# define YY_STACK_PRINT(Bottom, Top)                           \\r
1928 +do {                                                           \\r
1929 +  if (yydebug)                                                 \\r
1930 +    yy_stack_print ((Bottom), (Top));                          \\r
1931 +} while (YYID (0))\r
1932 +\r
1933 +\r
1934 +/*------------------------------------------------.\r
1935 +| Report that the YYRULE is going to be reduced.  |\r
1936 +`------------------------------------------------*/\r
1937 +\r
1938 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
1939 +     || defined __cplusplus || defined _MSC_VER)\r
1940 +static void\r
1941 +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, parser_control *pc)\r
1942 +#else\r
1943 +static void\r
1944 +yy_reduce_print (yyvsp, yyrule, pc)\r
1945 +    YYSTYPE *yyvsp;\r
1946 +    int yyrule;\r
1947 +    parser_control *pc;\r
1948 +#endif\r
1949 +{\r
1950 +  int yynrhs = yyr2[yyrule];\r
1951 +  int yyi;\r
1952 +  unsigned long int yylno = yyrline[yyrule];\r
1953 +  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",\r
1954 +            yyrule - 1, yylno);\r
1955 +  /* The symbols being reduced.  */\r
1956 +  for (yyi = 0; yyi < yynrhs; yyi++)\r
1957 +    {\r
1958 +      YYFPRINTF (stderr, "   $%d = ", yyi + 1);\r
1959 +      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],\r
1960 +                      &(yyvsp[(yyi + 1) - (yynrhs)])\r
1961 +                                      , pc);\r
1962 +      YYFPRINTF (stderr, "\n");\r
1963 +    }\r
1964 +}\r
1965 +\r
1966 +# define YY_REDUCE_PRINT(Rule)         \\r
1967 +do {                                   \\r
1968 +  if (yydebug)                         \\r
1969 +    yy_reduce_print (yyvsp, Rule, pc); \\r
1970 +} while (YYID (0))\r
1971 +\r
1972 +/* Nonzero means print parse trace.  It is left uninitialized so that\r
1973 +   multiple parsers can coexist.  */\r
1974 +int yydebug;\r
1975 +#else /* !YYDEBUG */\r
1976 +# define YYDPRINTF(Args)\r
1977 +# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\r
1978 +# define YY_STACK_PRINT(Bottom, Top)\r
1979 +# define YY_REDUCE_PRINT(Rule)\r
1980 +#endif /* !YYDEBUG */\r
1981 +\r
1982 +\r
1983 +/* YYINITDEPTH -- initial size of the parser's stacks.  */\r
1984 +#ifndef        YYINITDEPTH\r
1985 +# define YYINITDEPTH 200\r
1986 +#endif\r
1987 +\r
1988 +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only\r
1989 +   if the built-in stack extension method is used).\r
1990 +\r
1991 +   Do not make this value too large; the results are undefined if\r
1992 +   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)\r
1993 +   evaluated with infinite-precision integer arithmetic.  */\r
1994 +\r
1995 +#ifndef YYMAXDEPTH\r
1996 +# define YYMAXDEPTH 10000\r
1997 +#endif\r
1998 +\r
1999 +\f\r
2000 \r
2001 +\r
2002 +#if YYERROR_VERBOSE\r
2003 +\r
2004 +# ifndef yystrlen\r
2005 +#  if defined __GLIBC__ && defined _STRING_H\r
2006 +#   define yystrlen strlen\r
2007 +#  else\r
2008 +/* Return the length of YYSTR.  */\r
2009 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
2010 +     || defined __cplusplus || defined _MSC_VER)\r
2011 +static YYSIZE_T\r
2012 +yystrlen (const char *yystr)\r
2013 +#else\r
2014 +static YYSIZE_T\r
2015 +yystrlen (yystr)\r
2016 +    const char *yystr;\r
2017 +#endif\r
2018 +{\r
2019 +  YYSIZE_T yylen;\r
2020 +  for (yylen = 0; yystr[yylen]; yylen++)\r
2021 +    continue;\r
2022 +  return yylen;\r
2023 +}\r
2024 +#  endif\r
2025 +# endif\r
2026 +\r
2027 +# ifndef yystpcpy\r
2028 +#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE\r
2029 +#   define yystpcpy stpcpy\r
2030 +#  else\r
2031 +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in\r
2032 +   YYDEST.  */\r
2033 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
2034 +     || defined __cplusplus || defined _MSC_VER)\r
2035 +static char *\r
2036 +yystpcpy (char *yydest, const char *yysrc)\r
2037 +#else\r
2038 +static char *\r
2039 +yystpcpy (yydest, yysrc)\r
2040 +    char *yydest;\r
2041 +    const char *yysrc;\r
2042 +#endif\r
2043 +{\r
2044 +  char *yyd = yydest;\r
2045 +  const char *yys = yysrc;\r
2046 +\r
2047 +  while ((*yyd++ = *yys++) != '\0')\r
2048 +    continue;\r
2049 +\r
2050 +  return yyd - 1;\r
2051 +}\r
2052 +#  endif\r
2053 +# endif\r
2054 +\r
2055 +# ifndef yytnamerr\r
2056 +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary\r
2057 +   quotes and backslashes, so that it's suitable for yyerror.  The\r
2058 +   heuristic is that double-quoting is unnecessary unless the string\r
2059 +   contains an apostrophe, a comma, or backslash (other than\r
2060 +   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is\r
2061 +   null, do not copy; instead, return the length of what the result\r
2062 +   would have been.  */\r
2063 +static YYSIZE_T\r
2064 +yytnamerr (char *yyres, const char *yystr)\r
2065 +{\r
2066 +  if (*yystr == '"')\r
2067 +    {\r
2068 +      YYSIZE_T yyn = 0;\r
2069 +      char const *yyp = yystr;\r
2070 +\r
2071 +      for (;;)\r
2072 +       switch (*++yyp)\r
2073 +         {\r
2074 +         case '\'':\r
2075 +         case ',':\r
2076 +           goto do_not_strip_quotes;\r
2077 +\r
2078 +         case '\\':\r
2079 +           if (*++yyp != '\\')\r
2080 +             goto do_not_strip_quotes;\r
2081 +           /* Fall through.  */\r
2082 +         default:\r
2083 +           if (yyres)\r
2084 +             yyres[yyn] = *yyp;\r
2085 +           yyn++;\r
2086 +           break;\r
2087 +\r
2088 +         case '"':\r
2089 +           if (yyres)\r
2090 +             yyres[yyn] = '\0';\r
2091 +           return yyn;\r
2092 +         }\r
2093 +    do_not_strip_quotes: ;\r
2094 +    }\r
2095 +\r
2096 +  if (! yyres)\r
2097 +    return yystrlen (yystr);\r
2098 +\r
2099 +  return yystpcpy (yyres, yystr) - yyres;\r
2100 +}\r
2101 +# endif\r
2102 +\r
2103 +/* Copy into YYRESULT an error message about the unexpected token\r
2104 +   YYCHAR while in state YYSTATE.  Return the number of bytes copied,\r
2105 +   including the terminating null byte.  If YYRESULT is null, do not\r
2106 +   copy anything; just return the number of bytes that would be\r
2107 +   copied.  As a special case, return 0 if an ordinary "syntax error"\r
2108 +   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during\r
2109 +   size calculation.  */\r
2110 +static YYSIZE_T\r
2111 +yysyntax_error (char *yyresult, int yystate, int yychar)\r
2112 +{\r
2113 +  int yyn = yypact[yystate];\r
2114 +\r
2115 +  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))\r
2116 +    return 0;\r
2117 +  else\r
2118 +    {\r
2119 +      int yytype = YYTRANSLATE (yychar);\r
2120 +      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);\r
2121 +      YYSIZE_T yysize = yysize0;\r
2122 +      YYSIZE_T yysize1;\r
2123 +      int yysize_overflow = 0;\r
2124 +      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };\r
2125 +      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];\r
2126 +      int yyx;\r
2127 +\r
2128 +# if 0\r
2129 +      /* This is so xgettext sees the translatable formats that are\r
2130 +        constructed on the fly.  */\r
2131 +      YY_("syntax error, unexpected %s");\r
2132 +      YY_("syntax error, unexpected %s, expecting %s");\r
2133 +      YY_("syntax error, unexpected %s, expecting %s or %s");\r
2134 +      YY_("syntax error, unexpected %s, expecting %s or %s or %s");\r
2135 +      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");\r
2136 +# endif\r
2137 +      char *yyfmt;\r
2138 +      char const *yyf;\r
2139 +      static char const yyunexpected[] = "syntax error, unexpected %s";\r
2140 +      static char const yyexpecting[] = ", expecting %s";\r
2141 +      static char const yyor[] = " or %s";\r
2142 +      char yyformat[sizeof yyunexpected\r
2143 +                   + sizeof yyexpecting - 1\r
2144 +                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)\r
2145 +                      * (sizeof yyor - 1))];\r
2146 +      char const *yyprefix = yyexpecting;\r
2147 +\r
2148 +      /* Start YYX at -YYN if negative to avoid negative indexes in\r
2149 +        YYCHECK.  */\r
2150 +      int yyxbegin = yyn < 0 ? -yyn : 0;\r
2151 +\r
2152 +      /* Stay within bounds of both yycheck and yytname.  */\r
2153 +      int yychecklim = YYLAST - yyn + 1;\r
2154 +      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\r
2155 +      int yycount = 1;\r
2156 +\r
2157 +      yyarg[0] = yytname[yytype];\r
2158 +      yyfmt = yystpcpy (yyformat, yyunexpected);\r
2159 +\r
2160 +      for (yyx = yyxbegin; yyx < yyxend; ++yyx)\r
2161 +       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)\r
2162 +         {\r
2163 +           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)\r
2164 +             {\r
2165 +               yycount = 1;\r
2166 +               yysize = yysize0;\r
2167 +               yyformat[sizeof yyunexpected - 1] = '\0';\r
2168 +               break;\r
2169 +             }\r
2170 +           yyarg[yycount++] = yytname[yyx];\r
2171 +           yysize1 = yysize + yytnamerr (0, yytname[yyx]);\r
2172 +           yysize_overflow |= (yysize1 < yysize);\r
2173 +           yysize = yysize1;\r
2174 +           yyfmt = yystpcpy (yyfmt, yyprefix);\r
2175 +           yyprefix = yyor;\r
2176 +         }\r
2177 +\r
2178 +      yyf = YY_(yyformat);\r
2179 +      yysize1 = yysize + yystrlen (yyf);\r
2180 +      yysize_overflow |= (yysize1 < yysize);\r
2181 +      yysize = yysize1;\r
2182 +\r
2183 +      if (yysize_overflow)\r
2184 +       return YYSIZE_MAXIMUM;\r
2185 +\r
2186 +      if (yyresult)\r
2187 +       {\r
2188 +         /* Avoid sprintf, as that infringes on the user's name space.\r
2189 +            Don't have undefined behavior even if the translation\r
2190 +            produced a string with the wrong number of "%s"s.  */\r
2191 +         char *yyp = yyresult;\r
2192 +         int yyi = 0;\r
2193 +         while ((*yyp = *yyf) != '\0')\r
2194 +           {\r
2195 +             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)\r
2196 +               {\r
2197 +                 yyp += yytnamerr (yyp, yyarg[yyi++]);\r
2198 +                 yyf += 2;\r
2199 +               }\r
2200 +             else\r
2201 +               {\r
2202 +                 yyp++;\r
2203 +                 yyf++;\r
2204 +               }\r
2205 +           }\r
2206 +       }\r
2207 +      return yysize;\r
2208 +    }\r
2209 +}\r
2210 +#endif /* YYERROR_VERBOSE */\r
2211 +\f\r
2212 \r
2213 +\r
2214 +/*-----------------------------------------------.\r
2215 +| Release the memory associated to this symbol.  |\r
2216 +`-----------------------------------------------*/\r
2217 +\r
2218 +/*ARGSUSED*/\r
2219 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
2220 +     || defined __cplusplus || defined _MSC_VER)\r
2221 +static void\r
2222 +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_control *pc)\r
2223 +#else\r
2224 +static void\r
2225 +yydestruct (yymsg, yytype, yyvaluep, pc)\r
2226 +    const char *yymsg;\r
2227 +    int yytype;\r
2228 +    YYSTYPE *yyvaluep;\r
2229 +    parser_control *pc;\r
2230 +#endif\r
2231 +{\r
2232 +  YYUSE (yyvaluep);\r
2233 +  YYUSE (pc);\r
2234 +\r
2235 +  if (!yymsg)\r
2236 +    yymsg = "Deleting";\r
2237 +  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);\r
2238 +\r
2239 +  switch (yytype)\r
2240 +    {\r
2241 +\r
2242 +      default:\r
2243 +       break;\r
2244 +    }\r
2245 +}\r
2246 +\r
2247 +/* Prevent warnings from -Wmissing-prototypes.  */\r
2248 +#ifdef YYPARSE_PARAM\r
2249 +#if defined __STDC__ || defined __cplusplus\r
2250 +int yyparse (void *YYPARSE_PARAM);\r
2251 +#else\r
2252 +int yyparse ();\r
2253 +#endif\r
2254 +#else /* ! YYPARSE_PARAM */\r
2255 +#if defined __STDC__ || defined __cplusplus\r
2256 +int yyparse (parser_control *pc);\r
2257 +#else\r
2258 +int yyparse ();\r
2259 +#endif\r
2260 +#endif /* ! YYPARSE_PARAM */\r
2261 +\r
2262 +\r
2263 +\r
2264 +\r
2265 +\r
2266 +/*-------------------------.\r
2267 +| yyparse or yypush_parse.  |\r
2268 +`-------------------------*/\r
2269 +\r
2270 +#ifdef YYPARSE_PARAM\r
2271 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
2272 +     || defined __cplusplus || defined _MSC_VER)\r
2273 +int\r
2274 +yyparse (void *YYPARSE_PARAM)\r
2275 +#else\r
2276 +int\r
2277 +yyparse (YYPARSE_PARAM)\r
2278 +    void *YYPARSE_PARAM;\r
2279 +#endif\r
2280 +#else /* ! YYPARSE_PARAM */\r
2281 +#if (defined __STDC__ || defined __C99__FUNC__ \\r
2282 +     || defined __cplusplus || defined _MSC_VER)\r
2283 +int\r
2284 +yyparse (parser_control *pc)\r
2285 +#else\r
2286 +int\r
2287 +yyparse (pc)\r
2288 +    parser_control *pc;\r
2289 +#endif\r
2290 +#endif\r
2291 +{\r
2292 +/* The lookahead symbol.  */\r
2293 +int yychar;\r
2294 +\r
2295 +/* The semantic value of the lookahead symbol.  */\r
2296 +YYSTYPE yylval;\r
2297 +\r
2298 +    /* Number of syntax errors so far.  */\r
2299 +    int yynerrs;\r
2300 +\r
2301 +    int yystate;\r
2302 +    /* Number of tokens to shift before error messages enabled.  */\r
2303 +    int yyerrstatus;\r
2304 +\r
2305 +    /* The stacks and their tools:\r
2306 +       `yyss': related to states.\r
2307 +       `yyvs': related to semantic values.\r
2308 +\r
2309 +       Refer to the stacks thru separate pointers, to allow yyoverflow\r
2310 +       to reallocate them elsewhere.  */\r
2311 +\r
2312 +    /* The state stack.  */\r
2313 +    yytype_int16 yyssa[YYINITDEPTH];\r
2314 +    yytype_int16 *yyss;\r
2315 +    yytype_int16 *yyssp;\r
2316 +\r
2317 +    /* The semantic value stack.  */\r
2318 +    YYSTYPE yyvsa[YYINITDEPTH];\r
2319 +    YYSTYPE *yyvs;\r
2320 +    YYSTYPE *yyvsp;\r
2321 +\r
2322 +    YYSIZE_T yystacksize;\r
2323 +\r
2324 +  int yyn;\r
2325 +  int yyresult;\r
2326 +  /* Lookahead token as an internal (translated) token number.  */\r
2327 +  int yytoken;\r
2328 +  /* The variables used to return semantic value and location from the\r
2329 +     action routines.  */\r
2330 +  YYSTYPE yyval;\r
2331 +\r
2332 +#if YYERROR_VERBOSE\r
2333 +  /* Buffer for error messages, and its allocated size.  */\r
2334 +  char yymsgbuf[128];\r
2335 +  char *yymsg = yymsgbuf;\r
2336 +  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;\r
2337 +#endif\r
2338 +\r
2339 +#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))\r
2340 +\r
2341 +  /* The number of symbols on the RHS of the reduced rule.\r
2342 +     Keep to zero when no symbol should be popped.  */\r
2343 +  int yylen = 0;\r
2344 +\r
2345 +  yytoken = 0;\r
2346 +  yyss = yyssa;\r
2347 +  yyvs = yyvsa;\r
2348 +  yystacksize = YYINITDEPTH;\r
2349 +\r
2350 +  YYDPRINTF ((stderr, "Starting parse\n"));\r
2351 +\r
2352 +  yystate = 0;\r
2353 +  yyerrstatus = 0;\r
2354 +  yynerrs = 0;\r
2355 +  yychar = YYEMPTY; /* Cause a token to be read.  */\r
2356 +\r
2357 +  /* Initialize stack pointers.\r
2358 +     Waste one element of value and location stack\r
2359 +     so that they stay on the same level as the state stack.\r
2360 +     The wasted elements are never initialized.  */\r
2361 +  yyssp = yyss;\r
2362 +  yyvsp = yyvs;\r
2363 +\r
2364 +  goto yysetstate;\r
2365 +\r
2366 +/*------------------------------------------------------------.\r
2367 +| yynewstate -- Push a new state, which is found in yystate.  |\r
2368 +`------------------------------------------------------------*/\r
2369 + yynewstate:\r
2370 +  /* In all cases, when you get here, the value and location stacks\r
2371 +     have just been pushed.  So pushing a state here evens the stacks.  */\r
2372 +  yyssp++;\r
2373 +\r
2374 + yysetstate:\r
2375 +  *yyssp = yystate;\r
2376 +\r
2377 +  if (yyss + yystacksize - 1 <= yyssp)\r
2378 +    {\r
2379 +      /* Get the current used size of the three stacks, in elements.  */\r
2380 +      YYSIZE_T yysize = yyssp - yyss + 1;\r
2381 +\r
2382 +#ifdef yyoverflow\r
2383 +      {\r
2384 +       /* Give user a chance to reallocate the stack.  Use copies of\r
2385 +          these so that the &'s don't force the real ones into\r
2386 +          memory.  */\r
2387 +       YYSTYPE *yyvs1 = yyvs;\r
2388 +       yytype_int16 *yyss1 = yyss;\r
2389 +\r
2390 +       /* Each stack pointer address is followed by the size of the\r
2391 +          data in use in that stack, in bytes.  This used to be a\r
2392 +          conditional around just the two extra args, but that might\r
2393 +          be undefined if yyoverflow is a macro.  */\r
2394 +       yyoverflow (YY_("memory exhausted"),\r
2395 +                   &yyss1, yysize * sizeof (*yyssp),\r
2396 +                   &yyvs1, yysize * sizeof (*yyvsp),\r
2397 +                   &yystacksize);\r
2398 +\r
2399 +       yyss = yyss1;\r
2400 +       yyvs = yyvs1;\r
2401 +      }\r
2402 +#else /* no yyoverflow */\r
2403 +# ifndef YYSTACK_RELOCATE\r
2404 +      goto yyexhaustedlab;\r
2405 +# else\r
2406 +      /* Extend the stack our own way.  */\r
2407 +      if (YYMAXDEPTH <= yystacksize)\r
2408 +       goto yyexhaustedlab;\r
2409 +      yystacksize *= 2;\r
2410 +      if (YYMAXDEPTH < yystacksize)\r
2411 +       yystacksize = YYMAXDEPTH;\r
2412 +\r
2413 +      {\r
2414 +       yytype_int16 *yyss1 = yyss;\r
2415 +       union yyalloc *yyptr =\r
2416 +         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));\r
2417 +       if (! yyptr)\r
2418 +         goto yyexhaustedlab;\r
2419 +       YYSTACK_RELOCATE (yyss_alloc, yyss);\r
2420 +       YYSTACK_RELOCATE (yyvs_alloc, yyvs);\r
2421 +#  undef YYSTACK_RELOCATE\r
2422 +       if (yyss1 != yyssa)\r
2423 +         YYSTACK_FREE (yyss1);\r
2424 +      }\r
2425 +# endif\r
2426 +#endif /* no yyoverflow */\r
2427 +\r
2428 +      yyssp = yyss + yysize - 1;\r
2429 +      yyvsp = yyvs + yysize - 1;\r
2430 +\r
2431 +      YYDPRINTF ((stderr, "Stack size increased to %lu\n",\r
2432 +                 (unsigned long int) yystacksize));\r
2433 +\r
2434 +      if (yyss + yystacksize - 1 <= yyssp)\r
2435 +       YYABORT;\r
2436 +    }\r
2437 +\r
2438 +  YYDPRINTF ((stderr, "Entering state %d\n", yystate));\r
2439 +\r
2440 +  if (yystate == YYFINAL)\r
2441 +    YYACCEPT;\r
2442 +\r
2443 +  goto yybackup;\r
2444 +\r
2445 +/*-----------.\r
2446 +| yybackup.  |\r
2447 +`-----------*/\r
2448 +yybackup:\r
2449 +\r
2450 +  /* Do appropriate processing given the current state.  Read a\r
2451 +     lookahead token if we need one and don't already have one.  */\r
2452 +\r
2453 +  /* First try to decide what to do without reference to lookahead token.  */\r
2454 +  yyn = yypact[yystate];\r
2455 +  if (yyn == YYPACT_NINF)\r
2456 +    goto yydefault;\r
2457 +\r
2458 +  /* Not known => get a lookahead token if don't already have one.  */\r
2459 +\r
2460 +  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */\r
2461 +  if (yychar == YYEMPTY)\r
2462 +    {\r
2463 +      YYDPRINTF ((stderr, "Reading a token: "));\r
2464 +      yychar = YYLEX;\r
2465 +    }\r
2466 +\r
2467 +  if (yychar <= YYEOF)\r
2468 +    {\r
2469 +      yychar = yytoken = YYEOF;\r
2470 +      YYDPRINTF ((stderr, "Now at end of input.\n"));\r
2471 +    }\r
2472 +  else\r
2473 +    {\r
2474 +      yytoken = YYTRANSLATE (yychar);\r
2475 +      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);\r
2476 +    }\r
2477 +\r
2478 +  /* If the proper action on seeing token YYTOKEN is to reduce or to\r
2479 +     detect an error, take that action.  */\r
2480 +  yyn += yytoken;\r
2481 +  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)\r
2482 +    goto yydefault;\r
2483 +  yyn = yytable[yyn];\r
2484 +  if (yyn <= 0)\r
2485 +    {\r
2486 +      if (yyn == 0 || yyn == YYTABLE_NINF)\r
2487 +       goto yyerrlab;\r
2488 +      yyn = -yyn;\r
2489 +      goto yyreduce;\r
2490 +    }\r
2491 +\r
2492 +  /* Count tokens shifted since error; after three, turn off error\r
2493 +     status.  */\r
2494 +  if (yyerrstatus)\r
2495 +    yyerrstatus--;\r
2496 +\r
2497 +  /* Shift the lookahead token.  */\r
2498 +  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);\r
2499 +\r
2500 +  /* Discard the shifted token.  */\r
2501 +  yychar = YYEMPTY;\r
2502 +\r
2503 +  yystate = yyn;\r
2504 +  *++yyvsp = yylval;\r
2505 +\r
2506 +  goto yynewstate;\r
2507 +\r
2508 +\r
2509 +/*-----------------------------------------------------------.\r
2510 +| yydefault -- do the default action for the current state.  |\r
2511 +`-----------------------------------------------------------*/\r
2512 +yydefault:\r
2513 +  yyn = yydefact[yystate];\r
2514 +  if (yyn == 0)\r
2515 +    goto yyerrlab;\r
2516 +  goto yyreduce;\r
2517 +\r
2518 +\r
2519 +/*-----------------------------.\r
2520 +| yyreduce -- Do a reduction.  |\r
2521 +`-----------------------------*/\r
2522 +yyreduce:\r
2523 +  /* yyn is the number of a rule to reduce with.  */\r
2524 +  yylen = yyr2[yyn];\r
2525 +\r
2526 +  /* If YYLEN is nonzero, implement the default value of the action:\r
2527 +     `$$ = $1'.\r
2528 +\r
2529 +     Otherwise, the following line sets YYVAL to garbage.\r
2530 +     This behavior is undocumented and Bison\r
2531 +     users should not rely upon it.  Assigning to YYVAL\r
2532 +     unconditionally makes the parser a bit smaller, and it avoids a\r
2533 +     GCC warning that YYVAL may be used uninitialized.  */\r
2534 +  yyval = yyvsp[1-yylen];\r
2535 +\r
2536 +\r
2537 +  YY_REDUCE_PRINT (yyn);\r
2538 +  switch (yyn)\r
2539 +    {\r
2540 +        case 4:\r
2541 +\r
2542 +/* Line 1455 of yacc.c  */\r
2543 +#line 317 "getdate.y"\r
2544 +    {\r
2545 +        pc->seconds = (yyvsp[(2) - (2)].timespec);\r
2546 +        pc->timespec_seen = true;\r
2547 +      }\r
2548 +    break;\r
2549 +\r
2550 +  case 7:\r
2551 +\r
2552 +/* Line 1455 of yacc.c  */\r
2553 +#line 330 "getdate.y"\r
2554 +    { pc->times_seen++; }\r
2555 +    break;\r
2556 +\r
2557 +  case 8:\r
2558 +\r
2559 +/* Line 1455 of yacc.c  */\r
2560 +#line 332 "getdate.y"\r
2561 +    { pc->local_zones_seen++; }\r
2562 +    break;\r
2563 +\r
2564 +  case 9:\r
2565 +\r
2566 +/* Line 1455 of yacc.c  */\r
2567 +#line 334 "getdate.y"\r
2568 +    { pc->zones_seen++; }\r
2569 +    break;\r
2570 +\r
2571 +  case 10:\r
2572 +\r
2573 +/* Line 1455 of yacc.c  */\r
2574 +#line 336 "getdate.y"\r
2575 +    { pc->dates_seen++; }\r
2576 +    break;\r
2577 +\r
2578 +  case 11:\r
2579 +\r
2580 +/* Line 1455 of yacc.c  */\r
2581 +#line 338 "getdate.y"\r
2582 +    { pc->days_seen++; }\r
2583 +    break;\r
2584 +\r
2585 +  case 15:\r
2586 +\r
2587 +/* Line 1455 of yacc.c  */\r
2588 +#line 346 "getdate.y"\r
2589 +    {\r
2590 +        set_hhmmss (pc, (yyvsp[(1) - (2)].textintval).value, 0, 0, 0);\r
2591 +        pc->meridian = (yyvsp[(2) - (2)].intval);\r
2592 +      }\r
2593 +    break;\r
2594 +\r
2595 +  case 16:\r
2596 +\r
2597 +/* Line 1455 of yacc.c  */\r
2598 +#line 351 "getdate.y"\r
2599 +    {\r
2600 +        set_hhmmss (pc, (yyvsp[(1) - (4)].textintval).value, (yyvsp[(3) - (4)].textintval).value, 0, 0);\r
2601 +        pc->meridian = (yyvsp[(4) - (4)].intval);\r
2602 +      }\r
2603 +    break;\r
2604 +\r
2605 +  case 17:\r
2606 +\r
2607 +/* Line 1455 of yacc.c  */\r
2608 +#line 356 "getdate.y"\r
2609 +    {\r
2610 +        set_hhmmss (pc, (yyvsp[(1) - (5)].textintval).value, (yyvsp[(3) - (5)].textintval).value, 0, 0);\r
2611 +        pc->meridian = MER24;\r
2612 +        pc->zones_seen++;\r
2613 +        pc->time_zone = time_zone_hhmm (pc, (yyvsp[(4) - (5)].textintval), (yyvsp[(5) - (5)].intval));\r
2614 +      }\r
2615 +    break;\r
2616 +\r
2617 +  case 18:\r
2618 +\r
2619 +/* Line 1455 of yacc.c  */\r
2620 +#line 363 "getdate.y"\r
2621 +    {\r
2622 +        set_hhmmss (pc, (yyvsp[(1) - (6)].textintval).value, (yyvsp[(3) - (6)].textintval).value, (yyvsp[(5) - (6)].timespec).tv_sec, (yyvsp[(5) - (6)].timespec).tv_nsec);\r
2623 +        pc->meridian = (yyvsp[(6) - (6)].intval);\r
2624 +      }\r
2625 +    break;\r
2626 +\r
2627 +  case 19:\r
2628 +\r
2629 +/* Line 1455 of yacc.c  */\r
2630 +#line 368 "getdate.y"\r
2631 +    {\r
2632 +        set_hhmmss (pc, (yyvsp[(1) - (7)].textintval).value, (yyvsp[(3) - (7)].textintval).value, (yyvsp[(5) - (7)].timespec).tv_sec, (yyvsp[(5) - (7)].timespec).tv_nsec);\r
2633 +        pc->meridian = MER24;\r
2634 +        pc->zones_seen++;\r
2635 +        pc->time_zone = time_zone_hhmm (pc, (yyvsp[(6) - (7)].textintval), (yyvsp[(7) - (7)].intval));\r
2636 +      }\r
2637 +    break;\r
2638 +\r
2639 +  case 20:\r
2640 +\r
2641 +/* Line 1455 of yacc.c  */\r
2642 +#line 378 "getdate.y"\r
2643 +    {\r
2644 +        pc->local_isdst = (yyvsp[(1) - (1)].intval);\r
2645 +        pc->dsts_seen += (0 < (yyvsp[(1) - (1)].intval));\r
2646 +      }\r
2647 +    break;\r
2648 +\r
2649 +  case 21:\r
2650 +\r
2651 +/* Line 1455 of yacc.c  */\r
2652 +#line 383 "getdate.y"\r
2653 +    {\r
2654 +        pc->local_isdst = 1;\r
2655 +        pc->dsts_seen += (0 < (yyvsp[(1) - (2)].intval)) + 1;\r
2656 +      }\r
2657 +    break;\r
2658 +\r
2659 +  case 22:\r
2660 +\r
2661 +/* Line 1455 of yacc.c  */\r
2662 +#line 391 "getdate.y"\r
2663 +    { pc->time_zone = (yyvsp[(1) - (1)].intval); }\r
2664 +    break;\r
2665 +\r
2666 +  case 23:\r
2667 +\r
2668 +/* Line 1455 of yacc.c  */\r
2669 +#line 393 "getdate.y"\r
2670 +    { pc->time_zone = (yyvsp[(1) - (2)].intval);\r
2671 +        apply_relative_time (pc, (yyvsp[(2) - (2)].rel), 1); }\r
2672 +    break;\r
2673 +\r
2674 +  case 24:\r
2675 +\r
2676 +/* Line 1455 of yacc.c  */\r
2677 +#line 396 "getdate.y"\r
2678 +    { pc->time_zone = (yyvsp[(1) - (3)].intval) + time_zone_hhmm (pc, (yyvsp[(2) - (3)].textintval), (yyvsp[(3) - (3)].intval)); }\r
2679 +    break;\r
2680 +\r
2681 +  case 25:\r
2682 +\r
2683 +/* Line 1455 of yacc.c  */\r
2684 +#line 398 "getdate.y"\r
2685 +    { pc->time_zone = (yyvsp[(1) - (1)].intval) + 60; }\r
2686 +    break;\r
2687 +\r
2688 +  case 26:\r
2689 +\r
2690 +/* Line 1455 of yacc.c  */\r
2691 +#line 400 "getdate.y"\r
2692 +    { pc->time_zone = (yyvsp[(1) - (2)].intval) + 60; }\r
2693 +    break;\r
2694 +\r
2695 +  case 27:\r
2696 +\r
2697 +/* Line 1455 of yacc.c  */\r
2698 +#line 405 "getdate.y"\r
2699 +    {\r
2700 +        pc->day_ordinal = 0;\r
2701 +        pc->day_number = (yyvsp[(1) - (1)].intval);\r
2702 +      }\r
2703 +    break;\r
2704 +\r
2705 +  case 28:\r
2706 +\r
2707 +/* Line 1455 of yacc.c  */\r
2708 +#line 410 "getdate.y"\r
2709 +    {\r
2710 +        pc->day_ordinal = 0;\r
2711 +        pc->day_number = (yyvsp[(1) - (2)].intval);\r
2712 +      }\r
2713 +    break;\r
2714 +\r
2715 +  case 29:\r
2716 +\r
2717 +/* Line 1455 of yacc.c  */\r
2718 +#line 415 "getdate.y"\r
2719 +    {\r
2720 +        pc->day_ordinal = (yyvsp[(1) - (2)].intval);\r
2721 +        pc->day_number = (yyvsp[(2) - (2)].intval);\r
2722 +      }\r
2723 +    break;\r
2724 +\r
2725 +  case 30:\r
2726 +\r
2727 +/* Line 1455 of yacc.c  */\r
2728 +#line 420 "getdate.y"\r
2729 +    {\r
2730 +        pc->day_ordinal = (yyvsp[(1) - (2)].textintval).value;\r
2731 +        pc->day_number = (yyvsp[(2) - (2)].intval);\r
2732 +      }\r
2733 +    break;\r
2734 +\r
2735 +  case 31:\r
2736 +\r
2737 +/* Line 1455 of yacc.c  */\r
2738 +#line 428 "getdate.y"\r
2739 +    {\r
2740 +        pc->month = (yyvsp[(1) - (3)].textintval).value;\r
2741 +        pc->day = (yyvsp[(3) - (3)].textintval).value;\r
2742 +      }\r
2743 +    break;\r
2744 +\r
2745 +  case 32:\r
2746 +\r
2747 +/* Line 1455 of yacc.c  */\r
2748 +#line 433 "getdate.y"\r
2749 +    {\r
2750 +        /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,\r
2751 +           otherwise as MM/DD/YY.\r
2752 +           The goal in recognizing YYYY/MM/DD is solely to support legacy\r
2753 +           machine-generated dates like those in an RCS log listing.  If\r
2754 +           you want portability, use the ISO 8601 format.  */\r
2755 +        if (4 <= (yyvsp[(1) - (5)].textintval).digits)\r
2756 +          {\r
2757 +            pc->year = (yyvsp[(1) - (5)].textintval);\r
2758 +            pc->month = (yyvsp[(3) - (5)].textintval).value;\r
2759 +            pc->day = (yyvsp[(5) - (5)].textintval).value;\r
2760 +          }\r
2761 +        else\r
2762 +          {\r
2763 +            pc->month = (yyvsp[(1) - (5)].textintval).value;\r
2764 +            pc->day = (yyvsp[(3) - (5)].textintval).value;\r
2765 +            pc->year = (yyvsp[(5) - (5)].textintval);\r
2766 +          }\r
2767 +      }\r
2768 +    break;\r
2769 +\r
2770 +  case 33:\r
2771 +\r
2772 +/* Line 1455 of yacc.c  */\r
2773 +#line 453 "getdate.y"\r
2774 +    {\r
2775 +        /* ISO 8601 format.  YYYY-MM-DD.  */\r
2776 +        pc->year = (yyvsp[(1) - (3)].textintval);\r
2777 +        pc->month = -(yyvsp[(2) - (3)].textintval).value;\r
2778 +        pc->day = -(yyvsp[(3) - (3)].textintval).value;\r
2779 +      }\r
2780 +    break;\r
2781 +\r
2782 +  case 34:\r
2783 +\r
2784 +/* Line 1455 of yacc.c  */\r
2785 +#line 460 "getdate.y"\r
2786 +    {\r
2787 +        /* e.g. 17-JUN-1992.  */\r
2788 +        pc->day = (yyvsp[(1) - (3)].textintval).value;\r
2789 +        pc->month = (yyvsp[(2) - (3)].intval);\r
2790 +        pc->year.value = -(yyvsp[(3) - (3)].textintval).value;\r
2791 +        pc->year.digits = (yyvsp[(3) - (3)].textintval).digits;\r
2792 +      }\r
2793 +    break;\r
2794 +\r
2795 +  case 35:\r
2796 +\r
2797 +/* Line 1455 of yacc.c  */\r
2798 +#line 468 "getdate.y"\r
2799 +    {\r
2800 +        /* e.g. JUN-17-1992.  */\r
2801 +        pc->month = (yyvsp[(1) - (3)].intval);\r
2802 +        pc->day = -(yyvsp[(2) - (3)].textintval).value;\r
2803 +        pc->year.value = -(yyvsp[(3) - (3)].textintval).value;\r
2804 +        pc->year.digits = (yyvsp[(3) - (3)].textintval).digits;\r
2805 +      }\r
2806 +    break;\r
2807 +\r
2808 +  case 36:\r
2809 +\r
2810 +/* Line 1455 of yacc.c  */\r
2811 +#line 476 "getdate.y"\r
2812 +    {\r
2813 +        pc->month = (yyvsp[(1) - (2)].intval);\r
2814 +        pc->day = (yyvsp[(2) - (2)].textintval).value;\r
2815 +      }\r
2816 +    break;\r
2817 +\r
2818 +  case 37:\r
2819 +\r
2820 +/* Line 1455 of yacc.c  */\r
2821 +#line 481 "getdate.y"\r
2822 +    {\r
2823 +        pc->month = (yyvsp[(1) - (4)].intval);\r
2824 +        pc->day = (yyvsp[(2) - (4)].textintval).value;\r
2825 +        pc->year = (yyvsp[(4) - (4)].textintval);\r
2826 +      }\r
2827 +    break;\r
2828 +\r
2829 +  case 38:\r
2830 +\r
2831 +/* Line 1455 of yacc.c  */\r
2832 +#line 487 "getdate.y"\r
2833 +    {\r
2834 +        pc->day = (yyvsp[(1) - (2)].textintval).value;\r
2835 +        pc->month = (yyvsp[(2) - (2)].intval);\r
2836 +      }\r
2837 +    break;\r
2838 +\r
2839 +  case 39:\r
2840 +\r
2841 +/* Line 1455 of yacc.c  */\r
2842 +#line 492 "getdate.y"\r
2843 +    {\r
2844 +        pc->day = (yyvsp[(1) - (3)].textintval).value;\r
2845 +        pc->month = (yyvsp[(2) - (3)].intval);\r
2846 +        pc->year = (yyvsp[(3) - (3)].textintval);\r
2847 +      }\r
2848 +    break;\r
2849 +\r
2850 +  case 40:\r
2851 +\r
2852 +/* Line 1455 of yacc.c  */\r
2853 +#line 501 "getdate.y"\r
2854 +    { apply_relative_time (pc, (yyvsp[(1) - (2)].rel), -1); }\r
2855 +    break;\r
2856 +\r
2857 +  case 41:\r
2858 +\r
2859 +/* Line 1455 of yacc.c  */\r
2860 +#line 503 "getdate.y"\r
2861 +    { apply_relative_time (pc, (yyvsp[(1) - (1)].rel), 1); }\r
2862 +    break;\r
2863 +\r
2864 +  case 42:\r
2865 +\r
2866 +/* Line 1455 of yacc.c  */\r
2867 +#line 505 "getdate.y"\r
2868 +    { apply_relative_time (pc, (yyvsp[(1) - (1)].rel), 1); }\r
2869 +    break;\r
2870 +\r
2871 +  case 43:\r
2872 +\r
2873 +/* Line 1455 of yacc.c  */\r
2874 +#line 510 "getdate.y"\r
2875 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].intval); }\r
2876 +    break;\r
2877 +\r
2878 +  case 44:\r
2879 +\r
2880 +/* Line 1455 of yacc.c  */\r
2881 +#line 512 "getdate.y"\r
2882 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].textintval).value; }\r
2883 +    break;\r
2884 +\r
2885 +  case 45:\r
2886 +\r
2887 +/* Line 1455 of yacc.c  */\r
2888 +#line 514 "getdate.y"\r
2889 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = 1; }\r
2890 +    break;\r
2891 +\r
2892 +  case 46:\r
2893 +\r
2894 +/* Line 1455 of yacc.c  */\r
2895 +#line 516 "getdate.y"\r
2896 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].intval); }\r
2897 +    break;\r
2898 +\r
2899 +  case 47:\r
2900 +\r
2901 +/* Line 1455 of yacc.c  */\r
2902 +#line 518 "getdate.y"\r
2903 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].textintval).value; }\r
2904 +    break;\r
2905 +\r
2906 +  case 48:\r
2907 +\r
2908 +/* Line 1455 of yacc.c  */\r
2909 +#line 520 "getdate.y"\r
2910 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = 1; }\r
2911 +    break;\r
2912 +\r
2913 +  case 49:\r
2914 +\r
2915 +/* Line 1455 of yacc.c  */\r
2916 +#line 522 "getdate.y"\r
2917 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); }\r
2918 +    break;\r
2919 +\r
2920 +  case 50:\r
2921 +\r
2922 +/* Line 1455 of yacc.c  */\r
2923 +#line 524 "getdate.y"\r
2924 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); }\r
2925 +    break;\r
2926 +\r
2927 +  case 51:\r
2928 +\r
2929 +/* Line 1455 of yacc.c  */\r
2930 +#line 526 "getdate.y"\r
2931 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (1)].intval); }\r
2932 +    break;\r
2933 +\r
2934 +  case 52:\r
2935 +\r
2936 +/* Line 1455 of yacc.c  */\r
2937 +#line 528 "getdate.y"\r
2938 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].intval); }\r
2939 +    break;\r
2940 +\r
2941 +  case 53:\r
2942 +\r
2943 +/* Line 1455 of yacc.c  */\r
2944 +#line 530 "getdate.y"\r
2945 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].textintval).value; }\r
2946 +    break;\r
2947 +\r
2948 +  case 54:\r
2949 +\r
2950 +/* Line 1455 of yacc.c  */\r
2951 +#line 532 "getdate.y"\r
2952 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = 1; }\r
2953 +    break;\r
2954 +\r
2955 +  case 55:\r
2956 +\r
2957 +/* Line 1455 of yacc.c  */\r
2958 +#line 534 "getdate.y"\r
2959 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].intval); }\r
2960 +    break;\r
2961 +\r
2962 +  case 56:\r
2963 +\r
2964 +/* Line 1455 of yacc.c  */\r
2965 +#line 536 "getdate.y"\r
2966 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].textintval).value; }\r
2967 +    break;\r
2968 +\r
2969 +  case 57:\r
2970 +\r
2971 +/* Line 1455 of yacc.c  */\r
2972 +#line 538 "getdate.y"\r
2973 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = 1; }\r
2974 +    break;\r
2975 +\r
2976 +  case 58:\r
2977 +\r
2978 +/* Line 1455 of yacc.c  */\r
2979 +#line 540 "getdate.y"\r
2980 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].intval); }\r
2981 +    break;\r
2982 +\r
2983 +  case 59:\r
2984 +\r
2985 +/* Line 1455 of yacc.c  */\r
2986 +#line 542 "getdate.y"\r
2987 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].textintval).value; }\r
2988 +    break;\r
2989 +\r
2990 +  case 60:\r
2991 +\r
2992 +/* Line 1455 of yacc.c  */\r
2993 +#line 544 "getdate.y"\r
2994 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; }\r
2995 +    break;\r
2996 +\r
2997 +  case 61:\r
2998 +\r
2999 +/* Line 1455 of yacc.c  */\r
3000 +#line 546 "getdate.y"\r
3001 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; }\r
3002 +    break;\r
3003 +\r
3004 +  case 62:\r
3005 +\r
3006 +/* Line 1455 of yacc.c  */\r
3007 +#line 548 "getdate.y"\r
3008 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = 1; }\r
3009 +    break;\r
3010 +\r
3011 +  case 64:\r
3012 +\r
3013 +/* Line 1455 of yacc.c  */\r
3014 +#line 554 "getdate.y"\r
3015 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].textintval).value; }\r
3016 +    break;\r
3017 +\r
3018 +  case 65:\r
3019 +\r
3020 +/* Line 1455 of yacc.c  */\r
3021 +#line 556 "getdate.y"\r
3022 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].textintval).value; }\r
3023 +    break;\r
3024 +\r
3025 +  case 66:\r
3026 +\r
3027 +/* Line 1455 of yacc.c  */\r
3028 +#line 558 "getdate.y"\r
3029 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); }\r
3030 +    break;\r
3031 +\r
3032 +  case 67:\r
3033 +\r
3034 +/* Line 1455 of yacc.c  */\r
3035 +#line 560 "getdate.y"\r
3036 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].textintval).value; }\r
3037 +    break;\r
3038 +\r
3039 +  case 68:\r
3040 +\r
3041 +/* Line 1455 of yacc.c  */\r
3042 +#line 562 "getdate.y"\r
3043 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].textintval).value; }\r
3044 +    break;\r
3045 +\r
3046 +  case 69:\r
3047 +\r
3048 +/* Line 1455 of yacc.c  */\r
3049 +#line 564 "getdate.y"\r
3050 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].textintval).value; }\r
3051 +    break;\r
3052 +\r
3053 +  case 70:\r
3054 +\r
3055 +/* Line 1455 of yacc.c  */\r
3056 +#line 569 "getdate.y"\r
3057 +    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (1)].intval); }\r
3058 +    break;\r
3059 +\r
3060 +  case 74:\r
3061 +\r
3062 +/* Line 1455 of yacc.c  */\r
3063 +#line 577 "getdate.y"\r
3064 +    { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; }\r
3065 +    break;\r
3066 +\r
3067 +  case 76:\r
3068 +\r
3069 +/* Line 1455 of yacc.c  */\r
3070 +#line 583 "getdate.y"\r
3071 +    { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; }\r
3072 +    break;\r
3073 +\r
3074 +  case 77:\r
3075 +\r
3076 +/* Line 1455 of yacc.c  */\r
3077 +#line 588 "getdate.y"\r
3078 +    { digits_to_date_time (pc, (yyvsp[(1) - (1)].textintval)); }\r
3079 +    break;\r
3080 +\r
3081 +  case 78:\r
3082 +\r
3083 +/* Line 1455 of yacc.c  */\r
3084 +#line 593 "getdate.y"\r
3085 +    {\r
3086 +        /* Hybrid all-digit and relative offset, so that we accept e.g.,\r
3087 +           "YYYYMMDD +N days" as well as "YYYYMMDD N days".  */\r
3088 +        digits_to_date_time (pc, (yyvsp[(1) - (2)].textintval));\r
3089 +        apply_relative_time (pc, (yyvsp[(2) - (2)].rel), 1);\r
3090 +      }\r
3091 +    break;\r
3092 +\r
3093 +  case 79:\r
3094 +\r
3095 +/* Line 1455 of yacc.c  */\r
3096 +#line 603 "getdate.y"\r
3097 +    { (yyval.intval) = -1; }\r
3098 +    break;\r
3099 +\r
3100 +  case 80:\r
3101 +\r
3102 +/* Line 1455 of yacc.c  */\r
3103 +#line 605 "getdate.y"\r
3104 +    { (yyval.intval) = (yyvsp[(2) - (2)].textintval).value; }\r
3105 +    break;\r
3106 +\r
3107 +  case 81:\r
3108 +\r
3109 +/* Line 1455 of yacc.c  */\r
3110 +#line 610 "getdate.y"\r
3111 +    { (yyval.intval) = MER24; }\r
3112 +    break;\r
3113 +\r
3114 +  case 82:\r
3115 +\r
3116 +/* Line 1455 of yacc.c  */\r
3117 +#line 612 "getdate.y"\r
3118 +    { (yyval.intval) = (yyvsp[(1) - (1)].intval); }\r
3119 +    break;\r
3120 +\r
3121 +\r
3122 +\r
3123 +/* Line 1455 of yacc.c  */\r
3124 +#line 2327 "getdate.c"\r
3125 +      default: break;\r
3126 +    }\r
3127 +  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);\r
3128 +\r
3129 +  YYPOPSTACK (yylen);\r
3130 +  yylen = 0;\r
3131 +  YY_STACK_PRINT (yyss, yyssp);\r
3132 +\r
3133 +  *++yyvsp = yyval;\r
3134 +\r
3135 +  /* Now `shift' the result of the reduction.  Determine what state\r
3136 +     that goes to, based on the state we popped back to and the rule\r
3137 +     number reduced by.  */\r
3138 +\r
3139 +  yyn = yyr1[yyn];\r
3140 +\r
3141 +  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;\r
3142 +  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)\r
3143 +    yystate = yytable[yystate];\r
3144 +  else\r
3145 +    yystate = yydefgoto[yyn - YYNTOKENS];\r
3146 +\r
3147 +  goto yynewstate;\r
3148 +\r
3149 +\r
3150 +/*------------------------------------.\r
3151 +| yyerrlab -- here on detecting error |\r
3152 +`------------------------------------*/\r
3153 +yyerrlab:\r
3154 +  /* If not already recovering from an error, report this error.  */\r
3155 +  if (!yyerrstatus)\r
3156 +    {\r
3157 +      ++yynerrs;\r
3158 +#if ! YYERROR_VERBOSE\r
3159 +      yyerror (pc, YY_("syntax error"));\r
3160 +#else\r
3161 +      {\r
3162 +       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);\r
3163 +       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)\r
3164 +         {\r
3165 +           YYSIZE_T yyalloc = 2 * yysize;\r
3166 +           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))\r
3167 +             yyalloc = YYSTACK_ALLOC_MAXIMUM;\r
3168 +           if (yymsg != yymsgbuf)\r
3169 +             YYSTACK_FREE (yymsg);\r
3170 +           yymsg = (char *) YYSTACK_ALLOC (yyalloc);\r
3171 +           if (yymsg)\r
3172 +             yymsg_alloc = yyalloc;\r
3173 +           else\r
3174 +             {\r
3175 +               yymsg = yymsgbuf;\r
3176 +               yymsg_alloc = sizeof yymsgbuf;\r
3177 +             }\r
3178 +         }\r
3179 +\r
3180 +       if (0 < yysize && yysize <= yymsg_alloc)\r
3181 +         {\r
3182 +           (void) yysyntax_error (yymsg, yystate, yychar);\r
3183 +           yyerror (pc, yymsg);\r
3184 +         }\r
3185 +       else\r
3186 +         {\r
3187 +           yyerror (pc, YY_("syntax error"));\r
3188 +           if (yysize != 0)\r
3189 +             goto yyexhaustedlab;\r
3190 +         }\r
3191 +      }\r
3192 +#endif\r
3193 +    }\r
3194 +\r
3195 +\r
3196 +\r
3197 +  if (yyerrstatus == 3)\r
3198 +    {\r
3199 +      /* If just tried and failed to reuse lookahead token after an\r
3200 +        error, discard it.  */\r
3201 +\r
3202 +      if (yychar <= YYEOF)\r
3203 +       {\r
3204 +         /* Return failure if at end of input.  */\r
3205 +         if (yychar == YYEOF)\r
3206 +           YYABORT;\r
3207 +       }\r
3208 +      else\r
3209 +       {\r
3210 +         yydestruct ("Error: discarding",\r
3211 +                     yytoken, &yylval, pc);\r
3212 +         yychar = YYEMPTY;\r
3213 +       }\r
3214 +    }\r
3215 +\r
3216 +  /* Else will try to reuse lookahead token after shifting the error\r
3217 +     token.  */\r
3218 +  goto yyerrlab1;\r
3219 +\r
3220 +\r
3221 +/*---------------------------------------------------.\r
3222 +| yyerrorlab -- error raised explicitly by YYERROR.  |\r
3223 +`---------------------------------------------------*/\r
3224 +yyerrorlab:\r
3225 +\r
3226 +  /* Pacify compilers like GCC when the user code never invokes\r
3227 +     YYERROR and the label yyerrorlab therefore never appears in user\r
3228 +     code.  */\r
3229 +  if (/*CONSTCOND*/ 0)\r
3230 +     goto yyerrorlab;\r
3231 +\r
3232 +  /* Do not reclaim the symbols of the rule which action triggered\r
3233 +     this YYERROR.  */\r
3234 +  YYPOPSTACK (yylen);\r
3235 +  yylen = 0;\r
3236 +  YY_STACK_PRINT (yyss, yyssp);\r
3237 +  yystate = *yyssp;\r
3238 +  goto yyerrlab1;\r
3239 +\r
3240 +\r
3241 +/*-------------------------------------------------------------.\r
3242 +| yyerrlab1 -- common code for both syntax error and YYERROR.  |\r
3243 +`-------------------------------------------------------------*/\r
3244 +yyerrlab1:\r
3245 +  yyerrstatus = 3;     /* Each real token shifted decrements this.  */\r
3246 +\r
3247 +  for (;;)\r
3248 +    {\r
3249 +      yyn = yypact[yystate];\r
3250 +      if (yyn != YYPACT_NINF)\r
3251 +       {\r
3252 +         yyn += YYTERROR;\r
3253 +         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)\r
3254 +           {\r
3255 +             yyn = yytable[yyn];\r
3256 +             if (0 < yyn)\r
3257 +               break;\r
3258 +           }\r
3259 +       }\r
3260 +\r
3261 +      /* Pop the current state because it cannot handle the error token.  */\r
3262 +      if (yyssp == yyss)\r
3263 +       YYABORT;\r
3264 +\r
3265 +\r
3266 +      yydestruct ("Error: popping",\r
3267 +                 yystos[yystate], yyvsp, pc);\r
3268 +      YYPOPSTACK (1);\r
3269 +      yystate = *yyssp;\r
3270 +      YY_STACK_PRINT (yyss, yyssp);\r
3271 +    }\r
3272 +\r
3273 +  *++yyvsp = yylval;\r
3274 +\r
3275 +\r
3276 +  /* Shift the error token.  */\r
3277 +  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);\r
3278 +\r
3279 +  yystate = yyn;\r
3280 +  goto yynewstate;\r
3281 +\r
3282 +\r
3283 +/*-------------------------------------.\r
3284 +| yyacceptlab -- YYACCEPT comes here.  |\r
3285 +`-------------------------------------*/\r
3286 +yyacceptlab:\r
3287 +  yyresult = 0;\r
3288 +  goto yyreturn;\r
3289 +\r
3290 +/*-----------------------------------.\r
3291 +| yyabortlab -- YYABORT comes here.  |\r
3292 +`-----------------------------------*/\r
3293 +yyabortlab:\r
3294 +  yyresult = 1;\r
3295 +  goto yyreturn;\r
3296 +\r
3297 +#if !defined(yyoverflow) || YYERROR_VERBOSE\r
3298 +/*-------------------------------------------------.\r
3299 +| yyexhaustedlab -- memory exhaustion comes here.  |\r
3300 +`-------------------------------------------------*/\r
3301 +yyexhaustedlab:\r
3302 +  yyerror (pc, YY_("memory exhausted"));\r
3303 +  yyresult = 2;\r
3304 +  /* Fall through.  */\r
3305 +#endif\r
3306 +\r
3307 +yyreturn:\r
3308 +  if (yychar != YYEMPTY)\r
3309 +     yydestruct ("Cleanup: discarding lookahead",\r
3310 +                yytoken, &yylval, pc);\r
3311 +  /* Do not reclaim the symbols of the rule which action triggered\r
3312 +     this YYABORT or YYACCEPT.  */\r
3313 +  YYPOPSTACK (yylen);\r
3314 +  YY_STACK_PRINT (yyss, yyssp);\r
3315 +  while (yyssp != yyss)\r
3316 +    {\r
3317 +      yydestruct ("Cleanup: popping",\r
3318 +                 yystos[*yyssp], yyvsp, pc);\r
3319 +      YYPOPSTACK (1);\r
3320 +    }\r
3321 +#ifndef yyoverflow\r
3322 +  if (yyss != yyssa)\r
3323 +    YYSTACK_FREE (yyss);\r
3324 +#endif\r
3325 +#if YYERROR_VERBOSE\r
3326 +  if (yymsg != yymsgbuf)\r
3327 +    YYSTACK_FREE (yymsg);\r
3328 +#endif\r
3329 +  /* Make sure YYID is used.  */\r
3330 +  return YYID (yyresult);\r
3331 +}\r
3332 +\r
3333 +\r
3334 +\r
3335 +/* Line 1675 of yacc.c  */\r
3336 +#line 615 "getdate.y"\r
3337 +\r
3338 +\r
3339 +static table const meridian_table[] =\r
3340 +{\r
3341 +  { "AM",   tMERIDIAN, MERam },\r
3342 +  { "A.M.", tMERIDIAN, MERam },\r
3343 +  { "PM",   tMERIDIAN, MERpm },\r
3344 +  { "P.M.", tMERIDIAN, MERpm },\r
3345 +  { NULL, 0, 0 }\r
3346 +};\r
3347 +\r
3348 +static table const dst_table[] =\r
3349 +{\r
3350 +  { "DST", tDST, 0 }\r
3351 +};\r
3352 +\r
3353 +static table const month_and_day_table[] =\r
3354 +{\r
3355 +  { "JANUARY",  tMONTH,  1 },\r
3356 +  { "FEBRUARY", tMONTH,  2 },\r
3357 +  { "MARCH",    tMONTH,  3 },\r
3358 +  { "APRIL",    tMONTH,  4 },\r
3359 +  { "MAY",      tMONTH,  5 },\r
3360 +  { "JUNE",     tMONTH,  6 },\r
3361 +  { "JULY",     tMONTH,  7 },\r
3362 +  { "AUGUST",   tMONTH,  8 },\r
3363 +  { "SEPTEMBER",tMONTH,  9 },\r
3364 +  { "SEPT",     tMONTH,  9 },\r
3365 +  { "OCTOBER",  tMONTH, 10 },\r
3366 +  { "NOVEMBER", tMONTH, 11 },\r
3367 +  { "DECEMBER", tMONTH, 12 },\r
3368 +  { "SUNDAY",   tDAY,    0 },\r
3369 +  { "MONDAY",   tDAY,    1 },\r
3370 +  { "TUESDAY",  tDAY,    2 },\r
3371 +  { "TUES",     tDAY,    2 },\r
3372 +  { "WEDNESDAY",tDAY,    3 },\r
3373 +  { "WEDNES",   tDAY,    3 },\r
3374 +  { "THURSDAY", tDAY,    4 },\r
3375 +  { "THUR",     tDAY,    4 },\r
3376 +  { "THURS",    tDAY,    4 },\r
3377 +  { "FRIDAY",   tDAY,    5 },\r
3378 +  { "SATURDAY", tDAY,    6 },\r
3379 +  { NULL, 0, 0 }\r
3380 +};\r
3381 +\r
3382 +static table const time_units_table[] =\r
3383 +{\r
3384 +  { "YEAR",     tYEAR_UNIT,      1 },\r
3385 +  { "MONTH",    tMONTH_UNIT,     1 },\r
3386 +  { "FORTNIGHT",tDAY_UNIT,      14 },\r
3387 +  { "WEEK",     tDAY_UNIT,       7 },\r
3388 +  { "DAY",      tDAY_UNIT,       1 },\r
3389 +  { "HOUR",     tHOUR_UNIT,      1 },\r
3390 +  { "MINUTE",   tMINUTE_UNIT,    1 },\r
3391 +  { "MIN",      tMINUTE_UNIT,    1 },\r
3392 +  { "SECOND",   tSEC_UNIT,       1 },\r
3393 +  { "SEC",      tSEC_UNIT,       1 },\r
3394 +  { NULL, 0, 0 }\r
3395 +};\r
3396 +\r
3397 +/* Assorted relative-time words. */\r
3398 +static table const relative_time_table[] =\r
3399 +{\r
3400 +  { "TOMORROW", tDAY_SHIFT,      1 },\r
3401 +  { "YESTERDAY",tDAY_SHIFT,     -1 },\r
3402 +  { "TODAY",    tDAY_SHIFT,      0 },\r
3403 +  { "NOW",      tDAY_SHIFT,      0 },\r
3404 +  { "LAST",     tORDINAL,       -1 },\r
3405 +  { "THIS",     tORDINAL,        0 },\r
3406 +  { "NEXT",     tORDINAL,        1 },\r
3407 +  { "FIRST",    tORDINAL,        1 },\r
3408 +/*{ "SECOND",   tORDINAL,        2 }, */\r
3409 +  { "THIRD",    tORDINAL,        3 },\r
3410 +  { "FOURTH",   tORDINAL,        4 },\r
3411 +  { "FIFTH",    tORDINAL,        5 },\r
3412 +  { "SIXTH",    tORDINAL,        6 },\r
3413 +  { "SEVENTH",  tORDINAL,        7 },\r
3414 +  { "EIGHTH",   tORDINAL,        8 },\r
3415 +  { "NINTH",    tORDINAL,        9 },\r
3416 +  { "TENTH",    tORDINAL,       10 },\r
3417 +  { "ELEVENTH", tORDINAL,       11 },\r
3418 +  { "TWELFTH",  tORDINAL,       12 },\r
3419 +  { "AGO",      tAGO,            1 },\r
3420 +  { NULL, 0, 0 }\r
3421 +};\r
3422 +\r
3423 +/* The universal time zone table.  These labels can be used even for\r
3424 +   time stamps that would not otherwise be valid, e.g., GMT time\r
3425 +   stamps in London during summer.  */\r
3426 +static table const universal_time_zone_table[] =\r
3427 +{\r
3428 +  { "GMT",      tZONE,     HOUR ( 0) }, /* Greenwich Mean */\r
3429 +  { "UT",       tZONE,     HOUR ( 0) }, /* Universal (Coordinated) */\r
3430 +  { "UTC",      tZONE,     HOUR ( 0) },\r
3431 +  { NULL, 0, 0 }\r
3432 +};\r
3433 +\r
3434 +/* The time zone table.  This table is necessarily incomplete, as time\r
3435 +   zone abbreviations are ambiguous; e.g. Australians interpret "EST"\r
3436 +   as Eastern time in Australia, not as US Eastern Standard Time.\r
3437 +   You cannot rely on getdate to handle arbitrary time zone\r
3438 +   abbreviations; use numeric abbreviations like `-0500' instead.  */\r
3439 +static table const time_zone_table[] =\r
3440 +{\r
3441 +  { "WET",      tZONE,     HOUR ( 0) }, /* Western European */\r
3442 +  { "WEST",     tDAYZONE,  HOUR ( 0) }, /* Western European Summer */\r
3443 +  { "BST",      tDAYZONE,  HOUR ( 0) }, /* British Summer */\r
3444 +  { "ART",      tZONE,    -HOUR ( 3) }, /* Argentina */\r
3445 +  { "BRT",      tZONE,    -HOUR ( 3) }, /* Brazil */\r
3446 +  { "BRST",     tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */\r
3447 +  { "NST",      tZONE,   -(HOUR ( 3) + 30) },   /* Newfoundland Standard */\r
3448 +  { "NDT",      tDAYZONE,-(HOUR ( 3) + 30) },   /* Newfoundland Daylight */\r
3449 +  { "AST",      tZONE,    -HOUR ( 4) }, /* Atlantic Standard */\r
3450 +  { "ADT",      tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */\r
3451 +  { "CLT",      tZONE,    -HOUR ( 4) }, /* Chile */\r
3452 +  { "CLST",     tDAYZONE, -HOUR ( 4) }, /* Chile Summer */\r
3453 +  { "EST",      tZONE,    -HOUR ( 5) }, /* Eastern Standard */\r
3454 +  { "EDT",      tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */\r
3455 +  { "CST",      tZONE,    -HOUR ( 6) }, /* Central Standard */\r
3456 +  { "CDT",      tDAYZONE, -HOUR ( 6) }, /* Central Daylight */\r
3457 +  { "MST",      tZONE,    -HOUR ( 7) }, /* Mountain Standard */\r
3458 +  { "MDT",      tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */\r
3459 +  { "PST",      tZONE,    -HOUR ( 8) }, /* Pacific Standard */\r
3460 +  { "PDT",      tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */\r
3461 +  { "AKST",     tZONE,    -HOUR ( 9) }, /* Alaska Standard */\r
3462 +  { "AKDT",     tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */\r
3463 +  { "HST",      tZONE,    -HOUR (10) }, /* Hawaii Standard */\r
3464 +  { "HAST",     tZONE,    -HOUR (10) }, /* Hawaii-Aleutian Standard */\r
3465 +  { "HADT",     tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */\r
3466 +  { "SST",      tZONE,    -HOUR (12) }, /* Samoa Standard */\r
3467 +  { "WAT",      tZONE,     HOUR ( 1) }, /* West Africa */\r
3468 +  { "CET",      tZONE,     HOUR ( 1) }, /* Central European */\r
3469 +  { "CEST",     tDAYZONE,  HOUR ( 1) }, /* Central European Summer */\r
3470 +  { "MET",      tZONE,     HOUR ( 1) }, /* Middle European */\r
3471 +  { "MEZ",      tZONE,     HOUR ( 1) }, /* Middle European */\r
3472 +  { "MEST",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */\r
3473 +  { "MESZ",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */\r
3474 +  { "EET",      tZONE,     HOUR ( 2) }, /* Eastern European */\r
3475 +  { "EEST",     tDAYZONE,  HOUR ( 2) }, /* Eastern European Summer */\r
3476 +  { "CAT",      tZONE,     HOUR ( 2) }, /* Central Africa */\r
3477 +  { "SAST",     tZONE,     HOUR ( 2) }, /* South Africa Standard */\r
3478 +  { "EAT",      tZONE,     HOUR ( 3) }, /* East Africa */\r
3479 +  { "MSK",      tZONE,     HOUR ( 3) }, /* Moscow */\r
3480 +  { "MSD",      tDAYZONE,  HOUR ( 3) }, /* Moscow Daylight */\r
3481 +  { "IST",      tZONE,    (HOUR ( 5) + 30) },   /* India Standard */\r
3482 +  { "SGT",      tZONE,     HOUR ( 8) }, /* Singapore */\r
3483 +  { "KST",      tZONE,     HOUR ( 9) }, /* Korea Standard */\r
3484 +  { "JST",      tZONE,     HOUR ( 9) }, /* Japan Standard */\r
3485 +  { "GST",      tZONE,     HOUR (10) }, /* Guam Standard */\r
3486 +  { "NZST",     tZONE,     HOUR (12) }, /* New Zealand Standard */\r
3487 +  { "NZDT",     tDAYZONE,  HOUR (12) }, /* New Zealand Daylight */\r
3488 +  { NULL, 0, 0 }\r
3489 +};\r
3490 +\r
3491 +/* Military time zone table. */\r
3492 +static table const military_table[] =\r
3493 +{\r
3494 +  { "A", tZONE, -HOUR ( 1) },\r
3495 +  { "B", tZONE, -HOUR ( 2) },\r
3496 +  { "C", tZONE, -HOUR ( 3) },\r
3497 +  { "D", tZONE, -HOUR ( 4) },\r
3498 +  { "E", tZONE, -HOUR ( 5) },\r
3499 +  { "F", tZONE, -HOUR ( 6) },\r
3500 +  { "G", tZONE, -HOUR ( 7) },\r
3501 +  { "H", tZONE, -HOUR ( 8) },\r
3502 +  { "I", tZONE, -HOUR ( 9) },\r
3503 +  { "K", tZONE, -HOUR (10) },\r
3504 +  { "L", tZONE, -HOUR (11) },\r
3505 +  { "M", tZONE, -HOUR (12) },\r
3506 +  { "N", tZONE,  HOUR ( 1) },\r
3507 +  { "O", tZONE,  HOUR ( 2) },\r
3508 +  { "P", tZONE,  HOUR ( 3) },\r
3509 +  { "Q", tZONE,  HOUR ( 4) },\r
3510 +  { "R", tZONE,  HOUR ( 5) },\r
3511 +  { "S", tZONE,  HOUR ( 6) },\r
3512 +  { "T", tZONE,  HOUR ( 7) },\r
3513 +  { "U", tZONE,  HOUR ( 8) },\r
3514 +  { "V", tZONE,  HOUR ( 9) },\r
3515 +  { "W", tZONE,  HOUR (10) },\r
3516 +  { "X", tZONE,  HOUR (11) },\r
3517 +  { "Y", tZONE,  HOUR (12) },\r
3518 +  { "Z", tZONE,  HOUR ( 0) },\r
3519 +  { NULL, 0, 0 }\r
3520 +};\r
3521 +\r
3522 +\f\r
3523 \r
3524 +\r
3525 +/* Convert a time zone expressed as HH:MM into an integer count of\r
3526 +   minutes.  If MM is negative, then S is of the form HHMM and needs\r
3527 +   to be picked apart; otherwise, S is of the form HH.  As specified in\r
3528 +   http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow\r
3529 +   only valid TZ range, and consider first two digits as hours, if no\r
3530 +   minutes specified.  */\r
3531 +\r
3532 +static long int\r
3533 +time_zone_hhmm (parser_control *pc, textint s, long int mm)\r
3534 +{\r
3535 +  long int n_minutes;\r
3536 +\r
3537 +  /* If the length of S is 1 or 2 and no minutes are specified,\r
3538 +     interpret it as a number of hours.  */\r
3539 +  if (s.digits <= 2 && mm < 0)\r
3540 +    s.value *= 100;\r
3541 +\r
3542 +  if (mm < 0)\r
3543 +    n_minutes = (s.value / 100) * 60 + s.value % 100;\r
3544 +  else\r
3545 +    n_minutes = s.value * 60 + (s.negative ? -mm : mm);\r
3546 +\r
3547 +  /* If the absolute number of minutes is larger than 24 hours,\r
3548 +     arrange to reject it by incrementing pc->zones_seen.  Thus,\r
3549 +     we allow only values in the range UTC-24:00 to UTC+24:00.  */\r
3550 +  if (24 * 60 < abs (n_minutes))\r
3551 +    pc->zones_seen++;\r
3552 +\r
3553 +  return n_minutes;\r
3554 +}\r
3555 +\r
3556 +static int\r
3557 +to_hour (long int hours, int meridian)\r
3558 +{\r
3559 +  switch (meridian)\r
3560 +    {\r
3561 +    default: /* Pacify GCC.  */\r
3562 +    case MER24:\r
3563 +      return 0 <= hours && hours < 24 ? hours : -1;\r
3564 +    case MERam:\r
3565 +      return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;\r
3566 +    case MERpm:\r
3567 +      return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;\r
3568 +    }\r
3569 +}\r
3570 +\r
3571 +static long int\r
3572 +to_year (textint textyear)\r
3573 +{\r
3574 +  long int year = textyear.value;\r
3575 +\r
3576 +  if (year < 0)\r
3577 +    year = -year;\r
3578 +\r
3579 +  /* XPG4 suggests that years 00-68 map to 2000-2068, and\r
3580 +     years 69-99 map to 1969-1999.  */\r
3581 +  else if (textyear.digits == 2)\r
3582 +    year += year < 69 ? 2000 : 1900;\r
3583 +\r
3584 +  return year;\r
3585 +}\r
3586 +\r
3587 +static table const *\r
3588 +lookup_zone (parser_control const *pc, char const *name)\r
3589 +{\r
3590 +  table const *tp;\r
3591 +\r
3592 +  for (tp = universal_time_zone_table; tp->name; tp++)\r
3593 +    if (strcmp (name, tp->name) == 0)\r
3594 +      return tp;\r
3595 +\r
3596 +  /* Try local zone abbreviations before those in time_zone_table, as\r
3597 +     the local ones are more likely to be right.  */\r
3598 +  for (tp = pc->local_time_zone_table; tp->name; tp++)\r
3599 +    if (strcmp (name, tp->name) == 0)\r
3600 +      return tp;\r
3601 +\r
3602 +  for (tp = time_zone_table; tp->name; tp++)\r
3603 +    if (strcmp (name, tp->name) == 0)\r
3604 +      return tp;\r
3605 +\r
3606 +  return NULL;\r
3607 +}\r
3608 +\r
3609 +#if ! HAVE_TM_GMTOFF\r
3610 +/* Yield the difference between *A and *B,\r
3611 +   measured in seconds, ignoring leap seconds.\r
3612 +   The body of this function is taken directly from the GNU C Library;\r
3613 +   see src/strftime.c.  */\r
3614 +static long int\r
3615 +tm_diff (struct tm const *a, struct tm const *b)\r
3616 +{\r
3617 +  /* Compute intervening leap days correctly even if year is negative.\r
3618 +     Take care to avoid int overflow in leap day calculations.  */\r
3619 +  int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);\r
3620 +  int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);\r
3621 +  int a100 = a4 / 25 - (a4 % 25 < 0);\r
3622 +  int b100 = b4 / 25 - (b4 % 25 < 0);\r
3623 +  int a400 = SHR (a100, 2);\r
3624 +  int b400 = SHR (b100, 2);\r
3625 +  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);\r
3626 +  long int ayear = a->tm_year;\r
3627 +  long int years = ayear - b->tm_year;\r
3628 +  long int days = (365 * years + intervening_leap_days\r
3629 +                   + (a->tm_yday - b->tm_yday));\r
3630 +  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))\r
3631 +                + (a->tm_min - b->tm_min))\r
3632 +          + (a->tm_sec - b->tm_sec));\r
3633 +}\r
3634 +#endif /* ! HAVE_TM_GMTOFF */\r
3635 +\r
3636 +static table const *\r
3637 +lookup_word (parser_control const *pc, char *word)\r
3638 +{\r
3639 +  char *p;\r
3640 +  char *q;\r
3641 +  size_t wordlen;\r
3642 +  table const *tp;\r
3643 +  bool period_found;\r
3644 +  bool abbrev;\r
3645 +\r
3646 +  /* Make it uppercase.  */\r
3647 +  for (p = word; *p; p++)\r
3648 +    {\r
3649 +      unsigned char ch = *p;\r
3650 +      *p = c_toupper (ch);\r
3651 +    }\r
3652 +\r
3653 +  for (tp = meridian_table; tp->name; tp++)\r
3654 +    if (strcmp (word, tp->name) == 0)\r
3655 +      return tp;\r
3656 +\r
3657 +  /* See if we have an abbreviation for a month. */\r
3658 +  wordlen = strlen (word);\r
3659 +  abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');\r
3660 +\r
3661 +  for (tp = month_and_day_table; tp->name; tp++)\r
3662 +    if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)\r
3663 +      return tp;\r
3664 +\r
3665 +  if ((tp = lookup_zone (pc, word)))\r
3666 +    return tp;\r
3667 +\r
3668 +  if (strcmp (word, dst_table[0].name) == 0)\r
3669 +    return dst_table;\r
3670 +\r
3671 +  for (tp = time_units_table; tp->name; tp++)\r
3672 +    if (strcmp (word, tp->name) == 0)\r
3673 +      return tp;\r
3674 +\r
3675 +  /* Strip off any plural and try the units table again. */\r
3676 +  if (word[wordlen - 1] == 'S')\r
3677 +    {\r
3678 +      word[wordlen - 1] = '\0';\r
3679 +      for (tp = time_units_table; tp->name; tp++)\r
3680 +        if (strcmp (word, tp->name) == 0)\r
3681 +          return tp;\r
3682 +      word[wordlen - 1] = 'S';  /* For "this" in relative_time_table.  */\r
3683 +    }\r
3684 +\r
3685 +  for (tp = relative_time_table; tp->name; tp++)\r
3686 +    if (strcmp (word, tp->name) == 0)\r
3687 +      return tp;\r
3688 +\r
3689 +  /* Military time zones. */\r
3690 +  if (wordlen == 1)\r
3691 +    for (tp = military_table; tp->name; tp++)\r
3692 +      if (word[0] == tp->name[0])\r
3693 +        return tp;\r
3694 +\r
3695 +  /* Drop out any periods and try the time zone table again. */\r
3696 +  for (period_found = false, p = q = word; (*p = *q); q++)\r
3697 +    if (*q == '.')\r
3698 +      period_found = true;\r
3699 +    else\r
3700 +      p++;\r
3701 +  if (period_found && (tp = lookup_zone (pc, word)))\r
3702 +    return tp;\r
3703 +\r
3704 +  return NULL;\r
3705 +}\r
3706 +\r
3707 +static int\r
3708 +yylex (YYSTYPE *lvalp, parser_control *pc)\r
3709 +{\r
3710 +  unsigned char c;\r
3711 +  size_t count;\r
3712 +\r
3713 +  for (;;)\r
3714 +    {\r
3715 +      while (c = *pc->input, c_isspace (c))\r
3716 +        pc->input++;\r
3717 +\r
3718 +      if (ISDIGIT (c) || c == '-' || c == '+')\r
3719 +        {\r
3720 +          char const *p;\r
3721 +          int sign;\r
3722 +          unsigned long int value;\r
3723 +          if (c == '-' || c == '+')\r
3724 +            {\r
3725 +              sign = c == '-' ? -1 : 1;\r
3726 +              while (c = *++pc->input, c_isspace (c))\r
3727 +                continue;\r
3728 +              if (! ISDIGIT (c))\r
3729 +                /* skip the '-' sign */\r
3730 +                continue;\r
3731 +            }\r
3732 +          else\r
3733 +            sign = 0;\r
3734 +          p = pc->input;\r
3735 +          for (value = 0; ; value *= 10)\r
3736 +            {\r
3737 +              unsigned long int value1 = value + (c - '0');\r
3738 +              if (value1 < value)\r
3739 +                return '?';\r
3740 +              value = value1;\r
3741 +              c = *++p;\r
3742 +              if (! ISDIGIT (c))\r
3743 +                break;\r
3744 +              if (ULONG_MAX / 10 < value)\r
3745 +                return '?';\r
3746 +            }\r
3747 +          if ((c == '.' || c == ',') && ISDIGIT (p[1]))\r
3748 +            {\r
3749 +              time_t s;\r
3750 +              int ns;\r
3751 +              int digits;\r
3752 +              unsigned long int value1;\r
3753 +\r
3754 +              /* Check for overflow when converting value to time_t.  */\r
3755 +              if (sign < 0)\r
3756 +                {\r
3757 +                  s = - value;\r
3758 +                  if (0 < s)\r
3759 +                    return '?';\r
3760 +                  value1 = -s;\r
3761 +                }\r
3762 +              else\r
3763 +                {\r
3764 +                  s = value;\r
3765 +                  if (s < 0)\r
3766 +                    return '?';\r
3767 +                  value1 = s;\r
3768 +                }\r
3769 +              if (value != value1)\r
3770 +                return '?';\r
3771 +\r
3772 +              /* Accumulate fraction, to ns precision.  */\r
3773 +              p++;\r
3774 +              ns = *p++ - '0';\r
3775 +              for (digits = 2; digits <= LOG10_BILLION; digits++)\r
3776 +                {\r
3777 +                  ns *= 10;\r
3778 +                  if (ISDIGIT (*p))\r
3779 +                    ns += *p++ - '0';\r
3780 +                }\r
3781 +\r
3782 +              /* Skip excess digits, truncating toward -Infinity.  */\r
3783 +              if (sign < 0)\r
3784 +                for (; ISDIGIT (*p); p++)\r
3785 +                  if (*p != '0')\r
3786 +                    {\r
3787 +                      ns++;\r
3788 +                      break;\r
3789 +                    }\r
3790 +              while (ISDIGIT (*p))\r
3791 +                p++;\r
3792 +\r
3793 +              /* Adjust to the timespec convention, which is that\r
3794 +                 tv_nsec is always a positive offset even if tv_sec is\r
3795 +                 negative.  */\r
3796 +              if (sign < 0 && ns)\r
3797 +                {\r
3798 +                  s--;\r
3799 +                  if (! (s < 0))\r
3800 +                    return '?';\r
3801 +                  ns = BILLION - ns;\r
3802 +                }\r
3803 +\r
3804 +              lvalp->timespec.tv_sec = s;\r
3805 +              lvalp->timespec.tv_nsec = ns;\r
3806 +              pc->input = p;\r
3807 +              return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;\r
3808 +            }\r
3809 +          else\r
3810 +            {\r
3811 +              lvalp->textintval.negative = sign < 0;\r
3812 +              if (sign < 0)\r
3813 +                {\r
3814 +                  lvalp->textintval.value = - value;\r
3815 +                  if (0 < lvalp->textintval.value)\r
3816 +                    return '?';\r
3817 +                }\r
3818 +              else\r
3819 +                {\r
3820 +                  lvalp->textintval.value = value;\r
3821 +                  if (lvalp->textintval.value < 0)\r
3822 +                    return '?';\r
3823 +                }\r
3824 +              lvalp->textintval.digits = p - pc->input;\r
3825 +              pc->input = p;\r
3826 +              return sign ? tSNUMBER : tUNUMBER;\r
3827 +            }\r
3828 +        }\r
3829 +\r
3830 +      if (c_isalpha (c))\r
3831 +        {\r
3832 +          char buff[20];\r
3833 +          char *p = buff;\r
3834 +          table const *tp;\r
3835 +\r
3836 +          do\r
3837 +            {\r
3838 +              if (p < buff + sizeof buff - 1)\r
3839 +                *p++ = c;\r
3840 +              c = *++pc->input;\r
3841 +            }\r
3842 +          while (c_isalpha (c) || c == '.');\r
3843 +\r
3844 +          *p = '\0';\r
3845 +          tp = lookup_word (pc, buff);\r
3846 +          if (! tp)\r
3847 +            return '?';\r
3848 +          lvalp->intval = tp->value;\r
3849 +          return tp->type;\r
3850 +        }\r
3851 +\r
3852 +      if (c != '(')\r
3853 +        return *pc->input++;\r
3854 +      count = 0;\r
3855 +      do\r
3856 +        {\r
3857 +          c = *pc->input++;\r
3858 +          if (c == '\0')\r
3859 +            return c;\r
3860 +          if (c == '(')\r
3861 +            count++;\r
3862 +          else if (c == ')')\r
3863 +            count--;\r
3864 +        }\r
3865 +      while (count != 0);\r
3866 +    }\r
3867 +}\r
3868 +\r
3869 +/* Do nothing if the parser reports an error.  */\r
3870 +static int\r
3871 +yyerror (parser_control const *pc _GL_UNUSED,\r
3872 +         char const *s _GL_UNUSED)\r
3873 +{\r
3874 +  return 0;\r
3875 +}\r
3876 +\r
3877 +/* If *TM0 is the old and *TM1 is the new value of a struct tm after\r
3878 +   passing it to mktime, return true if it's OK that mktime returned T.\r
3879 +   It's not OK if *TM0 has out-of-range members.  */\r
3880 +\r
3881 +static bool\r
3882 +mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)\r
3883 +{\r
3884 +  if (t == (time_t) -1)\r
3885 +    {\r
3886 +      /* Guard against falsely reporting an error when parsing a time\r
3887 +         stamp that happens to equal (time_t) -1, on a host that\r
3888 +         supports such a time stamp.  */\r
3889 +      tm1 = localtime (&t);\r
3890 +      if (!tm1)\r
3891 +        return false;\r
3892 +    }\r
3893 +\r
3894 +  return ! ((tm0->tm_sec ^ tm1->tm_sec)\r
3895 +            | (tm0->tm_min ^ tm1->tm_min)\r
3896 +            | (tm0->tm_hour ^ tm1->tm_hour)\r
3897 +            | (tm0->tm_mday ^ tm1->tm_mday)\r
3898 +            | (tm0->tm_mon ^ tm1->tm_mon)\r
3899 +            | (tm0->tm_year ^ tm1->tm_year));\r
3900 +}\r
3901 +\r
3902 +/* A reasonable upper bound for the size of ordinary TZ strings.\r
3903 +   Use heap allocation if TZ's length exceeds this.  */\r
3904 +enum { TZBUFSIZE = 100 };\r
3905 +\r
3906 +/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated\r
3907 +   otherwise.  */\r
3908 +static char *\r
3909 +get_tz (char tzbuf[TZBUFSIZE])\r
3910 +{\r
3911 +  char *tz = getenv ("TZ");\r
3912 +  if (tz)\r
3913 +    {\r
3914 +      size_t tzsize = strlen (tz) + 1;\r
3915 +      tz = (tzsize <= TZBUFSIZE\r
3916 +            ? memcpy (tzbuf, tz, tzsize)\r
3917 +            : xmemdup (tz, tzsize));\r
3918 +    }\r
3919 +  return tz;\r
3920 +}\r
3921 +\r
3922 +/* Parse a date/time string, storing the resulting time value into *RESULT.\r
3923 +   The string itself is pointed to by P.  Return true if successful.\r
3924 +   P can be an incomplete or relative time specification; if so, use\r
3925 +   *NOW as the basis for the returned time.  */\r
3926 +bool\r
3927 +get_date (struct timespec *result, char const *p, struct timespec const *now)\r
3928 +{\r
3929 +  time_t Start;\r
3930 +  long int Start_ns;\r
3931 +  struct tm const *tmp;\r
3932 +  struct tm tm;\r
3933 +  struct tm tm0;\r
3934 +  parser_control pc;\r
3935 +  struct timespec gettime_buffer;\r
3936 +  unsigned char c;\r
3937 +  bool tz_was_altered = false;\r
3938 +  char *tz0 = NULL;\r
3939 +  char tz0buf[TZBUFSIZE];\r
3940 +  bool ok = true;\r
3941 +\r
3942 +  if (! now)\r
3943 +    {\r
3944 +      gettime (&gettime_buffer);\r
3945 +      now = &gettime_buffer;\r
3946 +    }\r
3947 +\r
3948 +  Start = now->tv_sec;\r
3949 +  Start_ns = now->tv_nsec;\r
3950 +\r
3951 +  tmp = localtime (&now->tv_sec);\r
3952 +  if (! tmp)\r
3953 +    return false;\r
3954 +\r
3955 +  while (c = *p, c_isspace (c))\r
3956 +    p++;\r
3957 +\r
3958 +  if (strncmp (p, "TZ=\"", 4) == 0)\r
3959 +    {\r
3960 +      char const *tzbase = p + 4;\r
3961 +      size_t tzsize = 1;\r
3962 +      char const *s;\r
3963 +\r
3964 +      for (s = tzbase; *s; s++, tzsize++)\r
3965 +        if (*s == '\\')\r
3966 +          {\r
3967 +            s++;\r
3968 +            if (! (*s == '\\' || *s == '"'))\r
3969 +              break;\r
3970 +          }\r
3971 +        else if (*s == '"')\r
3972 +          {\r
3973 +            char *z;\r
3974 +            char *tz1;\r
3975 +            char tz1buf[TZBUFSIZE];\r
3976 +            bool large_tz = TZBUFSIZE < tzsize;\r
3977 +            bool setenv_ok;\r
3978 +            /* Free tz0, in case this is the 2nd or subsequent time through. */\r
3979 +            free (tz0);\r
3980 +            tz0 = get_tz (tz0buf);\r
3981 +            z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf;\r
3982 +            for (s = tzbase; *s != '"'; s++)\r
3983 +              *z++ = *(s += *s == '\\');\r
3984 +            *z = '\0';\r
3985 +            setenv_ok = setenv ("TZ", tz1, 1) == 0;\r
3986 +            if (large_tz)\r
3987 +              free (tz1);\r
3988 +            if (!setenv_ok)\r
3989 +              goto fail;\r
3990 +            tz_was_altered = true;\r
3991 +            p = s + 1;\r
3992 +          }\r
3993 +    }\r
3994 +\r
3995 +  /* As documented, be careful to treat the empty string just like\r
3996 +     a date string of "0".  Without this, an empty string would be\r
3997 +     declared invalid when parsed during a DST transition.  */\r
3998 +  if (*p == '\0')\r
3999 +    p = "0";\r
4000 +\r
4001 +  pc.input = p;\r
4002 +  pc.year.value = tmp->tm_year;\r
4003 +  pc.year.value += TM_YEAR_BASE;\r
4004 +  pc.year.digits = 0;\r
4005 +  pc.month = tmp->tm_mon + 1;\r
4006 +  pc.day = tmp->tm_mday;\r
4007 +  pc.hour = tmp->tm_hour;\r
4008 +  pc.minutes = tmp->tm_min;\r
4009 +  pc.seconds.tv_sec = tmp->tm_sec;\r
4010 +  pc.seconds.tv_nsec = Start_ns;\r
4011 +  tm.tm_isdst = tmp->tm_isdst;\r
4012 +\r
4013 +  pc.meridian = MER24;\r
4014 +  pc.rel = RELATIVE_TIME_0;\r
4015 +  pc.timespec_seen = false;\r
4016 +  pc.rels_seen = false;\r
4017 +  pc.dates_seen = 0;\r
4018 +  pc.days_seen = 0;\r
4019 +  pc.times_seen = 0;\r
4020 +  pc.local_zones_seen = 0;\r
4021 +  pc.dsts_seen = 0;\r
4022 +  pc.zones_seen = 0;\r
4023 +\r
4024 +#if HAVE_STRUCT_TM_TM_ZONE\r
4025 +  pc.local_time_zone_table[0].name = tmp->tm_zone;\r
4026 +  pc.local_time_zone_table[0].type = tLOCAL_ZONE;\r
4027 +  pc.local_time_zone_table[0].value = tmp->tm_isdst;\r
4028 +  pc.local_time_zone_table[1].name = NULL;\r
4029 +\r
4030 +  /* Probe the names used in the next three calendar quarters, looking\r
4031 +     for a tm_isdst different from the one we already have.  */\r
4032 +  {\r
4033 +    int quarter;\r
4034 +    for (quarter = 1; quarter <= 3; quarter++)\r
4035 +      {\r
4036 +        time_t probe = Start + quarter * (90 * 24 * 60 * 60);\r
4037 +        struct tm const *probe_tm = localtime (&probe);\r
4038 +        if (probe_tm && probe_tm->tm_zone\r
4039 +            && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)\r
4040 +          {\r
4041 +              {\r
4042 +                pc.local_time_zone_table[1].name = probe_tm->tm_zone;\r
4043 +                pc.local_time_zone_table[1].type = tLOCAL_ZONE;\r
4044 +                pc.local_time_zone_table[1].value = probe_tm->tm_isdst;\r
4045 +                pc.local_time_zone_table[2].name = NULL;\r
4046 +              }\r
4047 +            break;\r
4048 +          }\r
4049 +      }\r
4050 +  }\r
4051 +#else\r
4052 +#if HAVE_TZNAME\r
4053 +  {\r
4054 +# if !HAVE_DECL_TZNAME\r
4055 +    extern char *tzname[];\r
4056 +# endif\r
4057 +    int i;\r
4058 +    for (i = 0; i < 2; i++)\r
4059 +      {\r
4060 +        pc.local_time_zone_table[i].name = tzname[i];\r
4061 +        pc.local_time_zone_table[i].type = tLOCAL_ZONE;\r
4062 +        pc.local_time_zone_table[i].value = i;\r
4063 +      }\r
4064 +    pc.local_time_zone_table[i].name = NULL;\r
4065 +  }\r
4066 +#else\r
4067 +  pc.local_time_zone_table[0].name = NULL;\r
4068 +#endif\r
4069 +#endif\r
4070 +\r
4071 +  if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name\r
4072 +      && ! strcmp (pc.local_time_zone_table[0].name,\r
4073 +                   pc.local_time_zone_table[1].name))\r
4074 +    {\r
4075 +      /* This locale uses the same abbrevation for standard and\r
4076 +         daylight times.  So if we see that abbreviation, we don't\r
4077 +         know whether it's daylight time.  */\r
4078 +      pc.local_time_zone_table[0].value = -1;\r
4079 +      pc.local_time_zone_table[1].name = NULL;\r
4080 +    }\r
4081 +\r
4082 +  if (yyparse (&pc) != 0)\r
4083 +    goto fail;\r
4084 +\r
4085 +  if (pc.timespec_seen)\r
4086 +    *result = pc.seconds;\r
4087 +  else\r
4088 +    {\r
4089 +      if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen\r
4090 +               | (pc.local_zones_seen + pc.zones_seen)))\r
4091 +        goto fail;\r
4092 +\r
4093 +      tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;\r
4094 +      tm.tm_mon = pc.month - 1;\r
4095 +      tm.tm_mday = pc.day;\r
4096 +      if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))\r
4097 +        {\r
4098 +          tm.tm_hour = to_hour (pc.hour, pc.meridian);\r
4099 +          if (tm.tm_hour < 0)\r
4100 +            goto fail;\r
4101 +          tm.tm_min = pc.minutes;\r
4102 +          tm.tm_sec = pc.seconds.tv_sec;\r
4103 +        }\r
4104 +      else\r
4105 +        {\r
4106 +          tm.tm_hour = tm.tm_min = tm.tm_sec = 0;\r
4107 +          pc.seconds.tv_nsec = 0;\r
4108 +        }\r
4109 +\r
4110 +      /* Let mktime deduce tm_isdst if we have an absolute time stamp.  */\r
4111 +      if (pc.dates_seen | pc.days_seen | pc.times_seen)\r
4112 +        tm.tm_isdst = -1;\r
4113 +\r
4114 +      /* But if the input explicitly specifies local time with or without\r
4115 +         DST, give mktime that information.  */\r
4116 +      if (pc.local_zones_seen)\r
4117 +        tm.tm_isdst = pc.local_isdst;\r
4118 +\r
4119 +      tm0 = tm;\r
4120 +\r
4121 +      Start = mktime (&tm);\r
4122 +\r
4123 +      if (! mktime_ok (&tm0, &tm, Start))\r
4124 +        {\r
4125 +          if (! pc.zones_seen)\r
4126 +            goto fail;\r
4127 +          else\r
4128 +            {\r
4129 +              /* Guard against falsely reporting errors near the time_t\r
4130 +                 boundaries when parsing times in other time zones.  For\r
4131 +                 example, suppose the input string "1969-12-31 23:00:00 -0100",\r
4132 +                 the current time zone is 8 hours ahead of UTC, and the min\r
4133 +                 time_t value is 1970-01-01 00:00:00 UTC.  Then the min\r
4134 +                 localtime value is 1970-01-01 08:00:00, and mktime will\r
4135 +                 therefore fail on 1969-12-31 23:00:00.  To work around the\r
4136 +                 problem, set the time zone to 1 hour behind UTC temporarily\r
4137 +                 by setting TZ="XXX1:00" and try mktime again.  */\r
4138 +\r
4139 +              long int time_zone = pc.time_zone;\r
4140 +              long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;\r
4141 +              long int abs_time_zone_hour = abs_time_zone / 60;\r
4142 +              int abs_time_zone_min = abs_time_zone % 60;\r
4143 +              char tz1buf[sizeof "XXX+0:00"\r
4144 +                          + sizeof pc.time_zone * CHAR_BIT / 3];\r
4145 +              if (!tz_was_altered)\r
4146 +                tz0 = get_tz (tz0buf);\r
4147 +              sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0),\r
4148 +                       abs_time_zone_hour, abs_time_zone_min);\r
4149 +              if (setenv ("TZ", tz1buf, 1) != 0)\r
4150 +                goto fail;\r
4151 +              tz_was_altered = true;\r
4152 +              tm = tm0;\r
4153 +              Start = mktime (&tm);\r
4154 +              if (! mktime_ok (&tm0, &tm, Start))\r
4155 +                goto fail;\r
4156 +            }\r
4157 +        }\r
4158 +\r
4159 +      if (pc.days_seen && ! pc.dates_seen)\r
4160 +        {\r
4161 +          tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7\r
4162 +                         + 7 * (pc.day_ordinal\r
4163 +                                - (0 < pc.day_ordinal\r
4164 +                                   && tm.tm_wday != pc.day_number)));\r
4165 +          tm.tm_isdst = -1;\r
4166 +          Start = mktime (&tm);\r
4167 +          if (Start == (time_t) -1)\r
4168 +            goto fail;\r
4169 +        }\r
4170 +\r
4171 +      /* Add relative date.  */\r
4172 +      if (pc.rel.year | pc.rel.month | pc.rel.day)\r
4173 +        {\r
4174 +          int year = tm.tm_year + pc.rel.year;\r
4175 +          int month = tm.tm_mon + pc.rel.month;\r
4176 +          int day = tm.tm_mday + pc.rel.day;\r
4177 +          if (((year < tm.tm_year) ^ (pc.rel.year < 0))\r
4178 +              | ((month < tm.tm_mon) ^ (pc.rel.month < 0))\r
4179 +              | ((day < tm.tm_mday) ^ (pc.rel.day < 0)))\r
4180 +            goto fail;\r
4181 +          tm.tm_year = year;\r
4182 +          tm.tm_mon = month;\r
4183 +          tm.tm_mday = day;\r
4184 +          tm.tm_hour = tm0.tm_hour;\r
4185 +          tm.tm_min = tm0.tm_min;\r
4186 +          tm.tm_sec = tm0.tm_sec;\r
4187 +          tm.tm_isdst = tm0.tm_isdst;\r
4188 +          Start = mktime (&tm);\r
4189 +          if (Start == (time_t) -1)\r
4190 +            goto fail;\r
4191 +        }\r
4192 +\r
4193 +      /* The only "output" of this if-block is an updated Start value,\r
4194 +         so this block must follow others that clobber Start.  */\r
4195 +      if (pc.zones_seen)\r
4196 +        {\r
4197 +          long int delta = pc.time_zone * 60;\r
4198 +          time_t t1;\r
4199 +#ifdef HAVE_TM_GMTOFF\r
4200 +          delta -= tm.tm_gmtoff;\r
4201 +#else\r
4202 +          time_t t = Start;\r
4203 +          struct tm const *gmt = gmtime (&t);\r
4204 +          if (! gmt)\r
4205 +            goto fail;\r
4206 +          delta -= tm_diff (&tm, gmt);\r
4207 +#endif\r
4208 +          t1 = Start - delta;\r
4209 +          if ((Start < t1) != (delta < 0))\r
4210 +            goto fail;  /* time_t overflow */\r
4211 +          Start = t1;\r
4212 +        }\r
4213 +\r
4214 +      /* Add relative hours, minutes, and seconds.  On hosts that support\r
4215 +         leap seconds, ignore the possibility of leap seconds; e.g.,\r
4216 +         "+ 10 minutes" adds 600 seconds, even if one of them is a\r
4217 +         leap second.  Typically this is not what the user wants, but it's\r
4218 +         too hard to do it the other way, because the time zone indicator\r
4219 +         must be applied before relative times, and if mktime is applied\r
4220 +         again the time zone will be lost.  */\r
4221 +      {\r
4222 +        long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns;\r
4223 +        long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;\r
4224 +        time_t t0 = Start;\r
4225 +        long int d1 = 60 * 60 * pc.rel.hour;\r
4226 +        time_t t1 = t0 + d1;\r
4227 +        long int d2 = 60 * pc.rel.minutes;\r
4228 +        time_t t2 = t1 + d2;\r
4229 +        long_time_t d3 = pc.rel.seconds;\r
4230 +        long_time_t t3 = t2 + d3;\r
4231 +        long int d4 = (sum_ns - normalized_ns) / BILLION;\r
4232 +        long_time_t t4 = t3 + d4;\r
4233 +        time_t t5 = t4;\r
4234 +\r
4235 +        if ((d1 / (60 * 60) ^ pc.rel.hour)\r
4236 +            | (d2 / 60 ^ pc.rel.minutes)\r
4237 +            | ((t1 < t0) ^ (d1 < 0))\r
4238 +            | ((t2 < t1) ^ (d2 < 0))\r
4239 +            | ((t3 < t2) ^ (d3 < 0))\r
4240 +            | ((t4 < t3) ^ (d4 < 0))\r
4241 +            | (t5 != t4))\r
4242 +          goto fail;\r
4243 +\r
4244 +        result->tv_sec = t5;\r
4245 +        result->tv_nsec = normalized_ns;\r
4246 +      }\r
4247 +    }\r
4248 +\r
4249 +  goto done;\r
4250 +\r
4251 + fail:\r
4252 +  ok = false;\r
4253 + done:\r
4254 +  if (tz_was_altered)\r
4255 +    ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0;\r
4256 +  if (tz0 != tz0buf)\r
4257 +    free (tz0);\r
4258 +  return ok;\r
4259 +}\r
4260 +\r
4261 +#if TEST\r
4262 +\r
4263 +int\r
4264 +main (int ac, char **av)\r
4265 +{\r
4266 +  char buff[BUFSIZ];\r
4267 +\r
4268 +  printf ("Enter date, or blank line to exit.\n\t> ");\r
4269 +  fflush (stdout);\r
4270 +\r
4271 +  buff[BUFSIZ - 1] = '\0';\r
4272 +  while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])\r
4273 +    {\r
4274 +      struct timespec d;\r
4275 +      struct tm const *tm;\r
4276 +      if (! get_date (&d, buff, NULL))\r
4277 +        printf ("Bad format - couldn't convert.\n");\r
4278 +      else if (! (tm = localtime (&d.tv_sec)))\r
4279 +        {\r
4280 +          long int sec = d.tv_sec;\r
4281 +          printf ("localtime (%ld) failed\n", sec);\r
4282 +        }\r
4283 +      else\r
4284 +        {\r
4285 +          int ns = d.tv_nsec;\r
4286 +          printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",\r
4287 +                  tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,\r
4288 +                  tm->tm_hour, tm->tm_min, tm->tm_sec, ns);\r
4289 +        }\r
4290 +      printf ("\t> ");\r
4291 +      fflush (stdout);\r
4292 +    }\r
4293 +  return 0;\r
4294 +}\r
4295 +#endif /* TEST */\r
4296 +\r
4297 diff --git a/lib/getdate.h b/lib/getdate.h\r
4298 new file mode 100644\r
4299 index 0000000..22cc2c0\r
4300 --- /dev/null\r
4301 +++ b/lib/getdate.h\r
4302 @@ -0,0 +1,22 @@\r
4303 +/* Parse a string into an internal time stamp.\r
4304 +\r
4305 +   Copyright (C) 1995, 1997, 1998, 2003, 2004, 2007, 2009, 2010 Free Software\r
4306 +   Foundation, Inc.\r
4307 +\r
4308 +   This program is free software: you can redistribute it and/or modify\r
4309 +   it under the terms of the GNU General Public License as published by\r
4310 +   the Free Software Foundation; either version 3 of the License, or\r
4311 +   (at your option) any later version.\r
4312 +\r
4313 +   This program is distributed in the hope that it will be useful,\r
4314 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
4315 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
4316 +   GNU General Public License for more details.\r
4317 +\r
4318 +   You should have received a copy of the GNU General Public License\r
4319 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
4320 +\r
4321 +#include <stdbool.h>\r
4322 +#include <time.h>\r
4323 +\r
4324 +bool get_date (struct timespec *, char const *, struct timespec const *);\r
4325 diff --git a/lib/getdate.y b/lib/getdate.y\r
4326 new file mode 100644\r
4327 index 0000000..445865b\r
4328 --- /dev/null\r
4329 +++ b/lib/getdate.y\r
4330 @@ -0,0 +1,1572 @@\r
4331 +%{\r
4332 +/* Parse a string into an internal time stamp.\r
4333 +\r
4334 +   Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,\r
4335 +   2010 Free Software Foundation, Inc.\r
4336 +\r
4337 +   This program is free software: you can redistribute it and/or modify\r
4338 +   it under the terms of the GNU General Public License as published by\r
4339 +   the Free Software Foundation; either version 3 of the License, or\r
4340 +   (at your option) any later version.\r
4341 +\r
4342 +   This program is distributed in the hope that it will be useful,\r
4343 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
4344 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
4345 +   GNU General Public License for more details.\r
4346 +\r
4347 +   You should have received a copy of the GNU General Public License\r
4348 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
4349 +\r
4350 +/* Originally written by Steven M. Bellovin <smb@research.att.com> while\r
4351 +   at the University of North Carolina at Chapel Hill.  Later tweaked by\r
4352 +   a couple of people on Usenet.  Completely overhauled by Rich $alz\r
4353 +   <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.\r
4354 +\r
4355 +   Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do\r
4356 +   the right thing about local DST.  Also modified by Paul Eggert\r
4357 +   <eggert@cs.ucla.edu> in February 2004 to support\r
4358 +   nanosecond-resolution time stamps, and in October 2004 to support\r
4359 +   TZ strings in dates.  */\r
4360 +\r
4361 +/* FIXME: Check for arithmetic overflow in all cases, not just\r
4362 +   some of them.  */\r
4363 +\r
4364 +#include <config.h>\r
4365 +\r
4366 +#include "getdate.h"\r
4367 +\r
4368 +#include "intprops.h"\r
4369 +#include "timespec.h"\r
4370 +#include "verify.h"\r
4371 +\r
4372 +/* There's no need to extend the stack, so there's no need to involve\r
4373 +   alloca.  */\r
4374 +#define YYSTACK_USE_ALLOCA 0\r
4375 +\r
4376 +/* Tell Bison how much stack space is needed.  20 should be plenty for\r
4377 +   this grammar, which is not right recursive.  Beware setting it too\r
4378 +   high, since that might cause problems on machines whose\r
4379 +   implementations have lame stack-overflow checking.  */\r
4380 +#define YYMAXDEPTH 20\r
4381 +#define YYINITDEPTH YYMAXDEPTH\r
4382 +\r
4383 +/* Since the code of getdate.y is not included in the Emacs executable\r
4384 +   itself, there is no need to #define static in this file.  Even if\r
4385 +   the code were included in the Emacs executable, it probably\r
4386 +   wouldn't do any harm to #undef it here; this will only cause\r
4387 +   problems if we try to write to a static variable, which I don't\r
4388 +   think this code needs to do.  */\r
4389 +#ifdef emacs\r
4390 +# undef static\r
4391 +#endif\r
4392 +\r
4393 +#include <c-ctype.h>\r
4394 +#include <limits.h>\r
4395 +#include <stdio.h>\r
4396 +#include <stdlib.h>\r
4397 +#include <string.h>\r
4398 +\r
4399 +#include "xalloc.h"\r
4400 +\r
4401 +\r
4402 +/* ISDIGIT differs from isdigit, as follows:\r
4403 +   - Its arg may be any int or unsigned int; it need not be an unsigned char\r
4404 +     or EOF.\r
4405 +   - It's typically faster.\r
4406 +   POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to\r
4407 +   isdigit unless it's important to use the locale's definition\r
4408 +   of `digit' even when the host does not conform to POSIX.  */\r
4409 +#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)\r
4410 +\r
4411 +/* Shift A right by B bits portably, by dividing A by 2**B and\r
4412 +   truncating towards minus infinity.  A and B should be free of side\r
4413 +   effects, and B should be in the range 0 <= B <= INT_BITS - 2, where\r
4414 +   INT_BITS is the number of useful bits in an int.  GNU code can\r
4415 +   assume that INT_BITS is at least 32.\r
4416 +\r
4417 +   ISO C99 says that A >> B is implementation-defined if A < 0.  Some\r
4418 +   implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift\r
4419 +   right in the usual way when A < 0, so SHR falls back on division if\r
4420 +   ordinary A >> B doesn't seem to be the usual signed shift.  */\r
4421 +#define SHR(a, b)       \\r
4422 +  (-1 >> 1 == -1        \\r
4423 +   ? (a) >> (b)         \\r
4424 +   : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))\r
4425 +\r
4426 +#define EPOCH_YEAR 1970\r
4427 +#define TM_YEAR_BASE 1900\r
4428 +\r
4429 +#define HOUR(x) ((x) * 60)\r
4430 +\r
4431 +/* long_time_t is a signed integer type that contains all time_t values.  */\r
4432 +verify (TYPE_IS_INTEGER (time_t));\r
4433 +#if TIME_T_FITS_IN_LONG_INT\r
4434 +typedef long int long_time_t;\r
4435 +#else\r
4436 +typedef time_t long_time_t;\r
4437 +#endif\r
4438 +\r
4439 +/* Lots of this code assumes time_t and time_t-like values fit into\r
4440 +   long_time_t.  */\r
4441 +verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t)\r
4442 +        && TYPE_MAXIMUM (time_t) <= TYPE_MAXIMUM (long_time_t));\r
4443 +\r
4444 +/* FIXME: It also assumes that signed integer overflow silently wraps around,\r
4445 +   but this is not true any more with recent versions of GCC 4.  */\r
4446 +\r
4447 +/* An integer value, and the number of digits in its textual\r
4448 +   representation.  */\r
4449 +typedef struct\r
4450 +{\r
4451 +  bool negative;\r
4452 +  long int value;\r
4453 +  size_t digits;\r
4454 +} textint;\r
4455 +\r
4456 +/* An entry in the lexical lookup table.  */\r
4457 +typedef struct\r
4458 +{\r
4459 +  char const *name;\r
4460 +  int type;\r
4461 +  int value;\r
4462 +} table;\r
4463 +\r
4464 +/* Meridian: am, pm, or 24-hour style.  */\r
4465 +enum { MERam, MERpm, MER24 };\r
4466 +\r
4467 +enum { BILLION = 1000000000, LOG10_BILLION = 9 };\r
4468 +\r
4469 +/* Relative times.  */\r
4470 +typedef struct\r
4471 +{\r
4472 +  /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */\r
4473 +  long int year;\r
4474 +  long int month;\r
4475 +  long int day;\r
4476 +  long int hour;\r
4477 +  long int minutes;\r
4478 +  long_time_t seconds;\r
4479 +  long int ns;\r
4480 +} relative_time;\r
4481 +\r
4482 +#if HAVE_COMPOUND_LITERALS\r
4483 +# define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 })\r
4484 +#else\r
4485 +static relative_time const RELATIVE_TIME_0;\r
4486 +#endif\r
4487 +\r
4488 +/* Information passed to and from the parser.  */\r
4489 +typedef struct\r
4490 +{\r
4491 +  /* The input string remaining to be parsed. */\r
4492 +  const char *input;\r
4493 +\r
4494 +  /* N, if this is the Nth Tuesday.  */\r
4495 +  long int day_ordinal;\r
4496 +\r
4497 +  /* Day of week; Sunday is 0.  */\r
4498 +  int day_number;\r
4499 +\r
4500 +  /* tm_isdst flag for the local zone.  */\r
4501 +  int local_isdst;\r
4502 +\r
4503 +  /* Time zone, in minutes east of UTC.  */\r
4504 +  long int time_zone;\r
4505 +\r
4506 +  /* Style used for time.  */\r
4507 +  int meridian;\r
4508 +\r
4509 +  /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds.  */\r
4510 +  textint year;\r
4511 +  long int month;\r
4512 +  long int day;\r
4513 +  long int hour;\r
4514 +  long int minutes;\r
4515 +  struct timespec seconds; /* includes nanoseconds */\r
4516 +\r
4517 +  /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */\r
4518 +  relative_time rel;\r
4519 +\r
4520 +  /* Presence or counts of nonterminals of various flavors parsed so far.  */\r
4521 +  bool timespec_seen;\r
4522 +  bool rels_seen;\r
4523 +  size_t dates_seen;\r
4524 +  size_t days_seen;\r
4525 +  size_t local_zones_seen;\r
4526 +  size_t dsts_seen;\r
4527 +  size_t times_seen;\r
4528 +  size_t zones_seen;\r
4529 +\r
4530 +  /* Table of local time zone abbrevations, terminated by a null entry.  */\r
4531 +  table local_time_zone_table[3];\r
4532 +} parser_control;\r
4533 +\r
4534 +union YYSTYPE;\r
4535 +static int yylex (union YYSTYPE *, parser_control *);\r
4536 +static int yyerror (parser_control const *, char const *);\r
4537 +static long int time_zone_hhmm (parser_control *, textint, long int);\r
4538 +\r
4539 +/* Extract into *PC any date and time info from a string of digits\r
4540 +   of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,\r
4541 +   YYYY, ...).  */\r
4542 +static void\r
4543 +digits_to_date_time (parser_control *pc, textint text_int)\r
4544 +{\r
4545 +  if (pc->dates_seen && ! pc->year.digits\r
4546 +      && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))\r
4547 +    pc->year = text_int;\r
4548 +  else\r
4549 +    {\r
4550 +      if (4 < text_int.digits)\r
4551 +        {\r
4552 +          pc->dates_seen++;\r
4553 +          pc->day = text_int.value % 100;\r
4554 +          pc->month = (text_int.value / 100) % 100;\r
4555 +          pc->year.value = text_int.value / 10000;\r
4556 +          pc->year.digits = text_int.digits - 4;\r
4557 +        }\r
4558 +      else\r
4559 +        {\r
4560 +          pc->times_seen++;\r
4561 +          if (text_int.digits <= 2)\r
4562 +            {\r
4563 +              pc->hour = text_int.value;\r
4564 +              pc->minutes = 0;\r
4565 +            }\r
4566 +          else\r
4567 +            {\r
4568 +              pc->hour = text_int.value / 100;\r
4569 +              pc->minutes = text_int.value % 100;\r
4570 +            }\r
4571 +          pc->seconds.tv_sec = 0;\r
4572 +          pc->seconds.tv_nsec = 0;\r
4573 +          pc->meridian = MER24;\r
4574 +        }\r
4575 +    }\r
4576 +}\r
4577 +\r
4578 +/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1).  */\r
4579 +static void\r
4580 +apply_relative_time (parser_control *pc, relative_time rel, int factor)\r
4581 +{\r
4582 +  pc->rel.ns += factor * rel.ns;\r
4583 +  pc->rel.seconds += factor * rel.seconds;\r
4584 +  pc->rel.minutes += factor * rel.minutes;\r
4585 +  pc->rel.hour += factor * rel.hour;\r
4586 +  pc->rel.day += factor * rel.day;\r
4587 +  pc->rel.month += factor * rel.month;\r
4588 +  pc->rel.year += factor * rel.year;\r
4589 +  pc->rels_seen = true;\r
4590 +}\r
4591 +\r
4592 +/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments.  */\r
4593 +static void\r
4594 +set_hhmmss (parser_control *pc, long int hour, long int minutes,\r
4595 +            time_t sec, long int nsec)\r
4596 +{\r
4597 +  pc->hour = hour;\r
4598 +  pc->minutes = minutes;\r
4599 +  pc->seconds.tv_sec = sec;\r
4600 +  pc->seconds.tv_nsec = nsec;\r
4601 +}\r
4602 +\r
4603 +%}\r
4604 +\r
4605 +/* We want a reentrant parser, even if the TZ manipulation and the calls to\r
4606 +   localtime and gmtime are not reentrant.  */\r
4607 +%pure-parser\r
4608 +%parse-param { parser_control *pc }\r
4609 +%lex-param { parser_control *pc }\r
4610 +\r
4611 +/* This grammar has 20 shift/reduce conflicts. */\r
4612 +%expect 20\r
4613 +\r
4614 +%union\r
4615 +{\r
4616 +  long int intval;\r
4617 +  textint textintval;\r
4618 +  struct timespec timespec;\r
4619 +  relative_time rel;\r
4620 +}\r
4621 +\r
4622 +%token tAGO tDST\r
4623 +\r
4624 +%token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT\r
4625 +%token <intval> tDAY_UNIT tDAY_SHIFT\r
4626 +\r
4627 +%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN\r
4628 +%token <intval> tMONTH tORDINAL tZONE\r
4629 +\r
4630 +%token <textintval> tSNUMBER tUNUMBER\r
4631 +%token <timespec> tSDECIMAL_NUMBER tUDECIMAL_NUMBER\r
4632 +\r
4633 +%type <intval> o_colon_minutes o_merid\r
4634 +%type <timespec> seconds signed_seconds unsigned_seconds\r
4635 +\r
4636 +%type <rel> relunit relunit_snumber dayshift\r
4637 +\r
4638 +%%\r
4639 +\r
4640 +spec:\r
4641 +    timespec\r
4642 +  | items\r
4643 +  ;\r
4644 +\r
4645 +timespec:\r
4646 +    '@' seconds\r
4647 +      {\r
4648 +        pc->seconds = $2;\r
4649 +        pc->timespec_seen = true;\r
4650 +      }\r
4651 +  ;\r
4652 +\r
4653 +items:\r
4654 +    /* empty */\r
4655 +  | items item\r
4656 +  ;\r
4657 +\r
4658 +item:\r
4659 +    time\r
4660 +      { pc->times_seen++; }\r
4661 +  | local_zone\r
4662 +      { pc->local_zones_seen++; }\r
4663 +  | zone\r
4664 +      { pc->zones_seen++; }\r
4665 +  | date\r
4666 +      { pc->dates_seen++; }\r
4667 +  | day\r
4668 +      { pc->days_seen++; }\r
4669 +  | rel\r
4670 +  | number\r
4671 +  | hybrid\r
4672 +  ;\r
4673 +\r
4674 +time:\r
4675 +    tUNUMBER tMERIDIAN\r
4676 +      {\r
4677 +        set_hhmmss (pc, $1.value, 0, 0, 0);\r
4678 +        pc->meridian = $2;\r
4679 +      }\r
4680 +  | tUNUMBER ':' tUNUMBER o_merid\r
4681 +      {\r
4682 +        set_hhmmss (pc, $1.value, $3.value, 0, 0);\r
4683 +        pc->meridian = $4;\r
4684 +      }\r
4685 +  | tUNUMBER ':' tUNUMBER tSNUMBER o_colon_minutes\r
4686 +      {\r
4687 +        set_hhmmss (pc, $1.value, $3.value, 0, 0);\r
4688 +        pc->meridian = MER24;\r
4689 +        pc->zones_seen++;\r
4690 +        pc->time_zone = time_zone_hhmm (pc, $4, $5);\r
4691 +      }\r
4692 +  | tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid\r
4693 +      {\r
4694 +        set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);\r
4695 +        pc->meridian = $6;\r
4696 +      }\r
4697 +  | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tSNUMBER o_colon_minutes\r
4698 +      {\r
4699 +        set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);\r
4700 +        pc->meridian = MER24;\r
4701 +        pc->zones_seen++;\r
4702 +        pc->time_zone = time_zone_hhmm (pc, $6, $7);\r
4703 +      }\r
4704 +  ;\r
4705 +\r
4706 +local_zone:\r
4707 +    tLOCAL_ZONE\r
4708 +      {\r
4709 +        pc->local_isdst = $1;\r
4710 +        pc->dsts_seen += (0 < $1);\r
4711 +      }\r
4712 +  | tLOCAL_ZONE tDST\r
4713 +      {\r
4714 +        pc->local_isdst = 1;\r
4715 +        pc->dsts_seen += (0 < $1) + 1;\r
4716 +      }\r
4717 +  ;\r
4718 +\r
4719 +zone:\r
4720 +    tZONE\r
4721 +      { pc->time_zone = $1; }\r
4722 +  | tZONE relunit_snumber\r
4723 +      { pc->time_zone = $1;\r
4724 +        apply_relative_time (pc, $2, 1); }\r
4725 +  | tZONE tSNUMBER o_colon_minutes\r
4726 +      { pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3); }\r
4727 +  | tDAYZONE\r
4728 +      { pc->time_zone = $1 + 60; }\r
4729 +  | tZONE tDST\r
4730 +      { pc->time_zone = $1 + 60; }\r
4731 +  ;\r
4732 +\r
4733 +day:\r
4734 +    tDAY\r
4735 +      {\r
4736 +        pc->day_ordinal = 0;\r
4737 +        pc->day_number = $1;\r
4738 +      }\r
4739 +  | tDAY ','\r
4740 +      {\r
4741 +        pc->day_ordinal = 0;\r
4742 +        pc->day_number = $1;\r
4743 +      }\r
4744 +  | tORDINAL tDAY\r
4745 +      {\r
4746 +        pc->day_ordinal = $1;\r
4747 +        pc->day_number = $2;\r
4748 +      }\r
4749 +  | tUNUMBER tDAY\r
4750 +      {\r
4751 +        pc->day_ordinal = $1.value;\r
4752 +        pc->day_number = $2;\r
4753 +      }\r
4754 +  ;\r
4755 +\r
4756 +date:\r
4757 +    tUNUMBER '/' tUNUMBER\r
4758 +      {\r
4759 +        pc->month = $1.value;\r
4760 +        pc->day = $3.value;\r
4761 +      }\r
4762 +  | tUNUMBER '/' tUNUMBER '/' tUNUMBER\r
4763 +      {\r
4764 +        /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,\r
4765 +           otherwise as MM/DD/YY.\r
4766 +           The goal in recognizing YYYY/MM/DD is solely to support legacy\r
4767 +           machine-generated dates like those in an RCS log listing.  If\r
4768 +           you want portability, use the ISO 8601 format.  */\r
4769 +        if (4 <= $1.digits)\r
4770 +          {\r
4771 +            pc->year = $1;\r
4772 +            pc->month = $3.value;\r
4773 +            pc->day = $5.value;\r
4774 +          }\r
4775 +        else\r
4776 +          {\r
4777 +            pc->month = $1.value;\r
4778 +            pc->day = $3.value;\r
4779 +            pc->year = $5;\r
4780 +          }\r
4781 +      }\r
4782 +  | tUNUMBER tSNUMBER tSNUMBER\r
4783 +      {\r
4784 +        /* ISO 8601 format.  YYYY-MM-DD.  */\r
4785 +        pc->year = $1;\r
4786 +        pc->month = -$2.value;\r
4787 +        pc->day = -$3.value;\r
4788 +      }\r
4789 +  | tUNUMBER tMONTH tSNUMBER\r
4790 +      {\r
4791 +        /* e.g. 17-JUN-1992.  */\r
4792 +        pc->day = $1.value;\r
4793 +        pc->month = $2;\r
4794 +        pc->year.value = -$3.value;\r
4795 +        pc->year.digits = $3.digits;\r
4796 +      }\r
4797 +  | tMONTH tSNUMBER tSNUMBER\r
4798 +      {\r
4799 +        /* e.g. JUN-17-1992.  */\r
4800 +        pc->month = $1;\r
4801 +        pc->day = -$2.value;\r
4802 +        pc->year.value = -$3.value;\r
4803 +        pc->year.digits = $3.digits;\r
4804 +      }\r
4805 +  | tMONTH tUNUMBER\r
4806 +      {\r
4807 +        pc->month = $1;\r
4808 +        pc->day = $2.value;\r
4809 +      }\r
4810 +  | tMONTH tUNUMBER ',' tUNUMBER\r
4811 +      {\r
4812 +        pc->month = $1;\r
4813 +        pc->day = $2.value;\r
4814 +        pc->year = $4;\r
4815 +      }\r
4816 +  | tUNUMBER tMONTH\r
4817 +      {\r
4818 +        pc->day = $1.value;\r
4819 +        pc->month = $2;\r
4820 +      }\r
4821 +  | tUNUMBER tMONTH tUNUMBER\r
4822 +      {\r
4823 +        pc->day = $1.value;\r
4824 +        pc->month = $2;\r
4825 +        pc->year = $3;\r
4826 +      }\r
4827 +  ;\r
4828 +\r
4829 +rel:\r
4830 +    relunit tAGO\r
4831 +      { apply_relative_time (pc, $1, -1); }\r
4832 +  | relunit\r
4833 +      { apply_relative_time (pc, $1, 1); }\r
4834 +  | dayshift\r
4835 +      { apply_relative_time (pc, $1, 1); }\r
4836 +  ;\r
4837 +\r
4838 +relunit:\r
4839 +    tORDINAL tYEAR_UNIT\r
4840 +      { $$ = RELATIVE_TIME_0; $$.year = $1; }\r
4841 +  | tUNUMBER tYEAR_UNIT\r
4842 +      { $$ = RELATIVE_TIME_0; $$.year = $1.value; }\r
4843 +  | tYEAR_UNIT\r
4844 +      { $$ = RELATIVE_TIME_0; $$.year = 1; }\r
4845 +  | tORDINAL tMONTH_UNIT\r
4846 +      { $$ = RELATIVE_TIME_0; $$.month = $1; }\r
4847 +  | tUNUMBER tMONTH_UNIT\r
4848 +      { $$ = RELATIVE_TIME_0; $$.month = $1.value; }\r
4849 +  | tMONTH_UNIT\r
4850 +      { $$ = RELATIVE_TIME_0; $$.month = 1; }\r
4851 +  | tORDINAL tDAY_UNIT\r
4852 +      { $$ = RELATIVE_TIME_0; $$.day = $1 * $2; }\r
4853 +  | tUNUMBER tDAY_UNIT\r
4854 +      { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; }\r
4855 +  | tDAY_UNIT\r
4856 +      { $$ = RELATIVE_TIME_0; $$.day = $1; }\r
4857 +  | tORDINAL tHOUR_UNIT\r
4858 +      { $$ = RELATIVE_TIME_0; $$.hour = $1; }\r
4859 +  | tUNUMBER tHOUR_UNIT\r
4860 +      { $$ = RELATIVE_TIME_0; $$.hour = $1.value; }\r
4861 +  | tHOUR_UNIT\r
4862 +      { $$ = RELATIVE_TIME_0; $$.hour = 1; }\r
4863 +  | tORDINAL tMINUTE_UNIT\r
4864 +      { $$ = RELATIVE_TIME_0; $$.minutes = $1; }\r
4865 +  | tUNUMBER tMINUTE_UNIT\r
4866 +      { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; }\r
4867 +  | tMINUTE_UNIT\r
4868 +      { $$ = RELATIVE_TIME_0; $$.minutes = 1; }\r
4869 +  | tORDINAL tSEC_UNIT\r
4870 +      { $$ = RELATIVE_TIME_0; $$.seconds = $1; }\r
4871 +  | tUNUMBER tSEC_UNIT\r
4872 +      { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; }\r
4873 +  | tSDECIMAL_NUMBER tSEC_UNIT\r
4874 +      { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; }\r
4875 +  | tUDECIMAL_NUMBER tSEC_UNIT\r
4876 +      { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; }\r
4877 +  | tSEC_UNIT\r
4878 +      { $$ = RELATIVE_TIME_0; $$.seconds = 1; }\r
4879 +  | relunit_snumber\r
4880 +  ;\r
4881 +\r
4882 +relunit_snumber:\r
4883 +    tSNUMBER tYEAR_UNIT\r
4884 +      { $$ = RELATIVE_TIME_0; $$.year = $1.value; }\r
4885 +  | tSNUMBER tMONTH_UNIT\r
4886 +      { $$ = RELATIVE_TIME_0; $$.month = $1.value; }\r
4887 +  | tSNUMBER tDAY_UNIT\r
4888 +      { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; }\r
4889 +  | tSNUMBER tHOUR_UNIT\r
4890 +      { $$ = RELATIVE_TIME_0; $$.hour = $1.value; }\r
4891 +  | tSNUMBER tMINUTE_UNIT\r
4892 +      { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; }\r
4893 +  | tSNUMBER tSEC_UNIT\r
4894 +      { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; }\r
4895 +  ;\r
4896 +\r
4897 +dayshift:\r
4898 +    tDAY_SHIFT\r
4899 +      { $$ = RELATIVE_TIME_0; $$.day = $1; }\r
4900 +  ;\r
4901 +\r
4902 +seconds: signed_seconds | unsigned_seconds;\r
4903 +\r
4904 +signed_seconds:\r
4905 +    tSDECIMAL_NUMBER\r
4906 +  | tSNUMBER\r
4907 +      { $$.tv_sec = $1.value; $$.tv_nsec = 0; }\r
4908 +  ;\r
4909 +\r
4910 +unsigned_seconds:\r
4911 +    tUDECIMAL_NUMBER\r
4912 +  | tUNUMBER\r
4913 +      { $$.tv_sec = $1.value; $$.tv_nsec = 0; }\r
4914 +  ;\r
4915 +\r
4916 +number:\r
4917 +    tUNUMBER\r
4918 +      { digits_to_date_time (pc, $1); }\r
4919 +  ;\r
4920 +\r
4921 +hybrid:\r
4922 +    tUNUMBER relunit_snumber\r
4923 +      {\r
4924 +        /* Hybrid all-digit and relative offset, so that we accept e.g.,\r
4925 +           "YYYYMMDD +N days" as well as "YYYYMMDD N days".  */\r
4926 +        digits_to_date_time (pc, $1);\r
4927 +        apply_relative_time (pc, $2, 1);\r
4928 +      }\r
4929 +  ;\r
4930 +\r
4931 +o_colon_minutes:\r
4932 +    /* empty */\r
4933 +      { $$ = -1; }\r
4934 +  | ':' tUNUMBER\r
4935 +      { $$ = $2.value; }\r
4936 +  ;\r
4937 +\r
4938 +o_merid:\r
4939 +    /* empty */\r
4940 +      { $$ = MER24; }\r
4941 +  | tMERIDIAN\r
4942 +      { $$ = $1; }\r
4943 +  ;\r
4944 +\r
4945 +%%\r
4946 +\r
4947 +static table const meridian_table[] =\r
4948 +{\r
4949 +  { "AM",   tMERIDIAN, MERam },\r
4950 +  { "A.M.", tMERIDIAN, MERam },\r
4951 +  { "PM",   tMERIDIAN, MERpm },\r
4952 +  { "P.M.", tMERIDIAN, MERpm },\r
4953 +  { NULL, 0, 0 }\r
4954 +};\r
4955 +\r
4956 +static table const dst_table[] =\r
4957 +{\r
4958 +  { "DST", tDST, 0 }\r
4959 +};\r
4960 +\r
4961 +static table const month_and_day_table[] =\r
4962 +{\r
4963 +  { "JANUARY",  tMONTH,  1 },\r
4964 +  { "FEBRUARY", tMONTH,  2 },\r
4965 +  { "MARCH",    tMONTH,  3 },\r
4966 +  { "APRIL",    tMONTH,  4 },\r
4967 +  { "MAY",      tMONTH,  5 },\r
4968 +  { "JUNE",     tMONTH,  6 },\r
4969 +  { "JULY",     tMONTH,  7 },\r
4970 +  { "AUGUST",   tMONTH,  8 },\r
4971 +  { "SEPTEMBER",tMONTH,  9 },\r
4972 +  { "SEPT",     tMONTH,  9 },\r
4973 +  { "OCTOBER",  tMONTH, 10 },\r
4974 +  { "NOVEMBER", tMONTH, 11 },\r
4975 +  { "DECEMBER", tMONTH, 12 },\r
4976 +  { "SUNDAY",   tDAY,    0 },\r
4977 +  { "MONDAY",   tDAY,    1 },\r
4978 +  { "TUESDAY",  tDAY,    2 },\r
4979 +  { "TUES",     tDAY,    2 },\r
4980 +  { "WEDNESDAY",tDAY,    3 },\r
4981 +  { "WEDNES",   tDAY,    3 },\r
4982 +  { "THURSDAY", tDAY,    4 },\r
4983 +  { "THUR",     tDAY,    4 },\r
4984 +  { "THURS",    tDAY,    4 },\r
4985 +  { "FRIDAY",   tDAY,    5 },\r
4986 +  { "SATURDAY", tDAY,    6 },\r
4987 +  { NULL, 0, 0 }\r
4988 +};\r
4989 +\r
4990 +static table const time_units_table[] =\r
4991 +{\r
4992 +  { "YEAR",     tYEAR_UNIT,      1 },\r
4993 +  { "MONTH",    tMONTH_UNIT,     1 },\r
4994 +  { "FORTNIGHT",tDAY_UNIT,      14 },\r
4995 +  { "WEEK",     tDAY_UNIT,       7 },\r
4996 +  { "DAY",      tDAY_UNIT,       1 },\r
4997 +  { "HOUR",     tHOUR_UNIT,      1 },\r
4998 +  { "MINUTE",   tMINUTE_UNIT,    1 },\r
4999 +  { "MIN",      tMINUTE_UNIT,    1 },\r
5000 +  { "SECOND",   tSEC_UNIT,       1 },\r
5001 +  { "SEC",      tSEC_UNIT,       1 },\r
5002 +  { NULL, 0, 0 }\r
5003 +};\r
5004 +\r
5005 +/* Assorted relative-time words. */\r
5006 +static table const relative_time_table[] =\r
5007 +{\r
5008 +  { "TOMORROW", tDAY_SHIFT,      1 },\r
5009 +  { "YESTERDAY",tDAY_SHIFT,     -1 },\r
5010 +  { "TODAY",    tDAY_SHIFT,      0 },\r
5011 +  { "NOW",      tDAY_SHIFT,      0 },\r
5012 +  { "LAST",     tORDINAL,       -1 },\r
5013 +  { "THIS",     tORDINAL,        0 },\r
5014 +  { "NEXT",     tORDINAL,        1 },\r
5015 +  { "FIRST",    tORDINAL,        1 },\r
5016 +/*{ "SECOND",   tORDINAL,        2 }, */\r
5017 +  { "THIRD",    tORDINAL,        3 },\r
5018 +  { "FOURTH",   tORDINAL,        4 },\r
5019 +  { "FIFTH",    tORDINAL,        5 },\r
5020 +  { "SIXTH",    tORDINAL,        6 },\r
5021 +  { "SEVENTH",  tORDINAL,        7 },\r
5022 +  { "EIGHTH",   tORDINAL,        8 },\r
5023 +  { "NINTH",    tORDINAL,        9 },\r
5024 +  { "TENTH",    tORDINAL,       10 },\r
5025 +  { "ELEVENTH", tORDINAL,       11 },\r
5026 +  { "TWELFTH",  tORDINAL,       12 },\r
5027 +  { "AGO",      tAGO,            1 },\r
5028 +  { NULL, 0, 0 }\r
5029 +};\r
5030 +\r
5031 +/* The universal time zone table.  These labels can be used even for\r
5032 +   time stamps that would not otherwise be valid, e.g., GMT time\r
5033 +   stamps in London during summer.  */\r
5034 +static table const universal_time_zone_table[] =\r
5035 +{\r
5036 +  { "GMT",      tZONE,     HOUR ( 0) }, /* Greenwich Mean */\r
5037 +  { "UT",       tZONE,     HOUR ( 0) }, /* Universal (Coordinated) */\r
5038 +  { "UTC",      tZONE,     HOUR ( 0) },\r
5039 +  { NULL, 0, 0 }\r
5040 +};\r
5041 +\r
5042 +/* The time zone table.  This table is necessarily incomplete, as time\r
5043 +   zone abbreviations are ambiguous; e.g. Australians interpret "EST"\r
5044 +   as Eastern time in Australia, not as US Eastern Standard Time.\r
5045 +   You cannot rely on getdate to handle arbitrary time zone\r
5046 +   abbreviations; use numeric abbreviations like `-0500' instead.  */\r
5047 +static table const time_zone_table[] =\r
5048 +{\r
5049 +  { "WET",      tZONE,     HOUR ( 0) }, /* Western European */\r
5050 +  { "WEST",     tDAYZONE,  HOUR ( 0) }, /* Western European Summer */\r
5051 +  { "BST",      tDAYZONE,  HOUR ( 0) }, /* British Summer */\r
5052 +  { "ART",      tZONE,    -HOUR ( 3) }, /* Argentina */\r
5053 +  { "BRT",      tZONE,    -HOUR ( 3) }, /* Brazil */\r
5054 +  { "BRST",     tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */\r
5055 +  { "NST",      tZONE,   -(HOUR ( 3) + 30) },   /* Newfoundland Standard */\r
5056 +  { "NDT",      tDAYZONE,-(HOUR ( 3) + 30) },   /* Newfoundland Daylight */\r
5057 +  { "AST",      tZONE,    -HOUR ( 4) }, /* Atlantic Standard */\r
5058 +  { "ADT",      tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */\r
5059 +  { "CLT",      tZONE,    -HOUR ( 4) }, /* Chile */\r
5060 +  { "CLST",     tDAYZONE, -HOUR ( 4) }, /* Chile Summer */\r
5061 +  { "EST",      tZONE,    -HOUR ( 5) }, /* Eastern Standard */\r
5062 +  { "EDT",      tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */\r
5063 +  { "CST",      tZONE,    -HOUR ( 6) }, /* Central Standard */\r
5064 +  { "CDT",      tDAYZONE, -HOUR ( 6) }, /* Central Daylight */\r
5065 +  { "MST",      tZONE,    -HOUR ( 7) }, /* Mountain Standard */\r
5066 +  { "MDT",      tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */\r
5067 +  { "PST",      tZONE,    -HOUR ( 8) }, /* Pacific Standard */\r
5068 +  { "PDT",      tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */\r
5069 +  { "AKST",     tZONE,    -HOUR ( 9) }, /* Alaska Standard */\r
5070 +  { "AKDT",     tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */\r
5071 +  { "HST",      tZONE,    -HOUR (10) }, /* Hawaii Standard */\r
5072 +  { "HAST",     tZONE,    -HOUR (10) }, /* Hawaii-Aleutian Standard */\r
5073 +  { "HADT",     tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */\r
5074 +  { "SST",      tZONE,    -HOUR (12) }, /* Samoa Standard */\r
5075 +  { "WAT",      tZONE,     HOUR ( 1) }, /* West Africa */\r
5076 +  { "CET",      tZONE,     HOUR ( 1) }, /* Central European */\r
5077 +  { "CEST",     tDAYZONE,  HOUR ( 1) }, /* Central European Summer */\r
5078 +  { "MET",      tZONE,     HOUR ( 1) }, /* Middle European */\r
5079 +  { "MEZ",      tZONE,     HOUR ( 1) }, /* Middle European */\r
5080 +  { "MEST",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */\r
5081 +  { "MESZ",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */\r
5082 +  { "EET",      tZONE,     HOUR ( 2) }, /* Eastern European */\r
5083 +  { "EEST",     tDAYZONE,  HOUR ( 2) }, /* Eastern European Summer */\r
5084 +  { "CAT",      tZONE,     HOUR ( 2) }, /* Central Africa */\r
5085 +  { "SAST",     tZONE,     HOUR ( 2) }, /* South Africa Standard */\r
5086 +  { "EAT",      tZONE,     HOUR ( 3) }, /* East Africa */\r
5087 +  { "MSK",      tZONE,     HOUR ( 3) }, /* Moscow */\r
5088 +  { "MSD",      tDAYZONE,  HOUR ( 3) }, /* Moscow Daylight */\r
5089 +  { "IST",      tZONE,    (HOUR ( 5) + 30) },   /* India Standard */\r
5090 +  { "SGT",      tZONE,     HOUR ( 8) }, /* Singapore */\r
5091 +  { "KST",      tZONE,     HOUR ( 9) }, /* Korea Standard */\r
5092 +  { "JST",      tZONE,     HOUR ( 9) }, /* Japan Standard */\r
5093 +  { "GST",      tZONE,     HOUR (10) }, /* Guam Standard */\r
5094 +  { "NZST",     tZONE,     HOUR (12) }, /* New Zealand Standard */\r
5095 +  { "NZDT",     tDAYZONE,  HOUR (12) }, /* New Zealand Daylight */\r
5096 +  { NULL, 0, 0 }\r
5097 +};\r
5098 +\r
5099 +/* Military time zone table. */\r
5100 +static table const military_table[] =\r
5101 +{\r
5102 +  { "A", tZONE, -HOUR ( 1) },\r
5103 +  { "B", tZONE, -HOUR ( 2) },\r
5104 +  { "C", tZONE, -HOUR ( 3) },\r
5105 +  { "D", tZONE, -HOUR ( 4) },\r
5106 +  { "E", tZONE, -HOUR ( 5) },\r
5107 +  { "F", tZONE, -HOUR ( 6) },\r
5108 +  { "G", tZONE, -HOUR ( 7) },\r
5109 +  { "H", tZONE, -HOUR ( 8) },\r
5110 +  { "I", tZONE, -HOUR ( 9) },\r
5111 +  { "K", tZONE, -HOUR (10) },\r
5112 +  { "L", tZONE, -HOUR (11) },\r
5113 +  { "M", tZONE, -HOUR (12) },\r
5114 +  { "N", tZONE,  HOUR ( 1) },\r
5115 +  { "O", tZONE,  HOUR ( 2) },\r
5116 +  { "P", tZONE,  HOUR ( 3) },\r
5117 +  { "Q", tZONE,  HOUR ( 4) },\r
5118 +  { "R", tZONE,  HOUR ( 5) },\r
5119 +  { "S", tZONE,  HOUR ( 6) },\r
5120 +  { "T", tZONE,  HOUR ( 7) },\r
5121 +  { "U", tZONE,  HOUR ( 8) },\r
5122 +  { "V", tZONE,  HOUR ( 9) },\r
5123 +  { "W", tZONE,  HOUR (10) },\r
5124 +  { "X", tZONE,  HOUR (11) },\r
5125 +  { "Y", tZONE,  HOUR (12) },\r
5126 +  { "Z", tZONE,  HOUR ( 0) },\r
5127 +  { NULL, 0, 0 }\r
5128 +};\r
5129 +\r
5130 +\f\r
5131 \r
5132 +\r
5133 +/* Convert a time zone expressed as HH:MM into an integer count of\r
5134 +   minutes.  If MM is negative, then S is of the form HHMM and needs\r
5135 +   to be picked apart; otherwise, S is of the form HH.  As specified in\r
5136 +   http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow\r
5137 +   only valid TZ range, and consider first two digits as hours, if no\r
5138 +   minutes specified.  */\r
5139 +\r
5140 +static long int\r
5141 +time_zone_hhmm (parser_control *pc, textint s, long int mm)\r
5142 +{\r
5143 +  long int n_minutes;\r
5144 +\r
5145 +  /* If the length of S is 1 or 2 and no minutes are specified,\r
5146 +     interpret it as a number of hours.  */\r
5147 +  if (s.digits <= 2 && mm < 0)\r
5148 +    s.value *= 100;\r
5149 +\r
5150 +  if (mm < 0)\r
5151 +    n_minutes = (s.value / 100) * 60 + s.value % 100;\r
5152 +  else\r
5153 +    n_minutes = s.value * 60 + (s.negative ? -mm : mm);\r
5154 +\r
5155 +  /* If the absolute number of minutes is larger than 24 hours,\r
5156 +     arrange to reject it by incrementing pc->zones_seen.  Thus,\r
5157 +     we allow only values in the range UTC-24:00 to UTC+24:00.  */\r
5158 +  if (24 * 60 < abs (n_minutes))\r
5159 +    pc->zones_seen++;\r
5160 +\r
5161 +  return n_minutes;\r
5162 +}\r
5163 +\r
5164 +static int\r
5165 +to_hour (long int hours, int meridian)\r
5166 +{\r
5167 +  switch (meridian)\r
5168 +    {\r
5169 +    default: /* Pacify GCC.  */\r
5170 +    case MER24:\r
5171 +      return 0 <= hours && hours < 24 ? hours : -1;\r
5172 +    case MERam:\r
5173 +      return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;\r
5174 +    case MERpm:\r
5175 +      return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;\r
5176 +    }\r
5177 +}\r
5178 +\r
5179 +static long int\r
5180 +to_year (textint textyear)\r
5181 +{\r
5182 +  long int year = textyear.value;\r
5183 +\r
5184 +  if (year < 0)\r
5185 +    year = -year;\r
5186 +\r
5187 +  /* XPG4 suggests that years 00-68 map to 2000-2068, and\r
5188 +     years 69-99 map to 1969-1999.  */\r
5189 +  else if (textyear.digits == 2)\r
5190 +    year += year < 69 ? 2000 : 1900;\r
5191 +\r
5192 +  return year;\r
5193 +}\r
5194 +\r
5195 +static table const *\r
5196 +lookup_zone (parser_control const *pc, char const *name)\r
5197 +{\r
5198 +  table const *tp;\r
5199 +\r
5200 +  for (tp = universal_time_zone_table; tp->name; tp++)\r
5201 +    if (strcmp (name, tp->name) == 0)\r
5202 +      return tp;\r
5203 +\r
5204 +  /* Try local zone abbreviations before those in time_zone_table, as\r
5205 +     the local ones are more likely to be right.  */\r
5206 +  for (tp = pc->local_time_zone_table; tp->name; tp++)\r
5207 +    if (strcmp (name, tp->name) == 0)\r
5208 +      return tp;\r
5209 +\r
5210 +  for (tp = time_zone_table; tp->name; tp++)\r
5211 +    if (strcmp (name, tp->name) == 0)\r
5212 +      return tp;\r
5213 +\r
5214 +  return NULL;\r
5215 +}\r
5216 +\r
5217 +#if ! HAVE_TM_GMTOFF\r
5218 +/* Yield the difference between *A and *B,\r
5219 +   measured in seconds, ignoring leap seconds.\r
5220 +   The body of this function is taken directly from the GNU C Library;\r
5221 +   see src/strftime.c.  */\r
5222 +static long int\r
5223 +tm_diff (struct tm const *a, struct tm const *b)\r
5224 +{\r
5225 +  /* Compute intervening leap days correctly even if year is negative.\r
5226 +     Take care to avoid int overflow in leap day calculations.  */\r
5227 +  int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);\r
5228 +  int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);\r
5229 +  int a100 = a4 / 25 - (a4 % 25 < 0);\r
5230 +  int b100 = b4 / 25 - (b4 % 25 < 0);\r
5231 +  int a400 = SHR (a100, 2);\r
5232 +  int b400 = SHR (b100, 2);\r
5233 +  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);\r
5234 +  long int ayear = a->tm_year;\r
5235 +  long int years = ayear - b->tm_year;\r
5236 +  long int days = (365 * years + intervening_leap_days\r
5237 +                   + (a->tm_yday - b->tm_yday));\r
5238 +  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))\r
5239 +                + (a->tm_min - b->tm_min))\r
5240 +          + (a->tm_sec - b->tm_sec));\r
5241 +}\r
5242 +#endif /* ! HAVE_TM_GMTOFF */\r
5243 +\r
5244 +static table const *\r
5245 +lookup_word (parser_control const *pc, char *word)\r
5246 +{\r
5247 +  char *p;\r
5248 +  char *q;\r
5249 +  size_t wordlen;\r
5250 +  table const *tp;\r
5251 +  bool period_found;\r
5252 +  bool abbrev;\r
5253 +\r
5254 +  /* Make it uppercase.  */\r
5255 +  for (p = word; *p; p++)\r
5256 +    {\r
5257 +      unsigned char ch = *p;\r
5258 +      *p = c_toupper (ch);\r
5259 +    }\r
5260 +\r
5261 +  for (tp = meridian_table; tp->name; tp++)\r
5262 +    if (strcmp (word, tp->name) == 0)\r
5263 +      return tp;\r
5264 +\r
5265 +  /* See if we have an abbreviation for a month. */\r
5266 +  wordlen = strlen (word);\r
5267 +  abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');\r
5268 +\r
5269 +  for (tp = month_and_day_table; tp->name; tp++)\r
5270 +    if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)\r
5271 +      return tp;\r
5272 +\r
5273 +  if ((tp = lookup_zone (pc, word)))\r
5274 +    return tp;\r
5275 +\r
5276 +  if (strcmp (word, dst_table[0].name) == 0)\r
5277 +    return dst_table;\r
5278 +\r
5279 +  for (tp = time_units_table; tp->name; tp++)\r
5280 +    if (strcmp (word, tp->name) == 0)\r
5281 +      return tp;\r
5282 +\r
5283 +  /* Strip off any plural and try the units table again. */\r
5284 +  if (word[wordlen - 1] == 'S')\r
5285 +    {\r
5286 +      word[wordlen - 1] = '\0';\r
5287 +      for (tp = time_units_table; tp->name; tp++)\r
5288 +        if (strcmp (word, tp->name) == 0)\r
5289 +          return tp;\r
5290 +      word[wordlen - 1] = 'S';  /* For "this" in relative_time_table.  */\r
5291 +    }\r
5292 +\r
5293 +  for (tp = relative_time_table; tp->name; tp++)\r
5294 +    if (strcmp (word, tp->name) == 0)\r
5295 +      return tp;\r
5296 +\r
5297 +  /* Military time zones. */\r
5298 +  if (wordlen == 1)\r
5299 +    for (tp = military_table; tp->name; tp++)\r
5300 +      if (word[0] == tp->name[0])\r
5301 +        return tp;\r
5302 +\r
5303 +  /* Drop out any periods and try the time zone table again. */\r
5304 +  for (period_found = false, p = q = word; (*p = *q); q++)\r
5305 +    if (*q == '.')\r
5306 +      period_found = true;\r
5307 +    else\r
5308 +      p++;\r
5309 +  if (period_found && (tp = lookup_zone (pc, word)))\r
5310 +    return tp;\r
5311 +\r
5312 +  return NULL;\r
5313 +}\r
5314 +\r
5315 +static int\r
5316 +yylex (YYSTYPE *lvalp, parser_control *pc)\r
5317 +{\r
5318 +  unsigned char c;\r
5319 +  size_t count;\r
5320 +\r
5321 +  for (;;)\r
5322 +    {\r
5323 +      while (c = *pc->input, c_isspace (c))\r
5324 +        pc->input++;\r
5325 +\r
5326 +      if (ISDIGIT (c) || c == '-' || c == '+')\r
5327 +        {\r
5328 +          char const *p;\r
5329 +          int sign;\r
5330 +          unsigned long int value;\r
5331 +          if (c == '-' || c == '+')\r
5332 +            {\r
5333 +              sign = c == '-' ? -1 : 1;\r
5334 +              while (c = *++pc->input, c_isspace (c))\r
5335 +                continue;\r
5336 +              if (! ISDIGIT (c))\r
5337 +                /* skip the '-' sign */\r
5338 +                continue;\r
5339 +            }\r
5340 +          else\r
5341 +            sign = 0;\r
5342 +          p = pc->input;\r
5343 +          for (value = 0; ; value *= 10)\r
5344 +            {\r
5345 +              unsigned long int value1 = value + (c - '0');\r
5346 +              if (value1 < value)\r
5347 +                return '?';\r
5348 +              value = value1;\r
5349 +              c = *++p;\r
5350 +              if (! ISDIGIT (c))\r
5351 +                break;\r
5352 +              if (ULONG_MAX / 10 < value)\r
5353 +                return '?';\r
5354 +            }\r
5355 +          if ((c == '.' || c == ',') && ISDIGIT (p[1]))\r
5356 +            {\r
5357 +              time_t s;\r
5358 +              int ns;\r
5359 +              int digits;\r
5360 +              unsigned long int value1;\r
5361 +\r
5362 +              /* Check for overflow when converting value to time_t.  */\r
5363 +              if (sign < 0)\r
5364 +                {\r
5365 +                  s = - value;\r
5366 +                  if (0 < s)\r
5367 +                    return '?';\r
5368 +                  value1 = -s;\r
5369 +                }\r
5370 +              else\r
5371 +                {\r
5372 +                  s = value;\r
5373 +                  if (s < 0)\r
5374 +                    return '?';\r
5375 +                  value1 = s;\r
5376 +                }\r
5377 +              if (value != value1)\r
5378 +                return '?';\r
5379 +\r
5380 +              /* Accumulate fraction, to ns precision.  */\r
5381 +              p++;\r
5382 +              ns = *p++ - '0';\r
5383 +              for (digits = 2; digits <= LOG10_BILLION; digits++)\r
5384 +                {\r
5385 +                  ns *= 10;\r
5386 +                  if (ISDIGIT (*p))\r
5387 +                    ns += *p++ - '0';\r
5388 +                }\r
5389 +\r
5390 +              /* Skip excess digits, truncating toward -Infinity.  */\r
5391 +              if (sign < 0)\r
5392 +                for (; ISDIGIT (*p); p++)\r
5393 +                  if (*p != '0')\r
5394 +                    {\r
5395 +                      ns++;\r
5396 +                      break;\r
5397 +                    }\r
5398 +              while (ISDIGIT (*p))\r
5399 +                p++;\r
5400 +\r
5401 +              /* Adjust to the timespec convention, which is that\r
5402 +                 tv_nsec is always a positive offset even if tv_sec is\r
5403 +                 negative.  */\r
5404 +              if (sign < 0 && ns)\r
5405 +                {\r
5406 +                  s--;\r
5407 +                  if (! (s < 0))\r
5408 +                    return '?';\r
5409 +                  ns = BILLION - ns;\r
5410 +                }\r
5411 +\r
5412 +              lvalp->timespec.tv_sec = s;\r
5413 +              lvalp->timespec.tv_nsec = ns;\r
5414 +              pc->input = p;\r
5415 +              return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;\r
5416 +            }\r
5417 +          else\r
5418 +            {\r
5419 +              lvalp->textintval.negative = sign < 0;\r
5420 +              if (sign < 0)\r
5421 +                {\r
5422 +                  lvalp->textintval.value = - value;\r
5423 +                  if (0 < lvalp->textintval.value)\r
5424 +                    return '?';\r
5425 +                }\r
5426 +              else\r
5427 +                {\r
5428 +                  lvalp->textintval.value = value;\r
5429 +                  if (lvalp->textintval.value < 0)\r
5430 +                    return '?';\r
5431 +                }\r
5432 +              lvalp->textintval.digits = p - pc->input;\r
5433 +              pc->input = p;\r
5434 +              return sign ? tSNUMBER : tUNUMBER;\r
5435 +            }\r
5436 +        }\r
5437 +\r
5438 +      if (c_isalpha (c))\r
5439 +        {\r
5440 +          char buff[20];\r
5441 +          char *p = buff;\r
5442 +          table const *tp;\r
5443 +\r
5444 +          do\r
5445 +            {\r
5446 +              if (p < buff + sizeof buff - 1)\r
5447 +                *p++ = c;\r
5448 +              c = *++pc->input;\r
5449 +            }\r
5450 +          while (c_isalpha (c) || c == '.');\r
5451 +\r
5452 +          *p = '\0';\r
5453 +          tp = lookup_word (pc, buff);\r
5454 +          if (! tp)\r
5455 +            return '?';\r
5456 +          lvalp->intval = tp->value;\r
5457 +          return tp->type;\r
5458 +        }\r
5459 +\r
5460 +      if (c != '(')\r
5461 +        return *pc->input++;\r
5462 +      count = 0;\r
5463 +      do\r
5464 +        {\r
5465 +          c = *pc->input++;\r
5466 +          if (c == '\0')\r
5467 +            return c;\r
5468 +          if (c == '(')\r
5469 +            count++;\r
5470 +          else if (c == ')')\r
5471 +            count--;\r
5472 +        }\r
5473 +      while (count != 0);\r
5474 +    }\r
5475 +}\r
5476 +\r
5477 +/* Do nothing if the parser reports an error.  */\r
5478 +static int\r
5479 +yyerror (parser_control const *pc _GL_UNUSED,\r
5480 +         char const *s _GL_UNUSED)\r
5481 +{\r
5482 +  return 0;\r
5483 +}\r
5484 +\r
5485 +/* If *TM0 is the old and *TM1 is the new value of a struct tm after\r
5486 +   passing it to mktime, return true if it's OK that mktime returned T.\r
5487 +   It's not OK if *TM0 has out-of-range members.  */\r
5488 +\r
5489 +static bool\r
5490 +mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)\r
5491 +{\r
5492 +  if (t == (time_t) -1)\r
5493 +    {\r
5494 +      /* Guard against falsely reporting an error when parsing a time\r
5495 +         stamp that happens to equal (time_t) -1, on a host that\r
5496 +         supports such a time stamp.  */\r
5497 +      tm1 = localtime (&t);\r
5498 +      if (!tm1)\r
5499 +        return false;\r
5500 +    }\r
5501 +\r
5502 +  return ! ((tm0->tm_sec ^ tm1->tm_sec)\r
5503 +            | (tm0->tm_min ^ tm1->tm_min)\r
5504 +            | (tm0->tm_hour ^ tm1->tm_hour)\r
5505 +            | (tm0->tm_mday ^ tm1->tm_mday)\r
5506 +            | (tm0->tm_mon ^ tm1->tm_mon)\r
5507 +            | (tm0->tm_year ^ tm1->tm_year));\r
5508 +}\r
5509 +\r
5510 +/* A reasonable upper bound for the size of ordinary TZ strings.\r
5511 +   Use heap allocation if TZ's length exceeds this.  */\r
5512 +enum { TZBUFSIZE = 100 };\r
5513 +\r
5514 +/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated\r
5515 +   otherwise.  */\r
5516 +static char *\r
5517 +get_tz (char tzbuf[TZBUFSIZE])\r
5518 +{\r
5519 +  char *tz = getenv ("TZ");\r
5520 +  if (tz)\r
5521 +    {\r
5522 +      size_t tzsize = strlen (tz) + 1;\r
5523 +      tz = (tzsize <= TZBUFSIZE\r
5524 +            ? memcpy (tzbuf, tz, tzsize)\r
5525 +            : xmemdup (tz, tzsize));\r
5526 +    }\r
5527 +  return tz;\r
5528 +}\r
5529 +\r
5530 +/* Parse a date/time string, storing the resulting time value into *RESULT.\r
5531 +   The string itself is pointed to by P.  Return true if successful.\r
5532 +   P can be an incomplete or relative time specification; if so, use\r
5533 +   *NOW as the basis for the returned time.  */\r
5534 +bool\r
5535 +get_date (struct timespec *result, char const *p, struct timespec const *now)\r
5536 +{\r
5537 +  time_t Start;\r
5538 +  long int Start_ns;\r
5539 +  struct tm const *tmp;\r
5540 +  struct tm tm;\r
5541 +  struct tm tm0;\r
5542 +  parser_control pc;\r
5543 +  struct timespec gettime_buffer;\r
5544 +  unsigned char c;\r
5545 +  bool tz_was_altered = false;\r
5546 +  char *tz0 = NULL;\r
5547 +  char tz0buf[TZBUFSIZE];\r
5548 +  bool ok = true;\r
5549 +\r
5550 +  if (! now)\r
5551 +    {\r
5552 +      gettime (&gettime_buffer);\r
5553 +      now = &gettime_buffer;\r
5554 +    }\r
5555 +\r
5556 +  Start = now->tv_sec;\r
5557 +  Start_ns = now->tv_nsec;\r
5558 +\r
5559 +  tmp = localtime (&now->tv_sec);\r
5560 +  if (! tmp)\r
5561 +    return false;\r
5562 +\r
5563 +  while (c = *p, c_isspace (c))\r
5564 +    p++;\r
5565 +\r
5566 +  if (strncmp (p, "TZ=\"", 4) == 0)\r
5567 +    {\r
5568 +      char const *tzbase = p + 4;\r
5569 +      size_t tzsize = 1;\r
5570 +      char const *s;\r
5571 +\r
5572 +      for (s = tzbase; *s; s++, tzsize++)\r
5573 +        if (*s == '\\')\r
5574 +          {\r
5575 +            s++;\r
5576 +            if (! (*s == '\\' || *s == '"'))\r
5577 +              break;\r
5578 +          }\r
5579 +        else if (*s == '"')\r
5580 +          {\r
5581 +            char *z;\r
5582 +            char *tz1;\r
5583 +            char tz1buf[TZBUFSIZE];\r
5584 +            bool large_tz = TZBUFSIZE < tzsize;\r
5585 +            bool setenv_ok;\r
5586 +            /* Free tz0, in case this is the 2nd or subsequent time through. */\r
5587 +            free (tz0);\r
5588 +            tz0 = get_tz (tz0buf);\r
5589 +            z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf;\r
5590 +            for (s = tzbase; *s != '"'; s++)\r
5591 +              *z++ = *(s += *s == '\\');\r
5592 +            *z = '\0';\r
5593 +            setenv_ok = setenv ("TZ", tz1, 1) == 0;\r
5594 +            if (large_tz)\r
5595 +              free (tz1);\r
5596 +            if (!setenv_ok)\r
5597 +              goto fail;\r
5598 +            tz_was_altered = true;\r
5599 +            p = s + 1;\r
5600 +          }\r
5601 +    }\r
5602 +\r
5603 +  /* As documented, be careful to treat the empty string just like\r
5604 +     a date string of "0".  Without this, an empty string would be\r
5605 +     declared invalid when parsed during a DST transition.  */\r
5606 +  if (*p == '\0')\r
5607 +    p = "0";\r
5608 +\r
5609 +  pc.input = p;\r
5610 +  pc.year.value = tmp->tm_year;\r
5611 +  pc.year.value += TM_YEAR_BASE;\r
5612 +  pc.year.digits = 0;\r
5613 +  pc.month = tmp->tm_mon + 1;\r
5614 +  pc.day = tmp->tm_mday;\r
5615 +  pc.hour = tmp->tm_hour;\r
5616 +  pc.minutes = tmp->tm_min;\r
5617 +  pc.seconds.tv_sec = tmp->tm_sec;\r
5618 +  pc.seconds.tv_nsec = Start_ns;\r
5619 +  tm.tm_isdst = tmp->tm_isdst;\r
5620 +\r
5621 +  pc.meridian = MER24;\r
5622 +  pc.rel = RELATIVE_TIME_0;\r
5623 +  pc.timespec_seen = false;\r
5624 +  pc.rels_seen = false;\r
5625 +  pc.dates_seen = 0;\r
5626 +  pc.days_seen = 0;\r
5627 +  pc.times_seen = 0;\r
5628 +  pc.local_zones_seen = 0;\r
5629 +  pc.dsts_seen = 0;\r
5630 +  pc.zones_seen = 0;\r
5631 +\r
5632 +#if HAVE_STRUCT_TM_TM_ZONE\r
5633 +  pc.local_time_zone_table[0].name = tmp->tm_zone;\r
5634 +  pc.local_time_zone_table[0].type = tLOCAL_ZONE;\r
5635 +  pc.local_time_zone_table[0].value = tmp->tm_isdst;\r
5636 +  pc.local_time_zone_table[1].name = NULL;\r
5637 +\r
5638 +  /* Probe the names used in the next three calendar quarters, looking\r
5639 +     for a tm_isdst different from the one we already have.  */\r
5640 +  {\r
5641 +    int quarter;\r
5642 +    for (quarter = 1; quarter <= 3; quarter++)\r
5643 +      {\r
5644 +        time_t probe = Start + quarter * (90 * 24 * 60 * 60);\r
5645 +        struct tm const *probe_tm = localtime (&probe);\r
5646 +        if (probe_tm && probe_tm->tm_zone\r
5647 +            && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)\r
5648 +          {\r
5649 +              {\r
5650 +                pc.local_time_zone_table[1].name = probe_tm->tm_zone;\r
5651 +                pc.local_time_zone_table[1].type = tLOCAL_ZONE;\r
5652 +                pc.local_time_zone_table[1].value = probe_tm->tm_isdst;\r
5653 +                pc.local_time_zone_table[2].name = NULL;\r
5654 +              }\r
5655 +            break;\r
5656 +          }\r
5657 +      }\r
5658 +  }\r
5659 +#else\r
5660 +#if HAVE_TZNAME\r
5661 +  {\r
5662 +# if !HAVE_DECL_TZNAME\r
5663 +    extern char *tzname[];\r
5664 +# endif\r
5665 +    int i;\r
5666 +    for (i = 0; i < 2; i++)\r
5667 +      {\r
5668 +        pc.local_time_zone_table[i].name = tzname[i];\r
5669 +        pc.local_time_zone_table[i].type = tLOCAL_ZONE;\r
5670 +        pc.local_time_zone_table[i].value = i;\r
5671 +      }\r
5672 +    pc.local_time_zone_table[i].name = NULL;\r
5673 +  }\r
5674 +#else\r
5675 +  pc.local_time_zone_table[0].name = NULL;\r
5676 +#endif\r
5677 +#endif\r
5678 +\r
5679 +  if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name\r
5680 +      && ! strcmp (pc.local_time_zone_table[0].name,\r
5681 +                   pc.local_time_zone_table[1].name))\r
5682 +    {\r
5683 +      /* This locale uses the same abbrevation for standard and\r
5684 +         daylight times.  So if we see that abbreviation, we don't\r
5685 +         know whether it's daylight time.  */\r
5686 +      pc.local_time_zone_table[0].value = -1;\r
5687 +      pc.local_time_zone_table[1].name = NULL;\r
5688 +    }\r
5689 +\r
5690 +  if (yyparse (&pc) != 0)\r
5691 +    goto fail;\r
5692 +\r
5693 +  if (pc.timespec_seen)\r
5694 +    *result = pc.seconds;\r
5695 +  else\r
5696 +    {\r
5697 +      if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen\r
5698 +               | (pc.local_zones_seen + pc.zones_seen)))\r
5699 +        goto fail;\r
5700 +\r
5701 +      tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;\r
5702 +      tm.tm_mon = pc.month - 1;\r
5703 +      tm.tm_mday = pc.day;\r
5704 +      if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))\r
5705 +        {\r
5706 +          tm.tm_hour = to_hour (pc.hour, pc.meridian);\r
5707 +          if (tm.tm_hour < 0)\r
5708 +            goto fail;\r
5709 +          tm.tm_min = pc.minutes;\r
5710 +          tm.tm_sec = pc.seconds.tv_sec;\r
5711 +        }\r
5712 +      else\r
5713 +        {\r
5714 +          tm.tm_hour = tm.tm_min = tm.tm_sec = 0;\r
5715 +          pc.seconds.tv_nsec = 0;\r
5716 +        }\r
5717 +\r
5718 +      /* Let mktime deduce tm_isdst if we have an absolute time stamp.  */\r
5719 +      if (pc.dates_seen | pc.days_seen | pc.times_seen)\r
5720 +        tm.tm_isdst = -1;\r
5721 +\r
5722 +      /* But if the input explicitly specifies local time with or without\r
5723 +         DST, give mktime that information.  */\r
5724 +      if (pc.local_zones_seen)\r
5725 +        tm.tm_isdst = pc.local_isdst;\r
5726 +\r
5727 +      tm0 = tm;\r
5728 +\r
5729 +      Start = mktime (&tm);\r
5730 +\r
5731 +      if (! mktime_ok (&tm0, &tm, Start))\r
5732 +        {\r
5733 +          if (! pc.zones_seen)\r
5734 +            goto fail;\r
5735 +          else\r
5736 +            {\r
5737 +              /* Guard against falsely reporting errors near the time_t\r
5738 +                 boundaries when parsing times in other time zones.  For\r
5739 +                 example, suppose the input string "1969-12-31 23:00:00 -0100",\r
5740 +                 the current time zone is 8 hours ahead of UTC, and the min\r
5741 +                 time_t value is 1970-01-01 00:00:00 UTC.  Then the min\r
5742 +                 localtime value is 1970-01-01 08:00:00, and mktime will\r
5743 +                 therefore fail on 1969-12-31 23:00:00.  To work around the\r
5744 +                 problem, set the time zone to 1 hour behind UTC temporarily\r
5745 +                 by setting TZ="XXX1:00" and try mktime again.  */\r
5746 +\r
5747 +              long int time_zone = pc.time_zone;\r
5748 +              long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;\r
5749 +              long int abs_time_zone_hour = abs_time_zone / 60;\r
5750 +              int abs_time_zone_min = abs_time_zone % 60;\r
5751 +              char tz1buf[sizeof "XXX+0:00"\r
5752 +                          + sizeof pc.time_zone * CHAR_BIT / 3];\r
5753 +              if (!tz_was_altered)\r
5754 +                tz0 = get_tz (tz0buf);\r
5755 +              sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0),\r
5756 +                       abs_time_zone_hour, abs_time_zone_min);\r
5757 +              if (setenv ("TZ", tz1buf, 1) != 0)\r
5758 +                goto fail;\r
5759 +              tz_was_altered = true;\r
5760 +              tm = tm0;\r
5761 +              Start = mktime (&tm);\r
5762 +              if (! mktime_ok (&tm0, &tm, Start))\r
5763 +                goto fail;\r
5764 +            }\r
5765 +        }\r
5766 +\r
5767 +      if (pc.days_seen && ! pc.dates_seen)\r
5768 +        {\r
5769 +          tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7\r
5770 +                         + 7 * (pc.day_ordinal\r
5771 +                                - (0 < pc.day_ordinal\r
5772 +                                   && tm.tm_wday != pc.day_number)));\r
5773 +          tm.tm_isdst = -1;\r
5774 +          Start = mktime (&tm);\r
5775 +          if (Start == (time_t) -1)\r
5776 +            goto fail;\r
5777 +        }\r
5778 +\r
5779 +      /* Add relative date.  */\r
5780 +      if (pc.rel.year | pc.rel.month | pc.rel.day)\r
5781 +        {\r
5782 +          int year = tm.tm_year + pc.rel.year;\r
5783 +          int month = tm.tm_mon + pc.rel.month;\r
5784 +          int day = tm.tm_mday + pc.rel.day;\r
5785 +          if (((year < tm.tm_year) ^ (pc.rel.year < 0))\r
5786 +              | ((month < tm.tm_mon) ^ (pc.rel.month < 0))\r
5787 +              | ((day < tm.tm_mday) ^ (pc.rel.day < 0)))\r
5788 +            goto fail;\r
5789 +          tm.tm_year = year;\r
5790 +          tm.tm_mon = month;\r
5791 +          tm.tm_mday = day;\r
5792 +          tm.tm_hour = tm0.tm_hour;\r
5793 +          tm.tm_min = tm0.tm_min;\r
5794 +          tm.tm_sec = tm0.tm_sec;\r
5795 +          tm.tm_isdst = tm0.tm_isdst;\r
5796 +          Start = mktime (&tm);\r
5797 +          if (Start == (time_t) -1)\r
5798 +            goto fail;\r
5799 +        }\r
5800 +\r
5801 +      /* The only "output" of this if-block is an updated Start value,\r
5802 +         so this block must follow others that clobber Start.  */\r
5803 +      if (pc.zones_seen)\r
5804 +        {\r
5805 +          long int delta = pc.time_zone * 60;\r
5806 +          time_t t1;\r
5807 +#ifdef HAVE_TM_GMTOFF\r
5808 +          delta -= tm.tm_gmtoff;\r
5809 +#else\r
5810 +          time_t t = Start;\r
5811 +          struct tm const *gmt = gmtime (&t);\r
5812 +          if (! gmt)\r
5813 +            goto fail;\r
5814 +          delta -= tm_diff (&tm, gmt);\r
5815 +#endif\r
5816 +          t1 = Start - delta;\r
5817 +          if ((Start < t1) != (delta < 0))\r
5818 +            goto fail;  /* time_t overflow */\r
5819 +          Start = t1;\r
5820 +        }\r
5821 +\r
5822 +      /* Add relative hours, minutes, and seconds.  On hosts that support\r
5823 +         leap seconds, ignore the possibility of leap seconds; e.g.,\r
5824 +         "+ 10 minutes" adds 600 seconds, even if one of them is a\r
5825 +         leap second.  Typically this is not what the user wants, but it's\r
5826 +         too hard to do it the other way, because the time zone indicator\r
5827 +         must be applied before relative times, and if mktime is applied\r
5828 +         again the time zone will be lost.  */\r
5829 +      {\r
5830 +        long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns;\r
5831 +        long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;\r
5832 +        time_t t0 = Start;\r
5833 +        long int d1 = 60 * 60 * pc.rel.hour;\r
5834 +        time_t t1 = t0 + d1;\r
5835 +        long int d2 = 60 * pc.rel.minutes;\r
5836 +        time_t t2 = t1 + d2;\r
5837 +        long_time_t d3 = pc.rel.seconds;\r
5838 +        long_time_t t3 = t2 + d3;\r
5839 +        long int d4 = (sum_ns - normalized_ns) / BILLION;\r
5840 +        long_time_t t4 = t3 + d4;\r
5841 +        time_t t5 = t4;\r
5842 +\r
5843 +        if ((d1 / (60 * 60) ^ pc.rel.hour)\r
5844 +            | (d2 / 60 ^ pc.rel.minutes)\r
5845 +            | ((t1 < t0) ^ (d1 < 0))\r
5846 +            | ((t2 < t1) ^ (d2 < 0))\r
5847 +            | ((t3 < t2) ^ (d3 < 0))\r
5848 +            | ((t4 < t3) ^ (d4 < 0))\r
5849 +            | (t5 != t4))\r
5850 +          goto fail;\r
5851 +\r
5852 +        result->tv_sec = t5;\r
5853 +        result->tv_nsec = normalized_ns;\r
5854 +      }\r
5855 +    }\r
5856 +\r
5857 +  goto done;\r
5858 +\r
5859 + fail:\r
5860 +  ok = false;\r
5861 + done:\r
5862 +  if (tz_was_altered)\r
5863 +    ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0;\r
5864 +  if (tz0 != tz0buf)\r
5865 +    free (tz0);\r
5866 +  return ok;\r
5867 +}\r
5868 +\r
5869 +#if TEST\r
5870 +\r
5871 +int\r
5872 +main (int ac, char **av)\r
5873 +{\r
5874 +  char buff[BUFSIZ];\r
5875 +\r
5876 +  printf ("Enter date, or blank line to exit.\n\t> ");\r
5877 +  fflush (stdout);\r
5878 +\r
5879 +  buff[BUFSIZ - 1] = '\0';\r
5880 +  while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])\r
5881 +    {\r
5882 +      struct timespec d;\r
5883 +      struct tm const *tm;\r
5884 +      if (! get_date (&d, buff, NULL))\r
5885 +        printf ("Bad format - couldn't convert.\n");\r
5886 +      else if (! (tm = localtime (&d.tv_sec)))\r
5887 +        {\r
5888 +          long int sec = d.tv_sec;\r
5889 +          printf ("localtime (%ld) failed\n", sec);\r
5890 +        }\r
5891 +      else\r
5892 +        {\r
5893 +          int ns = d.tv_nsec;\r
5894 +          printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",\r
5895 +                  tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,\r
5896 +                  tm->tm_hour, tm->tm_min, tm->tm_sec, ns);\r
5897 +        }\r
5898 +      printf ("\t> ");\r
5899 +      fflush (stdout);\r
5900 +    }\r
5901 +  return 0;\r
5902 +}\r
5903 +#endif /* TEST */\r
5904 diff --git a/lib/gettime.c b/lib/gettime.c\r
5905 new file mode 100644\r
5906 index 0000000..044b26f\r
5907 --- /dev/null\r
5908 +++ b/lib/gettime.c\r
5909 @@ -0,0 +1,48 @@\r
5910 +/* gettime -- get the system clock\r
5911 +\r
5912 +   Copyright (C) 2002, 2004-2007, 2009-2010 Free Software Foundation, Inc.\r
5913 +\r
5914 +   This program is free software: you can redistribute it and/or modify\r
5915 +   it under the terms of the GNU General Public License as published by\r
5916 +   the Free Software Foundation; either version 3 of the License, or\r
5917 +   (at your option) any later version.\r
5918 +\r
5919 +   This program is distributed in the hope that it will be useful,\r
5920 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
5921 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
5922 +   GNU General Public License for more details.\r
5923 +\r
5924 +   You should have received a copy of the GNU General Public License\r
5925 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
5926 +\r
5927 +/* Written by Paul Eggert.  */\r
5928 +\r
5929 +#include <config.h>\r
5930 +\r
5931 +#include "timespec.h"\r
5932 +\r
5933 +#include <sys/time.h>\r
5934 +\r
5935 +/* Get the system time into *TS.  */\r
5936 +\r
5937 +void\r
5938 +gettime (struct timespec *ts)\r
5939 +{\r
5940 +#if HAVE_NANOTIME\r
5941 +  nanotime (ts);\r
5942 +#else\r
5943 +\r
5944 +# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME\r
5945 +  if (clock_gettime (CLOCK_REALTIME, ts) == 0)\r
5946 +    return;\r
5947 +# endif\r
5948 +\r
5949 +  {\r
5950 +    struct timeval tv;\r
5951 +    gettimeofday (&tv, NULL);\r
5952 +    ts->tv_sec = tv.tv_sec;\r
5953 +    ts->tv_nsec = tv.tv_usec * 1000;\r
5954 +  }\r
5955 +\r
5956 +#endif\r
5957 +}\r
5958 diff --git a/lib/gettime.h b/lib/gettime.h\r
5959 new file mode 100644\r
5960 index 0000000..e69de29\r
5961 diff --git a/lib/intprops.h b/lib/intprops.h\r
5962 new file mode 100644\r
5963 index 0000000..46f4d47\r
5964 --- /dev/null\r
5965 +++ b/lib/intprops.h\r
5966 @@ -0,0 +1,83 @@\r
5967 +/* intprops.h -- properties of integer types\r
5968 +\r
5969 +   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009, 2010 Free Software\r
5970 +   Foundation, Inc.\r
5971 +\r
5972 +   This program is free software: you can redistribute it and/or modify\r
5973 +   it under the terms of the GNU General Public License as published by\r
5974 +   the Free Software Foundation; either version 3 of the License, or\r
5975 +   (at your option) any later version.\r
5976 +\r
5977 +   This program is distributed in the hope that it will be useful,\r
5978 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
5979 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
5980 +   GNU General Public License for more details.\r
5981 +\r
5982 +   You should have received a copy of the GNU General Public License\r
5983 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
5984 +\r
5985 +/* Written by Paul Eggert.  */\r
5986 +\r
5987 +#ifndef GL_INTPROPS_H\r
5988 +# define GL_INTPROPS_H\r
5989 +\r
5990 +# include <limits.h>\r
5991 +\r
5992 +/* The extra casts in the following macros work around compiler bugs,\r
5993 +   e.g., in Cray C 5.0.3.0.  */\r
5994 +\r
5995 +/* True if the arithmetic type T is an integer type.  bool counts as\r
5996 +   an integer.  */\r
5997 +# define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)\r
5998 +\r
5999 +/* True if negative values of the signed integer type T use two's\r
6000 +   complement, ones' complement, or signed magnitude representation,\r
6001 +   respectively.  Much GNU code assumes two's complement, but some\r
6002 +   people like to be portable to all possible C hosts.  */\r
6003 +# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)\r
6004 +# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)\r
6005 +# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)\r
6006 +\r
6007 +/* True if the arithmetic type T is signed.  */\r
6008 +# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))\r
6009 +\r
6010 +/* The maximum and minimum values for the integer type T.  These\r
6011 +   macros have undefined behavior if T is signed and has padding bits.\r
6012 +   If this is a problem for you, please let us know how to fix it for\r
6013 +   your host.  */\r
6014 +# define TYPE_MINIMUM(t) \\r
6015 +  ((t) (! TYPE_SIGNED (t) \\r
6016 +        ? (t) 0 \\r
6017 +        : TYPE_SIGNED_MAGNITUDE (t) \\r
6018 +        ? ~ (t) 0 \\r
6019 +        : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))\r
6020 +# define TYPE_MAXIMUM(t) \\r
6021 +  ((t) (! TYPE_SIGNED (t) \\r
6022 +        ? (t) -1 \\r
6023 +        : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))\r
6024 +\r
6025 +/* Return zero if T can be determined to be an unsigned type.\r
6026 +   Otherwise, return 1.\r
6027 +   When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a\r
6028 +   tighter bound.  Otherwise, it overestimates the true bound by one byte\r
6029 +   when applied to unsigned types of size 2, 4, 16, ... bytes.\r
6030 +   The symbol signed_type_or_expr__ is private to this header file.  */\r
6031 +# if __GNUC__ >= 2\r
6032 +#  define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))\r
6033 +# else\r
6034 +#  define signed_type_or_expr__(t) 1\r
6035 +# endif\r
6036 +\r
6037 +/* Bound on length of the string representing an integer type or expression T.\r
6038 +   Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;\r
6039 +   add 1 for integer division truncation; add 1 more for a minus sign\r
6040 +   if needed.  */\r
6041 +# define INT_STRLEN_BOUND(t) \\r
6042 +  ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \\r
6043 +   + signed_type_or_expr__ (t) + 1)\r
6044 +\r
6045 +/* Bound on buffer size needed to represent an integer type or expression T,\r
6046 +   including the terminating null.  */\r
6047 +# define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)\r
6048 +\r
6049 +#endif /* GL_INTPROPS_H */\r
6050 diff --git a/lib/timespec.h b/lib/timespec.h\r
6051 new file mode 100644\r
6052 index 0000000..81b3423\r
6053 --- /dev/null\r
6054 +++ b/lib/timespec.h\r
6055 @@ -0,0 +1,39 @@\r
6056 +/* timespec -- System time interface\r
6057 +\r
6058 +   Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2010 Free Software\r
6059 +   Foundation, Inc.\r
6060 +\r
6061 +   This program is free software: you can redistribute it and/or modify\r
6062 +   it under the terms of the GNU General Public License as published by\r
6063 +   the Free Software Foundation; either version 3 of the License, or\r
6064 +   (at your option) any later version.\r
6065 +\r
6066 +   This program is distributed in the hope that it will be useful,\r
6067 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
6068 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
6069 +   GNU General Public License for more details.\r
6070 +\r
6071 +   You should have received a copy of the GNU General Public License\r
6072 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
6073 +\r
6074 +#if ! defined TIMESPEC_H\r
6075 +# define TIMESPEC_H\r
6076 +\r
6077 +# include <time.h>\r
6078 +\r
6079 +/* Return negative, zero, positive if A < B, A == B, A > B, respectively.\r
6080 +   Assume the nanosecond components are in range, or close to it.  */\r
6081 +static inline int\r
6082 +timespec_cmp (struct timespec a, struct timespec b)\r
6083 +{\r
6084 +  return (a.tv_sec < b.tv_sec ? -1\r
6085 +          : a.tv_sec > b.tv_sec ? 1\r
6086 +          : a.tv_nsec < b.tv_nsec ? -1\r
6087 +          : a.tv_nsec > b.tv_nsec ? 1\r
6088 +          : 0);\r
6089 +}\r
6090 +\r
6091 +void gettime (struct timespec *);\r
6092 +int settime (struct timespec const *);\r
6093 +\r
6094 +#endif\r
6095 diff --git a/lib/verify.h b/lib/verify.h\r
6096 new file mode 100644\r
6097 index 0000000..bcd3f5a\r
6098 --- /dev/null\r
6099 +++ b/lib/verify.h\r
6100 @@ -0,0 +1,140 @@\r
6101 +/* Compile-time assert-like macros.\r
6102 +\r
6103 +   Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc.\r
6104 +\r
6105 +   This program is free software: you can redistribute it and/or modify\r
6106 +   it under the terms of the GNU General Public License as published by\r
6107 +   the Free Software Foundation; either version 3 of the License, or\r
6108 +   (at your option) any later version.\r
6109 +\r
6110 +   This program is distributed in the hope that it will be useful,\r
6111 +   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
6112 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
6113 +   GNU General Public License for more details.\r
6114 +\r
6115 +   You should have received a copy of the GNU General Public License\r
6116 +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\r
6117 +\r
6118 +/* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */\r
6119 +\r
6120 +#ifndef VERIFY_H\r
6121 +# define VERIFY_H 1\r
6122 +\r
6123 +/* Each of these macros verifies that its argument R is nonzero.  To\r
6124 +   be portable, R should be an integer constant expression.  Unlike\r
6125 +   assert (R), there is no run-time overhead.\r
6126 +\r
6127 +   There are two macros, since no single macro can be used in all\r
6128 +   contexts in C.  verify_true (R) is for scalar contexts, including\r
6129 +   integer constant expression contexts.  verify (R) is for declaration\r
6130 +   contexts, e.g., the top level.\r
6131 +\r
6132 +   Symbols ending in "__" are private to this header.\r
6133 +\r
6134 +   The code below uses several ideas.\r
6135 +\r
6136 +   * The first step is ((R) ? 1 : -1).  Given an expression R, of\r
6137 +     integral or boolean or floating-point type, this yields an\r
6138 +     expression of integral type, whose value is later verified to be\r
6139 +     constant and nonnegative.\r
6140 +\r
6141 +   * Next this expression W is wrapped in a type\r
6142 +     struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }.\r
6143 +     If W is negative, this yields a compile-time error.  No compiler can\r
6144 +     deal with a bit-field of negative size.\r
6145 +\r
6146 +     One might think that an array size check would have the same\r
6147 +     effect, that is, that the type struct { unsigned int dummy[W]; }\r
6148 +     would work as well.  However, inside a function, some compilers\r
6149 +     (such as C++ compilers and GNU C) allow local parameters and\r
6150 +     variables inside array size expressions.  With these compilers,\r
6151 +     an array size check would not properly diagnose this misuse of\r
6152 +     the verify macro:\r
6153 +\r
6154 +       void function (int n) { verify (n < 0); }\r
6155 +\r
6156 +   * For the verify macro, the struct verify_type__ will need to\r
6157 +     somehow be embedded into a declaration.  To be portable, this\r
6158 +     declaration must declare an object, a constant, a function, or a\r
6159 +     typedef name.  If the declared entity uses the type directly,\r
6160 +     such as in\r
6161 +\r
6162 +       struct dummy {...};\r
6163 +       typedef struct {...} dummy;\r
6164 +       extern struct {...} *dummy;\r
6165 +       extern void dummy (struct {...} *);\r
6166 +       extern struct {...} *dummy (void);\r
6167 +\r
6168 +     two uses of the verify macro would yield colliding declarations\r
6169 +     if the entity names are not disambiguated.  A workaround is to\r
6170 +     attach the current line number to the entity name:\r
6171 +\r
6172 +       #define GL_CONCAT0(x, y) x##y\r
6173 +       #define GL_CONCAT(x, y) GL_CONCAT0 (x, y)\r
6174 +       extern struct {...} * GL_CONCAT(dummy,__LINE__);\r
6175 +\r
6176 +     But this has the problem that two invocations of verify from\r
6177 +     within the same macro would collide, since the __LINE__ value\r
6178 +     would be the same for both invocations.\r
6179 +\r
6180 +     A solution is to use the sizeof operator.  It yields a number,\r
6181 +     getting rid of the identity of the type.  Declarations like\r
6182 +\r
6183 +       extern int dummy [sizeof (struct {...})];\r
6184 +       extern void dummy (int [sizeof (struct {...})]);\r
6185 +       extern int (*dummy (void)) [sizeof (struct {...})];\r
6186 +\r
6187 +     can be repeated.\r
6188 +\r
6189 +   * Should the implementation use a named struct or an unnamed struct?\r
6190 +     Which of the following alternatives can be used?\r
6191 +\r
6192 +       extern int dummy [sizeof (struct {...})];\r
6193 +       extern int dummy [sizeof (struct verify_type__ {...})];\r
6194 +       extern void dummy (int [sizeof (struct {...})]);\r
6195 +       extern void dummy (int [sizeof (struct verify_type__ {...})]);\r
6196 +       extern int (*dummy (void)) [sizeof (struct {...})];\r
6197 +       extern int (*dummy (void)) [sizeof (struct verify_type__ {...})];\r
6198 +\r
6199 +     In the second and sixth case, the struct type is exported to the\r
6200 +     outer scope; two such declarations therefore collide.  GCC warns\r
6201 +     about the first, third, and fourth cases.  So the only remaining\r
6202 +     possibility is the fifth case:\r
6203 +\r
6204 +       extern int (*dummy (void)) [sizeof (struct {...})];\r
6205 +\r
6206 +   * This implementation exploits the fact that GCC does not warn about\r
6207 +     the last declaration mentioned above.  If a future version of GCC\r
6208 +     introduces a warning for this, the problem could be worked around\r
6209 +     by using code specialized to GCC, e.g.,:\r
6210 +\r
6211 +       #if 4 <= __GNUC__\r
6212 +       # define verify(R) \\r
6213 +           extern int (* verify_function__ (void)) \\r
6214 +                      [__builtin_constant_p (R) && (R) ? 1 : -1]\r
6215 +       #endif\r
6216 +\r
6217 +   * In C++, any struct definition inside sizeof is invalid.\r
6218 +     Use a template type to work around the problem.  */\r
6219 +\r
6220 +\r
6221 +/* Verify requirement R at compile-time, as an integer constant expression.\r
6222 +   Return 1.  */\r
6223 +\r
6224 +# ifdef __cplusplus\r
6225 +template <int w>\r
6226 +  struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };\r
6227 +#  define verify_true(R) \\r
6228 +     (!!sizeof (verify_type__<(R) ? 1 : -1>))\r
6229 +# else\r
6230 +#  define verify_true(R) \\r
6231 +     (!!sizeof \\r
6232 +      (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))\r
6233 +# endif\r
6234 +\r
6235 +/* Verify requirement R at compile-time, as a declaration without a\r
6236 +   trailing ';'.  */\r
6237 +\r
6238 +# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)]\r
6239 +\r
6240 +#endif\r
6241 -- \r
6242 1.7.1\r
6243 \r