aboutsummaryrefslogtreecommitdiff
path: root/stdio-common/vfscanf.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-03-15 20:33:43 +0000
committerUlrich Drepper <drepper@redhat.com>2004-03-15 20:33:43 +0000
commite3b22ad379f53950da7edf8d63d9f44e4d55d51c (patch)
treea1458a07d60cd962a308870b1603882bc49ad6d8 /stdio-common/vfscanf.c
parent4f514b6bf2bdb23a144bf9c77ad34cde58f8c607 (diff)
downloadglibc-e3b22ad379f53950da7edf8d63d9f44e4d55d51c.tar
glibc-e3b22ad379f53950da7edf8d63d9f44e4d55d51c.tar.gz
glibc-e3b22ad379f53950da7edf8d63d9f44e4d55d51c.tar.bz2
glibc-e3b22ad379f53950da7edf8d63d9f44e4d55d51c.zip
Update.
* stdio-common/vfscanf.c: Simplify error handling macros. Use direct locale access functions.
Diffstat (limited to 'stdio-common/vfscanf.c')
-rw-r--r--stdio-common/vfscanf.c275
1 files changed, 105 insertions, 170 deletions
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index 75e187b765..603940da4c 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2002, 2003, 2004 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
@@ -65,97 +65,91 @@
#define I18N 0x400 /* I: use locale's digits */
-#ifdef USE_IN_LIBIO
-# include <libioP.h>
-# include <libio.h>
+#include <locale/localeinfo.h>
+#include <libioP.h>
+#include <libio.h>
-# undef va_list
-# define va_list _IO_va_list
+#undef va_list
+#define va_list _IO_va_list
-# ifdef COMPILE_WSCANF
-# define ungetc(c, s) ((void) (c == WEOF \
+#ifdef COMPILE_WSCANF
+# define ungetc(c, s) ((void) (c == WEOF \
|| (--read_in, \
INTUSE(_IO_sputbackwc) (s, c))))
-# define ungetc_not_eof(c, s) ((void) (--read_in, \
+# define ungetc_not_eof(c, s) ((void) (--read_in, \
INTUSE(_IO_sputbackwc) (s, c)))
-# define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
+# define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
: ((c = _IO_getwc_unlocked (s)), \
(void) (c != WEOF \
? ++read_in \
: (size_t) (inchar_errno = errno)), c))
-# define MEMCPY(d, s, n) __wmemcpy (d, s, n)
-# define ISSPACE(Ch) iswspace (Ch)
-# define ISDIGIT(Ch) iswdigit (Ch)
-# define ISXDIGIT(Ch) iswxdigit (Ch)
-# define TOLOWER(Ch) towlower (Ch)
-# define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
-# define __strtoll_internal __wcstoll_internal
-# define __strtoull_internal __wcstoull_internal
-# define __strtol_internal __wcstol_internal
-# define __strtoul_internal __wcstoul_internal
-# define __strtold_internal __wcstold_internal
-# define __strtod_internal __wcstod_internal
-# define __strtof_internal __wcstof_internal
-
-# define L_(Str) L##Str
-# define CHAR_T wchar_t
-# define UCHAR_T unsigned int
-# define WINT_T wint_t
-# undef EOF
-# define EOF WEOF
-# else
-# define ungetc(c, s) ((void) ((int) c == EOF \
+# define MEMCPY(d, s, n) __wmemcpy (d, s, n)
+# define ISSPACE(Ch) iswspace (Ch)
+# define ISDIGIT(Ch) iswdigit (Ch)
+# define ISXDIGIT(Ch) iswxdigit (Ch)
+# define TOLOWER(Ch) towlower (Ch)
+# define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
+# define __strtoll_internal __wcstoll_internal
+# define __strtoull_internal __wcstoull_internal
+# define __strtol_internal __wcstol_internal
+# define __strtoul_internal __wcstoul_internal
+# define __strtold_internal __wcstold_internal
+# define __strtod_internal __wcstod_internal
+# define __strtof_internal __wcstof_internal
+
+# define L_(Str) L##Str
+# define CHAR_T wchar_t
+# define UCHAR_T unsigned int
+# define WINT_T wint_t
+# undef EOF
+# define EOF WEOF
+#else
+# define ungetc(c, s) ((void) ((int) c == EOF \
|| (--read_in, \
INTUSE(_IO_sputbackc) (s, (unsigned char) c))))
-# define ungetc_not_eof(c, s) ((void) (--read_in, \
+# define ungetc_not_eof(c, s) ((void) (--read_in, \
INTUSE(_IO_sputbackc) (s, (unsigned char) c)))
-# define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
+# define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
: ((c = _IO_getc_unlocked (s)), \
(void) (c != EOF \
? ++read_in \
: (size_t) (inchar_errno = errno)), c))
-# define MEMCPY(d, s, n) memcpy (d, s, n)
-# define ISSPACE(Ch) isspace (Ch)
-# define ISDIGIT(Ch) isdigit (Ch)
-# define ISXDIGIT(Ch) isxdigit (Ch)
-# define TOLOWER(Ch) tolower (Ch)
-# define ORIENT if (_IO_vtable_offset (s) == 0 \
+# define MEMCPY(d, s, n) memcpy (d, s, n)
+# define ISSPACE(Ch) __isspace_l (Ch, loc)
+# define ISDIGIT(Ch) __isdigit_l (Ch, loc)
+# define ISXDIGIT(Ch) __isxdigit_l (Ch, loc)
+# define TOLOWER(Ch) __tolower_l (Ch, loc)
+# define ORIENT if (_IO_vtable_offset (s) == 0 \
&& _IO_fwide (s, -1) != -1) \
return EOF
-# define L_(Str) Str
-# define CHAR_T char
-# define UCHAR_T unsigned char
-# define WINT_T int
-# endif
+# define L_(Str) Str
+# define CHAR_T char
+# define UCHAR_T unsigned char
+# define WINT_T int
+#endif
-# define encode_error() do { \
- if (errp != NULL) *errp |= 4; \
- _IO_funlockfile (s); \
- __libc_cleanup_end (0); \
+#define encode_error() do { \
+ errval = 4; \
__set_errno (EILSEQ); \
- return done; \
+ goto errout; \
} while (0)
-# define conv_error() do { \
- if (errp != NULL) *errp |= 2; \
- _IO_funlockfile (s); \
- __libc_cleanup_end (0); \
- return done; \
+#define conv_error() do { \
+ errval = 2; \
+ goto errout; \
} while (0)
-# define input_error() do { \
- _IO_funlockfile (s); \
- if (errp != NULL) *errp |= 1; \
- __libc_cleanup_end (0); \
- return done ?: EOF; \
+#define input_error() do { \
+ errval = 1; \
+ if (done == 0) done = EOF; \
+ goto errout; \
} while (0)
-# define memory_error() do { \
- _IO_funlockfile (s); \
+#define memory_error() do { \
__set_errno (ENOMEM); \
- __libc_cleanup_end (0); \
- return EOF; \
+ done = EOF; \
+ goto errout; \
} while (0)
-# define ARGCHECK(s, format) \
+#define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
@@ -171,100 +165,31 @@
return EOF; \
} \
} while (0)
-# define LOCK_STREAM(S) \
+#define LOCK_STREAM(S) \
__libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
_IO_flockfile (S)
-# define UNLOCK_STREAM(S) \
+#define UNLOCK_STREAM(S) \
_IO_funlockfile (S); \
__libc_cleanup_region_end (0)
-#else
-# define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
-# define ungetc_not_eof(c, s) (--read_in, (ungetc) (c, s))
-# define inchar() (c == EOF ? EOF \
- : ((c = getc (s)), (void) (c != EOF && ++read_in), c))
-# define MEMCPY(d, s, n) memcpy (d, s, n)
-# define ISSPACE(Ch) isspace (Ch)
-# define ISDIGIT(Ch) isdigit (Ch)
-# define ISXDIGIT(Ch) isxdigit (Ch)
-# define TOLOWER(Ch) tolower (Ch)
-
-# define L_(Str) Str
-# define CHAR_T char
-# define UCHAR_T unsigned char
-# define WINT_T int
-
-# define encode_error() do { \
- funlockfile (s); \
- __set_errno (EILSEQ); \
- return done; \
- } while (0)
-# define conv_error() do { \
- funlockfile (s); \
- return done; \
- } while (0)
-# define input_error() do { \
- funlockfile (s); \
- return done ?: EOF; \
- } while (0)
-# define memory_error() do { \
- funlockfile (s); \
- __set_errno (ENOMEM); \
- return EOF; \
- } while (0)
-# define ARGCHECK(s, format) \
- do \
- { \
- /* Check file argument for consistence. */ \
- if (!__validfp (s) || !s->__mode.__read) \
- { \
- __set_errno (EBADF); \
- return EOF; \
- } \
- else if (format == NULL) \
- { \
- __set_errno (EINVAL); \
- return EOF; \
- } \
- } while (0)
-#if 1
- /* XXX For now !!! */
-# define flockfile(S) /* nothing */
-# define funlockfile(S) /* nothing */
-# define LOCK_STREAM(S)
-# define UNLOCK_STREAM(S)
-#else
-# define LOCK_STREAM(S) \
- __libc_cleanup_region_start (&__funlockfile, (S)); \
- __flockfile (S)
-# define UNLOCK_STREAM(S) \
- __funlockfile (S); \
- __libc_cleanup_region_end (0)
-#endif
-#endif
/* Read formatted input from S according to the format string
FORMAT, using the argument list in ARG.
Return the number of assignments made, or -1 for an input error. */
-#ifdef USE_IN_LIBIO
-# ifdef COMPILE_WSCANF
+#ifdef COMPILE_WSCANF
int
_IO_vfwscanf (s, format, argptr, errp)
_IO_FILE *s;
const wchar_t *format;
_IO_va_list argptr;
int *errp;
-# else
+#else
int
_IO_vfscanf (s, format, argptr, errp)
_IO_FILE *s;
const char *format;
_IO_va_list argptr;
int *errp;
-# endif
-#else
-int
-__vfscanf (FILE *s, const char *format, va_list argptr)
#endif
{
va_list arg;
@@ -275,6 +200,11 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
register WINT_T c = 0; /* Last char read. */
register int width; /* Maximum field width. */
register int flags; /* Modifiers for current format element. */
+ int errval = 0;
+#ifndef COMPILE_WSCANF
+ __locale_t loc = _NL_CURRENT_LOCALE;
+ struct locale_data *const curctype = loc->__locales[LC_CTYPE];
+#endif
/* Errno of last failed inchar call. */
int inchar_errno = 0;
@@ -353,20 +283,26 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
ARGCHECK (s, format);
- /* Figure out the decimal point character. */
+ {
+#ifndef COMPILE_WSCANF
+ struct locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
+#endif
+
+ /* Figure out the decimal point character. */
#ifdef COMPILE_WSCANF
- decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+ decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
#else
- decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+ decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
#endif
- /* Figure out the thousands separator character. */
+ /* Figure out the thousands separator character. */
#ifdef COMPILE_WSCANF
- thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
+ thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
#else
- thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
- if (*thousands == '\0')
- thousands = NULL;
+ thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
+ if (*thousands == '\0')
+ thousands = NULL;
#endif
+ }
/* Lock the stream. */
LOCK_STREAM (s);
@@ -1237,8 +1173,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
to_level = _NL_CURRENT_WORD (LC_CTYPE,
_NL_CTYPE_INDIGITS_WC_LEN) - 1;
#else
- to_level = _NL_CURRENT_WORD (LC_CTYPE,
- _NL_CTYPE_INDIGITS_MB_LEN) - 1;
+ to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
#endif
/* Read the number into workspace. */
@@ -1266,8 +1201,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
const char *cmpp;
int avail = width > 0 ? width : INT_MAX;
- mbdigits[n] = _NL_CURRENT (LC_CTYPE,
- _NL_CTYPE_INDIGITS0_MB + n);
+ mbdigits[n]
+ = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
for (level = 0; level < from_level; level++)
mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
@@ -2316,33 +2251,31 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
&& (char *) str == *strptr + strsize)
{
/* Enlarge the buffer. */
- str = (char *) realloc (*strptr, 2 * strsize);
+ size_t newsize = 2 * strsize;
+
+ allocagain:
+ str = (char *) realloc (*strptr, newsize);
if (str == NULL)
{
/* Can't allocate that much. Last-ditch
effort. */
- str = (char *) realloc (*strptr, strsize + 1);
- if (str == NULL)
+ if (newsize > strsize + 1)
{
- /* We lose. Oh well. Terminate the
- string and stop converting,
- so at least we don't skip any input. */
- ((char *) (*strptr))[strsize - 1] = '\0';
- ++done;
- conv_error ();
- }
- else
- {
- *strptr = (char *) str;
- str += strsize;
- ++strsize;
+ newsize = strsize + 1;
+ goto allocagain;
}
+ /* We lose. Oh well. Terminate the
+ string and stop converting,
+ so at least we don't skip any input. */
+ ((char *) (*strptr))[strsize - 1] = '\0';
+ ++done;
+ conv_error ();
}
else
{
*strptr = (char *) str;
str += strsize;
- strsize *= 2;
+ strsize = newsize;
}
}
}
@@ -2428,27 +2361,29 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
ungetc (c, s);
}
+ errout:
/* Unlock stream. */
UNLOCK_STREAM (s);
+ if (errp != NULL)
+ *errp |= errval;
+
return done;
}
-#ifdef USE_IN_LIBIO
-# ifdef COMPILE_WSCANF
+#ifdef COMPILE_WSCANF
int
__vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
{
return _IO_vfwscanf (s, format, argptr, NULL);
}
-# else
+#else
int
__vfscanf (FILE *s, const char *format, va_list argptr)
{
return INTUSE(_IO_vfscanf) (s, format, argptr, NULL);
}
libc_hidden_def (__vfscanf)
-# endif
#endif
#ifdef COMPILE_WSCANF