X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstrftime.c;h=dea5509b5a02eb274e25b8cbda784d2b39131407;hb=4bbca92c2c28a5528f67ec776c635a2a0009ccbf;hp=95e55cba514ecc79ff87d7bd34c1a0953208bb9a;hpb=cd89762c143f09ac5f7eb00e296472169784b785;p=gnulib.git diff --git a/lib/strftime.c b/lib/strftime.c index 95e55cba5..dea5509b5 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. +/* Copyright (C) 1991-1999, 2000, 2001 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. @@ -98,8 +98,8 @@ extern char *tzname[]; # define L_(Str) L##Str # define NLW(Sym) _NL_W##Sym -# define MEMCPY(d, s, n) wmemcpy (d, s, n) -# define STRLEN(s) wcslen (s) +# define MEMCPY(d, s, n) __wmemcpy (d, s, n) +# define STRLEN(s) __wcslen (s) #else # define CHAR_T char @@ -289,7 +289,7 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */ else if (to_uppcase) \ memcpy_uppcase (p, (s), _n); \ else \ - MEMCPY ((PTR) p, (PTR) (s), _n)) + MEMCPY ((PTR) p, (const PTR) (s), _n)) #ifdef COMPILE_WIDE # define widen(os, ws, l) \ @@ -421,44 +421,52 @@ static CHAR_T const month_name[][10] = #endif -#ifdef emacs -# define my_strftime emacs_strftimeu -# define ut_argument , ut -# define ut_argument_spec int ut; -# define ut_argument_spec_iso , int ut +/* When compiling this file, GNU applications can #define my_strftime + to a symbol (typically nstrftime) to get an extended strftime with + extra arguments UT and NS. Emacs is a special case for now, but + this Emacs-specific code can be removed once Emacs's config.h + defines my_strftime. */ +#if defined emacs && !defined my_strftime +# define my_strftime nstrftime +#endif + +#ifdef my_strftime +# define extra_args , ut, ns +# define extra_args_spec int ut; int ns; +# define extra_args_spec_iso , int ut, int ns #else # ifdef COMPILE_WIDE # define my_strftime wcsftime # else # define my_strftime strftime # endif -# define ut_argument -# define ut_argument_spec -# define ut_argument_spec_iso +# define extra_args +# define extra_args_spec +# define extra_args_spec_iso /* We don't have this information in general. */ # define ut 0 +# define ns 0 #endif #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. Work around this bug by copying *tp before it might be munged. */ size_t _strftime_copytm __P ((char *, size_t, const char *, - const struct tm * ut_argument_spec_iso)); + const struct tm * extra_args_spec_iso)); size_t - my_strftime (s, maxsize, format, tp ut_argument) + my_strftime (s, maxsize, format, tp extra_args) CHAR_T *s; size_t maxsize; const CHAR_T *format; const struct tm *tp; - ut_argument_spec + extra_args_spec { struct tm tmcopy; tmcopy = *tp; - return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument); + return _strftime_copytm (s, maxsize, format, &tmcopy extra_args); } # undef my_strftime -# define my_strftime(S, Maxsize, Format, Tp) \ - _strftime_copytm (S, Maxsize, Format, Tp) +# define my_strftime _strftime_copytm #endif @@ -469,12 +477,12 @@ static CHAR_T const month_name[][10] = anywhere, so to determine how many characters would be written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ size_t -my_strftime (s, maxsize, format, tp ut_argument) +my_strftime (s, maxsize, format, tp extra_args) CHAR_T *s; size_t maxsize; const CHAR_T *format; const struct tm *tp; - ut_argument_spec + extra_args_spec { int hour12 = tp->tm_hour; #ifdef _NL_CURRENT @@ -516,6 +524,9 @@ my_strftime (s, maxsize, format, tp ut_argument) size_t i = 0; CHAR_T *p = s; const CHAR_T *f; +#if DO_MULTIBYTE && !defined COMPILE_WIDE + const char *format_end = NULL; +#endif zone = NULL; #if HAVE_TM_ZONE @@ -608,10 +619,15 @@ my_strftime (s, maxsize, format, tp ut_argument) { mbstate_t mbstate = mbstate_zero; size_t len = 0; + size_t fsize; + + if (! format_end) + format_end = f + strlen (f) + 1; + fsize = format_end - f; do { - size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate); + size_t bytes = mbrlen (f + len, fsize - len, &mbstate); if (bytes == 0) break; @@ -752,6 +768,11 @@ my_strftime (s, maxsize, format, tp ut_argument) case L_('b'): case L_('h'): /* POSIX.2 extension. */ + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } if (modifier != 0) goto bad_format; #if defined _NL_CURRENT || !HAVE_STRFTIME @@ -781,10 +802,11 @@ my_strftime (s, maxsize, format, tp ut_argument) goto bad_format; #ifdef _NL_CURRENT if (! (modifier == 'E' - && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, - NLW(ERA_D_T_FMT))) + && (*(subfmt = + (const CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(ERA_D_T_FMT))) != '\0'))) - subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT)); + subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT)); #else # if HAVE_STRFTIME goto underlying_strftime; @@ -796,8 +818,10 @@ my_strftime (s, maxsize, format, tp ut_argument) subformat: { CHAR_T *old_start = p; - size_t len = my_strftime (NULL, (size_t) -1, subfmt, tp); - add (len, my_strftime (p, maxsize - i, subfmt, tp)); + size_t len = my_strftime (NULL, (size_t) -1, subfmt, + tp extra_args); + add (len, my_strftime (p, maxsize - i, subfmt, + tp extra_args)); if (to_uppcase) while (old_start < p) @@ -817,6 +841,14 @@ my_strftime (s, maxsize, format, tp ut_argument) char *u = ufmt; char ubuf[1024]; /* enough for any single format in practice */ size_t len; + /* Make sure we're calling the actual underlying strftime. + In some cases, config.h contains something like + "#define strftime rpl_strftime". */ +# ifdef strftime +# undef strftime + size_t strftime (); +# endif + *u++ = '%'; if (modifier != 0) *u++ = modifier; @@ -840,7 +872,7 @@ my_strftime (s, maxsize, format, tp ut_argument) if (era) { # ifdef COMPILE_WIDE - size_t len = wcslen (era->era_wname); + size_t len = __wcslen (era->era_wname); cpy (len, era->era_wname); # else size_t len = strlen (era->era_name); @@ -865,10 +897,10 @@ my_strftime (s, maxsize, format, tp ut_argument) goto bad_format; #ifdef _NL_CURRENT if (! (modifier == L_('E') - && (*(subfmt = (CHAR_T *)_NL_CURRENT (LC_TIME, - NLW(ERA_D_FMT))) + && (*(subfmt = + (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT))) != L_('\0')))) - subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT)); + subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT)); goto subformat; #else # if HAVE_STRFTIME @@ -1021,6 +1053,21 @@ my_strftime (s, maxsize, format, tp ut_argument) DO_NUMBER (2, tp->tm_mon + 1); + case L_('N'): /* GNU extension. */ + if (modifier == L_('E')) + goto bad_format; + + number_value = ns; + if (width != -1) + { + /* Take an explicit width less than 9 as a precision. */ + int j; + for (j = width; j < 9; j++) + number_value /= 10; + } + + DO_NUMBER (9, number_value); + case L_('n'): /* POSIX.2 extension. */ add (1, *p = L_('\n')); break; @@ -1045,14 +1092,15 @@ my_strftime (s, maxsize, format, tp ut_argument) goto underlying_strftime; #endif - case L_('R'): /* GNU extension. */ + case L_('R'): /* ISO C99 extension. */ subfmt = L_("%H:%M"); goto subformat; case L_('r'): /* POSIX.2 extension. */ #ifdef _NL_CURRENT - if (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, - NLW(T_FMT_AMPM))) == L_('\0')) + if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(T_FMT_AMPM))) + == L_('\0')) #endif subfmt = L_("%I:%M:%S %p"); goto subformat; @@ -1107,10 +1155,10 @@ my_strftime (s, maxsize, format, tp ut_argument) goto bad_format; #ifdef _NL_CURRENT if (! (modifier == L_('E') - && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, - NLW(ERA_T_FMT))) + && (*(subfmt = + (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT))) != L_('\0')))) - subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT)); + subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT)); goto subformat; #else # if HAVE_STRFTIME @@ -1137,8 +1185,8 @@ my_strftime (s, maxsize, format, tp ut_argument) DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7); case L_('V'): - case L_('g'): /* GNU extension. */ - case L_('G'): /* GNU extension. */ + case L_('g'): /* ISO C99 extension. */ + case L_('G'): /* ISO C99 extension. */ if (modifier == L_('E')) goto bad_format; { @@ -1262,7 +1310,7 @@ my_strftime (s, maxsize, format, tp ut_argument) #endif break; - case L_('z'): /* GNU extension. */ + case L_('z'): /* ISO C99 extension. */ if (tp->tm_isdst < 0) break; @@ -1344,15 +1392,15 @@ my_strftime (s, maxsize, format, tp ut_argument) #ifdef emacs /* For Emacs we have a separate interface which corresponds to the normal - strftime function and does not have the extra information whether the - TP arguments comes from a `gmtime' call or not. */ + strftime function plus the ut argument, but without the ns argument. */ size_t -emacs_strftime (s, maxsize, format, tp) +emacs_strftimeu (s, maxsize, format, tp, ut) char *s; size_t maxsize; const char *format; const struct tm *tp; + int ut; { - return my_strftime (s, maxsize, format, tp, 0); + return my_strftime (s, maxsize, format, tp, ut, 0); } #endif