2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: tmdate.c /main/3 1995/11/01 18:53:46 rswiston $ */
24 /***************************************************************
26 * AT&T - PROPRIETARY *
28 * THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
31 * Copyright (c) 1995 AT&T Corp. *
32 * All Rights Reserved *
34 * This software is licensed by AT&T Corp. *
35 * under the terms and conditions of the license in *
36 * http://www.research.att.com/orgs/ssr/book/reuse *
38 * This software was created by the *
39 * Software Engineering Research Department *
40 * AT&T Bell Laboratories *
42 * For further information contact *
43 * gsf@research.att.com *
45 ***************************************************************/
47 /* : : generated by proto : : */
49 #if !defined(__PROTO__)
50 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
51 #if defined(__cplusplus)
52 #define __MANGLE__ "C"
57 #define __PROTO__(x) x
59 #define __PARAM__(n,o) n
60 #if !defined(__STDC__) && !defined(__cplusplus)
61 #if !defined(c_plusplus)
72 #define __PROTO__(x) ()
73 #define __OTORP__(x) x
74 #define __PARAM__(n,o) o
82 #if defined(__cplusplus) || defined(c_plusplus)
83 #define __VARARG__ ...
87 #if defined(__STDARG__)
88 #define __VA_START__(p,a) va_start(p,a)
90 #define __VA_START__(p,a) va_start(p)
97 #define dig2(s,n) ((n)=((*(s)++)-'0')*10,(n)+=(*(s)++)-'0')
98 #define dig3(s,n) ((n)=((*(s)++)-'0')*100,(n)+=((*(s)++)-'0')*10,(n)+=(*(s)++)-'0')
111 #define YYMMDDHHMMSS (1<<11)
115 * parse date expression in s and return time_t value
117 * if non-null, e points to the first invalid sequence in s
118 * clock provides default values
122 tmdate __PARAM__((register const char* s, char** e, time_t* clock), (s, e, clock)) __OTORP__(register const char* s; char** e; time_t* clock;){
142 * use clock for defaults
146 tm_info.date = tm_info.zone;
153 * get <weekday year month day hour minutes seconds ?[ds]t [ap]m>
158 state &= (state & HOLD) ? ~(HOLD) : ~(EXACT|LAST|NEXT|THIS);
160 while (isspace(*s) || *s == ',' || *s == '-') s++;
161 if (!*(last = (char*)s)) break;
164 if (!isdigit(*++s)) break;
165 now = strtol(s, &t, 0);
172 n = strtol(s, &t, 10);
173 if (!(state & (LAST|NEXT|THIS)) && ((i = t - s) == 4 && *t == '.' || i > 4))
176 * various date(1) formats
178 * [yy[mm]]ddhhmm[.ss]
183 if (state & YYMMDDHHMMSS) break;
184 state |= YYMMDDHHMMSS;
187 if (dig2(s, m) < 38) m += 100;
196 if (i < 10) m = tm->tm_year;
197 else if (dig2(s, m) < 38) m += 100;
198 if ((t - s) < 8) l = tm->tm_mon;
199 else if (dig2(s, l) <= 0 || l > 12) break;
200 if ((t - s) < 6) k = tm->tm_mon;
201 else if (dig2(s, k) < 1 || k > 31) break;
202 if ((t - s) < 4) break;
203 if (dig2(s, j) > 24) break;
204 if (dig2(s, i) > 59) break;
205 if ((t - s) == 2) dig2(s, n);
206 else if (t - s) break;
207 else if (*t != '.') n = 0;
208 else n = strtol(t + 1, &t, 10);
209 if (n > (59 + TM_MAXLEAP)) break;
223 if ((state & HOUR) || n > 24 || *s++ != ':' || !isdigit(*s)) break;
225 n = strtol(s, &t, 10);
231 if (!isdigit(*++s)) break;
232 n = strtol(s, &t, 10);
234 if (n > (59 + TM_MAXLEAP)) break;
243 while (isspace(*s) || *s == ',' || *s == '-') s++;
244 if (isalpha(*s) && n < 1000)
246 if ((j = tmlex(s, &t, tm_info.format, TM_NFORM, tm_info.format + TM_SUFFIXES, TM_PARTS - TM_SUFFIXES)) >= 0)
249 switch (tm_data.lex[j])
267 if (n > 24) goto done;
270 if (j == TM_MERIDIAN)
272 if (tm->tm_hour == 12) tm->tm_hour = 0;
274 else if (tm->tm_hour < 12) tm->tm_hour += 12;
275 if (n > 0) goto clear_min;
278 j += TM_DAY - TM_DAY_3;
285 if (!(state & (LAST|NEXT|THIS))) for (;;)
287 while (isspace(*s) || *s == ',') s++;
288 if ((k = tmlex(s, &t, tm_info.format + TM_LAST, TM_NOISE - TM_LAST, NiL, 0)) >= 0)
291 if (k <= 2) state |= LAST;
292 else if (k <= 5) state |= THIS;
293 else if (k <= 8) state |= NEXT;
298 if (state & LAST) n = -n;
299 else if (!(state & NEXT)) n--;
323 tm->tm_mday += 7 * n - tm->tm_wday + 1;
347 j -= tm->tm_wday + TM_DAY;
348 if (state & (LAST|NEXT|THIS))
352 else if (j > 0) j -= 7;
353 tm->tm_mday += j + n * 7;
354 if (state & (LAST|NEXT|THIS)) goto clear_hour;
359 j += TM_MONTH - TM_MONTH_3;
362 if (state & MONTH) goto done;
365 tm->tm_mon = j - TM_MONTH;
368 while (isspace(*s) || *s == ',' || *s == '-') s++;
371 n = strtol(s, &t, 10);
378 if (n > 31) goto done;
382 if (state & (LAST|NEXT|THIS))
389 if (state & ZONE) goto done;
391 zone += tmgoff(s, &t, 0);
398 dst = tm_info.zone->dst;
399 zone = tm_info.zone->west;
401 zone += tmgoff(s, &t, dst);
410 if (!(state & ZONE) && (zp = tmzone(s, &t, type, &dst)))
413 zone += zp->west + dst;
418 if (!type && (zp = tmtype(s, &t)))
428 if (!isdigit(*++s) || (state & MONTH) || n == 0 || n > 12) break;
430 n = strtol(s, &t, 10);
432 if (n <= 0 || n > 31) break;
433 if (*s == '/' && !isdigit(*(s + 1))) break;
440 n = strtol(s + 1, &t, 10);
445 if (state & (LAST|NEXT|THIS))
448 if (state & LAST) tm->tm_year -= (tm->tm_mon < n) ? 0 : 1;
449 else tm->tm_year += ((state & NEXT) ? 1 : 0) + ((tm->tm_mon < n) ? 1 : 0);
450 if (state & MDAY) goto clear_hour;
456 if (n < 0 || (state & YEAR)) break;
458 if (n > 1900) n -= 1900;
459 if (n < 38) n += 100;
468 if (state & EXACT) continue;
471 if (state & EXACT) continue;
474 if (state & EXACT) continue;
477 if (state & EXACT) continue;
480 if (state & EXACT) continue;
485 return(tmtime(tmfix(tm), (state & ZONE) ? zone : TM_LOCALZONE));