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 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.
This commit is contained in:
Roland McGrath 1996-01-24 06:03:37 +00:00
parent 8ebd0a71be
commit 0793d3483a
9 changed files with 292 additions and 138 deletions

View File

@ -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> Mon Jan 22 10:40:40 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/posix/getcwd.c [__GNU_LIBRARY__]: Include unistd.h. * sysdeps/posix/getcwd.c [__GNU_LIBRARY__]: Include unistd.h.

View File

@ -48,3 +48,5 @@ others := pwd
tests := test-utime tests := test-utime
include ../Rules include ../Rules
CFLAGS-fts.c = -Wno-write-strings

View File

@ -54,3 +54,5 @@ $(objpfx)locale: $(locale-modules:%=$(objpfx)%.o)
$(objpfx)localedef $(objpfx)locale: $(lib-modules:%=$(objpfx)%.o) $(objpfx)localedef $(objpfx)locale: $(lib-modules:%=$(objpfx)%.o)
CPPFLAGS += -DLOCALE_PATH='"$(localedir)"' -DCHARMAP_PATH='"$(nlsdir)/charmap"' CPPFLAGS += -DLOCALE_PATH='"$(localedir)"' -DCHARMAP_PATH='"$(nlsdir)/charmap"'
CFLAGS-locfile-lex.c = -Wno-write-strings

View File

@ -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. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # 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 include ../Rules
CFLAGS-regex.c = -Wno-unused -Wno-strict-prototypes
$(objpfx)libposix.a: $(dep-dummy-lib); $(make-dummy-lib) $(objpfx)libposix.a: $(dep-dummy-lib); $(make-dummy-lib)
lib: $(objpfx)libposix.a lib: $(objpfx)libposix.a

View File

@ -29,3 +29,5 @@ routines := gethnamaddr getnetbyaddr getnetbyname getnetent getnetnamadr \
res_query res_send sethostent inet_addr res_query res_send sethostent inet_addr
include ../Rules include ../Rules
CFLAGS += -Wno-strict-prototypes -Wno-comment -Wno-write-strings

View File

@ -44,3 +44,5 @@ tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \
include ../Rules include ../Rules
CFLAGS-tst-printf.c = -Wno-format

View File

