diff options
-rw-r--r-- | ChangeLog | 71 | ||||
-rw-r--r-- | io/Makefile | 2 | ||||
-rw-r--r-- | locale/Makefile | 2 | ||||
-rw-r--r-- | posix/Makefile | 4 | ||||
-rw-r--r-- | resolv/Makefile | 2 | ||||
-rw-r--r-- | stdio-common/Makefile | 2 | ||||
-rw-r--r-- | stdio-common/vfscanf.c | 138 | ||||
-rw-r--r-- | sysdeps/generic/Makefile | 7 | ||||
-rw-r--r-- | time/strftime.c | 204 |
9 files changed, 293 insertions, 139 deletions
diff --git a/ChangeLog b/ChangeLog index dcc409cd35..291b2bf400 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,74 @@ +Wed Jan 24 04:18:36 1996 Paul Eggert <eggert@twinsun.com> + + * strftime.c (strftime): + When invoking self, check whether the subsidiary invocation failed. + Use "???" (not "") to denote unknown time zone information. + + Make this source file portable to standalone contexts (e.g. GNU Emacs). + <config.h>: Include if HAVE_CONFIG_H is defined. + (HAVE_LIMITS_H, HAVE_MBLEN, HAVE_TM_ZONE, STDC_HEADERS): New symbols, + defined if _LIBC or if <config.h> defines them. + <ansidecl.h>, "../locale/localeinfo.h": Include only if _LIBC. + <sys/types.h>: New include; some hosts require it for `time_t'. + <ctype.h>: Include only if HAVE_MBLEN (since it's only needed then). + <limits.h>: Include only if HAVE_LIMITS_H. + <stddef.h, stdlib.h, string.h>: Include only if STDC_HEADERS. + (memcpy): Define in terms of bcopy if !STDC_HEADERS. + (__P, PTR): Define if not already defined. + (__tzname, __daylight, __timezone): Remove macros; no longer needed. + (add, strftime): Don't use NULL, for portability to some weird hosts. + (fmt): If !_LIBC, don't assume sprintf returns a count. + (week, strftime): Use old-style function declarations. + (weekday_name, month_name): New constants. + (strftime): Use traditional C values if locale support isn't available. + Use `const' instead of CONST. For time zones, use tm_zone if + possible, then fall back on tzname. Don't check for multibyte + characters unless mblen is supported. Use formats like %02d instead + of %.2d, for portability to older hosts. + +Wed Jan 24 00:07:52 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio-common/vfscanf.c (GROUP, MALLOC): New flag macros. + (__vfscanf): Eliminate flag vars that were redundant with FLAGS bits. + Fix bug in recognition of %ll flag for long long. + Fix overeager checks for conflicting type modifiers. + With ' flag, match thousands separators for decimal numbers. + +Tue Jan 23 22:02:40 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * locale/Makefile (CFLAGS-locfile-lex.c): New variable. + + * resolv/Makefile (CFLAGS): Disable some warnings. + + * sysdeps/generic/Makefile (elided-routines): Removed hypot. + (+gccwarn): Set with override. + + * stdio-common/Makefile (CFLAGS-tst-printf.c): New variable. + + * posix/Makefile (CFLAGS-regex.c): New variable. + + * malloc/Makefile (CFLAGS-obstack.c): New variable. + + * io/Makefile (CFLAGS-fts.c): New variable. + * io/fts.c (fts_open): Use prototypes for COMPAR decl. + +Tue Jan 23 21:35:32 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * sysdeps/mach/hurd/bind.c (bind): Ensure NAME for the AF_LOCAL + case is '\0'-terminated. + +Tue Jan 23 19:49:54 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * elf/rtld.c (dl_main): Support additional args in --list mode for + debugging: look them up as symbol names and print values. + + * misc/getttyent.c (skip, value): Declare with prototypes in file + scope. + + * csu/initfini.c (_init): Explicitly set a variable that is + pointer to volatile with the address of __gmon_start__, to avoid + the test being optimized out. + Mon Jan 22 10:40:40 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * sysdeps/posix/getcwd.c [__GNU_LIBRARY__]: Include unistd.h. diff --git a/io/Makefile b/io/Makefile index cf8d21b24f..564b96a6f4 100644 --- a/io/Makefile +++ b/io/Makefile @@ -48,3 +48,5 @@ others := pwd tests := test-utime include ../Rules + +CFLAGS-fts.c = -Wno-write-strings diff --git a/locale/Makefile b/locale/Makefile index e4fbe290b1..b180b6e672 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -54,3 +54,5 @@ $(objpfx)locale: $(locale-modules:%=$(objpfx)%.o) $(objpfx)localedef $(objpfx)locale: $(lib-modules:%=$(objpfx)%.o) CPPFLAGS += -DLOCALE_PATH='"$(localedir)"' -DCHARMAP_PATH='"$(nlsdir)/charmap"' + +CFLAGS-locfile-lex.c = -Wno-write-strings diff --git a/posix/Makefile b/posix/Makefile index 4760512af6..fef141509d 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -52,6 +52,8 @@ gpl2lgpl := getopt.c getopt1.c getopt.h regex.c regex.h include ../Rules +CFLAGS-regex.c = -Wno-unused -Wno-strict-prototypes + $(objpfx)libposix.a: $(dep-dummy-lib); $(make-dummy-lib) lib: $(objpfx)libposix.a diff --git a/resolv/Makefile b/resolv/Makefile index db90dc7e4b..5bf0d0ce74 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -29,3 +29,5 @@ routines := gethnamaddr getnetbyaddr getnetbyname getnetent getnetnamadr \ res_query res_send sethostent inet_addr include ../Rules + +CFLAGS += -Wno-strict-prototypes -Wno-comment -Wno-write-strings diff --git a/stdio-common/Makefile b/stdio-common/Makefile index d8cd8af749..96a2731b35 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -44,3 +44,5 @@ tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \ include ../Rules + +CFLAGS-tst-printf.c = -Wno-format diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index dd635c9f34..8a799acf78 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -35,13 +35,15 @@ Cambridge, MA 02139, USA. */ #endif /* Those are flags in the conversion format. */ -# define LONG 0x01 /* l: long or double */ -# define LONGDBL 0x02 /* L: long long or long double */ -# define SHORT 0x04 /* h: short */ -# define SUPPRESS 0x08 /* suppress assignment */ -# define POINTER 0x10 /* weird %p pointer (`fake hex') */ -# define NOSKIP 0x20 /* do not skip blanks */ -# define WIDTH 0x40 /* width */ +# define LONG 0x001 /* l: long or double */ +# define LONGDBL 0x002 /* L: long long or long double */ +# define SHORT 0x004 /* h: short */ +# define SUPPRESS 0x008 /* *: suppress assignment */ +# define POINTER 0x010 /* weird %p pointer (`fake hex') */ +# define NOSKIP 0x020 /* do not skip blanks */ +# define WIDTH 0x040 /* width was given */ +# define GROUP 0x080 /* ': group numbers */ +# define MALLOC 0x100 /* a: malloc strings */ #ifdef USE_IN_LIBIO @@ -108,20 +110,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr) register size_t done = 0; /* Assignments done. */ register size_t read_in = 0; /* Chars read in. */ register int c; /* Last char read. */ - register int do_assign; /* Whether to do an assignment. */ register int width; /* Maximum field width. */ - int group_flag; /* %' modifier flag. */ - int flags; /* Trace flags for current format element. */ - - /* Type modifiers. */ - int is_short, is_long, is_long_double; -#ifdef HAVE_LONGLONG - /* We use the `L' modifier for `long long int'. */ -# define is_longlong is_long_double -#else -# define is_longlong 0 -#endif - int malloc_string; /* Args are char ** to be filled in. */ + register int flags; /* Modifiers for current format element. */ + /* Status for reading F-P nums. */ char got_dot, got_e; /* If a [...] is a [^...]. */ @@ -132,6 +123,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) int number_signed; /* Decimal point character. */ wchar_t decimal; + /* The thousands character of the current locale. */ + wchar_t thousands; /* Integral holding variables. */ union { @@ -173,6 +166,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr) if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT), strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0) decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); + /* Figure out the thousands separator character. */ + if (mbtowc (&thousands, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP), + strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0) + thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); c = inchar (); @@ -255,9 +252,6 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Initialize state of modifiers. */ argpos = 0; - do_assign = 1; - group_flag = 0; - is_short = is_long = is_long_double = malloc_string = 0; /* Prepare temporary buffer. */ wpsize = 0; @@ -274,6 +268,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) { /* Oops; that was actually the field width. */ width = argpos; + flags |= WIDTH; argpos = 0; goto got_width; } @@ -284,11 +279,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr) switch (*f++) { case '*': - flags = SUPPRESS; - do_assign = 0; + flags |= SUPPRESS; break; case '\'': - group_flag = 1; + flags |= GROUP; break; } @@ -313,42 +307,36 @@ __vfscanf (FILE *s, const char *format, va_list argptr) { case 'h': /* int's are short int's. */ - if (flags & ~(SUPPRESS | WIDTH)) + if (flags & (LONG|LONGDBL)) /* Signal illegal format element. */ conv_error (); flags |= SHORT; - is_short = 1; break; case 'l': - if (is_long) + if (flags & SHORT) + conv_error (); + else if (flags & LONG) { /* A double `l' is equivalent to an `L'. */ - if ((flags & ~(SUPPRESS | WIDTH))) - conv_error (); flags &= ~LONG; flags |= LONGDBL; - is_longlong = 1; } else - { - /* int's are long int's. */ - flags |= LONG; - is_long = 1; - } + /* int's are long int's. */ + flags |= LONG; break; case 'q': case 'L': /* double's are long double's, and int's are long long int's. */ - if (flags & ~(SUPPRESS | WIDTH)) + if (flags & (LONG|SHORT)) /* Signal illegal format element. */ conv_error (); flags |= LONGDBL; - is_long_double = 1; break; case 'a': /* String conversions (%s, %[) take a `char **' arg and fill it in with a malloc'd pointer. */ - malloc_string = 1; + flags |= MALLOC; break; } @@ -375,12 +363,12 @@ __vfscanf (FILE *s, const char *format, va_list argptr) break; case 'n': /* Answer number of assignments done. */ - if (do_assign) + if (!(flags & SUPPRESS)) *ARG (int *) = read_in - 1; /* Don't count the read-ahead. */ break; case 'c': /* Match characters. */ - if (do_assign) + if (!(flags & SUPPRESS)) { str = ARG (char *); if (str == NULL) @@ -393,7 +381,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) if (width == -1) width = 1; - if (do_assign) + if (!(flags & SUPPRESS)) { do *str++ = c; @@ -402,16 +390,16 @@ __vfscanf (FILE *s, const char *format, va_list argptr) else while (inchar () != EOF && --width > 0); - if (do_assign) + if (!(flags & SUPPRESS)) ++done; break; case 's': /* Read a string. */ #define STRING_ARG \ - if (do_assign) \ + if (!(flags & SUPPRESS)) \ { \ - if (malloc_string) \ + if (flags & MALLOC) \ { \ /* The string is to be stored in a malloc'd buffer. */ \ strptr = ARG (char **); \ @@ -436,10 +424,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr) if (isspace (c)) break; #define STRING_ADD_CHAR(c) \ - if (do_assign) \ + if (!(flags & SUPPRESS)) \ { \ *str++ = c; \ - if (malloc_string && str == *strptr + strsize) \ + if ((flags & MALLOC) && str == *strptr + strsize) \ { \ /* Enlarge the buffer. */ \ str = realloc (*strptr, strsize * 2); \ @@ -474,7 +462,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) STRING_ADD_CHAR (c); } while (inchar () != EOF && (width <= 0 || --width > 0)); - if (do_assign) + if (!(flags & SUPPRESS)) { *str = '\0'; ++done; @@ -550,7 +538,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) while (c != EOF && width != 0) { if (base == 16 ? !isxdigit (c) : - (!isdigit (c) || c - '0' >= base)) + ((!isdigit (c) || c - '0' >= base) && + !((flags & GROUP) && base == 10 && c == thousands))) break; ADDW (c); if (width > 0) @@ -566,32 +555,32 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Convert the number. */ ADDW ('\0'); - if (is_longlong) + if (flags & LONGDBL) { if (number_signed) - num.q = __strtoq_internal (wp, &tw, base, group_flag); + num.q = __strtoq_internal (wp, &tw, base, flags & GROUP); else - num.uq = __strtouq_internal (wp, &tw, base, group_flag); + num.uq = __strtouq_internal (wp, &tw, base, flags & GROUP); } else { if (number_signed) - num.l = __strtol_internal (wp, &tw, base, group_flag); + num.l = __strtol_internal (wp, &tw, base, flags & GROUP); else - num.ul = __strtoul_internal (wp, &tw, base, group_flag); + num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP); } if (wp == tw) conv_error (); - if (do_assign) + if (!(flags & SUPPRESS)) { if (! number_signed) { - if (is_longlong) + if (flags & LONGDBL) *ARG (unsigned LONGLONG int *) = num.uq; - else if (is_long) + else if (flags & LONG) *ARG (unsigned long int *) = num.ul; - else if (is_short) + else if (flags & SHORT) *ARG (unsigned short int *) = (unsigned short int) num.ul; else @@ -599,11 +588,11 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } else { - if (is_longlong) + if (flags & LONGDBL) *ARG (LONGLONG int *) = num.q; - else if (is_long) + else if (flags & LONG) *ARG (long int *) = num.l; - else if (is_short) + else if (flags & SHORT) *ARG (short int *) = (short int) num.l; else *ARG (int *) = (int) num.l; @@ -649,6 +638,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) ADDW (c); got_dot = 1; } + else if ((flags & GROUP) && c == thousands && !got_dot) + ADDW (c); else break; if (width > 0) @@ -663,29 +654,29 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Convert the number. */ ADDW ('\0'); - if (is_long_double) + if (flags & LONGDBL) { - long double d = __strtold_internal (wp, &tw, group_flag); - if (do_assign && tw != wp) + long double d = __strtold_internal (wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) *ARG (long double *) = d; } - else if (is_long) + else if (flags & LONG) { - double d = __strtod_internal (wp, &tw, group_flag); - if (do_assign && tw != wp) + double d = __strtod_internal (wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) *ARG (double *) = d; } else { - float d = __strtof_internal (wp, &tw, group_flag); - if (do_assign && tw != wp) + float d = __strtof_internal (wp, &tw, flags & GROUP); + if (!(flags & SUPPRESS) && tw != wp) *ARG (float *) = d; } if (tw == wp) conv_error (); - if (do_assign) + if (!(flags & SUPPRESS)) ++done; break; @@ -751,7 +742,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) if (read_in == num.ul) conv_error (); - if (do_assign) + if (!(flags & SUPPRESS)) { *str = '\0'; ++done; @@ -761,7 +752,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) case 'p': /* Generic pointer. */ base = 16; /* A PTR must be the same size as a `long int'. */ - is_long = 1; + flags &= ~(SHORT|LONGDBL); + flags |= LONG; number_signed = 0; goto number; } diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile index 9dfc82c928..665d1cc53e 100644 --- a/sysdeps/generic/Makefile +++ b/sysdeps/generic/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -19,10 +19,11 @@ ifeq ($(subdir),math) ifndef math-twiddled -elided-routines := $(elided-routines) acos asin cos sin hypot -sysdep_routines := $(sysdep_routines) sincos asincos exp__E log__L +sysdep_routines += sincos asincos exp__E log__L +elided-routines += acos asin cos sin math-twiddled := t +override +gccwarn := -w endif endif diff --git a/time/strftime.c b/time/strftime.c index c47fc07548..40a7a747cf 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -21,22 +21,57 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <ansidecl.h> -#include "../locale/localeinfo.h" -#include <ctype.h> -#include <limits.h> -#include <stddef.h> +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# define HAVE_MBLEN 1 +# define HAVE_TM_ZONE 1 +# define STDC_HEADERS 1 +# include <ansidecl.h> +# include "../locale/localeinfo.h" +#endif + #include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include <sys/types.h> /* Some systems define `time_t' here. */ #include <time.h> -#ifndef HAVE_GNU_LD -#define __tzname tzname -#define __daylight daylight -#define __timezone timezone +#if HAVE_MBLEN +# include <ctype.h> +#endif + +#if HAVE_LIMITS_H +# include <limits.h> #endif +#if STDC_HEADERS +# include <stddef.h> +# include <stdlib.h> +# include <string.h> +#else +# define memcpy(d, s, n) bcopy (s, d, n) +#endif + +#ifndef __P +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define __P(args) args +#else +#define __P(args) () +#endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef PTR +#ifdef __STDC__ +#define PTR void * +#else +#define PTR char * +#endif +#endif + +static unsigned int week __P((const struct tm *const, int)); + #define add(n, f) \ do \ @@ -45,14 +80,19 @@ Cambridge, MA 02139, USA. */ if (i >= maxsize) \ return 0; \ else \ - if (p != NULL) \ + if (p) \ { \ f; \ p += (n); \ } \ } while (0) #define cpy(n, s) add((n), memcpy((PTR) p, (PTR) (s), (n))) + +#ifdef _LIBC #define fmt(n, args) add((n), if (sprintf args != (n)) return 0) +#else +#define fmt(n, args) add((n), sprintf args; if (strlen (p) != (n)) return 0) +#endif /* Return the week in the year specified by TP, with weeks starting on STARTING_DAY. */ @@ -60,8 +100,9 @@ Cambridge, MA 02139, USA. */ inline #endif static unsigned int -DEFUN(week, (tp, starting_day), - CONST struct tm *CONST tp AND int starting_day) +week (tp, starting_day) + const struct tm *const tp; + int starting_day; { int wday, dl; @@ -78,6 +119,18 @@ DEFUN(week, (tp, starting_day), return dl <= 0 ? 0 : ((dl / 7) + ((dl % 7) == 0 ? 0 : 1)); } +#ifndef _NL_CURRENT +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +#endif /* Write information from TP into S according to the format string FORMAT, writing no more that MAXSIZE characters @@ -86,40 +139,55 @@ DEFUN(week, (tp, starting_day), anywhere, so to determine how many characters would be written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ size_t -DEFUN(strftime, (s, maxsize, format, tp), - char *s AND size_t maxsize AND - CONST char *format AND register CONST struct tm *tp) +strftime (s, maxsize, format, tp) + char *s; + size_t maxsize; + const char *format; + register const struct tm *tp; { - CONST char *CONST a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday); - CONST char *CONST f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); - CONST char *CONST a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); - CONST char *CONST f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); + int hour12 = tp->tm_hour; +#ifdef _NL_CURRENT + const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday); + const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); + const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); + const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); + const char *const ampm = _NL_CURRENT (LC_TIME, + hour12 > 12 ? PM_STR : AM_STR); size_t aw_len = strlen(a_wkday); size_t am_len = strlen(a_month); + size_t ap_len = strlen (ampm); +#else + const char *const f_wkday = weekday_name[tp->tm_wday]; + const char *const f_month = month_name[tp->tm_mon]; + const char *const a_wkday = f_wkday; + const char *const a_month = f_month; + const char *const ampm = "AMPM" + 2 * (hour12 > 12); + size_t aw_len = 3; + size_t am_len = 3; + size_t ap_len = 2; +#endif size_t wkday_len = strlen(f_wkday); size_t month_len = strlen(f_month); - int hour12 = tp->tm_hour; - CONST char *CONST ampm = _NL_CURRENT (LC_TIME, - hour12 > 12 ? PM_STR : AM_STR); - size_t ap_len = strlen (ampm); - CONST unsigned int y_week0 = week (tp, 0); - CONST unsigned int y_week1 = week (tp, 1); - CONST char *zone; + const unsigned int y_week0 = week (tp, 0); + const unsigned int y_week1 = week (tp, 1); + const char *zone; size_t zonelen; register size_t i = 0; register char *p = s; - register CONST char *f; + register const char *f; - if (tp->tm_isdst < 0) - { - zone = ""; - zonelen = 0; - } - else - { - zone = __tzname[tp->tm_isdst]; - zonelen = strlen(zone); - } + zone = 0; +#if HAVE_TM_ZONE + zone = (const char *) tp->tm_zone; +#endif +#if HAVE_TZNAME + if (!(zone && *zone) && tp->tm_isdst >= 0) + zone = tzname[tp->tm_isdst]; +#endif + if (!(zone && *zone)) + zone = "???"; + + zonelen = strlen (zone); if (hour12 > 12) hour12 -= 12; @@ -128,8 +196,9 @@ DEFUN(strftime, (s, maxsize, format, tp), for (f = format; *f != '\0'; ++f) { - CONST char *subfmt; + const char *subfmt; +#if HAVE_MBLEN if (!isascii(*f)) { /* Non-ASCII, may be a multibyte. */ @@ -140,6 +209,7 @@ DEFUN(strftime, (s, maxsize, format, tp), continue; } } +#endif if (*f != '%') { @@ -173,24 +243,36 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'c': +#ifdef _NL_CURRENT subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); +#else + subfmt = "%a %b %d %H:%M:%S %Z %Y"; +#endif subformat: { size_t len = strftime (p, maxsize - i, subfmt, tp); + if (len == 0 && *subfmt) + return 0; add(len, ); } break; case 'C': - fmt (2, (p, "%.2d", (1900 + tp->tm_year) / 100)); + fmt (2, (p, "%02d", (1900 + tp->tm_year) / 100)); break; + case 'x': +#ifdef _NL_CURRENT + subfmt = _NL_CURRENT (LC_TIME, D_FMT); + goto subformat; +#endif + /* Fall through. */ case 'D': /* GNU extension. */ subfmt = "%m/%d/%y"; goto subformat; case 'd': - fmt(2, (p, "%.2d", tp->tm_mday)); + fmt(2, (p, "%02d", tp->tm_mday)); break; case 'e': /* GNU extension: %d, but blank-padded. */ @@ -198,11 +280,11 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'H': - fmt(2, (p, "%.2d", tp->tm_hour)); + fmt(2, (p, "%02d", tp->tm_hour)); break; case 'I': - fmt(2, (p, "%.2d", hour12)); + fmt(2, (p, "%02d", hour12)); break; case 'k': /* GNU extension. */ @@ -214,15 +296,15 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'j': - fmt(3, (p, "%.3d", 1 + tp->tm_yday)); + fmt(3, (p, "%03d", 1 + tp->tm_yday)); break; case 'M': - fmt(2, (p, "%.2d", tp->tm_min)); + fmt(2, (p, "%02d", tp->tm_min)); break; case 'm': - fmt(2, (p, "%.2d", tp->tm_mon + 1)); + fmt(2, (p, "%02d", tp->tm_mon + 1)); break; case 'n': /* GNU extension. */ @@ -242,9 +324,15 @@ DEFUN(strftime, (s, maxsize, format, tp), goto subformat; case 'S': - fmt(2, (p, "%.2d", tp->tm_sec)); + fmt(2, (p, "%02d", tp->tm_sec)); break; + case 'X': +#ifdef _NL_CURRENT + subfmt = _NL_CURRENT (LC_TIME, T_FMT); + goto subformat; +#endif + /* Fall through. */ case 'T': /* GNU extenstion. */ subfmt = "%H:%M:%S"; goto subformat; @@ -254,31 +342,23 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'U': - fmt(2, (p, "%.2u", y_week0)); + fmt(2, (p, "%02u", y_week0)); break; case 'W': - fmt(2, (p, "%.2u", y_week1)); + fmt(2, (p, "%02u", y_week1)); break; case 'w': - fmt(2, (p, "%.2d", tp->tm_wday)); + fmt(2, (p, "%02d", tp->tm_wday)); break; - case 'X': - subfmt = _NL_CURRENT (LC_TIME, T_FMT); - goto subformat; - - case 'x': - subfmt = _NL_CURRENT (LC_TIME, D_FMT); - goto subformat; - case 'Y': - fmt(4, (p, "%.4d", 1900 + tp->tm_year)); + fmt(4, (p, "%04d", 1900 + tp->tm_year)); break; case 'y': - fmt(2, (p, "%.2d", tp->tm_year % 100)); + fmt(2, (p, "%02d", tp->tm_year % 100)); break; case 'Z': @@ -291,7 +371,7 @@ DEFUN(strftime, (s, maxsize, format, tp), } } - if (p != NULL) + if (p) *p = '\0'; return i; } |