PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lde/src/swiped/cnews/getdate.y

#
Happy | 532 lines | 464 code | 68 blank | 0 comment | 0 complexity | 96d08127cdda49bcee9c4a5318dd2d5c MD5 | raw file
Possible License(s): GPL-2.0
  1. %token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
  2. %{
  3. /* Steven M. Bellovin (unc!smb) */
  4. /* Dept. of Computer Science */
  5. /* University of North Carolina at Chapel Hill */
  6. /* @(#)getdate.y 2.13 9/16/86 */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #if HAVE_SYS_TYPES_H
  10. #include <sys/types.h>
  11. #endif
  12. #include <ctype.h>
  13. #include <time.h>
  14. time_t lde_getdate(char *p);
  15. #if HAVE_TIMEZONE
  16. #else
  17. static time_t timezone = 0;
  18. #endif
  19. #define daysec (24L*60L*60L)
  20. static int timeflag, dateflag, dayflag, relflag;
  21. static time_t relsec, relmonth;
  22. static int hh, mm, ss, merid;
  23. int daylight; //NOT static now?
  24. static int dayord, dayreq;
  25. static int month, day, year;
  26. static int ourzone;
  27. #define AM 1
  28. #define PM 2
  29. #define DAYLIGHT 1
  30. #define STANDARD 2
  31. #define MAYBE 3
  32. void yyerror(char *s);
  33. static time_t dateconv(int mm, int dd, int yy, int h, int m,
  34. int s, int mer);
  35. static time_t dayconv(int ord, int day, time_t now);
  36. static time_t timeconv(int hh, int mm, int ss, int mer);
  37. static time_t monthadd(time_t sdate, time_t relmonth);
  38. static time_t daylcorr(time_t future, time_t now);
  39. static int lookup(char *id);
  40. %}
  41. %%
  42. timedate: /* empty */
  43. | timedate item;
  44. item: tspec {timeflag++;}
  45. | zone {}
  46. | dtspec {dateflag++;}
  47. | dyspec {}
  48. | rspec {relflag++;}
  49. | nspec;
  50. nspec: NUMBER {if (timeflag && dateflag && !relflag) year = $1;
  51. else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
  52. tspec: NUMBER MERIDIAN
  53. {hh = $1; mm = 0; ss = 0; merid = $2;}
  54. | NUMBER ':' NUMBER
  55. {hh = $1; mm = $3; merid = 24;}
  56. | NUMBER ':' NUMBER MERIDIAN
  57. {hh = $1; mm = $3; merid = $4;}
  58. | NUMBER ':' NUMBER NUMBER
  59. {hh = $1; mm = $3; merid = 24;
  60. daylight = STANDARD; ourzone = $4%100 + 60*$4/100;}
  61. | NUMBER ':' NUMBER ':' NUMBER
  62. {hh = $1; mm = $3; ss = $5; merid = 24;}
  63. | NUMBER ':' NUMBER ':' NUMBER MERIDIAN
  64. {hh = $1; mm = $3; ss = $5; merid = $6;}
  65. | NUMBER ':' NUMBER ':' NUMBER NUMBER
  66. {hh = $1; mm = $3; ss = $5; merid = 24;
  67. daylight = STANDARD; ourzone = $6%100 + 60*$6/100;};
  68. zone: ZONE
  69. {ourzone = $1; daylight = STANDARD;}
  70. | DAYZONE
  71. {ourzone = $1; daylight = DAYLIGHT;};
  72. dyspec: DAY
  73. {dayord = 1; dayreq = $1;}
  74. | DAY ','
  75. {dayord = 1; dayreq = $1;}
  76. | NUMBER DAY
  77. {dayord = $1; dayreq = $2;};
  78. dtspec: NUMBER '/' NUMBER
  79. {month = $1; day = $3;}
  80. | NUMBER '/' NUMBER '/' NUMBER
  81. {month = $1; day = $3; year = $5;}
  82. | MONTH NUMBER
  83. {month = $1; day = $2;}
  84. | MONTH NUMBER ',' NUMBER
  85. {month = $1; day = $2; year = $4;}
  86. | NUMBER MONTH
  87. {month = $2; day = $1;}
  88. | NUMBER MONTH NUMBER
  89. {month = $2; day = $1; year = $3;};
  90. rspec: NUMBER UNIT
  91. {relsec += 60L * $1 * $2;}
  92. | NUMBER MUNIT
  93. {relmonth += $1 * $2;}
  94. | NUMBER SUNIT
  95. {relsec += $1;}
  96. | UNIT
  97. {relsec += 60L * $1;}
  98. | MUNIT
  99. {relmonth += $1;}
  100. | SUNIT
  101. {relsec++;}
  102. | rspec AGO
  103. {relsec = -relsec; relmonth = -relmonth;};
  104. %%
  105. static int mdays[12] =
  106. {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  107. #define epoch 1970
  108. static time_t
  109. dateconv(int mm, int dd, int yy, int h, int m, int s, int mer)
  110. {
  111. time_t tod, jdate;
  112. register int i;
  113. if (yy < 0) yy = -yy;
  114. if (yy < 70) yy += 2000; else if (yy < 100) yy += 1900;
  115. mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
  116. if (yy < epoch || mm < 1 || mm > 12 ||
  117. dd < 1 || dd > mdays[--mm]) return (-1);
  118. jdate = dd-1;
  119. for (i=0; i<mm; i++) jdate += mdays[i];
  120. for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
  121. jdate *= daysec;
  122. if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
  123. jdate += tod;
  124. jdate += timezone;
  125. return (jdate);
  126. }
  127. static time_t
  128. dayconv(int ord, int day, time_t now)
  129. {
  130. register struct tm *loctime;
  131. time_t tod;
  132. tod = now;
  133. loctime = localtime(&tod);
  134. tod += daysec * ((day - loctime->tm_wday + 7) % 7);
  135. tod += 7*daysec*(ord<=0?ord:ord-1);
  136. return daylcorr(tod, now);
  137. }
  138. static time_t
  139. timeconv(int hh, int mm, int ss, int mer)
  140. {
  141. if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
  142. switch (mer) {
  143. case AM: if (hh < 1 || hh > 12) return(-1);
  144. return (60L * ((hh%12)*60L + mm)+ss);
  145. case PM: if (hh < 1 || hh > 12) return(-1);
  146. return (60L * ((hh%12 +12)*60L + mm)+ss);
  147. case 24: if (hh < 0 || hh > 23) return (-1);
  148. return (60L * (hh*60L + mm)+ss);
  149. default: return (-1);
  150. }
  151. }
  152. static time_t
  153. monthadd(time_t sdate, time_t relmonth)
  154. {
  155. struct tm *ltime;
  156. int mm, yy;
  157. if (relmonth == 0) return 0;
  158. ltime = localtime(&sdate);
  159. mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
  160. yy = mm/12;
  161. mm = mm%12 + 1;
  162. return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
  163. ltime->tm_min, ltime->tm_sec, 24), sdate);
  164. }
  165. static time_t
  166. daylcorr(time_t future, time_t now)
  167. {
  168. int fdayl, nowdayl;
  169. nowdayl = (localtime(&now)->tm_hour+1) % 24;
  170. fdayl = (localtime(&future)->tm_hour+1) % 24;
  171. return (future-now) + 60L*60L*(nowdayl-fdayl);
  172. }
  173. static char *lptr;
  174. yylex()
  175. {
  176. extern int yylval;
  177. int sign;
  178. register char c;
  179. register char *p;
  180. char idbuf[20];
  181. int pcnt;
  182. for (;;) {
  183. while (isspace(*lptr)) lptr++;
  184. if (isdigit(c = *lptr) || c == '-' || c == '+') {
  185. if (c== '-' || c == '+') {
  186. if (c=='-') sign = -1;
  187. else sign = 1;
  188. if (!isdigit(*++lptr)) {
  189. /* yylval = sign; return (NUMBER); */
  190. return yylex(); /* skip the '-' sign */
  191. }
  192. } else sign = 1;
  193. yylval = 0;
  194. while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
  195. yylval *= sign;
  196. lptr--;
  197. return (NUMBER);
  198. } else if (isalpha(c)) {
  199. p = idbuf;
  200. while (isalpha(c = *lptr++) || c=='.')
  201. if (p < &idbuf[sizeof(idbuf)-1])
  202. *p++ = c;
  203. *p = '\0';
  204. lptr--;
  205. return (lookup(idbuf));
  206. }
  207. else if (c == '(') {
  208. pcnt = 0;
  209. do {
  210. c = *lptr++;
  211. if (c == '\0') return(c);
  212. else if (c == '(') pcnt++;
  213. else if (c == ')') pcnt--;
  214. } while (pcnt > 0);
  215. }
  216. else return (*lptr++);
  217. }
  218. }
  219. struct table {
  220. char *name;
  221. int type, value;
  222. };
  223. static struct table mdtab[] = {
  224. {"January", MONTH, 1},
  225. {"February", MONTH, 2},
  226. {"March", MONTH, 3},
  227. {"April", MONTH, 4},
  228. {"May", MONTH, 5},
  229. {"June", MONTH, 6},
  230. {"July", MONTH, 7},
  231. {"August", MONTH, 8},
  232. {"September", MONTH, 9},
  233. {"Sept", MONTH, 9},
  234. {"October", MONTH, 10},
  235. {"November", MONTH, 11},
  236. {"December", MONTH, 12},
  237. {"Sunday", DAY, 0},
  238. {"Monday", DAY, 1},
  239. {"Tuesday", DAY, 2},
  240. {"Tues", DAY, 2},
  241. {"Wednesday", DAY, 3},
  242. {"Wednes", DAY, 3},
  243. {"Thursday", DAY, 4},
  244. {"Thur", DAY, 4},
  245. {"Thurs", DAY, 4},
  246. {"Friday", DAY, 5},
  247. {"Saturday", DAY, 6},
  248. {0, 0, 0}};
  249. #define HRS *60
  250. #define HALFHR 30
  251. static struct table mztab[] = {
  252. {"a.m.", MERIDIAN, AM},
  253. {"am", MERIDIAN, AM},
  254. {"p.m.", MERIDIAN, PM},
  255. {"pm", MERIDIAN, PM},
  256. {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */
  257. {"n.s.t.", ZONE, 3 HRS + HALFHR},
  258. {"ast", ZONE, 4 HRS}, /* Atlantic */
  259. {"a.s.t.", ZONE, 4 HRS},
  260. {"adt", DAYZONE, 4 HRS},
  261. {"a.d.t.", DAYZONE, 4 HRS},
  262. {"est", ZONE, 5 HRS}, /* Eastern */
  263. {"e.s.t.", ZONE, 5 HRS},
  264. {"edt", DAYZONE, 5 HRS},
  265. {"e.d.t.", DAYZONE, 5 HRS},
  266. {"cst", ZONE, 6 HRS}, /* Central */
  267. {"c.s.t.", ZONE, 6 HRS},
  268. {"cdt", DAYZONE, 6 HRS},
  269. {"c.d.t.", DAYZONE, 6 HRS},
  270. {"mst", ZONE, 7 HRS}, /* Mountain */
  271. {"m.s.t.", ZONE, 7 HRS},
  272. {"mdt", DAYZONE, 7 HRS},
  273. {"m.d.t.", DAYZONE, 7 HRS},
  274. {"pst", ZONE, 8 HRS}, /* Pacific */
  275. {"p.s.t.", ZONE, 8 HRS},
  276. {"pdt", DAYZONE, 8 HRS},
  277. {"p.d.t.", DAYZONE, 8 HRS},
  278. {"yst", ZONE, 9 HRS}, /* Yukon */
  279. {"y.s.t.", ZONE, 9 HRS},
  280. {"ydt", DAYZONE, 9 HRS},
  281. {"y.d.t.", DAYZONE, 9 HRS},
  282. {"hst", ZONE, 10 HRS}, /* Hawaii */
  283. {"h.s.t.", ZONE, 10 HRS},
  284. {"hdt", DAYZONE, 10 HRS},
  285. {"h.d.t.", DAYZONE, 10 HRS},
  286. {"gmt", ZONE, 0 HRS},
  287. {"g.m.t.", ZONE, 0 HRS},
  288. {"ut", ZONE, 0 HRS},
  289. {"u.t.", ZONE, 0 HRS},
  290. {"bst", DAYZONE, 0 HRS}, /* British Summer Time */
  291. {"b.s.t.", DAYZONE, 0 HRS},
  292. {"eet", ZONE, 0 HRS}, /* European Eastern Time */
  293. {"e.e.t.", ZONE, 0 HRS},
  294. {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */
  295. {"e.e.s.t.", DAYZONE, 0 HRS},
  296. {"met", ZONE, -1 HRS}, /* Middle European Time */
  297. {"m.e.t.", ZONE, -1 HRS},
  298. {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */
  299. {"m.e.s.t.", DAYZONE, -1 HRS},
  300. {"wet", ZONE, -2 HRS }, /* Western European Time */
  301. {"w.e.t.", ZONE, -2 HRS },
  302. {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */
  303. {"w.e.s.t.", DAYZONE, -2 HRS},
  304. {"jst", ZONE, -9 HRS}, /* Japan Standard Time */
  305. {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */
  306. /* No daylight savings time */
  307. {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */
  308. {"a.e.s.t.", ZONE, -10 HRS},
  309. {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */
  310. {"a.e.s.s.t.", DAYZONE, -10 HRS},
  311. {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */
  312. {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
  313. {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */
  314. {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
  315. {"awst", ZONE, -8 HRS}, /* Australian Western Time */
  316. {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */
  317. {0, 0, 0}};
  318. static struct table unittb[] = {
  319. {"year", MUNIT, 12},
  320. {"month", MUNIT, 1},
  321. {"fortnight", UNIT, 14*24*60},
  322. {"week", UNIT, 7*24*60},
  323. {"day", UNIT, 1*24*60},
  324. {"hour", UNIT, 60},
  325. {"minute", UNIT, 1},
  326. {"min", UNIT, 1},
  327. {"second", SUNIT, 1},
  328. {"sec", SUNIT, 1},
  329. {0, 0, 0}};
  330. static struct table othertb[] = {
  331. {"tomorrow", UNIT, 1*24*60},
  332. {"yesterday", UNIT, -1*24*60},
  333. {"today", UNIT, 0},
  334. {"now", UNIT, 0},
  335. {"last", NUMBER, -1},
  336. {"this", UNIT, 0},
  337. {"next", NUMBER, 2},
  338. {"first", NUMBER, 1},
  339. /* {"second", NUMBER, 2}, */
  340. {"third", NUMBER, 3},
  341. {"fourth", NUMBER, 4},
  342. {"fifth", NUMBER, 5},
  343. {"sixth", NUMBER, 6},
  344. {"seventh", NUMBER, 7},
  345. {"eigth", NUMBER, 8},
  346. {"ninth", NUMBER, 9},
  347. {"tenth", NUMBER, 10},
  348. {"eleventh", NUMBER, 11},
  349. {"twelfth", NUMBER, 12},
  350. {"ago", AGO, 1},
  351. {0, 0, 0}};
  352. static struct table milzone[] = {
  353. {"a", ZONE, 1 HRS},
  354. {"b", ZONE, 2 HRS},
  355. {"c", ZONE, 3 HRS},
  356. {"d", ZONE, 4 HRS},
  357. {"e", ZONE, 5 HRS},
  358. {"f", ZONE, 6 HRS},
  359. {"g", ZONE, 7 HRS},
  360. {"h", ZONE, 8 HRS},
  361. {"i", ZONE, 9 HRS},
  362. {"k", ZONE, 10 HRS},
  363. {"l", ZONE, 11 HRS},
  364. {"m", ZONE, 12 HRS},
  365. {"n", ZONE, -1 HRS},
  366. {"o", ZONE, -2 HRS},
  367. {"p", ZONE, -3 HRS},
  368. {"q", ZONE, -4 HRS},
  369. {"r", ZONE, -5 HRS},
  370. {"s", ZONE, -6 HRS},
  371. {"t", ZONE, -7 HRS},
  372. {"u", ZONE, -8 HRS},
  373. {"v", ZONE, -9 HRS},
  374. {"w", ZONE, -10 HRS},
  375. {"x", ZONE, -11 HRS},
  376. {"y", ZONE, -12 HRS},
  377. {"z", ZONE, 0 HRS},
  378. {0, 0, 0}};
  379. static
  380. int lookup(char *id)
  381. {
  382. #define gotit (yylval=i->value, i->type)
  383. #define getid for(j=idvar, k=id; (*j++ = *k++); )
  384. char idvar[20];
  385. register char *j, *k;
  386. register struct table *i;
  387. int abbrev;
  388. getid;
  389. if (strlen(idvar) == 3) abbrev = 1;
  390. else if (strlen(idvar) == 4 && idvar[3] == '.') {
  391. abbrev = 1;
  392. idvar[3] = '\0';
  393. }
  394. else abbrev = 0;
  395. if (islower(*idvar)) *idvar = toupper(*idvar);
  396. for (i = mdtab; i->name; i++) {
  397. k = idvar;
  398. for (j = i->name; *j++ == *k++;) {
  399. if (abbrev && j==i->name+3) return gotit;
  400. if (j[-1] == 0) return gotit;
  401. }
  402. }
  403. getid;
  404. for (i = mztab; i->name; i++)
  405. if (strcmp(i->name, idvar) == 0) return gotit;
  406. for (j = idvar; *j; j++)
  407. if (isupper(*j)) *j = tolower(*j);
  408. for (i=mztab; i->name; i++)
  409. if (strcmp(i->name, idvar) == 0) return gotit;
  410. getid;
  411. for (i=unittb; i->name; i++)
  412. if (strcmp(i->name, idvar) == 0) return gotit;
  413. if (idvar[strlen(idvar)-1] == 's')
  414. idvar[strlen(idvar)-1] = '\0';
  415. for (i=unittb; i->name; i++)
  416. if (strcmp(i->name, idvar) == 0) return gotit;
  417. getid;
  418. for (i = othertb; i->name; i++)
  419. if (strcmp(i->name, idvar) == 0) return gotit;
  420. getid;
  421. if (strlen(idvar) == 1 && isalpha(*idvar)) {
  422. if (isupper(*idvar)) *idvar = tolower(*idvar);
  423. for (i = milzone; i->name; i++)
  424. if (strcmp(i->name, idvar) == 0) return gotit;
  425. }
  426. return(ID);
  427. }
  428. time_t
  429. lde_getdate(char *p)
  430. {
  431. #define mcheck(f) if (f>1) err++
  432. int err;
  433. struct tm *lt;
  434. time_t now;
  435. time_t sdate;
  436. lptr = p;
  437. time(&now);
  438. lt = localtime( &now );
  439. year = lt->tm_year;
  440. month = lt->tm_mon+1;
  441. day = lt->tm_mday;
  442. relsec = 0; relmonth = 0;
  443. timeflag=dateflag=relflag=0;
  444. hh = mm = ss = 0;
  445. merid = 24;
  446. if ((err = yyparse())) return (-1);
  447. mcheck(timeflag);
  448. mcheck(dateflag);
  449. if (err) return (-1);
  450. if (dateflag || timeflag ) {
  451. sdate = dateconv(month,day,year,hh,mm,ss,merid);
  452. if (sdate < 0) return -1;
  453. }
  454. else {
  455. sdate = now;
  456. if (relflag == 0)
  457. sdate -= (lt->tm_sec + lt->tm_min*60 +
  458. lt->tm_hour*(60L*60L));
  459. }
  460. sdate += relsec;
  461. sdate += monthadd(sdate, relmonth);
  462. return sdate;
  463. }
  464. void yyerror(char *s) {}