1999-07-14  Ulrich Drepper  <drepper@cygnus.com>

	* time/strptime.c (get_number): Handle number parsing more
	consistent with strftime.  Only parse a given number of digits.
	(get_alt_number):  Fix implementation.  Was broken.
	(strptime_internal): Add third parameter to get_number and
	get_alt_number calls.
This commit is contained in:
Ulrich Drepper 1999-07-14 18:20:41 +00:00
parent 3a8599b21c
commit 965e02a290
2 changed files with 77 additions and 50 deletions

View File

@ -1,3 +1,11 @@
1999-07-14 Ulrich Drepper <drepper@cygnus.com>
* time/strptime.c (get_number): Handle number parsing more
consistent with strftime. Only parse a given number of digits.
(get_alt_number): Fix implementation. Was broken.
(strptime_internal): Add third parameter to get_number and
get_alt_number calls.
1999-07-13 Jakub Jelinek <jj@ultra.linux.cz> 1999-07-13 Jakub Jelinek <jj@ultra.linux.cz>
* elf/ldd.bash.in: Add support for multiple dynamic linkers. * elf/ldd.bash.in: Add support for multiple dynamic linkers.

View File

@ -83,8 +83,9 @@ localtime_r (t, tp)
#endif #endif
/* We intentionally do not use isdigit() for testing because this will /* We intentionally do not use isdigit() for testing because this will
lead to problems with the wide character version. */ lead to problems with the wide character version. */
#define get_number(from, to) \ #define get_number(from, to, n) \
do { \ do { \
int __n = n; \
val = 0; \ val = 0; \
while (*rp == ' ') \ while (*rp == ' ') \
++rp; \ ++rp; \
@ -93,42 +94,60 @@ localtime_r (t, tp)
do { \ do { \
val *= 10; \ val *= 10; \
val += *rp++ - '0'; \ val += *rp++ - '0'; \
} while (val * 10 <= to && *rp >= '0' && *rp <= '9'); \ } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \
if (val < from || val > to) \ if (val < from || val > to) \
return NULL; \ return NULL; \
} while (0) } while (0)
#ifdef _NL_CURRENT #ifdef _NL_CURRENT
# define get_alt_number(from, to) \ # define get_alt_number(from, to, n) \
do { \ ({ \
__label__ do_normal; \
if (*decided != raw) \ if (*decided != raw) \
{ \ { \
const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
int __n = n; \
int any = 0; \
while (*rp == ' ') \
++rp; \
val = 0; \ val = 0; \
while (*alts != '\0') \ do { \
{ \ val *= 10; \
size_t len = strlen (alts); \ while (*alts != '\0') \
if (strncasecmp (alts, rp, len) == 0) \ { \
size_t len = strlen (alts); \
if (strncasecmp (alts, rp, len) == 0) \
break; \
alts += len + 1; \
++val; \
} \
if (*alts == '\0') \
{ \
if (*decided == not && ! any) \
goto do_normal; \
/* If we haven't read anything it's an error. */ \
if (! any) \
return NULL; \
/* Correct the premature multiplication. */ \
val /= 10; \
break; \ break; \
alts = strchr (alts, '\0') + 1; \ } \
++val; \ else \
} \
if (*alts == '\0') \
{ \
if (*decided == loc && val != 0) \
return NULL; \
} \
else \
{ \
*decided = loc; \ *decided = loc; \
break; \ } while (--__n > 0 && val * 10 <= to); \
} \ if (val < from || val > to) \
return NULL; \
} \ } \
get_number (from, to); \ else \
} while (0) { \
do_normal: \
get_number (from, to, n); \
} \
0; \
})
#else #else
# define get_alt_number(from, to) \ # define get_alt_number(from, to, n) \
/* We don't have the alternate representation. */ \ /* We don't have the alternate representation. */ \
get_number(from, to) get_number(from, to, n)
#endif #endif
#define recursive(new_fmt) \ #define recursive(new_fmt) \
(*(new_fmt) != '\0' \ (*(new_fmt) != '\0' \
@ -253,7 +272,7 @@ strptime_internal (buf, format, tm, decided)
int have_wday, want_xday; int have_wday, want_xday;
int have_yday; int have_yday;
int have_mon, have_mday; int have_mon, have_mday;
rp = buf; rp = buf;
fmt = format; fmt = format;
have_I = is_pm = 0; have_I = is_pm = 0;
@ -399,14 +418,14 @@ strptime_internal (buf, format, tm, decided)
break; break;
case 'C': case 'C':
/* Match century number. */ /* Match century number. */
get_number (0, 99); get_number (0, 99, 2);
century = val; century = val;
want_xday = 1; want_xday = 1;
break; break;
case 'd': case 'd':
case 'e': case 'e':
/* Match day of month. */ /* Match day of month. */
get_number (1, 31); get_number (1, 31, 2);
tm->tm_mday = val; tm->tm_mday = val;
have_mday = 1; have_mday = 1;
want_xday = 1; want_xday = 1;
@ -446,32 +465,32 @@ strptime_internal (buf, format, tm, decided)
case 'k': case 'k':
case 'H': case 'H':
/* Match hour in 24-hour clock. */ /* Match hour in 24-hour clock. */
get_number (0, 23); get_number (0, 23, 2);
tm->tm_hour = val; tm->tm_hour = val;
have_I = 0; have_I = 0;
break; break;
case 'I': case 'I':
/* Match hour in 12-hour clock. */ /* Match hour in 12-hour clock. */
get_number (1, 12); get_number (1, 12, 2);
tm->tm_hour = val % 12; tm->tm_hour = val % 12;
have_I = 1; have_I = 1;
break; break;
case 'j': case 'j':
/* Match day number of year. */ /* Match day number of year. */
get_number (1, 366); get_number (1, 366, 3);
tm->tm_yday = val - 1; tm->tm_yday = val - 1;
have_yday = 1; have_yday = 1;
break; break;
case 'm': case 'm':
/* Match number of month. */ /* Match number of month. */
get_number (1, 12); get_number (1, 12, 2);
tm->tm_mon = val - 1; tm->tm_mon = val - 1;
have_mon = 1; have_mon = 1;
want_xday = 1; want_xday = 1;
break; break;
case 'M': case 'M':
/* Match minute. */ /* Match minute. */
get_number (0, 59); get_number (0, 59, 2);
tm->tm_min = val; tm->tm_min = val;
break; break;
case 'n': case 'n':
@ -558,7 +577,7 @@ strptime_internal (buf, format, tm, decided)
} }
break; break;
case 'S': case 'S':
get_number (0, 61); get_number (0, 61, 2);
tm->tm_sec = val; tm->tm_sec = val;
break; break;
case 'X': case 'X':
@ -585,12 +604,12 @@ strptime_internal (buf, format, tm, decided)
return NULL; return NULL;
break; break;
case 'u': case 'u':
get_number (1, 7); get_number (1, 7, 1);
tm->tm_wday = val % 7; tm->tm_wday = val % 7;
have_wday = 1; have_wday = 1;
break; break;
case 'g': case 'g':
get_number (0, 99); get_number (0, 99, 2);
/* XXX This cannot determine any field in TM. */ /* XXX This cannot determine any field in TM. */
break; break;
case 'G': case 'G':
@ -605,19 +624,19 @@ strptime_internal (buf, format, tm, decided)
case 'U': case 'U':
case 'V': case 'V':
case 'W': case 'W':
get_number (0, 53); get_number (0, 53, 2);
/* XXX This cannot determine any field in TM without some /* XXX This cannot determine any field in TM without some
information. */ information. */
break; break;
case 'w': case 'w':
/* Match number of weekday. */ /* Match number of weekday. */
get_number (0, 6); get_number (0, 6, 1);
tm->tm_wday = val; tm->tm_wday = val;
have_wday = 1; have_wday = 1;
break; break;
case 'y': case 'y':
/* Match year within century. */ /* Match year within century. */
get_number (0, 99); get_number (0, 99, 2);
/* The "Year 2000: The Millennium Rollover" paper suggests that /* The "Year 2000: The Millennium Rollover" paper suggests that
values in the range 69-99 refer to the twentieth century. */ values in the range 69-99 refer to the twentieth century. */
tm->tm_year = val >= 69 ? val : val + 100; tm->tm_year = val >= 69 ? val : val + 100;
@ -627,7 +646,7 @@ strptime_internal (buf, format, tm, decided)
break; break;
case 'Y': case 'Y':
/* Match year including century number. */ /* Match year including century number. */
get_number (0, 9999); get_number (0, 9999, 4);
tm->tm_year = val - 1900; tm->tm_year = val - 1900;
want_century = 0; want_century = 0;
want_xday = 1; want_xday = 1;
@ -744,7 +763,7 @@ strptime_internal (buf, format, tm, decided)
case 'd': case 'd':
case 'e': case 'e':
/* Match day of month using alternate numeric symbols. */ /* Match day of month using alternate numeric symbols. */
get_alt_number (1, 31); get_alt_number (1, 31, 2);
tm->tm_mday = val; tm->tm_mday = val;
have_mday = 1; have_mday = 1;
want_xday = 1; want_xday = 1;
@ -752,50 +771,50 @@ strptime_internal (buf, format, tm, decided)
case 'H': case 'H':
/* Match hour in 24-hour clock using alternate numeric /* Match hour in 24-hour clock using alternate numeric
symbols. */ symbols. */
get_alt_number (0, 23); get_alt_number (0, 23, 2);
tm->tm_hour = val; tm->tm_hour = val;
have_I = 0; have_I = 0;
break; break;
case 'I': case 'I':
/* Match hour in 12-hour clock using alternate numeric /* Match hour in 12-hour clock using alternate numeric
symbols. */ symbols. */
get_alt_number (1, 12); get_alt_number (1, 12, 2);
tm->tm_hour = val - 1; tm->tm_hour = val - 1;
have_I = 1; have_I = 1;
break; break;
case 'm': case 'm':
/* Match month using alternate numeric symbols. */ /* Match month using alternate numeric symbols. */
get_alt_number (1, 12); get_alt_number (1, 12, 2);
tm->tm_mon = val - 1; tm->tm_mon = val - 1;
have_mon = 1; have_mon = 1;
want_xday = 1; want_xday = 1;
break; break;
case 'M': case 'M':
/* Match minutes using alternate numeric symbols. */ /* Match minutes using alternate numeric symbols. */
get_alt_number (0, 59); get_alt_number (0, 59, 2);
tm->tm_min = val; tm->tm_min = val;
break; break;
case 'S': case 'S':
/* Match seconds using alternate numeric symbols. */ /* Match seconds using alternate numeric symbols. */
get_alt_number (0, 61); get_alt_number (0, 61, 2);
tm->tm_sec = val; tm->tm_sec = val;
break; break;
case 'U': case 'U':
case 'V': case 'V':
case 'W': case 'W':
get_alt_number (0, 53); get_alt_number (0, 53, 2);
/* XXX This cannot determine any field in TM without /* XXX This cannot determine any field in TM without
further information. */ further information. */
break; break;
case 'w': case 'w':
/* Match number of weekday using alternate numeric symbols. */ /* Match number of weekday using alternate numeric symbols. */
get_alt_number (0, 6); get_alt_number (0, 6, 1);
tm->tm_wday = val; tm->tm_wday = val;
have_wday = 1; have_wday = 1;
break; break;
case 'y': case 'y':
/* Match year within century using alternate numeric symbols. */ /* Match year within century using alternate numeric symbols. */
get_alt_number (0, 99); get_alt_number (0, 99, 2);
tm->tm_year = val >= 69 ? val : val + 100; tm->tm_year = val >= 69 ? val : val + 100;
want_xday = 1; want_xday = 1;
break; break;
@ -824,9 +843,9 @@ strptime_internal (buf, format, tm, decided)
tm->tm_mon = t_mon - 1; tm->tm_mon = t_mon - 1;
if (!have_mday) if (!have_mday)
tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1; tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
} }
day_of_the_week (tm); day_of_the_week (tm);
} }
if (want_xday && !have_yday) if (want_xday && !have_yday)
day_of_the_year (tm); day_of_the_year (tm);