1 2 # line 2 "getdate.y" 3 /* 4 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 5 * Use is subject to license terms. 6 */ 7 #pragma ident "%Z%%M% %I% %E% SMI" 8 9 /* $OrigRevision: 2.1 $ 10 ** 11 ** Originally written by Steven M. Bellovin <smb@research.att.com> while 12 ** at the University of North Carolina at Chapel Hill. Later tweaked by 13 ** a couple of people on Usenet. Completely overhauled by Rich $alz 14 ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990; 15 ** send any email to Rich. 16 ** 17 ** This grammar has eight shift/reduce conflicts. 18 ** 19 ** This code is in the public domain and has no copyright. 20 */ 21 /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */ 22 /* SUPPRESS 288 on yyerrlab *//* Label unused */ 23 #include <stdio.h> 24 #include <ctype.h> 25 26 #include <sys/types.h> 27 #define NEED_TZSET 28 struct timeb { 29 time_t time; /* Seconds since the epoch */ 30 unsigned short millitm; /* Field not used */ 31 short timezone; 32 short dstflag; /* Field not used */ 33 }; 34 #include <time.h> 35 36 #include <locale.h> 37 #include <string.h> 38 #include <stdlib.h> 39 #include <note.h> 40 #include <libintl.h> 41 42 #if !defined(lint) && !defined(SABER) 43 static char RCS[] = 44 "$Header: /home/laramie/berliner/ws/backup/usr/src/cmd/backup/lib/getdate.y,v 1.5 1992/06/09 21:46:21 sam Exp $"; 45 #endif /* !defined(lint) && !defined(SABER) */ 46 47 48 #define EPOCH 1970 49 #define HOURN(x) (x * 60) 50 #define SECSPERDAY (24L * 60L * 60L) 51 52 #define CHECK_TM(y) (((y) % 100) < 70 ? (y) + 2000 : (y) + 1900) 53 54 /* 55 ** An entry in the lexical lookup table. 56 */ 57 typedef struct _TABLE { 58 char *name; 59 int type; 60 time_t value; 61 } TABLE; 62 63 64 /* 65 ** Daylight-savings mode: on, off, or not yet known. 66 */ 67 typedef enum _DSTMODE { 68 DSTon, DSToff, DSTmaybe 69 } DSTMODE; 70 71 /* 72 ** Meridian: am, pm, or 24-hour style. 73 */ 74 typedef enum _MERIDIAN { 75 MERam, MERpm, MER24 76 } MERIDIAN; 77 78 79 /* 80 ** Global variables. We could get rid of most of these by using a good 81 ** union as the yacc stack. (This routine was originally written before 82 ** yacc had the %union construct.) Maybe someday; right now we only use 83 ** the %union very rarely. 84 */ 85 static char *yyInput; 86 static DSTMODE yyDSTmode; 87 static time_t yyDayOrdinal; 88 static time_t yyDayNumber; 89 static int yyHaveDate; 90 static int yyHaveDay; 91 static int yyHaveRel; 92 static int yyHaveTime; 93 static int yyHaveZone; 94 static time_t yyTimezone; 95 static time_t yyDay; 96 static time_t yyHour; 97 static time_t yyMinutes; 98 static time_t yyMonth; 99 static time_t yySeconds; 100 static time_t yyYear; 101 static MERIDIAN yyMeridian; 102 static time_t yyRelMonth; 103 static time_t yyRelSeconds; 104 105 static char *domainname = "hsm_libdump"; /* for dgettext() */ 106 107 #define yylex 1 /* suppress yacc's definition */ 108 109 # line 109 "getdate.y" 110 typedef union 111 #ifdef __cplusplus 112 YYSTYPE 113 #endif 114 { 115 time_t Number; 116 enum _MERIDIAN Meridian; 117 } YYSTYPE; 118 # define tAGO 257 119 # define tDAY 258 120 # define tDAYZONE 259 121 # define tID 260 122 # define tMERIDIAN 261 123 # define tMINUTE_UNIT 262 124 # define tMONTH 263 125 # define tMONTH_UNIT 264 126 # define tSEC_UNIT 265 127 # define tSNUMBER 266 128 # define tUNUMBER 267 129 # define tZONE 268 130 131 #include <inttypes.h> 132 133 #ifdef __STDC__ 134 #include <stdlib.h> 135 #include <string.h> 136 #define YYCONST const 137 #else 138 #include <malloc.h> 139 #include <memory.h> 140 #define YYCONST 141 #endif 142 143 #include <values.h> 144 145 #if defined(__cplusplus) || defined(__STDC__) 146 147 #if defined(__cplusplus) && defined(__EXTERN_C__) 148 extern "C" { 149 #endif 150 #ifndef yyerror 151 #if defined(__cplusplus) 152 void yyerror(YYCONST char *); 153 #endif 154 #endif 155 #ifndef yylex 156 int yylex(void); 157 #endif 158 int yyparse(void); 159 #if defined(__cplusplus) && defined(__EXTERN_C__) 160 } 161 #endif 162 163 #endif 164 165 #define yyclearin yychar = -1 166 #define yyerrok yyerrflag = 0 167 extern int yychar; 168 extern int yyerrflag; 169 YYSTYPE yylval; 170 YYSTYPE yyval; 171 typedef int yytabelem; 172 #ifndef YYMAXDEPTH 173 #define YYMAXDEPTH 150 174 #endif 175 #if YYMAXDEPTH > 0 176 int yy_yys[YYMAXDEPTH], *yys = yy_yys; 177 YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv; 178 #else /* user does initial allocation */ 179 int *yys; 180 YYSTYPE *yyv; 181 #endif 182 static int yymaxdepth = YYMAXDEPTH; 183 # define YYERRCODE 256 184 185 # line 296 "getdate.y" 186 187 188 /* Month and day table. */ 189 static TABLE MonthDayTable[] = { 190 { "january", tMONTH, 1 }, 191 { "february", tMONTH, 2 }, 192 { "march", tMONTH, 3 }, 193 { "april", tMONTH, 4 }, 194 { "may", tMONTH, 5 }, 195 { "june", tMONTH, 6 }, 196 { "july", tMONTH, 7 }, 197 { "august", tMONTH, 8 }, 198 { "september", tMONTH, 9 }, 199 { "sept", tMONTH, 9 }, 200 { "october", tMONTH, 10 }, 201 { "november", tMONTH, 11 }, 202 { "december", tMONTH, 12 }, 203 { "sunday", tDAY, 0 }, 204 { "monday", tDAY, 1 }, 205 { "tuesday", tDAY, 2 }, 206 { "tues", tDAY, 2 }, 207 { "wednesday", tDAY, 3 }, 208 { "wednes", tDAY, 3 }, 209 { "thursday", tDAY, 4 }, 210 { "thur", tDAY, 4 }, 211 { "thurs", tDAY, 4 }, 212 { "friday", tDAY, 5 }, 213 { "saturday", tDAY, 6 }, 214 { NULL } 215 }; 216 217 /* Time units table. */ 218 static TABLE UnitsTable[] = { 219 { "year", tMONTH_UNIT, 12 }, 220 { "month", tMONTH_UNIT, 1 }, 221 { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 }, 222 { "week", tMINUTE_UNIT, 7 * 24 * 60 }, 223 { "day", tMINUTE_UNIT, 1 * 24 * 60 }, 224 { "hour", tMINUTE_UNIT, 60 }, 225 { "minute", tMINUTE_UNIT, 1 }, 226 { "min", tMINUTE_UNIT, 1 }, 227 { "second", tSEC_UNIT, 1 }, 228 { "sec", tSEC_UNIT, 1 }, 229 { NULL } 230 }; 231 232 /* Assorted relative-time words. */ 233 static TABLE OtherTable[] = { 234 { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, 235 { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, 236 { "today", tMINUTE_UNIT, 0 }, 237 { "now", tMINUTE_UNIT, 0 }, 238 { "last", tUNUMBER, -1 }, 239 { "this", tMINUTE_UNIT, 0 }, 240 { "next", tUNUMBER, 2 }, 241 { "first", tUNUMBER, 1 }, 242 /* { "second", tUNUMBER, 2 }, */ 243 { "third", tUNUMBER, 3 }, 244 { "fourth", tUNUMBER, 4 }, 245 { "fifth", tUNUMBER, 5 }, 246 { "sixth", tUNUMBER, 6 }, 247 { "seventh", tUNUMBER, 7 }, 248 { "eighth", tUNUMBER, 8 }, 249 { "ninth", tUNUMBER, 9 }, 250 { "tenth", tUNUMBER, 10 }, 251 { "eleventh", tUNUMBER, 11 }, 252 { "twelfth", tUNUMBER, 12 }, 253 { "ago", tAGO, 1 }, 254 { NULL } 255 }; 256 257 /* The timezone table. */ 258 static TABLE TimezoneTable[] = { 259 { "gmt", tZONE, HOURN( 0) }, /* Greenwich Mean */ 260 { "ut", tZONE, HOURN( 0) }, /* Universal (Coordinated) */ 261 { "utc", tZONE, HOURN( 0) }, 262 { "wet", tZONE, HOURN( 0) }, /* Western European */ 263 { "bst", tDAYZONE, HOURN( 0) }, /* British Summer */ 264 { "wat", tZONE, HOURN( 1) }, /* West Africa */ 265 { "at", tZONE, HOURN( 2) }, /* Azores */ 266 #if 0 267 /* For completeness. BST is also British Summer, and GST is 268 * also Guam Standard. */ 269 { "bst", tZONE, HOURN( 3) }, /* Brazil Standard */ 270 { "gst", tZONE, HOURN( 3) }, /* Greenland Standard */ 271 #endif 272 { "nft", tZONE, HOURN(3.5) }, /* Newfoundland */ 273 { "nst", tZONE, HOURN(3.5) }, /* Newfoundland Standard */ 274 { "ndt", tDAYZONE, HOURN(3.5) }, /* Newfoundland Daylight */ 275 { "ast", tZONE, HOURN( 4) }, /* Atlantic Standard */ 276 { "adt", tDAYZONE, HOURN( 4) }, /* Atlantic Daylight */ 277 { "est", tZONE, HOURN( 5) }, /* Eastern Standard */ 278 { "edt", tDAYZONE, HOURN( 5) }, /* Eastern Daylight */ 279 { "cst", tZONE, HOURN( 6) }, /* Central Standard */ 280 { "cdt", tDAYZONE, HOURN( 6) }, /* Central Daylight */ 281 { "mst", tZONE, HOURN( 7) }, /* Mountain Standard */ 282 { "mdt", tDAYZONE, HOURN( 7) }, /* Mountain Daylight */ 283 { "pst", tZONE, HOURN( 8) }, /* Pacific Standard */ 284 { "pdt", tDAYZONE, HOURN( 8) }, /* Pacific Daylight */ 285 { "yst", tZONE, HOURN( 9) }, /* Yukon Standard */ 286 { "ydt", tDAYZONE, HOURN( 9) }, /* Yukon Daylight */ 287 { "hst", tZONE, HOURN(10) }, /* Hawaii Standard */ 288 { "hdt", tDAYZONE, HOURN(10) }, /* Hawaii Daylight */ 289 { "cat", tZONE, HOURN(10) }, /* Central Alaska */ 290 { "ahst", tZONE, HOURN(10) }, /* Alaska-Hawaii Standard */ 291 { "nt", tZONE, HOURN(11) }, /* Nome */ 292 { "idlw", tZONE, HOURN(12) }, /* International Date Line West */ 293 { "cet", tZONE, -HOURN(1) }, /* Central European */ 294 { "met", tZONE, -HOURN(1) }, /* Middle European */ 295 { "mewt", tZONE, -HOURN(1) }, /* Middle European Winter */ 296 { "mest", tDAYZONE, -HOURN(1) }, /* Middle European Summer */ 297 { "swt", tZONE, -HOURN(1) }, /* Swedish Winter */ 298 { "sst", tDAYZONE, -HOURN(1) }, /* Swedish Summer */ 299 { "fwt", tZONE, -HOURN(1) }, /* French Winter */ 300 { "fst", tDAYZONE, -HOURN(1) }, /* French Summer */ 301 { "eet", tZONE, -HOURN(2) }, /* Eastern Europe, USSR Zone 1 */ 302 { "bt", tZONE, -HOURN(3) }, /* Baghdad, USSR Zone 2 */ 303 { "it", tZONE, -HOURN(3.5) },/* Iran */ 304 { "zp4", tZONE, -HOURN(4) }, /* USSR Zone 3 */ 305 { "zp5", tZONE, -HOURN(5) }, /* USSR Zone 4 */ 306 { "ist", tZONE, -HOURN(5.5) },/* Indian Standard */ 307 { "zp6", tZONE, -HOURN(6) }, /* USSR Zone 5 */ 308 #if 0 309 /* For completeness. NST is also Newfoundland Stanard, nad SST is 310 * also Swedish Summer. */ 311 { "nst", tZONE, -HOURN(6.5) },/* North Sumatra */ 312 { "sst", tZONE, -HOURN(7) }, /* South Sumatra, USSR Zone 6 */ 313 #endif /* 0 */ 314 { "wast", tZONE, -HOURN(7) }, /* West Australian Standard */ 315 { "wadt", tDAYZONE, -HOURN(7) }, /* West Australian Daylight */ 316 { "jt", tZONE, -HOURN(7.5) },/* Java (3pm in Cronusland!) */ 317 { "cct", tZONE, -HOURN(8) }, /* China Coast, USSR Zone 7 */ 318 { "jst", tZONE, -HOURN(9) }, /* Japan Standard, USSR Zone 8 */ 319 { "cast", tZONE, -HOURN(9.5) },/* Central Australian Standard */ 320 { "cadt", tDAYZONE, -HOURN(9.5) },/* Central Australian Daylight */ 321 { "east", tZONE, -HOURN(10) }, /* Eastern Australian Standard */ 322 { "eadt", tDAYZONE, -HOURN(10) }, /* Eastern Australian Daylight */ 323 { "gst", tZONE, -HOURN(10) }, /* Guam Standard, USSR Zone 9 */ 324 { "nzt", tZONE, -HOURN(12) }, /* New Zealand */ 325 { "nzst", tZONE, -HOURN(12) }, /* New Zealand Standard */ 326 { "nzdt", tDAYZONE, -HOURN(12) }, /* New Zealand Daylight */ 327 { "idle", tZONE, -HOURN(12) }, /* International Date Line East */ 328 { NULL } 329 }; 330 331 /* Military timezone table. */ 332 static TABLE MilitaryTable[] = { 333 { "a", tZONE, HOURN( 1) }, 334 { "b", tZONE, HOURN( 2) }, 335 { "c", tZONE, HOURN( 3) }, 336 { "d", tZONE, HOURN( 4) }, 337 { "e", tZONE, HOURN( 5) }, 338 { "f", tZONE, HOURN( 6) }, 339 { "g", tZONE, HOURN( 7) }, 340 { "h", tZONE, HOURN( 8) }, 341 { "i", tZONE, HOURN( 9) }, 342 { "k", tZONE, HOURN( 10) }, 343 { "l", tZONE, HOURN( 11) }, 344 { "m", tZONE, HOURN( 12) }, 345 { "n", tZONE, HOURN(- 1) }, 346 { "o", tZONE, HOURN(- 2) }, 347 { "p", tZONE, HOURN(- 3) }, 348 { "q", tZONE, HOURN(- 4) }, 349 { "r", tZONE, HOURN(- 5) }, 350 { "s", tZONE, HOURN(- 6) }, 351 { "t", tZONE, HOURN(- 7) }, 352 { "u", tZONE, HOURN(- 8) }, 353 { "v", tZONE, HOURN(- 9) }, 354 { "w", tZONE, HOURN(-10) }, 355 { "x", tZONE, HOURN(-11) }, 356 { "y", tZONE, HOURN(-12) }, 357 { "z", tZONE, HOURN( 0) }, 358 { NULL } 359 }; 360 361 362 363 364 /* ARGSUSED */ 365 static void 366 yyerror(s) 367 char *s; 368 { 369 } 370 371 372 static time_t 373 ToSeconds(Hours, Minutes, Seconds, Meridian) 374 time_t Hours; 375 time_t Minutes; 376 time_t Seconds; 377 MERIDIAN Meridian; 378 { 379 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) 380 return -1; 381 switch (Meridian) { 382 case MER24: 383 if (Hours < 0 || Hours > 23) 384 return -1; 385 return (Hours * 60L + Minutes) * 60L + Seconds; 386 case MERam: 387 if (Hours < 1 || Hours > 12) 388 return -1; 389 if (Hours != 12) 390 return (Hours * 60L + Minutes) * 60L + Seconds; 391 else 392 return Minutes * 60L + Seconds; 393 case MERpm: 394 if (Hours < 1 || Hours > 12) 395 return -1; 396 if (Hours != 12) 397 return ((Hours + 12) * 60L + Minutes) * 60L + Seconds; 398 else 399 return (720L + Minutes) * 60L + Seconds; 400 } 401 /* NOTREACHED */ 402 return (-1); 403 } 404 405 406 static time_t 407 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode) 408 time_t Month; 409 time_t Day; 410 time_t Year; 411 time_t Hours; 412 time_t Minutes; 413 time_t Seconds; 414 MERIDIAN Meridian; 415 DSTMODE DSTmode; 416 { 417 static int DaysInMonth[12] = { 418 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 419 }; 420 time_t tod; 421 time_t Julian; 422 time_t i; 423 424 if (Year < 0) 425 Year = -Year; 426 if (Year < 138) 427 Year += 1900; 428 DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) 429 ? 29 : 28; 430 if (Year < EPOCH || Year > 2037 431 || Month < 1 || Month > 12 432 /* LINTED Month is a time_t so intermediate results aren't truncated */ 433 || Day < 1 || Day > DaysInMonth[(int)--Month]) 434 return -1; 435 436 for (Julian = Day - 1, i = 0; i < Month; i++) 437 Julian += DaysInMonth[i]; 438 for (i = EPOCH; i < Year; i++) 439 Julian += 365 + (i % 4 == 0); 440 Julian *= SECSPERDAY; 441 Julian += yyTimezone * 60L; 442 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) 443 return -1; 444 Julian += tod; 445 if (DSTmode == DSTon 446 || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) 447 Julian -= 60 * 60; 448 return Julian; 449 } 450 451 452 static time_t 453 DSTcorrect(Start, Future) 454 time_t Start; 455 time_t Future; 456 { 457 time_t StartDay; 458 time_t FutureDay; 459 460 StartDay = (localtime(&Start)->tm_hour + 1) % 24; 461 FutureDay = (localtime(&Future)->tm_hour + 1) % 24; 462 return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; 463 } 464 465 466 static time_t 467 RelativeDate(Start, DayOrdinal, DayNumber) 468 time_t Start; 469 time_t DayOrdinal; 470 time_t DayNumber; 471 { 472 struct tm *tm; 473 time_t now; 474 475 now = Start; 476 tm = localtime(&now); 477 now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); 478 now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); 479 return DSTcorrect(Start, now); 480 } 481 482 483 static time_t 484 RelativeMonth(Start, RelMonth) 485 time_t Start; 486 time_t RelMonth; 487 { 488 struct tm *tm; 489 time_t Month; 490 time_t Year; 491 492 if (RelMonth == 0) 493 return 0; 494 tm = localtime(&Start); 495 Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; 496 Year = Month / 12; 497 Month = Month % 12 + 1; 498 return DSTcorrect(Start, 499 Convert(Month, (time_t)tm->tm_mday, Year, 500 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, 501 MER24, DSTmaybe)); 502 } 503 504 505 static int 506 LookupWord(buff) 507 char *buff; 508 { 509 char *p; 510 char *q; 511 TABLE *tp; 512 uint_t i; 513 int abbrev; 514 515 /* Make it lowercase. */ 516 for (p = buff; *p; p++) 517 if (isupper((u_char)*p)) 518 *p = tolower(*p); 519 520 if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) { 521 yylval.Meridian = MERam; 522 return tMERIDIAN; 523 } 524 if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) { 525 yylval.Meridian = MERpm; 526 return tMERIDIAN; 527 } 528 529 /* See if we have an abbreviation for a month. */ 530 if (strlen(buff) == 3) 531 abbrev = 1; 532 else if (strlen(buff) == 4 && buff[3] == '.') { 533 abbrev = 1; 534 buff[3] = '\0'; 535 } 536 else 537 abbrev = 0; 538 539 for (tp = MonthDayTable; tp->name; tp++) { 540 if (abbrev) { 541 if (strncmp(buff, tp->name, 3) == 0) { 542 yylval.Number = tp->value; 543 return tp->type; 544 } 545 } 546 else if (strcmp(buff, tp->name) == 0) { 547 yylval.Number = tp->value; 548 return tp->type; 549 } 550 } 551 552 for (tp = TimezoneTable; tp->name; tp++) 553 if (strcmp(buff, tp->name) == 0) { 554 yylval.Number = tp->value; 555 return tp->type; 556 } 557 558 for (tp = UnitsTable; tp->name; tp++) 559 if (strcmp(buff, tp->name) == 0) { 560 yylval.Number = tp->value; 561 return tp->type; 562 } 563 564 /* Strip off any plural and try the units table again. */ 565 i = strlen(buff) - 1; 566 if (buff[i] == 's') { 567 buff[i] = '\0'; 568 for (tp = UnitsTable; tp->name; tp++) 569 if (strcmp(buff, tp->name) == 0) { 570 yylval.Number = tp->value; 571 return tp->type; 572 } 573 } 574 575 for (tp = OtherTable; tp->name; tp++) 576 if (strcmp(buff, tp->name) == 0) { 577 yylval.Number = tp->value; 578 return tp->type; 579 } 580 581 /* Military timezones. */ 582 if (buff[1] == '\0' && isalpha((u_char)*buff)) { 583 for (tp = MilitaryTable; tp->name; tp++) 584 if (strcmp(buff, tp->name) == 0) { 585 yylval.Number = tp->value; 586 return tp->type; 587 } 588 } 589 590 /* Drop out any periods and try the timezone table again. */ 591 for (i = 0, p = q = buff; *q; q++) 592 if (*q != '.') 593 *p++ = *q; 594 else 595 i++; 596 *p = '\0'; 597 if (i) 598 for (tp = TimezoneTable; tp->name; tp++) 599 if (strcmp(buff, tp->name) == 0) { 600 yylval.Number = tp->value; 601 return tp->type; 602 } 603 604 return tID; 605 } 606 607 void 608 pdateerr(p) 609 char *p; 610 { 611 char *name = "DATEMSK"; /* env variable for date format */ 612 char *value; 613 char fmt[256], line[256]; 614 FILE *fp; 615 time_t now; 616 struct tm *tm; 617 618 value = getenv(name); 619 if (value == (char *)0) { 620 fprintf(stderr, 621 dgettext(domainname, "%s: Environment variable %s not set\n"), 622 p, name); 623 return; 624 } 625 switch (getdate_err) { 626 case 0: 627 default: 628 fprintf(stderr, 629 dgettext(domainname, "%s: Unkown getdate() error\n"), p); 630 break; 631 case 1: 632 fprintf(stderr, 633 dgettext(domainname, "%s: %s null or undefined\n"), p, name); 634 break; 635 case 2: 636 fprintf(stderr, dgettext(domainname, 637 "%s: Cannot read template file %s\n"), p, value); 638 break; 639 case 3: 640 fprintf(stderr, dgettext(domainname, 641 "%s: Failed to get file status information\n"), p); 642 break; 643 case 4: 644 fprintf(stderr, dgettext(domainname, 645 "%s: Template file %s not a regular file\n"), p, value); 646 break; 647 case 5: 648 fprintf(stderr, dgettext(domainname, 649 "%s: Error reading template file %s\n"), p, value); 650 break; 651 case 6: 652 fprintf(stderr, dgettext(domainname, 653 "%s: %s failed\n"), p, "malloc()"); 654 break; 655 case 7: 656 fprintf(stderr, dgettext(domainname, 657 "%s: Bad date/time format\n"), p); 658 fp = fopen(value, "r"); 659 if (fp == (FILE *)0) 660 break; 661 now = time((time_t *)0); 662 tm = localtime(&now); 663 fprintf(stderr, dgettext(domainname, 664 "The following are examples of valid formats:\n")); 665 while (fgets(fmt, sizeof (fmt), fp)) { 666 if (strchr(fmt, '%') == (char *)0) 667 continue; 668 fprintf(stderr, " "); 669 (void) strftime(line, sizeof (line), fmt, tm); 670 fprintf(stderr, "%s", line); 671 } 672 (void) fclose(fp); 673 break; 674 case 8: 675 (void) fprintf(stderr, dgettext(domainname, 676 "%s: Invalid date specification\n"), p); 677 break; 678 } 679 } 680 681 #undef yylex 682 static int 683 yylex() 684 { 685 char c; 686 char *p; 687 char buff[20]; 688 int Count; 689 int sign; 690 691 for ( ; ; ) { 692 while (isspace((u_char)*yyInput)) 693 yyInput++; 694 695 if (isdigit((u_char)(c = *yyInput)) || c == '-' || c == '+') { 696 if (c == '-' || c == '+') { 697 sign = c == '-' ? -1 : 1; 698 if (!isdigit((u_char)*++yyInput)) 699 /* skip the '-' sign */ 700 continue; 701 } 702 else 703 sign = 0; 704 yylval.Number = 0; 705 while (isdigit((u_char)(c = *yyInput++))) { 706 int n; 707 char digit = c; 708 (void) sscanf(&digit, "%1d", &n); 709 yylval.Number = 10 * yylval.Number + n; 710 } 711 yyInput--; 712 if (sign < 0) 713 yylval.Number = -yylval.Number; 714 return sign ? tSNUMBER : tUNUMBER; 715 } 716 if (isalpha((u_char)c)) { 717 for (p = buff; isalpha((u_char)(c = *yyInput++)) || c == '.'; ) 718 if (p < &buff[sizeof (buff) - 1]) 719 *p++ = c; 720 *p = '\0'; 721 yyInput--; 722 return LookupWord(buff); 723 } 724 if (c != '(') 725 return *yyInput++; 726 Count = 0; 727 do { 728 c = *yyInput++; 729 if (c == '\0') 730 return c; 731 if (c == '(') 732 Count++; 733 else if (c == ')') 734 Count--; 735 } while (Count > 0); 736 } 737 } 738 739 740 time_t 741 getreldate(p, now) 742 char *p; 743 struct timeb *now; 744 { 745 struct tm *tm; 746 struct timeb ftz; 747 time_t Start; 748 time_t tod; 749 750 if (strcmp(setlocale(LC_TIME, NULL), "C")) { 751 static char localedate[24]; 752 struct tm ltm; 753 754 tm = getdate(p); 755 if (getdate_err == 1 /* NODATEMASK */) { 756 char buffy[BUFSIZ]; 757 time_t current; 758 759 printf(gettext("environment variable %s not set\n"), "DATEMSK"); 760 do { 761 time(¤t); 762 tm = localtime(¤t); 763 memcpy(<m, tm, sizeof(ltm)); 764 tm = <m; 765 766 (void) fputs(gettext("Enter date as mmddhhmm[yy]: "), stdout); 767 (void) fflush(stdout); 768 if (fgets(buffy, sizeof (buffy), stdin) == NULL) { 769 (void) printf(gettext("Encountered EOF on stdin\n")); 770 return(-1); 771 } 772 } while (sscanf(buffy, "%2d%2d%2d%2d%2d", 773 &(tm->tm_mon), &(tm->tm_mday), &(tm->tm_hour), 774 &(tm->tm_min), &(tm->tm_year)) < 4); 775 776 (tm->tm_mon)--; 777 } else if (tm == NULL) 778 return(-1); 779 780 (void)sprintf(localedate, "%d:%2.2d %d/%d %d", 781 tm->tm_hour, tm->tm_min, tm->tm_mon + 1, 782 tm->tm_mday, CHECK_TM(tm->tm_year)); 783 p = localedate; 784 } 785 786 yyInput = p; 787 if (now == NULL) { 788 now = &ftz; 789 (void) time(&ftz.time); 790 /* Set the timezone global. */ 791 tzset(); 792 /* LINTED timezone is time_t so intermediate results aren't truncated */ 793 ftz.timezone = (int) timezone / 60; 794 } 795 796 tm = localtime(&now->time); 797 yyYear = tm->tm_year; 798 yyMonth = tm->tm_mon + 1; 799 yyDay = tm->tm_mday; 800 yyTimezone = now->timezone; 801 yyDSTmode = DSTmaybe; 802 yyHour = tm->tm_hour; 803 yyMinutes = tm->tm_min; 804 yySeconds = tm->tm_sec; 805 yyMeridian = MER24; 806 yyRelSeconds = 0; 807 yyRelMonth = 0; 808 yyHaveDate = 0; 809 yyHaveDay = 0; 810 yyHaveRel = 0; 811 yyHaveTime = 0; 812 yyHaveZone = 0; 813 814 if (yyparse() 815 || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) 816 return -1; 817 818 if (yyHaveDate || yyHaveTime || yyHaveDay) { 819 Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, 820 yyMeridian, yyDSTmode); 821 if (Start < 0) 822 return -1; 823 } 824 else { 825 Start = now->time; 826 if (!yyHaveRel) 827 Start -= ((tm->tm_hour * 60L) + tm->tm_min * 60L) + tm->tm_sec; 828 } 829 830 Start += yyRelSeconds; 831 Start += RelativeMonth(Start, yyRelMonth); 832 833 if (yyHaveDay && !yyHaveDate) { 834 tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber); 835 Start += tod; 836 } 837 838 /* Have to do *something* with a legitimate -1 so it's distinguishable 839 * from the error return value. (Alternately could set errno on error.) */ 840 return Start == -1 ? 0 : Start; 841 } 842 843 #if defined(TEST) 844 845 /* ARGSUSED */ 846 main(ac, av) 847 int ac; 848 char *av[]; 849 { 850 char buff[128]; 851 time_t d; 852 853 (void) setlocale(LC_ALL, ""); 854 #if !defined(TEXT_DOMAIN) 855 #define TEXT_DOMAIN "SYS_TEST" 856 #endif 857 (void) textdomain(TEXT_DOMAIN); 858 859 (void) printf(gettext("Enter date, or blank line to exit.\n\t> ")); 860 (void) fflush(stdout); 861 while (gets(buff) && buff[0]) { 862 d = getreldate(buff, (struct timeb *)NULL); 863 if (d == -1) 864 (void) printf(gettext("Bad format - couldn't convert.\n")); 865 else { 866 (void) cftime(buff, "%c\n", &d); 867 (void) printf("%s", buff); 868 } 869 (void) printf("\t> "); 870 (void) fflush(stdout); 871 } 872 exit(0); 873 /* NOTREACHED */ 874 } 875 #endif /* defined(TEST) */ 876 static YYCONST yytabelem yyexca[] ={ 877 -1, 1, 878 0, -1, 879 -2, 0, 880 }; 881 # define YYNPROD 39 882 # define YYLAST 221 883 static YYCONST yytabelem yyact[]={ 884 885 13, 11, 22, 39, 16, 12, 18, 17, 15, 9, 886 10, 40, 44, 20, 43, 42, 46, 29, 35, 34, 887 33, 30, 27, 32, 31, 41, 36, 28, 37, 14, 888 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 889 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 890 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 891 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 892 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 893 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 895 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 896 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 897 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 898 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 899 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 901 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 902 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 905 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 906 0, 38, 0, 21, 0, 0, 19, 24, 23, 26, 907 25 }; 908 static YYCONST yytabelem yypact[]={ 909 910 -10000000, -258,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000, -45, 911 -10000000,-10000000, -245, -17, -240, -241,-10000000,-10000000,-10000000,-10000000, 912 -247,-10000000, -248, -249,-10000000,-10000000,-10000000, -18,-10000000,-10000000, 913 -10000000,-10000000,-10000000, -55, -22,-10000000, -252,-10000000,-10000000, -253, 914 -10000000, -255,-10000000, -250,-10000000,-10000000,-10000000 }; 915 static YYCONST yytabelem yypgo[]={ 916 917 0, 28, 37, 36, 35, 34, 33, 32, 31, 30, 918 29 }; 919 static YYCONST yytabelem yyr1[]={ 920 921 0, 2, 2, 3, 3, 3, 3, 3, 3, 4, 922 4, 4, 4, 4, 5, 5, 7, 7, 7, 6, 923 6, 6, 6, 6, 6, 8, 8, 10, 10, 10, 924 10, 10, 10, 10, 10, 10, 9, 1, 1 }; 925 static YYCONST yytabelem yyr2[]={ 926 927 0, 0, 4, 3, 3, 3, 3, 3, 2, 5, 928 9, 9, 13, 13, 3, 3, 3, 5, 5, 7, 929 11, 5, 9, 5, 7, 5, 2, 5, 5, 3, 930 5, 5, 3, 5, 5, 3, 3, 1, 3 }; 931 static YYCONST yytabelem yychk[]={ 932 933 -10000000, -2, -3, -4, -5, -6, -7, -8, -9, 267, 934 268, 259, 263, 258, -10, 266, 262, 265, 264, 261, 935 58, 258, 47, 263, 262, 265, 264, 267, 44, 257, 936 262, 265, 264, 267, 267, 267, 44, -1, 266, 58, 937 261, 47, 267, 267, 267, -1, 266 }; 938 static YYCONST yytabelem yydef[]={ 939 940 1, -2, 2, 3, 4, 5, 6, 7, 8, 36, 941 14, 15, 0, 16, 26, 0, 29, 32, 35, 9, 942 0, 18, 0, 23, 27, 31, 34, 21, 17, 25, 943 28, 30, 33, 37, 19, 24, 0, 10, 11, 0, 944 38, 0, 22, 37, 20, 12, 13 }; 945 typedef struct 946 #ifdef __cplusplus 947 yytoktype 948 #endif 949 { 950 #ifdef __cplusplus 951 const 952 #endif 953 char *t_name; int t_val; } yytoktype; 954 #ifndef YYDEBUG 955 # define YYDEBUG 0 /* don't allow debugging */ 956 #endif 957 958 #if YYDEBUG 959 960 yytoktype yytoks[] = 961 { 962 "tAGO", 257, 963 "tDAY", 258, 964 "tDAYZONE", 259, 965 "tID", 260, 966 "tMERIDIAN", 261, 967 "tMINUTE_UNIT", 262, 968 "tMONTH", 263, 969 "tMONTH_UNIT", 264, 970 "tSEC_UNIT", 265, 971 "tSNUMBER", 266, 972 "tUNUMBER", 267, 973 "tZONE", 268, 974 "-unknown-", -1 /* ends search */ 975 }; 976 977 #ifdef __cplusplus 978 const 979 #endif 980 char * yyreds[] = 981 { 982 "-no such reduction-", 983 "spec : /* empty */", 984 "spec : spec item", 985 "item : time", 986 "item : zone", 987 "item : date", 988 "item : day", 989 "item : rel", 990 "item : number", 991 "time : tUNUMBER tMERIDIAN", 992 "time : tUNUMBER ':' tUNUMBER o_merid", 993 "time : tUNUMBER ':' tUNUMBER tSNUMBER", 994 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid", 995 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER", 996 "zone : tZONE", 997 "zone : tDAYZONE", 998 "day : tDAY", 999 "day : tDAY ','", 1000 "day : tUNUMBER tDAY", 1001 "date : tUNUMBER '/' tUNUMBER", 1002 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER", 1003 "date : tMONTH tUNUMBER", 1004 "date : tMONTH tUNUMBER ',' tUNUMBER", 1005 "date : tUNUMBER tMONTH", 1006 "date : tUNUMBER tMONTH tUNUMBER", 1007 "rel : relunit tAGO", 1008 "rel : relunit", 1009 "relunit : tUNUMBER tMINUTE_UNIT", 1010 "relunit : tSNUMBER tMINUTE_UNIT", 1011 "relunit : tMINUTE_UNIT", 1012 "relunit : tSNUMBER tSEC_UNIT", 1013 "relunit : tUNUMBER tSEC_UNIT", 1014 "relunit : tSEC_UNIT", 1015 "relunit : tSNUMBER tMONTH_UNIT", 1016 "relunit : tUNUMBER tMONTH_UNIT", 1017 "relunit : tMONTH_UNIT", 1018 "number : tUNUMBER", 1019 "o_merid : /* empty */", 1020 "o_merid : tMERIDIAN", 1021 }; 1022 #endif /* YYDEBUG */ 1023 # line 1 "/usr/share/lib/ccs/yaccpar" 1024 /* 1025 * CDDL HEADER START 1026 * 1027 * The contents of this file are subject to the terms of the 1028 * Common Development and Distribution License, Version 1.0 only 1029 * (the "License"). You may not use this file except in compliance 1030 * with the License. 1031 * 1032 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1033 * or http://www.opensolaris.org/os/licensing. 1034 * See the License for the specific language governing permissions 1035 * and limitations under the License. 1036 * 1037 * When distributing Covered Code, include this CDDL HEADER in each 1038 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1039 * If applicable, add the following below this CDDL HEADER, with the 1040 * fields enclosed by brackets "[]" replaced with your own identifying 1041 * information: Portions Copyright [yyyy] [name of copyright owner] 1042 * 1043 * CDDL HEADER END 1044 */ 1045 /* 1046 * Copyright 1993 Sun Microsystems, Inc. All rights reserved. 1047 * Use is subject to license terms. 1048 */ 1049 1050 /* Copyright (c) 1988 AT&T */ 1051 /* All Rights Reserved */ 1052 1053 #pragma ident "%Z%%M% %I% %E% SMI" 1054 1055 /* 1056 ** Skeleton parser driver for yacc output 1057 */ 1058 1059 /* 1060 ** yacc user known macros and defines 1061 */ 1062 #define YYERROR goto yyerrlab 1063 #define YYACCEPT return(0) 1064 #define YYABORT return(1) 1065 #define YYBACKUP( newtoken, newvalue )\ 1066 {\ 1067 if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ 1068 {\ 1069 yyerror( "syntax error - cannot backup" );\ 1070 goto yyerrlab;\ 1071 }\ 1072 yychar = newtoken;\ 1073 yystate = *yyps;\ 1074 yylval = newvalue;\ 1075 goto yynewstate;\ 1076 } 1077 #define YYRECOVERING() (!!yyerrflag) 1078 #define YYNEW(type) malloc(sizeof(type) * yynewmax) 1079 #define YYCOPY(to, from, type) \ 1080 (type *) memcpy(to, (char *) from, yymaxdepth * sizeof (type)) 1081 #define YYENLARGE( from, type) \ 1082 (type *) realloc((char *) from, yynewmax * sizeof(type)) 1083 #ifndef YYDEBUG 1084 # define YYDEBUG 1 /* make debugging available */ 1085 #endif 1086 1087 /* 1088 ** user known globals 1089 */ 1090 int yydebug; /* set to 1 to get debugging */ 1091 1092 /* 1093 ** driver internal defines 1094 */ 1095 #define YYFLAG (-10000000) 1096 1097 /* 1098 ** global variables used by the parser 1099 */ 1100 YYSTYPE *yypv; /* top of value stack */ 1101 int *yyps; /* top of state stack */ 1102 1103 int yystate; /* current state */ 1104 int yytmp; /* extra var (lasts between blocks) */ 1105 1106 int yynerrs; /* number of errors */ 1107 int yyerrflag; /* error recovery flag */ 1108 int yychar; /* current input token number */ 1109 1110 1111 1112 #ifdef YYNMBCHARS 1113 #define YYLEX() yycvtok(yylex()) 1114 /* 1115 ** yycvtok - return a token if i is a wchar_t value that exceeds 255. 1116 ** If i<255, i itself is the token. If i>255 but the neither 1117 ** of the 30th or 31st bit is on, i is already a token. 1118 */ 1119 #if defined(__STDC__) || defined(__cplusplus) 1120 int yycvtok(int i) 1121 #else 1122 int yycvtok(i) int i; 1123 #endif 1124 { 1125 int first = 0; 1126 int last = YYNMBCHARS - 1; 1127 int mid; 1128 wchar_t j; 1129 1130 if(i&0x60000000){/*Must convert to a token. */ 1131 if( yymbchars[last].character < i ){ 1132 return i;/*Giving up*/ 1133 } 1134 while ((last>=first)&&(first>=0)) {/*Binary search loop*/ 1135 mid = (first+last)/2; 1136 j = yymbchars[mid].character; 1137 if( j==i ){/*Found*/ 1138 return yymbchars[mid].tvalue; 1139 }else if( j<i ){ 1140 first = mid + 1; 1141 }else{ 1142 last = mid -1; 1143 } 1144 } 1145 /*No entry in the table.*/ 1146 return i;/* Giving up.*/ 1147 }else{/* i is already a token. */ 1148 return i; 1149 } 1150 } 1151 #else/*!YYNMBCHARS*/ 1152 #define YYLEX() yylex() 1153 #endif/*!YYNMBCHARS*/ 1154 1155 /* 1156 ** yyparse - return 0 if worked, 1 if syntax error not recovered from 1157 */ 1158 #if defined(__STDC__) || defined(__cplusplus) 1159 int yyparse(void) 1160 #else 1161 int yyparse() 1162 #endif 1163 { 1164 register YYSTYPE *yypvt = 0; /* top of value stack for $vars */ 1165 1166 #if defined(__cplusplus) || defined(lint) 1167 /* 1168 hacks to please C++ and lint - goto's inside 1169 switch should never be executed 1170 */ 1171 static int __yaccpar_lint_hack__ = 0; 1172 switch (__yaccpar_lint_hack__) 1173 { 1174 case 1: goto yyerrlab; 1175 case 2: goto yynewstate; 1176 } 1177 #endif 1178 1179 /* 1180 ** Initialize externals - yyparse may be called more than once 1181 */ 1182 yypv = &yyv[-1]; 1183 yyps = &yys[-1]; 1184 yystate = 0; 1185 yytmp = 0; 1186 yynerrs = 0; 1187 yyerrflag = 0; 1188 yychar = -1; 1189 1190 #if YYMAXDEPTH <= 0 1191 if (yymaxdepth <= 0) 1192 { 1193 if ((yymaxdepth = YYEXPAND(0)) <= 0) 1194 { 1195 yyerror("yacc initialization error"); 1196 YYABORT; 1197 } 1198 } 1199 #endif 1200 1201 { 1202 register YYSTYPE *yy_pv; /* top of value stack */ 1203 register int *yy_ps; /* top of state stack */ 1204 register int yy_state; /* current state */ 1205 register int yy_n; /* internal state number info */ 1206 goto yystack; /* moved from 6 lines above to here to please C++ */ 1207 1208 /* 1209 ** get globals into registers. 1210 ** branch to here only if YYBACKUP was called. 1211 */ 1212 yynewstate: 1213 yy_pv = yypv; 1214 yy_ps = yyps; 1215 yy_state = yystate; 1216 goto yy_newstate; 1217 1218 /* 1219 ** get globals into registers. 1220 ** either we just started, or we just finished a reduction 1221 */ 1222 yystack: 1223 yy_pv = yypv; 1224 yy_ps = yyps; 1225 yy_state = yystate; 1226 1227 /* 1228 ** top of for (;;) loop while no reductions done 1229 */ 1230 yy_stack: 1231 /* 1232 ** put a state and value onto the stacks 1233 */ 1234 #if YYDEBUG 1235 /* 1236 ** if debugging, look up token value in list of value vs. 1237 ** name pairs. 0 and negative (-1) are special values. 1238 ** Note: linear search is used since time is not a real 1239 ** consideration while debugging. 1240 */ 1241 if ( yydebug ) 1242 { 1243 register int yy_i; 1244 1245 printf( "State %d, token ", yy_state ); 1246 if ( yychar == 0 ) 1247 printf( "end-of-file\n" ); 1248 else if ( yychar < 0 ) 1249 printf( "-none-\n" ); 1250 else 1251 { 1252 for ( yy_i = 0; yytoks[yy_i].t_val >= 0; 1253 yy_i++ ) 1254 { 1255 if ( yytoks[yy_i].t_val == yychar ) 1256 break; 1257 } 1258 printf( "%s\n", yytoks[yy_i].t_name ); 1259 } 1260 } 1261 #endif /* YYDEBUG */ 1262 if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ 1263 { 1264 /* 1265 ** reallocate and recover. Note that pointers 1266 ** have to be reset, or bad things will happen 1267 */ 1268 long yyps_index = (yy_ps - yys); 1269 long yypv_index = (yy_pv - yyv); 1270 long yypvt_index = (yypvt - yyv); 1271 int yynewmax; 1272 #ifdef YYEXPAND 1273 yynewmax = YYEXPAND(yymaxdepth); 1274 #else 1275 yynewmax = 2 * yymaxdepth; /* double table size */ 1276 if (yymaxdepth == YYMAXDEPTH) /* first time growth */ 1277 { 1278 char *newyys = (char *)YYNEW(int); 1279 char *newyyv = (char *)YYNEW(YYSTYPE); 1280 if (newyys != 0 && newyyv != 0) 1281 { 1282 yys = YYCOPY(newyys, yys, int); 1283 yyv = YYCOPY(newyyv, yyv, YYSTYPE); 1284 } 1285 else 1286 yynewmax = 0; /* failed */ 1287 } 1288 else /* not first time */ 1289 { 1290 yys = YYENLARGE(yys, int); 1291 yyv = YYENLARGE(yyv, YYSTYPE); 1292 if (yys == 0 || yyv == 0) 1293 yynewmax = 0; /* failed */ 1294 } 1295 #endif 1296 if (yynewmax <= yymaxdepth) /* tables not expanded */ 1297 { 1298 yyerror( "yacc stack overflow" ); 1299 YYABORT; 1300 } 1301 yymaxdepth = yynewmax; 1302 1303 yy_ps = yys + yyps_index; 1304 yy_pv = yyv + yypv_index; 1305 yypvt = yyv + yypvt_index; 1306 } 1307 *yy_ps = yy_state; 1308 *++yy_pv = yyval; 1309 1310 /* 1311 ** we have a new state - find out what to do 1312 */ 1313 yy_newstate: 1314 if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) 1315 goto yydefault; /* simple state */ 1316 #if YYDEBUG 1317 /* 1318 ** if debugging, need to mark whether new token grabbed 1319 */ 1320 yytmp = yychar < 0; 1321 #endif 1322 if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) 1323 yychar = 0; /* reached EOF */ 1324 #if YYDEBUG 1325 if ( yydebug && yytmp ) 1326 { 1327 register int yy_i; 1328 1329 printf( "Received token " ); 1330 if ( yychar == 0 ) 1331 printf( "end-of-file\n" ); 1332 else if ( yychar < 0 ) 1333 printf( "-none-\n" ); 1334 else 1335 { 1336 for ( yy_i = 0; yytoks[yy_i].t_val >= 0; 1337 yy_i++ ) 1338 { 1339 if ( yytoks[yy_i].t_val == yychar ) 1340 break; 1341 } 1342 printf( "%s\n", yytoks[yy_i].t_name ); 1343 } 1344 } 1345 #endif /* YYDEBUG */ 1346 if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) 1347 goto yydefault; 1348 if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ 1349 { 1350 yychar = -1; 1351 yyval = yylval; 1352 yy_state = yy_n; 1353 if ( yyerrflag > 0 ) 1354 yyerrflag--; 1355 goto yy_stack; 1356 } 1357 1358 yydefault: 1359 if ( ( yy_n = yydef[ yy_state ] ) == -2 ) 1360 { 1361 #if YYDEBUG 1362 yytmp = yychar < 0; 1363 #endif 1364 if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) 1365 yychar = 0; /* reached EOF */ 1366 #if YYDEBUG 1367 if ( yydebug && yytmp ) 1368 { 1369 register int yy_i; 1370 1371 printf( "Received token " ); 1372 if ( yychar == 0 ) 1373 printf( "end-of-file\n" ); 1374 else if ( yychar < 0 ) 1375 printf( "-none-\n" ); 1376 else 1377 { 1378 for ( yy_i = 0; 1379 yytoks[yy_i].t_val >= 0; 1380 yy_i++ ) 1381 { 1382 if ( yytoks[yy_i].t_val 1383 == yychar ) 1384 { 1385 break; 1386 } 1387 } 1388 printf( "%s\n", yytoks[yy_i].t_name ); 1389 } 1390 } 1391 #endif /* YYDEBUG */ 1392 /* 1393 ** look through exception table 1394 */ 1395 { 1396 register YYCONST int *yyxi = yyexca; 1397 1398 while ( ( *yyxi != -1 ) || 1399 ( yyxi[1] != yy_state ) ) 1400 { 1401 yyxi += 2; 1402 } 1403 while ( ( *(yyxi += 2) >= 0 ) && 1404 ( *yyxi != yychar ) ) 1405 ; 1406 if ( ( yy_n = yyxi[1] ) < 0 ) 1407 YYACCEPT; 1408 } 1409 } 1410 1411 /* 1412 ** check for syntax error 1413 */ 1414 if ( yy_n == 0 ) /* have an error */ 1415 { 1416 /* no worry about speed here! */ 1417 switch ( yyerrflag ) 1418 { 1419 case 0: /* new error */ 1420 yyerror( "syntax error" ); 1421 goto skip_init; 1422 yyerrlab: 1423 /* 1424 ** get globals into registers. 1425 ** we have a user generated syntax type error 1426 */ 1427 yy_pv = yypv; 1428 yy_ps = yyps; 1429 yy_state = yystate; 1430 skip_init: 1431 yynerrs++; 1432 /* FALLTHRU */ 1433 case 1: 1434 case 2: /* incompletely recovered error */ 1435 /* try again... */ 1436 yyerrflag = 3; 1437 /* 1438 ** find state where "error" is a legal 1439 ** shift action 1440 */ 1441 while ( yy_ps >= yys ) 1442 { 1443 yy_n = yypact[ *yy_ps ] + YYERRCODE; 1444 if ( yy_n >= 0 && yy_n < YYLAST && 1445 yychk[yyact[yy_n]] == YYERRCODE) { 1446 /* 1447 ** simulate shift of "error" 1448 */ 1449 yy_state = yyact[ yy_n ]; 1450 goto yy_stack; 1451 } 1452 /* 1453 ** current state has no shift on 1454 ** "error", pop stack 1455 */ 1456 #if YYDEBUG 1457 # define _POP_ "Error recovery pops state %d, uncovers state %d\n" 1458 if ( yydebug ) 1459 printf( _POP_, *yy_ps, 1460 yy_ps[-1] ); 1461 # undef _POP_ 1462 #endif 1463 yy_ps--; 1464 yy_pv--; 1465 } 1466 /* 1467 ** there is no state on stack with "error" as 1468 ** a valid shift. give up. 1469 */ 1470 YYABORT; 1471 case 3: /* no shift yet; eat a token */ 1472 #if YYDEBUG 1473 /* 1474 ** if debugging, look up token in list of 1475 ** pairs. 0 and negative shouldn't occur, 1476 ** but since timing doesn't matter when 1477 ** debugging, it doesn't hurt to leave the 1478 ** tests here. 1479 */ 1480 if ( yydebug ) 1481 { 1482 register int yy_i; 1483 1484 printf( "Error recovery discards " ); 1485 if ( yychar == 0 ) 1486 printf( "token end-of-file\n" ); 1487 else if ( yychar < 0 ) 1488 printf( "token -none-\n" ); 1489 else 1490 { 1491 for ( yy_i = 0; 1492 yytoks[yy_i].t_val >= 0; 1493 yy_i++ ) 1494 { 1495 if ( yytoks[yy_i].t_val 1496 == yychar ) 1497 { 1498 break; 1499 } 1500 } 1501 printf( "token %s\n", 1502 yytoks[yy_i].t_name ); 1503 } 1504 } 1505 #endif /* YYDEBUG */ 1506 if ( yychar == 0 ) /* reached EOF. quit */ 1507 YYABORT; 1508 yychar = -1; 1509 goto yy_newstate; 1510 } 1511 }/* end if ( yy_n == 0 ) */ 1512 /* 1513 ** reduction by production yy_n 1514 ** put stack tops, etc. so things right after switch 1515 */ 1516 #if YYDEBUG 1517 /* 1518 ** if debugging, print the string that is the user's 1519 ** specification of the reduction which is just about 1520 ** to be done. 1521 */ 1522 if ( yydebug ) 1523 printf( "Reduce by (%d) \"%s\"\n", 1524 yy_n, yyreds[ yy_n ] ); 1525 #endif 1526 yytmp = yy_n; /* value to switch over */ 1527 yypvt = yy_pv; /* $vars top of value stack */ 1528 /* 1529 ** Look in goto table for next state 1530 ** Sorry about using yy_state here as temporary 1531 ** register variable, but why not, if it works... 1532 ** If yyr2[ yy_n ] doesn't have the low order bit 1533 ** set, then there is no action to be done for 1534 ** this reduction. So, no saving & unsaving of 1535 ** registers done. The only difference between the 1536 ** code just after the if and the body of the if is 1537 ** the goto yy_stack in the body. This way the test 1538 ** can be made before the choice of what to do is needed. 1539 */ 1540 { 1541 /* length of production doubled with extra bit */ 1542 register int yy_len = yyr2[ yy_n ]; 1543 1544 if ( !( yy_len & 01 ) ) 1545 { 1546 yy_len >>= 1; 1547 yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ 1548 yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + 1549 *( yy_ps -= yy_len ) + 1; 1550 if ( yy_state >= YYLAST || 1551 yychk[ yy_state = 1552 yyact[ yy_state ] ] != -yy_n ) 1553 { 1554 yy_state = yyact[ yypgo[ yy_n ] ]; 1555 } 1556 goto yy_stack; 1557 } 1558 yy_len >>= 1; 1559 yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ 1560 yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + 1561 *( yy_ps -= yy_len ) + 1; 1562 if ( yy_state >= YYLAST || 1563 yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) 1564 { 1565 yy_state = yyact[ yypgo[ yy_n ] ]; 1566 } 1567 } 1568 /* save until reenter driver code */ 1569 yystate = yy_state; 1570 yyps = yy_ps; 1571 yypv = yy_pv; 1572 } 1573 /* 1574 ** code supplied by user is placed in this switch 1575 */ 1576 switch( yytmp ) 1577 { 1578 1579 case 3: 1580 # line 127 "getdate.y" 1581 { 1582 yyHaveTime++; 1583 } break; 1584 case 4: 1585 # line 130 "getdate.y" 1586 { 1587 yyHaveZone++; 1588 } break; 1589 case 5: 1590 # line 133 "getdate.y" 1591 { 1592 yyHaveDate++; 1593 } break; 1594 case 6: 1595 # line 136 "getdate.y" 1596 { 1597 yyHaveDay++; 1598 } break; 1599 case 7: 1600 # line 139 "getdate.y" 1601 { 1602 yyHaveRel++; 1603 } break; 1604 case 9: 1605 # line 145 "getdate.y" 1606 { 1607 yyHour = yypvt[-1].Number; 1608 yyMinutes = 0; 1609 yySeconds = 0; 1610 yyMeridian = yypvt[-0].Meridian; 1611 } break; 1612 case 10: 1613 # line 151 "getdate.y" 1614 { 1615 yyHour = yypvt[-3].Number; 1616 yyMinutes = yypvt[-1].Number; 1617 yySeconds = 0; 1618 yyMeridian = yypvt[-0].Meridian; 1619 } break; 1620 case 11: 1621 # line 157 "getdate.y" 1622 { 1623 yyHour = yypvt[-3].Number; 1624 yyMinutes = yypvt[-1].Number; 1625 yyMeridian = MER24; 1626 yyDSTmode = DSToff; 1627 yyTimezone = - (yypvt[-0].Number % 100 + (yypvt[-0].Number / 100) * 60); 1628 } break; 1629 case 12: 1630 # line 164 "getdate.y" 1631 { 1632 yyHour = yypvt[-5].Number; 1633 yyMinutes = yypvt[-3].Number; 1634 yySeconds = yypvt[-1].Number; 1635 yyMeridian = yypvt[-0].Meridian; 1636 } break; 1637 case 13: 1638 # line 170 "getdate.y" 1639 { 1640 yyHour = yypvt[-5].Number; 1641 yyMinutes = yypvt[-3].Number; 1642 yySeconds = yypvt[-1].Number; 1643 yyMeridian = MER24; 1644 yyDSTmode = DSToff; 1645 yyTimezone = - (yypvt[-0].Number % 100 + (yypvt[-0].Number / 100) * 60); 1646 } break; 1647 case 14: 1648 # line 180 "getdate.y" 1649 { 1650 yyTimezone = yypvt[-0].Number; 1651 yyDSTmode = DSToff; 1652 } break; 1653 case 15: 1654 # line 184 "getdate.y" 1655 { 1656 yyTimezone = yypvt[-0].Number; 1657 yyDSTmode = DSTon; 1658 } break; 1659 case 16: 1660 # line 190 "getdate.y" 1661 { 1662 yyDayOrdinal = 1; 1663 yyDayNumber = yypvt[-0].Number; 1664 } break; 1665 case 17: 1666 # line 194 "getdate.y" 1667 { 1668 yyDayOrdinal = 1; 1669 yyDayNumber = yypvt[-1].Number; 1670 } break; 1671 case 18: 1672 # line 198 "getdate.y" 1673 { 1674 yyDayOrdinal = yypvt[-1].Number; 1675 yyDayNumber = yypvt[-0].Number; 1676 } break; 1677 case 19: 1678 # line 204 "getdate.y" 1679 { 1680 yyMonth = yypvt[-2].Number; 1681 yyDay = yypvt[-0].Number; 1682 } break; 1683 case 20: 1684 # line 208 "getdate.y" 1685 { 1686 yyMonth = yypvt[-4].Number; 1687 yyDay = yypvt[-2].Number; 1688 yyYear = yypvt[-0].Number; 1689 } break; 1690 case 21: 1691 # line 213 "getdate.y" 1692 { 1693 yyMonth = yypvt[-1].Number; 1694 yyDay = yypvt[-0].Number; 1695 } break; 1696 case 22: 1697 # line 217 "getdate.y" 1698 { 1699 yyMonth = yypvt[-3].Number; 1700 yyDay = yypvt[-2].Number; 1701 yyYear = yypvt[-0].Number; 1702 } break; 1703 case 23: 1704 # line 222 "getdate.y" 1705 { 1706 yyMonth = yypvt[-0].Number; 1707 yyDay = yypvt[-1].Number; 1708 } break; 1709 case 24: 1710 # line 226 "getdate.y" 1711 { 1712 yyMonth = yypvt[-1].Number; 1713 yyDay = yypvt[-2].Number; 1714 yyYear = yypvt[-0].Number; 1715 } break; 1716 case 25: 1717 # line 233 "getdate.y" 1718 { 1719 yyRelSeconds = -yyRelSeconds; 1720 yyRelMonth = -yyRelMonth; 1721 } break; 1722 case 27: 1723 # line 240 "getdate.y" 1724 { 1725 yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number * 60L; 1726 } break; 1727 case 28: 1728 # line 243 "getdate.y" 1729 { 1730 yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number * 60L; 1731 } break; 1732 case 29: 1733 # line 246 "getdate.y" 1734 { 1735 yyRelSeconds += yypvt[-0].Number * 60L; 1736 } break; 1737 case 30: 1738 # line 249 "getdate.y" 1739 { 1740 yyRelSeconds += yypvt[-1].Number; 1741 } break; 1742 case 31: 1743 # line 252 "getdate.y" 1744 { 1745 yyRelSeconds += yypvt[-1].Number; 1746 } break; 1747 case 32: 1748 # line 255 "getdate.y" 1749 { 1750 yyRelSeconds++; 1751 } break; 1752 case 33: 1753 # line 258 "getdate.y" 1754 { 1755 yyRelMonth += yypvt[-1].Number * yypvt[-0].Number; 1756 } break; 1757 case 34: 1758 # line 261 "getdate.y" 1759 { 1760 yyRelMonth += yypvt[-1].Number * yypvt[-0].Number; 1761 } break; 1762 case 35: 1763 # line 264 "getdate.y" 1764 { 1765 yyRelMonth += yypvt[-0].Number; 1766 } break; 1767 case 36: 1768 # line 269 "getdate.y" 1769 { 1770 if (yyHaveTime && yyHaveDate && !yyHaveRel) 1771 yyYear = yypvt[-0].Number; 1772 else { 1773 yyHaveTime++; 1774 if (yypvt[-0].Number < 100) { 1775 yyHour = yypvt[-0].Number; 1776 yyMinutes = 0; 1777 } 1778 else { 1779 yyHour = yypvt[-0].Number / 100; 1780 yyMinutes = yypvt[-0].Number % 100; 1781 } 1782 yySeconds = 0; 1783 yyMeridian = MER24; 1784 } 1785 } break; 1786 case 37: 1787 # line 288 "getdate.y" 1788 { 1789 yyval.Meridian = MER24; 1790 } break; 1791 case 38: 1792 # line 291 "getdate.y" 1793 { 1794 yyval.Meridian = yypvt[-0].Meridian; 1795 } break; 1796 # line 556 "/usr/share/lib/ccs/yaccpar" 1797 } 1798 goto yystack; /* reset registers in driver code */ 1799 } 1800 1801