From f98c2d06bb4e04e59bb067b301bacf880fb72a9f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 10 Jul 2007 22:14:12 +0000 Subject: [PATCH] [BZ #4773] 2007-07-10 Ulrich Drepper [BZ #4773] * time/strptime_l.c (__strptime_internal): Implement greedy matching of weekday and month names. --- ChangeLog | 6 +++ localedata/ChangeLog | 6 +++ localedata/Makefile | 3 +- time/strptime_l.c | 97 +++++++++++++++++++++++++++++++------------- 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53e7d76d00..f92e76606d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-07-10 Ulrich Drepper + + [BZ #4773] + * time/strptime_l.c (__strptime_internal): Implement greedy + matching of weekday and month names. + 2007-07-09 Roland McGrath * elf/elf.h (NT_GNU_ABI_TAG): New macro. diff --git a/localedata/ChangeLog b/localedata/ChangeLog index 301eabaa04..2aa5560235 100644 --- a/localedata/ChangeLog +++ b/localedata/ChangeLog @@ -1,3 +1,9 @@ +2007-07-10 Ulrich Drepper + + [BZ #4773] + * Makefile: Add rules to build and run tst-strptime. + * tst-strptime.c: New file. + 2007-05-07 Ulrich Drepper * locales/as_IN: Fix currency_symbol, abday for Sunday, abmon for diff --git a/localedata/Makefile b/localedata/Makefile index be80ff8950..0d80a7879a 100644 --- a/localedata/Makefile +++ b/localedata/Makefile @@ -93,7 +93,7 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \ tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ - tst-strfmon1 tst-sscanf + tst-strfmon1 tst-sscanf tst-strptime ifeq (yes,$(build-shared)) ifneq (no,$(PERL)) tests: $(objpfx)mtrace-tst-leaks @@ -284,6 +284,7 @@ tst-mbswcs6-ENV = $(TEST_MBWC_ENV) tst-xlocale1-ENV = $(TEST_MBWC_ENV) tst-xlocale2-ENV = $(TEST_MBWC_ENV) tst-strfmon1-ENV = $(TEST_MBWC_ENV) +tst-strptime-ENV = $(TEST_MBWC_ENV) tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP diff --git a/time/strptime_l.c b/time/strptime_l.c index 443a6fa88e..27b6f9ba86 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -264,18 +264,26 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM) #endif const char *rp_backup; + const char *rp_longest; int cnt; + int cnt_longest; size_t val; - int have_I, is_pm; - int century, want_century; + int have_I; + int is_pm; + int century; + int want_century; int want_era; - int have_wday, want_xday; + int have_wday; + int want_xday; int have_yday; - int have_mon, have_mday; - int have_uweek, have_wweek; + int have_mon; + int have_mday; + int have_uweek; + int have_wweek; int week_no; size_t num_eras; struct era_entry *era; + enum ptime_locale_status decided_longest; have_I = is_pm = 0; century = -1; @@ -325,81 +333,112 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM) case 'a': case 'A': /* Match day of week. */ + rp_longest = NULL; + decided_longest = *decided; + cnt_longest = -1; for (cnt = 0; cnt < 7; ++cnt) { + const char *trp; #ifdef _NL_CURRENT if (*decided !=raw) { - if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) + trp = rp; + if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), trp) + && trp > rp_longest) { + rp_longest = trp; + cnt_longest = cnt; if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), weekday_name[cnt])) - *decided = loc; - break; + decided_longest = loc; } - if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) + trp = rp; + if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), trp) + && trp > rp_longest) { + rp_longest = trp; + cnt_longest = cnt; if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), ab_weekday_name[cnt])) - *decided = loc; - break; + decided_longest = loc; } } #endif if (*decided != loc - && (match_string (weekday_name[cnt], rp) - || match_string (ab_weekday_name[cnt], rp))) + && (((trp = rp, match_string (weekday_name[cnt], trp)) + && trp > rp_longest) + || ((trp = rp, match_string (ab_weekday_name[cnt], rp)) + && trp > rp_longest))) { - *decided = raw; - break; + rp_longest = trp; + cnt_longest = cnt; + decided_longest = raw; } } - if (cnt == 7) + if (rp_longest == NULL) /* Does not match a weekday name. */ return NULL; - tm->tm_wday = cnt; + rp = rp_longest; + *decided = decided_longest; + tm->tm_wday = cnt_longest; have_wday = 1; break; case 'b': case 'B': case 'h': /* Match month name. */ + rp_longest = NULL; + decided_longest = *decided; + cnt_longest = -1; for (cnt = 0; cnt < 12; ++cnt) { + const char *trp; #ifdef _NL_CURRENT if (*decided !=raw) { - if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) + trp = rp; + if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), trp) + && trp > rp_longest) { + rp_longest = trp; + cnt_longest = cnt; if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), month_name[cnt])) - *decided = loc; - break; + decided_longest = loc; } - if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) + trp = rp; + if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), trp) + && trp > rp_longest) { + rp_longest = trp; + cnt_longest = cnt; if (*decided == not && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), ab_month_name[cnt])) - *decided = loc; - break; + decided_longest = loc; } } #endif - if (match_string (month_name[cnt], rp) - || match_string (ab_month_name[cnt], rp)) + if (*decided != loc + && (((trp = rp, match_string (month_name[cnt], trp)) + && trp > rp_longest) + || ((trp = rp, match_string (ab_month_name[cnt], trp)) + && trp > rp_longest))) { - *decided = raw; - break; + rp_longest = trp; + cnt_longest = cnt; + decided_longest = raw; } } - if (cnt == 12) + if (rp_longest == NULL) /* Does not match a month name. */ return NULL; - tm->tm_mon = cnt; + rp = rp_longest; + *decided = decided_longest; + tm->tm_mon = cnt_longest; have_mon = 1; want_xday = 1; break;