| 584 | } |
| 585 | |
| 586 | static const char * getrule(const char * strp, struct rule * const rulep) { |
| 587 | if (*strp == 'J') { |
| 588 | /* |
| 589 | ** Julian day. |
| 590 | */ |
| 591 | rulep->r_type = JULIAN_DAY; |
| 592 | ++strp; |
| 593 | strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); |
| 594 | } else if (*strp == 'M') { |
| 595 | /* |
| 596 | ** Month, week, day. |
| 597 | */ |
| 598 | rulep->r_type = MONTH_NTH_DAY_OF_WEEK; |
| 599 | ++strp; |
| 600 | strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); |
| 601 | if (strp == NULL) |
| 602 | return NULL; |
| 603 | if (*strp++ != '.') |
| 604 | return NULL; |
| 605 | strp = getnum(strp, &rulep->r_week, 1, 5); |
| 606 | if (strp == NULL) |
| 607 | return NULL; |
| 608 | if (*strp++ != '.') |
| 609 | return NULL; |
| 610 | strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); |
| 611 | } else if (is_digit(*strp)) { |
| 612 | /* |
| 613 | ** Day of year. |
| 614 | */ |
| 615 | rulep->r_type = DAY_OF_YEAR; |
| 616 | strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); |
| 617 | } else return NULL; /* invalid format */ |
| 618 | if (strp == NULL) |
| 619 | return NULL; |
| 620 | if (*strp == '/') { |
| 621 | /* |
| 622 | ** Time specified. |
| 623 | */ |
| 624 | ++strp; |
| 625 | strp = getsecs(strp, &rulep->r_time); |
| 626 | } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ |
| 627 | return strp; |
| 628 | } |
| 629 | |
| 630 | // this routine modified / simplified / reduced in 2010 |
| 631 | static int tzload(const char * name, struct state * const sp, const int doextend) { |