@ -35,13 +35,15 @@ Cambridge, MA 02139, USA. */
#endif #endif
/* Those are flags in the conversion format. */ /* Those are flags in the conversion format. */
# define LONG 0x01 /* l: long or double */ # define LONG 0x001 /* l: long or double */
# define LONGDBL 0x02 /* L: long long or long double */ # define LONGDBL 0x002 /* L: long long or long double */
# define SHORT 0x04 /* h: short */ # define SHORT 0x004 /* h: short */
# define SUPPRESS 0x08 /* suppress assignment */ # define SUPPRESS 0x008 /* *: suppress assignment */
# define POINTER 0x10 /* weird %p pointer (`fake hex') */ # define POINTER 0x010 /* weird %p pointer (`fake hex') */
# define NOSKIP 0x20 /* do not skip blanks */ # define NOSKIP 0x020 /* do not skip blanks */
# define WIDTH 0x40 /* width */ # define WIDTH 0x040 /* width was given */
# define GROUP 0x080 /* ': group numbers */
# define MALLOC 0x100 /* a: malloc strings */
#ifdef USE_IN_LIBIO #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 done = 0; /* Assignments done. */
register size_t read_in = 0; /* Chars read in. */ register size_t read_in = 0; /* Chars read in. */
register int c; /* Last char read. */ register int c; /* Last char read. */
register int do_assign; /* Whether to do an assignment. */
register int width; /* Maximum field width. */ register int width; /* Maximum field width. */
int group_flag; /* %' modifier flag. */ register int flags; /* Modifiers for current format element. */
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. */
/* Status for reading F-P nums. */ /* Status for reading F-P nums. */
char got_dot, got_e; char got_dot, got_e;
/* If a [...] is a [^...]. */ /* If a [...] is a [^...]. */
@ -132,6 +123,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
int number_signed; int number_signed;
/* Decimal point character. */ /* Decimal point character. */
wchar_t decimal; wchar_t decimal;
/* The thousands character of the current locale. */
wchar_t thousands;
/* Integral holding variables. */ /* Integral holding variables. */
union union
{ {
@ -173,6 +166,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT), if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0) strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); 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 (); c = inchar ();
@ -255,9 +252,6 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
/* Initialize state of modifiers. */ /* Initialize state of modifiers. */
argpos = 0; argpos = 0;
do_assign = 1;
group_flag = 0;
is_short = is_long = is_long_double = malloc_string = 0;
/* Prepare temporary buffer. */ /* Prepare temporary buffer. */
wpsize = 0; wpsize = 0;
@ -274,6 +268,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
{ {
/* Oops; that was actually the field width. */ /* Oops; that was actually the field width. */
width = argpos; width = argpos;
flags |= WIDTH;
argpos = 0; argpos = 0;
goto got_width; goto got_width;
} }
@ -284,11 +279,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
switch (*f++) switch (*f++)
{ {
case '*': case '*':
flags = SUPPRESS; flags |= SUPPRESS;
do_assign = 0;
break; break;
case '\'': case '\'':
group_flag = 1; flags |= GROUP;
break; break;
} }
@ -313,42 +307,36 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
{ {
case 'h': case 'h':
/* int's are short int's. */ /* int's are short int's. */
if (flags & ~(SUPPRESS | WIDTH)) if (flags & (LONG|LONGDBL))
/* Signal illegal format element. */ /* Signal illegal format element. */
conv_error (); conv_error ();
flags |= SHORT; flags |= SHORT;
is_short = 1;
break; break;
case 'l': case 'l':
if (is_long) if (flags & SHORT)
conv_error ();
else if (flags & LONG)
{ {
/* A double `l' is equivalent to an `L'. */ /* A double `l' is equivalent to an `L'. */
if ((flags & ~(SUPPRESS | WIDTH)))
conv_error ();
flags &= ~LONG; flags &= ~LONG;
flags |= LONGDBL; flags |= LONGDBL;
is_longlong = 1;
} }
else else
{ /* int's are long int's. */
/* int's are long int's. */ flags |= LONG;
flags |= LONG;
is_long = 1;
}
break; break;
case 'q': case 'q':
case 'L': case 'L':
/* double's are long double's, and int's are long long int's. */ /* 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. */ /* Signal illegal format element. */
conv_error (); conv_error ();
flags |= LONGDBL; flags |= LONGDBL;
is_long_double = 1;
break; break;
case 'a': case 'a':
/* String conversions (%s, %[) take a `char **' /* String conversions (%s, %[) take a `char **'
arg and fill it in with a malloc'd pointer. */ arg and fill it in with a malloc'd pointer. */
malloc_string = 1; flags |= MALLOC;
break; break;
} }
@ -375,12 +363,12 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
break; break;
case 'n': /* Answer number of assignments done. */ case 'n': /* Answer number of assignments done. */
if (do_assign) if (!(flags & SUPPRESS))
*ARG (int *) = read_in - 1; /* Don't count the read-ahead. */ *ARG (int *) = read_in - 1; /* Don't count the read-ahead. */
break; break;
case 'c': /* Match characters. */ case 'c': /* Match characters. */
if (do_assign) if (!(flags & SUPPRESS))
{ {
str = ARG (char *); str = ARG (char *);
if (str == NULL) if (str == NULL)
@ -393,7 +381,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
if (width == -1) if (width == -1)
width = 1; width = 1;
if (do_assign) if (!(flags & SUPPRESS))
{ {
do do
*str++ = c; *str++ = c;
@ -402,16 +390,16 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
else else
while (inchar () != EOF && --width > 0); while (inchar () != EOF && --width > 0);
if (do_assign) if (!(flags & SUPPRESS))
++done; ++done;
break; break;
case 's': /* Read a string. */ case 's': /* Read a string. */
#define STRING_ARG \ #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. */ \ /* The string is to be stored in a malloc'd buffer. */ \
strptr = ARG (char **); \ strptr = ARG (char **); \
@ -436,10 +424,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
if (isspace (c)) if (isspace (c))
break; break;
#define STRING_ADD_CHAR(c) \ #define STRING_ADD_CHAR(c) \
if (do_assign) \ if (!(flags & SUPPRESS)) \
{ \ { \
*str++ = c; \ *str++ = c; \
if (malloc_string && str == *strptr + strsize) \ if ((flags & MALLOC) && str == *strptr + strsize) \
{ \ { \
/* Enlarge the buffer. */ \ /* Enlarge the buffer. */ \
str = realloc (*strptr, strsize * 2); \ str = realloc (*strptr, strsize * 2); \
@ -474,7 +462,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
STRING_ADD_CHAR (c); STRING_ADD_CHAR (c);
} while (inchar () != EOF && (width <= 0 || --width > 0)); } while (inchar () != EOF && (width <= 0 || --width > 0));
if (do_assign) if (!(flags & SUPPRESS))
{ {
*str = '\0'; *str = '\0';
++done; ++done;
@ -550,7 +538,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
while (c != EOF && width != 0) while (c != EOF && width != 0)
{ {
if (base == 16 ? !isxdigit (c) : if (base == 16 ? !isxdigit (c) :
(!isdigit (c) || c - '0' >= base)) ((!isdigit (c) || c - '0' >= base) &&
!((flags & GROUP) && base == 10 && c == thousands)))
break; break;
ADDW (c); ADDW (c);
if (width > 0) if (width > 0)
@ -566,32 +555,32 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
/* Convert the number. */ /* Convert the number. */
ADDW ('\0'); ADDW ('\0');
if (is_longlong) if (flags & LONGDBL)
{ {
if (number_signed) if (number_signed)
num.q = __strtoq_internal (wp, &tw, base, group_flag); num.q = __strtoq_internal (wp, &tw, base, flags & GROUP);
else else
num.uq = __strtouq_internal (wp, &tw, base, group_flag); num.uq = __strtouq_internal (wp, &tw, base, flags & GROUP);
} }
else else
{ {
if (number_signed) if (number_signed)
num.l = __strtol_internal (wp, &tw, base, group_flag); num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
else else
num.ul = __strtoul_internal (wp, &tw, base, group_flag); num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
} }
if (wp == tw) if (wp == tw)
conv_error (); conv_error ();
if (do_assign) if (!(flags & SUPPRESS))
{ {
if (! number_signed) if (! number_signed)
{ {
if (is_longlong) if (flags & LONGDBL)
*ARG (unsigned LONGLONG int *) = num.uq; *ARG (unsigned LONGLONG int *) = num.uq;
else if (is_long) else if (flags & LONG)
*ARG (unsigned long int *) = num.ul; *ARG (unsigned long int *) = num.ul;
else if (is_short) else if (flags & SHORT)
*ARG (unsigned short int *) *ARG (unsigned short int *)
= (unsigned short int) num.ul; = (unsigned short int) num.ul;
else else
@ -599,11 +588,11 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
} }
else else
{ {
if (is_longlong) if (flags & LONGDBL)
*ARG (LONGLONG int *) = num.q; *ARG (LONGLONG int *) = num.q;
else if (is_long) else if (flags & LONG)
*ARG (long int *) = num.l; *ARG (long int *) = num.l;
else if (is_short) else if (flags & SHORT)
*ARG (short int *) = (short int) num.l; *ARG (short int *) = (short int) num.l;
else else
*ARG (int *) = (int) num.l; *ARG (int *) = (int) num.l;
@ -649,6 +638,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
ADDW (c); ADDW (c);
got_dot = 1; got_dot = 1;
} }
else if ((flags & GROUP) && c == thousands && !got_dot)
ADDW (c);
else else
break; break;
if (width > 0) if (width > 0)
@ -663,29 +654,29 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
/* Convert the number. */ /* Convert the number. */
ADDW ('\0'); ADDW ('\0');
if (is_long_double) if (flags & LONGDBL)
{ {
long double d = __strtold_internal (wp, &tw, group_flag); long double d = __strtold_internal (wp, &tw, flags & GROUP);
if (do_assign && tw != wp) if (!(flags & SUPPRESS) && tw != wp)
*ARG (long double *) = d; *ARG (long double *) = d;
} }
else if (is_long) else if (flags & LONG)
{ {
double d = __strtod_internal (wp, &tw, group_flag); double d = __strtod_internal (wp, &tw, flags & GROUP);
if (do_assign && tw != wp) if (!(flags & SUPPRESS) && tw != wp)
*ARG (double *) = d; *ARG (double *) = d;
} }
else else
{ {
float d = __strtof_internal (wp, &tw, group_flag); float d = __strtof_internal (wp, &tw, flags & GROUP);
if (do_assign && tw != wp) if (!(flags & SUPPRESS) && tw != wp)
*ARG (float *) = d; *ARG (float *) = d;
} }
if (tw == wp) if (tw == wp)
conv_error (); conv_error ();
if (do_assign) if (!(flags & SUPPRESS))
++done; ++done;
break; break;
@ -751,7 +742,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
if (read_in == num.ul) if (read_in == num.ul)
conv_error (); conv_error ();
if (do_assign) if (!(flags & SUPPRESS))
{ {
*str = '\0'; *str = '\0';
++done; ++done;
@ -761,7 +752,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
case 'p': /* Generic pointer. */ case 'p': /* Generic pointer. */
base = 16; base = 16;
/* A PTR must be the same size as a `long int'. */ /* A PTR must be the same size as a `long int'. */
is_long = 1; flags &= ~(SHORT|LONGDBL);
flags |= LONG;
number_signed = 0; number_signed = 0;
goto number; goto number;
} }

View File

@ -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. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -19,10 +19,11 @@
ifeq ($(subdir),math) ifeq ($(subdir),math)
ifndef math-twiddled ifndef math-twiddled
elided-routines := $(elided-routines) acos asin cos sin hypot sysdep_routines += sincos asincos exp__E log__L
sysdep_routines := $(sysdep_routines) sincos asincos exp__E log__L elided-routines += acos asin cos sin
math-twiddled := t math-twiddled := t
override +gccwarn := -w
endif endif
endif endif

View File

@ -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, not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */ Cambridge, MA 02139, USA. */
#include <ansidecl.h> #ifdef HAVE_CONFIG_H
#include "../locale/localeinfo.h" # include <config.h>
#include <ctype.h> #endif
#include <limits.h>
#include <stddef.h> #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 <stdio.h>
#include <stdlib.h> #include <sys/types.h> /* Some systems define `time_t' here. */
#include <string.h>
#include <time.h> #include <time.h>
#ifndef HAVE_GNU_LD #if HAVE_MBLEN
#define __tzname tzname # include <ctype.h>
#define __daylight daylight
#define __timezone timezone
#endif #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) \ #define add(n, f) \
do \ do \
@ -45,14 +80,19 @@ Cambridge, MA 02139, USA. */
if (i >= maxsize) \ if (i >= maxsize) \
return 0; \ return 0; \
else \ else \
if (p != NULL) \ if (p) \
{ \ { \
f; \ f; \
p += (n); \ p += (n); \
} \ } \
} while (0) } while (0)
#define cpy(n, s) add((n), memcpy((PTR) p, (PTR) (s), (n))) #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) #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, /* Return the week in the year specified by TP,
with weeks starting on STARTING_DAY. */ with weeks starting on STARTING_DAY. */
@ -60,8 +100,9 @@ Cambridge, MA 02139, USA. */
inline inline
#endif #endif
static unsigned int static unsigned int
DEFUN(week, (tp, starting_day), week (tp, starting_day)
CONST struct tm *CONST tp AND int starting_day) const struct tm *const tp;
int starting_day;
{ {
int wday, dl; int wday, dl;
@ -78,6 +119,18 @@ DEFUN(week, (tp, starting_day),
return dl <= 0 ? 0 : ((dl / 7) + ((dl % 7) == 0 ? 0 : 1)); 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 /* Write information from TP into S according to the format
string FORMAT, writing no more that MAXSIZE characters 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 anywhere, so to determine how many characters would be
written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
size_t size_t
DEFUN(strftime, (s, maxsize, format, tp), strftime (s, maxsize, format, tp)
char *s AND size_t maxsize AND char *s;
CONST char *format AND register CONST struct tm *tp) 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); int hour12 = tp->tm_hour;
CONST char *CONST f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); #ifdef _NL_CURRENT
CONST char *CONST a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
CONST char *CONST f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); 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 aw_len = strlen(a_wkday);
size_t am_len = strlen(a_month); 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 wkday_len = strlen(f_wkday);
size_t month_len = strlen(f_month); size_t month_len = strlen(f_month);
int hour12 = tp->tm_hour; const unsigned int y_week0 = week (tp, 0);
CONST char *CONST ampm = _NL_CURRENT (LC_TIME, const unsigned int y_week1 = week (tp, 1);
hour12 > 12 ? PM_STR : AM_STR); const char *zone;
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;
size_t zonelen; size_t zonelen;
register size_t i = 0; register size_t i = 0;
register char *p = s; register char *p = s;
register CONST char *f; register const char *f;
if (tp->tm_isdst < 0) zone = 0;
{ #if HAVE_TM_ZONE
zone = ""; zone = (const char *) tp->tm_zone;
zonelen = 0; #endif
} #if HAVE_TZNAME
else if (!(zone && *zone) && tp->tm_isdst >= 0)
{ zone = tzname[tp->tm_isdst];
zone = __tzname[tp->tm_isdst]; #endif
zonelen = strlen(zone); if (!(zone && *zone))
} zone = "???";
zonelen = strlen (zone);
if (hour12 > 12) if (hour12 > 12)
hour12 -= 12; hour12 -= 12;
@ -128,8 +196,9 @@ DEFUN(strftime, (s, maxsize, format, tp),
for (f = format; *f != '\0'; ++f) for (f = format; *f != '\0'; ++f)
{ {
CONST char *subfmt; const char *subfmt;
#if HAVE_MBLEN
if (!isascii(*f)) if (!isascii(*f))
{ {
/* Non-ASCII, may be a multibyte. */ /* Non-ASCII, may be a multibyte. */
@ -140,6 +209,7 @@ DEFUN(strftime, (s, maxsize, format, tp),
continue; continue;
} }
} }
#endif
if (*f != '%') if (*f != '%')
{ {
@ -173,24 +243,36 @@ DEFUN(strftime, (s, maxsize, format, tp),
break; break;
case 'c': case 'c':
#ifdef _NL_CURRENT
subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
#else
subfmt = "%a %b %d %H:%M:%S %Z %Y";
#endif
subformat: subformat:
{ {
size_t len = strftime (p, maxsize - i, subfmt, tp); size_t len = strftime (p, maxsize - i, subfmt, tp);
if (len == 0 && *subfmt)
return 0;
add(len, ); add(len, );
} }
break; break;
case 'C': case 'C':
fmt (2, (p, "%.2d", (1900 + tp->tm_year) / 100)); fmt (2, (p, "%02d", (1900 + tp->tm_year) / 100));
break; break;
case 'x':
#ifdef _NL_CURRENT
subfmt = _NL_CURRENT (LC_TIME, D_FMT);
goto subformat;
#endif
/* Fall through. */
case 'D': /* GNU extension. */ case 'D': /* GNU extension. */
subfmt = "%m/%d/%y"; subfmt = "%m/%d/%y";
goto subformat; goto subformat;
case 'd': case 'd':
fmt(2, (p, "%.2d", tp->tm_mday)); fmt(2, (p, "%02d", tp->tm_mday));
break; break;
case 'e': /* GNU extension: %d, but blank-padded. */ case 'e': /* GNU extension: %d, but blank-padded. */
@ -198,11 +280,11 @@ DEFUN(strftime, (s, maxsize, format, tp),
break; break;
case 'H': case 'H':
fmt(2, (p, "%.2d", tp->tm_hour)); fmt(2, (p, "%02d", tp->tm_hour));
break; break;
case 'I': case 'I':
fmt(2, (p, "%.2d", hour12)); fmt(2, (p, "%02d", hour12));
break; break;
case 'k': /* GNU extension. */ case 'k': /* GNU extension. */
@ -214,15 +296,15 @@ DEFUN(strftime, (s, maxsize, format, tp),
break; break;
case 'j': case 'j':
fmt(3, (p, "%.3d", 1 + tp->tm_yday)); fmt(3, (p, "%03d", 1 + tp->tm_yday));
break; break;
case 'M': case 'M':
fmt(2, (p, "%.2d", tp->tm_min)); fmt(2, (p, "%02d", tp->tm_min));
break; break;
case 'm': case 'm':
fmt(2, (p, "%.2d", tp->tm_mon + 1)); fmt(2, (p, "%02d", tp->tm_mon + 1));
break; break;
case 'n': /* GNU extension. */ case 'n': /* GNU extension. */
@ -242,9 +324,15 @@ DEFUN(strftime, (s, maxsize, format, tp),
goto subformat; goto subformat;
case 'S': case 'S':
fmt(2, (p, "%.2d", tp->tm_sec)); fmt(2, (p, "%02d", tp->tm_sec));
break; break;
case 'X':
#ifdef _NL_CURRENT
subfmt = _NL_CURRENT (LC_TIME, T_FMT);
goto subformat;
#endif
/* Fall through. */
case 'T': /* GNU extenstion. */ case 'T': /* GNU extenstion. */
subfmt = "%H:%M:%S"; subfmt = "%H:%M:%S";
goto subformat; goto subformat;
@ -254,31 +342,23 @@ DEFUN(strftime, (s, maxsize, format, tp),
break; break;
case 'U': case 'U':
fmt(2, (p, "%.2u", y_week0)); fmt(2, (p, "%02u", y_week0));
break; break;
case 'W': case 'W':
fmt(2, (p, "%.2u", y_week1)); fmt(2, (p, "%02u", y_week1));
break; break;
case 'w': case 'w':
fmt(2, (p, "%.2d", tp->tm_wday)); fmt(2, (p, "%02d", tp->tm_wday));
break; 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': case 'Y':
fmt(4, (p, "%.4d", 1900 + tp->tm_year)); fmt(4, (p, "%04d", 1900 + tp->tm_year));
break; break;
case 'y': case 'y':
fmt(2, (p, "%.2d", tp->tm_year % 100)); fmt(2, (p, "%02d", tp->tm_year % 100));
break; break;
case 'Z': case 'Z':
@ -291,7 +371,7 @@ DEFUN(strftime, (s, maxsize, format, tp),
} }
} }
if (p != NULL) if (p)
*p = '\0'; *p = '\0';
return i; return i;
} }