diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/Makefile | 3 | ||||
-rw-r--r-- | time/strftime_l.c | 11 | ||||
-rw-r--r-- | time/strptime_l.c | 32 | ||||
-rw-r--r-- | time/tst-strptime.c | 12 |
4 files changed, 51 insertions, 7 deletions
diff --git a/time/Makefile b/time/Makefile index 264eed978a..2deb025013 100644 --- a/time/Makefile +++ b/time/Makefile @@ -48,7 +48,8 @@ tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ include ../Rules ifeq ($(run-built-tests),yes) -LOCALES := de_DE.ISO-8859-1 en_US.ISO-8859-1 ja_JP.EUC-JP +LOCALES := de_DE.ISO-8859-1 en_US.ISO-8859-1 ja_JP.EUC-JP fr_FR.UTF-8 \ + pl_PL.UTF-8 include ../gen-locales.mk $(objpfx)tst-ftime_l.out: $(gen-locales) diff --git a/time/strftime_l.c b/time/strftime_l.c index 18651fff0e..ac5d28fbcc 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -492,6 +492,9 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format, # define f_month \ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) +# define f_altmonth \ + ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ + ? "?" : _NL_CURRENT (LC_TIME, NLW(ALTMON_1) + tp->tm_mon))) # define ampm \ ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ ? NLW(PM_STR) : NLW(AM_STR))) @@ -507,6 +510,7 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format, ? "?" : month_name[tp->tm_mon]) # define a_wkday f_wkday # define a_month f_month +# define f_altmonth f_month # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) size_t aw_len = 3; @@ -785,7 +789,7 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format, #endif case L_('B'): - if (modifier != 0) + if (modifier == L_('E')) goto bad_format; if (change_case) { @@ -793,7 +797,10 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format, to_lowcase = 0; } #if defined _NL_CURRENT || !HAVE_STRFTIME - cpy (STRLEN (f_month), f_month); + if (modifier == L_('O')) + cpy (STRLEN (f_altmonth), f_altmonth); + else + cpy (STRLEN (f_month), f_month); break; #else goto underlying_strftime; diff --git a/time/strptime_l.c b/time/strptime_l.c index 7d4758ee5c..39cf38d9a9 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -124,6 +124,8 @@ extern const struct __locale_data _nl_C_LC_TIME attribute_hidden; (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) +# define alt_month_name \ + (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ALTMON_1)].string) # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) @@ -319,10 +321,9 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tmp, while (*fmt >= '0' && *fmt <= '9') ++fmt; -#ifndef _NL_CURRENT - /* We need this for handling the `E' modifier. */ + /* In some cases, modifiers are handled by adjusting state and + then restarting the switch statement below. */ start_over: -#endif /* Make back up of current processing pointer. */ rp_backup = rp; @@ -423,13 +424,32 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tmp, ab_month_name[cnt])) decided_longest = loc; } +#ifdef _LIBC + /* Now check the alt month. */ + trp = rp; + if (match_string (_NL_CURRENT (LC_TIME, ALTMON_1 + cnt), trp) + && trp > rp_longest) + { + rp_longest = trp; + cnt_longest = cnt; + if (s.decided == not + && strcmp (_NL_CURRENT (LC_TIME, ALTMON_1 + cnt), + alt_month_name[cnt])) + decided_longest = loc; + } +#endif } #endif if (s.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))) + && trp > rp_longest) +#ifdef _LIBC + || ((trp = rp, match_string (alt_month_name[cnt], trp)) + && trp > rp_longest) +#endif + )) { rp_longest = trp; cnt_longest = cnt; @@ -1015,6 +1035,10 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tmp, case 'O': switch (*fmt++) { + case 'B': + /* Match month name. Reprocess as plain 'B'. */ + fmt--; + goto start_over; case 'd': case 'e': /* Match day of month using alternate numeric symbols. */ diff --git a/time/tst-strptime.c b/time/tst-strptime.c index 34ad797ba4..62ecb7c804 100644 --- a/time/tst-strptime.c +++ b/time/tst-strptime.c @@ -51,6 +51,18 @@ static const struct 6, 0, 0, 1 }, { "ja_JP.EUC-JP", "2001 20 \xb7\xee", "%Y %U %a", 1, 140, 4, 21 }, { "ja_JP.EUC-JP", "2001 21 \xb7\xee", "%Y %W %a", 1, 140, 4, 21 }, + /* Most of the languages do not need the declension of the month names + and do not distinguish between %B and %OB. */ + { "en_US.ISO-8859-1", "November 17, 2017", "%B %e, %Y", 5, 320, 10, 17 }, + { "de_DE.ISO-8859-1", "18. Nov 2017", "%d. %b %Y", 6, 321, 10, 18 }, + { "fr_FR.UTF-8", "19 novembre 2017", "%d %OB %Y", 0, 322, 10, 19 }, + /* Some languages do need the declension of the month names. */ + { "pl_PL.UTF-8", "21 lis 2017", "%d %b %Y", 2, 324, 10, 21 }, + { "pl_PL.UTF-8", "22 LIS 2017", "%d %B %Y", 3, 325, 10, 22 }, + /* TODO: Use the genitive case here as soon as it is added to localedata. */ + { "pl_PL.UTF-8", "23 listopad 2017", "%d %B %Y", 4, 326, 10, 23 }, + /* The nominative case is incorrect here but it is parseable. */ + { "pl_PL.UTF-8", "24 listopad 2017", "%d %OB %Y", 5, 327, 10, 24 }, }; |