Mercurial > hg > octave-kai > gnulib-hg
annotate lib/getdate.y @ 3466:45d73183ee54
Revert some of the previous change; intead,
fix the HAVE_GETCWD_NULL code to behave more like the
!HAVE_GETCWD_NULL code used to.
Include "xalloc.h".
(xgetcwd): Do not return NULL when memory is exhausted; instead,
invoke xalloc_die.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Tue, 04 Sep 2001 20:28:31 +0000 |
parents | adeccf81e409 |
children | 72422d1e9181 |
rev | line source |
---|---|
9 | 1 %{ |
1928 | 2 /* Parse a string into an internal time stamp. |
2110 | 3 Copyright 1999, 2000 Free Software Foundation, Inc. |
1928 | 4 |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2, or (at your option) | |
8 any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; if not, write to the Free Software Foundation, | |
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
18 | |
19 /* Originally written by Steven M. Bellovin <smb@research.att.com> while | |
20 at the University of North Carolina at Chapel Hill. Later tweaked by | |
21 a couple of people on Usenet. Completely overhauled by Rich $alz | |
22 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990. | |
23 | |
24 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do | |
25 the right thing about local DST. Unlike previous versions, this | |
26 version is reentrant. */ | |
9 | 27 |
48 | 28 #ifdef HAVE_CONFIG_H |
855
9c89b90524b8
(get_date): Change prototype to reflect const'ness of parameters.
Jim Meyering <jim@meyering.net>
parents:
852
diff
changeset
|
29 # include <config.h> |
1717
4b9de8310f84
<alloca.h>: Include if HAVE_ALLOCA_H, not FORCE_ALLOCA_H.
Jim Meyering <jim@meyering.net>
parents:
1584
diff
changeset
|
30 # ifdef HAVE_ALLOCA_H |
855
9c89b90524b8
(get_date): Change prototype to reflect const'ness of parameters.
Jim Meyering <jim@meyering.net>
parents:
852
diff
changeset
|
31 # include <alloca.h> |
9c89b90524b8
(get_date): Change prototype to reflect const'ness of parameters.
Jim Meyering <jim@meyering.net>
parents:
852
diff
changeset
|
32 # endif |
101 | 33 #endif |
48 | 34 |
100
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
35 /* Since the code of getdate.y is not included in the Emacs executable |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
36 itself, there is no need to #define static in this file. Even if |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
37 the code were included in the Emacs executable, it probably |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
38 wouldn't do any harm to #undef it here; this will only cause |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
39 problems if we try to write to a static variable, which I don't |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
40 think this code needs to do. */ |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
41 #ifdef emacs |
855
9c89b90524b8
(get_date): Change prototype to reflect const'ness of parameters.
Jim Meyering <jim@meyering.net>
parents:
852
diff
changeset
|
42 # undef static |
100
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
43 #endif |
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
44 |
9 | 45 #include <ctype.h> |
46 | |
1785
197f4bdf9a3d
<stdlib.h>: Include if HAVE_STDLIB_H, since bison 1.27 invokes "free".
Jim Meyering <jim@meyering.net>
parents:
1777
diff
changeset
|
47 #if HAVE_STDLIB_H |
197f4bdf9a3d
<stdlib.h>: Include if HAVE_STDLIB_H, since bison 1.27 invokes "free".
Jim Meyering <jim@meyering.net>
parents:
1777
diff
changeset
|
48 # include <stdlib.h> /* for `free'; used by Bison 1.27 */ |
197f4bdf9a3d
<stdlib.h>: Include if HAVE_STDLIB_H, since bison 1.27 invokes "free".
Jim Meyering <jim@meyering.net>
parents:
1777
diff
changeset
|
49 #endif |
197f4bdf9a3d
<stdlib.h>: Include if HAVE_STDLIB_H, since bison 1.27 invokes "free".
Jim Meyering <jim@meyering.net>
parents:
1777
diff
changeset
|
50 |
1928 | 51 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII) |
811
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
52 # define IN_CTYPE_DOMAIN(c) 1 |
688
cc4dbb9f5f58
Define and use upper case variants of ctype.h IS* macros.
Jim Meyering <jim@meyering.net>
parents:
562
diff
changeset
|
53 #else |
1928 | 54 # define IN_CTYPE_DOMAIN(c) isascii (c) |
688
cc4dbb9f5f58
Define and use upper case variants of ctype.h IS* macros.
Jim Meyering <jim@meyering.net>
parents:
562
diff
changeset
|
55 #endif |
cc4dbb9f5f58
Define and use upper case variants of ctype.h IS* macros.
Jim Meyering <jim@meyering.net>
parents:
562
diff
changeset
|
56 |
811
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
57 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
58 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) |
1928 | 59 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c)) |
811
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
60 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) |
814 | 61 |
811
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
62 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows: |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
63 - Its arg may be any int or unsigned int; it need not be an unsigned char. |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
64 - It's guaranteed to evaluate its argument exactly once. |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
65 - It's typically faster. |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
66 Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
67 only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
68 it's important to use the locale's definition of `digit' even when the |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
69 host does not conform to Posix. */ |
193f7d202848
(IN_CTYPE_DOMAIN): Rename from ISASCII.
Jim Meyering <jim@meyering.net>
parents:
805
diff
changeset
|
70 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) |
688
cc4dbb9f5f58
Define and use upper case variants of ctype.h IS* macros.
Jim Meyering <jim@meyering.net>
parents:
562
diff
changeset
|
71 |
1928 | 72 #if STDC_HEADERS || HAVE_STRING_H |
856
3cea2ffcbce4
Indent 2 more cpp-directives to reflect nesting.
Jim Meyering <jim@meyering.net>
parents:
855
diff
changeset
|
73 # include <string.h> |
9 | 74 #endif |
75 | |
1962
1f3b3ce10ab6
(__attribute__): Define to empty if GCC claims to
Jim Meyering <jim@meyering.net>
parents:
1931
diff
changeset
|
76 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ |
1584
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
77 # define __attribute__(x) |
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
78 #endif |
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
79 |
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
80 #ifndef ATTRIBUTE_UNUSED |
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
81 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) |
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
82 #endif |
0f1daf1810b4
Fix warnings from gcc -W -Wall
Jim Meyering <jim@meyering.net>
parents:
1265
diff
changeset
|
83 |
1928 | 84 #define EPOCH_YEAR 1970 |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
85 #define TM_YEAR_BASE 1900 |
1928 | 86 |
87 #define HOUR(x) ((x) * 60) | |
2588
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
88 |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
89 /* An integer value, and the number of digits in its textual |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
90 representation. */ |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
91 typedef struct |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
92 { |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
93 int value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
94 int digits; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
95 } textint; |
100
4d645beabfa4
merge with 1.8.1 + partial --version and --help
Jim Meyering <jim@meyering.net>
parents:
49
diff
changeset
|
96 |
1928 | 97 /* An entry in the lexical lookup table. */ |
98 typedef struct | |
99 { | |
100 char const *name; | |
101 int type; | |
102 int value; | |
103 } table; | |
104 | |
105 /* Meridian: am, pm, or 24-hour style. */ | |
106 enum { MERam, MERpm, MER24 }; | |
769
c906850e724f
Remap yacc globals to have gd_ prefix.
Jim Meyering <jim@meyering.net>
parents:
688
diff
changeset
|
107 |
1928 | 108 /* Information passed to and from the parser. */ |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
109 typedef struct |
2047
626ebcce50a3
(get_date): Fix typo in time_t overflow test.
Jim Meyering <jim@meyering.net>
parents:
1986
diff
changeset
|
110 { |
1928 | 111 /* The input string remaining to be parsed. */ |
112 const char *input; | |
113 | |
114 /* N, if this is the Nth Tuesday. */ | |
115 int day_ordinal; | |
116 | |
117 /* Day of week; Sunday is 0. */ | |
118 int day_number; | |
119 | |
120 /* tm_isdst flag for the local zone. */ | |
121 int local_isdst; | |
122 | |
123 /* Time zone, in minutes east of UTC. */ | |
124 int time_zone; | |
9 | 125 |
1928 | 126 /* Style used for time. */ |
127 int meridian; | |
9 | 128 |
1928 | 129 /* Gregorian year, month, day, hour, minutes, and seconds. */ |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
130 textint year; |
1928 | 131 int month; |
132 int day; | |
133 int hour; | |
134 int minutes; | |
135 int seconds; | |
9 | 136 |
1928 | 137 /* Relative year, month, day, hour, minutes, and seconds. */ |
138 int rel_year; | |
139 int rel_month; | |
140 int rel_day; | |
141 int rel_hour; | |
142 int rel_minutes; | |
143 int rel_seconds; | |
9 | 144 |
1928 | 145 /* Counts of nonterminals of various flavors parsed so far. */ |
146 int dates_seen; | |
147 int days_seen; | |
148 int local_zones_seen; | |
149 int rels_seen; | |
150 int times_seen; | |
151 int zones_seen; | |
152 | |
153 /* Table of local time zone abbrevations, terminated by a null entry. */ | |
154 table local_time_zone_table[3]; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
155 } parser_control; |
1928 | 156 |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
157 #define PC (* (parser_control *) parm) |
1928 | 158 #define YYLEX_PARAM parm |
159 #define YYPARSE_PARAM parm | |
160 | |
161 static int yyerror (); | |
162 static int yylex (); | |
9 | 163 |
164 %} | |
165 | |
1928 | 166 /* We want a reentrant parser. */ |
167 %pure_parser | |
168 | |
1203 | 169 /* This grammar has 13 shift/reduce conflicts. */ |
170 %expect 13 | |
2588
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
171 |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
172 %union |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
173 { |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
174 int intval; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
175 textint textintval; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
176 } |
1203 | 177 |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
178 %token tAGO tDST |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
179 |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
180 %token <intval> tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tLOCAL_ZONE tMERIDIAN |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
181 %token <intval> tMINUTE_UNIT tMONTH tMONTH_UNIT tSEC_UNIT tYEAR_UNIT tZONE |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
182 |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
183 %token <textintval> tSNUMBER tUNUMBER |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
184 |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
185 %type <intval> o_merid |
9 | 186 |
187 %% | |
188 | |
1928 | 189 spec: |
190 /* empty */ | |
191 | spec item | |
192 ; | |
9 | 193 |
1928 | 194 item: |
195 time | |
196 { PC.times_seen++; } | |
197 | local_zone | |
198 { PC.local_zones_seen++; } | |
199 | zone | |
200 { PC.zones_seen++; } | |
201 | date | |
202 { PC.dates_seen++; } | |
203 | day | |
204 { PC.days_seen++; } | |
205 | rel | |
206 { PC.rels_seen++; } | |
207 | number | |
208 ; | |
9 | 209 |
1928 | 210 time: |
211 tUNUMBER tMERIDIAN | |
212 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
213 PC.hour = $1.value; |
1928 | 214 PC.minutes = 0; |
215 PC.seconds = 0; | |
216 PC.meridian = $2; | |
217 } | |
218 | tUNUMBER ':' tUNUMBER o_merid | |
219 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
220 PC.hour = $1.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
221 PC.minutes = $3.value; |
1928 | 222 PC.seconds = 0; |
223 PC.meridian = $4; | |
224 } | |
225 | tUNUMBER ':' tUNUMBER tSNUMBER | |
226 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
227 PC.hour = $1.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
228 PC.minutes = $3.value; |
1928 | 229 PC.meridian = MER24; |
230 PC.zones_seen++; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
231 PC.time_zone = $4.value % 100 + ($4.value / 100) * 60; |
1928 | 232 } |
233 | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid | |
234 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
235 PC.hour = $1.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
236 PC.minutes = $3.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
237 PC.seconds = $5.value; |
1928 | 238 PC.meridian = $6; |
239 } | |
240 | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER | |
241 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
242 PC.hour = $1.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
243 PC.minutes = $3.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
244 PC.seconds = $5.value; |
1928 | 245 PC.meridian = MER24; |
246 PC.zones_seen++; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
247 PC.time_zone = $6.value % 100 + ($6.value / 100) * 60; |
1928 | 248 } |
249 ; | |
9 | 250 |
1928 | 251 local_zone: |
252 tLOCAL_ZONE | |
253 { PC.local_isdst = $1; } | |
254 | tLOCAL_ZONE tDST | |
255 { PC.local_isdst = $1 < 0 ? 1 : $1 + 1; } | |
256 ; | |
257 | |
258 zone: | |
259 tZONE | |
260 { PC.time_zone = $1; } | |
261 | tDAYZONE | |
262 { PC.time_zone = $1 + 60; } | |
263 | tZONE tDST | |
264 { PC.time_zone = $1 + 60; } | |
265 ; | |
9 | 266 |
1928 | 267 day: |
268 tDAY | |
269 { | |
270 PC.day_ordinal = 1; | |
271 PC.day_number = $1; | |
272 } | |
273 | tDAY ',' | |
274 { | |
275 PC.day_ordinal = 1; | |
276 PC.day_number = $1; | |
277 } | |
278 | tUNUMBER tDAY | |
279 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
280 PC.day_ordinal = $1.value; |
1928 | 281 PC.day_number = $2; |
282 } | |
283 ; | |
9 | 284 |
1928 | 285 date: |
286 tUNUMBER '/' tUNUMBER | |
287 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
288 PC.month = $1.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
289 PC.day = $3.value; |
1928 | 290 } |
291 | tUNUMBER '/' tUNUMBER '/' tUNUMBER | |
292 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
293 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits, |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
294 otherwise as MM/DD/YY. |
1928 | 295 The goal in recognizing YYYY/MM/DD is solely to support legacy |
296 machine-generated dates like those in an RCS log listing. If | |
297 you want portability, use the ISO 8601 format. */ | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
298 if (4 <= $1.digits) |
1928 | 299 { |
300 PC.year = $1; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
301 PC.month = $3.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
302 PC.day = $5.value; |
1928 | 303 } |
304 else | |
305 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
306 PC.month = $1.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
307 PC.day = $3.value; |
1928 | 308 PC.year = $5; |
309 } | |
310 } | |
311 | tUNUMBER tSNUMBER tSNUMBER | |
312 { | |
313 /* ISO 8601 format. YYYY-MM-DD. */ | |
314 PC.year = $1; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
315 PC.month = -$2.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
316 PC.day = -$3.value; |
1928 | 317 } |
318 | tUNUMBER tMONTH tSNUMBER | |
319 { | |
320 /* e.g. 17-JUN-1992. */ | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
321 PC.day = $1.value; |
1928 | 322 PC.month = $2; |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
323 PC.year.value = -$3.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
324 PC.year.digits = $3.digits; |
1928 | 325 } |
326 | tMONTH tUNUMBER | |
327 { | |
328 PC.month = $1; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
329 PC.day = $2.value; |
1928 | 330 } |
331 | tMONTH tUNUMBER ',' tUNUMBER | |
332 { | |
333 PC.month = $1; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
334 PC.day = $2.value; |
1928 | 335 PC.year = $4; |
336 } | |
337 | tUNUMBER tMONTH | |
338 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
339 PC.day = $1.value; |
1928 | 340 PC.month = $2; |
341 } | |
342 | tUNUMBER tMONTH tUNUMBER | |
343 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
344 PC.day = $1.value; |
1928 | 345 PC.month = $2; |
346 PC.year = $3; | |
347 } | |
348 ; | |
9 | 349 |
1928 | 350 rel: |
351 relunit tAGO | |
352 { | |
353 PC.rel_seconds = -PC.rel_seconds; | |
354 PC.rel_minutes = -PC.rel_minutes; | |
355 PC.rel_hour = -PC.rel_hour; | |
356 PC.rel_day = -PC.rel_day; | |
357 PC.rel_month = -PC.rel_month; | |
358 PC.rel_year = -PC.rel_year; | |
359 } | |
360 | relunit | |
361 ; | |
9 | 362 |
1928 | 363 relunit: |
364 tUNUMBER tYEAR_UNIT | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
365 { PC.rel_year += $1.value * $2; } |
1928 | 366 | tSNUMBER tYEAR_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
367 { PC.rel_year += $1.value * $2; } |
1928 | 368 | tYEAR_UNIT |
369 { PC.rel_year += $1; } | |
370 | tUNUMBER tMONTH_UNIT | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
371 { PC.rel_month += $1.value * $2; } |
1928 | 372 | tSNUMBER tMONTH_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
373 { PC.rel_month += $1.value * $2; } |
1928 | 374 | tMONTH_UNIT |
375 { PC.rel_month += $1; } | |
376 | tUNUMBER tDAY_UNIT | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
377 { PC.rel_day += $1.value * $2; } |
1928 | 378 | tSNUMBER tDAY_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
379 { PC.rel_day += $1.value * $2; } |
1928 | 380 | tDAY_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
381 { PC.rel_day += $1 } |
1928 | 382 | tUNUMBER tHOUR_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
383 { PC.rel_hour += $1.value * $2; } |
1928 | 384 | tSNUMBER tHOUR_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
385 { PC.rel_hour += $1.value * $2; } |
1928 | 386 | tHOUR_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
387 { PC.rel_hour += $1 } |
1928 | 388 | tUNUMBER tMINUTE_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
389 { PC.rel_minutes += $1.value * $2; } |
1928 | 390 | tSNUMBER tMINUTE_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
391 { PC.rel_minutes += $1.value * $2; } |
1928 | 392 | tMINUTE_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
393 { PC.rel_minutes += $1 } |
1928 | 394 | tUNUMBER tSEC_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
395 { PC.rel_seconds += $1.value * $2; } |
1928 | 396 | tSNUMBER tSEC_UNIT |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
397 { PC.rel_seconds += $1.value * $2; } |
1928 | 398 | tSEC_UNIT |
399 { PC.rel_seconds += $1; } | |
400 ; | |
9 | 401 |
1928 | 402 number: |
403 tUNUMBER | |
404 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
405 if (PC.dates_seen |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
406 && ! PC.rels_seen && (PC.times_seen || 2 < $1.digits)) |
1928 | 407 PC.year = $1; |
408 else | |
409 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
410 if (4 < $1.digits) |
1928 | 411 { |
412 PC.dates_seen++; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
413 PC.day = $1.value % 100; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
414 PC.month = ($1.value / 100) % 100; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
415 PC.year.value = $1.value / 10000; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
416 PC.year.digits = $1.digits - 4; |
1928 | 417 } |
857 | 418 else |
419 { | |
1928 | 420 PC.times_seen++; |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
421 if ($1.digits <= 2) |
857 | 422 { |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
423 PC.hour = $1.value; |
1928 | 424 PC.minutes = 0; |
857 | 425 } |
426 else | |
427 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
428 PC.hour = $1.value / 100; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
429 PC.minutes = $1.value % 100; |
857 | 430 } |
1928 | 431 PC.seconds = 0; |
432 PC.meridian = MER24; | |
857 | 433 } |
434 } | |
1928 | 435 } |
436 ; | |
9 | 437 |
1928 | 438 o_merid: |
439 /* empty */ | |
440 { $$ = MER24; } | |
441 | tMERIDIAN | |
442 { $$ = $1; } | |
443 ; | |
9 | 444 |
445 %% | |
446 | |
1203 | 447 /* Include this file down here because bison inserts code above which |
448 may define-away `const'. We want the prototype for get_date to have | |
1928 | 449 the same signature as the function definition. */ |
1265 | 450 #include "getdate.h" |
1203 | 451 |
1928 | 452 #ifndef gmtime |
453 struct tm *gmtime (); | |
454 #endif | |
455 #ifndef localtime | |
456 struct tm *localtime (); | |
457 #endif | |
458 #ifndef mktime | |
459 time_t mktime (); | |
460 #endif | |
1203 | 461 |
1928 | 462 static table const meridian_table[] = |
463 { | |
464 { "AM", tMERIDIAN, MERam }, | |
465 { "A.M.", tMERIDIAN, MERam }, | |
466 { "PM", tMERIDIAN, MERpm }, | |
467 { "P.M.", tMERIDIAN, MERpm }, | |
468 { 0, 0, 0 } | |
469 }; | |
470 | |
471 static table const dst_table[] = | |
472 { | |
473 { "DST", tDST, 0 } | |
9 | 474 }; |
475 | |
1928 | 476 static table const month_and_day_table[] = |
477 { | |
478 { "JANUARY", tMONTH, 1 }, | |
479 { "FEBRUARY", tMONTH, 2 }, | |
480 { "MARCH", tMONTH, 3 }, | |
481 { "APRIL", tMONTH, 4 }, | |
482 { "MAY", tMONTH, 5 }, | |
483 { "JUNE", tMONTH, 6 }, | |
484 { "JULY", tMONTH, 7 }, | |
485 { "AUGUST", tMONTH, 8 }, | |
486 { "SEPTEMBER",tMONTH, 9 }, | |
487 { "SEPT", tMONTH, 9 }, | |
488 { "OCTOBER", tMONTH, 10 }, | |
489 { "NOVEMBER", tMONTH, 11 }, | |
490 { "DECEMBER", tMONTH, 12 }, | |
491 { "SUNDAY", tDAY, 0 }, | |
492 { "MONDAY", tDAY, 1 }, | |
493 { "TUESDAY", tDAY, 2 }, | |
494 { "TUES", tDAY, 2 }, | |
495 { "WEDNESDAY",tDAY, 3 }, | |
496 { "WEDNES", tDAY, 3 }, | |
497 { "THURSDAY", tDAY, 4 }, | |
498 { "THUR", tDAY, 4 }, | |
499 { "THURS", tDAY, 4 }, | |
500 { "FRIDAY", tDAY, 5 }, | |
501 { "SATURDAY", tDAY, 6 }, | |
502 { 0, 0, 0 } | |
503 }; | |
504 | |
505 static table const time_units_table[] = | |
506 { | |
507 { "YEAR", tYEAR_UNIT, 1 }, | |
508 { "MONTH", tMONTH_UNIT, 1 }, | |
509 { "FORTNIGHT",tDAY_UNIT, 14 }, | |
510 { "WEEK", tDAY_UNIT, 7 }, | |
511 { "DAY", tDAY_UNIT, 1 }, | |
512 { "HOUR", tHOUR_UNIT, 1 }, | |
513 { "MINUTE", tMINUTE_UNIT, 1 }, | |
514 { "MIN", tMINUTE_UNIT, 1 }, | |
515 { "SECOND", tSEC_UNIT, 1 }, | |
516 { "SEC", tSEC_UNIT, 1 }, | |
517 { 0, 0, 0 } | |
9 | 518 }; |
519 | |
520 /* Assorted relative-time words. */ | |
1928 | 521 static table const relative_time_table[] = |
522 { | |
523 { "TOMORROW", tMINUTE_UNIT, 24 * 60 }, | |
524 { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) }, | |
525 { "TODAY", tMINUTE_UNIT, 0 }, | |
526 { "NOW", tMINUTE_UNIT, 0 }, | |
527 { "LAST", tUNUMBER, -1 }, | |
1931
42ae6b089943
(relative_time_table): Change `type' of `THIS' from
Jim Meyering <jim@meyering.net>
parents:
1930
diff
changeset
|
528 { "THIS", tUNUMBER, 0 }, |
1928 | 529 { "NEXT", tUNUMBER, 1 }, |
530 { "FIRST", tUNUMBER, 1 }, | |
531 /*{ "SECOND", tUNUMBER, 2 }, */ | |
532 { "THIRD", tUNUMBER, 3 }, | |
533 { "FOURTH", tUNUMBER, 4 }, | |
534 { "FIFTH", tUNUMBER, 5 }, | |
535 { "SIXTH", tUNUMBER, 6 }, | |
536 { "SEVENTH", tUNUMBER, 7 }, | |
537 { "EIGHTH", tUNUMBER, 8 }, | |
538 { "NINTH", tUNUMBER, 9 }, | |
539 { "TENTH", tUNUMBER, 10 }, | |
540 { "ELEVENTH", tUNUMBER, 11 }, | |
541 { "TWELFTH", tUNUMBER, 12 }, | |
542 { "AGO", tAGO, 1 }, | |
543 { 0, 0, 0 } | |
9 | 544 }; |
545 | |
1928 | 546 /* The time zone table. This table is necessarily incomplete, as time |
547 zone abbreviations are ambiguous; e.g. Australians interpret "EST" | |
548 as Eastern time in Australia, not as US Eastern Standard Time. | |
549 You cannot rely on getdate to handle arbitrary time zone | |
550 abbreviations; use numeric abbreviations like `-0500' instead. */ | |
551 static table const time_zone_table[] = | |
552 { | |
553 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */ | |
554 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ | |
555 { "UTC", tZONE, HOUR ( 0) }, | |
556 { "WET", tZONE, HOUR ( 0) }, /* Western European */ | |
557 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */ | |
558 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */ | |
559 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */ | |
560 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */ | |
561 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */ | |
562 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */ | |
563 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */ | |
564 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */ | |
565 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */ | |
566 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */ | |
567 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */ | |
568 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */ | |
569 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */ | |
570 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */ | |
571 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */ | |
572 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */ | |
573 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */ | |
574 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */ | |
575 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */ | |
576 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */ | |
577 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */ | |
578 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */ | |
579 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */ | |
580 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */ | |
581 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */ | |
582 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */ | |
583 { "CET", tZONE, HOUR ( 1) }, /* Central European */ | |
584 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */ | |
585 { "MET", tZONE, HOUR ( 1) }, /* Middle European */ | |
586 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */ | |
587 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ | |
588 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ | |
589 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */ | |
590 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */ | |
591 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */ | |
592 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */ | |
593 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */ | |
594 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */ | |
595 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */ | |
596 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */ | |
597 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */ | |
598 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */ | |
599 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */ | |
600 { "GST", tZONE, HOUR (10) }, /* Guam Standard */ | |
601 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */ | |
602 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */ | |
603 { 0, 0, 0 } | |
9 | 604 }; |
605 | |
1928 | 606 /* Military time zone table. */ |
607 static table const military_table[] = | |
608 { | |
609 { "A", tZONE, -HOUR ( 1) }, | |
610 { "B", tZONE, -HOUR ( 2) }, | |
611 { "C", tZONE, -HOUR ( 3) }, | |
612 { "D", tZONE, -HOUR ( 4) }, | |
613 { "E", tZONE, -HOUR ( 5) }, | |
614 { "F", tZONE, -HOUR ( 6) }, | |
615 { "G", tZONE, -HOUR ( 7) }, | |
616 { "H", tZONE, -HOUR ( 8) }, | |
617 { "I", tZONE, -HOUR ( 9) }, | |
618 { "K", tZONE, -HOUR (10) }, | |
619 { "L", tZONE, -HOUR (11) }, | |
620 { "M", tZONE, -HOUR (12) }, | |
621 { "N", tZONE, HOUR ( 1) }, | |
622 { "O", tZONE, HOUR ( 2) }, | |
623 { "P", tZONE, HOUR ( 3) }, | |
624 { "Q", tZONE, HOUR ( 4) }, | |
625 { "R", tZONE, HOUR ( 5) }, | |
626 { "S", tZONE, HOUR ( 6) }, | |
627 { "T", tZONE, HOUR ( 7) }, | |
628 { "U", tZONE, HOUR ( 8) }, | |
629 { "V", tZONE, HOUR ( 9) }, | |
630 { "W", tZONE, HOUR (10) }, | |
631 { "X", tZONE, HOUR (11) }, | |
632 { "Y", tZONE, HOUR (12) }, | |
633 { "Z", tZONE, HOUR ( 0) }, | |
634 { 0, 0, 0 } | |
9 | 635 }; |
636 | |
637 | |
638 | |
16
01c6d40adf9d
Make tables static and const when possible.
Jim Meyering <jim@meyering.net>
parents:
9
diff
changeset
|
639 static int |
1928 | 640 to_hour (int hours, int meridian) |
9 | 641 { |
1928 | 642 switch (meridian) |
857 | 643 { |
644 case MER24: | |
1928 | 645 return 0 <= hours && hours < 24 ? hours : -1; |
857 | 646 case MERam: |
1928 | 647 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1; |
857 | 648 case MERpm: |
1928 | 649 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1; |
857 | 650 default: |
651 abort (); | |
652 } | |
303 | 653 /* NOTREACHED */ |
9 | 654 } |
655 | |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
656 static int |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
657 to_year (textint textyear) |
9 | 658 { |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
659 int year = textyear.value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
660 |
1928 | 661 if (year < 0) |
662 year = -year; | |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
663 |
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
664 /* XPG4 suggests that years 00-68 map to 2000-2068, and |
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
665 years 69-99 map to 1969-1999. */ |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
666 if (textyear.digits == 2) |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
667 year += year < 69 ? 2000 : 1900; |
9 | 668 |
1928 | 669 return year; |
9 | 670 } |
671 | |
1928 | 672 static table const * |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
673 lookup_zone (parser_control const *pc, char const *name) |
9 | 674 { |
1928 | 675 table const *tp; |
857 | 676 |
1928 | 677 /* Try local zone abbreviations first; they're more likely to be right. */ |
678 for (tp = pc->local_time_zone_table; tp->name; tp++) | |
679 if (strcmp (name, tp->name) == 0) | |
680 return tp; | |
9 | 681 |
1928 | 682 for (tp = time_zone_table; tp->name; tp++) |
683 if (strcmp (name, tp->name) == 0) | |
684 return tp; | |
857 | 685 |
1928 | 686 return 0; |
9 | 687 } |
688 | |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
689 #if ! HAVE_TM_GMTOFF |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
690 /* Yield the difference between *A and *B, |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
691 measured in seconds, ignoring leap seconds. |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
692 The body of this function is taken directly from the GNU C Library; |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
693 see src/strftime.c. */ |
16
01c6d40adf9d
Make tables static and const when possible.
Jim Meyering <jim@meyering.net>
parents:
9
diff
changeset
|
694 static int |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
695 tm_diff (struct tm const *a, struct tm const *b) |
207
25a5ae7fce09
Revert 1.14-1.16 changes that removed difftm and modified get_date.
Jim Meyering <jim@meyering.net>
parents:
202
diff
changeset
|
696 { |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
697 /* Compute intervening leap days correctly even if year is negative. |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
698 Take care to avoid int overflow in leap day calculations, |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
699 but it's OK to assume that A and B are close to each other. */ |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
700 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3); |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
701 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3); |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
702 int a100 = a4 / 25 - (a4 % 25 < 0); |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
703 int b100 = b4 / 25 - (b4 % 25 < 0); |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
704 int a400 = a100 >> 2; |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
705 int b400 = b100 >> 2; |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
706 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
707 int years = a->tm_year - b->tm_year; |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
708 int days = (365 * years + intervening_leap_days |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
709 + (a->tm_yday - b->tm_yday)); |
857 | 710 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) |
711 + (a->tm_min - b->tm_min)) | |
207
25a5ae7fce09
Revert 1.14-1.16 changes that removed difftm and modified get_date.
Jim Meyering <jim@meyering.net>
parents:
202
diff
changeset
|
712 + (a->tm_sec - b->tm_sec)); |
25a5ae7fce09
Revert 1.14-1.16 changes that removed difftm and modified get_date.
Jim Meyering <jim@meyering.net>
parents:
202
diff
changeset
|
713 } |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
714 #endif /* ! HAVE_TM_GMTOFF */ |
207
25a5ae7fce09
Revert 1.14-1.16 changes that removed difftm and modified get_date.
Jim Meyering <jim@meyering.net>
parents:
202
diff
changeset
|
715 |
1928 | 716 static table const * |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
717 lookup_word (parser_control const *pc, char *word) |
1928 | 718 { |
719 char *p; | |
720 char *q; | |
721 size_t wordlen; | |
722 table const *tp; | |
723 int i; | |
724 int abbrev; | |
725 | |
726 /* Make it uppercase. */ | |
727 for (p = word; *p; p++) | |
728 if (ISLOWER ((unsigned char) *p)) | |
729 *p = toupper ((unsigned char) *p); | |
730 | |
731 for (tp = meridian_table; tp->name; tp++) | |
732 if (strcmp (word, tp->name) == 0) | |
733 return tp; | |
734 | |
735 /* See if we have an abbreviation for a month. */ | |
736 wordlen = strlen (word); | |
737 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.'); | |
738 | |
739 for (tp = month_and_day_table; tp->name; tp++) | |
740 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0) | |
741 return tp; | |
742 | |
743 if ((tp = lookup_zone (pc, word))) | |
744 return tp; | |
745 | |
746 if (strcmp (word, dst_table[0].name) == 0) | |
747 return dst_table; | |
748 | |
749 for (tp = time_units_table; tp->name; tp++) | |
750 if (strcmp (word, tp->name) == 0) | |
751 return tp; | |
752 | |
753 /* Strip off any plural and try the units table again. */ | |
754 if (word[wordlen - 1] == 'S') | |
755 { | |
756 word[wordlen - 1] = '\0'; | |
757 for (tp = time_units_table; tp->name; tp++) | |
758 if (strcmp (word, tp->name) == 0) | |
759 return tp; | |
760 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */ | |
761 } | |
762 | |
763 for (tp = relative_time_table; tp->name; tp++) | |
764 if (strcmp (word, tp->name) == 0) | |
765 return tp; | |
766 | |
767 /* Military time zones. */ | |
768 if (wordlen == 1) | |
769 for (tp = military_table; tp->name; tp++) | |
770 if (word[0] == tp->name[0]) | |
771 return tp; | |
772 | |
773 /* Drop out any periods and try the time zone table again. */ | |
774 for (i = 0, p = q = word; (*p = *q); q++) | |
775 if (*q == '.') | |
776 i = 1; | |
777 else | |
778 p++; | |
779 if (i && (tp = lookup_zone (pc, word))) | |
780 return tp; | |
781 | |
782 return 0; | |
783 } | |
784 | |
785 static int | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
786 yylex (YYSTYPE *lvalp, parser_control *pc) |
1928 | 787 { |
788 unsigned char c; | |
789 int count; | |
790 | |
791 for (;;) | |
792 { | |
793 while (c = *pc->input, ISSPACE (c)) | |
794 pc->input++; | |
795 | |
796 if (ISDIGIT (c) || c == '-' || c == '+') | |
797 { | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
798 char const *p; |
1928 | 799 int sign; |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
800 int value; |
1928 | 801 if (c == '-' || c == '+') |
802 { | |
803 sign = c == '-' ? -1 : 1; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
804 c = *++pc->input; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
805 if (! ISDIGIT (c)) |
1928 | 806 /* skip the '-' sign */ |
807 continue; | |
808 } | |
809 else | |
810 sign = 0; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
811 p = pc->input; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
812 value = 0; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
813 do |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
814 { |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
815 value = 10 * value + c - '0'; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
816 c = *++p; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
817 } |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
818 while (ISDIGIT (c)); |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
819 lvalp->textintval.value = sign < 0 ? -value : value; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
820 lvalp->textintval.digits = p - pc->input; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
821 pc->input = p; |
1928 | 822 return sign ? tSNUMBER : tUNUMBER; |
823 } | |
824 | |
825 if (ISALPHA (c)) | |
826 { | |
827 char buff[20]; | |
828 char *p = buff; | |
829 table const *tp; | |
830 | |
831 do | |
832 { | |
833 if (p < buff + sizeof buff - 1) | |
834 *p++ = c; | |
835 c = *++pc->input; | |
836 } | |
837 while (ISALPHA (c) || c == '.'); | |
838 | |
839 *p = '\0'; | |
840 tp = lookup_word (pc, buff); | |
841 if (! tp) | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
842 return '?'; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
843 lvalp->intval = tp->value; |
1928 | 844 return tp->type; |
845 } | |
846 | |
847 if (c != '(') | |
848 return *pc->input++; | |
849 count = 0; | |
850 do | |
851 { | |
852 c = *pc->input++; | |
853 if (c == '\0') | |
854 return c; | |
855 if (c == '(') | |
856 count++; | |
857 else if (c == ')') | |
858 count--; | |
859 } | |
860 while (count > 0); | |
861 } | |
862 } | |
863 | |
864 /* Do nothing if the parser reports an error. */ | |
865 static int | |
866 yyerror (char *s ATTRIBUTE_UNUSED) | |
867 { | |
868 return 0; | |
869 } | |
870 | |
1986
eaeb35566cf8
update a comment from alpha.gnu.org:/home/gd/gnu/lib/getdate.y
Jim Meyering <jim@meyering.net>
parents:
1962
diff
changeset
|
871 /* Parse a date/time string P. Return the corresponding time_t value, |
eaeb35566cf8
update a comment from alpha.gnu.org:/home/gd/gnu/lib/getdate.y
Jim Meyering <jim@meyering.net>
parents:
1962
diff
changeset
|
872 or (time_t) -1 if there is an error. P can be an incomplete or |
eaeb35566cf8
update a comment from alpha.gnu.org:/home/gd/gnu/lib/getdate.y
Jim Meyering <jim@meyering.net>
parents:
1962
diff
changeset
|
873 relative time specification; if so, use *NOW as the basis for the |
eaeb35566cf8
update a comment from alpha.gnu.org:/home/gd/gnu/lib/getdate.y
Jim Meyering <jim@meyering.net>
parents:
1962
diff
changeset
|
874 returned time. */ |
9 | 875 time_t |
1203 | 876 get_date (const char *p, const time_t *now) |
9 | 877 { |
1928 | 878 time_t Start = now ? *now : time (0); |
879 struct tm *tmp = localtime (&Start); | |
880 struct tm tm; | |
881 struct tm tm0; | |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
882 parser_control pc; |
9 | 883 |
1928 | 884 if (! tmp) |
303 | 885 return -1; |
9 | 886 |
1928 | 887 pc.input = p; |
2280
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
888 pc.year.value = tmp->tm_year + TM_YEAR_BASE; |
adaf08e40364
Handle two-digit years with leading zeros correctly.
Jim Meyering <jim@meyering.net>
parents:
2110
diff
changeset
|
889 pc.year.digits = 4; |
1928 | 890 pc.month = tmp->tm_mon + 1; |
891 pc.day = tmp->tm_mday; | |
892 pc.hour = tmp->tm_hour; | |
893 pc.minutes = tmp->tm_min; | |
894 pc.seconds = tmp->tm_sec; | |
895 tm.tm_isdst = tmp->tm_isdst; | |
896 | |
897 pc.meridian = MER24; | |
898 pc.rel_seconds = 0; | |
899 pc.rel_minutes = 0; | |
900 pc.rel_hour = 0; | |
901 pc.rel_day = 0; | |
902 pc.rel_month = 0; | |
903 pc.rel_year = 0; | |
904 pc.dates_seen = 0; | |
905 pc.days_seen = 0; | |
906 pc.rels_seen = 0; | |
907 pc.times_seen = 0; | |
908 pc.local_zones_seen = 0; | |
909 pc.zones_seen = 0; | |
910 | |
911 #if HAVE_TM_ZONE | |
912 pc.local_time_zone_table[0].name = tmp->tm_zone; | |
913 pc.local_time_zone_table[0].type = tLOCAL_ZONE; | |
914 pc.local_time_zone_table[0].value = tmp->tm_isdst; | |
915 pc.local_time_zone_table[1].name = 0; | |
916 | |
917 /* Probe the names used in the next three calendar quarters, looking | |
918 for a tm_isdst different from the one we already have. */ | |
919 { | |
1929
f7d4ee7478d7
(get_date): Rename outermost local `probe' to `quarter'.
Jim Meyering <jim@meyering.net>
parents:
1928
diff
changeset
|
920 int quarter; |
f7d4ee7478d7
(get_date): Rename outermost local `probe' to `quarter'.
Jim Meyering <jim@meyering.net>
parents:
1928
diff
changeset
|
921 for (quarter = 1; quarter <= 3; quarter++) |
1928 | 922 { |
1929
f7d4ee7478d7
(get_date): Rename outermost local `probe' to `quarter'.
Jim Meyering <jim@meyering.net>
parents:
1928
diff
changeset
|
923 time_t probe = Start + quarter * (90 * 24 * 60 * 60); |
1930
92632825178b
(get_date): Rename latter local `tm' to probe_tm.
Jim Meyering <jim@meyering.net>
parents:
1929
diff
changeset
|
924 struct tm *probe_tm = localtime (&probe); |
92632825178b
(get_date): Rename latter local `tm' to probe_tm.
Jim Meyering <jim@meyering.net>
parents:
1929
diff
changeset
|
925 if (probe_tm && probe_tm->tm_zone |
92632825178b
(get_date): Rename latter local `tm' to probe_tm.
Jim Meyering <jim@meyering.net>
parents:
1929
diff
changeset
|
926 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value) |
1928 | 927 { |
928 { | |
1930
92632825178b
(get_date): Rename latter local `tm' to probe_tm.
Jim Meyering <jim@meyering.net>
parents:
1929
diff
changeset
|
929 pc.local_time_zone_table[1].name = probe_tm->tm_zone; |
1928 | 930 pc.local_time_zone_table[1].type = tLOCAL_ZONE; |
1930
92632825178b
(get_date): Rename latter local `tm' to probe_tm.
Jim Meyering <jim@meyering.net>
parents:
1929
diff
changeset
|
931 pc.local_time_zone_table[1].value = probe_tm->tm_isdst; |
1928 | 932 pc.local_time_zone_table[2].name = 0; |
933 } | |
934 break; | |
935 } | |
936 } | |
937 } | |
938 #else | |
939 #if HAVE_TZNAME | |
940 { | |
941 # ifndef tzname | |
942 extern char *tzname[]; | |
943 # endif | |
944 int i; | |
945 for (i = 0; i < 2; i++) | |
946 { | |
947 pc.local_time_zone_table[i].name = tzname[i]; | |
948 pc.local_time_zone_table[i].type = tLOCAL_ZONE; | |
949 pc.local_time_zone_table[i].value = i; | |
950 } | |
951 pc.local_time_zone_table[i].name = 0; | |
952 } | |
953 #else | |
954 pc.local_time_zone_table[0].name = 0; | |
955 #endif | |
956 #endif | |
957 | |
958 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name | |
959 && ! strcmp (pc.local_time_zone_table[0].name, | |
960 pc.local_time_zone_table[1].name)) | |
857 | 961 { |
1928 | 962 /* This locale uses the same abbrevation for standard and |
963 daylight times. So if we see that abbreviation, we don't | |
964 know whether it's daylight time. */ | |
965 pc.local_time_zone_table[0].value = -1; | |
966 pc.local_time_zone_table[1].name = 0; | |
967 } | |
968 | |
969 if (yyparse (&pc) != 0 | |
970 || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen | |
971 || 1 < (pc.local_zones_seen + pc.zones_seen) | |
972 || (pc.local_zones_seen && 1 < pc.local_isdst)) | |
973 return -1; | |
974 | |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
975 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year; |
1928 | 976 tm.tm_mon = pc.month - 1 + pc.rel_month; |
977 tm.tm_mday = pc.day + pc.rel_day; | |
978 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen)) | |
979 { | |
980 tm.tm_hour = to_hour (pc.hour, pc.meridian); | |
857 | 981 if (tm.tm_hour < 0) |
982 return -1; | |
1928 | 983 tm.tm_min = pc.minutes; |
984 tm.tm_sec = pc.seconds; | |
857 | 985 } |
986 else | |
987 { | |
988 tm.tm_hour = tm.tm_min = tm.tm_sec = 0; | |
989 } | |
1850
b6b8118c96e5
add the comment to go with last change
Jim Meyering <jim@meyering.net>
parents:
1849
diff
changeset
|
990 |
1928 | 991 /* Let mktime deduce tm_isdst if we have an absolute time stamp, |
992 or if the relative time stamp mentions days, months, or years. */ | |
3228
adeccf81e409
that's necessary when the offset spans a DST transition.
Jim Meyering <jim@meyering.net>
parents:
2588
diff
changeset
|
993 if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day |
adeccf81e409
that's necessary when the offset spans a DST transition.
Jim Meyering <jim@meyering.net>
parents:
2588
diff
changeset
|
994 | pc.rel_month | pc.rel_year) |
1849
d591bbc0e8aa
(get_date): Let mktime deduce tm_isdst if we
Jim Meyering <jim@meyering.net>
parents:
1785
diff
changeset
|
995 tm.tm_isdst = -1; |
1850
b6b8118c96e5
add the comment to go with last change
Jim Meyering <jim@meyering.net>
parents:
1849
diff
changeset
|
996 |
1928 | 997 /* But if the input explicitly specifies local time with or without |
998 DST, give mktime that information. */ | |
999 if (pc.local_zones_seen) | |
1000 tm.tm_isdst = pc.local_isdst; | |
1001 | |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1002 tm0 = tm; |
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1003 |
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1004 Start = mktime (&tm); |
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1005 |
857 | 1006 if (Start == (time_t) -1) |
1007 { | |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1008 |
857 | 1009 /* Guard against falsely reporting errors near the time_t boundaries |
1010 when parsing times in other time zones. For example, if the min | |
1011 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead | |
1012 of UTC, then the min localtime value is 1970-01-01 08:00:00; if | |
1013 we apply mktime to 1970-01-01 00:00:00 we will get an error, so | |
1014 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time | |
1015 zone by 24 hours to compensate. This algorithm assumes that | |
1016 there is no DST transition within a day of the time_t boundaries. */ | |
1928 | 1017 if (pc.zones_seen) |
857 | 1018 { |
1019 tm = tm0; | |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1020 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE) |
857 | 1021 { |
1022 tm.tm_mday++; | |
1928 | 1023 pc.time_zone += 24 * 60; |
857 | 1024 } |
1025 else | |
1026 { | |
1027 tm.tm_mday--; | |
1928 | 1028 pc.time_zone -= 24 * 60; |
857 | 1029 } |
1030 Start = mktime (&tm); | |
1031 } | |
1032 | |
1033 if (Start == (time_t) -1) | |
1034 return Start; | |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1035 } |
855
9c89b90524b8
(get_date): Change prototype to reflect const'ness of parameters.
Jim Meyering <jim@meyering.net>
parents:
852
diff
changeset
|
1036 |
1928 | 1037 if (pc.days_seen && ! pc.dates_seen) |
857 | 1038 { |
1928 | 1039 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 |
1040 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal))); | |
3228
adeccf81e409
that's necessary when the offset spans a DST transition.
Jim Meyering <jim@meyering.net>
parents:
2588
diff
changeset
|
1041 tm.tm_isdst = -1; |
857 | 1042 Start = mktime (&tm); |
1043 if (Start == (time_t) -1) | |
1044 return Start; | |
1045 } | |
9 | 1046 |
1928 | 1047 if (pc.zones_seen) |
857 | 1048 { |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1049 int delta = pc.time_zone * 60; |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1050 #ifdef HAVE_TM_GMTOFF |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1051 delta -= tm.tm_gmtoff; |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1052 #else |
1761
14b8e8de40c8
(get_date): Reuse tm_isdst of first localtime
Jim Meyering <jim@meyering.net>
parents:
1717
diff
changeset
|
1053 struct tm *gmt = gmtime (&Start); |
1928 | 1054 if (! gmt) |
1761
14b8e8de40c8
(get_date): Reuse tm_isdst of first localtime
Jim Meyering <jim@meyering.net>
parents:
1717
diff
changeset
|
1055 return -1; |
2080
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1056 delta -= tm_diff (&tm, gmt); |
32451d20b978
Sync tm_diff with the GNU C Library.
Jim Meyering <jim@meyering.net>
parents:
2048
diff
changeset
|
1057 #endif |
2048
75813b83df17
rewrite expression (equivalently) at request of Paul Eggert
Jim Meyering <jim@meyering.net>
parents:
2047
diff
changeset
|
1058 if ((Start < Start - delta) != (delta < 0)) |
1928 | 1059 return -1; /* time_t overflow */ |
1060 Start -= delta; | |
857 | 1061 } |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1062 |
2588
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1063 /* Add relative hours, minutes, and seconds. Ignore leap seconds; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1064 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1065 leap second. Typically this is not what the user wants, but it's |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1066 too hard to do it the other way, because the time zone indicator |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1067 must be applied before relative times, and if mktime is applied |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1068 again the time zone will be lost. */ |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1069 { |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1070 time_t t0 = Start; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1071 long d1 = 60 * 60 * (long) pc.rel_hour; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1072 time_t t1 = t0 + d1; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1073 long d2 = 60 * (long) pc.rel_minutes; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1074 time_t t2 = t1 + d2; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1075 int d3 = pc.rel_seconds; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1076 time_t t3 = t2 + d3; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1077 if ((d1 / (60 * 60) ^ pc.rel_hour) |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1078 | (d2 / 60 ^ pc.rel_minutes) |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1079 | ((t0 + d1 < t0) ^ (d1 < 0)) |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1080 | ((t1 + d2 < t1) ^ (d2 < 0)) |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1081 | ((t2 + d3 < t2) ^ (d3 < 0))) |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1082 return -1; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1083 Start = t3; |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1084 } |
17f2ecbac01c
(get_date): Apply relative times after time zone indicator, not before.
Jim Meyering <jim@meyering.net>
parents:
2280
diff
changeset
|
1085 |
852
2156a43352c1
1997-01-06 Paul Eggert <eggert@twinsun.com>
Jim Meyering <jim@meyering.net>
parents:
814
diff
changeset
|
1086 return Start; |
9 | 1087 } |
1088 | |
1928 | 1089 #if TEST |
9 | 1090 |
1928 | 1091 #include <stdio.h> |
1092 | |
202 | 1093 int |
1928 | 1094 main (int ac, char **av) |
9 | 1095 { |
1928 | 1096 char buff[BUFSIZ]; |
321 | 1097 time_t d; |
9 | 1098 |
1928 | 1099 printf ("Enter date, or blank line to exit.\n\t> "); |
1100 fflush (stdout); | |
321 | 1101 |
1928 | 1102 buff[BUFSIZ - 1] = 0; |
1103 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) | |
857 | 1104 { |
1928 | 1105 d = get_date (buff, 0); |
1106 if (d == (time_t) -1) | |
1107 printf ("Bad format - couldn't convert.\n"); | |
857 | 1108 else |
1928 | 1109 printf ("%s", ctime (&d)); |
1110 printf ("\t> "); | |
1111 fflush (stdout); | |
857 | 1112 } |
1928 | 1113 return 0; |
9 | 1114 } |
1928 | 1115 #endif /* defined TEST */ |