diff --git a/.cvsignore b/.cvsignore index 9368ec8..36815c3 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -at-3.1.8.tar.bz2 +at_3.1.8-11.tar.gz diff --git a/at-3.1.8-11-lexer-parser.diff b/at-3.1.8-11-lexer-parser.diff new file mode 100644 index 0000000..5608887 --- /dev/null +++ b/at-3.1.8-11-lexer-parser.diff @@ -0,0 +1,894 @@ +diff -u at-3.1.8-orig/parsetime.l at-3.1.8/parsetime.l +--- at-3.1.8-orig/parsetime.l Sun Sep 28 13:26:30 1997 ++++ at-3.1.8/parsetime.l Sat Jan 26 14:18:10 2002 +@@ -32,7 +32,6 @@ + } while(0) + %} + +-WORD [a-z][a-z0-9]+ + %% + + now { COPY_TOK ; return NOW; } +@@ -57,6 +56,7 @@ + day(s)? { COPY_TOK ; return DAY; } + week(s)? { COPY_TOK ; return WEEK; } + month(s)? { COPY_TOK ; return MONTH; } ++year(s)? { COPY_TOK ; return YEAR; } + jan(uary)? { COPY_TOK ; return JAN; } + feb(ruary)? { COPY_TOK ; return FEB; } + mar(ch)? { COPY_TOK ; return MAR; } +@@ -69,9 +69,16 @@ + oct(ober)? { COPY_TOK ; return OCT; } + nov(ember)? { COPY_TOK ; return NOV; } + dec(ember)? { COPY_TOK ; return DEC; } ++utc { COPY_TOK ; return UTC; } ++[0-9]{1} { COPY_TOK ; COPY_VAL; return INT1DIGIT; } ++[0-9]{2} { COPY_TOK ; COPY_VAL; return INT2DIGIT; } ++[0-9]{4} { COPY_TOK ; COPY_VAL; return INT4DIGIT; } ++[0-9]{5,8} { COPY_TOK ; COPY_VAL; return INT5_8DIGIT; } + [0-9]+ { COPY_TOK ; COPY_VAL; return INT; } ++[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{2}([0-9]{2})? { COPY_TOK ; COPY_VAL; return DOTTEDDATE; } ++[0-9]{2}([0-9]{2})?-[0-9]{1,2}-[0-9]{1,2} { COPY_TOK ; COPY_VAL; return HYPHENDATE; } ++[012]?[0-9][:'h,.][0-9]{2} { COPY_TOK ; COPY_VAL; return HOURMIN; } + [ \t\n] ; +-{WORD} { COPY_TOK ; COPY_VAL; return WORD; } + . { COPY_TOK ; return yytext[0]; } + + %% +diff -u at-3.1.8-orig/parsetime.y at-3.1.8/parsetime.y +--- at-3.1.8-orig/parsetime.y Thu Jan 17 22:15:27 2002 ++++ at-3.1.8/parsetime.y Sat Jan 26 14:25:25 2002 +@@ -22,6 +22,13 @@ + int intval; + } + ++%token DOTTEDDATE ++%token HYPHENDATE ++%token HOURMIN ++%token INT1DIGIT ++%token INT2DIGIT ++%token INT4DIGIT ++%token INT5_8DIGIT + %token INT + %token NOW + %token AM PM +@@ -31,48 +38,61 @@ + %token NEXT + %token MINUTE HOUR DAY WEEK MONTH YEAR + %token JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC +-%token WORD ++%token UTC + +-%type inc_period +-%type inc_number ++%type concatenated_date ++%type hr24clock_hr_min ++%type int1_2digit ++%type int2_or_4digit ++%type integer ++%type inc_dec_period ++%type inc_dec_number + %type day_of_week + + %start timespec + %% +-timespec : date ++timespec : spec_base ++ | spec_base inc_or_dec ++ { ++ time_only = 0; ++ ++ } ++ ; ++ ++spec_base : date + | time + { + time_only = 1; + } + | time date +- | time_or_not inc_or_dec +- | time_or_not date inc_or_dec +- | nowspec +- ; ++ | NOW ++ ; + +-nowspec : now +- | now inc_or_dec ++time : time_base ++ | time_base timezone_name + ; + +-now : NOW +- | TOMORROW +- { +- add_date(1, DAY); +- } +- ; +- +-time_or_not : time +- | ++time_base : hr24clock_hr_min ++ { ++ exectm.tm_min = -1; ++ exectm.tm_hour = -1; ++ sscanf($1, "%2d %2d", &exectm.tm_hour, ++ &exectm.tm_min); ++ free($1); + +-time : hr24clock_hr_min +- | hr24clock_hr_min timezone_name +- | hr24clock_hour time_sep minute +- | hr24clock_hour time_sep minute timezone_name +- | hr24clock_hour am_pm +- | hr24clock_hour am_pm timezone_name +- | hr24clock_hour time_sep minute am_pm +- | hr24clock_hour time_sep minute am_pm timezone_name +- | NOON ++ if (exectm.tm_min > 60 || exectm.tm_min < 0) { ++ yyerror("Problem in minutes specification"); ++ YYERROR; ++ } ++ if (exectm.tm_hour > 24 || exectm.tm_hour < 0) { ++ yyerror("Problem in hours specification"); ++ YYERROR; ++ } ++ } ++ | time_hour am_pm ++ | time_hour_min ++ | time_hour_min am_pm ++ | NOON + { + exectm.tm_hour = 12; + exectm.tm_min = 0; +@@ -81,128 +101,23 @@ + { + exectm.tm_hour = 0; + exectm.tm_min = 0; +- add_date(1, DAY); + } + | TEATIME + { + exectm.tm_hour = 16; + exectm.tm_min = 0; + } +- ; +- +-date : month_name day_number +- | month_name day_number year_number +- | month_name day_number ',' year_number +- | day_of_week +- { +- add_date ((6 + $1 - exectm.tm_wday) %7 + 1, DAY); +- } +- | TODAY +- | TOMORROW +- { +- add_date(1, DAY); +- } +- | year_number '-' month_number '-' day_number +- | day_number '.' month_number '.' year_number +- | day_number '.' month_number +- | day_number month_name +- | day_number month_name year_number +- | month_number '/' day_number '/' year_number +- ; +- +-inc_or_dec : increment +- | decrement +- +-increment : '+' inc_number inc_period +- { +- add_date($2, $3); +- } +- | NEXT inc_period +- { +- add_date(1, $2); +- } +- | NEXT day_of_week +- { +- add_date ((6 + $2 - exectm.tm_wday) %7 +1, DAY); +- } +- ; +- +-decrement : '-' inc_number inc_period +- { +- add_date(-$2, $3); +- } + ; + +-inc_period : MINUTE { $$ = MINUTE ; } +- | HOUR { $$ = HOUR ; } +- | DAY { $$ = DAY ; } +- | WEEK { $$ = WEEK ; } +- | MONTH { $$ = MONTH ; } +- | YEAR { $$ = YEAR ; } +- ; ++hr24clock_hr_min: INT4DIGIT ++ ; + +-hr24clock_hr_min: INT ++time_hour : int1_2digit + { +- if (strlen($1) == 4) { +- exectm.tm_min = -1; +- exectm.tm_hour = -1; +- sscanf($1, "%2d %2d", &exectm.tm_hour, +- &exectm.tm_min); +- } else if (strlen($1) >= 5 && strlen($1) <= 8) { +- /* Ok, this is a kluge. I hate design errors... -Joey */ +- char shallot[5]; +- char *onion; +- +- onion=$1; +- memset (shallot, 0, sizeof (shallot)); +- if (strlen($1) == 5 || strlen($1) == 7) { +- strncpy (shallot,onion,1); +- onion++; +- } else { +- strncpy (shallot,onion,2); +- onion+=2; +- } +- sscanf(shallot, "%d", &exectm.tm_mon); +- +- if (exectm.tm_mon < 1 || exectm.tm_mon > 12) { +- yyerror("Error in month number"); +- YYERROR; +- } +- exectm.tm_mon--; +- +- memset (shallot, 0, sizeof (shallot)); +- strncpy (shallot,onion,2); +- sscanf(shallot, "%d", &exectm.tm_mday); +- if (exectm.tm_mday < 0 || exectm.tm_mday > 31) +- { +- yyerror("Error in day of month"); +- YYERROR; +- } +- +- onion+=2; +- memset (shallot, 0, sizeof (shallot)); +- strncpy (shallot,onion,4); +- if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) { +- yyerror("Error in year"); +- YYERROR; +- } +- if (exectm.tm_year < 70) { +- exectm.tm_year += 100; +- } +- else if (exectm.tm_year > 1900) { +- exectm.tm_year -= 1900; +- } +- } +- else { +- sscanf($1, "%d", &exectm.tm_hour); +- exectm.tm_min = 0; +- } ++ sscanf($1, "%d", &exectm.tm_hour); ++ exectm.tm_min = 0; + free($1); + +- if (exectm.tm_min > 60 || exectm.tm_min < 0) { +- yyerror("Problem in minutes specification"); +- YYERROR; +- } + if (exectm.tm_hour > 24 || exectm.tm_hour < 0) { + yyerror("Problem in hours specification"); + YYERROR; +@@ -210,29 +125,22 @@ + } + ; + +-timezone_name : WORD ++time_hour_min : HOURMIN + { +- if (strcasecmp($1,"utc") == 0) { +- isgmt = 1; +- } +- else { +- yyerror("Only UTC timezone is supported"); +- YYERROR; +- } ++ exectm.tm_min = -1; ++ exectm.tm_hour = -1; ++ sscanf($1, "%d %*c %d", &exectm.tm_hour, ++ &exectm.tm_min); + free($1); +- } +- ; +- +-hr24clock_hour : hr24clock_hr_min +- ; + +-minute : INT +- { +- if (sscanf($1, "%d", &exectm.tm_min) != 1) { +- yyerror("Error in minute"); ++ if (exectm.tm_min > 60 || exectm.tm_min < 0) { ++ yyerror("Problem in minutes specification"); ++ YYERROR; ++ } ++ if (exectm.tm_hour > 24 || exectm.tm_hour < 0) { ++ yyerror("Problem in hours specification"); + YYERROR; + } +- free($1); + } + ; + +@@ -258,6 +166,171 @@ + } + ; + ++timezone_name : UTC ++ { ++ isgmt = 1; ++ } ++ ; ++ ++date : month_name day_number ++ | month_name day_number year_number ++ | month_name day_number ',' year_number ++ | day_of_week ++ { ++ add_date ((6 + $1 - exectm.tm_wday) %7 + 1, DAY); ++ } ++ | TODAY ++ | TOMORROW ++ { ++ add_date(1, DAY); ++ } ++ | HYPHENDATE ++ { ++ int ynum = -1; ++ int mnum = -1; ++ int dnum = -1; ++ ++ if (sscanf($1, "%d %*c %d %*c %d", &ynum, &mnum, &dnum) != 3) { ++ yyerror("Error in hypenated date"); ++ YYERROR; ++ } ++ ++ if (mnum < 1 || mnum > 12) { ++ yyerror("Error in month number"); ++ YYERROR; ++ } ++ exectm.tm_mon = mnum -1; ++ ++ if (ynum < 70) { ++ ynum += 100; ++ } ++ else if (ynum > 1900) { ++ ynum -= 1900; ++ } ++ exectm.tm_year = ynum ; ++ ++ if ( dnum < 0 ++ || ((mnum == 1 || mnum == 3 || mnum == 5 || ++ mnum == 7 || mnum == 8 || mnum == 10 || ++ mnum == 12) && dnum > 31) ++ || ((mnum == 4 || mnum == 6 || mnum == 9 || ++ mnum == 11) && dnum > 30) ++ || (mnum == 2 && dnum > 29 && __isleap(ynum+1900)) ++ || (mnum == 2 && dnum > 28 && !__isleap(ynum+1900)) ++ ) ++ { ++ yyerror("Error in day of month"); ++ YYERROR; ++ } ++ exectm.tm_mday = dnum; ++ ++ free($1); ++ } ++ | DOTTEDDATE ++ { ++ int ynum = -1; ++ int mnum = -1; ++ int dnum = -1; ++ ++ if (sscanf($1, "%d %*c %d %*c %d", &dnum, &mnum, &ynum) != 3) { ++ yyerror("Error in dotted date"); ++ YYERROR; ++ } ++ ++ if (mnum < 1 || mnum > 12) { ++ yyerror("Error in month number"); ++ YYERROR; ++ } ++ exectm.tm_mon = mnum -1; ++ ++ if (ynum < 70) { ++ ynum += 100; ++ } ++ else if (ynum > 1900) { ++ ynum -= 1900; ++ } ++ exectm.tm_year = ynum ; ++ ++ if ( dnum < 0 ++ || ((mnum == 1 || mnum == 3 || mnum == 5 || ++ mnum == 7 || mnum == 8 || mnum == 10 || ++ mnum == 12) && dnum > 31) ++ || ((mnum == 4 || mnum == 6 || mnum == 9 || ++ mnum == 11) && dnum > 30) ++ || (mnum == 2 && dnum > 29 && __isleap(ynum+1900)) ++ || (mnum == 2 && dnum > 28 && !__isleap(ynum+1900)) ++ ) ++ { ++ yyerror("Error in day of month"); ++ YYERROR; ++ } ++ exectm.tm_mday = dnum; ++ ++ free($1); ++ } ++ | day_number month_name ++ | day_number month_name year_number ++ | month_number '/' day_number '/' year_number ++ | concatenated_date ++ { ++ /* Ok, this is a kluge. I hate design errors... -Joey */ ++ char shallot[5]; ++ char *onion; ++ ++ onion=$1; ++ memset (shallot, 0, sizeof (shallot)); ++ if (strlen($1) == 5 || strlen($1) == 7) { ++ strncpy (shallot,onion,1); ++ onion++; ++ } else { ++ strncpy (shallot,onion,2); ++ onion+=2; ++ } ++ sscanf(shallot, "%d", &exectm.tm_mon); ++ ++ if (exectm.tm_mon < 1 || exectm.tm_mon > 12) { ++ yyerror("Error in month number"); ++ YYERROR; ++ } ++ exectm.tm_mon--; ++ ++ memset (shallot, 0, sizeof (shallot)); ++ strncpy (shallot,onion,2); ++ sscanf(shallot, "%d", &exectm.tm_mday); ++ if (exectm.tm_mday < 0 || exectm.tm_mday > 31) ++ { ++ yyerror("Error in day of month"); ++ YYERROR; ++ } ++ ++ onion+=2; ++ memset (shallot, 0, sizeof (shallot)); ++ strncpy (shallot,onion,4); ++ if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) { ++ yyerror("Error in year"); ++ YYERROR; ++ } ++ if (exectm.tm_year < 70) { ++ exectm.tm_year += 100; ++ } ++ else if (exectm.tm_year > 1900) { ++ exectm.tm_year -= 1900; ++ } ++ ++ free ($1); ++ } ++ | NEXT inc_dec_period ++ { ++ add_date(1, $2); ++ } ++ | NEXT day_of_week ++ { ++ add_date ((6 + $2 - exectm.tm_wday) %7 +1, DAY); ++ } ++ ; ++ ++concatenated_date: INT5_8DIGIT ++ ; + + month_name : JAN { exectm.tm_mon = 0; } + | FEB { exectm.tm_mon = 1; } +@@ -273,7 +346,7 @@ + | DEC { exectm.tm_mon =11; } + ; + +-month_number : INT ++month_number : int1_2digit + { + { + int mnum = -1; +@@ -287,7 +360,9 @@ + free($1); + } + } +-day_number : INT ++ ; ++ ++day_number : int1_2digit + { + exectm.tm_mday = -1; + sscanf($1, "%d", &exectm.tm_mday); +@@ -300,7 +375,7 @@ + } + ; + +-year_number : INT ++year_number : int2_or_4digit + { + { + int ynum; +@@ -322,7 +397,6 @@ + } + ; + +- + day_of_week : SUN { $$ = 0; } + | MON { $$ = 1; } + | TUE { $$ = 2; } +@@ -332,7 +406,23 @@ + | SAT { $$ = 6; } + ; + +-inc_number : INT ++inc_or_dec : increment ++ | decrement ++ ; ++ ++increment : '+' inc_dec_number inc_dec_period ++ { ++ add_date($2, $3); ++ } ++ ; ++ ++decrement : '-' inc_dec_number inc_dec_period ++ { ++ add_date(-$2, $3); ++ } ++ ; ++ ++inc_dec_number : integer + { + if (sscanf($1, "%d", &$$) != 1) { + yyerror("Unknown increment"); +@@ -342,11 +432,27 @@ + } + ; + +-time_sep : ':' +- | '\'' +- | '.' +- | 'h' +- | ',' ++inc_dec_period : MINUTE { $$ = MINUTE ; } ++ | HOUR { $$ = HOUR ; } ++ | DAY { $$ = DAY ; } ++ | WEEK { $$ = WEEK ; } ++ | MONTH { $$ = MONTH ; } ++ | YEAR { $$ = YEAR ; } ++ ; ++ ++int1_2digit : INT1DIGIT ++ | INT2DIGIT ++ ; ++ ++int2_or_4digit : INT2DIGIT ++ | INT4DIGIT ++ ; ++ ++integer : INT ++ | INT1DIGIT ++ | INT2DIGIT ++ | INT4DIGIT ++ | INT5_8DIGIT + ; + + %% +@@ -370,10 +476,7 @@ + if (exectime == (time_t)-1) + return 0; + if (isgmt) { +- exectime += timezone; +- if (daylight) { +- exectime -= 3600; +- } ++ exectime -= timezone; + } + if (time_only && (currtime > exectime)) { + exectime += 24*3600; +@@ -386,39 +489,29 @@ + } + + #ifdef TEST_PARSER +-/* +- +-Here are some lines to test: +- +-./parsetest 7AM Mar 24 2000 +-./parsetest 7AM Mar 24 00 +-./parsetest 7AM 032400 +-./parsetest 7AM 03/24/00 +-./parsetest 7AM 24.03.00 +-./parsetest 7AM Mar 24 +- +-./parsetest 03242000 +-./parsetest noon 03242000 +-./parsetest 5:30 +-./parsetest 4pm + 3 days +-./parsetest 10am Jul 31 +- +- */ ++ + int + main(int argc, char **argv) + { ++ int retval = 1; + time_t res; + res = parsetime(argc-1, &argv[1]); ++ if (time_only) { ++ fprintf(stderr, "time_only = 1\n"); ++ } + if (res > 0) { + printf("%s",ctime(&res)); ++ retval = 0; + } + else { + printf("Ooops...\n"); ++ retval = 1; + } +- return 0; ++ return retval; + } + + #endif ++ + int yyerror(char *s) + { + if (last_token == NULL) +@@ -430,12 +523,36 @@ + void + add_seconds(struct tm *tm, long numsec) + { ++ struct tm basetm = *tm; + time_t timeval; ++ + timeval = mktime(tm); + if (timeval == (time_t)-1) + timeval = (time_t)0; + timeval += numsec; + *tm = *localtime(&timeval); ++ ++ /* ++ * Adjust +-1 hour when moving in or out of DST ++ */ ++ ++ if (daylight > 0) /* Only check if DST is used here */ ++ { ++ /* Set tm_isdst on &basetm and tm */ ++ (void) mktime(&basetm); ++ (void) mktime(tm); ++ ++ if (basetm.tm_isdst > 0 && tm->tm_isdst < 1) ++ { /* DST to no DST */ ++ timeval += 3600l; ++ *tm = *localtime(&timeval); ++ } ++ else if (basetm.tm_isdst < 1 && tm->tm_isdst > 0) ++ { /* no DST to DST */ ++ timeval -= 3600l; ++ *tm = *localtime(&timeval); ++ } ++ } + } + + int +@@ -468,6 +585,10 @@ + } + exectm.tm_mon = newmonth % 12; + number += newmonth / 12 ; ++ ++ /* Recalculate tm_isdst so we don't get a +-1 hour creep */ ++ exectm.tm_isdst = -1; ++ (void) mktime(&exectm); + } + if (number == 0) { + break; +@@ -476,6 +597,9 @@ + + case YEAR: + exectm.tm_year += number; ++ /* Recalculate tm_isdst so we don't get a +-1 hour creep */ ++ exectm.tm_isdst = -1; ++ (void) mktime(&exectm); + break; + + default: +@@ -483,5 +607,6 @@ + fprintf(stderr,"Unexpected case %d\n", period); + abort(); + } ++ + return 0; + } +diff -u at-3.1.8-orig/timespec at-3.1.8/timespec +--- at-3.1.8-orig/timespec Wed Mar 12 12:11:05 1997 ++++ at-3.1.8/timespec Sat Jan 26 14:18:10 2002 +@@ -2,6 +2,13 @@ + * Abbreviated version of the yacc grammar used by at(1). + */ + ++%token DOTTEDDATE ++%token HYPHENDATE ++%token HOURMIN ++%token INT1DIGIT ++%token INT2DIGIT ++%token INT4DIGIT ++%token INT5_8DIGIT + %token INT + %token NOW + %token AM PM +@@ -11,100 +18,115 @@ + %token NEXT + %token MINUTE HOUR DAY WEEK MONTH YEAR + %token JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC +-%token WORD ++%token UTC + +-%type inc_period +-%type inc_number ++%type concatenated_date ++%type hr24clock_hr_min ++%type int1_2digit ++%type int2_or_4digit ++%type integer ++%type inc_dec_period ++%type inc_dec_number + %type day_of_week + + %start timespec + %% +-timespec : time +- | time date +- | time increment +- | time date increment +- | time decrement +- | time date decrement +- | nowspec +- ; +- +-nowspec : now +- | now increment +- | now decrement ++timespec : spec_base ++ | spec_base inc_or_dec + ; + +-now : NOW ++spec_base : date ++ | time ++ | time date ++ | NOW + ; + +-time : hr24clock_hr_min +- | hr24clock_hr_min timezone_name +- | hr24clock_hour time_sep minute +- | hr24clock_hour time_sep minute timezone_name +- | hr24clock_hour am_pm +- | hr24clock_hour am_pm timezone_name +- | hr24clock_hour time_sep minute am_pm +- | hr24clock_hour time_sep minute am_pm timezone_name +- | NOON ++time : time_base ++ | time_base timezone_name ++ ; ++ ++time_base : hr24clock_hr_min ++ | time_hour am_pm ++ | time_hour_min ++ | time_hour_min am_pm ++ | NOON + | MIDNIGHT + | TEATIME +- ; ++ ; ++ ++hr24clock_hr_min: INT4DIGIT ++ ; ++ ++time_hour : int1_2digit ++ ; ++ ++time_hour_min : HOURMIN ++ ; ++ ++am_pm : AM ++ | PM ++ ; ++ ++timezone_name : UTC ++ ; + + date : month_name day_number ++ | month_name day_number year_number + | month_name day_number ',' year_number + | day_of_week + | TODAY + | TOMORROW +- | year_number '-' month_number '-' day_number +- | day_number '.' month_number '.' year_number +- | day_number '.' month_number ++ | HYPHENDATE ++ | DOTTEDDATE + | day_number month_name + | day_number month_name year_number + | month_number '/' day_number '/' year_number +- ; +- +-increment : '+' inc_number inc_period +- | NEXT inc_period ++ | concatenated_date ++ | NEXT inc_dec_period + | NEXT day_of_week + ; + +-decrement : '-' inc_number inc_period ++concatenated_date: INT5_8DIGIT + ; + +-inc_period : MINUTE | HOUR | DAY | WEEK | MONTH | YEAR ++month_name : JAN | FEB | MAR | APR | MAY | JUN ++ | JUL | AUG | SEP | OCT | NOV | DEC + ; + +-hr24clock_hr_min: INT ++month_number : int1_2digit + ; + +-timezone_name : WORD ++day_number : int1_2digit + ; + +-hr24clock_hour : hr24clock_hr_min ++year_number : int2_or_4digit + ; + +-minute : INT ++day_of_week : SUN | MON | TUE | WED | THU | FRI | SAT + ; + +-am_pm : AM | PM ++inc_or_dec : increment | decrement + ; + +-month_name : JAN | FEB | MAR | APR | MAY | JUN | JUL +- | AUG | SEP | OCT | NOV | DEC +- ; ++increment : '+' inc_dec_number inc_dec_period ++ ; + +-month_number : INT ++decrement : '-' inc_dec_number inc_dec_period + ; +-day_number : INT ++ ++inc_dec_number : integer + ; + +-year_number : INT ++inc_dec_period : MINUTE | HOUR | DAY | WEEK | MONTH | YEAR + ; + +-day_of_week : SUN | MON | TUE | WED | THU | FRI | SAT ++int1_2digit : INT1DIGIT | INT2DIGIT + ; + +-inc_number : INT ++int2_or_4digit : INT2DIGIT | INT4DIGIT + ; + +-time_sep : ':' | '\'' | '.' | 'h' | ',' ++integer : INT | INT1DIGIT | INT2DIGIT | INT4DIGIT | INT5_8DIGIT + ; ++ ++%% diff --git a/at-3.1.8-man-timespec-path.patch b/at-3.1.8-man-timespec-path.patch new file mode 100644 index 0000000..4efefc4 --- /dev/null +++ b/at-3.1.8-man-timespec-path.patch @@ -0,0 +1,12 @@ +diff -u at-3.1.8/at.1.in~ at-3.1.8/at.1.in +--- at-3.1.8/at.1.in~ 2003-06-03 10:06:37.000000000 +0900 ++++ at-3.1.8/at.1.in 2003-06-03 10:06:37.000000000 +0900 +@@ -117,7 +117,7 @@ + .B at 1am tomorrow. + .PP + The exact definition of the time specification can be found in +-.IR @prefix@/share/doc/at/timespec . ++.IR @prefix@/share/doc/at-@VERSION@/timespec . + .PP + For both + .BR at " and " batch , diff --git a/at-3.1.8-test.patch b/at-3.1.8-test.patch index a95eaed..f5bc2b8 100644 --- a/at-3.1.8-test.patch +++ b/at-3.1.8-test.patch @@ -21,806 +21,3 @@ diff -u at-3.1.8/Makefile.in.orig at-3.1.8/Makefile.in .depend: $(CSRCS) gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend diff -u at-3.1.8/test.pl.orig at-3.1.8/test.pl ---- at-3.1.8/test.pl.orig Mon Feb 19 14:51:37 2001 -+++ at-3.1.8/test.pl Mon Feb 19 14:30:17 2001 -@@ -0,0 +1,800 @@ -+#!/usr/bin/perl -w -+# -+# test.pl - tests vailidity of lexer/parser for at(1) -+# -+# Copyright 2001 David D. Kilzer -+# -+# Licensed under the GNU Public License -+# -+# Environment variables: -+# TEST_VERBOSE -+# 0 - no verbosity -+# 1 - verbose output only on failed tests, and all stderr output -+# > 1 - verbose output on every test, and all stderr output -+# -+ -+use strict; -+ -+use constant SECOND => 1; # seconds per second -+use constant MINUTE => 60*SECOND; # seconds per minute -+use constant HOUR => 60*MINUTE; # seconds per hour -+use constant DAY => 24*HOUR; # seconds per day -+use constant WEEK => 7*DAY; # seconds per week -+ -+use vars qw($verbose); -+ -+use POSIX; # strftime -+use Time::Local; # timelocal() and timegm() -+ -+BEGIN { $| = 1; } # no output buffering -+ -+ -+# -+# Subroutines -+# -+sub is_dst (;$); # is time in DST? -+sub get_utc_offset (;$); # calculate hours offset from UTC -+ -+ -+# -+# Data structures containing test data -+# -+my @date_tests; # date strings -+my @time_tests; # time strings -+my @date_time_tests_time; # time + date strings (just times) -+my @date_time_tests_date; # time + date strings (just dates) -+my @inc_dec_tests; # increment and decrement strings -+my @misc_tests; # miscellaneous strings (mostly for DST) -+ -+my $num_tests; # number of tests -+my $show_stderr; # set to "2> /dev/null" if (! $verbose) -+my $utc_off; # timezone offset in minutes west of UTC -+ -+ -+# -+# Set variables before running tests -+# -+$verbose = $ENV{'TEST_VERBOSE'} || 0; -+ -+$show_stderr = ($verbose > 0 ? "" : "2> /dev/null"); -+ -+$utc_off = get_utc_offset(); -+ -+ -+# -+# Tests for dates only -+# These tests include both relative and specific dates. -+# They are not combined with any other tests. -+# -+# Format: "string", month, day, year, hour, minute, [offset] -+# -+@date_tests = -+( -+[ "dec 31", 12, 31, '$y', '$h', '$mi' ], -+[ "Dec 31", 12, 31, '$y', '$h', '$mi' ], -+[ "DEC 31", 12, 31, '$y', '$h', '$mi' ], -+[ "december 31", 12, 31, '$y', '$h', '$mi' ], -+[ "December 31", 12, 31, '$y', '$h', '$mi' ], -+[ "DECEMBER 31", 12, 31, '$y', '$h', '$mi' ], -+[ "Dec 31 10", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31 10", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31,10", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31, 10", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31,10", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31, 10", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31,2010", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31, 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31,2010", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31, 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "sun", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], -+[ "Sun", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], -+[ "SUN", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], -+[ "sunday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], -+[ "Sunday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], -+[ "SUNDAY", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], -+[ "Mon", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], -+[ "Monday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], -+[ "Tue", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 2 ? 7 : ((7 - $wd + 2) % 7)) * DAY)' ], -+[ "Tuesday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 2 ? 7 : ((7 - $wd + 2) % 7)) * DAY)' ], -+[ "Wed", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 3 ? 7 : ((7 - $wd + 3) % 7)) * DAY)' ], -+[ "Wednesday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 3 ? 7 : ((7 - $wd + 3) % 7)) * DAY)' ], -+[ "Thu", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 4 ? 7 : ((7 - $wd + 4) % 7)) * DAY)' ], -+[ "Thursday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 4 ? 7 : ((7 - $wd + 4) % 7)) * DAY)' ], -+[ "Fri", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 5 ? 7 : ((7 - $wd + 5) % 7)) * DAY)' ], -+[ "Friday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 5 ? 7 : ((7 - $wd + 5) % 7)) * DAY)' ], -+[ "Sat", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 6 ? 7 : ((7 - $wd + 6) % 7)) * DAY)' ], -+[ "Saturday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 6 ? 7 : ((7 - $wd + 6) % 7)) * DAY)' ], -+[ "now", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "Now", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "NOW", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "today", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "Today", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "TODAY", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], -+[ "Tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], -+[ "TOMORROW", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], -+[ "10-12-31", 12, 31, 2010, '$h', '$mi' ], -+[ "2010-12-31", 12, 31, 2010, '$h', '$mi' ], -+[ "31.12.10", 12, 31, 2010, '$h', '$mi' ], -+[ "31.12.2010", 12, 31, 2010, '$h', '$mi' ], -+[ "31 Dec", 12, 31, '$y', '$h', '$mi' ], -+[ "31 December", 12, 31, '$y', '$h', '$mi' ], -+[ "31 Dec 10", 12, 31, 2010, '$h', '$mi' ], -+[ "31 Dec 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "31 December 10", 12, 31, 2010, '$h', '$mi' ], -+[ "31 December 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "12/31/10", 12, 31, 2010, '$h', '$mi' ], -+[ "12/31/2010", 12, 31, 2010, '$h', '$mi' ], -+[ "13010", 01, 30, 2010, '$h', '$mi' ], -+[ "1302010", 01, 30, 2010, '$h', '$mi' ], -+[ "013010", 01, 30, 2010, '$h', '$mi' ], -+[ "01302010", 01, 30, 2010, '$h', '$mi' ], -+[ "123110", 12, 31, 2010, '$h', '$mi' ], -+[ "12312010", 12, 31, 2010, '$h', '$mi' ], -+[ "next minute", '$mo', '$d', '$y', '$h', '$mi', '1 * MINUTE' ], -+[ "next hour", '$mo', '$d', '$y', '$h', '$mi', '1 * HOUR' ], -+[ "next day", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], -+[ "next week", '$mo', '$d', '$y', '$h', '$mi', '1 * WEEK' ], -+[ "next month", '($mo == 12 ? 1 : $mo + 1)', '$d', '($mo == 12 ? $y + 1 : $y)', '$h', '$mi' ], -+[ "next year", '$mo', '$d', '$y + 1', '$h', '$mi' ], -+); -+ -+ -+# -+# Tests for times only -+# These tests include specific times and time aliases. -+# They are not combined with any other tests. -+# -+# Format: "string", month, day, year, hour, minute, [offset] -+# -+@time_tests = -+( -+[ "0800", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "2300", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8:00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08:00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "23:00", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8'00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08'00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "23'00", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8.00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08.00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "23.00", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8h00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08h00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "23h00", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8,00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08,00", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "23,00", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8:00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08:00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "11:00 pm", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8'00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08'00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "11'00 pm", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8.00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08.00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "11.00 pm", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8h00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08h00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "11h00 pm", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "8,00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "08,00 am", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], -+[ "11,00 pm", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], -+[ "0800 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "2300 utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8:00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08:00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "23:00 utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8'00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08'00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "23'00 utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8.00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08.00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "23.00 utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8h00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08h00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "23h00 utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8,00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08,00 utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "23,00 utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8:00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08:00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "11:00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8'00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08'00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "11'00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8.00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08.00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "11.00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8h00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08h00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "11h00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "8,00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "08,00 am utc", '$mo', '$d', '$y', 8, 0, -+ '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "11,00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "noon", '$mo', '$d', '$y', 12, 0, -+ '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], -+[ "Noon", '$mo', '$d', '$y', 12, 0, -+ '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], -+[ "NOON", '$mo', '$d', '$y', 12, 0, -+ '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], -+[ "midnight", '$mo', '$d', '$y', 0, 0, -+ '(($h*60+$mi) < ( 0*60+0) ? 1 * DAY : 1 * DAY)' ], -+[ "teatime", '$mo', '$d', '$y', 16, 0, -+ '(($h*60+$mi) < (16*60+0) ? 0 : 1 * DAY)' ], -+[ "noon utc", '$mo', '$d', '$y', 12, 0, -+ '(($h*60+$mi+$utc_off) < (12*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "noon UTC", '$mo', '$d', '$y', 12, 0, -+ '(($h*60+$mi+$utc_off) < (12*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+[ "midnight utc", '$mo', '$d', '$y', 0, 0, -+ '(($h*60+$mi+$utc_off) < ( 0*60+0) ? 1 * DAY : 1 * DAY) - $utc_off * MINUTE' ], -+[ "teatime utc", '$mo', '$d', '$y', 16, 0, -+ '(($h*60+$mi+$utc_off) < (16*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], -+); -+ -+ -+# -+# Tests for combining times and dates and inc/dec -+# These tests include specific times and time aliases that are -+# combined with @date_time_tests_date and with @inc_dec_tests -+# during testing. -+# -+# Format: "string", month, day, year, hour, minute, [offset] -+# -+@date_time_tests_time = -+( -+[ "0800", '$mo', '$d', '$y', 8, 0 ], -+[ "2300", '$mo', '$d', '$y', 23, 0 ], -+[ "8:00", '$mo', '$d', '$y', 8, 0 ], -+[ "23:00", '$mo', '$d', '$y', 23, 0 ], -+[ "8'00", '$mo', '$d', '$y', 8, 0 ], -+[ "23'00", '$mo', '$d', '$y', 23, 0 ], -+[ "8.00", '$mo', '$d', '$y', 8, 0 ], -+[ "23.00", '$mo', '$d', '$y', 23, 0 ], -+[ "8h00", '$mo', '$d', '$y', 8, 0 ], -+[ "23h00", '$mo', '$d', '$y', 23, 0 ], -+[ "8,00", '$mo', '$d', '$y', 8, 0 ], -+[ "23,00", '$mo', '$d', '$y', 23, 0 ], -+[ "8:00 am", '$mo', '$d', '$y', 8, 0 ], -+[ "11:00 pm", '$mo', '$d', '$y', 23, 0 ], -+[ "8'00 am", '$mo', '$d', '$y', 8, 0 ], -+[ "11'00 pm", '$mo', '$d', '$y', 23, 0 ], -+[ "8.00 am", '$mo', '$d', '$y', 8, 0 ], -+[ "11.00 pm", '$mo', '$d', '$y', 23, 0 ], -+[ "8h00 am", '$mo', '$d', '$y', 8, 0 ], -+[ "11h00 pm", '$mo', '$d', '$y', 23, 0 ], -+[ "8,00 am", '$mo', '$d', '$y', 8, 0 ], -+[ "11,00 pm", '$mo', '$d', '$y', 23, 0 ], -+[ "0800 utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "2300 utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8:00 utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "23:00 utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8'00 utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "23'00 utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8.00 utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "23.00 utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8h00 utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "23h00 utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8,00 utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "23,00 utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8:00 am utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "11:00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8'00 am utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "11'00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8.00 am utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "11.00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8h00 am utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "11h00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "8,00 am utc", '$mo', '$d', '$y', 8, 0, -+ '- $utc_off * MINUTE' ], -+[ "11,00 pm utc", '$mo', '$d', '$y', 23, 0, -+ '- $utc_off * MINUTE' ], -+[ "noon", '$mo', '$d', '$y', 12, 0 ], -+[ "midnight", '$mo', '$d', '$y', 0, 0 ], -+[ "teatime", '$mo', '$d', '$y', 16, 0 ], -+[ "noon utc", '$mo', '$d', '$y', 12, 0, -+ '- $utc_off * MINUTE' ], -+[ "midnight utc", '$mo', '$d', '$y', 0, 0, -+ '- $utc_off * MINUTE' ], -+[ "teatime utc", '$mo', '$d', '$y', 16, 0, -+ '- $utc_off * MINUTE' ], -+); -+ -+ -+# -+# Tests for combining times and dates and inc/dec -+# These tests include both relative and specific dates that are -+# combined with @date_time_tests_time and with @inc_dec_tests -+# during testing. -+# -+# Format: "string", month, day, year, hour, minute, [offset] -+# -+@date_time_tests_date = -+( -+[ "Dec 31", 12, 31, '($mo==12 && $d==31 ? $y+1 : $y)', '$h', '$mi' ], -+[ "Dec 31 10", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "Dec 31, 10", 12, 31, 2010, '$h', '$mi' ], -+[ "December 31, 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "Monday", '$mo', '$d', '$y', '$h', '$mi', -+ '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], -+[ "today", '$mo', '$d', '$y', '$h', '$mi' ], -+[ "tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], -+[ "10-12-31", 12, 31, 2010, '$h', '$mi' ], -+[ "2010-12-31", 12, 31, 2010, '$h', '$mi' ], -+[ "31.12.10", 12, 31, 2010, '$h', '$mi' ], -+[ "31.12.2010", 12, 31, 2010, '$h', '$mi' ], -+[ "31 Dec", 12, 31, '($mo==12 && $d==31 ? $y+1 : $y)', '$h', '$mi' ], -+[ "31 Dec 10", 12, 31, 2010, '$h', '$mi' ], -+[ "31 Dec 2010", 12, 31, 2010, '$h', '$mi' ], -+[ "12/31/10", 12, 31, 2010, '$h', '$mi' ], -+[ "12/31/2010", 12, 31, 2010, '$h', '$mi' ], -+[ "13010", 01, 30, 2010, '$h', '$mi' ], -+[ "1302010", 01, 30, 2010, '$h', '$mi' ], -+[ "123110", 12, 31, 2010, '$h', '$mi' ], -+[ "12312010", 12, 31, 2010, '$h', '$mi' ], -+[ "next minute", '$mo', '$d', '$y', '$h', '$mi', '1 * MINUTE' ], -+[ "next hour", '$mo', '$d', '$y', '$h', '$mi', '1 * HOUR' ], -+[ "next day", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], -+[ "next week", '$mo', '$d', '$y', '$h', '$mi', '1 * WEEK' ], -+[ "next month", '($mo == 12 ? 1 : $mo + 1)', '$d', '($mo == 12 ? $y + 1 : $y)', '$h', '$mi' ], -+[ "next year", '$mo', '$d', '$y + 1', '$h', '$mi' ], -+); -+ -+ -+# -+# Tests for combining times and dates and inc/dec -+# These tests include both increments and decrements that are -+# combined with @date_time_tests_time and with @date_time_tests_date -+# during testing. Note how these tests refer to elements from -+# the data structures that they will be combined with ($$i[N]). -+# -+# Format: "string", month, day, year, hour, minute, [offset] -+# -+@inc_dec_tests = -+( -+[ "- 1 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * MINUTE' ], -+[ "- 1 minute", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * MINUTE' ], -+[ "- 1 hour", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * HOUR' ], -+[ "- 1 day", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * DAY' ], -+[ "- 1 week", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * WEEK' ], -+[ "- 1 month", '($$i[1] == 1 ? 12 : $$i[1] - 1)', '$$i[2]', '($$i[1] == 1 ? $$i[3] - 1 : $$i[3])', '$$i[4]', '$$i[5]' ], -+[ "- 1 year", '$$i[1]', '$$i[2]', '$$i[3] - 1', '$$i[4]', '$$i[5]' ], -+[ "- 10 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * MINUTE' ], -+[ "- 10 minutes", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * MINUTE' ], -+[ "- 10 hours", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * HOUR' ], -+[ "- 10 days", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * DAY' ], -+[ "- 10 weeks", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * WEEK' ], -+[ "- 10 months", '($$i[1] > 10 ? $$i[1] - 10 : $$i[1] + 2)', '$$i[2]', '($$i[1] > 10 ? $$i[3]: $$i[3] - 1)', '$$i[4]', '$$i[5]' ], -+[ "- 10 years", '$$i[1]', '$$i[2]', '$$i[3] - 10', '$$i[4]', '$$i[5]' ], -+[ "+ 1 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * MINUTE' ], -+[ "+ 1 minute", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * MINUTE' ], -+[ "+ 1 hour", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * HOUR' ], -+[ "+ 1 day", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * DAY' ], -+[ "+ 1 week", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * WEEK' ], -+[ "+ 1 month", '($$i[1] == 12 ? 1 : $$i[1] + 1)', '$$i[2]', '($$i[1] == 12 ? $$i[3] + 1 : $$i[3])', '$$i[4]', '$$i[5]' ], -+[ "+ 1 year", '$$i[1]', '$$i[2]', '$$i[3] + 1', '$$i[4]', '$$i[5]' ], -+[ "+ 10 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * MINUTE' ], -+[ "+ 10 minutes", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * MINUTE' ], -+[ "+ 10 hours", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * HOUR' ], -+[ "+ 10 days", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * DAY' ], -+[ "+ 10 weeks", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * WEEK' ], -+[ "+ 10 months", '($$i[1] < 3 ? $$i[1] + 10 : $$i[1] - 2)', '$$i[2]', '($$i[1] < 3 ? $$i[3] : $$i[3] + 1)', '$$i[4]', '$$i[5]' ], -+[ "+ 10 years", '$$i[1]', '$$i[2]', '$$i[3] + 10', '$$i[4]', '$$i[5]' ], -+); -+ -+ -+# -+# Miscellaneous tests -+# These tests include any specific test cases that won't fit easily -+# into the test data above. -+# They are not combined with any other tests. -+# -+# Format: "string", month, day, year, hour, minute, [offset] -+# -+@misc_tests = -+( -+# Test moving back and forth across DST -+[ "March 1 + 3 months", '6', '1', '$y', '$h', '$mi' ], -+[ "June 1 - 3 months", '3', '1', '$y', '$h', '$mi' ], -+[ "September 1 + 3 months", '12', '1', '$y', '$h', '$mi' ], -+[ "December 1 - 3 months", '9', '1', '$y', '$h', '$mi' ], -+[ "March 1 + 12 weeks", '3', '1', '$y', '$h', '$mi', '+12 * WEEK' ], -+[ "June 1 - 12 weeks", '6', '1', '$y', '$h', '$mi', '-12 * WEEK' ], -+[ "September 1 + 12 weeks", '9', '1', '$y', '$h', '$mi', '+12 * WEEK' ], -+[ "December 1 - 12 weeks", '12', '1', '$y', '$h', '$mi', '-12 * WEEK' ], -+); -+ -+ -+$num_tests = ($#date_tests + 1) -+ + ($#time_tests + 1) -+ + ($#misc_tests + 1) -+ + ($#date_time_tests_time + 1) * ($#date_time_tests_date + 1) -+ + ($#date_time_tests_time + 1) * ($#inc_dec_tests + 1) -+ + ($#date_time_tests_date + 1) * ($#inc_dec_tests + 1) -+ ; -+ -+ -+# -+# Print out the number of tests to perform -+# -+print "1..$num_tests\n"; -+ -+ -+# -+# Run date, time and miscellaneous tests -+# -+foreach my $i (@date_tests, @time_tests, @misc_tests) -+{ -+ my $s; # current second -+ my $mi; # current minute -+ my $h; # current hour -+ my $d; # current day -+ my $mo; # current month -+ my $y; # current year -+ my $wd; # current week day -+ my $yd; # current year day -+ my $dst; # is daylight savings time? -+ -+ my $epoch_time; # time string in epoch seconds -+ my $offset = 0; # offset for test in epoch seconds -+ my $t; # time string to test against -+ -+ my $o; # output of parsetest command -+ my $run_time; # internal timestamp used for comparison -+ -+ ## WARNING: Next two statements could run in different minutes! -+ $o = `./parsetest \"$$i[0]\" $show_stderr`; -+ $run_time = time(); -+ -+ ## Set variables for $run_time before calculating $offset -+ ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); -+ $mo += 1; -+ $y += 1900; -+ -+ $offset = eval "$$i[6]" if (defined $$i[6]); -+ -+ $epoch_time = strftime("%s", -+ 0, -+ eval "$$i[5]", -+ eval "$$i[4]", -+ eval "$$i[2]", -+ eval "$$i[1] - 1", -+ eval "$$i[3] - 1900", -+ -1, # wday -+ -1, # yday -+ -1, # isdst -+ ); -+ -+ ## Adjust +-1 hour when moving in or out of DST -+ if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) -+ { # DST to no DST -+ $epoch_time += 1 * HOUR; -+ } -+ elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) -+ { # no DST to DST -+ $epoch_time -= 1 * HOUR; -+ } -+ -+ $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); -+ -+ chomp $o; -+ -+ print $o eq $t ? "ok" : "not ok", "\n"; -+ -+ print "'", $$i[0], "': '$o' =? '$t'\n" -+ if ($verbose > 1 || ($verbose == 1 && $o ne $t)); -+} -+ -+ -+# -+# Run time + date tests -+# -+foreach my $i (@date_time_tests_time) -+{ -+ foreach my $j (@date_time_tests_date) -+ { -+ my $s; # current second -+ my $mi; # current minute -+ my $h; # current hour -+ my $d; # current day -+ my $mo; # current month -+ my $y; # current year -+ my $wd; # current week day -+ my $yd; # current year day -+ my $dst; # is daylight savings time? -+ -+ my $epoch_time; # time string in epoch seconds -+ my $offset = 0; # offset for test in epoch seconds -+ my $t; # time string to test against -+ -+ my $o; # output of parsetest command -+ my $run_time; # internal timestamp used for comparison -+ -+ ## WARNING: Next two statements could run in different minutes! -+ $o = `./parsetest \"$$i[0] $$j[0]\" $show_stderr`; -+ $run_time = time(); -+ -+ ## Set variables for $run_time before calculating $offset -+ ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); -+ $mo += 1; -+ $y += 1900; -+ -+ if (defined $$i[6]) -+ { -+ if (defined $$j[6]) -+ { -+ $offset = eval "($$i[6]) + ($$j[6])"; -+ } -+ else -+ { -+ $offset = eval "$$i[6]"; -+ } -+ } -+ elsif (defined $$j[6]) -+ { -+ $offset = eval "$$j[6]"; -+ } -+ -+ $epoch_time = strftime("%s", -+ 0, -+ eval "$$i[5]", -+ eval "$$i[4]", -+ eval "$$j[2]", -+ eval "$$j[1] - 1", -+ eval "$$j[3] - 1900", -+ -1, # wday -+ -1, # yday -+ -1, # isdst -+ ); -+ -+ ## Adjust +-1 hour when moving in or out of DST -+ if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) -+ { # DST to no DST -+ $epoch_time += 1 * HOUR; -+ } -+ elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) -+ { # no DST to DST -+ $epoch_time -= 1 * HOUR; -+ } -+ -+ $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); -+ -+ chomp $o; -+ -+ print $o eq $t ? "ok" : "not ok", "\n"; -+ -+ print "'$$i[0] $$j[0]': '$o' =? '$t'\n" -+ if ($verbose > 1 || ($verbose == 1 && $o ne $t)); -+ } -+} -+ -+ -+# -+# Run time + inc_dec and date + inc_dec tests -+# -+foreach my $i (@date_time_tests_time, @date_time_tests_date) -+{ -+ foreach my $j (@inc_dec_tests) -+ { -+ my $s; # current second -+ my $mi; # current minute -+ my $h; # current hour -+ my $d; # current day -+ my $mo; # current month -+ my $y; # current year -+ my $wd; # current week day -+ my $yd; # current year day -+ my $dst; # is daylight savings time? -+ -+ my $epoch_time; # time string in epoch seconds -+ my $offset = 0; # offset for test in epoch seconds -+ my $t; # time string to test against -+ -+ my $o; # output of parsetest command -+ my $run_time; # internal timestamp used for comparison -+ -+ ## WARNING: Next two statements could run in different minutes! -+ $o = `./parsetest \"$$i[0] $$j[0]\" $show_stderr`; -+ $run_time = time(); -+ -+ ## Set variables for $run_time before calculating $offset -+ ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); -+ $mo += 1; -+ $y += 1900; -+ -+ if (defined $$i[6]) -+ { -+ if (defined $$j[6]) -+ { -+ $offset = eval "($$i[6]) + ($$j[6])"; -+ } -+ else -+ { -+ $offset = eval "$$i[6]"; -+ } -+ } -+ elsif (defined $$j[6]) -+ { -+ $offset = eval "$$j[6]"; -+ } -+ -+ $epoch_time = strftime("%s", -+ 0, -+ eval "$$i[5]", -+ eval "$$i[4]", -+ eval "eval \"$$j[2]\"", -+ eval "eval \"$$j[1] - 1\"", -+ eval "eval \"$$j[3] - 1900\"", -+ -1, # wday -+ -1, # yday -+ -1, # isdst -+ ); -+ -+ ## Adjust +-1 hour when moving in or out of DST -+ if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) -+ { # DST to no DST -+ $epoch_time += 1 * HOUR; -+ } -+ elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) -+ { # no DST to DST -+ $epoch_time -= 1 * HOUR; -+ } -+ -+ $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); -+ -+ chomp $o; -+ -+ print $o eq $t ? "ok" : "not ok", "\n"; -+ -+ print "'$$i[0] $$j[0]': '$o' =? '$t'\n" -+ if ($verbose > 1 || ($verbose == 1 && $o ne $t)); -+ } -+} -+ -+exit 0; -+ -+ -+# -+# Subroutine: -+# is_dst -+# -+# Description: -+# returns true if the time passed in is in DST, else -+# returns false if the time passed in is not in DST -+# -+# Arg 1: -+# [Optional] time in epoch seconds; defaults to the current -+# time if no argument is given -+# -+sub is_dst (;$) -+{ -+ my $t = shift || time(); -+ return ((localtime($t))[8] > 0); -+} -+ -+ -+# -+# Subroutine: -+# get_utc_offset -+# -+# Description: -+# returns the number of offest hours from UTC for the current timezone -+# -+# Arg 1: -+# [Optional] time in epoch seconds; defaults to the current -+# time if no argument is given -+# -+sub get_utc_offset (;$) -+{ -+ my $t = shift || time(); -+ my @t = localtime($t); -+ my $is_dst = $t[8]; -+ return ((timelocal(@t) - timegm(@t) + ($is_dst > 0 ? HOUR : 0)) / MINUTE); -+} -+ diff --git a/at.spec b/at.spec index 02cf17c..9afb7a7 100644 --- a/at.spec +++ b/at.spec @@ -1,31 +1,28 @@ Summary: Job spooling tools. Name: at Version: 3.1.8 -Release: 33 +Release: 46.1 License: GPL Group: System Environment/Daemons -Source: ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/at-3.1.8.tar.bz2 +Source: http://ftp.debian.org/debian/pool/main/a/at/at_3.1.8-11.tar.gz +Source1: test.pl Source2: atd.init Patch0: at-3.1.7-lockfile.patch Patch1: at-3.1.7-noon.patch -Patch2: at-3.1.7-paths.patch +Patch2: at-3.1.8-man-timespec-path.patch Patch3: at-3.1.7-sigchld.patch Patch4: at-noroot.patch Patch5: at-3.1.7-typo.patch -Patch6: at-debian.patch Patch7: at-3.1.8-buflen.patch -Patch9: at-3.1.8-shell.patch Patch10: at-3.1.8-batch.patch -Patch11: at-3.1.8-lexer.patch -Patch12: at-3.1.8-dst.patch +Patch11: at-3.1.8-11-lexer-parser.diff Patch13: at-3.1.8-test.patch -Patch14: at-3.1.8-test-fix.patch -#Patch15: at-3.1.8-env.patch Patch15: at-3.1.8-env-tng.patch -Patch16: at-3.1.8-lsbdoc.patch -Patch17: at-3.1.8-o_excl.patch +#Patch16: at-3.1.8-lsbdoc.patch Patch18: at-3.1.8-perr.patch Patch19: at-3.1.8-instinet.patch +Patch20: at-3.1.8-SHELL-91233.patch +Patch21: at-3.1.8-atrun.8-typo-97697.patch Prereq: fileutils chkconfig /etc/init.d BuildPrereq: flex bison autoconf @@ -45,54 +42,62 @@ time-oriented job control. Note: If it is a recurring job that will need to be repeated at the same time every day/week, etc. you should use crontab instead. +%{?_without_check: %define _without_check 1} +%{!?_without_check: %define _without_check 0} + %prep %setup -q +cp %{SOURCE1} . %patch0 -p1 -b .lockfile # The next path is a brute-force fix that will have to be updated # when new versions of at are released. %patch2 -p1 -b .paths %patch3 -p1 -b .sigchld -%patch6 -p1 -b .debian +#%%patch6 -p1 -b .debian %patch4 -p1 -b .noroot %patch5 -p1 -b .tyop %patch7 -p1 -b .buflen -%patch9 -p1 -b .shell %patch10 -p1 -b .batch %patch11 -p1 -b .lexer -%patch12 -p1 -b .dst +#%%patch12 -p1 -b .dst %patch13 -p1 -b .test -%patch14 -p1 -b .test-fix +#%%patch14 -p1 -b .test-fix %patch15 -p1 -b .env -%patch16 -p1 -b .lsbdoc -%patch17 -p1 -b .o_excl +#%%patch16 -p1 -b .lsbdoc +#%%patch17 -p1 -b .o_excl %patch18 -p1 -b .perr %patch19 -p1 -b .instinet +%patch20 -p1 -b .SHELL +%patch21 -p1 -b .typo %build -# for patch 9 +# patch10 touches configure.in autoconf -cp /usr/share/libtool/config.{sub,guess} . -%configure --with-atspool=/var/spool/at/spool --with-jobdir=/var/spool/at - -# for patch 11 +# for patch11 rm -f lex.yy.* y.tab.* +%configure --with-atspool=%{_localstatedir}/spool/at/spool --with-jobdir=%{_localstatedir}/spool/at make +%if ! %{_without_check} + LANG=C make test > /dev/null +%endif + %install rm -rf %{buildroot} -mkdir -p %{buildroot}/etc/rc.d/init.d %makeinstall DAEMON_USERNAME=`id -nu` \ DAEMON_GROUPNAME=`id -ng` \ - etcdir=%{buildroot}/etc \ - ATJOB_DIR=%{buildroot}/var/spool/at \ - ATSPOOL_DIR=%{buildroot}/var/spool/at/spool -echo > %{buildroot}/etc/at.deny + etcdir=%{buildroot}%{_sysconfdir} \ + ATJOB_DIR=%{buildroot}%{_localstatedir}/spool/at \ + ATSPOOL_DIR=%{buildroot}%{_localstatedir}/spool/at/spool +echo > %{buildroot}%{_sysconfdir}/at.deny mkdir docs cp $RPM_BUILD_ROOT/%{_prefix}/doc/at/* docs/ -install -m 755 %{SOURCE2} %{buildroot}/etc/rc.d/init.d/atd + +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d +install -m 755 %{SOURCE2} %{buildroot}%{_sysconfdir}/rc.d/init.d/atd mv -f %{buildroot}/%{_mandir}/man5/at_allow.5 \ %{buildroot}/%{_mandir}/man5/at.allow.5 @@ -101,15 +106,15 @@ ln -s at.allow.5 \ %{buildroot}/%{_mandir}/man5/at.deny.5 # remove unpackaged files from the buildroot -rm -rf $RPM_BUILD_ROOT%{_prefix}/doc +rm -r $RPM_BUILD_ROOT%{_prefix}/doc %clean rm -rf %{buildroot} %post -touch /var/spool/at/.SEQ -chmod 600 /var/spool/at/.SEQ -chown daemon.daemon /var/spool/at/.SEQ +touch %{_localstatedir}/spool/at/.SEQ +chmod 600 %{_localstatedir}/spool/at/.SEQ +chown daemon.daemon %{_localstatedir}/spool/at/.SEQ /sbin/chkconfig --add atd %preun @@ -126,21 +131,53 @@ fi %files %defattr(-,root,root) %doc docs/* -%config /etc/at.deny -%config /etc/rc.d/init.d/atd -%attr(0700,daemon,daemon) %dir /var/spool/at -%attr(0600,daemon,daemon) %verify(not md5 size mtime) %ghost /var/spool/at/.SEQ -%attr(0700,daemon,daemon) %dir /var/spool/at/spool -%{_prefix}/sbin/atrun -%{_prefix}/sbin/atd +%config %{_sysconfdir}/at.deny +%config %{_sysconfdir}/rc.d/init.d/atd +%attr(0700,daemon,daemon) %dir %{_localstatedir}/spool/at +%attr(0600,daemon,daemon) %verify(not md5 size mtime) %ghost %{_localstatedir}/spool/at/.SEQ +%attr(0700,daemon,daemon) %dir %{_localstatedir}/spool/at/spool +%{_sbindir}/atrun +%{_sbindir}/atd %{_mandir}/man*/* -%{_prefix}/bin/batch -%{_prefix}/bin/atrm -%{_prefix}/bin/atq -%attr(4755,root,root) %{_prefix}/bin/at +%{_bindir}/batch +%{_bindir}/atrm +%{_bindir}/atq +%attr(4755,root,root) %{_bindir}/at %changelog -* Wed Jan 22 2003 Tim Powers +* Fri Jun 20 2003 Jens Petersen - 3.1.8-46 +- add at-3.1.8-atrun.8-typo-97697.patch to fix typo in atrun.8 (#97697) +- update at.1 description of shell behaviour (#91233) + +* Tue Jun 17 2003 Jens Petersen - 3.1.8-45 +- make the job shell default to SHELL instead of "/bin/sh" (#91233) + +* Wed Jun 04 2003 Elliot Lee - 3.1.8-44 +- rebuilt + +* Tue Jun 3 2003 Jens Petersen - 3.1.8-43 +- Replace redundant at-3.1.7-paths.patch by at-3.1.8-man-timespec-path.patch + to fix timespec path + +* Tue Jun 3 2003 Jens Petersen - 3.1.8-41 +- update source to at_3.1.8-11 from debian upstream + - update source url + - at-debian.patch no longer needed + - at-3.1.7-paths.patch: the patch to "at.1.in" no longer needed + - replace at-3.1.8-lexer.patch with at-3.1.8-11-lexer-parser.diff + - at-3.1.8-dst.patch no longer needed + - at-3.1.8-lsbdoc.patch no longer needed + - at-3.1.8-o_excl.patch no longer needed + - bump release number +- at-3.1.8-test.patch: move out test.pl to a separate source file + - apply at-3.1.8-test-fix.patch to it and drop patch +- at-3.1.8-shell.patch: drop (#22216,#91233) +- run "make test" after building +- add "--without check" rpmbuild option +- fix autoconf comment to point to right patch +- use _sysconfdir, _sbindir, _bindir, and _localstatedir + +* Wed Jan 22 2003 Tim Powers 3.1.8-33 - rebuilt * Wed Nov 27 2002 Tim Powers 3.1.8-32 diff --git a/sources b/sources index 43e0dae..1bfc743 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f5194baac29a30b0d90604422dad7037 at-3.1.8.tar.bz2 +81dbae5162aaa8a398a81424d6631c77 at_3.1.8-11.tar.gz diff --git a/test.pl b/test.pl new file mode 100755 index 0000000..4bdba6c --- /dev/null +++ b/test.pl @@ -0,0 +1,800 @@ +#!/usr/bin/perl -w +# +# test.pl - tests validity of lexer/parser for at(1) +# +# Copyright 2001 David D. Kilzer +# +# Licensed under the GNU Public License +# +# Environment variables: +# TEST_VERBOSE +# 0 - no verbosity +# 1 - verbose output only on failed tests, and all stderr output +# > 1 - verbose output on every test, and all stderr output +# + +use strict; + +use constant SECOND => 1; # seconds per second +use constant MINUTE => 60*SECOND; # seconds per minute +use constant HOUR => 60*MINUTE; # seconds per hour +use constant DAY => 24*HOUR; # seconds per day +use constant WEEK => 7*DAY; # seconds per week + +use vars qw($verbose); + +use POSIX; # strftime +use Time::Local; # timelocal() and timegm() + +BEGIN { $| = 1; } # no output buffering + + +# +# Subroutines +# +sub is_dst (;$); # is time in DST? +sub get_utc_offset (;$); # calculate hours offset from UTC + + +# +# Data structures containing test data +# +my @date_tests; # date strings +my @time_tests; # time strings +my @date_time_tests_time; # time + date strings (just times) +my @date_time_tests_date; # time + date strings (just dates) +my @inc_dec_tests; # increment and decrement strings +my @misc_tests; # miscellaneous strings (mostly for DST) + +my $num_tests; # number of tests +my $show_stderr; # set to "2> /dev/null" if (! $verbose) +my $utc_off; # timezone offset in minutes west of UTC + + +# +# Set variables before running tests +# +$verbose = $ENV{'TEST_VERBOSE'} || 0; + +$show_stderr = ($verbose > 0 ? "" : "2> /dev/null"); + +$utc_off = get_utc_offset(); + + +# +# Tests for dates only +# These tests include both relative and specific dates. +# They are not combined with any other tests. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@date_tests = +( +[ "dec 31", 12, 31, '$y', '$h', '$mi' ], +[ "Dec 31", 12, 31, '$y', '$h', '$mi' ], +[ "DEC 31", 12, 31, '$y', '$h', '$mi' ], +[ "december 31", 12, 31, '$y', '$h', '$mi' ], +[ "December 31", 12, 31, '$y', '$h', '$mi' ], +[ "DECEMBER 31", 12, 31, '$y', '$h', '$mi' ], +[ "Dec 31 10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31 10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31 2010", 12, 31, 2010, '$h', '$mi' ], +[ "December 31 2010", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31,10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31, 10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31,10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31, 10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31,2010", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31, 2010", 12, 31, 2010, '$h', '$mi' ], +[ "December 31,2010", 12, 31, 2010, '$h', '$mi' ], +[ "December 31, 2010", 12, 31, 2010, '$h', '$mi' ], +[ "sun", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "Sun", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "SUN", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "sunday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "Sunday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "SUNDAY", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "Mon", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], +[ "Monday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], +[ "Tue", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 2 ? 7 : ((7 - $wd + 2) % 7)) * DAY)' ], +[ "Tuesday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 2 ? 7 : ((7 - $wd + 2) % 7)) * DAY)' ], +[ "Wed", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 3 ? 7 : ((7 - $wd + 3) % 7)) * DAY)' ], +[ "Wednesday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 3 ? 7 : ((7 - $wd + 3) % 7)) * DAY)' ], +[ "Thu", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 4 ? 7 : ((7 - $wd + 4) % 7)) * DAY)' ], +[ "Thursday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 4 ? 7 : ((7 - $wd + 4) % 7)) * DAY)' ], +[ "Fri", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 5 ? 7 : ((7 - $wd + 5) % 7)) * DAY)' ], +[ "Friday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 5 ? 7 : ((7 - $wd + 5) % 7)) * DAY)' ], +[ "Sat", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 6 ? 7 : ((7 - $wd + 6) % 7)) * DAY)' ], +[ "Saturday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 6 ? 7 : ((7 - $wd + 6) % 7)) * DAY)' ], +[ "now", '$mo', '$d', '$y', '$h', '$mi' ], +[ "Now", '$mo', '$d', '$y', '$h', '$mi' ], +[ "NOW", '$mo', '$d', '$y', '$h', '$mi' ], +[ "today", '$mo', '$d', '$y', '$h', '$mi' ], +[ "Today", '$mo', '$d', '$y', '$h', '$mi' ], +[ "TODAY", '$mo', '$d', '$y', '$h', '$mi' ], +[ "tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "Tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "TOMORROW", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "10-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "2010-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.10", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.2010", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec", 12, 31, '$y', '$h', '$mi' ], +[ "31 December", 12, 31, '$y', '$h', '$mi' ], +[ "31 Dec 10", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec 2010", 12, 31, 2010, '$h', '$mi' ], +[ "31 December 10", 12, 31, 2010, '$h', '$mi' ], +[ "31 December 2010", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/10", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/2010", 12, 31, 2010, '$h', '$mi' ], +[ "13010", 01, 30, 2010, '$h', '$mi' ], +[ "1302010", 01, 30, 2010, '$h', '$mi' ], +[ "013010", 01, 30, 2010, '$h', '$mi' ], +[ "01302010", 01, 30, 2010, '$h', '$mi' ], +[ "123110", 12, 31, 2010, '$h', '$mi' ], +[ "12312010", 12, 31, 2010, '$h', '$mi' ], +[ "next minute", '$mo', '$d', '$y', '$h', '$mi', '1 * MINUTE' ], +[ "next hour", '$mo', '$d', '$y', '$h', '$mi', '1 * HOUR' ], +[ "next day", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "next week", '$mo', '$d', '$y', '$h', '$mi', '1 * WEEK' ], +[ "next month", '($mo == 12 ? 1 : $mo + 1)', '$d', '($mo == 12 ? $y + 1 : $y)', '$h', '$mi' ], +[ "next year", '$mo', '$d', '$y + 1', '$h', '$mi' ], +); + + +# +# Tests for times only +# These tests include specific times and time aliases. +# They are not combined with any other tests. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@time_tests = +( +[ "0800", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "2300", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8:00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08:00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23:00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8'00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08'00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23'00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8.00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08.00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23.00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8h00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08h00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23h00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8,00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08,00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23,00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8:00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08:00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11:00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8'00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08'00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11'00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8.00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08.00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11.00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8h00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08h00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11h00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8,00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08,00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11,00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "0800 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "2300 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8:00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08:00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23:00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8'00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08'00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23'00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8.00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08.00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23.00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8h00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08h00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23h00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8,00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08,00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23,00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8:00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08:00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11:00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8'00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08'00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11'00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8.00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08.00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11.00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8h00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08h00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11h00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8,00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08,00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11,00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "noon", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], +[ "Noon", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], +[ "NOON", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], +[ "midnight", '$mo', '$d', '$y', 0, 0, + '(($h*60+$mi) < ( 0*60+0) ? 1 * DAY : 1 * DAY)' ], +[ "teatime", '$mo', '$d', '$y', 16, 0, + '(($h*60+$mi) < (16*60+0) ? 0 : 1 * DAY)' ], +[ "noon utc", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi+$utc_off) < (12*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "noon UTC", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi+$utc_off) < (12*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "midnight utc", '$mo', '$d', '$y', 0, 0, + '(($h*60+$mi+$utc_off) < ( 0*60+0) ? 1 * DAY : 1 * DAY) - $utc_off * MINUTE' ], +[ "teatime utc", '$mo', '$d', '$y', 16, 0, + '(($h*60+$mi+$utc_off) < (16*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +); + + +# +# Tests for combining times and dates and inc/dec +# These tests include specific times and time aliases that are +# combined with @date_time_tests_date and with @inc_dec_tests +# during testing. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@date_time_tests_time = +( +[ "0800", '$mo', '$d', '$y', 8, 0 ], +[ "2300", '$mo', '$d', '$y', 23, 0 ], +[ "8:00", '$mo', '$d', '$y', 8, 0 ], +[ "23:00", '$mo', '$d', '$y', 23, 0 ], +[ "8'00", '$mo', '$d', '$y', 8, 0 ], +[ "23'00", '$mo', '$d', '$y', 23, 0 ], +[ "8.00", '$mo', '$d', '$y', 8, 0 ], +[ "23.00", '$mo', '$d', '$y', 23, 0 ], +[ "8h00", '$mo', '$d', '$y', 8, 0 ], +[ "23h00", '$mo', '$d', '$y', 23, 0 ], +[ "8,00", '$mo', '$d', '$y', 8, 0 ], +[ "23,00", '$mo', '$d', '$y', 23, 0 ], +[ "8:00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11:00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8'00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11'00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8.00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11.00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8h00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11h00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8,00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11,00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "0800 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "2300 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8:00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23:00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8'00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23'00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8.00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23.00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8h00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23h00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8,00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23,00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8:00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11:00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8'00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11'00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8.00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11.00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8h00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11h00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8,00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11,00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "noon", '$mo', '$d', '$y', 12, 0 ], +[ "midnight", '$mo', '$d', '$y', 0, 0 ], +[ "teatime", '$mo', '$d', '$y', 16, 0 ], +[ "noon utc", '$mo', '$d', '$y', 12, 0, + '- $utc_off * MINUTE' ], +[ "midnight utc", '$mo', '$d', '$y', 0, 0, + '- $utc_off * MINUTE' ], +[ "teatime utc", '$mo', '$d', '$y', 16, 0, + '- $utc_off * MINUTE' ], +); + + +# +# Tests for combining times and dates and inc/dec +# These tests include both relative and specific dates that are +# combined with @date_time_tests_time and with @inc_dec_tests +# during testing. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@date_time_tests_date = +( +[ "Dec 31", 12, 31, '$y', '$h', '$mi' ], +[ "Dec 31 10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31 2010", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31, 10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31, 2010", 12, 31, 2010, '$h', '$mi' ], +[ "Monday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], +[ "today", '$mo', '$d', '$y', '$h', '$mi' ], +[ "tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "10-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "2010-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.10", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.2010", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec", 12, 31, '$y', '$h', '$mi' ], +[ "31 Dec 10", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec 2010", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/10", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/2010", 12, 31, 2010, '$h', '$mi' ], +[ "13010", 01, 30, 2010, '$h', '$mi' ], +[ "1302010", 01, 30, 2010, '$h', '$mi' ], +[ "123110", 12, 31, 2010, '$h', '$mi' ], +[ "12312010", 12, 31, 2010, '$h', '$mi' ], +[ "next minute", '$mo', '$d', '$y', '$h', '$mi', '1 * MINUTE' ], +[ "next hour", '$mo', '$d', '$y', '$h', '$mi', '1 * HOUR' ], +[ "next day", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "next week", '$mo', '$d', '$y', '$h', '$mi', '1 * WEEK' ], +[ "next month", '($mo == 12 ? 1 : $mo + 1)', '$d', '($mo == 12 ? $y + 1 : $y)', '$h', '$mi' ], +[ "next year", '$mo', '$d', '$y + 1', '$h', '$mi' ], +); + + +# +# Tests for combining times and dates and inc/dec +# These tests include both increments and decrements that are +# combined with @date_time_tests_time and with @date_time_tests_date +# during testing. Note how these tests refer to elements from +# the data structures that they will be combined with ($$i[N]). +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@inc_dec_tests = +( +[ "- 1 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * MINUTE' ], +[ "- 1 minute", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * MINUTE' ], +[ "- 1 hour", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * HOUR' ], +[ "- 1 day", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * DAY' ], +[ "- 1 week", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * WEEK' ], +[ "- 1 month", '($$i[1] == 1 ? 12 : $$i[1] - 1)', '$$i[2]', '($$i[1] == 1 ? $$i[3] - 1 : $$i[3])', '$$i[4]', '$$i[5]' ], +[ "- 1 year", '$$i[1]', '$$i[2]', '$$i[3] - 1', '$$i[4]', '$$i[5]' ], +[ "- 10 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * MINUTE' ], +[ "- 10 minutes", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * MINUTE' ], +[ "- 10 hours", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * HOUR' ], +[ "- 10 days", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * DAY' ], +[ "- 10 weeks", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * WEEK' ], +[ "- 10 months", '($$i[1] > 10 ? $$i[1] - 10 : $$i[1] + 2)', '$$i[2]', '($$i[1] > 10 ? $$i[3]: $$i[3] - 1)', '$$i[4]', '$$i[5]' ], +[ "- 10 years", '$$i[1]', '$$i[2]', '$$i[3] - 10', '$$i[4]', '$$i[5]' ], +[ "+ 1 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * MINUTE' ], +[ "+ 1 minute", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * MINUTE' ], +[ "+ 1 hour", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * HOUR' ], +[ "+ 1 day", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * DAY' ], +[ "+ 1 week", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * WEEK' ], +[ "+ 1 month", '($$i[1] == 12 ? 1 : $$i[1] + 1)', '$$i[2]', '($$i[1] == 12 ? $$i[3] + 1 : $$i[3])', '$$i[4]', '$$i[5]' ], +[ "+ 1 year", '$$i[1]', '$$i[2]', '$$i[3] + 1', '$$i[4]', '$$i[5]' ], +[ "+ 10 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * MINUTE' ], +[ "+ 10 minutes", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * MINUTE' ], +[ "+ 10 hours", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * HOUR' ], +[ "+ 10 days", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * DAY' ], +[ "+ 10 weeks", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * WEEK' ], +[ "+ 10 months", '($$i[1] < 3 ? $$i[1] + 10 : $$i[1] - 2)', '$$i[2]', '($$i[1] < 3 ? $$i[3] : $$i[3] + 1)', '$$i[4]', '$$i[5]' ], +[ "+ 10 years", '$$i[1]', '$$i[2]', '$$i[3] + 10', '$$i[4]', '$$i[5]' ], +); + + +# +# Miscellaneous tests +# These tests include any specific test cases that won't fit easily +# into the test data above. +# They are not combined with any other tests. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@misc_tests = +( +# Test moving back and forth across DST +[ "March 1 + 3 months", '6', '1', '$y', '$h', '$mi' ], +[ "June 1 - 3 months", '3', '1', '$y', '$h', '$mi' ], +[ "September 1 + 3 months", '12', '1', '$y', '$h', '$mi' ], +[ "December 1 - 3 months", '9', '1', '$y', '$h', '$mi' ], +[ "March 1 + 12 weeks", '3', '1', '$y', '$h', '$mi', '+12 * WEEK' ], +[ "June 1 - 12 weeks", '6', '1', '$y', '$h', '$mi', '-12 * WEEK' ], +[ "September 1 + 12 weeks", '9', '1', '$y', '$h', '$mi', '+12 * WEEK' ], +[ "December 1 - 12 weeks", '12', '1', '$y', '$h', '$mi', '-12 * WEEK' ], +); + + +$num_tests = ($#date_tests + 1) + + ($#time_tests + 1) + + ($#misc_tests + 1) + + ($#date_time_tests_time + 1) * ($#date_time_tests_date + 1) + + ($#date_time_tests_time + 1) * ($#inc_dec_tests + 1) + + ($#date_time_tests_date + 1) * ($#inc_dec_tests + 1) + ; + + +# +# Print out the number of tests to perform +# +print "1..$num_tests\n"; + + +# +# Run date, time and miscellaneous tests +# +foreach my $i (@date_tests, @time_tests, @misc_tests) +{ + my $s; # current second + my $mi; # current minute + my $h; # current hour + my $d; # current day + my $mo; # current month + my $y; # current year + my $wd; # current week day + my $yd; # current year day + my $dst; # is daylight savings time? + + my $epoch_time; # time string in epoch seconds + my $offset = 0; # offset for test in epoch seconds + my $t; # time string to test against + + my $o; # output of parsetest command + my $run_time; # internal timestamp used for comparison + + ## WARNING: Next two statements could run in different minutes! + $o = `./parsetest \"$$i[0]\" $show_stderr`; + $run_time = time(); + + ## Set variables for $run_time before calculating $offset + ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); + $mo += 1; + $y += 1900; + + $offset = eval "$$i[6]" if (defined $$i[6]); + + $epoch_time = strftime("%s", + 0, + eval "$$i[5]", + eval "$$i[4]", + eval "$$i[2]", + eval "$$i[1] - 1", + eval "$$i[3] - 1900", + -1, # wday + -1, # yday + -1, # isdst + ); + + ## Adjust +-1 hour when moving in or out of DST + if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) + { # DST to no DST + $epoch_time += 1 * HOUR; + } + elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) + { # no DST to DST + $epoch_time -= 1 * HOUR; + } + + $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); + + chomp $o; + + print $o eq $t ? "ok" : "not ok", "\n"; + + print "'", $$i[0], "': '$o' =? '$t'\n" + if ($verbose > 1 || ($verbose == 1 && $o ne $t)); +} + + +# +# Run time + date tests +# +foreach my $i (@date_time_tests_time) +{ + foreach my $j (@date_time_tests_date) + { + my $s; # current second + my $mi; # current minute + my $h; # current hour + my $d; # current day + my $mo; # current month + my $y; # current year + my $wd; # current week day + my $yd; # current year day + my $dst; # is daylight savings time? + + my $epoch_time; # time string in epoch seconds + my $offset = 0; # offset for test in epoch seconds + my $t; # time string to test against + + my $o; # output of parsetest command + my $run_time; # internal timestamp used for comparison + + ## WARNING: Next two statements could run in different minutes! + $o = `./parsetest \"$$i[0] $$j[0]\" $show_stderr`; + $run_time = time(); + + ## Set variables for $run_time before calculating $offset + ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); + $mo += 1; + $y += 1900; + + if (defined $$i[6]) + { + if (defined $$j[6]) + { + $offset = eval "($$i[6]) + ($$j[6])"; + } + else + { + $offset = eval "$$i[6]"; + } + } + elsif (defined $$j[6]) + { + $offset = eval "$$j[6]"; + } + + $epoch_time = strftime("%s", + 0, + eval "$$i[5]", + eval "$$i[4]", + eval "$$j[2]", + eval "$$j[1] - 1", + eval "$$j[3] - 1900", + -1, # wday + -1, # yday + -1, # isdst + ); + + ## Adjust +-1 hour when moving in or out of DST + if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) + { # DST to no DST + $epoch_time += 1 * HOUR; + } + elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) + { # no DST to DST + $epoch_time -= 1 * HOUR; + } + + $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); + + chomp $o; + + print $o eq $t ? "ok" : "not ok", "\n"; + + print "'$$i[0] $$j[0]': '$o' =? '$t'\n" + if ($verbose > 1 || ($verbose == 1 && $o ne $t)); + } +} + + +# +# Run time + inc_dec and date + inc_dec tests +# +foreach my $i (@date_time_tests_time, @date_time_tests_date) +{ + foreach my $j (@inc_dec_tests) + { + my $s; # current second + my $mi; # current minute + my $h; # current hour + my $d; # current day + my $mo; # current month + my $y; # current year + my $wd; # current week day + my $yd; # current year day + my $dst; # is daylight savings time? + + my $epoch_time; # time string in epoch seconds + my $offset = 0; # offset for test in epoch seconds + my $t; # time string to test against + + my $o; # output of parsetest command + my $run_time; # internal timestamp used for comparison + + ## WARNING: Next two statements could run in different minutes! + $o = `./parsetest \"$$i[0] $$j[0]\" $show_stderr`; + $run_time = time(); + + ## Set variables for $run_time before calculating $offset + ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); + $mo += 1; + $y += 1900; + + if (defined $$i[6]) + { + if (defined $$j[6]) + { + $offset = eval "($$i[6]) + ($$j[6])"; + } + else + { + $offset = eval "$$i[6]"; + } + } + elsif (defined $$j[6]) + { + $offset = eval "$$j[6]"; + } + + $epoch_time = strftime("%s", + 0, + eval "$$i[5]", + eval "$$i[4]", + eval "eval \"$$j[2]\"", + eval "eval \"$$j[1] - 1\"", + eval "eval \"$$j[3] - 1900\"", + -1, # wday + -1, # yday + -1, # isdst + ); + + ## Adjust +-1 hour when moving in or out of DST + if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) + { # DST to no DST + $epoch_time += 1 * HOUR; + } + elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) + { # no DST to DST + $epoch_time -= 1 * HOUR; + } + + $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); + + chomp $o; + + print $o eq $t ? "ok" : "not ok", "\n"; + + print "'$$i[0] $$j[0]': '$o' =? '$t'\n" + if ($verbose > 1 || ($verbose == 1 && $o ne $t)); + } +} + +exit 0; + + +# +# Subroutine: +# is_dst +# +# Description: +# returns true if the time passed in is in DST, else +# returns false if the time passed in is not in DST +# +# Arg 1: +# [Optional] time in epoch seconds; defaults to the current +# time if no argument is given +# +sub is_dst (;$) +{ + my $t = shift || time(); + return ((localtime($t))[8] > 0); +} + + +# +# Subroutine: +# get_utc_offset +# +# Description: +# returns the number of offest hours from UTC for the current timezone +# +# Arg 1: +# [Optional] time in epoch seconds; defaults to the current +# time if no argument is given +# +sub get_utc_offset (;$) +{ + my $t = shift || time(); + my @t = localtime($t); + my $is_dst = $t[8]; + return ((timelocal(@t) - timegm(@t) + ($is_dst > 0 ? HOUR : 0)) / MINUTE); +} +