Convert uses of XKeycodeToKeysym (deprecated) to XkbKeycodeToKeysym
[oweals/cde.git] / cde / programs / dtcm / libDtCmP / getdate.y
1 /*******************************************************************************
2 **
3 **  getdate.y
4 **
5 **  $XConsortium: getdate.y /main/3 1995/11/03 10:38:01 rswiston $
6 **
7 **  RESTRICTED CONFIDENTIAL INFORMATION:
8 **
9 **  The information in this document is subject to special
10 **  restrictions in a confidential disclosure agreement between
11 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
12 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
13 **  Sun's specific written approval.  This document and all copies
14 **  and derivative works thereof must be returned or destroyed at
15 **  Sun's request.
16 **
17 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
18 **
19 *******************************************************************************/
20
21 /*                                                                      *
22  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
23  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
24  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
25  * (c) Copyright 1993, 1994 Novell, Inc.                                *
26  */
27
28
29 %{
30 #ifndef lint
31 __attribute__((unused))
32 static  char sccsid[] = "@(#)getdate.y 1.10 94/11/07 Copyr 1993 Sun Microsystems, Inc.";
33 #endif
34 %}
35
36 %token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
37 %{
38         /*      Steven M. Bellovin (unc!smb)                    */
39         /*      Dept. of Computer Science                       */
40         /*      University of North Carolina at Chapel Hill     */
41         /*      @(#)getdate.y   2.6     4/20/84 */
42
43 #include <EUSCompat.h>
44 #include <ctype.h>
45 #include <string.h>
46 #include <time.h>
47 #include "getdate.h"
48 #ifdef SVR4
49 #include <sys/time.h>
50 #endif /* SVR4 */
51
52 #ifndef NULL
53 #define NULL    0
54 #endif
55
56 #define daysec (24L*60L*60L)
57         static int timeflag, zoneflag, dateflag, dayflag, relflag;
58         static time_t relsec, relmonth;
59         static int hh, mm, ss, merid, daylightsavings;
60         static int dayord, dayreq;
61         static int month, day, year;
62         static int noyear;
63         static int ourzone;
64 #define AM 1
65 #define PM 2
66 #define DAYLIGHT 1
67 #define STANDARD 2
68 #define MAYBE    3
69
70 #ifdef SVR4
71 extern long timezone;
72 #endif
73
74 %}
75
76 %%
77 timedate:               /* empty */
78         | timedate item;
79
80 item:   tspec
81                 {timeflag++;}
82         | zone
83                 {zoneflag++;}
84         | dtspec
85                 {dateflag++;}
86         | dyspec
87                 {dayflag++;}
88         | rspec
89                 {relflag++;}
90         | nspec;
91
92 nspec:  NUMBER
93                 {if (timeflag && dateflag && !relflag) year = $1;
94                 else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
95
96 tspec:  NUMBER MERIDIAN
97                 {hh = $1; mm = 0; ss = 0; merid = $2;}
98         | NUMBER ':' NUMBER
99                 {hh = $1; mm = $3; merid = 24;}
100         | NUMBER ':' NUMBER MERIDIAN
101                 {hh = $1; mm = $3; merid = $4;}
102         | NUMBER ':' NUMBER ':' NUMBER
103                 {hh = $1; mm = $3; ss = $5; merid = 24;}
104         | NUMBER ':' NUMBER ':' NUMBER MERIDIAN
105                 {hh = $1; mm = $3; ss = $5; merid = $6;};
106
107 zone:   ZONE
108                 {ourzone = $1; daylightsavings = STANDARD;}
109         | DAYZONE
110                 {ourzone = $1; daylightsavings = DAYLIGHT;};
111
112 dyspec: DAY
113                 {dayord = 1; dayreq = $1;}
114         | DAY ','
115                 {dayord = 1; dayreq = $1;}
116         | NUMBER ' ' DAY
117                 {dayord = $1; dayreq = $3;};
118
119 dtspec: NUMBER '/' NUMBER
120                 {month = $1; day = $3; noyear = 1;}
121         | NUMBER '/' NUMBER '/' NUMBER
122                 {month = $1; day = $3; year = $5;}
123         | NUMBER '-' NUMBER
124                 {month = $1; day = $3; noyear = 1;}
125         | NUMBER '-' NUMBER '-' NUMBER
126                 {month = $1; day = $3; year = $5;}
127         | MONTH NUMBER
128                 {month = $1; day = $2; noyear = 1;}
129         | MONTH NUMBER ',' NUMBER
130                 {month = $1; day = $2; year = $4;}
131         | NUMBER ' ' MONTH
132                 {month = $3; day = $1; noyear = 1;}
133         | NUMBER ' ' MONTH ' ' NUMBER
134                 {month = $3; day = $1; year = $5;};
135
136
137 rspec:  NUMBER ' ' UNIT
138                 {relsec +=  60L * $1 * $3;}
139         | NUMBER ' ' MUNIT
140                 {relmonth += $1 * $3;}
141         | NUMBER ' ' SUNIT
142                 {relsec += $1;}
143         | UNIT
144                 {relsec +=  60L * $1;}
145         | MUNIT
146                 {relmonth += $1;}
147         | SUNIT
148                 {relsec++;}
149         | rspec AGO
150                 {relsec = -relsec; relmonth = -relmonth;};
151 %%
152
153 static int mdays[12] =
154         {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
155 #define epoch BOT_YEAR
156
157 extern struct tm *localtime();
158 time_t dateconv(int mm, 
159     int dd, 
160     int yy, 
161     int h, 
162     int m, 
163     int s, 
164     int mer, 
165     int zone, 
166     int dayflag)
167 {
168         time_t tod, jdate;
169         int i;
170
171         if (yy < 0) yy = -yy;
172
173         if (yy < 70)
174                 yy += 2000;
175         else if (yy < 100)
176                 yy += 1900;
177
178         mdays[1] = 28 + (yy%4 == 0);
179
180         if (yy < epoch)
181                 return(DATE_BBOT);
182
183         if (yy > EOT_YEAR)
184                 return(DATE_AEOT);
185
186         if (mm < 1 || mm > 12)
187                 return(DATE_BMONTH);
188
189         if (dd < 1 || dd > mdays[--mm])
190                 return(DATE_BDAY);
191
192         jdate = dd-1;
193         for (i=0; i<mm; i++) jdate += mdays[i];
194         for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
195         jdate *= daysec;
196         jdate += zone * 60L;
197         if ((tod = timeconv(h, m, s, mer)) < 0) return (tod);
198         jdate += tod;
199         if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
200                 jdate += -1*60*60;
201         return (jdate);
202 }
203
204 time_t dayconv(int ord, int day, time_t now)
205 {
206         struct tm *loctime;
207         time_t tod;
208
209         tod = now;
210         loctime = localtime(&tod);
211         tod += daysec * ((day - loctime->tm_wday + 7) % 7);
212         tod += 7*daysec*(ord<=0?ord:ord-1);
213         return daylcorr(tod, now);
214 }
215
216 time_t timeconv(int hh, int mm, int ss, int mer)
217 {
218         if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (DATE_BMIN);
219         switch (mer) {
220                 case AM: if (hh < 1 || hh > 12) return(DATE_BHOUR);
221                          return (60L * ((hh%12)*60L + mm)+ss);
222                 case PM: if (hh < 1 || hh > 12) return(DATE_BHOUR);
223                          return (60L * ((hh%12 +12)*60L + mm)+ss);
224                 case 24: if (hh < 0 || hh > 23) return (DATE_BHOUR);
225                          return (60L * (hh*60L + mm)+ss);
226                 default: return (DATE_CONV);
227         }
228 }
229 time_t monthadd(time_t sdate, time_t relmonth)
230 {
231         struct tm *ltime;
232         int mm, yy;
233
234         if (relmonth == 0) return 0;
235         ltime = localtime(&sdate);
236         mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
237         yy = mm/12;
238         mm = mm%12 + 1;
239         return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
240                 ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
241 }
242
243 time_t daylcorr(time_t future, time_t now)
244 {
245         int fdayl, nowdayl;
246
247         nowdayl = (localtime(&now)->tm_hour+1) % 24;
248         fdayl = (localtime(&future)->tm_hour+1) % 24;
249         return (future-now) + 60L*60L*(nowdayl-fdayl);
250 }
251
252 struct table {
253         char *name;
254         int type, value;
255 };
256
257 struct table mdtab[] = {
258         {"January", MONTH, 1},
259         {"February", MONTH, 2},
260         {"March", MONTH, 3},
261         {"April", MONTH, 4},
262         {"May", MONTH, 5},
263         {"June", MONTH, 6},
264         {"July", MONTH, 7},
265         {"August", MONTH, 8},
266         {"September", MONTH, 9},
267         {"Sept", MONTH, 9},
268         {"October", MONTH, 10},
269         {"November", MONTH, 11},
270         {"December", MONTH, 12},
271
272         {"Sunday", DAY, 0},
273         {"Monday", DAY, 1},
274         {"Tuesday", DAY, 2},
275         {"Tues", DAY, 2},
276         {"Wednesday", DAY, 3},
277         {"Wednes", DAY, 3},
278         {"Thursday", DAY, 4},
279         {"Thur", DAY, 4},
280         {"Thurs", DAY, 4},
281         {"Friday", DAY, 5},
282         {"Saturday", DAY, 6},
283         {0, 0, 0}};
284
285 #define HRS *60
286 #define HALFHR 30
287 struct table mztab[] = {
288         {"a.m.", MERIDIAN, AM},
289         {"am", MERIDIAN, AM},
290         {"p.m.", MERIDIAN, PM},
291         {"pm", MERIDIAN, PM},
292         {"nst", ZONE, 3 HRS + HALFHR},          /* Newfoundland */
293         {"n.s.t.", ZONE, 3 HRS + HALFHR},
294         {"ast", ZONE, 4 HRS},           /* Atlantic */
295         {"a.s.t.", ZONE, 4 HRS},
296         {"adt", DAYZONE, 4 HRS},
297         {"a.d.t.", DAYZONE, 4 HRS},
298         {"est", ZONE, 5 HRS},           /* Eastern */
299         {"e.s.t.", ZONE, 5 HRS},
300         {"edt", DAYZONE, 5 HRS},
301         {"e.d.t.", DAYZONE, 5 HRS},
302         {"cst", ZONE, 6 HRS},           /* Central */
303         {"c.s.t.", ZONE, 6 HRS},
304         {"cdt", DAYZONE, 6 HRS},
305         {"c.d.t.", DAYZONE, 6 HRS},
306         {"mst", ZONE, 7 HRS},           /* Mountain */
307         {"m.s.t.", ZONE, 7 HRS},
308         {"mdt", DAYZONE, 7 HRS},
309         {"m.d.t.", DAYZONE, 7 HRS},
310         {"pst", ZONE, 8 HRS},           /* Pacific */
311         {"p.s.t.", ZONE, 8 HRS},
312         {"pdt", DAYZONE, 8 HRS},
313         {"p.d.t.", DAYZONE, 8 HRS},
314         {"yst", ZONE, 9 HRS},           /* Yukon */
315         {"y.s.t.", ZONE, 9 HRS},
316         {"ydt", DAYZONE, 9 HRS},
317         {"y.d.t.", DAYZONE, 9 HRS},
318         {"hst", ZONE, 10 HRS},          /* Hawaii */
319         {"h.s.t.", ZONE, 10 HRS},
320         {"hdt", DAYZONE, 10 HRS},
321         {"h.d.t.", DAYZONE, 10 HRS},
322         {"bst", ZONE, 11 HRS},          /* Bering */
323         {"b.s.t.", ZONE, 11 HRS},
324         {"bdt", DAYZONE, 11 HRS},
325         {"b.d.t.", DAYZONE, 11 HRS},
326
327         {"gmt", ZONE, 0 HRS},
328         {"g.m.t.", ZONE, 0 HRS},
329
330         {"aest", ZONE, -10 HRS},        /* Australian Eastern Time */
331         {"a.e.s.t.", ZONE, -10 HRS},
332         {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
333         {"a.e.s.s.t.", DAYZONE, -10 HRS},
334         {"acst", ZONE, -(9 HRS + HALFHR)},      /* Australian Central Time */
335         {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
336         {"acsst", DAYZONE, -(9 HRS + HALFHR)},  /* Australian Central Summer */
337         {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
338         {"awst", ZONE, -8 HRS},         /* Australian Western Time */
339         {"a.w.s.t.", ZONE, -8 HRS},     /* (no daylightsavings time there, I'm told */
340         {0, 0, 0}};
341
342 struct table unittb[] = {
343         {"year", MUNIT, 12},
344         {"month", MUNIT, 1},
345         {"fortnight", UNIT, 14*24*60},
346         {"week", UNIT, 7*24*60},
347         {"day", UNIT, 1*24*60},
348         {"hour", UNIT, 60},
349         {"minute", UNIT, 1},
350         {"min", UNIT, 1},
351         {"second", SUNIT, 1},
352         {"sec", SUNIT, 1},
353         {0, 0, 0}};
354
355 struct table othertb[] = {
356         {"tomorrow", UNIT, 1*24*60},
357         {"yesterday", UNIT, -1*24*60},
358         {"today", UNIT, 0},
359         {"now", UNIT, 0},
360         {"last", NUMBER, -1},
361         {"this", UNIT, 0},
362         {"next", NUMBER, 2},
363         {"first", NUMBER, 1},
364         /* {"second", NUMBER, 2}, */
365         {"third", NUMBER, 3},
366         {"fourth", NUMBER, 4},
367         {"fifth", NUMBER, 5},
368         {"sixth", NUMBER, 6},
369         {"seventh", NUMBER, 7},
370         {"eighth", NUMBER, 8},
371         {"ninth", NUMBER, 9},
372         {"tenth", NUMBER, 10},
373         {"eleventh", NUMBER, 11},
374         {"twelfth", NUMBER, 12},
375         {"ago", AGO, 1},
376         {0, 0, 0}};
377
378 struct table milzone[] = {
379         {"a", ZONE, 1 HRS},
380         {"b", ZONE, 2 HRS},
381         {"c", ZONE, 3 HRS},
382         {"d", ZONE, 4 HRS},
383         {"e", ZONE, 5 HRS},
384         {"f", ZONE, 6 HRS},
385         {"g", ZONE, 7 HRS},
386         {"h", ZONE, 8 HRS},
387         {"i", ZONE, 9 HRS},
388         {"k", ZONE, 10 HRS},
389         {"l", ZONE, 11 HRS},
390         {"m", ZONE, 12 HRS},
391         {"n", ZONE, -1 HRS},
392         {"o", ZONE, -2 HRS},
393         {"p", ZONE, -3 HRS},
394         {"q", ZONE, -4 HRS},
395         {"r", ZONE, -5 HRS},
396         {"s", ZONE, -6 HRS},
397         {"t", ZONE, -7 HRS},
398         {"u", ZONE, -8 HRS},
399         {"v", ZONE, -9 HRS},
400         {"w", ZONE, -10 HRS},
401         {"x", ZONE, -11 HRS},
402         {"y", ZONE, -12 HRS},
403         {"z", ZONE, 0 HRS},
404         {0, 0, 0}};
405
406 static int
407 lookup(char *id)
408 {
409 #define gotit (yylval=i->value,  i->type)
410 #define getid for(j=idvar, k=id; (*j++ = *k++); )
411
412         char idvar[20];
413         char *j, *k;
414         struct table *i;
415         int abbrev;
416
417         getid;
418         if (strlen(idvar) == 3) abbrev = 1;
419         else if (strlen(idvar) == 4 && idvar[3] == '.') {
420                 abbrev = 1;
421                 idvar[3] = '\0';
422         }
423         else abbrev = 0;
424
425         if (islower(*idvar)) *idvar = toupper(*idvar);
426
427         for (i = mdtab; i->name; i++) {
428                 k = idvar;
429                 for (j = i->name; *j++ == *k++;) {
430                         if (abbrev && j==i->name+3) return gotit;
431                         if (j[-1] == 0) return gotit;
432                 }
433         }
434
435         getid;
436         for (i = mztab; i->name; i++)
437                 if (strcmp(i->name, idvar) == 0) return gotit;
438
439         for (j = idvar; *j; j++) if (isupper(*j)) *j = tolower(*j);
440         for (i=mztab; i->name; i++)
441                 if (strcmp(i->name, idvar) == 0) return gotit;
442
443         getid;
444         for (i=unittb; i->name; i++)
445                 if (strcmp(i->name, idvar) == 0) return gotit;
446
447         if (idvar[strlen(idvar)-1] == 's') idvar[strlen(idvar)-1] = '\0';
448         for (i=unittb; i->name; i++)
449                 if (strcmp(i->name, idvar) == 0) return gotit;
450
451         getid;
452         for (i = othertb; i->name; i++)
453                 if (strcmp(i->name, idvar) == 0) return gotit;
454
455         getid;
456         if (strlen(idvar) == 1 && isalpha(*idvar)) {
457                 if (isupper(*idvar)) *idvar = tolower(*idvar);
458                 for (i = milzone; i->name; i++)
459                         if (strcmp(i->name, idvar) == 0) return gotit;
460         }
461
462         return(ID);
463 }
464
465 static char *lptr;
466
467 int yylex(void)
468 {
469         extern int yylval;
470         int sign;
471         char c;
472         char *p;
473         char idbuf[20];
474         int pcnt;
475
476         for (;;) {
477                 while (isspace(*lptr)) lptr++;
478
479                 if (isdigit(c = *lptr) || c == '-' || c == '+') {
480                         if (c== '-' || c == '+') {
481                                 if (c=='-') sign = -1;
482                                 else sign = 1;
483                                 if (!isdigit(*++lptr)) {
484                                         /* yylval = sign; return (NUMBER); */
485                                         return yylex(); /* skip the '-' sign */
486                                 }
487                         } else sign = 1;
488                         yylval = 0;
489                         while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
490                         yylval *= sign;
491                         lptr--;
492                         return (NUMBER);
493
494                 } else if (isalpha(c)) {
495                         p = idbuf;
496                         while (isalpha(c = *lptr++) || c=='.')
497                                 *p++ = c;
498                         *p = '\0';
499                         lptr--;
500                         return (lookup(idbuf));
501                 }
502
503                 else if (c == '(') {
504                         pcnt = 0;
505                         do {
506                                 c = *lptr++;
507                                 if (c == '\0') return(c);
508                                 else if (c == '(') pcnt++;
509                                 else if (c == ')') pcnt--;
510                         } while (pcnt > 0);
511                 }
512
513                 else return (*lptr++);
514         }
515 }
516
517
518 time_t cm_getdate(char *p, struct timeb *now)
519 {
520 #define mcheck(f)       if (f>1) err++
521         int err;
522         struct tm *lt=NULL;
523         time_t sdate, tod;
524         struct timeb ftz;
525
526         lptr = p;
527         if (now == ((struct timeb *) NULL)) {
528                 now = &ftz;
529 #if defined(SVR4) || defined(__OpenBSD__)
530                 tod = time(0);
531                 lt = localtime(&tod);
532                 now->time = lt->tm_sec;
533 #ifdef __OpenBSD__
534                 now->timezone = lt->tm_gmtoff / 60;
535 #else
536                 now->timezone = timezone/60;
537 #endif
538 #else
539                 ftime(&ftz);
540 #endif /* SVR4 */
541         }
542         if (lt == NULL)
543                 lt = localtime(&now->time);
544         year = lt->tm_year;
545         month = lt->tm_mon+1;
546         day = lt->tm_mday;
547         relsec = 0; relmonth = 0;
548         timeflag=zoneflag=dateflag=dayflag=relflag=0;
549         ourzone = now->timezone;
550         daylightsavings = MAYBE;
551         hh = mm = ss = 0;
552         merid = 24;
553
554         if ((err = yyparse())) return (-1);
555
556         mcheck(timeflag);
557         mcheck(zoneflag);
558         mcheck(dateflag);
559         mcheck(dayflag);
560
561         if (err) return (-1);
562
563         /* Relflag also needs to set the sdate variable */
564         /* This fixes QAR 28447 */
565         if (dateflag || timeflag || dayflag || relflag) {
566                 sdate = dateconv(month, day, year, hh, mm, ss, merid, ourzone,
567                     daylightsavings);
568                 if (sdate < 0) return(sdate);
569                 /*
570                   if more than 6 months ago, then probably means
571                   next year
572                  
573                 if (noyear && sdate < now->time - daysec*(365/2)) {
574                                 year++;
575                                 sdate = dateconv(month, day, year, hh, mm, ss,
576                                     merid, ourzone, daylightsavings);
577                 }  */
578         }
579         else {
580                 sdate = now->time;
581                 if (relflag == 0)
582                         sdate -= (lt->tm_sec + lt->tm_min*60 +
583                                 lt->tm_hour*(60L*60L));
584         }
585
586         sdate += relsec;
587         sdate += monthadd(sdate, relmonth);
588
589         if (dayflag && !dateflag) {
590                 tod = dayconv(dayord, dayreq, sdate);
591                 sdate += tod;
592         }
593
594         return sdate;
595 }
596
597 void
598 yyerror(char *s)
599 {
600 }