diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/Makefile | 4 | ||||
-rw-r--r-- | time/bug-getdate1.c | 146 | ||||
-rw-r--r-- | time/getdate.c | 21 |
3 files changed, 161 insertions, 10 deletions
diff --git a/time/Makefile b/time/Makefile index 8ce34e4..71d919d 100644 --- a/time/Makefile +++ b/time/Makefile @@ -36,7 +36,7 @@ distribute := datemsk tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ - tst-strptime3 + tst-strptime3 bug-getdate1 include ../Rules @@ -56,3 +56,5 @@ test_time-ARGS= EST5EDT CST tst-strptime-ENV = LOCPATH=${common-objpfx}localedata tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata + +bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt diff --git a/time/bug-getdate1.c b/time/bug-getdate1.c new file mode 100644 index 0000000..7da88f4 --- /dev/null +++ b/time/bug-getdate1.c @@ -0,0 +1,146 @@ +/* BZ #5451 */ +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +static char *templ_filename; + +// Writes template given as parameter to file, +// specified as the argument +static void +output_to_template_file (const char *str) +{ + FILE *fd = fopen (templ_filename, "w"); + if (fd == NULL) + { + printf ("Can not open file for writing\n"); + exit (1); + } + + fprintf (fd, "%s\n", str); + fclose (fd); +} + +// Calls getdate() function with specified parameter, +// specified as the argument, also checks the contents of +// file with template and prints the result +static int +process_getdate_on (const char *str) +{ + struct tm *res; + char templ[1000]; + FILE *fd = fopen (templ_filename, "r"); + + if (fd == NULL) + { + printf ("Can not open file for reading\n"); + exit (1); + } + + if (fgets (templ, 1000, fd) == NULL) + { + printf ("Can not read file\n"); + exit (1); + } + fclose (fd); + + res = getdate (str); + if (res == NULL) + { + printf ("Failed on getdate(\"%s\"), template is: %s", str, templ); + printf ("Error number: %d\n\n", getdate_err); + return 1; + } + printf ("Success on getdate(\"%s\"), template is: %s\n", str, templ); + printf ("Result is\n"); + printf ("Seconds: %d\n", res->tm_sec); + printf ("Minutes: %d\n", res->tm_min); + printf ("Hour: %d\n", res->tm_hour); + printf ("Day of month: %d\n", res->tm_mday); + printf ("Month of year: %d\n", res->tm_mon); + printf ("Years since 1900: %d\n", res->tm_year); + printf ("Day of week: %d\n", res->tm_wday); + printf ("Day of year: %d\n", res->tm_yday); + printf ("Daylight Savings flag: %d\n\n", res->tm_isdst); + return 0; +} + +static int +do_test (int argc, char *argv[]) +{ + + templ_filename = argv[1]; + + setenv ("DATEMSK", templ_filename, 1); + + /* + * The following 4 testcases reproduce the problem: + * 1. Templates "%S" and "%M" are not processed, + * when used without "%H" template + */ + int res = 0; + output_to_template_file ("%M"); + res |= process_getdate_on ("1"); + + output_to_template_file ("%M %H"); + res |= process_getdate_on ("1 2"); + + output_to_template_file ("%S"); + res |= process_getdate_on ("1"); + + output_to_template_file ("%S %H"); + res |= process_getdate_on ("1 2"); + + /* + * The following 9 testcases reproduce the problem: + * 2. Templates "%Y", "%y", "%d", "%C", "%C %y" + * are not processed separately + */ + output_to_template_file ("%Y"); + process_getdate_on ("2001"); + + output_to_template_file ("%Y %m"); + res |= process_getdate_on ("2001 3"); + + output_to_template_file ("%y"); + res |= process_getdate_on ("70"); + + output_to_template_file ("%y %m"); + res |= process_getdate_on ("70 3"); + + output_to_template_file ("%d"); + res |= process_getdate_on ("06"); + + output_to_template_file ("%d %m"); + res |= process_getdate_on ("25 3"); + + output_to_template_file ("%C"); + res |= process_getdate_on ("98"); + + output_to_template_file ("%C %y %m"); + res |= process_getdate_on ("98 3 2"); + + output_to_template_file ("%C %y"); + res |= process_getdate_on ("21 5"); + + /* + * The following testcase reproduces the problem: + * 3. When template is "%Y %m", day of month is not set + * to 1 as standard requires + */ + output_to_template_file ("%Y %m"); + res |= process_getdate_on ("2008 3"); + + return res; +} + +#define PREPARE(argc, argv) \ + if (argc < 2) \ + { \ + puts ("Command line: progname template_filename_full_path"); \ + exit (1); \ + } \ + add_temp_file (argv[1]) + +#define TEST_FUNCTION do_test (argc, argv) +#include "../test-skeleton.c" diff --git a/time/getdate.c b/time/getdate.c index 851efac..cbaa41d 100644 --- a/time/getdate.c +++ b/time/getdate.c @@ -212,28 +212,31 @@ __getdate_r (const char *string, struct tm *tp) tp->tm_sec = tm.tm_sec; } + /* Fill in the gaps. */ + if (tp->tm_hour == INT_MIN) + tp->tm_hour = 0; + if (tp->tm_min == INT_MIN) + tp->tm_min = 0; + if (tp->tm_sec == INT_MIN) + tp->tm_sec = 0; + /* If no date is given, today is assumed if the given hour is greater than the current hour and tomorrow is assumed if it is less. */ if (tp->tm_hour >= 0 && tp->tm_hour <= 23 - && tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN + && tp->tm_mon == INT_MIN && tp->tm_mday == INT_MIN && tp->tm_wday == INT_MIN) { - tp->tm_year = tm.tm_year; tp->tm_mon = tm.tm_mon; tp->tm_mday = tm.tm_mday + ((tp->tm_hour - tm.tm_hour) < 0 ? 1 : 0); mday_ok = 1; } - /* Fill in the gaps. */ + /* More fillers. */ if (tp->tm_year == INT_MIN) tp->tm_year = tm.tm_year; - if (tp->tm_hour == INT_MIN) - tp->tm_hour = 0; - if (tp->tm_min == INT_MIN) - tp->tm_min = 0; - if (tp->tm_sec == INT_MIN) - tp->tm_sec = 0; + if (tp->tm_mon == INT_MIN) + tp->tm_mon = tm.tm_mon; /* Check if the day of month is within range, and if the time can be represented in a time_t. We make use of the fact that the mktime |