2007-07-10  Ulrich Drepper  <drepper@redhat.com>
	[BZ #4773]
	* time/strptime_l.c (__strptime_internal): Implement greedy
	matching of weekday and month names.
This commit is contained in:
Ulrich Drepper 2007-07-10 22:14:12 +00:00
parent 9ffe4385a8
commit f98c2d06bb
4 changed files with 82 additions and 30 deletions

View File

@ -1,3 +1,9 @@
2007-07-10 Ulrich Drepper <drepper@redhat.com>
[BZ #4773]
* time/strptime_l.c (__strptime_internal): Implement greedy
matching of weekday and month names.
2007-07-09 Roland McGrath <roland@redhat.com> 2007-07-09 Roland McGrath <roland@redhat.com>
* elf/elf.h (NT_GNU_ABI_TAG): New macro. * elf/elf.h (NT_GNU_ABI_TAG): New macro.

View File

@ -1,3 +1,9 @@
2007-07-10 Ulrich Drepper <drepper@redhat.com>
[BZ #4773]
* Makefile: Add rules to build and run tst-strptime.
* tst-strptime.c: New file.
2007-05-07 Ulrich Drepper <drepper@redhat.com> 2007-05-07 Ulrich Drepper <drepper@redhat.com>
* locales/as_IN: Fix currency_symbol, abday for Sunday, abmon for * locales/as_IN: Fix currency_symbol, abday for Sunday, abmon for

View File

@ -93,7 +93,7 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \
tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
tst-strfmon1 tst-sscanf tst-strfmon1 tst-sscanf tst-strptime
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
ifneq (no,$(PERL)) ifneq (no,$(PERL))
tests: $(objpfx)mtrace-tst-leaks tests: $(objpfx)mtrace-tst-leaks
@ -284,6 +284,7 @@ tst-mbswcs6-ENV = $(TEST_MBWC_ENV)
tst-xlocale1-ENV = $(TEST_MBWC_ENV) tst-xlocale1-ENV = $(TEST_MBWC_ENV)
tst-xlocale2-ENV = $(TEST_MBWC_ENV) tst-xlocale2-ENV = $(TEST_MBWC_ENV)
tst-strfmon1-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 tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP

View File

@ -264,18 +264,26 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM)
#endif #endif
const char *rp_backup; const char *rp_backup;
const char *rp_longest;
int cnt; int cnt;
int cnt_longest;
size_t val; size_t val;
int have_I, is_pm; int have_I;
int century, want_century; int is_pm;
int century;
int want_century;
int want_era; int want_era;
int have_wday, want_xday; int have_wday;
int want_xday;
int have_yday; int have_yday;
int have_mon, have_mday; int have_mon;
int have_uweek, have_wweek; int have_mday;
int have_uweek;
int have_wweek;
int week_no; int week_no;
size_t num_eras; size_t num_eras;
struct era_entry *era; struct era_entry *era;
enum ptime_locale_status decided_longest;
have_I = is_pm = 0; have_I = is_pm = 0;
century = -1; century = -1;
@ -325,81 +333,112 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM)
case 'a': case 'a':
case 'A': case 'A':
/* Match day of week. */ /* Match day of week. */
rp_longest = NULL;
decided_longest = *decided;
cnt_longest = -1;
for (cnt = 0; cnt < 7; ++cnt) for (cnt = 0; cnt < 7; ++cnt)
{ {
const char *trp;
#ifdef _NL_CURRENT #ifdef _NL_CURRENT
if (*decided !=raw) 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 if (*decided == not
&& strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
weekday_name[cnt])) weekday_name[cnt]))
*decided = loc; decided_longest = loc;
break;
} }
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 if (*decided == not
&& strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
ab_weekday_name[cnt])) ab_weekday_name[cnt]))
*decided = loc; decided_longest = loc;
break;
} }
} }
#endif #endif
if (*decided != loc if (*decided != loc
&& (match_string (weekday_name[cnt], rp) && (((trp = rp, match_string (weekday_name[cnt], trp))
|| match_string (ab_weekday_name[cnt], rp))) && trp > rp_longest)
|| ((trp = rp, match_string (ab_weekday_name[cnt], rp))
&& trp > rp_longest)))
{ {
*decided = raw; rp_longest = trp;
break; cnt_longest = cnt;
decided_longest = raw;
} }
} }
if (cnt == 7) if (rp_longest == NULL)
/* Does not match a weekday name. */ /* Does not match a weekday name. */
return NULL; return NULL;
tm->tm_wday = cnt; rp = rp_longest;
*decided = decided_longest;
tm->tm_wday = cnt_longest;
have_wday = 1; have_wday = 1;
break; break;
case 'b': case 'b':
case 'B': case 'B':
case 'h': case 'h':
/* Match month name. */ /* Match month name. */
rp_longest = NULL;
decided_longest = *decided;
cnt_longest = -1;
for (cnt = 0; cnt < 12; ++cnt) for (cnt = 0; cnt < 12; ++cnt)
{ {
const char *trp;
#ifdef _NL_CURRENT #ifdef _NL_CURRENT
if (*decided !=raw) 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 if (*decided == not
&& strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
month_name[cnt])) month_name[cnt]))
*decided = loc; decided_longest = loc;
break;
} }
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 if (*decided == not
&& strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
ab_month_name[cnt])) ab_month_name[cnt]))
*decided = loc; decided_longest = loc;
break;
} }
} }
#endif #endif
if (match_string (month_name[cnt], rp) if (*decided != loc
|| match_string (ab_month_name[cnt], rp)) && (((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; rp_longest = trp;
break; cnt_longest = cnt;
decided_longest = raw;
} }
} }
if (cnt == 12) if (rp_longest == NULL)
/* Does not match a month name. */ /* Does not match a month name. */
return NULL; return NULL;
tm->tm_mon = cnt; rp = rp_longest;
*decided = decided_longest;
tm->tm_mon = cnt_longest;
have_mon = 1; have_mon = 1;
want_xday = 1; want_xday = 1;
break; break;