]>
Commit | Line | Data |
---|---|---|
4d6d1997 | 1 | --- at-3.1.8.orig/at.c |
2 | +++ at-3.1.8/at.c | |
3 | @@ -111,7 +111,7 @@ | |
4 | static char rcsid[] = "$Id$"; | |
5 | char *no_export[] = | |
6 | { | |
7 | - "TERM", "DISPLAY", "_", "SHELLOPTS" | |
8 | + "TERM", "DISPLAY", "_", "SHELLOPTS", "BASH_VERSINFO", "EUID", "GROUPS", "PPID", "UID" | |
9 | }; | |
10 | static int send_mail = 0; | |
11 | ||
12 | @@ -235,6 +235,7 @@ | |
13 | /* Install the signal handler for SIGINT; terminate after removing the | |
14 | * spool file if necessary | |
15 | */ | |
16 | + memset(&act, 0, sizeof act); | |
17 | act.sa_handler = sigc; | |
18 | sigemptyset(&(act.sa_mask)); | |
19 | act.sa_flags = 0; | |
20 | @@ -274,8 +275,8 @@ | |
21 | if ((jobno = nextjob()) == EOF) | |
22 | perr("Cannot generate job number"); | |
23 | ||
24 | - sprintf(ppos, "%c%5lx%8lx", queue, | |
25 | - jobno, (unsigned long) (runtimer / 60)); | |
26 | + (void)snprintf(ppos, sizeof(atfile) - (ppos - atfile), | |
27 | + "%c%5lx%8lx", queue, jobno, (unsigned long) (runtimer / 60)); | |
28 | ||
29 | for (ap = ppos; *ap != '\0'; ap++) | |
30 | if (*ap == ' ') | |
31 | @@ -291,7 +292,7 @@ | |
32 | * bit. Yes, this is a kluge. | |
33 | */ | |
34 | cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR); | |
35 | - if ((fd = creat(atfile, O_WRONLY)) == -1) | |
36 | + if ((fd = open(atfile, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR)) == -1) | |
37 | perr("Cannot create atjob file %.500s", atfile); | |
38 | ||
39 | if ((fd2 = dup(fd)) < 0) | |
40 | @@ -461,14 +462,6 @@ | |
41 | ||
42 | close(fd2); | |
43 | ||
44 | - /* POSIX.2 allows the shell specified by the user's SHELL environment | |
45 | - variable, the login shell from the user's password database entry, | |
46 | - or /bin/sh to be the command interpreter that processes the at-job. | |
47 | - It also alows a warning diagnostic to be printed. Because of the | |
48 | - possible variance, we always output the diagnostic. */ | |
49 | - | |
50 | - fprintf(stderr, "warning: commands will be executed using /bin/sh\n"); | |
51 | - | |
52 | runtime = localtime(&runtimer); | |
53 | ||
54 | /* We only use the sick POSIX time format if POSIXLY_CORRECT | |
55 | @@ -546,6 +539,7 @@ | |
56 | long jobno; | |
57 | time_t runtimer; | |
58 | char timestr[TIMESIZE]; | |
59 | + struct passwd *pwd; | |
60 | ||
61 | PRIV_START | |
62 | ||
63 | @@ -581,7 +575,10 @@ | |
64 | } else { | |
65 | strftime(timestr, TIMESIZE, TIMEFORMAT_ISO, runtime); | |
66 | } | |
67 | - printf("%ld\t%s %c\n", jobno, timestr, queue); | |
68 | + if ((pwd = getpwuid(buf.st_uid))) | |
69 | + printf("%ld\t%s %c %s\n", jobno, timestr, queue, pwd->pw_name); | |
70 | + else | |
71 | + printf("%ld\t%s %c\n", jobno, timestr, queue); | |
72 | } | |
73 | PRIV_END | |
74 | } | |
75 | @@ -695,7 +692,7 @@ | |
76 | char *pgm; | |
77 | ||
78 | int program = AT; /* our default program */ | |
79 | - char *options = "q:f:mvldVc"; /* default options for at */ | |
80 | + char *options = "q:f:MmvldhVc"; /* default options for at */ | |
81 | int disp_version = 0; | |
82 | time_t timer; | |
83 | struct passwd *pwe; | |
84 | @@ -726,16 +723,20 @@ | |
85 | */ | |
86 | if (strcmp(pgm, "atq") == 0) { | |
87 | program = ATQ; | |
88 | - options = "q:V"; | |
89 | + options = "hq:V"; | |
90 | } else if (strcmp(pgm, "atrm") == 0) { | |
91 | program = ATRM; | |
92 | - options = "V"; | |
93 | + options = "hV"; | |
94 | } | |
95 | /* process whatever options we can process | |
96 | */ | |
97 | opterr = 1; | |
98 | while ((c = getopt(argc, argv, options)) != EOF) | |
99 | switch (c) { | |
100 | + case 'h': | |
101 | + usage(); | |
102 | + exit (0); | |
103 | + | |
104 | case 'v': /* verify time settings */ | |
105 | atverify = 1; | |
106 | break; | |
107 | @@ -744,6 +745,10 @@ | |
108 | send_mail = 1; | |
109 | break; | |
110 | ||
111 | + case 'M': /* don't send mail, even when job failed */ | |
112 | + send_mail = -1; | |
113 | + break; | |
114 | + | |
115 | case 'f': | |
116 | atinput = optarg; | |
117 | break; | |
118 | @@ -753,7 +758,7 @@ | |
119 | usage(); | |
120 | ||
121 | atqueue = queue = *optarg; | |
122 | - if (!(islower(queue) || isupper(queue))) | |
123 | + if (!(islower(queue) || isupper(queue)) & (queue != '=')) | |
124 | usage(); | |
125 | ||
126 | queue_set = 1; | |
127 | @@ -842,6 +847,15 @@ | |
128 | struct tm *tm = localtime(&timer); | |
129 | fprintf(stderr, "%s\n", asctime(tm)); | |
130 | } | |
131 | + | |
132 | + /* POSIX.2 allows the shell specified by the user's SHELL environment | |
133 | + variable, the login shell from the user's password database entry, | |
134 | + or /bin/sh to be the command interpreter that processes the at-job. | |
135 | + It also alows a warning diagnostic to be printed. Because of the | |
136 | + possible variance, we always output the diagnostic. */ | |
137 | + | |
138 | + fprintf(stderr, "warning: commands will be executed using /bin/sh\n"); | |
139 | + | |
140 | writefile(timer, queue); | |
141 | break; | |
142 | ||
143 | --- at-3.1.8.orig/atd.c | |
144 | +++ at-3.1.8/atd.c | |
145 | @@ -22,6 +22,18 @@ | |
146 | #include "config.h" | |
147 | #endif | |
148 | ||
149 | +/* | |
150 | + * /usr/bin/mail aka /usr/bin/mailx require the subject to be | |
151 | + * specified on the command line instead of reading it from stdin like | |
152 | + * /usr/sbin/sendmail does. For now simply disable MAILC and MAILX, | |
153 | + * | |
154 | + * TODO: Remove tests for MAILC and MAILX from configure.in in the | |
155 | + * next upstream version. | |
156 | + */ | |
157 | +#undef MAILC | |
158 | +#undef MAILX | |
159 | + | |
160 | + | |
161 | /* System Headers */ | |
162 | ||
163 | #include <sys/types.h> | |
164 | @@ -101,6 +113,8 @@ | |
165 | static char rcsid[] = "$Id$"; | |
166 | static double load_avg = LOADAVG_MX; | |
167 | static time_t now; | |
168 | +static time_t last_chg; | |
169 | +static int nothing_to_do; | |
170 | unsigned int batch_interval; | |
171 | static int run_as_daemon = 0; | |
172 | ||
173 | @@ -121,6 +135,29 @@ | |
174 | return; | |
175 | } | |
176 | ||
177 | +/* SIGCHLD handler - discards completion status of children */ | |
178 | +RETSIGTYPE | |
179 | +release_zombie(int dummy) | |
180 | +{ | |
181 | + int status; | |
182 | + pid_t pid; | |
183 | + | |
184 | + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { | |
185 | +#ifdef DEBUG_ZOMBIE | |
186 | + if (WIFEXITED(status)) | |
187 | + syslog(LOG_INFO, "pid %ld exited with status %d.", pid, WEXITSTATUS(status)); | |
188 | + else if (WIFSIGNALED(status)) | |
189 | + syslog(LOG_NOTICE, "pid %ld killed with signal %d.", pid, WTERMSIG(status)); | |
190 | + else if (WIFSTOPPED(status)) | |
191 | + syslog(LOG_NOTICE, "pid %ld stopped with signal %d.", pid, WSTOPSIG(status)); | |
192 | + else | |
193 | + syslog(LOG_WARNING, "pid %ld unknown reason for SIGCHLD", pid); | |
194 | +#endif | |
195 | + } | |
196 | + return; | |
197 | +} | |
198 | + | |
199 | + | |
200 | /* Local functions */ | |
201 | ||
202 | static int | |
203 | @@ -255,6 +292,13 @@ | |
204 | ||
205 | fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC); | |
206 | ||
207 | + /* | |
208 | + * If the spool directory is mounted via NFS `atd' isn't able to | |
209 | + * read from the job file and will bump out here. The file is | |
210 | + * opened as "root" but it is read as "daemon" which fails over | |
211 | + * NFS and works with local file systems. It's not clear where | |
212 | + * the bug is located. -Joey | |
213 | + */ | |
214 | if (fscanf(stream, "#!/bin/sh\n# atrun uid=%d gid=%d\n# mail %8s %d", | |
215 | &nuid, &ngid, mailbuf, &send_mail) != 4) | |
216 | pabort("File %.500s is in wrong format - aborting", | |
217 | @@ -298,6 +342,8 @@ | |
218 | ||
219 | write_string(fd_out, "Subject: Output from your job "); | |
220 | write_string(fd_out, jobbuf); | |
221 | + write_string(fd_out, "\nTo: "); | |
222 | + write_string(fd_out, mailname); | |
223 | write_string(fd_out, "\n\n"); | |
224 | fstat(fd_out, &buf); | |
225 | size = buf.st_size; | |
226 | @@ -359,6 +405,11 @@ | |
227 | */ | |
228 | close(fd_in); | |
229 | close(fd_out); | |
230 | + | |
231 | + /* We inherited the master's SIGCHLD handler, which does a | |
232 | + non-blocking waitpid. So this blocking one will eventually | |
233 | + return with an ECHILD error. | |
234 | + */ | |
235 | waitpid(pid, (int *) NULL, 0); | |
236 | ||
237 | /* Send mail. Unlink the output file after opening it, so it | |
238 | @@ -376,7 +427,7 @@ | |
239 | unlink(newname); | |
240 | free(newname); | |
241 | ||
242 | - if ((buf.st_size != size) || send_mail) { | |
243 | + if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) { | |
244 | ||
245 | PRIV_START | |
246 | ||
247 | @@ -436,34 +487,51 @@ | |
248 | * atrun. | |
249 | */ | |
250 | ||
251 | - if ((spool = opendir(".")) == NULL) | |
252 | - perr("Cannot read " ATJOB_DIR); | |
253 | - | |
254 | next_job = now + CHECK_INTERVAL; | |
255 | if (next_batch == 0) | |
256 | next_batch = now; | |
257 | ||
258 | + /* To avoid spinning up the disk unnecessarily, stat the directory and | |
259 | + * return immediately if it hasn't changed since the last time we woke | |
260 | + * up. | |
261 | + */ | |
262 | + | |
263 | + if (stat(".", &buf) == -1) | |
264 | + perr("Cannot stat " ATJOB_DIR); | |
265 | + | |
266 | + if (nothing_to_do && buf.st_mtime <= last_chg) | |
267 | + return next_job; | |
268 | + last_chg = buf.st_mtime; | |
269 | + | |
270 | + if ((spool = opendir(".")) == NULL) | |
271 | + perr("Cannot read " ATJOB_DIR); | |
272 | + | |
273 | run_batch = 0; | |
274 | + nothing_to_do = 1; | |
275 | ||
276 | batch_uid = (uid_t) - 1; | |
277 | batch_gid = (gid_t) - 1; | |
278 | ||
279 | while ((dirent = readdir(spool)) != NULL) { | |
280 | ||
281 | - if (stat(dirent->d_name, &buf) != 0) { | |
282 | - /* Chances are a '=' file has been deleted from under us. | |
283 | - * Ignore. | |
284 | - */ | |
285 | - } | |
286 | + /* Avoid the stat if this doesn't look like a job file */ | |
287 | + if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3) | |
288 | + continue; | |
289 | ||
290 | - /* We don't want directories or files which at(1) hasn't yet | |
291 | - * marked executable. | |
292 | + /* Chances are a '=' file has been deleted from under us. | |
293 | + * Ignore. | |
294 | */ | |
295 | - if ((!S_ISREG(buf.st_mode)) || !(buf.st_mode & S_IXUSR)) | |
296 | + if (stat(dirent->d_name, &buf) != 0) | |
297 | continue; | |
298 | ||
299 | - if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3) | |
300 | + if (!S_ISREG(buf.st_mode)) | |
301 | + continue; | |
302 | + | |
303 | + /* We don't want files which at(1) hasn't yet marked executable. */ | |
304 | + if (!(buf.st_mode & S_IXUSR)) { | |
305 | + nothing_to_do = 0; /* it will probably become executable soon */ | |
306 | continue; | |
307 | + } | |
308 | ||
309 | run_time = (time_t) ctm *60; | |
310 | ||
311 | @@ -493,9 +561,18 @@ | |
312 | lock_name[0] = '='; | |
313 | unlink(lock_name); | |
314 | next_job = now; | |
315 | + nothing_to_do = 0; | |
316 | } | |
317 | continue; | |
318 | } | |
319 | + | |
320 | + /* If we got here, then there are jobs of some kind waiting. | |
321 | + * We could try to be smarter and leave nothing_to_do set if | |
322 | + * we end up processing all the jobs, but that's risky (run_file | |
323 | + * might fail and expect the job to be rescheduled), and it doesn't | |
324 | + * gain us much. */ | |
325 | + nothing_to_do = 0; | |
326 | + | |
327 | /* There's a job for later. Note its execution time if it's | |
328 | * the earlierst so far. | |
329 | */ | |
330 | @@ -540,6 +617,7 @@ | |
331 | } | |
332 | } | |
333 | if (run_batch && (next_batch < next_job)) { | |
334 | + nothing_to_do = 0; | |
335 | next_job = next_batch; | |
336 | } | |
337 | return next_job; | |
338 | @@ -631,6 +709,11 @@ | |
339 | if (optind < argc) | |
340 | pabort("non-option arguments - not allowed"); | |
341 | ||
342 | + sigaction(SIGCHLD, NULL, &act); | |
343 | + act.sa_handler = release_zombie; | |
344 | + act.sa_flags = SA_NOCLDSTOP; | |
345 | + sigaction(SIGCHLD, &act, NULL); | |
346 | + | |
347 | if (!run_as_daemon) { | |
348 | now = time(NULL); | |
349 | run_loop(); | |
350 | @@ -646,10 +729,6 @@ | |
351 | sigaction(SIGHUP, NULL, &act); | |
352 | act.sa_handler = sdummy; | |
353 | sigaction(SIGHUP, &act, NULL); | |
354 | - | |
355 | - sigaction(SIGCHLD, NULL, &act); | |
356 | - act.sa_handler = SIG_IGN; | |
357 | - sigaction(SIGCHLD, &act, NULL); | |
358 | ||
359 | sigaction(SIGTERM, NULL, &act); | |
360 | act.sa_handler = set_term; | |
361 | --- at-3.1.8.orig/panic.c | |
362 | +++ at-3.1.8/panic.c | |
363 | @@ -41,6 +41,7 @@ | |
364 | /* Local headers */ | |
365 | ||
366 | #include "panic.h" | |
367 | +#include "privs.h" | |
368 | #include "at.h" | |
369 | ||
370 | /* File scope variables */ | |
371 | @@ -72,12 +73,15 @@ | |
372 | va_list args; | |
373 | ||
374 | va_start(args, fmt); | |
375 | - vsprintf(buf, fmt, args); | |
376 | + vsnprintf(buf, sizeof(buf), fmt, args); | |
377 | va_end(args); | |
378 | ||
379 | perror(buf); | |
380 | - if (fcreated) | |
381 | + if (fcreated) { | |
382 | + PRIV_START | |
383 | unlink(atfile); | |
384 | + PRIV_END | |
385 | + } | |
386 | ||
387 | exit(EXIT_FAILURE); | |
388 | } | |
389 | @@ -88,7 +92,7 @@ | |
390 | /* Print usage and exit. | |
391 | */ | |
392 | fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-m] time\n" | |
393 | - " atq [-V] [-q x] [-v]\n" | |
394 | + " atq [-V] [-q x]\n" | |
395 | " atrm [-V] [-q x] job ...\n" | |
396 | " batch [-V] [-f file] [-m]\n"); | |
397 | exit(EXIT_FAILURE); | |
398 | --- at-3.1.8.orig/perm.c | |
399 | +++ at-3.1.8/perm.c | |
400 | @@ -43,7 +43,13 @@ | |
401 | ||
402 | /* Macros */ | |
403 | ||
404 | -#define MAXUSERID 10 | |
405 | +#if defined(DEBUG_PERM_C) | |
406 | +#define ETCDIR "../test/etc" | |
407 | +#undef PRIV_START | |
408 | +#define PRIV_START while(0) | |
409 | +#undef PRIV_END | |
410 | +#define PRIV_END while(0) | |
411 | +#endif | |
412 | ||
413 | /* Structures and unions */ | |
414 | ||
415 | @@ -54,66 +60,87 @@ | |
416 | ||
417 | /* Function declarations */ | |
418 | ||
419 | -static int check_for_user(FILE * fp, const char *name); | |
420 | +static int user_in_file(const char *path, const char *name); | |
421 | ||
422 | /* Local functions */ | |
423 | ||
424 | +/* | |
425 | + */ | |
426 | static int | |
427 | -check_for_user(FILE * fp, const char *name) | |
428 | +user_in_file(const char *path, const char *name) | |
429 | { | |
430 | - char *buffer; | |
431 | - size_t len; | |
432 | - int found = 0; | |
433 | - | |
434 | - len = strlen(name); | |
435 | - buffer = mymalloc(len + 2); | |
436 | - | |
437 | - while (fgets(buffer, len + 2, fp) != NULL) { | |
438 | - if ((strncmp(name, buffer, len) == 0) && | |
439 | - (buffer[len] == '\n')) { | |
440 | - found = 1; | |
441 | - break; | |
442 | - } | |
443 | - } | |
444 | - fclose(fp); | |
445 | - free(buffer); | |
446 | - return found; | |
447 | -} | |
448 | -/* Global functions */ | |
449 | -int | |
450 | -check_permission() | |
451 | -{ | |
452 | - FILE *fp; | |
453 | - uid_t uid = geteuid(); | |
454 | - struct passwd *pentry; | |
455 | + FILE *fp; | |
456 | + char buffer[256]; | |
457 | + int found = 0; | |
458 | + int c = '\n'; | |
459 | + | |
460 | + PRIV_START; | |
461 | + fp = fopen( path, "r"); | |
462 | + PRIV_END; | |
463 | + | |
464 | + if ( fp == NULL ) | |
465 | + return -1; | |
466 | + | |
467 | + | |
468 | + while ( !found && fgets(buffer, sizeof(buffer), fp) != NULL) { | |
469 | + size_t llen = strlen(buffer); | |
470 | ||
471 | - if (uid == 0) | |
472 | - return 1; | |
473 | + c = buffer[llen-1]; | |
474 | ||
475 | - if ((pentry = getpwuid(uid)) == NULL) { | |
476 | - perror("Cannot access user database"); | |
477 | - exit(EXIT_FAILURE); | |
478 | - } | |
479 | - PRIV_START | |
480 | + if (c == '\n') | |
481 | + buffer[llen-1] = '\0'; | |
482 | + while (c != '\n' && c != EOF) | |
483 | + c = fgetc(fp); | |
484 | + | |
485 | + found = (strcmp(buffer, name)==0); | |
486 | + } | |
487 | ||
488 | - fp = fopen(ETCDIR "/at.allow", "r"); | |
489 | + fclose(fp); | |
490 | ||
491 | - PRIV_END | |
492 | + if (c == EOF) { | |
493 | + fprintf(stderr, "%s: incomplete last line.\n", path); | |
494 | + } | |
495 | + | |
496 | + return found; | |
497 | +} | |
498 | ||
499 | - if (fp != NULL) { | |
500 | - return check_for_user(fp, pentry->pw_name); | |
501 | - } else { | |
502 | ||
503 | - PRIV_START | |
504 | +/* Global functions */ | |
505 | +int | |
506 | +check_permission() | |
507 | +{ | |
508 | + uid_t uid = geteuid(); | |
509 | + struct passwd *pentry; | |
510 | + int allow = 0, deny = 1; | |
511 | + | |
512 | + if (uid == 0) | |
513 | + return 1; | |
514 | + | |
515 | + if ((pentry = getpwuid(uid)) == NULL) { | |
516 | + perror("Cannot access user database"); | |
517 | + exit(EXIT_FAILURE); | |
518 | + } | |
519 | + | |
520 | + allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name); | |
521 | + if (allow==0 || allow==1) | |
522 | + return allow; | |
523 | + | |
524 | + /* There was an error while looking for pw_name in at.allow. | |
525 | + * Check at.deny only when at.allow doesn't exist. | |
526 | + */ | |
527 | + | |
528 | + deny = user_in_file(ETCDIR "/at.deny", pentry->pw_name); | |
529 | + return deny == 0; | |
530 | +} | |
531 | ||
532 | - fp = fopen(ETCDIR "/at.deny", "r"); | |
533 | ||
534 | - PRIV_END | |
535 | +#if defined(DEBUG_PERM_C) | |
536 | ||
537 | - if (fp != NULL) { | |
538 | - return !check_for_user(fp, pentry->pw_name); | |
539 | - } | |
540 | - perror("at.deny"); | |
541 | - } | |
542 | - return 0; | |
543 | +int | |
544 | +main(int argc, char *argv[]) | |
545 | +{ | |
546 | + printf("check_permission() ==> %d\n", check_permission()); | |
547 | + return 0; | |
548 | } | |
549 | + | |
550 | +#endif | |
551 | --- at-3.1.8.orig/daemon.c | |
552 | +++ at-3.1.8/daemon.c | |
553 | @@ -72,7 +72,7 @@ | |
554 | va_list args; | |
555 | ||
556 | va_start(args, fmt); | |
557 | - vsprintf(buf, fmt, args); | |
558 | + vsnprintf(buf, sizeof(buf), fmt, args); | |
559 | va_end(args); | |
560 | ||
561 | if (daemon_debug) { | |
562 | @@ -90,7 +90,7 @@ | |
563 | va_list args; | |
564 | ||
565 | va_start(args, fmt); | |
566 | - vsprintf(buf, fmt, args); | |
567 | + vsnprintf(buf, sizeof(buf), fmt, args); | |
568 | va_end(args); | |
569 | ||
570 | if (daemon_debug) { | |
571 | @@ -127,6 +127,7 @@ | |
572 | } | |
573 | } | |
574 | old_umask = umask(S_IWGRP | S_IWOTH); | |
575 | + (void) setsid(); | |
576 | ||
577 | PRIV_START | |
578 | ||
579 | --- at-3.1.8.orig/y.tab.c | |
580 | +++ at-3.1.8/y.tab.c | |
581 | @@ -1,45 +1,45 @@ | |
582 | ||
583 | -/* A Bison parser, made from parsetime.y with Bison version GNU Bison version 1.22 | |
584 | - */ | |
585 | +/* A Bison parser, made from parsetime.y | |
586 | + by GNU Bison version 1.28 */ | |
587 | ||
588 | #define YYBISON 1 /* Identify Bison output. */ | |
589 | ||
590 | -#define INT 258 | |
591 | -#define NOW 259 | |
592 | -#define AM 260 | |
593 | -#define PM 261 | |
594 | -#define NOON 262 | |
595 | -#define MIDNIGHT 263 | |
596 | -#define TEATIME 264 | |
597 | -#define SUN 265 | |
598 | -#define MON 266 | |
599 | -#define TUE 267 | |
600 | -#define WED 268 | |
601 | -#define THU 269 | |
602 | -#define FRI 270 | |
603 | -#define SAT 271 | |
604 | -#define TODAY 272 | |
605 | -#define TOMORROW 273 | |
606 | -#define NEXT 274 | |
607 | -#define MINUTE 275 | |
608 | -#define HOUR 276 | |
609 | -#define DAY 277 | |
610 | -#define WEEK 278 | |
611 | -#define MONTH 279 | |
612 | -#define YEAR 280 | |
613 | -#define JAN 281 | |
614 | -#define FEB 282 | |
615 | -#define MAR 283 | |
616 | -#define APR 284 | |
617 | -#define MAY 285 | |
618 | -#define JUN 286 | |
619 | -#define JUL 287 | |
620 | -#define AUG 288 | |
621 | -#define SEP 289 | |
622 | -#define OCT 290 | |
623 | -#define NOV 291 | |
624 | -#define DEC 292 | |
625 | -#define WORD 293 | |
626 | +#define INT 257 | |
627 | +#define NOW 258 | |
628 | +#define AM 259 | |
629 | +#define PM 260 | |
630 | +#define NOON 261 | |
631 | +#define MIDNIGHT 262 | |
632 | +#define TEATIME 263 | |
633 | +#define SUN 264 | |
634 | +#define MON 265 | |
635 | +#define TUE 266 | |
636 | +#define WED 267 | |
637 | +#define THU 268 | |
638 | +#define FRI 269 | |
639 | +#define SAT 270 | |
640 | +#define TODAY 271 | |
641 | +#define TOMORROW 272 | |
642 | +#define NEXT 273 | |
643 | +#define MINUTE 274 | |
644 | +#define HOUR 275 | |
645 | +#define DAY 276 | |
646 | +#define WEEK 277 | |
647 | +#define MONTH 278 | |
648 | +#define YEAR 279 | |
649 | +#define JAN 280 | |
650 | +#define FEB 281 | |
651 | +#define MAR 282 | |
652 | +#define APR 283 | |
653 | +#define MAY 284 | |
654 | +#define JUN 285 | |
655 | +#define JUL 286 | |
656 | +#define AUG 287 | |
657 | +#define SEP 288 | |
658 | +#define OCT 289 | |
659 | +#define NOV 290 | |
660 | +#define DEC 291 | |
661 | +#define WORD 292 | |
662 | ||
663 | #line 1 "parsetime.y" | |
664 | ||
665 | @@ -55,30 +55,16 @@ | |
666 | static int isgmt; | |
667 | static int time_only; | |
668 | ||
669 | +extern int yyerror(char *s); | |
670 | +extern int yylex(); | |
671 | + | |
672 | int add_date(int number, int period); | |
673 | ||
674 | -#line 17 "parsetime.y" | |
675 | +#line 20 "parsetime.y" | |
676 | typedef union { | |
677 | char * charval; | |
678 | int intval; | |
679 | } YYSTYPE; | |
680 | - | |
681 | -#ifndef YYLTYPE | |
682 | -typedef | |
683 | - struct yyltype | |
684 | - { | |
685 | - int timestamp; | |
686 | - int first_line; | |
687 | - int first_column; | |
688 | - int last_line; | |
689 | - int last_column; | |
690 | - char *text; | |
691 | - } | |
692 | - yyltype; | |
693 | - | |
694 | -#define YYLTYPE yyltype | |
695 | -#endif | |
696 | - | |
697 | #include <stdio.h> | |
698 | ||
699 | #ifndef __cplusplus | |
700 | @@ -89,11 +75,11 @@ | |
701 | ||
702 | ||
703 | ||
704 | -#define YYFINAL 100 | |
705 | +#define YYFINAL 104 | |
706 | #define YYFLAG -32768 | |
707 | #define YYNTBASE 47 | |
708 | ||
709 | -#define YYTRANSLATE(x) ((unsigned)(x) <= 293 ? yytranslate[x] : 67) | |
710 | +#define YYTRANSLATE(x) ((unsigned)(x) <= 292 ? yytranslate[x] : 69) | |
711 | ||
712 | static const char yytranslate[] = { 0, | |
713 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
714 | @@ -121,176 +107,203 @@ | |
715 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
716 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
717 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
718 | - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, | |
719 | - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | |
720 | - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, | |
721 | - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, | |
722 | - 36, 37, 38 | |
723 | + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, | |
724 | + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, | |
725 | + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, | |
726 | + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, | |
727 | + 37, 38 | |
728 | }; | |
729 | ||
730 | #if YYDEBUG != 0 | |
731 | static const short yyprhs[] = { 0, | |
732 | - 0, 2, 5, 8, 12, 15, 19, 21, 23, 26, | |
733 | - 29, 31, 33, 36, 40, 45, 48, 52, 57, 63, | |
734 | - 65, 67, 69, 72, 77, 79, 81, 83, 89, 95, | |
735 | - 99, 102, 106, 112, 116, 119, 122, 126, 128, 130, | |
736 | - 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, | |
737 | - 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, | |
738 | - 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, | |
739 | - 192, 194, 196, 198, 200, 202, 204 | |
740 | + 0, 2, 4, 7, 10, 14, 16, 18, 21, 23, | |
741 | + 25, 27, 28, 30, 33, 37, 42, 45, 49, 54, | |
742 | + 60, 62, 64, 66, 69, 73, 78, 80, 82, 84, | |
743 | + 90, 96, 100, 103, 107, 113, 115, 117, 121, 124, | |
744 | + 127, 131, 133, 135, 137, 139, 141, 143, 145, 147, | |
745 | + 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, | |
746 | + 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, | |
747 | + 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, | |
748 | + 209 | |
749 | }; | |
750 | ||
751 | -static const short yyrhs[] = { 50, | |
752 | - 0, 50, 51, 0, 50, 52, 0, 50, 51, 52, | |
753 | - 0, 50, 53, 0, 50, 51, 53, 0, 48, 0, | |
754 | - 49, 0, 49, 52, 0, 49, 53, 0, 4, 0, | |
755 | - 55, 0, 55, 56, 0, 57, 66, 58, 0, 57, | |
756 | - 66, 58, 56, 0, 57, 59, 0, 57, 59, 56, | |
757 | - 0, 57, 66, 58, 59, 0, 57, 66, 58, 59, | |
758 | - 56, 0, 7, 0, 8, 0, 9, 0, 60, 62, | |
759 | - 0, 60, 62, 39, 63, 0, 64, 0, 17, 0, | |
760 | - 18, 0, 63, 40, 61, 40, 62, 0, 62, 41, | |
761 | - 61, 41, 63, 0, 62, 41, 61, 0, 62, 60, | |
762 | - 0, 62, 60, 63, 0, 61, 42, 62, 42, 63, | |
763 | - 0, 43, 65, 54, 0, 19, 54, 0, 19, 64, | |
764 | - 0, 40, 65, 54, 0, 20, 0, 21, 0, 22, | |
765 | - 0, 23, 0, 24, 0, 25, 0, 3, 0, 38, | |
766 | - 0, 55, 0, 3, 0, 5, 0, 6, 0, 26, | |
767 | - 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, | |
768 | - 0, 32, 0, 33, 0, 34, 0, 35, 0, 36, | |
769 | - 0, 37, 0, 3, 0, 3, 0, 3, 0, 10, | |
770 | - 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, | |
771 | - 0, 16, 0, 3, 0, 44, 0, 45, 0, 41, | |
772 | - 0, 46, 0, 39, 0 | |
773 | +static const short yyrhs[] = { 52, | |
774 | + 0, 51, 0, 51, 52, 0, 50, 53, 0, 50, | |
775 | + 52, 53, 0, 48, 0, 49, 0, 49, 53, 0, | |
776 | + 4, 0, 18, 0, 51, 0, 0, 57, 0, 57, | |
777 | + 58, 0, 59, 68, 60, 0, 59, 68, 60, 58, | |
778 | + 0, 59, 61, 0, 59, 61, 58, 0, 59, 68, | |
779 | + 60, 61, 0, 59, 68, 60, 61, 58, 0, 7, | |
780 | + 0, 8, 0, 9, 0, 62, 64, 0, 62, 64, | |
781 | + 65, 0, 62, 64, 39, 65, 0, 66, 0, 17, | |
782 | + 0, 18, 0, 65, 40, 63, 40, 64, 0, 64, | |
783 | + 41, 63, 41, 65, 0, 64, 41, 63, 0, 64, | |
784 | + 62, 0, 64, 62, 65, 0, 63, 42, 64, 42, | |
785 | + 65, 0, 54, 0, 55, 0, 43, 67, 56, 0, | |
786 | + 19, 56, 0, 19, 66, 0, 40, 67, 56, 0, | |
787 | + 20, 0, 21, 0, 22, 0, 23, 0, 24, 0, | |
788 | + 25, 0, 3, 0, 38, 0, 57, 0, 3, 0, | |
789 | + 5, 0, 6, 0, 26, 0, 27, 0, 28, 0, | |
790 | + 29, 0, 30, 0, 31, 0, 32, 0, 33, 0, | |
791 | + 34, 0, 35, 0, 36, 0, 37, 0, 3, 0, | |
792 | + 3, 0, 3, 0, 10, 0, 11, 0, 12, 0, | |
793 | + 13, 0, 14, 0, 15, 0, 16, 0, 3, 0, | |
794 | + 44, 0, 45, 0, 41, 0, 46, 0, 39, 0 | |
795 | }; | |
796 | ||
797 | #endif | |
798 | ||
799 | #if YYDEBUG != 0 | |
800 | static const short yyrline[] = { 0, | |
801 | - 39, 43, 44, 45, 46, 47, 48, 51, 52, 53, | |
802 | - 56, 59, 60, 61, 62, 63, 64, 65, 66, 67, | |
803 | - 72, 78, 85, 86, 87, 91, 92, 96, 97, 98, | |
804 | - 99, 100, 101, 104, 108, 112, 118, 124, 125, 126, | |
805 | - 127, 128, 129, 132, 157, 170, 173, 183, 184, 197, | |
806 | - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, | |
807 | - 208, 211, 225, 238, 261, 262, 263, 264, 265, 266, | |
808 | - 267, 270, 280, 281, 282, 283, 284 | |
809 | + 42, 43, 47, 48, 49, 50, 53, 54, 57, 58, | |
810 | + 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, | |
811 | + 75, 80, 86, 93, 94, 95, 96, 100, 101, 105, | |
812 | + 106, 107, 108, 109, 110, 113, 114, 116, 120, 124, | |
813 | + 130, 136, 137, 138, 139, 140, 141, 144, 215, 228, | |
814 | + 231, 241, 251, 264, 265, 266, 267, 268, 269, 270, | |
815 | + 271, 272, 273, 274, 275, 278, 292, 305, 328, 329, | |
816 | + 330, 331, 332, 333, 334, 337, 347, 348, 349, 350, | |
817 | + 351 | |
818 | }; | |
819 | +#endif | |
820 | + | |
821 | ||
822 | -static const char * const yytname[] = { "$","error","$illegal.","INT","NOW", | |
823 | +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) | |
824 | + | |
825 | +static const char * const yytname[] = { "$","error","$undefined.","INT","NOW", | |
826 | "AM","PM","NOON","MIDNIGHT","TEATIME","SUN","MON","TUE","WED","THU","FRI","SAT", | |
827 | "TODAY","TOMORROW","NEXT","MINUTE","HOUR","DAY","WEEK","MONTH","YEAR","JAN", | |
828 | "FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC","WORD","','", | |
829 | -"'-'","'.'","'/'","'+'","':'","'\\''","'h'","timespec","nowspec","now","time", | |
830 | -"date","increment","decrement","inc_period","hr24clock_hr_min","timezone_name", | |
831 | -"hr24clock_hour","minute","am_pm","month_name","month_number","day_number","year_number", | |
832 | -"day_of_week","inc_number","time_sep","" | |
833 | +"'-'","'.'","'/'","'+'","':'","'\\''","'h'","timespec","nowspec","now","time_or_not", | |
834 | +"time","date","inc_or_dec","increment","decrement","inc_period","hr24clock_hr_min", | |
835 | +"timezone_name","hr24clock_hour","minute","am_pm","month_name","month_number", | |
836 | +"day_number","year_number","day_of_week","inc_number","time_sep", NULL | |
837 | }; | |
838 | #endif | |
839 | ||
840 | static const short yyr1[] = { 0, | |
841 | - 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, | |
842 | - 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, | |
843 | + 47, 47, 47, 47, 47, 47, 48, 48, 49, 49, | |
844 | 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, | |
845 | - 51, 51, 51, 52, 52, 52, 53, 54, 54, 54, | |
846 | - 54, 54, 54, 55, 56, 57, 58, 59, 59, 60, | |
847 | - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, | |
848 | - 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, | |
849 | - 64, 65, 66, 66, 66, 66, 66 | |
850 | + 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, | |
851 | + 52, 52, 52, 52, 52, 53, 53, 54, 54, 54, | |
852 | + 55, 56, 56, 56, 56, 56, 56, 57, 58, 59, | |
853 | + 60, 61, 61, 62, 62, 62, 62, 62, 62, 62, | |
854 | + 62, 62, 62, 62, 62, 63, 64, 65, 66, 66, | |
855 | + 66, 66, 66, 66, 66, 67, 68, 68, 68, 68, | |
856 | + 68 | |
857 | }; | |
858 | ||
859 | static const short yyr2[] = { 0, | |
860 | - 1, 2, 2, 3, 2, 3, 1, 1, 2, 2, | |
861 | - 1, 1, 2, 3, 4, 2, 3, 4, 5, 1, | |
862 | - 1, 1, 2, 4, 1, 1, 1, 5, 5, 3, | |
863 | - 2, 3, 5, 3, 2, 2, 3, 1, 1, 1, | |
864 | + 1, 1, 2, 2, 3, 1, 1, 2, 1, 1, | |
865 | + 1, 0, 1, 2, 3, 4, 2, 3, 4, 5, | |
866 | + 1, 1, 1, 2, 3, 4, 1, 1, 1, 5, | |
867 | + 5, 3, 2, 3, 5, 1, 1, 3, 2, 2, | |
868 | + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
869 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
870 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
871 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
872 | - 1, 1, 1, 1, 1, 1, 1 | |
873 | + 1 | |
874 | }; | |
875 | ||
876 | -static const short yydefact[] = { 0, | |
877 | - 44, 11, 20, 21, 22, 7, 8, 1, 12, 0, | |
878 | - 0, 0, 0, 9, 10, 63, 65, 66, 67, 68, | |
879 | - 69, 70, 71, 26, 27, 50, 51, 52, 53, 54, | |
880 | - 55, 56, 57, 58, 59, 60, 61, 2, 3, 5, | |
881 | - 0, 0, 0, 0, 25, 45, 13, 48, 49, 77, | |
882 | - 75, 73, 74, 76, 16, 0, 38, 39, 40, 41, | |
883 | - 42, 43, 35, 36, 72, 0, 0, 4, 6, 63, | |
884 | - 23, 0, 0, 31, 0, 17, 47, 14, 37, 34, | |
885 | - 0, 0, 62, 30, 64, 32, 0, 15, 18, 24, | |
886 | - 0, 0, 0, 19, 33, 29, 28, 0, 0, 0 | |
887 | +static const short yydefact[] = { 12, | |
888 | + 48, 9, 21, 22, 23, 69, 70, 71, 72, 73, | |
889 | + 74, 75, 28, 10, 54, 55, 56, 57, 58, 59, | |
890 | + 60, 61, 62, 63, 64, 65, 6, 7, 0, 11, | |
891 | + 1, 13, 0, 0, 0, 0, 0, 27, 0, 0, | |
892 | + 0, 8, 36, 37, 67, 29, 0, 4, 3, 49, | |
893 | + 14, 52, 53, 81, 79, 77, 78, 80, 17, 0, | |
894 | + 67, 24, 0, 0, 33, 0, 42, 43, 44, 45, | |
895 | + 46, 47, 39, 40, 76, 0, 0, 5, 18, 51, | |
896 | + 15, 68, 0, 25, 0, 66, 32, 34, 0, 41, | |
897 | + 38, 16, 19, 26, 0, 0, 0, 20, 35, 31, | |
898 | + 30, 0, 0, 0 | |
899 | }; | |
900 | ||
901 | -static const short yydefgoto[] = { 98, | |
902 | - 6, 7, 8, 38, 14, 15, 63, 9, 47, 10, | |
903 | - 78, 55, 41, 42, 43, 44, 45, 66, 56 | |
904 | +static const short yydefgoto[] = { 102, | |
905 | + 27, 28, 29, 30, 31, 42, 43, 44, 73, 32, | |
906 | + 51, 33, 81, 59, 34, 35, 36, 37, 38, 76, | |
907 | + 60 | |
908 | }; | |
909 | ||
910 | -static const short yypact[] = { 8, | |
911 | --32768,-32768,-32768,-32768,-32768,-32768, -14, 43, -4, 4, | |
912 | - 80, 5, 5,-32768,-32768, -12,-32768,-32768,-32768,-32768, | |
913 | +static const short yypact[] = { 114, | |
914 | + -21,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, | |
915 | -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, | |
916 | --32768,-32768,-32768,-32768,-32768,-32768,-32768, -14,-32768,-32768, | |
917 | - 10, -6, 81, -8,-32768,-32768,-32768,-32768,-32768,-32768, | |
918 | --32768,-32768,-32768,-32768, 9, 48,-32768,-32768,-32768,-32768, | |
919 | --32768,-32768,-32768,-32768,-32768, -2, -2,-32768,-32768,-32768, | |
920 | - 25, 10, 63, 64, 63,-32768,-32768, 1,-32768,-32768, | |
921 | - 64, 26,-32768, 41,-32768,-32768, 44,-32768, 9,-32768, | |
922 | - 64, 64, 10,-32768,-32768,-32768,-32768, 85, 87,-32768 | |
923 | +-32768,-32768,-32768,-32768,-32768,-32768,-32768, -13, 41, 79, | |
924 | +-32768, -4, 4, 22, -14, 142, -8,-32768, 174, 33, | |
925 | + 33,-32768,-32768,-32768, -18,-32768, -13,-32768,-32768,-32768, | |
926 | +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 9, 58, | |
927 | +-32768, 0, 22, 59, 61, 59,-32768,-32768,-32768,-32768, | |
928 | +-32768,-32768,-32768,-32768,-32768, -5, -5,-32768,-32768,-32768, | |
929 | + 8,-32768, 61,-32768, 23,-32768, 25,-32768, 40,-32768, | |
930 | +-32768,-32768, 9,-32768, 61, 61, 22,-32768,-32768,-32768, | |
931 | +-32768, 83, 85,-32768 | |
932 | }; | |
933 | ||
934 | static const short yypgoto[] = {-32768, | |
935 | --32768,-32768,-32768,-32768, -5, 6, -42,-32768, -51,-32768, | |
936 | --32768, 11, 54, -10, -41, 7, 95, 106,-32768 | |
937 | +-32768,-32768,-32768,-32768, -22, -24,-32768,-32768, -65,-32768, | |
938 | + -55,-32768,-32768, 5, 51, -33, -34, 71, 49, 57, | |
939 | +-32768 | |
940 | }; | |
941 | ||
942 | ||
943 | -#define YYLAST 122 | |
944 | +#define YYLAST 199 | |
945 | ||
946 | ||
947 | -static const short yytable[] = { 71, | |
948 | - -46, -46, 39, 76, 11, 48, 49, 65, 48, 49, | |
949 | - 1, 2, 70, 40, 3, 4, 5, 57, 58, 59, | |
950 | - 60, 61, 62, 79, 80, 12, 88, -64, 13, -62, | |
951 | - 82, 75, 68, 46, -46, 72, -46, 94, 46, -46, | |
952 | - -46, -46, 50, 69, 51, 16, 46, 52, 53, 54, | |
953 | - 77, 97, 17, 18, 19, 20, 21, 22, 23, 24, | |
954 | - 25, 11, 84, 81, 87, 83, 85, 91, 26, 27, | |
955 | - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, | |
956 | - 86, 92, 12, 93, 99, 13, 100, 90, 89, 17, | |
957 | - 18, 19, 20, 21, 22, 23, 74, 95, 96, 57, | |
958 | - 58, 59, 60, 61, 62, 64, 26, 27, 28, 29, | |
959 | - 30, 31, 32, 33, 34, 35, 36, 37, 67, 0, | |
960 | - 0, 73 | |
961 | +static const short yytable[] = { 62, | |
962 | + -50, -50, 82, 79, 48, 39, 47, 49, 52, 53, | |
963 | + 90, 91, 52, 53, 67, 68, 69, 70, 71, 72, | |
964 | + -66, -68, 78, -66, 61, 92, 40, 63, 85, 41, | |
965 | + 87, 66, 89, 50, -50, 75, -50, 98, 83, -50, | |
966 | + -50, -50, 54, 45, 55, 50, 50, 56, 57, 58, | |
967 | + 6, 7, 8, 9, 10, 11, 12, 13, 46, 39, | |
968 | + 80, 86, 101, 82, 95, 96, 15, 16, 17, 18, | |
969 | + 19, 20, 21, 22, 23, 24, 25, 26, -2, 97, | |
970 | + 40, 45, 103, 41, 104, 93, 65, 74, 6, 7, | |
971 | + 8, 9, 10, 11, 12, 13, 46, 77, 0, 0, | |
972 | + 0, 0, 0, 0, 15, 16, 17, 18, 19, 20, | |
973 | + 21, 22, 23, 24, 25, 26, 1, 2, 0, 0, | |
974 | + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, | |
975 | + 13, 14, 84, 0, 0, 88, 0, 0, 0, 15, | |
976 | + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, | |
977 | + 26, 0, 0, 94, 0, 0, 0, 0, 0, 0, | |
978 | + 0, 0, 0, 0, 0, 99, 100, 15, 16, 17, | |
979 | + 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, | |
980 | + 0, 0, 64, 6, 7, 8, 9, 10, 11, 12, | |
981 | + 0, 0, 0, 67, 68, 69, 70, 71, 72 | |
982 | }; | |
983 | ||
984 | -static const short yycheck[] = { 41, | |
985 | - 5, 6, 8, 55, 19, 5, 6, 3, 5, 6, | |
986 | - 3, 4, 3, 8, 7, 8, 9, 20, 21, 22, | |
987 | - 23, 24, 25, 66, 67, 40, 78, 40, 43, 42, | |
988 | - 72, 40, 38, 38, 39, 42, 41, 89, 38, 44, | |
989 | - 45, 46, 39, 38, 41, 3, 38, 44, 45, 46, | |
990 | - 3, 93, 10, 11, 12, 13, 14, 15, 16, 17, | |
991 | - 18, 19, 73, 39, 75, 3, 3, 42, 26, 27, | |
992 | - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, | |
993 | - 74, 41, 40, 40, 0, 43, 0, 81, 78, 10, | |
994 | - 11, 12, 13, 14, 15, 16, 43, 91, 92, 20, | |
995 | - 21, 22, 23, 24, 25, 11, 26, 27, 28, 29, | |
996 | - 30, 31, 32, 33, 34, 35, 36, 37, 13, -1, | |
997 | - -1, 41 | |
998 | +static const short yycheck[] = { 34, | |
999 | + 5, 6, 3, 59, 29, 19, 29, 30, 5, 6, | |
1000 | + 76, 77, 5, 6, 20, 21, 22, 23, 24, 25, | |
1001 | + 42, 40, 47, 42, 3, 81, 40, 42, 63, 43, | |
1002 | + 64, 40, 66, 38, 39, 3, 41, 93, 39, 44, | |
1003 | + 45, 46, 39, 3, 41, 38, 38, 44, 45, 46, | |
1004 | + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, | |
1005 | + 3, 3, 97, 3, 42, 41, 26, 27, 28, 29, | |
1006 | + 30, 31, 32, 33, 34, 35, 36, 37, 0, 40, | |
1007 | + 40, 3, 0, 43, 0, 81, 36, 39, 10, 11, | |
1008 | + 12, 13, 14, 15, 16, 17, 18, 41, -1, -1, | |
1009 | + -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, | |
1010 | + 32, 33, 34, 35, 36, 37, 3, 4, -1, -1, | |
1011 | + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, | |
1012 | + 17, 18, 62, -1, -1, 65, -1, -1, -1, 26, | |
1013 | + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, | |
1014 | + 37, -1, -1, 83, -1, -1, -1, -1, -1, -1, | |
1015 | + -1, -1, -1, -1, -1, 95, 96, 26, 27, 28, | |
1016 | + 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, | |
1017 | + -1, -1, 41, 10, 11, 12, 13, 14, 15, 16, | |
1018 | + -1, -1, -1, 20, 21, 22, 23, 24, 25 | |
1019 | }; | |
1020 | /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ | |
1021 | -#line 3 "/usr/lib/bison.simple" | |
1022 | +#line 3 "/usr/share/misc/bison.simple" | |
1023 | +/* This file comes from bison-1.28. */ | |
1024 | ||
1025 | /* Skeleton output parser for bison, | |
1026 | - Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman | |
1027 | + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. | |
1028 | ||
1029 | This program is free software; you can redistribute it and/or modify | |
1030 | it under the terms of the GNU General Public License as published by | |
1031 | - the Free Software Foundation; either version 1, or (at your option) | |
1032 | + the Free Software Foundation; either version 2, or (at your option) | |
1033 | any later version. | |
1034 | ||
1035 | This program is distributed in the hope that it will be useful, | |
1036 | @@ -300,42 +313,66 @@ | |
1037 | ||
1038 | You should have received a copy of the GNU General Public License | |
1039 | along with this program; if not, write to the Free Software | |
1040 | - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
1041 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
1042 | + Boston, MA 02111-1307, USA. */ | |
1043 | ||
1044 | +/* As a special exception, when this file is copied by Bison into a | |
1045 | + Bison output file, you may use that output file without restriction. | |
1046 | + This special exception was added by the Free Software Foundation | |
1047 | + in version 1.24 of Bison. */ | |
1048 | ||
1049 | -#ifndef alloca | |
1050 | +/* This is the parser code that is written into each bison parser | |
1051 | + when the %semantic_parser declaration is not specified in the grammar. | |
1052 | + It was written by Richard Stallman by simplifying the hairy parser | |
1053 | + used when %semantic_parser is specified. */ | |
1054 | + | |
1055 | +#ifndef YYSTACK_USE_ALLOCA | |
1056 | +#ifdef alloca | |
1057 | +#define YYSTACK_USE_ALLOCA | |
1058 | +#else /* alloca not defined */ | |
1059 | #ifdef __GNUC__ | |
1060 | +#define YYSTACK_USE_ALLOCA | |
1061 | #define alloca __builtin_alloca | |
1062 | #else /* not GNU C. */ | |
1063 | -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) | |
1064 | +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) | |
1065 | +#define YYSTACK_USE_ALLOCA | |
1066 | #include <alloca.h> | |
1067 | #else /* not sparc */ | |
1068 | -#if defined (MSDOS) && !defined (__TURBOC__) | |
1069 | +/* We think this test detects Watcom and Microsoft C. */ | |
1070 | +/* This used to test MSDOS, but that is a bad idea | |
1071 | + since that symbol is in the user namespace. */ | |
1072 | +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) | |
1073 | +#if 0 /* No need for malloc.h, which pollutes the namespace; | |
1074 | + instead, just don't use alloca. */ | |
1075 | #include <malloc.h> | |
1076 | +#endif | |
1077 | #else /* not MSDOS, or __TURBOC__ */ | |
1078 | #if defined(_AIX) | |
1079 | -#include <malloc.h> | |
1080 | +/* I don't know what this was needed for, but it pollutes the namespace. | |
1081 | + So I turned it off. rms, 2 May 1997. */ | |
1082 | +/* #include <malloc.h> */ | |
1083 | #pragma alloca | |
1084 | -#else /* not MSDOS, __TURBOC__, or _AIX */ | |
1085 | -#ifdef __hpux | |
1086 | -#ifdef __cplusplus | |
1087 | -extern "C" { | |
1088 | -void *alloca (unsigned int); | |
1089 | -}; | |
1090 | -#else /* not __cplusplus */ | |
1091 | -void *alloca (); | |
1092 | -#endif /* not __cplusplus */ | |
1093 | +#define YYSTACK_USE_ALLOCA | |
1094 | +#else /* not MSDOS, or __TURBOC__, or _AIX */ | |
1095 | +#if 0 | |
1096 | +#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, | |
1097 | + and on HPUX 10. Eventually we can turn this on. */ | |
1098 | +#define YYSTACK_USE_ALLOCA | |
1099 | +#define alloca __builtin_alloca | |
1100 | #endif /* __hpux */ | |
1101 | +#endif | |
1102 | #endif /* not _AIX */ | |
1103 | #endif /* not MSDOS, or __TURBOC__ */ | |
1104 | -#endif /* not sparc. */ | |
1105 | -#endif /* not GNU C. */ | |
1106 | -#endif /* alloca not defined. */ | |
1107 | +#endif /* not sparc */ | |
1108 | +#endif /* not GNU C */ | |
1109 | +#endif /* alloca not defined */ | |
1110 | +#endif /* YYSTACK_USE_ALLOCA not defined */ | |
1111 | ||
1112 | -/* This is the parser code that is written into each bison parser | |
1113 | - when the %semantic_parser declaration is not specified in the grammar. | |
1114 | - It was written by Richard Stallman by simplifying the hairy parser | |
1115 | - used when %semantic_parser is specified. */ | |
1116 | +#ifdef YYSTACK_USE_ALLOCA | |
1117 | +#define YYSTACK_ALLOC alloca | |
1118 | +#else | |
1119 | +#define YYSTACK_ALLOC malloc | |
1120 | +#endif | |
1121 | ||
1122 | /* Note: there must be only one dollar sign in this file. | |
1123 | It is replaced by the list of actions, each action | |
1124 | @@ -345,8 +382,8 @@ | |
1125 | #define yyclearin (yychar = YYEMPTY) | |
1126 | #define YYEMPTY -2 | |
1127 | #define YYEOF 0 | |
1128 | -#define YYACCEPT return(0) | |
1129 | -#define YYABORT return(1) | |
1130 | +#define YYACCEPT goto yyacceptlab | |
1131 | +#define YYABORT goto yyabortlab | |
1132 | #define YYERROR goto yyerrlab1 | |
1133 | /* Like YYERROR except do call yyerror. | |
1134 | This remains here temporarily to ease the | |
1135 | @@ -375,10 +412,18 @@ | |
1136 | ||
1137 | #ifdef YYPURE | |
1138 | #ifdef YYLSP_NEEDED | |
1139 | +#ifdef YYLEX_PARAM | |
1140 | +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) | |
1141 | +#else | |
1142 | #define YYLEX yylex(&yylval, &yylloc) | |
1143 | +#endif | |
1144 | +#else /* not YYLSP_NEEDED */ | |
1145 | +#ifdef YYLEX_PARAM | |
1146 | +#define YYLEX yylex(&yylval, YYLEX_PARAM) | |
1147 | #else | |
1148 | #define YYLEX yylex(&yylval) | |
1149 | #endif | |
1150 | +#endif /* not YYLSP_NEEDED */ | |
1151 | #endif | |
1152 | ||
1153 | /* If nonreentrant, generate the variables here */ | |
1154 | @@ -419,24 +464,24 @@ | |
1155 | #ifndef YYMAXDEPTH | |
1156 | #define YYMAXDEPTH 10000 | |
1157 | #endif | |
1158 | - | |
1159 | -/* Prevent warning if -Wstrict-prototypes. */ | |
1160 | -#ifdef __GNUC__ | |
1161 | -int yyparse (void); | |
1162 | -#endif | |
1163 | \f | |
1164 | +/* Define __yy_memcpy. Note that the size argument | |
1165 | + should be passed with type unsigned int, because that is what the non-GCC | |
1166 | + definitions require. With GCC, __builtin_memcpy takes an arg | |
1167 | + of type size_t, but it can handle unsigned int. */ | |
1168 | + | |
1169 | #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ | |
1170 | -#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) | |
1171 | +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) | |
1172 | #else /* not GNU C or C++ */ | |
1173 | #ifndef __cplusplus | |
1174 | ||
1175 | /* This is the most reliable way to avoid incompatibilities | |
1176 | in available built-in functions on various systems. */ | |
1177 | static void | |
1178 | -__yy_bcopy (from, to, count) | |
1179 | - char *from; | |
1180 | +__yy_memcpy (to, from, count) | |
1181 | char *to; | |
1182 | - int count; | |
1183 | + char *from; | |
1184 | + unsigned int count; | |
1185 | { | |
1186 | register char *f = from; | |
1187 | register char *t = to; | |
1188 | @@ -451,10 +496,10 @@ | |
1189 | /* This is the most reliable way to avoid incompatibilities | |
1190 | in available built-in functions on various systems. */ | |
1191 | static void | |
1192 | -__yy_bcopy (char *from, char *to, int count) | |
1193 | +__yy_memcpy (char *to, char *from, unsigned int count) | |
1194 | { | |
1195 | - register char *f = from; | |
1196 | register char *t = to; | |
1197 | + register char *f = from; | |
1198 | register int i = count; | |
1199 | ||
1200 | while (i-- > 0) | |
1201 | @@ -464,9 +509,39 @@ | |
1202 | #endif | |
1203 | #endif | |
1204 | \f | |
1205 | -#line 184 "/usr/lib/bison.simple" | |
1206 | +#line 217 "/usr/share/misc/bison.simple" | |
1207 | + | |
1208 | +/* The user can define YYPARSE_PARAM as the name of an argument to be passed | |
1209 | + into yyparse. The argument should have type void *. | |
1210 | + It should actually point to an object. | |
1211 | + Grammar actions can access the variable by casting it | |
1212 | + to the proper pointer type. */ | |
1213 | + | |
1214 | +#ifdef YYPARSE_PARAM | |
1215 | +#ifdef __cplusplus | |
1216 | +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM | |
1217 | +#define YYPARSE_PARAM_DECL | |
1218 | +#else /* not __cplusplus */ | |
1219 | +#define YYPARSE_PARAM_ARG YYPARSE_PARAM | |
1220 | +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; | |
1221 | +#endif /* not __cplusplus */ | |
1222 | +#else /* not YYPARSE_PARAM */ | |
1223 | +#define YYPARSE_PARAM_ARG | |
1224 | +#define YYPARSE_PARAM_DECL | |
1225 | +#endif /* not YYPARSE_PARAM */ | |
1226 | + | |
1227 | +/* Prevent warning if -Wstrict-prototypes. */ | |
1228 | +#ifdef __GNUC__ | |
1229 | +#ifdef YYPARSE_PARAM | |
1230 | +int yyparse (void *); | |
1231 | +#else | |
1232 | +int yyparse (void); | |
1233 | +#endif | |
1234 | +#endif | |
1235 | + | |
1236 | int | |
1237 | -yyparse() | |
1238 | +yyparse(YYPARSE_PARAM_ARG) | |
1239 | + YYPARSE_PARAM_DECL | |
1240 | { | |
1241 | register int yystate; | |
1242 | register int yyn; | |
1243 | @@ -492,6 +567,7 @@ | |
1244 | #endif | |
1245 | ||
1246 | int yystacksize = YYINITDEPTH; | |
1247 | + int yyfree_stacks = 0; | |
1248 | ||
1249 | #ifdef YYPURE | |
1250 | int yychar; | |
1251 | @@ -576,18 +652,32 @@ | |
1252 | if (yystacksize >= YYMAXDEPTH) | |
1253 | { | |
1254 | yyerror("parser stack overflow"); | |
1255 | + if (yyfree_stacks) | |
1256 | + { | |
1257 | + free (yyss); | |
1258 | + free (yyvs); | |
1259 | +#ifdef YYLSP_NEEDED | |
1260 | + free (yyls); | |
1261 | +#endif | |
1262 | + } | |
1263 | return 2; | |
1264 | } | |
1265 | yystacksize *= 2; | |
1266 | if (yystacksize > YYMAXDEPTH) | |
1267 | yystacksize = YYMAXDEPTH; | |
1268 | - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); | |
1269 | - __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); | |
1270 | - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); | |
1271 | - __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); | |
1272 | +#ifndef YYSTACK_USE_ALLOCA | |
1273 | + yyfree_stacks = 1; | |
1274 | +#endif | |
1275 | + yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); | |
1276 | + __yy_memcpy ((char *)yyss, (char *)yyss1, | |
1277 | + size * (unsigned int) sizeof (*yyssp)); | |
1278 | + yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); | |
1279 | + __yy_memcpy ((char *)yyvs, (char *)yyvs1, | |
1280 | + size * (unsigned int) sizeof (*yyvsp)); | |
1281 | #ifdef YYLSP_NEEDED | |
1282 | - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); | |
1283 | - __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); | |
1284 | + yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); | |
1285 | + __yy_memcpy ((char *)yyls, (char *)yyls1, | |
1286 | + size * (unsigned int) sizeof (*yylsp)); | |
1287 | #endif | |
1288 | #endif /* no yyoverflow */ | |
1289 | ||
1290 | @@ -747,102 +837,154 @@ | |
1291 | ||
1292 | switch (yyn) { | |
1293 | ||
1294 | -case 1: | |
1295 | -#line 40 "parsetime.y" | |
1296 | +case 2: | |
1297 | +#line 44 "parsetime.y" | |
1298 | { | |
1299 | time_only = 1; | |
1300 | ; | |
1301 | break;} | |
1302 | -case 20: | |
1303 | -#line 68 "parsetime.y" | |
1304 | +case 10: | |
1305 | +#line 59 "parsetime.y" | |
1306 | +{ | |
1307 | + add_date(1, DAY); | |
1308 | + ; | |
1309 | + break;} | |
1310 | +case 21: | |
1311 | +#line 76 "parsetime.y" | |
1312 | { | |
1313 | exectm.tm_hour = 12; | |
1314 | exectm.tm_min = 0; | |
1315 | ; | |
1316 | break;} | |
1317 | -case 21: | |
1318 | -#line 73 "parsetime.y" | |
1319 | +case 22: | |
1320 | +#line 81 "parsetime.y" | |
1321 | { | |
1322 | exectm.tm_hour = 0; | |
1323 | exectm.tm_min = 0; | |
1324 | add_date(1, DAY); | |
1325 | ; | |
1326 | break;} | |
1327 | -case 22: | |
1328 | -#line 79 "parsetime.y" | |
1329 | +case 23: | |
1330 | +#line 87 "parsetime.y" | |
1331 | { | |
1332 | exectm.tm_hour = 16; | |
1333 | exectm.tm_min = 0; | |
1334 | ; | |
1335 | break;} | |
1336 | -case 25: | |
1337 | -#line 88 "parsetime.y" | |
1338 | +case 27: | |
1339 | +#line 97 "parsetime.y" | |
1340 | { | |
1341 | - add_date ((7 + yyvsp[0].intval - exectm.tm_wday) %7 + 1, DAY); | |
1342 | + add_date ((6 + yyvsp[0].intval - exectm.tm_wday) %7 + 1, DAY); | |
1343 | ; | |
1344 | break;} | |
1345 | -case 27: | |
1346 | -#line 93 "parsetime.y" | |
1347 | +case 29: | |
1348 | +#line 102 "parsetime.y" | |
1349 | { | |
1350 | add_date(1, DAY); | |
1351 | ; | |
1352 | break;} | |
1353 | -case 34: | |
1354 | -#line 105 "parsetime.y" | |
1355 | +case 38: | |
1356 | +#line 117 "parsetime.y" | |
1357 | { | |
1358 | add_date(yyvsp[-1].intval, yyvsp[0].intval); | |
1359 | ; | |
1360 | break;} | |
1361 | -case 35: | |
1362 | -#line 109 "parsetime.y" | |
1363 | +case 39: | |
1364 | +#line 121 "parsetime.y" | |
1365 | { | |
1366 | add_date(1, yyvsp[0].intval); | |
1367 | ; | |
1368 | break;} | |
1369 | -case 36: | |
1370 | -#line 113 "parsetime.y" | |
1371 | +case 40: | |
1372 | +#line 125 "parsetime.y" | |
1373 | { | |
1374 | add_date ((6 + yyvsp[0].intval - exectm.tm_wday) %7 +1, DAY); | |
1375 | ; | |
1376 | break;} | |
1377 | -case 37: | |
1378 | -#line 119 "parsetime.y" | |
1379 | +case 41: | |
1380 | +#line 131 "parsetime.y" | |
1381 | { | |
1382 | add_date(-yyvsp[-1].intval, yyvsp[0].intval); | |
1383 | ; | |
1384 | break;} | |
1385 | -case 38: | |
1386 | -#line 124 "parsetime.y" | |
1387 | +case 42: | |
1388 | +#line 136 "parsetime.y" | |
1389 | { yyval.intval = MINUTE ; ; | |
1390 | break;} | |
1391 | -case 39: | |
1392 | -#line 125 "parsetime.y" | |
1393 | +case 43: | |
1394 | +#line 137 "parsetime.y" | |
1395 | { yyval.intval = HOUR ; ; | |
1396 | break;} | |
1397 | -case 40: | |
1398 | -#line 126 "parsetime.y" | |
1399 | +case 44: | |
1400 | +#line 138 "parsetime.y" | |
1401 | { yyval.intval = DAY ; ; | |
1402 | break;} | |
1403 | -case 41: | |
1404 | -#line 127 "parsetime.y" | |
1405 | +case 45: | |
1406 | +#line 139 "parsetime.y" | |
1407 | { yyval.intval = WEEK ; ; | |
1408 | break;} | |
1409 | -case 42: | |
1410 | -#line 128 "parsetime.y" | |
1411 | +case 46: | |
1412 | +#line 140 "parsetime.y" | |
1413 | { yyval.intval = MONTH ; ; | |
1414 | break;} | |
1415 | -case 43: | |
1416 | -#line 129 "parsetime.y" | |
1417 | +case 47: | |
1418 | +#line 141 "parsetime.y" | |
1419 | { yyval.intval = YEAR ; ; | |
1420 | break;} | |
1421 | -case 44: | |
1422 | -#line 133 "parsetime.y" | |
1423 | +case 48: | |
1424 | +#line 145 "parsetime.y" | |
1425 | { | |
1426 | - exectm.tm_min = -1; | |
1427 | - exectm.tm_hour = -1; | |
1428 | if (strlen(yyvsp[0].charval) == 4) { | |
1429 | + exectm.tm_min = -1; | |
1430 | + exectm.tm_hour = -1; | |
1431 | sscanf(yyvsp[0].charval, "%2d %2d", &exectm.tm_hour, | |
1432 | &exectm.tm_min); | |
1433 | + } else if (strlen(yyvsp[0].charval) >= 5 && strlen(yyvsp[0].charval) <= 8) { | |
1434 | + /* Ok, this is a kluge. I hate design errors... -Joey */ | |
1435 | + char shallot[5]; | |
1436 | + char *onion; | |
1437 | + | |
1438 | + onion=yyvsp[0].charval; | |
1439 | + memset (shallot, 0, sizeof (shallot)); | |
1440 | + if (strlen(yyvsp[0].charval) == 5 || strlen(yyvsp[0].charval) == 7) { | |
1441 | + strncpy (shallot,onion,1); | |
1442 | + onion++; | |
1443 | + } else { | |
1444 | + strncpy (shallot,onion,2); | |
1445 | + onion+=2; | |
1446 | + } | |
1447 | + sscanf(shallot, "%d", &exectm.tm_mon); | |
1448 | + | |
1449 | + if (exectm.tm_mon < 1 || exectm.tm_mon > 12) { | |
1450 | + yyerror("Error in month number"); | |
1451 | + YYERROR; | |
1452 | + } | |
1453 | + exectm.tm_mon--; | |
1454 | + | |
1455 | + memset (shallot, 0, sizeof (shallot)); | |
1456 | + strncpy (shallot,onion,2); | |
1457 | + sscanf(shallot, "%d", &exectm.tm_mday); | |
1458 | + if (exectm.tm_mday < 0 || exectm.tm_mday > 31) | |
1459 | + { | |
1460 | + yyerror("Error in day of month"); | |
1461 | + YYERROR; | |
1462 | + } | |
1463 | + | |
1464 | + onion+=2; | |
1465 | + memset (shallot, 0, sizeof (shallot)); | |
1466 | + strncpy (shallot,onion,4); | |
1467 | + if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) { | |
1468 | + yyerror("Error in year"); | |
1469 | + YYERROR; | |
1470 | + } | |
1471 | + if (exectm.tm_year < 70) { | |
1472 | + exectm.tm_year += 100; | |
1473 | + } | |
1474 | + else if (exectm.tm_year > 1900) { | |
1475 | + exectm.tm_year -= 1900; | |
1476 | + } | |
1477 | + | |
1478 | + free (yyvsp[0].charval); | |
1479 | } | |
1480 | else { | |
1481 | sscanf(yyvsp[0].charval, "%d", &exectm.tm_hour); | |
1482 | @@ -855,13 +997,13 @@ | |
1483 | YYERROR; | |
1484 | } | |
1485 | if (exectm.tm_hour > 24 || exectm.tm_hour < 0) { | |
1486 | - yyerror("Problem in minutes specification"); | |
1487 | + yyerror("Problem in hours specification"); | |
1488 | YYERROR; | |
1489 | } | |
1490 | ; | |
1491 | break;} | |
1492 | -case 45: | |
1493 | -#line 158 "parsetime.y" | |
1494 | +case 49: | |
1495 | +#line 216 "parsetime.y" | |
1496 | { | |
1497 | if (strcasecmp(yyvsp[0].charval,"utc") == 0) { | |
1498 | isgmt = 1; | |
1499 | @@ -873,8 +1015,8 @@ | |
1500 | free(yyvsp[0].charval); | |
1501 | ; | |
1502 | break;} | |
1503 | -case 47: | |
1504 | -#line 174 "parsetime.y" | |
1505 | +case 51: | |
1506 | +#line 232 "parsetime.y" | |
1507 | { | |
1508 | if (sscanf(yyvsp[0].charval, "%d", &exectm.tm_min) != 1) { | |
1509 | yyerror("Error in minute"); | |
1510 | @@ -883,8 +1025,20 @@ | |
1511 | free(yyvsp[0].charval); | |
1512 | ; | |
1513 | break;} | |
1514 | -case 49: | |
1515 | -#line 185 "parsetime.y" | |
1516 | +case 52: | |
1517 | +#line 242 "parsetime.y" | |
1518 | +{ | |
1519 | + if (exectm.tm_hour > 12) { | |
1520 | + yyerror("Hour too large for AM"); | |
1521 | + YYERROR; | |
1522 | + } | |
1523 | + else if (exectm.tm_hour == 12) { | |
1524 | + exectm.tm_hour = 0; | |
1525 | + } | |
1526 | + ; | |
1527 | + break;} | |
1528 | +case 53: | |
1529 | +#line 252 "parsetime.y" | |
1530 | { | |
1531 | if (exectm.tm_hour > 12) { | |
1532 | yyerror("Hour too large for PM"); | |
1533 | @@ -895,56 +1049,56 @@ | |
1534 | } | |
1535 | ; | |
1536 | break;} | |
1537 | -case 50: | |
1538 | -#line 197 "parsetime.y" | |
1539 | +case 54: | |
1540 | +#line 264 "parsetime.y" | |
1541 | { exectm.tm_mon = 0; ; | |
1542 | break;} | |
1543 | -case 51: | |
1544 | -#line 198 "parsetime.y" | |
1545 | +case 55: | |
1546 | +#line 265 "parsetime.y" | |
1547 | { exectm.tm_mon = 1; ; | |
1548 | break;} | |
1549 | -case 52: | |
1550 | -#line 199 "parsetime.y" | |
1551 | +case 56: | |
1552 | +#line 266 "parsetime.y" | |
1553 | { exectm.tm_mon = 2; ; | |
1554 | break;} | |
1555 | -case 53: | |
1556 | -#line 200 "parsetime.y" | |
1557 | +case 57: | |
1558 | +#line 267 "parsetime.y" | |
1559 | { exectm.tm_mon = 3; ; | |
1560 | break;} | |
1561 | -case 54: | |
1562 | -#line 201 "parsetime.y" | |
1563 | +case 58: | |
1564 | +#line 268 "parsetime.y" | |
1565 | { exectm.tm_mon = 4; ; | |
1566 | break;} | |
1567 | -case 55: | |
1568 | -#line 202 "parsetime.y" | |
1569 | +case 59: | |
1570 | +#line 269 "parsetime.y" | |
1571 | { exectm.tm_mon = 5; ; | |
1572 | break;} | |
1573 | -case 56: | |
1574 | -#line 203 "parsetime.y" | |
1575 | +case 60: | |
1576 | +#line 270 "parsetime.y" | |
1577 | { exectm.tm_mon = 6; ; | |
1578 | break;} | |
1579 | -case 57: | |
1580 | -#line 204 "parsetime.y" | |
1581 | +case 61: | |
1582 | +#line 271 "parsetime.y" | |
1583 | { exectm.tm_mon = 7; ; | |
1584 | break;} | |
1585 | -case 58: | |
1586 | -#line 205 "parsetime.y" | |
1587 | +case 62: | |
1588 | +#line 272 "parsetime.y" | |
1589 | { exectm.tm_mon = 8; ; | |
1590 | break;} | |
1591 | -case 59: | |
1592 | -#line 206 "parsetime.y" | |
1593 | +case 63: | |
1594 | +#line 273 "parsetime.y" | |
1595 | { exectm.tm_mon = 9; ; | |
1596 | break;} | |
1597 | -case 60: | |
1598 | -#line 207 "parsetime.y" | |
1599 | +case 64: | |
1600 | +#line 274 "parsetime.y" | |
1601 | { exectm.tm_mon =10; ; | |
1602 | break;} | |
1603 | -case 61: | |
1604 | -#line 208 "parsetime.y" | |
1605 | +case 65: | |
1606 | +#line 275 "parsetime.y" | |
1607 | { exectm.tm_mon =11; ; | |
1608 | break;} | |
1609 | -case 62: | |
1610 | -#line 212 "parsetime.y" | |
1611 | +case 66: | |
1612 | +#line 279 "parsetime.y" | |
1613 | { | |
1614 | { | |
1615 | int mnum = -1; | |
1616 | @@ -959,8 +1113,8 @@ | |
1617 | } | |
1618 | ; | |
1619 | break;} | |
1620 | -case 63: | |
1621 | -#line 226 "parsetime.y" | |
1622 | +case 67: | |
1623 | +#line 293 "parsetime.y" | |
1624 | { | |
1625 | exectm.tm_mday = -1; | |
1626 | sscanf(yyvsp[0].charval, "%d", &exectm.tm_mday); | |
1627 | @@ -972,8 +1126,8 @@ | |
1628 | free(yyvsp[0].charval); | |
1629 | ; | |
1630 | break;} | |
1631 | -case 64: | |
1632 | -#line 239 "parsetime.y" | |
1633 | +case 68: | |
1634 | +#line 306 "parsetime.y" | |
1635 | { | |
1636 | { | |
1637 | int ynum; | |
1638 | @@ -994,36 +1148,36 @@ | |
1639 | } | |
1640 | ; | |
1641 | break;} | |
1642 | -case 65: | |
1643 | -#line 261 "parsetime.y" | |
1644 | +case 69: | |
1645 | +#line 328 "parsetime.y" | |
1646 | { yyval.intval = 0; ; | |
1647 | break;} | |
1648 | -case 66: | |
1649 | -#line 262 "parsetime.y" | |
1650 | +case 70: | |
1651 | +#line 329 "parsetime.y" | |
1652 | { yyval.intval = 1; ; | |
1653 | break;} | |
1654 | -case 67: | |
1655 | -#line 263 "parsetime.y" | |
1656 | +case 71: | |
1657 | +#line 330 "parsetime.y" | |
1658 | { yyval.intval = 2; ; | |
1659 | break;} | |
1660 | -case 68: | |
1661 | -#line 264 "parsetime.y" | |
1662 | +case 72: | |
1663 | +#line 331 "parsetime.y" | |
1664 | { yyval.intval = 3; ; | |
1665 | break;} | |
1666 | -case 69: | |
1667 | -#line 265 "parsetime.y" | |
1668 | +case 73: | |
1669 | +#line 332 "parsetime.y" | |
1670 | { yyval.intval = 4; ; | |
1671 | break;} | |
1672 | -case 70: | |
1673 | -#line 266 "parsetime.y" | |
1674 | +case 74: | |
1675 | +#line 333 "parsetime.y" | |
1676 | { yyval.intval = 5; ; | |
1677 | break;} | |
1678 | -case 71: | |
1679 | -#line 267 "parsetime.y" | |
1680 | +case 75: | |
1681 | +#line 334 "parsetime.y" | |
1682 | { yyval.intval = 6; ; | |
1683 | break;} | |
1684 | -case 72: | |
1685 | -#line 271 "parsetime.y" | |
1686 | +case 76: | |
1687 | +#line 338 "parsetime.y" | |
1688 | { | |
1689 | if (sscanf(yyvsp[0].charval, "%d", &yyval.intval) != 1) { | |
1690 | yyerror("Unknown increment"); | |
1691 | @@ -1034,7 +1188,7 @@ | |
1692 | break;} | |
1693 | } | |
1694 | /* the action file gets copied in in place of this dollarsign */ | |
1695 | -#line 465 "/usr/lib/bison.simple" | |
1696 | +#line 543 "/usr/share/misc/bison.simple" | |
1697 | \f | |
1698 | yyvsp -= yylen; | |
1699 | yyssp -= yylen; | |
1700 | @@ -1229,8 +1383,32 @@ | |
1701 | ||
1702 | yystate = yyn; | |
1703 | goto yynewstate; | |
1704 | + | |
1705 | + yyacceptlab: | |
1706 | + /* YYACCEPT comes here. */ | |
1707 | + if (yyfree_stacks) | |
1708 | + { | |
1709 | + free (yyss); | |
1710 | + free (yyvs); | |
1711 | +#ifdef YYLSP_NEEDED | |
1712 | + free (yyls); | |
1713 | +#endif | |
1714 | + } | |
1715 | + return 0; | |
1716 | + | |
1717 | + yyabortlab: | |
1718 | + /* YYABORT comes here. */ | |
1719 | + if (yyfree_stacks) | |
1720 | + { | |
1721 | + free (yyss); | |
1722 | + free (yyvs); | |
1723 | +#ifdef YYLSP_NEEDED | |
1724 | + free (yyls); | |
1725 | +#endif | |
1726 | + } | |
1727 | + return 1; | |
1728 | } | |
1729 | -#line 287 "parsetime.y" | |
1730 | +#line 354 "parsetime.y" | |
1731 | ||
1732 | ||
1733 | ||
1734 | @@ -1266,6 +1444,24 @@ | |
1735 | } | |
1736 | ||
1737 | #ifdef TEST_PARSER | |
1738 | +/* | |
1739 | + | |
1740 | +Here are some lines to test: | |
1741 | + | |
1742 | +./parsetest 7AM Mar 24 2000 | |
1743 | +./parsetest 7AM Mar 24 00 | |
1744 | +./parsetest 7AM 032400 | |
1745 | +./parsetest 7AM 03/24/00 | |
1746 | +./parsetest 7AM 24.03.00 | |
1747 | +./parsetest 7AM Mar 24 | |
1748 | + | |
1749 | +./parsetest 03242000 | |
1750 | +./parsetest noon 03242000 | |
1751 | +./parsetest 5:30 | |
1752 | +./parsetest 4pm + 3 days | |
1753 | +./parsetest 10am Jul 31 | |
1754 | + | |
1755 | + */ | |
1756 | int | |
1757 | main(int argc, char **argv) | |
1758 | { | |
1759 | --- at-3.1.8.orig/y.tab.h | |
1760 | +++ at-3.1.8/y.tab.h | |
1761 | @@ -2,42 +2,42 @@ | |
1762 | char * charval; | |
1763 | int intval; | |
1764 | } YYSTYPE; | |
1765 | -#define INT 258 | |
1766 | -#define NOW 259 | |
1767 | -#define AM 260 | |
1768 | -#define PM 261 | |
1769 | -#define NOON 262 | |
1770 | -#define MIDNIGHT 263 | |
1771 | -#define TEATIME 264 | |
1772 | -#define SUN 265 | |
1773 | -#define MON 266 | |
1774 | -#define TUE 267 | |
1775 | -#define WED 268 | |
1776 | -#define THU 269 | |
1777 | -#define FRI 270 | |
1778 | -#define SAT 271 | |
1779 | -#define TODAY 272 | |
1780 | -#define TOMORROW 273 | |
1781 | -#define NEXT 274 | |
1782 | -#define MINUTE 275 | |
1783 | -#define HOUR 276 | |
1784 | -#define DAY 277 | |
1785 | -#define WEEK 278 | |
1786 | -#define MONTH 279 | |
1787 | -#define YEAR 280 | |
1788 | -#define JAN 281 | |
1789 | -#define FEB 282 | |
1790 | -#define MAR 283 | |
1791 | -#define APR 284 | |
1792 | -#define MAY 285 | |
1793 | -#define JUN 286 | |
1794 | -#define JUL 287 | |
1795 | -#define AUG 288 | |
1796 | -#define SEP 289 | |
1797 | -#define OCT 290 | |
1798 | -#define NOV 291 | |
1799 | -#define DEC 292 | |
1800 | -#define WORD 293 | |
1801 | +#define INT 257 | |
1802 | +#define NOW 258 | |
1803 | +#define AM 259 | |
1804 | +#define PM 260 | |
1805 | +#define NOON 261 | |
1806 | +#define MIDNIGHT 262 | |
1807 | +#define TEATIME 263 | |
1808 | +#define SUN 264 | |
1809 | +#define MON 265 | |
1810 | +#define TUE 266 | |
1811 | +#define WED 267 | |
1812 | +#define THU 268 | |
1813 | +#define FRI 269 | |
1814 | +#define SAT 270 | |
1815 | +#define TODAY 271 | |
1816 | +#define TOMORROW 272 | |
1817 | +#define NEXT 273 | |
1818 | +#define MINUTE 274 | |
1819 | +#define HOUR 275 | |
1820 | +#define DAY 276 | |
1821 | +#define WEEK 277 | |
1822 | +#define MONTH 278 | |
1823 | +#define YEAR 279 | |
1824 | +#define JAN 280 | |
1825 | +#define FEB 281 | |
1826 | +#define MAR 282 | |
1827 | +#define APR 283 | |
1828 | +#define MAY 284 | |
1829 | +#define JUN 285 | |
1830 | +#define JUL 286 | |
1831 | +#define AUG 287 | |
1832 | +#define SEP 288 | |
1833 | +#define OCT 289 | |
1834 | +#define NOV 290 | |
1835 | +#define DEC 291 | |
1836 | +#define WORD 292 | |
1837 | ||
1838 | ||
1839 | extern YYSTYPE yylval; | |
1840 | --- at-3.1.8.orig/lex.yy.c | |
1841 | +++ at-3.1.8/lex.yy.c | |
1842 | @@ -1,7 +1,7 @@ | |
1843 | /* A lexical scanner generated by flex */ | |
1844 | ||
1845 | /* Scanner skeleton version: | |
1846 | - * $Header$ | |
1847 | + * $Header$ | |
1848 | */ | |
1849 | ||
1850 | #define FLEX_SCANNER | |
1851 | @@ -126,6 +126,7 @@ | |
1852 | { \ | |
1853 | /* Undo effects of setting up yytext. */ \ | |
1854 | *yy_cp = yy_hold_char; \ | |
1855 | + YY_RESTORE_YY_MORE_OFFSET \ | |
1856 | yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ | |
1857 | YY_DO_BEFORE_ACTION; /* set up yytext again */ \ | |
1858 | } \ | |
1859 | @@ -235,7 +236,7 @@ | |
1860 | #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) | |
1861 | ||
1862 | YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); | |
1863 | -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str )); | |
1864 | +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); | |
1865 | YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); | |
1866 | ||
1867 | static void *yy_flex_alloc YY_PROTO(( yy_size_t )); | |
1868 | @@ -456,6 +457,7 @@ | |
1869 | #define REJECT reject_used_but_not_detected | |
1870 | #define yymore() yymore_used_but_not_detected | |
1871 | #define YY_MORE_ADJ 0 | |
1872 | +#define YY_RESTORE_YY_MORE_OFFSET | |
1873 | char *yytext; | |
1874 | #line 1 "parsetime.l" | |
1875 | #define INITIAL 0 | |
1876 | @@ -491,7 +493,7 @@ | |
1877 | result = 1; \ | |
1878 | } \ | |
1879 | } while(0) | |
1880 | -#line 495 "lex.yy.c" | |
1881 | +#line 497 "lex.yy.c" | |
1882 | ||
1883 | /* Macros after this point can all be overridden by user definitions in | |
1884 | * section 1. | |
1885 | @@ -513,6 +515,10 @@ | |
1886 | static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); | |
1887 | #endif | |
1888 | ||
1889 | +#ifdef YY_NEED_STRLEN | |
1890 | +static int yy_flex_strlen YY_PROTO(( yyconst char * )); | |
1891 | +#endif | |
1892 | + | |
1893 | #ifndef YY_NO_INPUT | |
1894 | #ifdef __cplusplus | |
1895 | static int yyinput YY_PROTO(( void )); | |
1896 | @@ -641,7 +647,7 @@ | |
1897 | #line 36 "parsetime.l" | |
1898 | ||
1899 | ||
1900 | -#line 645 "lex.yy.c" | |
1901 | +#line 651 "lex.yy.c" | |
1902 | ||
1903 | if ( yy_init ) | |
1904 | { | |
1905 | @@ -919,7 +925,7 @@ | |
1906 | #line 77 "parsetime.l" | |
1907 | ECHO; | |
1908 | YY_BREAK | |
1909 | -#line 923 "lex.yy.c" | |
1910 | +#line 929 "lex.yy.c" | |
1911 | case YY_STATE_EOF(INITIAL): | |
1912 | yyterminate(); | |
1913 | ||
1914 | @@ -930,6 +936,7 @@ | |
1915 | ||
1916 | /* Undo the effects of YY_DO_BEFORE_ACTION. */ | |
1917 | *yy_cp = yy_hold_char; | |
1918 | + YY_RESTORE_YY_MORE_OFFSET | |
1919 | ||
1920 | if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) | |
1921 | { | |
1922 | @@ -1075,7 +1082,7 @@ | |
1923 | { /* Don't try to fill the buffer, so this is an EOF. */ | |
1924 | if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) | |
1925 | { | |
1926 | - /* We matched a singled characater, the EOB, so | |
1927 | + /* We matched a single character, the EOB, so | |
1928 | * treat this as a final EOF. | |
1929 | */ | |
1930 | return EOB_ACT_END_OF_FILE; | |
1931 | @@ -1102,7 +1109,7 @@ | |
1932 | /* don't do the read, it's not guaranteed to return an EOF, | |
1933 | * just force an EOF | |
1934 | */ | |
1935 | - yy_n_chars = 0; | |
1936 | + yy_current_buffer->yy_n_chars = yy_n_chars = 0; | |
1937 | ||
1938 | else | |
1939 | { | |
1940 | @@ -1157,6 +1164,8 @@ | |
1941 | /* Read in more data. */ | |
1942 | YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), | |
1943 | yy_n_chars, num_to_read ); | |
1944 | + | |
1945 | + yy_current_buffer->yy_n_chars = yy_n_chars; | |
1946 | } | |
1947 | ||
1948 | if ( yy_n_chars == 0 ) | |
1949 | @@ -1281,7 +1290,8 @@ | |
1950 | ||
1951 | yy_cp += (int) (dest - source); | |
1952 | yy_bp += (int) (dest - source); | |
1953 | - yy_n_chars = yy_current_buffer->yy_buf_size; | |
1954 | + yy_current_buffer->yy_n_chars = | |
1955 | + yy_n_chars = yy_current_buffer->yy_buf_size; | |
1956 | ||
1957 | if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) | |
1958 | YY_FATAL_ERROR( "flex scanner push-back overflow" ); | |
1959 | @@ -1319,19 +1329,31 @@ | |
1960 | ||
1961 | else | |
1962 | { /* need more input */ | |
1963 | - yytext_ptr = yy_c_buf_p; | |
1964 | + int offset = yy_c_buf_p - yytext_ptr; | |
1965 | ++yy_c_buf_p; | |
1966 | ||
1967 | switch ( yy_get_next_buffer() ) | |
1968 | { | |
1969 | + case EOB_ACT_LAST_MATCH: | |
1970 | + /* This happens because yy_g_n_b() | |
1971 | + * sees that we've accumulated a | |
1972 | + * token and flags that we need to | |
1973 | + * try matching the token before | |
1974 | + * proceeding. But for input(), | |
1975 | + * there's no matching to consider. | |
1976 | + * So convert the EOB_ACT_LAST_MATCH | |
1977 | + * to EOB_ACT_END_OF_FILE. | |
1978 | + */ | |
1979 | + | |
1980 | + /* Reset buffer status. */ | |
1981 | + yyrestart( yyin ); | |
1982 | + | |
1983 | + /* fall through */ | |
1984 | + | |
1985 | case EOB_ACT_END_OF_FILE: | |
1986 | { | |
1987 | if ( yywrap() ) | |
1988 | - { | |
1989 | - yy_c_buf_p = | |
1990 | - yytext_ptr + YY_MORE_ADJ; | |
1991 | return EOF; | |
1992 | - } | |
1993 | ||
1994 | if ( ! yy_did_buffer_switch_on_eof ) | |
1995 | YY_NEW_FILE; | |
1996 | @@ -1343,17 +1365,8 @@ | |
1997 | } | |
1998 | ||
1999 | case EOB_ACT_CONTINUE_SCAN: | |
2000 | - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; | |
2001 | + yy_c_buf_p = yytext_ptr + offset; | |
2002 | break; | |
2003 | - | |
2004 | - case EOB_ACT_LAST_MATCH: | |
2005 | -#ifdef __cplusplus | |
2006 | - YY_FATAL_ERROR( | |
2007 | - "unexpected last match in yyinput()" ); | |
2008 | -#else | |
2009 | - YY_FATAL_ERROR( | |
2010 | - "unexpected last match in input()" ); | |
2011 | -#endif | |
2012 | } | |
2013 | } | |
2014 | } | |
2015 | @@ -1517,6 +1530,9 @@ | |
2016 | #endif | |
2017 | ||
2018 | { | |
2019 | + if ( ! b ) | |
2020 | + return; | |
2021 | + | |
2022 | b->yy_n_chars = 0; | |
2023 | ||
2024 | /* We always need two end-of-buffer characters. The first causes | |
2025 | @@ -1576,17 +1592,17 @@ | |
2026 | ||
2027 | #ifndef YY_NO_SCAN_STRING | |
2028 | #ifdef YY_USE_PROTOS | |
2029 | -YY_BUFFER_STATE yy_scan_string( yyconst char *str ) | |
2030 | +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) | |
2031 | #else | |
2032 | -YY_BUFFER_STATE yy_scan_string( str ) | |
2033 | -yyconst char *str; | |
2034 | +YY_BUFFER_STATE yy_scan_string( yy_str ) | |
2035 | +yyconst char *yy_str; | |
2036 | #endif | |
2037 | { | |
2038 | int len; | |
2039 | - for ( len = 0; str[len]; ++len ) | |
2040 | + for ( len = 0; yy_str[len]; ++len ) | |
2041 | ; | |
2042 | ||
2043 | - return yy_scan_bytes( str, len ); | |
2044 | + return yy_scan_bytes( yy_str, len ); | |
2045 | } | |
2046 | #endif | |
2047 | ||
2048 | @@ -1707,7 +1723,7 @@ | |
2049 | { \ | |
2050 | /* Undo effects of setting up yytext. */ \ | |
2051 | yytext[yyleng] = yy_hold_char; \ | |
2052 | - yy_c_buf_p = yytext + n - YY_MORE_ADJ; \ | |
2053 | + yy_c_buf_p = yytext + n; \ | |
2054 | yy_hold_char = *yy_c_buf_p; \ | |
2055 | *yy_c_buf_p = '\0'; \ | |
2056 | yyleng = n; \ | |
2057 | @@ -1730,6 +1746,22 @@ | |
2058 | register int i; | |
2059 | for ( i = 0; i < n; ++i ) | |
2060 | s1[i] = s2[i]; | |
2061 | + } | |
2062 | +#endif | |
2063 | + | |
2064 | +#ifdef YY_NEED_STRLEN | |
2065 | +#ifdef YY_USE_PROTOS | |
2066 | +static int yy_flex_strlen( yyconst char *s ) | |
2067 | +#else | |
2068 | +static int yy_flex_strlen( s ) | |
2069 | +yyconst char *s; | |
2070 | +#endif | |
2071 | + { | |
2072 | + register int n; | |
2073 | + for ( n = 0; s[n]; ++n ) | |
2074 | + ; | |
2075 | + | |
2076 | + return n; | |
2077 | } | |
2078 | #endif | |
2079 | ||
2080 | --- at-3.1.8.orig/Makefile.in | |
2081 | +++ at-3.1.8/Makefile.in | |
2082 | @@ -131,6 +133,7 @@ | |
2083 | ||
2084 | clean: | |
2085 | rm -f subs.sed *.o *.s at atd core a.out *~ $(CLONES) *.bak stamp-built | |
2086 | + rm -f parsetest | |
2087 | ||
2088 | distclean: clean | |
2089 | rm -rf at.1 atd.8 atrun.8 config.cache atrun config.h \ | |
2090 | @@ -144,6 +147,9 @@ | |
2091 | ||
2092 | Filelist.asc: Filelist | |
2093 | pgp -sba Filelist | |
2094 | + | |
2095 | +parsetest: lex.yy.c y.tab.c | |
2096 | + $(CC) -o parsetest $(CFLAGS) $(DEFS) -DTEST_PARSER -DNEED_YYWRAP lex.yy.c y.tab.c | |
2097 | ||
2098 | .depend: $(CSRCS) | |
2099 | gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend | |
2100 | --- at-3.1.8.orig/parsetime.y | |
2101 | +++ at-3.1.8/parsetime.y | |
2102 | @@ -11,6 +11,9 @@ | |
2103 | static int isgmt; | |
2104 | static int time_only; | |
2105 | ||
2106 | +extern int yyerror(char *s); | |
2107 | +extern int yylex(); | |
2108 | + | |
2109 | int add_date(int number, int period); | |
2110 | %} | |
2111 | ||
2112 | @@ -36,26 +39,31 @@ | |
2113 | ||
2114 | %start timespec | |
2115 | %% | |
2116 | -timespec : time | |
2117 | +timespec : date | |
2118 | + | time | |
2119 | { | |
2120 | time_only = 1; | |
2121 | } | |
2122 | | time date | |
2123 | - | time increment | |
2124 | - | time date increment | |
2125 | - | time decrement | |
2126 | - | time date decrement | |
2127 | + | time_or_not inc_or_dec | |
2128 | + | time_or_not date inc_or_dec | |
2129 | | nowspec | |
2130 | ; | |
2131 | ||
2132 | nowspec : now | |
2133 | - | now increment | |
2134 | - | now decrement | |
2135 | + | now inc_or_dec | |
2136 | ; | |
2137 | ||
2138 | now : NOW | |
2139 | + | TOMORROW | |
2140 | + { | |
2141 | + add_date(1, DAY); | |
2142 | + } | |
2143 | ; | |
2144 | ||
2145 | +time_or_not : time | |
2146 | + | | |
2147 | + | |
2148 | time : hr24clock_hr_min | |
2149 | | hr24clock_hr_min timezone_name | |
2150 | | hr24clock_hour time_sep minute | |
2151 | @@ -83,10 +91,11 @@ | |
2152 | ; | |
2153 | ||
2154 | date : month_name day_number | |
2155 | + | month_name day_number year_number | |
2156 | | month_name day_number ',' year_number | |
2157 | | day_of_week | |
2158 | { | |
2159 | - add_date ((7 + $1 - exectm.tm_wday) %7 + 1, DAY); | |
2160 | + add_date ((6 + $1 - exectm.tm_wday) %7 + 1, DAY); | |
2161 | } | |
2162 | | TODAY | |
2163 | | TOMORROW | |
2164 | @@ -101,6 +110,9 @@ | |
2165 | | month_number '/' day_number '/' year_number | |
2166 | ; | |
2167 | ||
2168 | +inc_or_dec : increment | |
2169 | + | decrement | |
2170 | + | |
2171 | increment : '+' inc_number inc_period | |
2172 | { | |
2173 | add_date($2, $3); | |
2174 | @@ -131,11 +143,57 @@ | |
2175 | ||
2176 | hr24clock_hr_min: INT | |
2177 | { | |
2178 | - exectm.tm_min = -1; | |
2179 | - exectm.tm_hour = -1; | |
2180 | if (strlen($1) == 4) { | |
2181 | + exectm.tm_min = -1; | |
2182 | + exectm.tm_hour = -1; | |
2183 | sscanf($1, "%2d %2d", &exectm.tm_hour, | |
2184 | &exectm.tm_min); | |
2185 | + } else if (strlen($1) >= 5 && strlen($1) <= 8) { | |
2186 | + /* Ok, this is a kluge. I hate design errors... -Joey */ | |
2187 | + char shallot[5]; | |
2188 | + char *onion; | |
2189 | + | |
2190 | + onion=$1; | |
2191 | + memset (shallot, 0, sizeof (shallot)); | |
2192 | + if (strlen($1) == 5 || strlen($1) == 7) { | |
2193 | + strncpy (shallot,onion,1); | |
2194 | + onion++; | |
2195 | + } else { | |
2196 | + strncpy (shallot,onion,2); | |
2197 | + onion+=2; | |
2198 | + } | |
2199 | + sscanf(shallot, "%d", &exectm.tm_mon); | |
2200 | + | |
2201 | + if (exectm.tm_mon < 1 || exectm.tm_mon > 12) { | |
2202 | + yyerror("Error in month number"); | |
2203 | + YYERROR; | |
2204 | + } | |
2205 | + exectm.tm_mon--; | |
2206 | + | |
2207 | + memset (shallot, 0, sizeof (shallot)); | |
2208 | + strncpy (shallot,onion,2); | |
2209 | + sscanf(shallot, "%d", &exectm.tm_mday); | |
2210 | + if (exectm.tm_mday < 0 || exectm.tm_mday > 31) | |
2211 | + { | |
2212 | + yyerror("Error in day of month"); | |
2213 | + YYERROR; | |
2214 | + } | |
2215 | + | |
2216 | + onion+=2; | |
2217 | + memset (shallot, 0, sizeof (shallot)); | |
2218 | + strncpy (shallot,onion,4); | |
2219 | + if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) { | |
2220 | + yyerror("Error in year"); | |
2221 | + YYERROR; | |
2222 | + } | |
2223 | + if (exectm.tm_year < 70) { | |
2224 | + exectm.tm_year += 100; | |
2225 | + } | |
2226 | + else if (exectm.tm_year > 1900) { | |
2227 | + exectm.tm_year -= 1900; | |
2228 | + } | |
2229 | + | |
2230 | + free ($1); | |
2231 | } | |
2232 | else { | |
2233 | sscanf($1, "%d", &exectm.tm_hour); | |
2234 | @@ -148,7 +206,7 @@ | |
2235 | YYERROR; | |
2236 | } | |
2237 | if (exectm.tm_hour > 24 || exectm.tm_hour < 0) { | |
2238 | - yyerror("Problem in minutes specification"); | |
2239 | + yyerror("Problem in hours specification"); | |
2240 | YYERROR; | |
2241 | } | |
2242 | } | |
2243 | @@ -181,6 +239,15 @@ | |
2244 | ; | |
2245 | ||
2246 | am_pm : AM | |
2247 | + { | |
2248 | + if (exectm.tm_hour > 12) { | |
2249 | + yyerror("Hour too large for AM"); | |
2250 | + YYERROR; | |
2251 | + } | |
2252 | + else if (exectm.tm_hour == 12) { | |
2253 | + exectm.tm_hour = 0; | |
2254 | + } | |
2255 | + } | |
2256 | | PM | |
2257 | { | |
2258 | if (exectm.tm_hour > 12) { | |
2259 | @@ -319,6 +386,24 @@ | |
2260 | } | |
2261 | ||
2262 | #ifdef TEST_PARSER | |
2263 | +/* | |
2264 | + | |
2265 | +Here are some lines to test: | |
2266 | + | |
2267 | +./parsetest 7AM Mar 24 2000 | |
2268 | +./parsetest 7AM Mar 24 00 | |
2269 | +./parsetest 7AM 032400 | |
2270 | +./parsetest 7AM 03/24/00 | |
2271 | +./parsetest 7AM 24.03.00 | |
2272 | +./parsetest 7AM Mar 24 | |
2273 | + | |
2274 | +./parsetest 03242000 | |
2275 | +./parsetest noon 03242000 | |
2276 | +./parsetest 5:30 | |
2277 | +./parsetest 4pm + 3 days | |
2278 | +./parsetest 10am Jul 31 | |
2279 | + | |
2280 | + */ | |
2281 | int | |
2282 | main(int argc, char **argv) | |
2283 | { |