diff options
174 files changed, 8495 insertions, 1921 deletions
@@ -1,5 +1,237 @@ 1999-06-16 Ulrich Drepper <drepper@cygnus.com> + * Versions.def: Add GLIBC_2.2 for libc. + + * iconv/gconv.h: Make header suitable for inclusion in public header + by protecting all names with __. + * iconv/gconv.c: Adapt for symbol name changes. + * iconv/gconv.h: Likewise. + * iconv/gconv_builtin.c: Likewise. + * iconv/gconv_close.c: Likewise. + * iconv/gconv_db.c: Likewise. + * iconv/gconv_dl.c: Likewise. + * iconv/gconv_int.h: Likewise. + * iconv/gconv_open.c: Likewise. + * iconv/gconv_simple.c: Likewise. + * iconv/iconv.c: Likewise. + * iconv/iconv_close.c: Likewise. + * iconv/iconv_open.c: Likewise. + * iconv/loop.c: Likewise. + * iconv/skeleton.c: Likewise. + * iconvdata/8bit-gap.c: Likewise. + * iconvdata/8bit-generic.c: Likewise. + * iconvdata/ansi_x3.110.c: Likewise. + * iconvdata/big5.c: Likewise. + * iconvdata/cns11643.h: Likewise. + * iconvdata/cns11643l1.h: Likewise. + * iconvdata/euc-cn.c: Likewise. + * iconvdata/euc-jp.c: Likewise. + * iconvdata/euc-kr.c: Likewise. + * iconvdata/euc-tw.c: Likewise. + * iconvdata/gb2312.h: Likewise. + * iconvdata/iso-2022-jp.c: Likewise. + * iconvdata/iso-2022-kr.c: Likewise. + * iconvdata/iso646.c: Likewise. + * iconvdata/iso8859-1.c: Likewise. + * iconvdata/iso_6937-2.c: Likewise. + * iconvdata/iso_6937.c: Likewise. + * iconvdata/jis0201.h: Likewise. + * iconvdata/jis0208.h: Likewise. + * iconvdata/jis0212.h: Likewise. + * iconvdata/johab.c: Likewise. + * iconvdata/ksc5601.h: Likewise. + * iconvdata/sjis.c: Likewise. + * iconvdata/t.61.c: Likewise. + * iconvdata/uhc.c: Likewise. + * stdlib/mblen.c: Likewise. + * stdlib/mbtowc.c: Likewise. + * stdlib/wctomb.c: Likewise. + * wcsmbs/btowc.c: Likewise. + * wcsmbs/mbrtowc.c: Likewise. + * wcsmbs/mbsnrtowcs.c: Likewise. + * wcsmbs/mbsrtowcs.c: Likewise. + * wcsmbs/wchar.h: Likewise. + * wcsmbs/wcrtomb.c: Likewise. + * wcsmbs/wcsmbsload.c: Likewise. + * wcsmbs/wcsmbsload.h: Likewise. + * wcsmbs/wcsnrtombs.c: Likewise. + * wcsmbs/wcsrtombs.c: Likewise. + * wcsmbs/wctob.c: Likewise. + + * include/limits.h (MB_LEN_MAX): Increase to 16. + + * sysdeps/generic/_G_config.h: Define _G_fpos_t as struct. Define + _G_iconv_t. + * sysdeps/unix/sysv/linux/_G_config.h: Likewise. + * include/wchar.h: Change mbstate_t to __mbstate_t. + + * libio/Makefile (routines): Add wfiledoalloc, oldiofgetpos, + oldiofgetpos64, oldiofsetpos, oldiofsetpos64, fputwc, fputwc_u, + getwc, getwc_u, getwchar, getwchar_u, iofgetws, iofgetws_u, + iofputws, iofputws_u, iogetwline, iowpadn, ioungetwc, putwc, putwc_u, + putchar, putchar_u, swprintf, vwprintf, wprintf, wscanf, fwscanf, + vwscanf, vswprintf, iovswscanf, swscanf, wgenops, wstrops, wfileops, + and iofwide. + (tests): Add tst_swprintf, tst_wprintf, tst_swscanf, and tst_wscanf. + * libio/Versions: Add _IO_fgetpos, _IO_fgetpos64, _IO_fsetpos, + _IO_fsetpos64, fgetpos, fgetpos64, fgetwc, fgetwc_unlocked, fgetws, + fgetws_unlocked, fputwc, fputwc_unlocked, fputws, fputws_unlocked, + fsetpos, fsetpos64, fwide, fwprintf, fwscanf, getwc, getwc_unlocked, + getwchar, getwchar_unlocked, putwc, putwc_unlocked, putwchar, + putwchar_unlocked, swprintf, swscanf, ungetwc, vfwprintf, vswprintf, + vwprintf, vfwscanf, vswscanf, vwscanf, wprintf, and wscanf to + GLIBC_2.2 for libc. + * libio/libio.h: Define codecvt struct. Define _IO_wide_data. + Extend _IO_file contain pointer to codecvt, widedata and mode. + (_IO_getwc_unlocked): New macro. + (_IO_putwc_unlocked): New macro. + (_IO_fwide): New macro. + * libio/libioP.h: Add new prototypes and adjust existing declarations. + * libio/fileops.c (_IO_new_file_close_it): Reset normal or widedata + buffers based on mode. + (new_do_write): Set _IO_write_end to _IO_buf_end if stream is wide + oriented. + (_IO_new_file_overflow): Don't depend only on _IO_CURRENTLY_PUTTING + flag to be enough to signal unallocated buffer. For wide oriented + stream don't make it linebuffered. Don't use _IO_do_flush, use + _IO_new_do_write directly. + (_IO_new_file_seekoff): Change return value type to _IO_off64_t. + (_IO_file_seek): Likewise. + * libio/genops.c (_IO_least_marker): Make global. + (__underflow): Orient stream if not already done. + (__uflow): Likewise. + (_IO_default_seekpos): Change to type _IO_off64_t. + (_IO_default_seekoff): Likewise. + (_IO_default_seek): Likewise. + (_IO_no_init): New function. Similar to _IO_init but allows to orient + in initialization. + * libio/iolibio.h: Add prototype for _IO_vswprintf. Change _IO_pos_BAD + to use _IO_off64_t. + * libio/ftello.c: Use _IO_off_t. For now abort when use with wide + char stream. + * libio/ftello64.c: Likewise. + * libio/ioftell.c: Likewise. + * libio/iofopncook.c: Likewise. + * libio/ioseekoff.c: Likewise. + * libio/ioseekpos.c: Likewise. + * libio/oldfileops.c: Likewise. + * libio/iofgetpos.c: Store state of conversion if necessary. + * libio/iofgetpos64.c: Likewise. + * libio/iofsetpos.c: Restore conversion state if necessary. + * libio/iofsetpos64.c: Likewise. + * libio/iofdopen.c: Initialize so that stream can be wide oriented. + * libio/iofopen.c: Likewise. + * libio/iofopen64.c: Likewise. + * libio/iopopen.c: Likewise. + * libio/iovdprintf.c: Likewise. + * libio/iovsprintf.c: Likewise. + * libio/iovsscanf.c: Likewise. + * libio/memstream.c: Likewise. + * libio/obprintf.c: Likewise. + * libio/iofputs.c: Orient stream if not already happened. + * libio/iofputs_u.c: Likewise. + * libio/iofwrite.c: Likewise. + * libio/iofwrite_u.c: Likewise. + * libio/ioputs.c: Likewise. + * libio/iosetbuffer.c: Handle not yet oriented stream. + * libio/iosetvbuf.c: Likewise. + * libio/oldstdfiles.c: Adjust FILEBUF_LITERAL call. + * libio/stdfiles.c: Likewise. + * libio/strops.c (_IO_str_overflow): Correctly free buffer after + failed allocation. + (_IO_str_seekoff): Use _IO_off64_t. + * libio/vasprintf.c: Pre-orient stream. + * libio/vsnprintf.c: Likewise. + * libio/fputwc.c: New file. + * libio/fputwc_u.c: New file. + * libio/fwprintf.c: New file. + * libio/fwscanf.c: New file. + * libio/getwc.c: New file. + * libio/getwc_u.c: New file. + * libio/getwchar.c: New file. + * libio/getwchar_u.c: New file. + * libio/iofgetws.c: New file. + * libio/iofgetws_u.c: New file. + * libio/iofputws.c: New file. + * libio/iofputws_u.c: New file. + * libio/iofwide.c: New file. + * libio/iogetwline.c: New file. + * libio/ioungetwc.c: New file. + * libio/iovswscanf.c: New file. + * libio/iowpadn.c: New file. + * libio/oldiofgetpos.c: New file. + * libio/oldiofgetpos64.c: New file. + * libio/oldiofsetpos.c: New file. + * libio/oldiofsetpos64.c: New file. + * libio/putwc.c: New file. + * libio/putwc_u.c: New file. + * libio/putwchar.c: New file. + * libio/putwchar_u.c: New file. + * libio/swprintf.c: New file. + * libio/swscanf.c: New file. + * libio/tst_swprintf.c: New file. + * libio/tst_swscanf.c: New file. + * libio/tst_wprintf.c: New file. + * libio/tst_wscanf.c: New file. + * libio/tst_wscanf.input: New file. + * libio/vswprintf.c: New file. + * libio/vwprintf.c: New file. + * libio/vwscanf.c: New file. + * libio/wfiledoalloc.c: New file. + * libio/wfileops.c: New file. + * libio/wgenops.c: New file. + * libio/wprintf.c: New file. + * libio/wscanf.c: New file. + * libio/wstrops.c: New file. + * stdio-common/Makefile (routines): Add _itowa, itowa-digits, + vfwprintf, and vfwscanf. + * stdio-common/_itoa.c (base_table): Rename to _IO_base_table and + make global. + * stdio-common/_itowa.c: New file. + * stdio-common/_itowa.h: New file. + * stdio-common/itoa-digits.c: Minimal optimization. + * stdio-common/itowa-digits.c: New file. + * stdio-common/printf-parse.h: Allow use in wide character context. + * stdio-common/printf-prs.c: Define ISASCII and MBRLEN. + * stdio-common/printf.h (printf_info): Add wide bit. + * stdio-common/printf_fp.c: Determine from wide bit whether stream + is wide oriented or not. + * stdio-common/printf_size.c: Likewise. + * sysdeps/generic/printf_fphex.c: Likewise. + * stdlib/strfmon.c: Call __printf_fp with wide bit cleared. + * stdio-common/vfprintf.c: Rewrite to allow use in wide character + context. + * stdio-common/vfscand.c: Likewise. + * stdio-common/vfwprintf.c: New file. + * stdio-common/vfwscanf.c: New file. + + * time/Makefile (routines): Add wcsftime. + (tests): Add tst_wcsftime. + * time/Versions: Add wcsftime to GLIBC_2.2 for libc. + * time/strftime.c: Make usable as wcsftime. + * time/wcsftime.c: New file. + * time/tst_wcsftime.c: New file. + + * wcsmbs/Makefile (routines): Add wmempcpy and wcschrnul. + * wcsmbs/Versions: Add wmempcpy and wcschrnul to GLIBC_2.2 for libc. + * wcsmbs/wcschrnul.c: New file. + * wcsmbs/wmemcpy.c: New file. + * wcsmbs/wmemcpy.c: Rename to __wmemcpy and make wmemcpy weak alias. + * wcsmbs/wmemmove.c: Likewise for wmemmove. + + * manual/stdio.texi: Document is_char and wide element if printf_info. + + * manual/time.texi: Document wcsftime. + + * include/wchar.h: Add prototypes for __wmemcpy, __wmempcpy, + __wmemmove, __wcschrnul, and __vfwscanf. + + * locale/langinfo.h: Add new LC_TIME entries for wchar_t data. + * locale/C-time.c: Adapt for above change. + * locale/categories.def: Likewise. + * locale/localeinfo.h: Likewise. + * localedata/Makefile: Don't run tests for now. + * manual/errno.texi: Fix typos. * manual/memory.texi: Likewise. * manual/ctype.texi: Likewise. diff --git a/Versions.def b/Versions.def index 0c46092..1353a08 100644 --- a/Versions.def +++ b/Versions.def @@ -5,6 +5,7 @@ libc { GLIBC_2.0 GLIBC_2.1 GLIBC_2.0 GLIBC_2.1.1 GLIBC_2.1 + GLIBC_2.2 GLIBC_2.1.1 } libcrypt { GLIBC_2.0 diff --git a/iconv/gconv.c b/iconv/gconv.c index 14398e2..828db9d 100644 --- a/iconv/gconv.c +++ b/iconv/gconv.c @@ -27,43 +27,45 @@ int internal_function -__gconv (gconv_t cd, const unsigned char **inbuf, const unsigned char *inbufend, - unsigned char **outbuf, unsigned char *outbufend, size_t *converted) +__gconv (__gconv_t cd, const unsigned char **inbuf, + const unsigned char *inbufend, unsigned char **outbuf, + unsigned char *outbufend, size_t *converted) { - size_t last_step = cd->nsteps - 1; + size_t last_step = cd->__nsteps - 1; int result; - if (cd == (gconv_t) -1L) - return GCONV_ILLEGAL_DESCRIPTOR; + if (cd == (__gconv_t) -1L) + return __GCONV_ILLEGAL_DESCRIPTOR; assert (converted != NULL); *converted = 0; if (inbuf == NULL || *inbuf == NULL) /* We just flush. */ - result = _CALL_DL_FCT (cd->steps->fct, - (cd->steps, cd->data, NULL, NULL, converted, 1)); + result = _CALL_DL_FCT (cd->__steps->__fct, + (cd->__steps, cd->__data, NULL, NULL, + converted, 1)); else { const unsigned char *last_start; assert (outbuf != NULL && *outbuf != NULL); - cd->data[last_step].outbuf = *outbuf; - cd->data[last_step].outbufend = outbufend; + cd->__data[last_step].__outbuf = *outbuf; + cd->__data[last_step].__outbufend = outbufend; do { last_start = *inbuf; - result = _CALL_DL_FCT (cd->steps->fct, - (cd->steps, cd->data, inbuf, inbufend, + result = _CALL_DL_FCT (cd->__steps->__fct, + (cd->__steps, cd->__data, inbuf, inbufend, converted, 0)); } - while (result == GCONV_EMPTY_INPUT && last_start != *inbuf - && *inbuf + cd->steps->min_needed_from <= inbufend); + while (result == __GCONV_EMPTY_INPUT && last_start != *inbuf + && *inbuf + cd->__steps->__min_needed_from <= inbufend); } if (outbuf != NULL && *outbuf != NULL) - *outbuf = cd->data[last_step].outbuf; + *outbuf = cd->__data[last_step].__outbuf; return result; } diff --git a/iconv/gconv.h b/iconv/gconv.h index 4b71ccf..f4a66c6 100644 --- a/iconv/gconv.h +++ b/iconv/gconv.h @@ -24,106 +24,108 @@ #define _GCONV_H 1 #include <features.h> +#define __need_mbstate_t #include <wchar.h> #define __need_size_t #include <stddef.h> /* ISO 10646 value used to signal invalid value. */ -#define UNKNOWN_10646_CHAR ((wchar_t) 0xfffd) +#define __UNKNOWN_10646_CHAR ((wchar_t) 0xfffd) /* Error codes for gconv functions. */ enum { - GCONV_OK = 0, - GCONV_NOCONV, - GCONV_NODB, - GCONV_NOMEM, - - GCONV_EMPTY_INPUT, - GCONV_FULL_OUTPUT, - GCONV_ILLEGAL_INPUT, - GCONV_INCOMPLETE_INPUT, - - GCONV_ILLEGAL_DESCRIPTOR, - GCONV_INTERNAL_ERROR + __GCONV_OK = 0, + __GCONV_NOCONV, + __GCONV_NODB, + __GCONV_NOMEM, + + __GCONV_EMPTY_INPUT, + __GCONV_FULL_OUTPUT, + __GCONV_ILLEGAL_INPUT, + __GCONV_INCOMPLETE_INPUT, + + __GCONV_ILLEGAL_DESCRIPTOR, + __GCONV_INTERNAL_ERROR }; /* Forward declarations. */ -struct gconv_step; -struct gconv_step_data; -struct gconv_loaded_object; +struct __gconv_step; +struct __gconv_step_data; +struct __gconv_loaded_object; /* Type of a conversion function. */ -typedef int (*gconv_fct) __PMT ((struct gconv_step *, - struct gconv_step_data *, - __const unsigned char **, - __const unsigned char *, size_t *, int)); +typedef int (*__gconv_fct) __PMT ((struct __gconv_step *, + struct __gconv_step_data *, + __const unsigned char **, + __const unsigned char *, size_t *, int)); /* Constructor and destructor for local data for conversion step. */ -typedef int (*gconv_init_fct) __PMT ((struct gconv_step *)); -typedef void (*gconv_end_fct) __PMT ((struct gconv_step *)); +typedef int (*__gconv_init_fct) __PMT ((struct __gconv_step *)); +typedef void (*__gconv_end_fct) __PMT ((struct __gconv_step *)); /* Description of a conversion step. */ -struct gconv_step +struct __gconv_step { - struct gconv_loaded_object *shlib_handle; - __const char *modname; + struct __gconv_loaded_object *__shlib_handle; + __const char *__modname; - int counter; + int __counter; - __const char *from_name; - __const char *to_name; + __const char *__from_name; + __const char *__to_name; - gconv_fct fct; - gconv_init_fct init_fct; - gconv_end_fct end_fct; + __gconv_fct __fct; + __gconv_init_fct __init_fct; + __gconv_end_fct __end_fct; /* Information about the number of bytes needed or produced in this step. This helps optimizing the buffer sizes. */ - int min_needed_from; - int max_needed_from; - int min_needed_to; - int max_needed_to; + int __min_needed_from; + int __max_needed_from; + int __min_needed_to; + int __max_needed_to; /* Flag whether this is a stateful encoding or not. */ - int stateful; + int __stateful; - void *data; /* Pointer to step-local data. */ + void *__data; /* Pointer to step-local data. */ }; /* Additional data for steps in use of conversion descriptor. This is allocated by the `init' function. */ -struct gconv_step_data +struct __gconv_step_data { - unsigned char *outbuf; /* Output buffer for this step. */ - unsigned char *outbufend; /* Address of first byte after the output buffer.*/ + unsigned char *__outbuf; /* Output buffer for this step. */ + unsigned char *__outbufend; /* Address of first byte after the output + buffer.*/ /* Is this the last module in the chain. */ - int is_last; + int __is_last; /* Counter for number of invocations of the module function for this descriptor. */ - int invocation_counter; + int __invocation_counter; /* Flag whether this is an internal use of the module (in the mb*towc* and wc*tomb* functions) or regular with iconv(3). */ - int internal_use; + int __internal_use; - mbstate_t *statep; - mbstate_t __state; /* This element should not be used directly by + __mbstate_t *__statep; + __mbstate_t __state; /* This element should not be used directly by any module; always use STATEP! */ }; /* Combine conversion step description with data. */ -typedef struct gconv_info +typedef struct __gconv_info { - size_t nsteps; - struct gconv_step *steps; - struct gconv_step_data data[0]; -} *gconv_t; + size_t __nsteps; + struct __gconv_step *__steps; + struct __gconv_step_data __data[0]; +} *__gconv_t; #endif /* gconv.h */ diff --git a/iconv/gconv_builtin.c b/iconv/gconv_builtin.c index 4f3ca56..ca3ca3e 100644 --- a/iconv/gconv_builtin.c +++ b/iconv/gconv_builtin.c @@ -1,5 +1,5 @@ /* Table for builtin transformation mapping. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -29,9 +29,9 @@ static struct builtin_map { const char *name; - gconv_fct fct; - gconv_init_fct init; - gconv_end_fct end; + __gconv_fct fct; + __gconv_init_fct init; + __gconv_end_fct end; int min_needed_from; int max_needed_from; @@ -43,15 +43,15 @@ static struct builtin_map #define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \ Fct, Init, End, MinF, MaxF, MinT, MaxT) \ { \ - name: Name, \ - fct: Fct, \ - init: Init, \ - end: End, \ + .name = Name, \ + .fct = Fct, \ + .init = Init, \ + .end = End, \ \ - min_needed_from: MinF, \ - max_needed_from: MaxF, \ - min_needed_to: MinT, \ - max_needed_to: MaxT \ + .min_needed_from = MinF, \ + .max_needed_from = MaxF, \ + .min_needed_to = MinT, \ + .max_needed_to = MaxT \ }, #define BUILTIN_ALIAS(From, To) @@ -61,7 +61,7 @@ static struct builtin_map void internal_function -__gconv_get_builtin_trans (const char *name, struct gconv_step *step) +__gconv_get_builtin_trans (const char *name, struct __gconv_step *step) { size_t cnt; @@ -71,17 +71,17 @@ __gconv_get_builtin_trans (const char *name, struct gconv_step *step) assert (cnt < sizeof (map) / sizeof (map[0])); - step->fct = map[cnt].fct; - step->init_fct = map[cnt].init; - step->end_fct = map[cnt].end; - step->counter = INT_MAX; - step->shlib_handle = NULL; + step->__fct = map[cnt].fct; + step->__init_fct = map[cnt].init; + step->__end_fct = map[cnt].end; + step->__counter = INT_MAX; + step->__shlib_handle = NULL; - step->min_needed_from = map[cnt].min_needed_from; - step->max_needed_from = map[cnt].max_needed_from; - step->min_needed_to = map[cnt].min_needed_to; - step->max_needed_to = map[cnt].max_needed_to; + step->__min_needed_from = map[cnt].min_needed_from; + step->__max_needed_from = map[cnt].max_needed_from; + step->__min_needed_to = map[cnt].min_needed_to; + step->__max_needed_to = map[cnt].max_needed_to; /* None of the builtin converters handles stateful encoding. */ - step->stateful = 0; + step->__stateful = 0; } diff --git a/iconv/gconv_close.c b/iconv/gconv_close.c index 2fe8424..a22123b 100644 --- a/iconv/gconv_close.c +++ b/iconv/gconv_close.c @@ -25,23 +25,23 @@ int internal_function -__gconv_close (gconv_t cd) +__gconv_close (__gconv_t cd) { - struct gconv_step *srunp; - struct gconv_step_data *drunp; + struct __gconv_step *srunp; + struct __gconv_step_data *drunp; size_t nsteps; /* Free all resources by calling destructor functions and release the implementations. */ - srunp = cd->steps; - nsteps = cd->nsteps; - drunp = cd->data; + srunp = cd->__steps; + nsteps = cd->__nsteps; + drunp = cd->__data; do { - if (!drunp->is_last && drunp->outbuf != NULL) - free (drunp->outbuf); + if (!drunp->__is_last && drunp->__outbuf != NULL) + free (drunp->__outbuf); } - while (!(drunp++)->is_last); + while (!(drunp++)->__is_last); /* Free the data allocated for the descriptor. */ free (cd); diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c index 4abc1ae..727be41 100644 --- a/iconv/gconv_db.c +++ b/iconv/gconv_db.c @@ -82,7 +82,7 @@ struct known_derivation { const char *from; const char *to; - struct gconv_step *steps; + struct __gconv_step *steps; size_t nsteps; }; @@ -107,7 +107,7 @@ static void *known_derivations; static int internal_function derivation_lookup (const char *fromset, const char *toset, - struct gconv_step **handle, size_t *nsteps) + struct __gconv_step **handle, size_t *nsteps) { struct known_derivation key = { fromset, toset, NULL, 0 }; struct known_derivation **result; @@ -115,21 +115,21 @@ derivation_lookup (const char *fromset, const char *toset, result = __tfind (&key, &known_derivations, derivation_compare); if (result == NULL) - return GCONV_NOCONV; + return __GCONV_NOCONV; *handle = (*result)->steps; *nsteps = (*result)->nsteps; /* Please note that we return GCONV_OK even if the last search for this transformation was unsuccessful. */ - return GCONV_OK; + return __GCONV_OK; } /* Add new derivation to list of known ones. */ static void internal_function add_derivation (const char *fromset, const char *toset, - struct gconv_step *handle, size_t nsteps) + struct __gconv_step *handle, size_t nsteps) { struct known_derivation *new_deriv; size_t fromset_len = strlen (fromset) + 1; @@ -163,14 +163,14 @@ free_derivation (void *p) size_t cnt; for (cnt = 0; cnt < deriv->nsteps; ++cnt) - if (deriv->steps[cnt].end_fct) - _CALL_DL_FCT (deriv->steps[cnt].end_fct, (&deriv->steps[cnt])); + if (deriv->steps[cnt].__end_fct) + _CALL_DL_FCT (deriv->steps[cnt].__end_fct, (&deriv->steps[cnt])); /* Free the name strings. */ - free ((char *) deriv->steps[0].from_name); - free ((char *) deriv->steps[deriv->nsteps - 1].to_name); + free ((char *) deriv->steps[0].__from_name); + free ((char *) deriv->steps[deriv->nsteps - 1].__to_name); - free ((struct gconv_step *) deriv->steps); + free ((struct __gconv_step *) deriv->steps); free (deriv); } @@ -178,40 +178,40 @@ free_derivation (void *p) static int internal_function gen_steps (struct derivation_step *best, const char *toset, - const char *fromset, struct gconv_step **handle, size_t *nsteps) + const char *fromset, struct __gconv_step **handle, size_t *nsteps) { size_t step_cnt = 0; - struct gconv_step *result; + struct __gconv_step *result; struct derivation_step *current; - int status = GCONV_NOMEM; + int status = __GCONV_NOMEM; /* First determine number of steps. */ for (current = best; current->last != NULL; current = current->last) ++step_cnt; - result = (struct gconv_step *) malloc (sizeof (struct gconv_step) - * step_cnt); + result = (struct __gconv_step *) malloc (sizeof (struct __gconv_step) + * step_cnt); if (result != NULL) { int failed = 0; - status = GCONV_OK; + status = __GCONV_OK; *nsteps = step_cnt; current = best; while (step_cnt-- > 0) { - result[step_cnt].from_name = (step_cnt == 0 - ? __strdup (fromset) - : current->last->result_set); - result[step_cnt].to_name = (step_cnt + 1 == *nsteps - ? __strdup (current->result_set) - : result[step_cnt + 1].from_name); + result[step_cnt].__from_name = (step_cnt == 0 + ? __strdup (fromset) + : current->last->result_set); + result[step_cnt].__to_name = (step_cnt + 1 == *nsteps + ? __strdup (current->result_set) + : result[step_cnt + 1].__from_name); #ifndef STATIC_GCONV if (current->code->module_name[0] == '/') { /* Load the module, return handle for it. */ - struct gconv_loaded_object *shlib_handle = + struct __gconv_loaded_object *shlib_handle = __gconv_find_shlib (current->code->module_name); if (shlib_handle == NULL) @@ -220,12 +220,12 @@ gen_steps (struct derivation_step *best, const char *toset, break; } - result[step_cnt].shlib_handle = shlib_handle; - result[step_cnt].modname = shlib_handle->name; - result[step_cnt].counter = 0; - result[step_cnt].fct = shlib_handle->fct; - result[step_cnt].init_fct = shlib_handle->init_fct; - result[step_cnt].end_fct = shlib_handle->end_fct; + result[step_cnt].__shlib_handle = shlib_handle; + result[step_cnt].__modname = shlib_handle->name; + result[step_cnt].__counter = 0; + result[step_cnt].__fct = shlib_handle->fct; + result[step_cnt].__init_fct = shlib_handle->init_fct; + result[step_cnt].__end_fct = shlib_handle->end_fct; } else #endif @@ -234,12 +234,12 @@ gen_steps (struct derivation_step *best, const char *toset, &result[step_cnt]); /* Call the init function. */ - if (result[step_cnt].init_fct != NULL) + if (result[step_cnt].__init_fct != NULL) { - status = _CALL_DL_FCT (result[step_cnt].init_fct, + status = _CALL_DL_FCT (result[step_cnt].__init_fct, (&result[step_cnt])); - if (status != GCONV_OK) + if (status != __GCONV_OK) { failed = 1; /* Make sure we unload this modules. */ @@ -256,17 +256,17 @@ gen_steps (struct derivation_step *best, const char *toset, /* Something went wrong while initializing the modules. */ while (++step_cnt < *nsteps) { - if (result[step_cnt].end_fct != NULL) - _CALL_DL_FCT (result[step_cnt].end_fct, (&result[step_cnt])); + if (result[step_cnt].__end_fct != NULL) + _CALL_DL_FCT (result[step_cnt].__end_fct, (&result[step_cnt])); #ifndef STATIC_GCONV - __gconv_release_shlib (result[step_cnt].shlib_handle); + __gconv_release_shlib (result[step_cnt].__shlib_handle); #endif } free (result); *nsteps = 0; *handle = NULL; - if (status == GCONV_OK) - status = GCONV_NOCONV; + if (status == __GCONV_OK) + status = __GCONV_NOCONV; } else *handle = result; @@ -287,7 +287,7 @@ static int internal_function find_derivation (const char *toset, const char *toset_expand, const char *fromset, const char *fromset_expand, - struct gconv_step **handle, size_t *nsteps) + struct __gconv_step **handle, size_t *nsteps) { __libc_lock_define_initialized (static, lock) struct derivation_step *first, *current, **lastp, *solution = NULL; @@ -297,7 +297,7 @@ find_derivation (const char *toset, const char *toset_expand, result = derivation_lookup (fromset_expand ?: fromset, toset_expand ?: toset, handle, nsteps); - if (result == GCONV_OK) + if (result == __GCONV_OK) return result; __libc_lock_lock (lock); @@ -307,7 +307,7 @@ find_derivation (const char *toset, const char *toset_expand, find it but at the same time another thread looked for this derivation. */ result = derivation_lookup (fromset_expand ?: fromset, toset_expand ?: toset, handle, nsteps); - if (result == GCONV_OK) + if (result == __GCONV_OK) { __libc_lock_unlock (lock); return result; @@ -613,7 +613,7 @@ find_derivation (const char *toset, const char *toset_expand, int internal_function __gconv_find_transform (const char *toset, const char *fromset, - struct gconv_step **handle, size_t *nsteps) + struct __gconv_step **handle, size_t *nsteps) { __libc_once_define (static, once); const char *fromset_expand = NULL; @@ -630,7 +630,7 @@ __gconv_find_transform (const char *toset, const char *fromset, if (__gconv_modules_db == NULL) { __libc_lock_unlock (lock); - return GCONV_NOCONV; + return __GCONV_NOCONV; } /* See whether the names are aliases. */ @@ -653,23 +653,23 @@ __gconv_find_transform (const char *toset, const char *fromset, #ifndef STATIC_GCONV /* Increment the user counter. */ - if (result == GCONV_OK) + if (result == __GCONV_OK) { size_t cnt = *nsteps; - struct gconv_step *steps = *handle; + struct __gconv_step *steps = *handle; while (cnt > 0) - if (steps[--cnt].counter++ == 0) + if (steps[--cnt].__counter++ == 0) { - steps[cnt].shlib_handle = - __gconv_find_shlib (steps[cnt].modname); - if (steps[cnt].shlib_handle == NULL) + steps[cnt].__shlib_handle = + __gconv_find_shlib (steps[cnt].__modname); + if (steps[cnt].__shlib_handle == NULL) { /* Oops, this is the second time we use this module (after unloading) and this time loading failed!? */ while (++cnt < *nsteps) - __gconv_release_shlib (steps[cnt].shlib_handle); - result = GCONV_NOCONV; + __gconv_release_shlib (steps[cnt].__shlib_handle); + result = __GCONV_NOCONV; break; } } @@ -682,8 +682,8 @@ __gconv_find_transform (const char *toset, const char *fromset, /* The following code is necessary since `find_derivation' will return GCONV_OK even when no derivation was found but the same request was processed before. I.e., negative results will also be cached. */ - return (result == GCONV_OK - ? (*handle == NULL ? GCONV_NOCONV : GCONV_OK) + return (result == __GCONV_OK + ? (*handle == NULL ? __GCONV_NOCONV : __GCONV_OK) : result); } @@ -691,22 +691,22 @@ __gconv_find_transform (const char *toset, const char *fromset, /* Release the entries of the modules list. */ int internal_function -__gconv_close_transform (struct gconv_step *steps, size_t nsteps) +__gconv_close_transform (struct __gconv_step *steps, size_t nsteps) { - int result = GCONV_OK; + int result = __GCONV_OK; #ifndef STATIC_GCONV /* Acquire the lock. */ __libc_lock_lock (lock); while (nsteps-- > 0) - if (steps[nsteps].shlib_handle != NULL - && --steps[nsteps].counter == 0) + if (steps[nsteps].__shlib_handle != NULL + && --steps[nsteps].__counter == 0) { - result = __gconv_release_shlib (steps[nsteps].shlib_handle); - if (result != GCONV_OK) + result = __gconv_release_shlib (steps[nsteps].__shlib_handle); + if (result != __GCONV_OK) break; - steps[nsteps].shlib_handle = NULL; + steps[nsteps].__shlib_handle = NULL; } /* Release the lock. */ diff --git a/iconv/gconv_dl.c b/iconv/gconv_dl.c index 52cf9d3..dc90986 100644 --- a/iconv/gconv_dl.c +++ b/iconv/gconv_dl.c @@ -50,10 +50,10 @@ static void *loaded; static int known_compare (const void *p1, const void *p2) { - const struct gconv_loaded_object *s1 = - (const struct gconv_loaded_object *) p1; - const struct gconv_loaded_object *s2 = - (const struct gconv_loaded_object *) p2; + const struct __gconv_loaded_object *s1 = + (const struct __gconv_loaded_object *) p1; + const struct __gconv_loaded_object *s2 = + (const struct __gconv_loaded_object *) p2; return (intptr_t) s1->handle - (intptr_t) s2->handle; } @@ -62,7 +62,7 @@ known_compare (const void *p1, const void *p2) static void do_open (void *a) { - struct gconv_loaded_object *args = (struct gconv_loaded_object *) a; + struct __gconv_loaded_object *args = (struct __gconv_loaded_object *) a; /* Open and relocate the shared object. */ args->handle = _dl_open (args->name, RTLD_LAZY, NULL); } @@ -124,11 +124,11 @@ __gconv_find_func (void *handle, const char *name) /* Open the gconv database if necessary. A non-negative return value means success. */ -struct gconv_loaded_object * +struct __gconv_loaded_object * internal_function __gconv_find_shlib (const char *name) { - struct gconv_loaded_object *found; + struct __gconv_loaded_object *found; void *keyp; /* Search the tree of shared objects previously requested. Data in @@ -144,7 +144,7 @@ __gconv_find_shlib (const char *name) if (keyp == NULL) { /* This name was not known before. */ - found = malloc (sizeof (struct gconv_loaded_object)); + found = malloc (sizeof (struct __gconv_loaded_object)); if (found != NULL) { /* Point the tree node at this new structure. */ @@ -161,7 +161,7 @@ __gconv_find_shlib (const char *name) } } else - found = *(struct gconv_loaded_object **) keyp; + found = *(struct __gconv_loaded_object **) keyp; /* Try to load the shared object if the usage count is 0. This implies that if the shared object is not loadable, the handle is @@ -206,12 +206,12 @@ __gconv_find_shlib (const char *name) /* This is very ugly but the tsearch functions provide no way to pass information to the walker function. So we use a global variable. It is MT safe since we use a lock. */ -static struct gconv_loaded_object *release_handle; +static struct __gconv_loaded_object *release_handle; static void do_release_shlib (const void *nodep, VISIT value, int level) { - struct gconv_loaded_object *obj = *(struct gconv_loaded_object **) nodep; + struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep; if (value != preorder && value != leaf) return; @@ -238,7 +238,7 @@ do_release_shlib (const void *nodep, VISIT value, int level) /* Notify system that a shared object is not longer needed. */ int internal_function -__gconv_release_shlib (struct gconv_loaded_object *handle) +__gconv_release_shlib (struct __gconv_loaded_object *handle) { /* Urgh, this is ugly but we have no other possibility. */ release_handle = handle; @@ -248,7 +248,7 @@ __gconv_release_shlib (struct gconv_loaded_object *handle) if necessary. */ __twalk (loaded, do_release_shlib); - return GCONV_OK; + return __GCONV_OK; } @@ -256,7 +256,7 @@ __gconv_release_shlib (struct gconv_loaded_object *handle) static void do_release_all (void *nodep) { - struct gconv_loaded_object *obj = (struct gconv_loaded_object *) nodep; + struct __gconv_loaded_object *obj = (struct __gconv_loaded_object *) nodep; /* Unload the shared object. We don't use the trick to catch errors since in the case an error is signalled diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 9b00e65..29f495c 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -41,7 +41,7 @@ struct gconv_alias /* Structure describing one loaded shared object. This normally are objects to perform conversation but as a special case the db shared object is also handled. */ -struct gconv_loaded_object +struct __gconv_loaded_object { /* Name of the object. */ const char *name; @@ -54,9 +54,9 @@ struct gconv_loaded_object struct link_map *handle; /* Pointer to the functions the module defines. */ - gconv_fct fct; - gconv_init_fct init_fct; - gconv_end_fct end_fct; + __gconv_fct fct; + __gconv_init_fct init_fct; + __gconv_end_fct end_fct; }; @@ -95,18 +95,18 @@ extern struct gconv_module *__gconv_modules_db; /* Return in *HANDLE decriptor for transformation from FROMSET to TOSET. */ extern int __gconv_open (const char *__toset, const char *__fromset, - gconv_t *__handle) + __gconv_t *__handle) internal_function; /* Free resources associated with transformation descriptor CD. */ -extern int __gconv_close (gconv_t cd) +extern int __gconv_close (__gconv_t cd) internal_function; /* Transform at most *INBYTESLEFT bytes from buffer starting at *INBUF according to rules described by CD and place up to *OUTBYTESLEFT bytes in buffer starting at *OUTBUF. Return number of written characters in *CONVERTED if this pointer is not null. */ -extern int __gconv (gconv_t __cd, const unsigned char **__inbuf, +extern int __gconv (__gconv_t __cd, const unsigned char **__inbuf, const unsigned char *inbufend, unsigned char **__outbuf, unsigned char *outbufend, size_t *converted) internal_function; @@ -114,7 +114,7 @@ extern int __gconv (gconv_t __cd, const unsigned char **__inbuf, /* Return in *HANDLE a pointer to an array with *NSTEPS elements describing the single steps necessary for transformation from FROMSET to TOSET. */ extern int __gconv_find_transform (const char *__toset, const char *__fromset, - struct gconv_step **__handle, + struct __gconv_step **__handle, size_t *__nsteps) internal_function; @@ -126,13 +126,13 @@ extern int __gconv_alias_compare (const void *__p1, const void *__p2); /* Clear reference to transformation step implementations which might cause the code to be unloaded. */ -extern int __gconv_close_transform (struct gconv_step *__steps, +extern int __gconv_close_transform (struct __gconv_step *__steps, size_t __nsteps) internal_function; /* Load shared object named by NAME. If already loaded increment reference count. */ -extern struct gconv_loaded_object *__gconv_find_shlib (const char *__name) +extern struct __gconv_loaded_object *__gconv_find_shlib (const char *__name) internal_function; /* Find function named NAME in shared object referenced by HANDLE. */ @@ -141,12 +141,12 @@ void *__gconv_find_func (void *handle, const char *name) /* Release shared object. If no further reference is available unload the object. */ -extern int __gconv_release_shlib (struct gconv_loaded_object *__handle) +extern int __gconv_release_shlib (struct __gconv_loaded_object *__handle) internal_function; /* Fill STEP with information about builtin module with NAME. */ extern void __gconv_get_builtin_trans (const char *__name, - struct gconv_step *__step) + struct __gconv_step *__step) internal_function; @@ -154,7 +154,8 @@ extern void __gconv_get_builtin_trans (const char *__name, /* Builtin transformations. */ #ifdef _LIBC # define __BUILTIN_TRANS(Name) \ - extern int Name (struct gconv_step *__step, struct gconv_step_data *__data, \ + extern int Name (struct __gconv_step *__step, \ + struct __gconv_step_data *__data, \ const unsigned char **__inbuf, \ const unsigned char *__inbufend, size_t *__written, \ int __do_flush) diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index f3b6dfa..e10abbb 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -26,31 +26,32 @@ int internal_function -__gconv_open (const char *toset, const char *fromset, gconv_t *handle) +__gconv_open (const char *toset, const char *fromset, __gconv_t *handle) { - struct gconv_step *steps; + struct __gconv_step *steps; size_t nsteps; - gconv_t result = NULL; + __gconv_t result = NULL; size_t cnt = 0; int res; res = __gconv_find_transform (toset, fromset, &steps, &nsteps); - if (res == GCONV_OK) + if (res == __GCONV_OK) { /* Allocate room for handle. */ - result = (gconv_t) malloc (sizeof (struct gconv_info) - + nsteps * sizeof (struct gconv_step_data)); + result = (__gconv_t) malloc (sizeof (struct __gconv_info) + + (nsteps + * sizeof (struct __gconv_step_data))); if (result == NULL) - res = GCONV_NOMEM; + res = __GCONV_NOMEM; else { /* Remember the list of steps. */ - result->steps = steps; - result->nsteps = nsteps; + result->__steps = steps; + result->__nsteps = nsteps; /* Clear the array for the step data. */ - memset (result->data, '\0', - nsteps * sizeof (struct gconv_step_data)); + memset (result->__data, '\0', + nsteps * sizeof (struct __gconv_step_data)); /* Call all initialization functions for the transformation step implemenations. */ @@ -58,37 +59,37 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle) { /* If this is the last step we must not allocate an output buffer. */ - result->data[cnt].is_last = cnt == nsteps - 1; + result->__data[cnt].__is_last = cnt == nsteps - 1; /* Reset the counter. */ - result->data[cnt].invocation_counter = 0; + result->__data[cnt].__invocation_counter = 0; /* It's a regular use. */ - result->data[cnt].internal_use = 0; + result->__data[cnt].__internal_use = 0; /* We use the `mbstate_t' member in DATA. */ - result->data[cnt].statep = &result->data[cnt].__state; + result->__data[cnt].__statep = &result->__data[cnt].__state; /* Allocate the buffer. */ - if (!result->data[cnt].is_last) + if (!result->__data[cnt].__is_last) { size_t size = (GCONV_NCHAR_GOAL - * steps[cnt].max_needed_to); + * steps[cnt].__max_needed_to); - result->data[cnt].outbuf = (char *) malloc (size); - if (result->data[cnt].outbuf == NULL) + result->__data[cnt].__outbuf = (char *) malloc (size); + if (result->__data[cnt].__outbuf == NULL) { - res = GCONV_NOMEM; + res = __GCONV_NOMEM; break; } - result->data[cnt].outbufend = (result->data[cnt].outbuf - + size); + result->__data[cnt].__outbufend = + result->__data[cnt].__outbuf + size; } } } } - if (res != GCONV_OK) + if (res != __GCONV_OK) { /* Something went wrong. Free all the resources. */ int serrno = errno; @@ -96,7 +97,7 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle) if (result != NULL) { while (cnt-- > 0) - free (result->data[cnt].outbuf); + free (result->__data[cnt].__outbuf); free (result); result = NULL; diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 74dbfc0..3f9df34 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -90,11 +90,11 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, /* Determine the status. */ if (*outptrp == outend) - result = GCONV_FULL_OUTPUT; + result = __GCONV_FULL_OUTPUT; else if (*inptrp == inend) - result = GCONV_EMPTY_INPUT; + result = __GCONV_EMPTY_INPUT; else - result = GCONV_INCOMPLETE_INPUT; + result = __GCONV_INCOMPLETE_INPUT; if (converted != NULL) converted += n_convert; @@ -123,7 +123,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (*inptr > '\x7f') \ { \ /* This is no correct ANSI_X3.4-1968 character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -152,7 +152,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (*((uint32_t *) inptr) > 0x7f) \ { \ /* This is no correct ANSI_X3.4-1968 character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -200,7 +200,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (outptr + step >= outend) \ { \ /* Too long. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -287,14 +287,14 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, else \ { \ /* This is an illegal encoding. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ if (NEED_LENGTH_TEST && inptr + cnt > inend) \ { \ /* We don't have enough input. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -306,7 +306,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if ((byte & 0xc0) != 0x80) \ { \ /* This is an illegal encoding. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -366,7 +366,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ if (*((uint32_t *) inptr) >= 0x10000) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ /* Please note that we use the `uint32_t' from-pointer as an `uint16_t' \ @@ -379,7 +379,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ if (*((uint32_t *) inptr) >= 0x10000) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \ @@ -432,7 +432,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ if (*((uint32_t *) inptr) >= 0x10000) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \ @@ -442,7 +442,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ if (*((uint32_t *) inptr) >= 0x10000) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ *((uint16_t *) outptr)++ = bswap_16 (((uint16_t *) inptr)[1]); \ @@ -475,7 +475,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ if (*((uint32_t *) inptr) >= 0x110000) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -483,7 +483,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (NEED_LENGTH_TEST && outptr + 4 > outend) \ { \ /* Overflow in the output buffer. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -506,7 +506,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ if (*((uint32_t *) inptr) >= 0x110000) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -514,7 +514,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (NEED_LENGTH_TEST && outptr + 4 > outend) \ { \ /* Overflow in the output buffer. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -565,7 +565,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ /* We don't have enough input for another complete input \ character. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -573,7 +573,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (u2 < 0xdc00 || u2 >= 0xdfff) \ { \ /* This is no valid second word for a surrogate. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -602,7 +602,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, { \ /* We don't have enough input for another complete input \ character. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -610,7 +610,7 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, if (u2 < 0xdc00 || u2 >= 0xdfff) \ { \ /* This is no valid second word for a surrogate. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ diff --git a/iconv/iconv.c b/iconv/iconv.c index a6c8436..85a39e3fa 100644 --- a/iconv/iconv.c +++ b/iconv/iconv.c @@ -31,7 +31,7 @@ size_t iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { - gconv_t gcd = (gconv_t) cd; + __gconv_t gcd = (__gconv_t) cd; char *outstart = outbuf ? *outbuf : NULL; size_t converted; int result; @@ -59,28 +59,28 @@ iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, switch (result) { - case GCONV_ILLEGAL_DESCRIPTOR: + case __GCONV_ILLEGAL_DESCRIPTOR: __set_errno (EBADF); converted = (size_t) -1L; break; - case GCONV_ILLEGAL_INPUT: + case __GCONV_ILLEGAL_INPUT: __set_errno (EILSEQ); converted = (size_t) -1L; break; - case GCONV_FULL_OUTPUT: + case __GCONV_FULL_OUTPUT: __set_errno (E2BIG); converted = (size_t) -1L; break; - case GCONV_INCOMPLETE_INPUT: + case __GCONV_INCOMPLETE_INPUT: __set_errno (EINVAL); converted = (size_t) -1L; break; - case GCONV_EMPTY_INPUT: - case GCONV_OK: + case __GCONV_EMPTY_INPUT: + case __GCONV_OK: /* Nothing. */ break; diff --git a/iconv/iconv_close.c b/iconv/iconv_close.c index d3974c5..6f81aa2 100644 --- a/iconv/iconv_close.c +++ b/iconv/iconv_close.c @@ -1,5 +1,5 @@ /* Release any resource associated with given conversion descriptor. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -33,5 +33,5 @@ iconv_close (iconv_t cd) return -1; } - return __gconv_close ((gconv_t) cd) ? -1 : 0; + return __gconv_close ((__gconv_t) cd) ? -1 : 0; } diff --git a/iconv/iconv_open.c b/iconv/iconv_open.c index 51dcf0b..e566c6a 100644 --- a/iconv/iconv_open.c +++ b/iconv/iconv_open.c @@ -69,7 +69,7 @@ iconv_open (const char *tocode, const char *fromcode) char *fromcode_conv; size_t tocode_len; size_t fromcode_len; - gconv_t cd; + __gconv_t cd; int res; /* Normalize the name. We remove all characters beside alpha-numeric, @@ -87,10 +87,10 @@ iconv_open (const char *tocode, const char *fromcode) res = __gconv_open (tocode, fromcode, &cd); - if (res != GCONV_OK) + if (res != __GCONV_OK) { /* We must set the error number according to the specs. */ - if (res == GCONV_NOCONV || res == GCONV_NODB) + if (res == __GCONV_NOCONV || res == __GCONV_NODB) __set_errno (EINVAL); return (iconv_t) -1; diff --git a/iconv/loop.c b/iconv/loop.c index eac4c75..ada4f0a 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -1,5 +1,5 @@ /* Conversion loop frame work. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -51,6 +51,7 @@ */ #include <gconv.h> +#include <wchar.h> #include <sys/param.h> /* For MIN. */ #define __need_size_t #include <stddef.h> @@ -124,7 +125,7 @@ LOOPFCT (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, mbstate_t *state, void *data, size_t *converted EXTRA_LOOP_DECLS) { - int result = GCONV_OK; + int result = __GCONV_OK; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; #ifndef COUNT_CONVERTED @@ -157,7 +158,7 @@ LOOPFCT (const unsigned char **inptrp, const unsigned char *inend, #endif } - if (result == GCONV_OK) + if (result == __GCONV_OK) { #if MIN_NEEDED_INPUT == MAX_NEEDED_INPUT \ && MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT @@ -166,16 +167,16 @@ LOOPFCT (const unsigned char **inptrp, const unsigned char *inend, to be determined is the status. */ if (inptr == inend) /* No more input. */ - result = GCONV_EMPTY_INPUT; + result = __GCONV_EMPTY_INPUT; else if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend) || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend)) /* Overflow in the output buffer. */ - result = GCONV_FULL_OUTPUT; + result = __GCONV_FULL_OUTPUT; else /* We have something left in the input buffer. */ - result = GCONV_INCOMPLETE_INPUT; + result = __GCONV_INCOMPLETE_INPUT; #else - result = GCONV_EMPTY_INPUT; + result = __GCONV_EMPTY_INPUT; # undef NEED_LENGTH_TEST # define NEED_LENGTH_TEST 1 @@ -188,14 +189,14 @@ LOOPFCT (const unsigned char **inptrp, const unsigned char *inend, || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend)) { /* Overflow in the output buffer. */ - result = GCONV_FULL_OUTPUT; + result = __GCONV_FULL_OUTPUT; break; } if (MIN_NEEDED_INPUT > 1 && inptr + MIN_NEEDED_INPUT > inend) { /* We don't have enough input for another complete input character. */ - result = GCONV_INCOMPLETE_INPUT; + result = __GCONV_INCOMPLETE_INPUT; break; } diff --git a/iconv/skeleton.c b/iconv/skeleton.c index a9fc249..cd750ba 100644 --- a/iconv/skeleton.c +++ b/iconv/skeleton.c @@ -95,7 +95,7 @@ static int from_object; static int to_object; # ifndef FROM_DIRECTION -# define FROM_DIRECTION (step->data == &from_object) +# define FROM_DIRECTION (step->__data == &from_object) # endif #else # ifndef FROM_DIRECTION @@ -140,37 +140,37 @@ static int to_object; # endif int -gconv_init (struct gconv_step *step) +gconv_init (struct __gconv_step *step) { /* Determine which direction. */ - if (strcmp (step->from_name, CHARSET_NAME) == 0) + if (strcmp (step->__from_name, CHARSET_NAME) == 0) { - step->data = &from_object; + step->__data = &from_object; - step->min_needed_from = MIN_NEEDED_FROM; - step->max_needed_from = MAX_NEEDED_FROM; - step->min_needed_to = MIN_NEEDED_TO; - step->max_needed_to = MAX_NEEDED_TO; + step->__min_needed_from = MIN_NEEDED_FROM; + step->__max_needed_from = MAX_NEEDED_FROM; + step->__min_needed_to = MIN_NEEDED_TO; + step->__max_needed_to = MAX_NEEDED_TO; } - else if (strcmp (step->to_name, CHARSET_NAME) == 0) + else if (strcmp (step->__to_name, CHARSET_NAME) == 0) { - step->data = &to_object; + step->__data = &to_object; - step->min_needed_from = MIN_NEEDED_TO; - step->max_needed_from = MAX_NEEDED_TO; - step->min_needed_to = MIN_NEEDED_FROM; - step->max_needed_to = MAX_NEEDED_FROM; + step->__min_needed_from = MIN_NEEDED_TO; + step->__max_needed_from = MAX_NEEDED_TO; + step->__min_needed_to = MIN_NEEDED_FROM; + step->__max_needed_to = MAX_NEEDED_FROM; } else - return GCONV_NOCONV; + return __GCONV_NOCONV; #ifdef RESET_STATE - step->stateful = 1; + step->__stateful = 1; #else - step->stateful = 0; + step->__stateful = 0; #endif - return GCONV_OK; + return __GCONV_OK; } #endif @@ -195,13 +195,13 @@ gconv_init (struct gconv_step *step) #endif int -FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, +FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, const unsigned char **inbuf, const unsigned char *inbufend, size_t *written, int do_flush) { - struct gconv_step *next_step = step + 1; - struct gconv_step_data *next_data = data + 1; - gconv_fct fct = next_step->fct; + struct __gconv_step *next_step = step + 1; + struct __gconv_step_data *next_data = data + 1; + __gconv_fct fct = next_step->__fct; int status; /* If the function is called with no input this means we have to reset @@ -209,7 +209,7 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, dropped. */ if (do_flush) { - status = GCONV_OK; + status = __GCONV_OK; #ifdef EMIT_SHIFT_TO_INIT /* Emit the escape sequence to reset the state. */ @@ -217,7 +217,7 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, #endif /* Call the steps down the chain if there are any but only if we successfully emitted the escape sequence. */ - if (status == GCONV_OK && ! data->is_last) + if (status == __GCONV_OK && ! data->__is_last) status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL, written, 1)); } @@ -225,8 +225,8 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, { /* We preserve the initial values of the pointer variables. */ const unsigned char *inptr = *inbuf; - unsigned char *outbuf = data->outbuf; - unsigned char *outend = data->outbufend; + unsigned char *outbuf = data->__outbuf; + unsigned char *outend = data->__outbufend; unsigned char *outstart; /* This variable is used to count the number of characters we @@ -251,20 +251,20 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, if (FROM_DIRECTION) /* Run the conversion loop. */ status = FROM_LOOP (inbuf, inbufend, &outbuf, outend, - data->statep, step->data, &converted + data->__statep, step->__data, &converted EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ status = TO_LOOP (inbuf, inbufend, &outbuf, outend, - data->statep, step->data, &converted + data->__statep, step->__data, &converted EXTRA_LOOP_ARGS); /* If this is the last step leave the loop, there is nothing we can do. */ - if (data->is_last) + if (data->__is_last) { /* Store information about how many bytes are available. */ - data->outbuf = outbuf; + data->__outbuf = outbuf; /* Remember how many characters we converted. */ *written += converted; @@ -275,13 +275,13 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, /* Write out all output which was produced. */ if (outbuf > outstart) { - const unsigned char *outerr = data->outbuf; + const unsigned char *outerr = data->__outbuf; int result; result = DL_CALL_FCT (fct, (next_step, next_data, &outerr, outbuf, written, 0)); - if (result != GCONV_EMPTY_INPUT) + if (result != __GCONV_EMPTY_INPUT) { if (outerr != outbuf) { @@ -307,7 +307,7 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, (const unsigned char *) inbufend, (unsigned char **) &outbuf, (unsigned char *) outerr, - data->statep, step->data, + data->__statep, step->__data, &converted EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ @@ -315,13 +315,13 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, (const unsigned char *) inbufend, (unsigned char **) &outbuf, (unsigned char *) outerr, - data->statep, step->data, + data->__statep, step->__data, &converted EXTRA_LOOP_ARGS); /* We must run out of output buffer space in this rerun. */ assert (outbuf == outerr); - assert (nstatus == GCONV_FULL_OUTPUT); + assert (nstatus == __GCONV_FULL_OUTPUT); #endif /* reset input buffer */ } @@ -331,18 +331,18 @@ FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data, else /* All the output is consumed, we can make another run if everything was ok. */ - if (status == GCONV_FULL_OUTPUT) - status = GCONV_OK; + if (status == __GCONV_FULL_OUTPUT) + status = __GCONV_OK; } } - while (status == GCONV_OK); + while (status == __GCONV_OK); #ifdef END_LOOP END_LOOP #endif /* We finished one use of this step. */ - ++data->invocation_counter; + ++data->__invocation_counter; } return status; diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c index d9fe4dd..5ab2975 100644 --- a/iconvdata/8bit-gap.c +++ b/iconvdata/8bit-gap.c @@ -1,6 +1,6 @@ /* Generic conversion to and from 8bit charsets, converting from UCS using gaps. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -51,7 +51,7 @@ struct gap if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -74,7 +74,7 @@ struct gap if (ch >= 0xffff) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ while (ch > rp->end) \ @@ -82,7 +82,7 @@ struct gap if (ch < rp->start) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -90,7 +90,7 @@ struct gap if (ch != 0 && res == '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c index 2ea3331..bd9da7a 100644 --- a/iconvdata/8bit-generic.c +++ b/iconvdata/8bit-generic.c @@ -1,5 +1,5 @@ /* Generic conversion to and from 8bit charsets. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -37,7 +37,7 @@ if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -59,7 +59,7 @@ || (ch != 0 && from_ucs4[ch] == '\0')) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ diff --git a/iconvdata/ansi_x3.110.c b/iconvdata/ansi_x3.110.c index c754ce0..9371c5a 100644 --- a/iconvdata/ansi_x3.110.c +++ b/iconvdata/ansi_x3.110.c @@ -1,5 +1,5 @@ /* Generic conversion to and from ANSI_X3.110-1983. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -409,7 +409,7 @@ static const char from_ucs4[][2] = if (NEED_LENGTH_TEST && inptr + 1 >= inend) \ { \ /* The second character is not available. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -418,7 +418,7 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -435,7 +435,7 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -477,7 +477,7 @@ static const char from_ucs4[][2] = if (tmp[0] == '\0') \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ tmp[1] = '\0'; \ @@ -518,7 +518,7 @@ static const char from_ucs4[][2] = else \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -529,7 +529,7 @@ static const char from_ucs4[][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -542,7 +542,7 @@ static const char from_ucs4[][2] = { \ /* The result does not fit into the buffer. */ \ --outptr; \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ diff --git a/iconvdata/big5.c b/iconvdata/big5.c index b9ffce6..5551bba 100644 --- a/iconvdata/big5.c +++ b/iconvdata/big5.c @@ -1,5 +1,5 @@ /* Mapping tables for Big5 handling. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -8441,7 +8441,7 @@ static const char from_ucs4_tab13[][2] = if (NEED_LENGTH_TEST && inptr + 1 >= inend) \ { \ /* The second character is not available. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -8455,7 +8455,7 @@ static const char from_ucs4_tab13[][2] = else \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -8466,7 +8466,7 @@ static const char from_ucs4_tab13[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -8566,7 +8566,7 @@ static const char from_ucs4_tab13[][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -8574,7 +8574,7 @@ static const char from_ucs4_tab13[][2] = if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ { \ /* We have not enough room. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ diff --git a/iconvdata/cns11643.h b/iconvdata/cns11643.h index 342c877..27c484b 100644 --- a/iconvdata/cns11643.h +++ b/iconvdata/cns11643.h @@ -1,5 +1,5 @@ /* Access functions for CNS 11643, plane 2 handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -35,46 +35,46 @@ cns11643_to_ucs4 (const char **s, size_t avail, unsigned char offset) int idx; if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) > 0x30) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 3) return 0; ch2 = (*s)[1]; if ((ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; ch3 = (*s)[2]; if ((ch3 - offset) <= 0x20 || (ch3 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; idx = (ch2 - 0x21 - offset) * 94 + (ch3 - 0x21 - offset); if ((ch - 0x21 - offset) == 1) { if (idx > 0x2196) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; result = __cns11643l1_to_ucs4_tab[idx]; } else if ((ch - 0x21 - offset) == 2) { if (idx > 0x1de1) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; result = __cns11643l2_to_ucs4_tab[idx]; } else if ((ch - 0x21 - offset) == 0xe) { if (idx > 0x19bd) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; result = __cns11643l14_to_ucs4_tab[idx]; } else - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (result != L'\0') (*s) += 3; else - result = UNKNOWN_10646_CHAR; + result = __UNKNOWN_10646_CHAR; return result; } @@ -200,11 +200,11 @@ ucs4_to_cns11643 (uint32_t wch, char *s, size_t avail) cp = "\x22\x64"; break; default: - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } if (cp[0] == '\0') - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < needed) return 0; diff --git a/iconvdata/cns11643l1.h b/iconvdata/cns11643l1.h index 5e5abb7..3e0d042 100644 --- a/iconvdata/cns11643l1.h +++ b/iconvdata/cns11643l1.h @@ -1,5 +1,5 @@ /* Access functions for CNS 11643, plane 1 handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -33,22 +33,22 @@ cns11643l1_to_ucs4 (const char **s, size_t avail, unsigned char offset) int idx; if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) > 0x7d) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 2) return 0; ch2 = (*s)[1]; if ((ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset); if (idx > 0x2196) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; (*s) += 2; - return __cns11643l1_to_ucs4_tab[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR); + return __cns11643l1_to_ucs4_tab[idx] ?: ((*s) -= 2, __UNKNOWN_10646_CHAR); } @@ -163,11 +163,11 @@ ucs4_to_cns11643l1 (uint32_t wch, char *s, size_t avail) cp = "\x22\x64"; break; default: - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } if (cp[0] == '\0') - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 2) return 0; diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c index 89b8f48..fa2f7cb 100644 --- a/iconvdata/euc-cn.c +++ b/iconvdata/euc-cn.c @@ -1,5 +1,5 @@ /* Mapping tables for EUC-CN handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -47,7 +47,7 @@ if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -60,7 +60,7 @@ { \ /* The second character is not available. Store \ the intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -70,7 +70,7 @@ if (ch < 0xa1) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -78,10 +78,10 @@ endp = inptr; \ \ ch = gb2312_to_ucs4 (&endp, 2, 0x80); \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -114,10 +114,10 @@ ? outend - outptr : MAX_NEEDED_OUTPUT)); \ if (!NEED_LENGTH_TEST || found != 0) \ { \ - if (found == UNKNOWN_10646_CHAR) \ + if (found == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -128,7 +128,7 @@ else \ { \ /* We ran out of space. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ } \ diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c index 4936e40..3d97c01 100644 --- a/iconvdata/euc-jp.c +++ b/iconvdata/euc-jp.c @@ -1,5 +1,5 @@ /* Mapping tables for EUC-JP handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -49,7 +49,7 @@ else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -62,7 +62,7 @@ { \ /* The second character is not available. Store the \ intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -72,7 +72,7 @@ if (ch2 < 0xa1) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -108,13 +108,13 @@ if (NEED_LENGTH_TEST && ch == 0) \ { \ /* Not enough input available. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ inptr = endp; \ @@ -152,12 +152,12 @@ /* See whether we have room for at least two characters. */ \ if (NEED_LENGTH_TEST && outptr + 1 >= outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ found = ucs4_to_jisx0201 (ch, outptr + 1); \ - if (found != UNKNOWN_10646_CHAR) \ + if (found != __UNKNOWN_10646_CHAR) \ { \ /* Yes, it's a JIS 0201 character. Store the shift byte. */ \ *outptr = 0x8e; \ @@ -168,7 +168,7 @@ /* No JIS 0201 character. */ \ found = ucs4_to_jisx0208 (ch, outptr, 2); \ /* Please note that we always have enough room for the output. */ \ - if (found != UNKNOWN_10646_CHAR) \ + if (found != __UNKNOWN_10646_CHAR) \ { \ /* It's a JIS 0208 character, adjust it for EUC-JP. */ \ *outptr++ += 0x80; \ @@ -184,10 +184,10 @@ if (found == 0) \ { \ /* We ran out of space. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ - else if (found != UNKNOWN_10646_CHAR) \ + else if (found != __UNKNOWN_10646_CHAR) \ { \ /* It's a JIS 0212 character, adjust it for EUC-JP. */ \ *outptr++ = 0x8f; \ @@ -197,7 +197,7 @@ else \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c index 61046b3..4f51170 100644 --- a/iconvdata/euc-kr.c +++ b/iconvdata/euc-kr.c @@ -1,5 +1,5 @@ /* Mapping tables for EUC-KR handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jungshik Shin <jshin@pantheon.yale.edu> and Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -28,7 +28,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) { if (ch > 0x7f) { - if (ucs4_to_ksc5601 (ch, cp, 2) != UNKNOWN_10646_CHAR) + if (ucs4_to_ksc5601 (ch, cp, 2) != __UNKNOWN_10646_CHAR) { cp[0] |= 0x80; cp[1] |= 0x80; @@ -79,7 +79,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) else if (ch <= 0xa0 || ch > 0xfe || ch == 0xc9) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -91,13 +91,13 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) if (NEED_LENGTH_TEST && ch == 0) \ { \ /* The second character is not available. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -124,7 +124,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -136,7 +136,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) { \ /* The result does not fit into the buffer. */ \ --outptr; \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = cp[1]; \ diff --git a/iconvdata/euc-tw.c b/iconvdata/euc-tw.c index ca1cdac..4772908 100644 --- a/iconvdata/euc-tw.c +++ b/iconvdata/euc-tw.c @@ -1,5 +1,5 @@ /* Mapping tables for EUC-TW handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -48,7 +48,7 @@ else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -61,7 +61,7 @@ { \ /* The second character is not available. Store the \ intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -71,7 +71,7 @@ if (ch2 < 0xa1 || ch2 == 0xff) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -85,10 +85,10 @@ 0x80); \ /* Please note that we need not test for the missing input \ characters here anymore. */ \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal input. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -104,10 +104,10 @@ 0x80); \ /* Please note that we need not test for the missing input \ characters here anymore. */ \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal input. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -142,10 +142,10 @@ if (NEED_LENGTH_TEST && found == 0) \ { \ /* We ran out of space. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ - if (found != UNKNOWN_10646_CHAR) \ + if (found != __UNKNOWN_10646_CHAR) \ { \ /* It's a CNS 11643, plane 1 character, adjust it for EUC-TW. */ \ *outptr++ += 0x80; \ @@ -161,13 +161,13 @@ if (NEED_LENGTH_TEST && found == 0) \ { \ /* We ran out of space. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ - if (found == UNKNOWN_10646_CHAR) \ + if (found == __UNKNOWN_10646_CHAR) \ { \ /* No legal input. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ diff --git a/iconvdata/gb2312.h b/iconvdata/gb2312.h index cde9375..5cac987 100644 --- a/iconvdata/gb2312.h +++ b/iconvdata/gb2312.h @@ -1,5 +1,5 @@ /* Access functions for GB2312 conversion. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -37,22 +37,22 @@ gb2312_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) int idx; if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) > 0x77) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 2) return 0; ch2 = (*s)[1]; if ((ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset); if (idx > 0x1ff1) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; (*s) += 2; - return __gb2312_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR); + return __gb2312_to_ucs[idx] ?: ((*s) -= 2, __UNKNOWN_10646_CHAR); } @@ -210,11 +210,11 @@ ucs4_to_gb2312 (uint32_t wch, unsigned char *s, size_t avail) cp = "\x23\x24"; break; default: - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } if (cp[0] == '\0') - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; assert (cp[1] != '\0'); diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c index bb15849..31b1cbc 100644 --- a/iconvdata/iso-2022-jp.c +++ b/iconvdata/iso-2022-jp.c @@ -53,10 +53,10 @@ struct gap #define MAX_NEEDED_TO 4 #define FROM_DIRECTION (dir == from_iso2022jp) #define PREPARE_LOOP \ - enum direction dir = ((struct iso2022jp_data *) step->data)->dir; \ - enum variant var = ((struct iso2022jp_data *) step->data)->var; \ + enum direction dir = ((struct iso2022jp_data *) step->__data)->dir; \ + enum variant var = ((struct iso2022jp_data *) step->__data)->var; \ int save_set; \ - int *setp = &data->statep->count; + int *setp = &data->__statep->count; #define EXTRA_LOOP_ARGS , var, setp @@ -109,7 +109,7 @@ enum int -gconv_init (struct gconv_step *step) +gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct iso2022jp_data *new_data; @@ -117,59 +117,59 @@ gconv_init (struct gconv_step *step) enum variant var = illegal_var; int result; - if (__strcasecmp (step->from_name, "ISO-2022-JP//") == 0) + if (__strcasecmp (step->__from_name, "ISO-2022-JP//") == 0) { dir = from_iso2022jp; var = iso2022jp; } - else if (__strcasecmp (step->to_name, "ISO-2022-JP//") == 0) + else if (__strcasecmp (step->__to_name, "ISO-2022-JP//") == 0) { dir = to_iso2022jp; var = iso2022jp; } - else if (__strcasecmp (step->from_name, "ISO-2022-JP-2//") == 0) + else if (__strcasecmp (step->__from_name, "ISO-2022-JP-2//") == 0) { dir = from_iso2022jp; var = iso2022jp2; } - else if (__strcasecmp (step->to_name, "ISO-2022-JP-2//") == 0) + else if (__strcasecmp (step->__to_name, "ISO-2022-JP-2//") == 0) { dir = to_iso2022jp; var = iso2022jp2; } - result = GCONV_NOCONV; + result = __GCONV_NOCONV; if (dir != illegal_dir) { new_data = (struct iso2022jp_data *) malloc (sizeof (struct iso2022jp_data)); - result = GCONV_NOMEM; + result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; - step->data = new_data; + step->__data = new_data; if (dir == from_iso2022jp) { - step->min_needed_from = MIN_NEEDED_FROM; - step->max_needed_from = MAX_NEEDED_FROM; - step->min_needed_to = MIN_NEEDED_TO; - step->max_needed_to = MAX_NEEDED_TO; + step->__min_needed_from = MIN_NEEDED_FROM; + step->__max_needed_from = MAX_NEEDED_FROM; + step->__min_needed_to = MIN_NEEDED_TO; + step->__max_needed_to = MAX_NEEDED_TO; } else { - step->min_needed_from = MIN_NEEDED_TO; - step->max_needed_from = MAX_NEEDED_TO; - step->min_needed_to = MIN_NEEDED_FROM; - step->max_needed_to = MAX_NEEDED_FROM + 2; + step->__min_needed_from = MIN_NEEDED_TO; + step->__max_needed_from = MAX_NEEDED_TO; + step->__min_needed_to = MIN_NEEDED_FROM; + step->__max_needed_to = MAX_NEEDED_FROM + 2; } /* Yes, this is a stateful encoding. */ - step->stateful = 1; + step->__stateful = 1; - result = GCONV_OK; + result = __GCONV_OK; } } @@ -178,9 +178,9 @@ gconv_init (struct gconv_step *step) void -gconv_end (struct gconv_step *data) +gconv_end (struct __gconv_step *data) { - free (data->data); + free (data->__data); } @@ -188,33 +188,33 @@ gconv_end (struct gconv_step *data) the output state to the initial state. This has to be done during the flushing. */ #define EMIT_SHIFT_TO_INIT \ - if (data->statep->count != ASCII_set) \ + if (data->__statep->count != ASCII_set) \ { \ - enum direction dir = ((struct iso2022jp_data *) step->data)->dir; \ + enum direction dir = ((struct iso2022jp_data *) step->__data)->dir; \ \ if (dir == from_iso2022jp) \ /* It's easy, we don't have to emit anything, we just reset the \ state for the input. Note that this also clears the G2 \ designation. */ \ - data->statep->count = ASCII_set; \ + data->__statep->count = ASCII_set; \ else \ { \ - unsigned char *outbuf = data->outbuf; \ + unsigned char *outbuf = data->__outbuf; \ \ /* We are not in the initial state. To switch back we have \ to emit the sequence `Esc ( B'. */ \ - if (outbuf + 3 > data->outbufend) \ + if (outbuf + 3 > data->__outbufend) \ /* We don't have enough room in the output buffer. */ \ - status = GCONV_FULL_OUTPUT; \ + status = __GCONV_FULL_OUTPUT; \ else \ { \ /* Write out the shift sequence. */ \ *outbuf++ = ESC; \ *outbuf++ = '('; \ *outbuf++ = 'B'; \ - data->outbuf = outbuf; \ + data->__outbuf = outbuf; \ /* Note that this also clears the G2 designation. */ \ - data->statep->count = ASCII_set; \ + data->__statep->count = ASCII_set; \ } \ } \ } @@ -251,7 +251,7 @@ gconv_end (struct gconv_step *data) && inptr + 3 >= inend)) \ { \ /* Not enough input available. */ \ - result = GCONV_EMPTY_INPUT; \ + result = __GCONV_EMPTY_INPUT; \ break; \ } \ \ @@ -354,20 +354,20 @@ gconv_end (struct gconv_step *data) /* We use the table from the ISO 8859-7 module. */ \ if (inptr[2] < 0x20 || inptr[2] > 0x80) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ ch = iso88597_to_ucs4[inptr[2] - 0x20]; \ if (ch == 0) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ inptr += 3; \ } \ else \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -378,9 +378,9 @@ gconv_end (struct gconv_step *data) { \ /* Use the JIS X 0201 table. */ \ ch = jisx0201_to_ucs4 (ch); \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ ++inptr; \ @@ -389,9 +389,9 @@ gconv_end (struct gconv_step *data) { \ /* Use the JIS X 0201 table. */ \ ch = jisx0201_to_ucs4 (ch + 0x80); \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ ++inptr; \ @@ -424,12 +424,12 @@ gconv_end (struct gconv_step *data) \ if (NEED_LENGTH_TEST && ch == 0) \ { \ - result = GCONV_EMPTY_INPUT; \ + result = __GCONV_EMPTY_INPUT; \ break; \ } \ - else if (ch == UNKNOWN_10646_CHAR) \ + else if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -474,25 +474,27 @@ gconv_end (struct gconv_step *data) { \ unsigned char buf[2]; \ written = ucs4_to_jisx0201 (ch, buf); \ - if (written != UNKNOWN_10646_CHAR && buf[0] > 0x20 && buf[0] < 0x80) \ + if (written != __UNKNOWN_10646_CHAR && buf[0] > 0x20 \ + && buf[0] < 0x80) \ { \ *outptr++ = buf[0]; \ written = 1; \ } \ else \ - written = UNKNOWN_10646_CHAR; \ + written = __UNKNOWN_10646_CHAR; \ } \ else if (set == JISX0201_Kana_set) \ { \ unsigned char buf[2]; \ written = ucs4_to_jisx0201 (ch, buf); \ - if (written != UNKNOWN_10646_CHAR && buf[0] > 0xa0 && buf[0] < 0xe0) \ + if (written != __UNKNOWN_10646_CHAR && buf[0] > 0xa0 \ + && buf[0] < 0xe0) \ { \ *outptr++ = buf[0] - 0x80; \ written = 1; \ } \ else \ - written = UNKNOWN_10646_CHAR; \ + written = __UNKNOWN_10646_CHAR; \ } \ else \ { \ @@ -518,14 +520,14 @@ gconv_end (struct gconv_step *data) \ if (NEED_LENGTH_TEST && written == 0) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ - else if (written != UNKNOWN_10646_CHAR) \ + else if (written != __UNKNOWN_10646_CHAR) \ outptr += written; \ } \ \ - if (written == UNKNOWN_10646_CHAR || written == 0) \ + if (written == __UNKNOWN_10646_CHAR || written == 0) \ { \ if (set2 == ISO88591_set) \ { \ @@ -557,7 +559,7 @@ gconv_end (struct gconv_step *data) } \ } \ \ - if (written == UNKNOWN_10646_CHAR || written == 0) \ + if (written == __UNKNOWN_10646_CHAR || written == 0) \ { \ /* Either this is an unknown character or we have to switch \ the currently selected character set. The character sets \ @@ -576,7 +578,7 @@ gconv_end (struct gconv_step *data) escape sequence. */ \ if (NEED_LENGTH_TEST && outptr + 4 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -600,12 +602,12 @@ gconv_end (struct gconv_step *data) unsigned char buf[2]; \ \ written = ucs4_to_jisx0201 (ch, buf); \ - if (written != UNKNOWN_10646_CHAR && buf[0] < 0x80) \ + if (written != __UNKNOWN_10646_CHAR && buf[0] < 0x80) \ { \ /* We use JIS X 0201. */ \ if (NEED_LENGTH_TEST && outptr + 4 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -618,12 +620,12 @@ gconv_end (struct gconv_step *data) else \ { \ written = ucs4_to_jisx0208 (ch, buf, 2); \ - if (written != UNKNOWN_10646_CHAR) \ + if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use JIS X 0208. */ \ if (NEED_LENGTH_TEST && outptr + 5 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -637,18 +639,18 @@ gconv_end (struct gconv_step *data) else if (var == iso2022jp) \ { \ /* We have no other choice. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ { \ written = ucs4_to_jisx0212 (ch, buf, 2); \ - if (written != UNKNOWN_10646_CHAR) \ + if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use JIS X 0212. */ \ if (NEED_LENGTH_TEST && outptr + 6 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -662,12 +664,13 @@ gconv_end (struct gconv_step *data) else \ { \ written = ucs4_to_jisx0201 (ch, buf); \ - if (written != UNKNOWN_10646_CHAR && buf[0] >= 0x80) \ + if (written != __UNKNOWN_10646_CHAR \ + && buf[0] >= 0x80) \ { \ /* We use JIS X 0201. */ \ if (NEED_LENGTH_TEST && outptr + 4 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -682,7 +685,7 @@ gconv_end (struct gconv_step *data) /* ISO 8859-1 upper half. */ \ if (NEED_LENGTH_TEST && outptr + 6 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -697,12 +700,12 @@ gconv_end (struct gconv_step *data) else \ { \ written = ucs4_to_gb2312 (ch, buf, 2); \ - if (written != UNKNOWN_10646_CHAR) \ + if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use GB 2312. */ \ if (NEED_LENGTH_TEST && outptr + 5 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -716,13 +719,13 @@ gconv_end (struct gconv_step *data) else \ { \ written = ucs4_to_ksc5601 (ch, buf, 2); \ - if (written != UNKNOWN_10646_CHAR) \ + if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use KSC 5601. */ \ if (NEED_LENGTH_TEST \ && outptr + 6 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -752,7 +755,7 @@ gconv_end (struct gconv_step *data) if (NEED_LENGTH_TEST \ && outptr + 6 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -765,7 +768,7 @@ gconv_end (struct gconv_step *data) } \ else \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c index a0c213c..178753f 100644 --- a/iconvdata/iso-2022-kr.c +++ b/iconvdata/iso-2022-kr.c @@ -44,12 +44,13 @@ #define MAX_NEEDED_TO 4 #define PREPARE_LOOP \ int save_set; \ - int *setp = &data->statep->count; \ - if (!FROM_DIRECTION && !data->internal_use && data->invocation_counter == 0)\ + int *setp = &data->__statep->count; \ + if (!FROM_DIRECTION && !data->__internal_use \ + && data->__invocation_counter == 0) \ { \ /* Emit the designator sequence. */ \ if (outbuf + 4 > outend) \ - return GCONV_FULL_OUTPUT; \ + return __GCONV_FULL_OUTPUT; \ \ *outbuf++ = ESC; \ *outbuf++ = '$'; \ @@ -72,27 +73,27 @@ enum the output state to the initial state. This has to be done during the flushing. */ #define EMIT_SHIFT_TO_INIT \ - if (data->statep->count != ASCII_set) \ + if (data->__statep->count != ASCII_set) \ { \ if (FROM_DIRECTION) \ /* It's easy, we don't have to emit anything, we just reset the \ state for the input. */ \ - data->statep->count = ASCII_set; \ + data->__statep->count = ASCII_set; \ else \ { \ - unsigned char *outbuf = data->outbuf; \ + unsigned char *outbuf = data->__outbuf; \ \ /* We are not in the initial state. To switch back we have \ to emit `SI'. */ \ - if (outbuf == data->outbufend) \ + if (outbuf == data->__outbufend) \ /* We don't have enough room in the output buffer. */ \ - status = GCONV_FULL_OUTPUT; \ + status = __GCONV_FULL_OUTPUT; \ else \ { \ /* Write out the shift sequence. */ \ *outbuf++ = SI; \ - data->outbuf = outbuf; \ - data->statep->count = ASCII_set; \ + data->__outbuf = outbuf; \ + data->__statep->count = ASCII_set; \ } \ } \ } @@ -119,7 +120,7 @@ enum /* This is a 7bit character set, disallow all 8bit characters. */ \ if (ch > 0x7f) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -136,7 +137,7 @@ enum || (inptr[2] == ')' && inptr + 3 > inend)))) \ \ { \ - result = GCONV_EMPTY_INPUT; \ + result = __GCONV_EMPTY_INPUT; \ break; \ } \ if (inptr[1] == '$' && inptr[2] == ')' && inptr[3] == 'C') \ @@ -165,7 +166,7 @@ enum { \ if (ch >= 0x80) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ /* Almost done, just advance the input pointer. */ \ @@ -181,12 +182,12 @@ enum \ if (NEED_LENGTH_TEST && ch == 0) \ { \ - result = GCONV_EMPTY_INPUT; \ + result = __GCONV_EMPTY_INPUT; \ break; \ } \ - else if (ch == UNKNOWN_10646_CHAR) \ + else if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -221,7 +222,7 @@ enum set = ASCII_set; \ if (NEED_LENGTH_TEST && outptr == outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ } \ @@ -235,10 +236,10 @@ enum \ written = ucs4_to_ksc5601 (ch, buf, 2); \ \ - if (written == UNKNOWN_10646_CHAR) \ + if (written == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ assert (written == 2); \ @@ -252,7 +253,7 @@ enum \ if (NEED_LENGTH_TEST && outptr + 2 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c index 701a71d..5b2ba72 100644 --- a/iconvdata/iso646.c +++ b/iconvdata/iso646.c @@ -1,5 +1,5 @@ /* Conversion to and from the various ISO 646 CCS. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -45,8 +45,8 @@ #define MIN_NEEDED_TO 4 #define FROM_DIRECTION (dir == from_iso646) #define PREPARE_LOOP \ - enum direction dir = ((struct iso646_data *) step->data)->dir; \ - enum variant var = ((struct iso646_data *) step->data)->var; + enum direction dir = ((struct iso646_data *) step->__data)->dir; \ + enum variant var = ((struct iso646_data *) step->__data)->var; #define EXTRA_LOOP_ARGS , var @@ -124,7 +124,7 @@ struct iso646_data int -gconv_init (struct gconv_step *step) +gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct iso646_data *new_data; @@ -133,47 +133,47 @@ gconv_init (struct gconv_step *step) int result; for (var = sizeof (names) / sizeof (names[0]) - 1; var > illegal_var; --var) - if (__strcasecmp (step->from_name, names[var]) == 0) + if (__strcasecmp (step->__from_name, names[var]) == 0) { dir = from_iso646; break; } - else if (__strcasecmp (step->to_name, names[var]) == 0) + else if (__strcasecmp (step->__to_name, names[var]) == 0) { dir = to_iso646; break; } - result = GCONV_NOCONV; + result = __GCONV_NOCONV; if (dir != illegal_dir) { new_data = (struct iso646_data *) malloc (sizeof (struct iso646_data)); - result = GCONV_NOMEM; + result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; - step->data = new_data; + step->__data = new_data; if (var == from_iso646) { - step->min_needed_from = MIN_NEEDED_FROM; - step->max_needed_from = MIN_NEEDED_FROM; - step->min_needed_to = MIN_NEEDED_TO; - step->max_needed_to = MIN_NEEDED_TO; + step->__min_needed_from = MIN_NEEDED_FROM; + step->__max_needed_from = MIN_NEEDED_FROM; + step->__min_needed_to = MIN_NEEDED_TO; + step->__max_needed_to = MIN_NEEDED_TO; } else { - step->min_needed_from = MIN_NEEDED_TO; - step->max_needed_from = MIN_NEEDED_TO; - step->min_needed_to = MIN_NEEDED_FROM; - step->max_needed_to = MIN_NEEDED_FROM; + step->__min_needed_from = MIN_NEEDED_TO; + step->__max_needed_from = MIN_NEEDED_TO; + step->__min_needed_to = MIN_NEEDED_FROM; + step->__max_needed_to = MIN_NEEDED_FROM; } - step->stateful = 0; + step->__stateful = 0; - result = GCONV_OK; + result = __GCONV_OK; } } @@ -182,9 +182,9 @@ gconv_init (struct gconv_step *step) void -gconv_end (struct gconv_step *data) +gconv_end (struct __gconv_step *data) { - free (data->data); + free (data->__data); } @@ -195,7 +195,7 @@ gconv_end (struct gconv_step *data) #define BODY \ { \ uint32_t ch; \ - int failure = GCONV_OK; \ + int failure = __GCONV_OK; \ \ ch = *inptr; \ switch (ch) \ @@ -308,7 +308,7 @@ gconv_end (struct gconv_step *data) ch = 0xf9; \ else if (var == JP_OCR_B) \ /* Illegal character. */ \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ else if (var == YU) \ ch = 0x17e; \ else if (var == HU) \ @@ -382,7 +382,7 @@ gconv_end (struct gconv_step *data) ch = 0xec; \ else if (var == JP_OCR_B) \ /* Illegal character. */ \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ else if (var == YU) \ ch = 0x10d; \ else if (var == HU) \ @@ -398,13 +398,13 @@ gconv_end (struct gconv_step *data) break; \ case 0x80 ... 0xff: \ /* Illegal character. */ \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ /* Hopefully gcc can recognize that the following `if' is only true \ when we reach the default case in the `switch' statement. */ \ - if (failure == GCONV_ILLEGAL_INPUT) \ + if (failure == __GCONV_ILLEGAL_INPUT) \ { \ /* Exit the loop with an error. */ \ result = failure; \ @@ -424,7 +424,7 @@ gconv_end (struct gconv_step *data) #define BODY \ { \ unsigned char ch; \ - int failure = GCONV_OK; \ + int failure = __GCONV_OK; \ \ ch = *((uint32_t *) inptr); \ switch (*((uint32_t *) inptr)) \ @@ -432,17 +432,17 @@ gconv_end (struct gconv_step *data) case 0x23: \ if (var == GB || var == ES || var == IT || var == FR || var == FR1 \ || var == NO2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x24: \ if (var == CN || var == HU || var == CU || var == SE || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x40: \ if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \ || var == IT || var == YU || var == HU || var == FR || var == FR1 \ || var == PT || var == PT2 || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x5b: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ @@ -450,7 +450,7 @@ gconv_end (struct gconv_step *data) || var == HU || var == FR || var == FR1 || var == NO \ || var == NO2 || var == PT || var == PT2 || var == SE \ || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ else if (var == CU) \ ch = 0x7d; \ break; \ @@ -460,7 +460,7 @@ gconv_end (struct gconv_step *data) || var == YU || var == KR || var == HU || var == CU || var == FR \ || var == FR1 || var == NO || var == NO2 || var == PT \ || var == PT2 || var == SE || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x5d: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ @@ -468,17 +468,17 @@ gconv_end (struct gconv_step *data) || var == HU || var == FR || var == FR1 || var == NO \ || var == NO2 || var == PT || var == PT2 || var == SE \ || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x5e: \ if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \ || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x60: \ if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \ || var == YU || var == HU || var == FR || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x7b: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ @@ -486,14 +486,14 @@ gconv_end (struct gconv_step *data) || var == CU || var == FR || var == FR1 || var == NO \ || var == NO2 || var == PT || var == PT2 || var == SE \ || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x7c: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ || var == ES2 || var == IT || var == YU || var == HU || var == CU \ || var == FR || var == FR1 || var == NO || var == PT \ || var == PT2 || var == SE || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ else if (var == NO2) \ ch = 0x7e; \ break; \ @@ -502,7 +502,7 @@ gconv_end (struct gconv_step *data) || var == ES2 || var == IT || var == YU || var == HU || var == CU \ || var == FR || var == FR1 || var == NO || var == NO2 \ || var == PT || var == PT2 || var == SE || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x7e: \ if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \ @@ -510,21 +510,21 @@ gconv_end (struct gconv_step *data) || var == YU || var == HU || var == CU || var == FR || var == FR1 \ || var == NO || var == NO2 || var == PT || var == SE \ || var == SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xa1: \ if (var != ES && var != ES2 && var != CU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0xa3: \ if (var != GB && var != ES && var != IT && var != FR && var != FR1) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x23; \ break; \ case 0xa4: \ if (var != HU && var != CU && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x24; \ break; \ case 0xa5: \ @@ -533,7 +533,7 @@ gconv_end (struct gconv_step *data) else if (var == JP || var == JP_OCR_B) \ ch = 0x5c; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xa7: \ if (var == DE || var == ES || var == IT || var == PT) \ @@ -543,11 +543,11 @@ gconv_end (struct gconv_step *data) else if (var == NO2) \ ch = 0x23; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xa8: \ if (var != ES2 && var != CU && var != FR && var != FR1) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0xb0: \ @@ -558,7 +558,7 @@ gconv_end (struct gconv_step *data) else if (var == PT) \ ch = 0x7e; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xb4: \ if (var == ES2 || var == CU) \ @@ -566,11 +566,11 @@ gconv_end (struct gconv_step *data) else if (var == PT2) \ ch = 0x40; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xb5: \ if (var != FR) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x60; \ break; \ case 0xbf: \ @@ -579,31 +579,31 @@ gconv_end (struct gconv_step *data) else if (var == ES2 || var == CU) \ ch = 0x5e; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xc1: \ if (var != HU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x40; \ break; \ case 0xc3: \ if (var != PT && var != PT2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0xc4: \ if (var != DE && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0xc5: \ if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5d; \ break; \ case 0xc6: \ if (var != DK && var != NO && var != NO2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0xc7: \ @@ -612,7 +612,7 @@ gconv_end (struct gconv_step *data) else if (var == PT || var == PT2) \ ch = 0x5c; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xc9: \ if (var == CA2) \ @@ -622,26 +622,26 @@ gconv_end (struct gconv_step *data) else if (var == SE2) \ ch = 0x40; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xd1: \ if (var != ES && var != ES2 && var != CU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5c; \ break; \ case 0xd5: \ if (var != PT && var != PT2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5d; \ break; \ case 0xd6: \ if (var != DE && var != HU && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5c; \ break; \ case 0xd8: \ if (var != DK && var != NO && var != NO2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5c; \ break; \ case 0xdc: \ @@ -650,11 +650,11 @@ gconv_end (struct gconv_step *data) else if (var == SE2) \ ch = 0x5e; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xdf: \ if (var != DE) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0xe0: \ @@ -663,36 +663,36 @@ gconv_end (struct gconv_step *data) else if (var == IT) \ ch = 0x7b; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xe1: \ if (var != HU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x60; \ break; \ case 0xe2: \ if (var != CA && var != CA2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0xe3: \ if (var != PT && var != PT2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7b; \ break; \ case 0xe4: \ if (var != DE && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7b; \ break; \ case 0xe5: \ if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7d; \ break; \ case 0xe6: \ if (var != DK && var != NO && var != NO2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7b; \ break; \ case 0xe7: \ @@ -703,11 +703,11 @@ gconv_end (struct gconv_step *data) else if (var == PT || var == PT2) \ ch = 0x7c; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xe8: \ if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7d; \ break; \ case 0xe9: \ @@ -718,51 +718,51 @@ gconv_end (struct gconv_step *data) else if (var == SE2) \ ch = 0x60; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xea: \ if (var != CA && var != CA2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5d; \ break; \ case 0xec: \ if (var != IT) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0xee: \ if (var != CA) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5e; \ break; \ case 0xf1: \ if (var != ES && var != ES2 && var != CU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7c; \ break; \ case 0xf2: \ if (var != IT) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7c; \ break; \ case 0xf4: \ if (var != CA && var != CA2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x60; \ break; \ case 0xf5: \ if (var != PT && var != PT2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7d; \ break; \ case 0xf6: \ if (var != DE && var != HU && var != SE && var != SE2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7c; \ break; \ case 0xf8: \ if (var != DK && var != NO && var != NO2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7c; \ break; \ case 0xf9: \ @@ -771,11 +771,11 @@ gconv_end (struct gconv_step *data) else if (var == IT) \ ch = 0x60; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0xfb: \ if (var != CA && var != CA2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0xfc: \ @@ -784,95 +784,95 @@ gconv_end (struct gconv_step *data) else if (var == SE2) \ ch = 0x7e; \ else \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ case 0x160: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0x106: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5d; \ break; \ case 0x107: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7d; \ break; \ case 0x10c: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5e; \ break; \ case 0x10d: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0x110: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5c; \ break; \ case 0x111: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7c; \ break; \ case 0x161: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7b; \ break; \ case 0x17d: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x40; \ break; \ case 0x17e: \ if (var != YU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x60; \ break; \ case 0x2dd: \ if (var != HU) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0x2022: \ if (var != ES2) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x40; \ break; \ case 0x203e: \ if (var != GB && var != CN && var != JP && var != NO && var != SE) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x7e; \ break; \ case 0x20a9: \ if (var != KR) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5c; \ break; \ case 0x2329: \ if (var != JP_OCR_B) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5b; \ break; \ case 0x232a: \ if (var != JP_OCR_B) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ ch = 0x5d; \ break; \ default: \ if (*((uint32_t *) inptr) > 0x7f) \ - failure = GCONV_ILLEGAL_INPUT; \ + failure = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ - if (failure == GCONV_ILLEGAL_INPUT) \ + if (failure == __GCONV_ILLEGAL_INPUT) \ { \ /* Exit the loop with an error. */ \ result = failure; \ diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c index db6cbdf..06eeda5 100644 --- a/iconvdata/iso8859-1.c +++ b/iconvdata/iso8859-1.c @@ -1,5 +1,5 @@ /* Conversion to and from ISO 8859-1. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -48,7 +48,7 @@ if (ch > 0xff) \ { \ /* We have an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ *outptr++ = (unsigned char) ch; \ diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c index c104d83..1ec0976 100644 --- a/iconvdata/iso_6937-2.c +++ b/iconvdata/iso_6937-2.c @@ -1,5 +1,5 @@ /* Generic conversion to and from ISO 6937-2. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -409,7 +409,7 @@ static const char from_ucs4[][2] = { \ /* The second character is not available. Store the \ intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -418,7 +418,7 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -427,7 +427,7 @@ static const char from_ucs4[][2] = if (ch == 0) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -440,7 +440,7 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ ++inptr; \ @@ -542,14 +542,14 @@ static const char from_ucs4[][2] = if (fail) \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ else if (from_ucs4[ch][0] == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -562,7 +562,7 @@ static const char from_ucs4[][2] = if (NEED_LENGTH_TEST && outptr >= outend) \ { \ /* The result does not fit into the buffer. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = cp[1]; \ diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c index 5e9f25f..ca4ab0f 100644 --- a/iconvdata/iso_6937.c +++ b/iconvdata/iso_6937.c @@ -1,5 +1,5 @@ /* Generic conversion to and from ISO 6937. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -401,7 +401,7 @@ static const char from_ucs4[][2] = { \ /* The second character is not available. Store the \ intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -410,7 +410,7 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -419,7 +419,7 @@ static const char from_ucs4[][2] = if (ch == 0) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -432,7 +432,7 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ ++inptr; \ @@ -513,14 +513,14 @@ static const char from_ucs4[][2] = if (fail) \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ else if (from_ucs4[ch][0] == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -533,7 +533,7 @@ static const char from_ucs4[][2] = if (NEED_LENGTH_TEST && outptr >= outend) \ { \ /* The result does not fit into the buffer. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = cp[1]; \ diff --git a/iconvdata/jis0201.h b/iconvdata/jis0201.h index 362da17..5a55537 100644 --- a/iconvdata/jis0201.h +++ b/iconvdata/jis0201.h @@ -1,5 +1,5 @@ /* Access functions for JISX0201 conversion. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -31,7 +31,7 @@ jisx0201_to_ucs4 (char ch) uint32_t val = __jisx0201_to_ucs4[(unsigned char) ch]; if (val == 0 && ch != '\0') - val = UNKNOWN_10646_CHAR; + val = __UNKNOWN_10646_CHAR; return val; } @@ -51,7 +51,7 @@ ucs4_to_jisx0201 (uint32_t wch, char *s) else if (wch >= 0xff61 && wch <= 0xff9f) ch = wch - 0xfec0; else - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; s[0] = ch; return 1; diff --git a/iconvdata/jis0208.h b/iconvdata/jis0208.h index 67d7be5..df8eb0d 100644 --- a/iconvdata/jis0208.h +++ b/iconvdata/jis0208.h @@ -1,5 +1,5 @@ /* Access functions for JISX0208 conversion. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -50,22 +50,22 @@ jisx0208_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) int idx; if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) > 0xea) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 2) return 0; ch2 = (*s)[1]; if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset); if (idx >= 0x1e80) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; (*s) += 2; - return __jis0208_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR); + return __jis0208_to_ucs[idx] ?: ((*s) -= 2, __UNKNOWN_10646_CHAR); } @@ -87,17 +87,17 @@ ucs4_to_jisx0208 (uint32_t wch, char *s, size_t avail) const struct jisx0208_ucs_idx *rp = __jisx0208_from_ucs_idx; if (ch >= 0xffff) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; while (ch > rp->end) ++rp; if (ch >= rp->start) cp = __jisx0208_from_ucs_tab[rp->idx + ch - rp->start]; else - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } if (cp[0] == '\0') - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; s[0] = cp[0]; s[1] = cp[1]; diff --git a/iconvdata/jis0212.h b/iconvdata/jis0212.h index 28d4b3f..f08fdd8 100644 --- a/iconvdata/jis0212.h +++ b/iconvdata/jis0212.h @@ -1,5 +1,5 @@ /* Access functions for JISX0212 conversion. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -51,14 +51,14 @@ jisx0212_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) int idx; if (ch < offset || (ch - offset) < 0x22 || (ch - offset) > 0x6d) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 2) return 0; ch2 = (*s)[1]; if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; idx = (ch - offset - 0x21) * 94 + (ch2 - offset - 0x21); @@ -70,7 +70,7 @@ jisx0212_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) if (wch != L'\0') (*s) += 2; else - wch = UNKNOWN_10646_CHAR; + wch = __UNKNOWN_10646_CHAR; return wch; } @@ -84,16 +84,16 @@ ucs4_to_jisx0212 (uint32_t wch, char *s, size_t avail) const char *cp; if (ch >= 0xffff) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; while (ch > rp->end) ++rp; if (ch >= rp->start) cp = __jisx0212_from_ucs[rp->idx + ch - rp->start]; else - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (cp[0] == '\0') - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; s[0] = cp[0]; if (cp[1] != '\0') diff --git a/iconvdata/johab.c b/iconvdata/johab.c index 6a5d8be..21a9c9b 100644 --- a/iconvdata/johab.c +++ b/iconvdata/johab.c @@ -1,5 +1,5 @@ /* Mapping tables for JOHAB handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jungshik Shin <jshin@pantheon.yale.edu> and Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -183,7 +183,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) || (ch > 0xd3 && ch < 0xd9)) \ { \ /* These are illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -197,7 +197,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) { \ /* The second character is not available. Store the \ intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -215,7 +215,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) if (i == -1 || m == -1 || f == -1) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else if (i > 0 && m > 0) \ @@ -229,7 +229,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) else \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -238,14 +238,14 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4) \ { \ /* This is illegal. Modern Hangul Jaso is defined \ elsewhere in Johab */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -267,7 +267,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) if (ch == 0) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -315,7 +315,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) \ if (NEED_LENGTH_TEST && outptr + 2 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -330,7 +330,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) \ if (NEED_LENGTH_TEST && outptr + 2 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -346,12 +346,12 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) ? outend - outptr : 2)); \ if (NEED_LENGTH_TEST && written == 0) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ - if (written == UNKNOWN_10646_CHAR) \ + if (written == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -375,12 +375,12 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) ? outend - outptr : 2)); \ if (NEED_LENGTH_TEST && written == 0) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ - if (written == UNKNOWN_10646_CHAR) \ + if (written == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ diff --git a/iconvdata/ksc5601.h b/iconvdata/ksc5601.h index e67d911..ebe3a82 100644 --- a/iconvdata/ksc5601.h +++ b/iconvdata/ksc5601.h @@ -1,5 +1,5 @@ /* Access functions for KS C 5601-1992 based encoding conversion. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 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 @@ -54,14 +54,14 @@ ksc5601_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) >= 0x7e || (ch - offset) == 0x49) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; if (avail < 2) return 0; ch2 = (*s)[1]; if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; idx = (ch - offset - 0x21) * 94 + (ch2 - offset - 0x21); @@ -72,13 +72,13 @@ ksc5601_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) if (idx >= 1410 && idx < 3760) return (__ksc5601_hangul_to_ucs[idx - 1410] - ?: ((*s) -= 2, UNKNOWN_10646_CHAR)); + ?: ((*s) -= 2, __UNKNOWN_10646_CHAR)); else if (idx >= 3854) /* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */ return (__ksc5601_hanja_to_ucs[idx - 3854] - ?: ((*s) -= 2, UNKNOWN_10646_CHAR)); + ?: ((*s) -= 2, __UNKNOWN_10646_CHAR)); else - return __ksc5601_sym_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR); + return __ksc5601_sym_to_ucs[idx] ?: ((*s) -= 2, __UNKNOWN_10646_CHAR); } static inline size_t @@ -108,7 +108,7 @@ ucs4_to_ksc5601_hangul (uint32_t wch, unsigned char *s, size_t avail) } } - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } @@ -139,7 +139,7 @@ ucs4_to_ksc5601_hanja (uint32_t wch, unsigned char *s, size_t avail) } } - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } static inline size_t @@ -169,7 +169,7 @@ ucs4_to_ksc5601_sym (uint32_t wch, unsigned char *s, size_t avail) } } - return UNKNOWN_10646_CHAR; + return __UNKNOWN_10646_CHAR; } diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c index fe54c8c..d18ab9b 100644 --- a/iconvdata/sjis.c +++ b/iconvdata/sjis.c @@ -1,5 +1,5 @@ /* Mapping tables for SJIS handling. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -4291,7 +4291,7 @@ static const char from_ucs4_extra[0x100][2] = [0x0055] = "\x82\x95", [0x0056] = "\x82\x96", [0x0057] = "\x82\x97", [0x0058] = "\x82\x98", [0x0059] = "\x82\x99", [0x005a] = "\x82\x9a", [0x005b] = "\x81\x6f", [0x005c] = "\x81\x62", [0x005d] = "\x81\x70", - [0x005e] = "\x00\x00", [0x005f] = "\x00\x00", + [0x005e] = "\x00\x00", [0x005f] = "\x00\x00", [0x0060] = "\x00\x00", [0x0061] = "\xa1\x00", [0x0062] = "\xa2\x00", [0x0063] = "\xa3\x00", [0x0064] = "\xa4\x00", [0x0065] = "\xa5\x00", [0x0066] = "\xa6\x00", [0x0067] = "\xa7\x00", [0x0068] = "\xa8\x00", @@ -4357,7 +4357,7 @@ static const char from_ucs4_extra[0x100][2] = else if (ch > 0xea || ch == 0xa0 || ch == 0x7f || ch == 0x80) \ { \ /* These are illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -4371,7 +4371,7 @@ static const char from_ucs4_extra[0x100][2] = { \ /* The second character is not available. Store \ the intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -4382,7 +4382,7 @@ static const char from_ucs4_extra[0x100][2] = || (idx > 0x9ffc && idx < 0xe040) || idx > 0xeaa4) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -4405,7 +4405,7 @@ static const char from_ucs4_extra[0x100][2] = if (ch == 0) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -4436,7 +4436,7 @@ static const char from_ucs4_extra[0x100][2] = else \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -4446,7 +4446,7 @@ static const char from_ucs4_extra[0x100][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -4457,7 +4457,7 @@ static const char from_ucs4_extra[0x100][2] = if (NEED_LENGTH_TEST && outptr >= outend) \ { \ /* The result does not fit into the buffer. */ \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = cp[1]; \ diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c index d1ef6c2..c9f674a 100644 --- a/iconvdata/t.61.c +++ b/iconvdata/t.61.c @@ -1,5 +1,5 @@ /* Generic conversion to and from T.61. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -392,7 +392,7 @@ static const char from_ucs4[][2] = if (NEED_LENGTH_TEST && inptr + 1 >= inend) \ { \ /* The second character is not available. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -401,7 +401,7 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -418,7 +418,7 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -447,7 +447,7 @@ static const char from_ucs4[][2] = else if (ch < 0x2d8 || ch > 0x2dd || ch == 0x02dc) \ { \ /* Illegal characters. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -466,7 +466,7 @@ static const char from_ucs4[][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -479,7 +479,7 @@ static const char from_ucs4[][2] = { \ /* The result does not fit into the buffer. */ \ --outptr; \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c index 5aef36c..ac4be8a 100644 --- a/iconvdata/uhc.c +++ b/iconvdata/uhc.c @@ -1,5 +1,5 @@ /* Mapping tables for UHC handling. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998. @@ -3066,7 +3066,7 @@ static const char uhc_hangul_from_ucs[11172][2] = else if (ch <= 0x80 || ch >= 0xfe || ch == 0xc9) \ { \ /* This is illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ else \ @@ -3079,7 +3079,7 @@ static const char uhc_hangul_from_ucs[11172][2] = { \ /* The second character is not available. Store \ the intermediate result. */ \ - result = GCONV_INCOMPLETE_INPUT; \ + result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ \ @@ -3109,7 +3109,7 @@ static const char uhc_hangul_from_ucs[11172][2] = || (ch2 > 0x7a && ch2 < 0x81) || (ch == 0xc6 && ch2 > 0x52)) \ { \ /* This is not legal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -3122,7 +3122,7 @@ static const char uhc_hangul_from_ucs[11172][2] = if (ch == 0) \ { \ /* This is an illegal character. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -3131,10 +3131,10 @@ static const char uhc_hangul_from_ucs[11172][2] = else \ { \ ch = ksc5601_to_ucs4 (&inptr, 2, 0x80); \ - if (ch == UNKNOWN_10646_CHAR) \ + if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal. */ \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ } \ @@ -3163,7 +3163,7 @@ static const char uhc_hangul_from_ucs[11172][2] = \ if (NEED_LENGTH_TEST && outptr + 2 > outend) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ @@ -3178,12 +3178,12 @@ static const char uhc_hangul_from_ucs[11172][2] = \ if (NEED_LENGTH_TEST && written == 0) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ - if (written == UNKNOWN_10646_CHAR) \ + if (written == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -3202,12 +3202,12 @@ static const char uhc_hangul_from_ucs[11172][2] = \ if (NEED_LENGTH_TEST && written == 0) \ { \ - result = GCONV_FULL_OUTPUT; \ + result = __GCONV_FULL_OUTPUT; \ break; \ } \ - if (written == UNKNOWN_10646_CHAR) \ + if (written == __UNKNOWN_10646_CHAR) \ { \ - result = GCONV_ILLEGAL_INPUT; \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ diff --git a/include/limits.h b/include/limits.h index 21520f3..71222d7 100644 --- a/include/limits.h +++ b/include/limits.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 96, 97, 98, 99 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 @@ -42,7 +42,7 @@ /* Maximum length of any multibyte character in any locale. We define this value here since the gcc header does not define the correct value. */ -#define MB_LEN_MAX 6 +#define MB_LEN_MAX 16 /* If we are not using GNU CC we have to define all the symbols ourself. diff --git a/include/wchar.h b/include/wchar.h index 33166ed..fb8ece5 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -1,32 +1,47 @@ #ifndef _WCHAR_H #include <wcsmbs/wchar.h> +# ifdef _WCHAR_H /* Now define the internal interfaces. */ extern int __wcscasecmp __P ((__const wchar_t *__s1, __const wchar_t *__s2)); extern int __wcsncasecmp __P ((__const wchar_t *__s1, __const wchar_t *__s2, size_t __n)); extern size_t __wcsnlen __P ((__const wchar_t *__s, size_t __maxlen)); extern wint_t __btowc __P ((int __c)); -extern int __mbsinit __P ((__const mbstate_t *__ps)); +extern int __mbsinit __P ((__const __mbstate_t *__ps)); extern size_t __mbrtowc __P ((wchar_t *__restrict __pwc, __const char *__restrict __s, size_t __n, - mbstate_t *__restrict __p)); + __mbstate_t *__restrict __p)); extern size_t __wcrtomb __P ((char *__restrict __s, wchar_t __wc, - mbstate_t *__restrict __ps)); + __mbstate_t *__restrict __ps)); extern size_t __mbsrtowcs __P ((wchar_t *__restrict __dst, __const char **__restrict __src, - size_t __len, mbstate_t *__restrict __ps)); + size_t __len, __mbstate_t *__restrict __ps)); extern size_t __wcsrtombs __P ((char *__restrict __dst, __const wchar_t **__restrict __src, - size_t __len, mbstate_t *__restrict __ps)); + size_t __len, __mbstate_t *__restrict __ps)); extern size_t __mbsnrtowcs __P ((wchar_t *__restrict __dst, __const char **__restrict __src, size_t __nmc, - size_t __len, mbstate_t *__restrict __ps)); + size_t __len, __mbstate_t *__restrict __ps)); extern size_t __wcsnrtombs __P ((char *__restrict __dst, __const wchar_t **__restrict __src, size_t __nwc, size_t __len, - mbstate_t *__restrict __ps)); + __mbstate_t *__restrict __ps)); extern wchar_t *__wcpcpy __P ((wchar_t *__dest, __const wchar_t *__src)); extern wchar_t *__wcpncpy __P ((wchar_t *__dest, __const wchar_t *__src, size_t __n)); +extern wchar_t *__wmemcpy __P ((wchar_t *__s1, __const wchar_t *s2, + size_t __n)); +extern wchar_t *__wmempcpy __P ((wchar_t *__restrict __s1, + __const wchar_t *__restrict __s2, + size_t __n)); +extern wchar_t *__wmemmove __P ((wchar_t *__s1, __const wchar_t *__s2, + size_t __n)); +extern wchar_t *__wcschrnul __P ((__const wchar_t *__s, wchar_t __wc)); + +extern int __vfwscanf __P ((FILE *__restrict __s, + __const wchar_t *__restrict __format, + va_list __arg)) + /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; +# endif #endif diff --git a/libio/Makefile b/libio/Makefile index 948556e..6fcde40 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -25,11 +25,16 @@ headers := stdio.h libio.h _G_config.h bits/stdio.h routines := \ filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \ - iofopncook iofputs iofread iofsetpos ioftell \ + iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc \ iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs \ ioseekoff ioseekpos iosetbuffer iosetvbuf iosprintf ioungetc \ iovsprintf iovsscanf \ iofgetpos64 iofopen64 iofsetpos64 \ + oldiofgetpos oldiofgetpos64 oldiofsetpos oldiofsetpos64 \ + fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \ + iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u \ + putchar putchar_u swprintf vwprintf wprintf wscanf fwscanf vwscanf \ + vswprintf iovswscanf swscanf wgenops wstrops wfileops iofwide \ \ clearerr feof ferror fileno fputc freopen fseek getc getchar \ memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \ @@ -38,6 +43,8 @@ routines := \ \ libc_fatal +tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf + all: # Make this the default target; it will be defined in Rules. include ../Makeconfig diff --git a/libio/Versions b/libio/Versions index 61b767a..c7a5f66 100644 --- a/libio/Versions +++ b/libio/Versions @@ -100,4 +100,31 @@ libc { # p* pclose; popen; } + GLIBC_2.2 { + # functions used in libstdc++ + _IO_fgetpos; _IO_fgetpos64; _IO_fsetpos; _IO_fsetpos64; + + # f* + fgetpos; fgetpos64; fgetwc; fgetwc_unlocked; fgetws; fgetws_unlocked; + fputwc; fputwc_unlocked; fputws; fputws_unlocked; fsetpos; fsetpos64; + fwide; fwprintf; fwscanf; + + # g* + getwc; getwc_unlocked; getwchar; getwchar_unlocked; + + # p* + putwc; putwc_unlocked; putwchar; putwchar_unlocked; + + # s* + swprintf; swscanf; + + # u* + ungetwc; + + # v* + vfwprintf; vswprintf; vwprintf; vfwscanf; vswscanf; vwscanf; + + # w* + wprintf; wscanf; + } } diff --git a/libio/fileops.c b/libio/fileops.c index f5ec0e2..8d480ad 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. Written by Per Bothner <bothner@cygnus.com>. @@ -136,9 +136,18 @@ _IO_new_file_close_it (fp) close_status = _IO_SYSCLOSE (fp); /* Free buffer. */ - _IO_setb (fp, NULL, NULL, 0); - _IO_setg (fp, NULL, NULL, NULL); - _IO_setp (fp, NULL, NULL); + if (fp->_mode <= 0) + { + _IO_setb (fp, NULL, NULL, 0); + _IO_setg (fp, NULL, NULL, NULL); + _IO_setp (fp, NULL, NULL); + } + else + { + _IO_wsetb (fp, NULL, NULL, 0); + _IO_wsetg (fp, NULL, NULL, NULL); + _IO_wsetp (fp, NULL, NULL); + } _IO_un_link (fp); fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; @@ -277,14 +286,14 @@ _IO_new_file_setbuf (fp, p, len) char *p; _IO_ssize_t len; { - if (_IO_default_setbuf (fp, p, len) == NULL) - return NULL; + if (_IO_default_setbuf (fp, p, len) == NULL) + return NULL; - fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end - = fp->_IO_buf_base; - _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); - return fp; + return fp; } static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); @@ -319,7 +328,7 @@ new_do_write (fp, data, to_do) fp->_offset = _IO_pos_BAD; else if (fp->_IO_read_end != fp->_IO_write_base) { - _IO_fpos64_t new_pos + _IO_off64_t new_pos = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); if (new_pos == _IO_pos_BAD) return 0; @@ -330,7 +339,8 @@ new_do_write (fp, data, to_do) fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1; _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base; - fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + fp->_IO_write_end = (fp->_mode < 0 + && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) ? fp->_IO_buf_base : fp->_IO_buf_end); return count; } @@ -410,7 +420,7 @@ _IO_new_file_overflow (f, ch) return EOF; } /* If currently reading or no buffer allocated. */ - if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0) { /* Allocate a buffer if needed. */ if (f->_IO_write_base == 0) @@ -433,18 +443,20 @@ _IO_new_file_overflow (f, ch) f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; f->_flags |= _IO_CURRENTLY_PUTTING; - if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + if (f->_mode < 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) f->_IO_write_end = f->_IO_write_ptr; } if (ch == EOF) - return _IO_do_flush (f); + return _IO_new_do_write(f, f->_IO_write_base, + f->_IO_write_ptr - f->_IO_write_base); if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ if (_IO_do_flush (f) == EOF) return EOF; *f->_IO_write_ptr++ = ch; if ((f->_flags & _IO_UNBUFFERED) || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) - if (_IO_do_flush (f) == EOF) + if (_IO_new_do_write(f, f->_IO_write_base, + f->_IO_write_ptr - f->_IO_write_base) == EOF) return EOF; return (unsigned char) ch; } @@ -483,14 +495,14 @@ _IO_new_file_sync (fp) return retval; } -_IO_fpos64_t +_IO_off64_t _IO_new_file_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off64_t offset; int dir; int mode; { - _IO_fpos64_t result; + _IO_off64_t result; _IO_off64_t delta, new_offset; long count; /* POSIX.1 8.2.3.7 says that after a call the fflush() the file @@ -534,7 +546,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode) if (fp->_offset == _IO_pos_BAD) goto dumb; /* Make offset absolute, assuming current pointer is file_ptr(). */ - offset += _IO_pos_as_off (fp->_offset); + offset += fp->_offset; dir = _IO_seek_set; break; @@ -563,8 +575,8 @@ _IO_new_file_seekoff (fp, offset, dir, mode) && !_IO_in_backup (fp)) { /* Offset relative to start of main get area. */ - _IO_fpos64_t rel_offset = (offset - fp->_offset - + (fp->_IO_read_end - fp->_IO_read_base)); + _IO_off64_t rel_offset = (offset - fp->_offset + + (fp->_IO_read_end - fp->_IO_read_base)); if (rel_offset >= 0) { #if 0 @@ -678,7 +690,7 @@ _IO_file_read (fp, buf, size) return read (fp->_fileno, buf, size); } -_IO_fpos64_t +_IO_off64_t _IO_file_seek (fp, offset, dir) _IO_FILE *fp; _IO_off64_t offset; @@ -720,7 +732,7 @@ _IO_new_file_write (f, data, n) while (to_do > 0) { _IO_ssize_t count = write (f->_fileno, data, to_do); - if (count == EOF) + if (count < 0) { f->_flags |= _IO_ERR_SEEN; break; @@ -740,7 +752,7 @@ _IO_new_file_xsputn (f, data, n) const void *data; _IO_size_t n; { - register const char *s = (char *) data; + register const char *s = (const char *) data; _IO_size_t to_do = n; int must_flush = 0; _IO_size_t count; diff --git a/libio/fputwc.c b/libio/fputwc.c new file mode 100644 index 0000000..cc8451a --- /dev/null +++ b/libio/fputwc.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +fputwc (wc, fp) + wint_t wc; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_fwide (fp, 1) < 0) + result = WEOF; + else + result = _IO_putwc_unlocked (wc, fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/fputwc_u.c b/libio/fputwc_u.c new file mode 100644 index 0000000..343e34d --- /dev/null +++ b/libio/fputwc_u.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +#undef fputwc_unlocked + +wint_t +fputwc_unlocked (wc, fp) + wint_t wc; + _IO_FILE *fp; +{ + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, 1) < 0) + return WEOF; + return _IO_putwc_unlocked (wc, fp); +} diff --git a/libio/ftello.c b/libio/ftello.c index 2d8a8a7..ed4ef8b 100644 --- a/libio/ftello.c +++ b/libio/ftello.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -32,13 +32,19 @@ off_t ftello (fp) _IO_FILE *fp; { - _IO_pos_t pos; + _IO_off_t pos; CHECK_FILE (fp, -1L); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); if (_IO_in_backup (fp)) - pos -= fp->_IO_save_end - fp->_IO_save_base; + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + else + /* XXX Not done yet. */ + abort (); + } _IO_funlockfile (fp); _IO_cleanup_region_end (0); if (pos == _IO_pos_BAD) @@ -49,5 +55,5 @@ ftello (fp) #endif return -1L; } - return _IO_pos_as_off (pos); + return pos; } diff --git a/libio/ftello64.c b/libio/ftello64.c index 6214549..7cb7562 100644 --- a/libio/ftello64.c +++ b/libio/ftello64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -33,13 +33,18 @@ ftello64 (fp) _IO_FILE *fp; { #ifdef _G_LSEEK64 - _IO_pos_t pos; + _IO_off64_t pos; CHECK_FILE (fp, -1L); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); if (_IO_in_backup (fp)) - pos -= fp->_IO_save_end - fp->_IO_save_base; + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + else + abort (); + } _IO_funlockfile (fp); _IO_cleanup_region_end (0); if (pos == _IO_pos_BAD) @@ -50,7 +55,7 @@ ftello64 (fp) #endif return -1L; } - return _IO_pos_as_off (pos); + return pos; #else __set_errno (ENOSYS); return -1; diff --git a/libio/fwprintf.c b/libio/fwprintf.c new file mode 100644 index 0000000..c26a2ff --- /dev/null +++ b/libio/fwprintf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#include <wchar.h> + + +/* Write formatted output to STREAM from the format string FORMAT. */ +/* VARARGS2 */ +int +fwprintf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = vfwprintf (stream, format, arg); + va_end (arg); + + return done; +} diff --git a/libio/fwscanf.c b/libio/fwscanf.c new file mode 100644 index 0000000..4510fc5 --- /dev/null +++ b/libio/fwscanf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#include <wchar.h> + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +fwscanf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwscanf (stream, format, arg); + va_end (arg); + + return done; +} diff --git a/libio/genops.c b/libio/genops.c index 81752e3..a8f3446 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -80,9 +80,9 @@ _IO_link_in (fp) /* Return minimum _pos markers Assumes the current get area is the main get area. */ -static _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p)); +_IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p)); -static _IO_ssize_t +_IO_ssize_t _IO_least_marker (fp, end_p) _IO_FILE *fp; char *end_p; @@ -282,6 +282,9 @@ int __underflow (fp) _IO_FILE *fp; { + if (_IO_fwide (fp, -1) != -1) + return EOF; + if (_IO_in_put_mode (fp)) if (_IO_switch_to_get_mode (fp) == EOF) return EOF; @@ -307,6 +310,9 @@ int __uflow (fp) _IO_FILE *fp; { + if (_IO_fwide (fp, -1) != -1) + return EOF; + if (_IO_in_put_mode (fp)) if (_IO_switch_to_get_mode (fp) == EOF) return EOF; @@ -508,13 +514,13 @@ _IO_default_setbuf (fp, p, len) return fp; } -_IO_fpos64_t +_IO_off64_t _IO_default_seekpos (fp, pos, mode) _IO_FILE *fp; - _IO_fpos64_t pos; + _IO_off64_t pos; int mode; { - return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode); + return _IO_SEEKOFF (fp, pos, 0, mode); } int @@ -533,6 +539,17 @@ _IO_init (fp, flags) _IO_FILE *fp; int flags; { + _IO_no_init (fp, flags, -1, NULL, NULL); +} + +void +_IO_no_init (fp, flags, orientation, wd, jmp) + _IO_FILE *fp; + int flags; + int orientation; + struct _IO_wide_data *wd; + struct _IO_jump_t *jmp; +{ fp->_flags = _IO_MAGIC|flags; fp->_IO_buf_base = NULL; fp->_IO_buf_end = NULL; @@ -555,6 +572,24 @@ _IO_init (fp, flags) #ifdef _IO_MTSAFE_IO _IO_lock_init (*fp->_lock); #endif + fp->_mode = orientation; + if (orientation >= 0) + { + fp->_wide_data = wd; + fp->_wide_data->_IO_buf_base = NULL; + fp->_wide_data->_IO_buf_end = NULL; + fp->_wide_data->_IO_read_base = NULL; + fp->_wide_data->_IO_read_ptr = NULL; + fp->_wide_data->_IO_read_end = NULL; + fp->_wide_data->_IO_write_base = NULL; + fp->_wide_data->_IO_write_ptr = NULL; + fp->_wide_data->_IO_write_end = NULL; + fp->_wide_data->_IO_save_base = NULL; + fp->_wide_data->_IO_backup_base = NULL; + fp->_wide_data->_IO_save_end = NULL; + + fp->_wide_data->_wide_vtable = jmp; + } } int @@ -595,7 +630,7 @@ _IO_default_finish (fp, dummy) _IO_un_link (fp); } -_IO_fpos64_t +_IO_off64_t _IO_default_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off64_t offset; @@ -706,7 +741,9 @@ _IO_flush_all () int result = 0; _IO_FILE *fp; for (fp = _IO_list_all; fp != NULL; fp = fp->_chain) - if (fp->_IO_write_ptr > fp->_IO_write_base + if (((fp->_mode < 0 && fp->_IO_write_ptr > fp->_IO_write_base) + || (fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr + > fp->_wide_data->_IO_write_base))) && _IO_OVERFLOW (fp, EOF) == EOF) result = EOF; return result; @@ -941,7 +978,7 @@ _IO_default_pbackfail (fp, c) return (unsigned char) c; } -_IO_fpos64_t +_IO_off64_t _IO_default_seek (fp, offset, dir) _IO_FILE *fp; _IO_off64_t offset; diff --git a/libio/getwc.c b/libio/getwc.c new file mode 100644 index 0000000..0829ea0 --- /dev/null +++ b/libio/getwc.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +#undef _IO_getwc + +wint_t +_IO_getwc (fp) + FILE *fp; +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_getwc_unlocked (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#undef getwc + +#ifdef weak_alias +weak_alias (_IO_getwc, getwc) +weak_alias (_IO_getwc, fgetwc) +#endif diff --git a/libio/getwc_u.c b/libio/getwc_u.c new file mode 100644 index 0000000..606b4d2 --- /dev/null +++ b/libio/getwc_u.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getwc_unlocked + +wint_t +__getwc_unlocked (FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_getwc_unlocked (fp); +} + +weak_alias (__getwc_unlocked, getwc_unlocked) +weak_alias (__getwc_unlocked, fgetwc_unlocked) diff --git a/libio/getwchar.c b/libio/getwchar.c new file mode 100644 index 0000000..6ef1f9b --- /dev/null +++ b/libio/getwchar.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +#undef getwchar + +wint_t +getwchar () +{ + wint_t result; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdin); + _IO_flockfile (_IO_stdin); + result = _IO_getwc_unlocked (_IO_stdin); + _IO_funlockfile (_IO_stdin); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/getwchar_u.c b/libio/getwchar_u.c new file mode 100644 index 0000000..18dc2ca --- /dev/null +++ b/libio/getwchar_u.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +#undef getwchar_unlocked + +wint_t +getwchar_unlocked () +{ + return _IO_getwc_unlocked (_IO_stdin); +} diff --git a/libio/iofdopen.c b/libio/iofdopen.c index 40419bd..3bfa40c 100644 --- a/libio/iofdopen.c +++ b/libio/iofdopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -50,6 +50,7 @@ _IO_new_fdopen (fd, mode) #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif + struct _IO_wide_data wd; } *new_f; int fd_flags; @@ -112,7 +113,7 @@ _IO_new_fdopen (fd, mode) #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif - _IO_init (&new_f->fp.file, 0); + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; _IO_file_init (&new_f->fp.file); #if !_IO_UNIFIED_JUMPTABLES diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c index 27f018d..5b8f6a4 100644 --- a/libio/iofgetpos.c +++ b/libio/iofgetpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -27,11 +27,11 @@ #include <errno.h> int -_IO_fgetpos (fp, posp) +_IO_new_fgetpos (fp, posp) _IO_FILE *fp; _IO_fpos_t *posp; { - _IO_fpos_t pos; + _IO_off_t pos; CHECK_FILE (fp, EOF); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); @@ -50,10 +50,16 @@ _IO_fgetpos (fp, posp) #endif return EOF; } - *posp = pos; + posp->__pos = pos; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; return 0; } #ifdef weak_alias -weak_alias (_IO_fgetpos, fgetpos) +strong_alias (_IO_new_fgetpos, __new_fgetpos) +default_symbol_version (_IO_new_fgetpos, _IO_fgetpos, GLIBC_2.2); +default_symbol_version (__new_fgetpos, fgetpos, GLIBC_2.2); #endif diff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c index a705e9e..cc39a3a 100644 --- a/libio/iofgetpos64.c +++ b/libio/iofgetpos64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -27,12 +27,12 @@ #include <errno.h> int -_IO_fgetpos64 (fp, posp) +_IO_new_fgetpos64 (fp, posp) _IO_FILE *fp; _IO_fpos64_t *posp; { #ifdef _G_LSEEK64 - _IO_fpos64_t pos; + _IO_off64_t pos; CHECK_FILE (fp, EOF); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); @@ -45,13 +45,17 @@ _IO_fgetpos64 (fp, posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO +# ifdef EIO if (errno == 0) __set_errno (EIO); -#endif +# endif return EOF; } - *posp = pos; + posp->__pos = pos; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; return 0; #else __set_errno (ENOSYS); @@ -60,5 +64,7 @@ _IO_fgetpos64 (fp, posp) } #ifdef weak_alias -weak_alias (_IO_fgetpos64, fgetpos64) +default_symbol_version (_IO_new_fgetpos64, _IO_fgetpos64, GLIBC_2.2); +strong_alias (_IO_new_fgetpos64, __new_fgetpos64) +default_symbol_version (__new_fgetpos64, fgetpos64, GLIBC_2.2); #endif diff --git a/libio/iofgetws.c b/libio/iofgetws.c new file mode 100644 index 0000000..25ed836 --- /dev/null +++ b/libio/iofgetws.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +wchar_t * +fgetws (buf, n, fp) + wchar_t *buf; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + wchar_t *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, n - 1, L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/iofgetws_u.c b/libio/iofgetws_u.c new file mode 100644 index 0000000..951ab80 --- /dev/null +++ b/libio/iofgetws_u.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +wchar_t * +fgetws_unlocked (buf, n, fp) + wchar_t *buf; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + wchar_t *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, n - 1, L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + return result; +} diff --git a/libio/iofopen.c b/libio/iofopen.c index 92d58bb..60b15a0 100644 --- a/libio/iofopen.c +++ b/libio/iofopen.c @@ -39,6 +39,7 @@ _IO_new_fopen (filename, mode) #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif + struct _IO_wide_data wd; } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) @@ -46,7 +47,7 @@ _IO_new_fopen (filename, mode) #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif - _IO_init (&new_f->fp.file, 0); + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; _IO_file_init (&new_f->fp.file); #if !_IO_UNIFIED_JUMPTABLES diff --git a/libio/iofopen64.c b/libio/iofopen64.c index b071a0e..0dc19b2 100644 --- a/libio/iofopen64.c +++ b/libio/iofopen64.c @@ -40,6 +40,7 @@ _IO_fopen64 (filename, mode) #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif + struct _IO_wide_data wd; } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) @@ -47,7 +48,7 @@ _IO_fopen64 (filename, mode) #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif - _IO_init (&new_f->fp.file, 0); + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; _IO_file_init (&new_f->fp.file); #if !_IO_UNIFIED_JUMPTABLES diff --git a/libio/iofopncook.c b/libio/iofopncook.c index f26744f..85ea35c 100644 --- a/libio/iofopncook.c +++ b/libio/iofopncook.c @@ -33,8 +33,8 @@ static _IO_ssize_t _IO_cookie_read __P ((register _IO_FILE* fp, void* buf, _IO_ssize_t size)); static _IO_ssize_t _IO_cookie_write __P ((register _IO_FILE* fp, const void* buf, _IO_ssize_t size)); -static _IO_fpos64_t _IO_cookie_seek __P ((_IO_FILE *fp, _IO_off64_t offset, - int dir)); +static _IO_off64_t _IO_cookie_seek __P ((_IO_FILE *fp, _IO_off64_t offset, + int dir)); static int _IO_cookie_close __P ((_IO_FILE* fp)); @@ -66,7 +66,7 @@ _IO_cookie_write (fp, buf, size) return cfile->__io_functions.write (cfile->__cookie, buf, size); } -static _IO_fpos64_t +static _IO_off64_t _IO_cookie_seek (fp, offset, dir) _IO_FILE *fp; _IO_off64_t offset; diff --git a/libio/iofputs.c b/libio/iofputs.c index 1805387..ed41d5a 100644 --- a/libio/iofputs.c +++ b/libio/iofputs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -32,13 +32,12 @@ _IO_fputs (str, fp) _IO_FILE *fp; { _IO_size_t len = strlen (str); - int result; + int result = EOF; CHECK_FILE (fp, EOF); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); - if (_IO_sputn (fp, str, len) != len) - result = EOF; - else + if (_IO_fwide (fp, -1) == -1 + && _IO_sputn (fp, str, len) == len) result = 1; _IO_funlockfile (fp); _IO_cleanup_region_end (0); diff --git a/libio/iofputs_u.c b/libio/iofputs_u.c index dfd91ab..556522b 100644 --- a/libio/iofputs_u.c +++ b/libio/iofputs_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -33,11 +33,9 @@ fputs_unlocked (str, fp) _IO_FILE *fp; { _IO_size_t len = strlen (str); - int result; + int result = EOF; CHECK_FILE (fp, EOF); - if (_IO_sputn (fp, str, len) != len) - result = EOF; - else + if (_IO_fwide (fp, -1) == -1 && _IO_sputn (fp, str, len) == len) result = 1; return result; } diff --git a/libio/iofputws.c b/libio/iofputws.c new file mode 100644 index 0000000..daad1b9 --- /dev/null +++ b/libio/iofputws.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +int +fputws (str, fp) + const wchar_t *str; + _IO_FILE *fp; +{ + _IO_size_t len = wcslen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_fwide (fp, 1) == 1 + && _IO_sputn (fp, (char *) str, len) == len) + result = 1; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/iofputws_u.c b/libio/iofputws_u.c new file mode 100644 index 0000000..a5749cd --- /dev/null +++ b/libio/iofputws_u.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <stdio.h> +#include <wchar.h> + +int +fputws_unlocked (str, fp) + const wchar_t *str; + _IO_FILE *fp; +{ + _IO_size_t len = wcslen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, 1) == 1 + && _IO_sputn (fp, (char *) str, len) == len) + result = 1; + return result; +} diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c index cbf7734..bd49c13 100644 --- a/libio/iofsetpos.c +++ b/libio/iofsetpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -27,7 +27,7 @@ #include <errno.h> int -_IO_fsetpos (fp, posp) +_IO_new_fsetpos (fp, posp) _IO_FILE *fp; const _IO_fpos_t *posp; { @@ -35,7 +35,7 @@ _IO_fsetpos (fp, posp) CHECK_FILE (fp, EOF); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); - if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) + if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) { /* ANSI explicitly requires setting errno to a positive value on failure. */ @@ -46,12 +46,20 @@ _IO_fsetpos (fp, posp) result = EOF; } else - result = 0; + { + result = 0; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, restore the state. */ + fp->_wide_data->_IO_state = posp->__state; + } _IO_funlockfile (fp); _IO_cleanup_region_end (0); return result; } #ifdef weak_alias -weak_alias (_IO_fsetpos, fsetpos) +default_symbol_version (_IO_new_fsetpos, _IO_fsetpos, GLIBC_2.2); +strong_alias (_IO_new_fsetpos, __new_fsetpos) +default_symbol_version (__new_fsetpos, fsetpos, GLIBC_2.2); #endif diff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c index 13ce0fb..a70d5e2 100644 --- a/libio/iofsetpos64.c +++ b/libio/iofsetpos64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -27,7 +27,7 @@ #include <errno.h> int -_IO_fsetpos64 (fp, posp) +_IO_new_fsetpos64 (fp, posp) _IO_FILE *fp; const _IO_fpos64_t *posp; { @@ -36,7 +36,7 @@ _IO_fsetpos64 (fp, posp) CHECK_FILE (fp, EOF); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); - if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) + if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) { /* ANSI explicitly requires setting errno to a positive value on failure. */ @@ -47,7 +47,13 @@ _IO_fsetpos64 (fp, posp) result = EOF; } else - result = 0; + { + result = 0; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + fp->_wide_data->_IO_state = posp->__state; + } _IO_funlockfile (fp); _IO_cleanup_region_end (0); return result; @@ -58,5 +64,7 @@ _IO_fsetpos64 (fp, posp) } #ifdef weak_alias -weak_alias (_IO_fsetpos64, fsetpos64) +default_symbol_version (_IO_new_fsetpos64, _IO_fsetpos64, GLIBC_2.2); +strong_alias (_IO_new_fsetpos64, __new_fsetpos64) +default_symbol_version (__new_fsetpos64, fsetpos64, GLIBC_2.2); #endif diff --git a/libio/ioftell.c b/libio/ioftell.c index 3de1ee9..1f25b66 100644 --- a/libio/ioftell.c +++ b/libio/ioftell.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -31,13 +31,19 @@ long int _IO_ftell (fp) _IO_FILE *fp; { - _IO_pos_t pos; + _IO_off_t pos; CHECK_FILE (fp, -1L); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); if (_IO_in_backup (fp)) - pos -= fp->_IO_save_end - fp->_IO_save_base; + { + if (fp->_mode < 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + else + /* XXX For now. */ + abort (); + } _IO_funlockfile (fp); _IO_cleanup_region_end (0); if (pos == _IO_pos_BAD) @@ -48,7 +54,7 @@ _IO_ftell (fp) #endif return -1L; } - return _IO_pos_as_off (pos); + return pos; } #ifdef weak_alias diff --git a/libio/iofwide.c b/libio/iofwide.c new file mode 100644 index 0000000..853920a --- /dev/null +++ b/libio/iofwide.c @@ -0,0 +1,365 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include <libioP.h> +#ifdef _LIBC +# include <wchar.h> +#endif +#include <stdlib.h> +#include <string.h> + +#ifdef _LIBC +# include <langinfo.h> +# include <locale/localeinfo.h> +# include <wcsmbs/wcsmbsload.h> +#endif + + +/* Prototypes of libio's codecvt functions. */ +static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const wchar_t *from_start, + const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt, + __mbstate_t *statep, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const char *from_start, + const char *from_end, + const char **from_stop, wchar_t *to_start, + wchar_t *to_end, wchar_t **to_stop); +static int do_encoding (struct _IO_codecvt *codecvt); +static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, + const char *from_end, _IO_size_t max); +static int do_max_length (struct _IO_codecvt *codecvt); +static int do_always_noconv (struct _IO_codecvt *codecvt); + + +/* The functions used in `codecvt' for libio are always the same. */ +static struct _IO_codecvt libio_codecvt = +{ + .__codecvt_destr = NULL, /* Destructor, never used. */ + .__codecvt_do_out = do_out, + .__codecvt_do_unshift = do_unshift, + .__codecvt_do_in = do_in, + .__codecvt_do_encoding = do_encoding, + .__codecvt_do_always_noconv = do_always_noconv, + .__codecvt_do_length = do_length, + .__codecvt_do_max_length = do_max_length +}; + + +/* Return orientation of stream. If mode is nonzero try to change + the orientation first. */ +#undef _IO_fwide +int +_IO_fwide (fp, mode) + _IO_FILE *fp; + int mode; +{ + /* Normalize the value. */ + mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); + + if (mode == 0 || fp->_mode != 0) + /* The caller simply wants to know about the current orientation + or the orientation already has been determined. */ + return fp->_mode; + + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + + /* Set the orientation appropriately. */ + if (mode > 0) + { + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; + + /* Clear the state. We start all over again. */ + memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); + memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t)); + + /* Get the character conversion functions based on the currently + selected locale for LC_CTYPE. */ +#ifdef _LIBC + { + struct gconv_fcts fcts; + struct _IO_codecvt *cc = &fp->_wide_data->_codecvt; + + __wcsmbs_clone_conv (&fcts); + + /* The functions are always the same. */ + *cc = libio_codecvt; + + cc->__cd_in.__cd.__nsteps = 1; /* Only one step allowed. */ + cc->__cd_in.__cd.__steps = fcts.towc; + + cc->__cd_in.__cd.__data[0].__invocation_counter = 0; + cc->__cd_in.__cd.__data[0].__internal_use = 1; + cc->__cd_in.__cd.__data[0].__is_last = 1; + cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + + cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */ + cc->__cd_out.__cd.__steps = fcts.tomb; + + cc->__cd_out.__cd.__data[0].__invocation_counter = 0; + cc->__cd_out.__cd.__data[0].__internal_use = 1; + cc->__cd_out.__cd.__data[0].__is_last = 1; + cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + } +#else +# error "somehow determine this from LC_CTYPE" +#endif + + /* From now on use the wide character callback functions. */ + ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable; + } + + /* Set the mode now. */ + fp->_mode = mode; + + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + + return mode; +} + +#ifdef weak_alias +weak_alias (_IO_fwide, fwide) +#endif + + +static enum __codecvt_result +do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const wchar_t *from_start, const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, char *to_end, + char **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t written; + const unsigned char *from_start_copy = (unsigned char *) from_start; + + codecvt->__cd_out.__cd.__data[0].__outbuf = to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + status = (*gs->__fct) (gs, codecvt->__cd_out.__cd.__data, &from_start_copy, + (const unsigned char *) from_end, &written, 0); + + *from_stop = (wchar_t *) from_start_copy; + *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else + /* Decide what to do. */ + result = __codecvt_error; +#endif + + return result; +} + + +static enum __codecvt_result +do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, + char *to_start, char *to_end, char **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t written; + + codecvt->__cd_out.__cd.__data[0].__outbuf = to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + status = (*gs->__fct) (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, + &written, 1); + + *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else + /* Decide what to do. */ + result = __codecvt_error; +#endif + + return result; +} + + +static enum __codecvt_result +do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, const char **from_stop, + wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; + int status; + size_t written; + const unsigned char *from_start_copy = (unsigned char *) from_start; + + codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_start; + codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) to_end; + codecvt->__cd_in.__cd.__data[0].__statep = statep; + + status = (*gs->__fct) (gs, codecvt->__cd_in.__cd.__data, &from_start_copy, + from_end, &written, 0); + + *from_stop = from_start_copy; + *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else + /* Decide what to do. */ + result = __codecvt_error; +#endif + + return result; +} + + +static int +do_encoding (struct _IO_codecvt *codecvt) +{ +#ifdef _LIBC + /* See whether the encoding is stateful. */ + if (codecvt->__cd_in.__cd.__steps[0].__stateful) + return -1; + /* Fortunately not. Now determine the input bytes for the conversion + necessary for each wide character. */ + if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from + != codecvt->__cd_in.__cd.__steps[0].__max_needed_from) + /* Not a constant value. */ + return 0; + + return codecvt->__cd_in.__cd.__steps[0].__min_needed_from; +#else + /* Worst case scenario. */ + return -1; +#endif +} + + +static int +do_always_noconv (struct _IO_codecvt *codecvt) +{ + return 0; +} + + +static int +do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, _IO_size_t max) +{ + int result; +#ifdef _LIBC + const unsigned char *cp = (const unsigned char *) from_start; + wchar_t to_buf[max]; + struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; + int status; + size_t written; + + codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_buf; + codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) &to_buf[max]; + codecvt->__cd_in.__cd.__data[0].__statep = statep; + + status = (*gs->__fct) (gs, codecvt->__cd_in.__cd.__data, &cp, from_end, + &written, 0); + + result = cp - (const unsigned char *) from_start; +#else + /* Decide what to do. */ + result = 0; +#endif + + return result; +} + + +static int +do_max_length (struct _IO_codecvt *codecvt) +{ +#ifdef _LIBC + return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; +#else + return MB_CUR_MAX; +#endif +} diff --git a/libio/iofwrite.c b/libio/iofwrite.c index d163d29..886de7a 100644 --- a/libio/iofwrite.c +++ b/libio/iofwrite.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -33,7 +33,7 @@ _IO_fwrite (buf, size, count, fp) _IO_FILE *fp; { _IO_size_t request = size * count; - _IO_size_t written; + _IO_size_t written = 0; CHECK_FILE (fp, 0); /* Many traditional implementations return 0 if size==0 && count > 0, but ANSI requires us to return count in this case. */ @@ -41,7 +41,8 @@ _IO_fwrite (buf, size, count, fp) return count; _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); - written = _IO_sputn (fp, (const char *) buf, request); + if (_IO_fwide (fp, -1) == -1) + written = _IO_sputn (fp, (const char *) buf, request); _IO_funlockfile (fp); _IO_cleanup_region_end (0); if (written == request) diff --git a/libio/iofwrite_u.c b/libio/iofwrite_u.c index 38d1bd0..acb5b2f 100644 --- a/libio/iofwrite_u.c +++ b/libio/iofwrite_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -36,15 +36,18 @@ fwrite_unlocked (buf, size, count, fp) _IO_FILE *fp; { _IO_size_t request = size * count; - _IO_size_t written; + _IO_size_t written = 0; CHECK_FILE (fp, 0); /* Many traditional implementations return 0 if size==0 && count > 0, but ANSI requires us to return count in this case. */ if (request == 0) return count; - written = _IO_sputn (fp, (const char *) buf, request); - if (written == request) - return count; - else - return written / size; + if (_IO_fwide (fp, -1) == -1) + { + written = _IO_sputn (fp, (const char *) buf, request); + if (written == request) + return count; + } + + return written / size; } diff --git a/libio/iogetwline.c b/libio/iogetwline.c new file mode 100644 index 0000000..402158a --- /dev/null +++ b/libio/iogetwline.c @@ -0,0 +1,120 @@ +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <string.h> +#include <wchar.h> + +#if defined _LIBC || !_G_HAVE_IO_GETLINE_INFO + +_IO_size_t +_IO_getwline (fp, buf, n, delim, extract_delim) + _IO_FILE *fp; + wchar_t *buf; + _IO_size_t n; + wint_t delim; + int extract_delim; +{ + return _IO_getwline_info (fp, buf, n, delim, extract_delim, (wint_t *) 0); +} + +/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation. + + Read chars into buf (of size n), until delim is seen. + Return number of chars read (at most n). + Does not put a terminating '\0' in buf. + If extract_delim < 0, leave delimiter unread. + If extract_delim > 0, insert delim in output. */ + +_IO_size_t +_IO_getwline_info (fp, buf, n, delim, extract_delim, eof) + _IO_FILE *fp; + wchar_t *buf; + _IO_size_t n; + wint_t delim; + int extract_delim; + wint_t *eof; +{ + wchar_t *ptr = buf; + if (eof != NULL) + *eof = 0; + while (n != 0) + { + _IO_ssize_t len = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); + if (len <= 0) + { + wint_t wc = __wuflow (fp); + if (wc == WEOF) + { + if (eof) + *eof = wc; + break; + } + if (wc == delim) + { + if (extract_delim > 0) + *ptr++ = wc; + else if (extract_delim < 0) + _IO_sputbackc (fp, wc); + return ptr - buf; + if (extract_delim > 0) + ++len; + } + *ptr++ = wc; + n--; + } + else + { + wchar_t *t; + if ((_IO_size_t) len >= n) + len = n; + t = (wchar_t *) memchr ((void *) fp->_wide_data->_IO_read_ptr, + delim, len); + if (t != NULL) + { + _IO_size_t old_len = ptr - buf; + len = t - fp->_wide_data->_IO_read_ptr; + if (extract_delim >= 0) + { + ++t; + if (extract_delim > 0) + ++len; + } + memcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, + len); + fp->_wide_data->_IO_read_ptr = t; + return old_len + len; + } + memcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len); + fp->_wide_data->_IO_read_ptr += len; + ptr += len; + n -= len; + } + } + return ptr - buf; +} + +#endif /* Defined _LIBC || !_G_HAVE_IO_GETLINE_INFO */ diff --git a/libio/iolibio.h b/libio/iolibio.h index 7b25b40..92f25cf 100644 --- a/libio/iolibio.h +++ b/libio/iolibio.h @@ -41,13 +41,15 @@ extern int _IO_sprintf __P((char *, const char*, ...)); extern int _IO_ungetc __P((int, _IO_FILE*)); extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list)); extern int _IO_vsprintf __P((char*, const char*, _IO_va_list)); +extern int _IO_vswprintf __P((wchar_t*, _IO_size_t, const wchar_t*, + _IO_va_list)); struct obstack; extern int _IO_obstack_vprintf __P ((struct obstack *, const char *, _IO_va_list)); extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...)); #ifndef _IO_pos_BAD -#define _IO_pos_BAD ((_IO_fpos64_t)(-1)) +#define _IO_pos_BAD ((_IO_off64_t)(-1)) #endif #define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN)) #define _IO_fseek(__fp, __offset, __whence) \ diff --git a/libio/iopopen.c b/libio/iopopen.c index 6b2d7f5..15c1502 100644 --- a/libio/iopopen.c +++ b/libio/iopopen.c @@ -101,6 +101,8 @@ struct _IO_proc_file }; typedef struct _IO_proc_file _IO_proc_file; +static struct _IO_jump_t _IO_wproc_jumps; + static struct _IO_proc_file *proc_file_chain; _IO_FILE * @@ -186,6 +188,7 @@ _IO_new_popen (command, mode) #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif + struct _IO_wide_data wd; } *new_f; _IO_FILE *fp; @@ -196,7 +199,7 @@ _IO_new_popen (command, mode) new_f->fpx.file.file._lock = &new_f->lock; #endif fp = &new_f->fpx.file.file; - _IO_init (fp, 0); + _IO_no_init (fp, 0, 0, &new_f->wd, &_IO_wproc_jumps); _IO_JUMPS (fp) = &_IO_proc_jumps; _IO_new_file_init (fp); #if !_IO_UNIFIED_JUMPTABLES @@ -273,6 +276,29 @@ struct _IO_jump_t _IO_proc_jumps = { JUMP_INIT(imbue, _IO_default_imbue) }; +static struct _IO_jump_t _IO_wproc_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, _IO_new_file_overflow), + JUMP_INIT(underflow, _IO_new_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_new_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_new_proc_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + #if defined PIC && DO_VERSIONING strong_alias (_IO_new_popen, __new_popen) default_symbol_version (_IO_new_popen, _IO_popen, GLIBC_2.1); diff --git a/libio/ioputs.c b/libio/ioputs.c index 9ed8fe6..954b0f2 100644 --- a/libio/ioputs.c +++ b/libio/ioputs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -30,16 +30,17 @@ int _IO_puts (str) const char *str; { - int result; + int result = EOF; _IO_size_t len = strlen (str); _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, _IO_stdout); _IO_flockfile (_IO_stdout); - if (_IO_sputn (_IO_stdout, str, len) == len + + if (_IO_fwide (_IO_stdout, -1) == -1 + && _IO_sputn (_IO_stdout, str, len) == len && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) result = len + 1; - else - result = EOF; + _IO_funlockfile (_IO_stdout); _IO_cleanup_region_end (0); return result; diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c index 4a951dd..4bd1be1 100644 --- a/libio/ioseekoff.c +++ b/libio/ioseekoff.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -24,27 +24,27 @@ General Public License. */ #include <libioP.h> -#include <errno.h> -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif +#include <errno.h> +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif -_IO_fpos64_t +_IO_off64_t _IO_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off64_t offset; int dir; int mode; { - _IO_fpos64_t retval; + _IO_off64_t retval; - if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end) - { - __set_errno (EINVAL); - return EOF; + if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end) + { + __set_errno (EINVAL); + return EOF; } /* If we have a backup buffer, get rid of it, since the __seekoff diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c index c81c333..3e692da 100644 --- a/libio/ioseekpos.c +++ b/libio/ioseekpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -25,13 +25,13 @@ #include <libioP.h> -_IO_fpos64_t +_IO_off64_t _IO_seekpos (fp, pos, mode) _IO_FILE *fp; - _IO_fpos64_t pos; + _IO_off64_t pos; int mode; { - _IO_fpos64_t retval; + _IO_off64_t retval; /* If we have a backup buffer, get rid of it, since the __seekoff callback may not know to do the right thing about it. diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c index d615da5..d119cd0 100644 --- a/libio/iosetbuffer.c +++ b/libio/iosetbuffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -38,6 +38,9 @@ _IO_setbuffer (fp, buf, size) if (!buf) size = 0; (void) _IO_SETBUF (fp, buf, size); + if (fp->_mode == 0) + /* We also have to set the buffer using the wide char function. */ + (*fp->_wide_data->_wide_vtable->__setbuf) (fp, buf, size); _IO_funlockfile (fp); _IO_cleanup_region_end (0); } diff --git a/libio/iosetvbuf.c b/libio/iosetvbuf.c index 02f4eef..b9ef31a 100644 --- a/libio/iosetvbuf.c +++ b/libio/iosetvbuf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -90,6 +90,10 @@ _IO_setvbuf (fp, buf, mode, size) goto unlock_return; } result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; + if (result == 0 && fp->_mode > 0) + /* We also have to set the buffer using the wide char function. */ + result = ((*fp->_wide_data->_wide_vtable->__setbuf) (fp, buf, size) == NULL + ? EOF : 0); unlock_return: _IO_funlockfile (fp); _IO_cleanup_region_end (0); diff --git a/libio/ioungetwc.c b/libio/ioungetwc.c new file mode 100644 index 0000000..88b4162 --- /dev/null +++ b/libio/ioungetwc.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +ungetwc (c, fp) + wint_t c; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, WEOF); + if (c == WEOF) + return WEOF; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_sputbackwc (fp, c); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c index d95af47..b951006 100644 --- a/libio/iovdprintf.c +++ b/libio/iovdprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -36,12 +36,13 @@ _IO_vdprintf (d, format, arg) #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif + struct _IO_wide_data wd; int done; #ifdef _IO_MTSAFE_IO tmpfil.file._lock = &lock; #endif - _IO_init (&tmpfil.file, 0); + _IO_no_init (&tmpfil.file, 0, 0, &wd, &_IO_wfile_jumps); _IO_JUMPS (&tmpfil.file) = &_IO_file_jumps; _IO_file_init (&tmpfil.file); #if !_IO_UNIFIED_JUMPTABLES diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c index a1ece2d..84c24d8 100644 --- a/libio/iovsprintf.c +++ b/libio/iovsprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -41,7 +41,7 @@ _IO_vsprintf (string, format, args) #ifdef _IO_MTSAFE_IO sf._sbf._f._lock = &lock; #endif - _IO_init (&sf._sbf._f, 0); + _IO_no_init (&sf._sbf._f, 0, -1, NULL, NULL); _IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps; _IO_str_init_static (&sf._sbf._f, string, -1, string); ret = _IO_vfprintf (&sf._sbf._f, format, args); diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c index 923e829..2b1e44d 100644 --- a/libio/iovsscanf.c +++ b/libio/iovsscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -38,7 +38,7 @@ _IO_vsscanf (string, format, args) _IO_lock_t lock; sf._sbf._f._lock = &lock; #endif - _IO_init (&sf._sbf._f, 0); + _IO_no_init (&sf._sbf._f, 0, -1, NULL, NULL); _IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps; _IO_str_init_static (&sf._sbf._f, (char*)string, 0, NULL); ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL); diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c new file mode 100644 index 0000000..f0ab62a --- /dev/null +++ b/libio/iovswscanf.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include "strfile.h" +#include <wchar.h> + +int +vswscanf (string, format, args) + const wchar_t *string; + const wchar_t *format; + _IO_va_list args; +{ + int ret; + _IO_strfile sf; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; + sf._sbf._f._lock = &lock; +#endif + _IO_no_init (&sf._sbf._f, 0, 1, &wd, &_IO_wstr_jumps); + _IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps; + _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); + ret = _IO_vfwscanf (&sf._sbf._f, format, args, NULL); + return ret; +} diff --git a/libio/iowpadn.c b/libio/iowpadn.c new file mode 100644 index 0000000..b490458 --- /dev/null +++ b/libio/iowpadn.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" + +#define PADSIZE 16 +static wchar_t const blanks[PADSIZE] = +{ + L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ', + L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ' +}; +static wchar_t const zeroes[PADSIZE] = +{ + L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0', + L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0' +}; + +_IO_ssize_t +_IO_wpadn (fp, pad, count) + _IO_FILE *fp; + wint_t pad; + _IO_ssize_t count; +{ + wchar_t padbuf[PADSIZE]; + const wchar_t *padptr; + int i; + _IO_size_t written = 0; + _IO_size_t w; + + if (pad == L' ') + padptr = blanks; + else if (pad == L'0') + padptr = zeroes; + else + { + for (i = PADSIZE; --i >= 0; ) + padbuf[i] = pad; + padptr = padbuf; + } + for (i = count; i >= PADSIZE; i -= PADSIZE) + { + w = _IO_sputn (fp, (char *) padptr, PADSIZE); + written += w; + if (w != PADSIZE) + return written; + } + + if (i > 0) + { + w = _IO_sputn (fp, (char *) padptr, i); + written += w; + } + return written; +} diff --git a/libio/libio.h b/libio/libio.h index b4be610..a385288 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -37,10 +37,12 @@ #define _IO_off64_t _G_off64_t #define _IO_pid_t _G_pid_t #define _IO_uid_t _G_uid_t +#define _IO_iconv_t _G_iconv_t #define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT #define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE #define _IO_BUFSIZ _G_BUFSIZ #define _IO_va_list _G_va_list +#define _IO_wint_t _G_wint_t #ifdef _G_NEED_STDARG_H /* This define avoids name pollution if we're using GNU stdarg.h */ @@ -186,6 +188,70 @@ struct _IO_marker { #endif }; +/* This is the structure from the libstdc++ codecvt class. */ +enum __codecvt_result +{ + __codecvt_ok, + __codecvt_partial, + __codecvt_error, + __codecvt_noconv +}; + +/* The order of the elements in the following struct must match the order + of the virtual functions in the libstdc++ codecvt class. */ +struct _IO_codecvt +{ + void (*__codecvt_destr) __P ((struct _IO_codecvt *)); + enum __codecvt_result (*__codecvt_do_out) __P ((struct _IO_codecvt *, + __mbstate_t *, + const wchar_t *, + const wchar_t *, + const wchar_t **, char *, + char *, char **)); + enum __codecvt_result (*__codecvt_do_unshift) __P ((struct _IO_codecvt *, + __mbstate_t *, char *, + char *, char **)); + enum __codecvt_result (*__codecvt_do_in) __P ((struct _IO_codecvt *, + __mbstate_t *, + const char *, const char *, + const char **, wchar_t *, + wchar_t *, wchar_t **)); + int (*__codecvt_do_encoding) __P ((struct _IO_codecvt *)); + int (*__codecvt_do_always_noconv) __P ((struct _IO_codecvt *)); + int (*__codecvt_do_length) __P ((struct _IO_codecvt *, __mbstate_t *, + const char *, const char *, _IO_size_t)); + int (*__codecvt_do_max_length) __P ((struct _IO_codecvt *)); + + _IO_iconv_t __cd_in; + _IO_iconv_t __cd_out; +}; + +/* Extra data for wide character streams. */ +struct _IO_wide_data +{ + wchar_t *_IO_read_ptr; /* Current read pointer */ + wchar_t *_IO_read_end; /* End of get area. */ + wchar_t *_IO_read_base; /* Start of putback+get area. */ + wchar_t *_IO_write_base; /* Start of put area. */ + wchar_t *_IO_write_ptr; /* Current put pointer. */ + wchar_t *_IO_write_end; /* End of put area. */ + wchar_t *_IO_buf_base; /* Start of reserve area. */ + wchar_t *_IO_buf_end; /* End of reserve area. */ + /* The following fields are used to support backing up and undo. */ + wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */ + wchar_t *_IO_backup_base; /* Pointer to first valid character of + backup area */ + wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */ + + __mbstate_t _IO_state; + __mbstate_t _IO_last_state; + struct _IO_codecvt _codecvt; + + wchar_t _shortbuf[1]; + + struct _IO_jump_t *_wide_vtable; +}; + struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ #define _IO_file_flags _flags @@ -231,8 +297,12 @@ struct _IO_FILE_complete #endif #if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001 _IO_off64_t _offset; + /* Wide character stream stuff. */ + struct _IO_codecvt *_codecvt; + struct _IO_wide_data *_wide_data; + int _mode; /* Make sure we don't get into trouble again. */ - int _unused2[16]; + char _unused2[15 * sizeof (int) - 2 * sizeof (void *)]; #endif }; @@ -318,6 +388,9 @@ extern "C" { extern int __underflow __P ((_IO_FILE *)); extern int __uflow __P ((_IO_FILE *)); extern int __overflow __P ((_IO_FILE *, int)); +extern _IO_wint_t __wunderflow __P ((_IO_FILE *)); +extern _IO_wint_t __wuflow __P ((_IO_FILE *)); +extern _IO_wint_t __woverflow __P ((_IO_FILE *, _IO_wint_t)); #define _IO_getc_unlocked(_fp) \ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow (_fp) \ @@ -331,16 +404,44 @@ extern int __overflow __P ((_IO_FILE *, int)); ? __overflow (_fp, (unsigned char) (_ch)) \ : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch))) +#define _IO_getwc_unlocked(_fp) \ + ((_fp)->_wide_data->_IO_read_ptr >= (_fp)->_wide_data->_IO_read_end \ + ? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++) +#define _IO_putwc_unlocked(_wch, _fp) \ + ((_fp)->_wide_data->_IO_write_ptr >= (_fp)->_wide_data->_IO_write_end \ + ? __woverflow (_fp, _wch) \ + : (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch))) + #define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) #define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) extern int _IO_getc __P ((_IO_FILE *__fp)); extern int _IO_putc __P ((int __c, _IO_FILE *__fp)); +extern _IO_wint_t _IO_getwc __P ((_IO_FILE *__fp)); +extern _IO_wint_t _IO_putwc __P ((_IO_wint_t __wc, _IO_FILE *__fp)); extern int _IO_feof __P ((_IO_FILE *__fp)); extern int _IO_ferror __P ((_IO_FILE *__fp)); extern int _IO_peekc_locked __P ((_IO_FILE *__fp)); +extern int _IO_fwide __P ((_IO_FILE *__fp, int __mode)); +#if __GNUC__ >= 2 +/* A special optimized version of the function above. It optimizes the + case of initializing an unoriented byte stream. */ +# define _IO_fwide(__fp, __mode) \ + ({ int __result = (__mode); \ + if (__result < 0) \ + { \ + if ((__fp)->_mode == 0) \ + /* We know that all we have to do is to set the flag. */ \ + (__fp)->_mode = -1; \ + __result = (__fp)->_mode; \ + } \ + else \ + __result = _IO_fwide (__fp, __result); \ + __result; }) +#endif + /* This one is for Emacs. */ #define _IO_PENDING_OUTPUT_COUNT(_fp) \ ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) @@ -362,15 +463,22 @@ extern int _IO_ftrylockfile __P ((_IO_FILE *)); extern int _IO_vfscanf __P ((_IO_FILE * __restrict, const char * __restrict, _IO_va_list, int *__restrict)); +extern int _IO_vfwscanf __P ((_IO_FILE * __restrict, + const wchar_t * __restrict, + _IO_va_list, int *__restrict)); extern int _IO_vfprintf __P ((_IO_FILE *__restrict, const char *__restrict, _IO_va_list)); +extern int _IO_vfwprintf __P ((_IO_FILE *__restrict, const wchar_t *__restrict, + _IO_va_list)); extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t)); +extern _IO_ssize_t _IO_wpadn __P ((_IO_FILE *, wint_t, _IO_ssize_t)); extern _IO_size_t _IO_sgetn __P ((_IO_FILE *, void *, _IO_size_t)); -extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); -extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int)); +extern _IO_off64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_off64_t _IO_seekpos __P ((_IO_FILE *, _IO_off64_t, int)); extern void _IO_free_backup_area __P ((_IO_FILE *)); +extern void _IO_free_wbackup_area __P ((_IO_FILE *)); #ifdef __cplusplus } diff --git a/libio/libioP.h b/libio/libioP.h index a9577ce..6ed79b7 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -70,6 +70,7 @@ extern "C" { #endif #define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable +#define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable #if _IO_JUMPS_OFFSET # define _IO_JUMPS_FUNC(THIS) \ (*(struct _IO_jump_t **) ((void *) &((struct _IO_FILE_plus *) (THIS))->vtable\ @@ -146,8 +147,8 @@ typedef _IO_size_t (*_IO_xsgetn_t) __PMT ((_IO_FILE *FP, void *DATA, (MODE==1), or the end of the file (MODE==2). It matches the streambuf::seekoff virtual function. It is also used for the ANSI fseek function. */ -typedef _IO_fpos64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF, - int DIR, int MODE)); +typedef _IO_off64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF, + int DIR, int MODE)); #define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE) /* The 'seekpos' hook also moves the stream position, @@ -155,7 +156,7 @@ typedef _IO_fpos64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF, It matches the streambuf::seekpos virtual function. It is also used for the ANSI fgetpos and fsetpos functions. */ /* The _IO_seek_cur and _IO_seek_end options are not allowed. */ -typedef _IO_fpos64_t (*_IO_seekpos_t) __PMT ((_IO_FILE *, _IO_fpos64_t, int)); +typedef _IO_off64_t (*_IO_seekpos_t) __PMT ((_IO_FILE *, _IO_off64_t, int)); #define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS) /* The 'setbuf' hook gives a buffer to the file. @@ -205,7 +206,7 @@ typedef _IO_ssize_t (*_IO_write_t) __PMT ((_IO_FILE *, const void *, It generalizes the Unix lseek(2) function. It matches the streambuf::sys_seek virtual function, which is specific to this implementation. */ -typedef _IO_fpos64_t (*_IO_seek_t) __PMT ((_IO_FILE *, _IO_off64_t, int)); +typedef _IO_off64_t (*_IO_seek_t) __PMT ((_IO_FILE *, _IO_off64_t, int)); #define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE) /* The 'sysclose' hook is used to finalize (close, finish up) an @@ -282,9 +283,6 @@ struct _IO_FILE_plus /* Generic functions */ -extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); -extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int)); - extern void _IO_switch_to_main_get_area __P ((_IO_FILE *)); extern void _IO_switch_to_backup_area __P ((_IO_FILE *)); extern int _IO_switch_to_get_mode __P ((_IO_FILE *)); @@ -299,56 +297,94 @@ extern void _IO_setb __P ((_IO_FILE *, char *, char *, int)); extern unsigned _IO_adjust_column __P ((unsigned, const char *, int)); #define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n) +extern void _IO_switch_to_main_wget_area __P ((_IO_FILE *)); +extern void _IO_switch_to_wbackup_area __P ((_IO_FILE *)); +extern int _IO_switch_to_wget_mode __P ((_IO_FILE *)); +extern void _IO_wsetb __P ((_IO_FILE *, wchar_t *, wchar_t *, int)); +extern wint_t _IO_sputbackwc __P ((_IO_FILE *, wint_t)); +extern wint_t _IO_sungetwc __P ((_IO_FILE *)); +extern void _IO_wdoallocbuf __P ((_IO_FILE *)); +extern void _IO_unsave_wmarkers __P ((_IO_FILE *)); +extern void _IO_wsetb __P ((_IO_FILE *, wchar_t *, wchar_t *, int)); +extern unsigned _IO_adjust_wcolumn __P ((unsigned, const wchar_t *, int)); + /* Marker-related function. */ extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *)); +extern void _IO_init_wmarker __P ((struct _IO_marker *, _IO_FILE *)); extern void _IO_remove_marker __P ((struct _IO_marker *)); extern int _IO_marker_difference __P ((struct _IO_marker *, struct _IO_marker *)); extern int _IO_marker_delta __P ((struct _IO_marker *)); +extern int _IO_wmarker_delta __P ((struct _IO_marker *)); extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int)); +extern int _IO_seekwmark __P ((_IO_FILE *, struct _IO_marker *, int)); /* Default jumptable functions. */ extern int _IO_default_underflow __P ((_IO_FILE *)); extern int _IO_default_uflow __P ((_IO_FILE *)); +extern wint_t _IO_wdefault_uflow __P ((_IO_FILE *)); extern int _IO_default_doallocate __P ((_IO_FILE *)); +extern int _IO_wdefault_doallocate __P ((_IO_FILE *)); extern void _IO_default_finish __P ((_IO_FILE *, int)); +extern void _IO_wdefault_finish __P ((_IO_FILE *, int)); extern int _IO_default_pbackfail __P ((_IO_FILE *, int)); +extern wint_t _IO_wdefault_pbackfail __P ((_IO_FILE *, wint_t)); extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); +extern _IO_FILE* _IO_wdefault_setbuf __P ((_IO_FILE *, wchar_t *, + _IO_ssize_t)); extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); +extern _IO_size_t _IO_wdefault_xsputn __P ((_IO_FILE *, const void *, + _IO_size_t)); extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); -extern _IO_fpos64_t _IO_default_seekoff __P ((_IO_FILE *, - _IO_off64_t, int, int)); -extern _IO_fpos64_t _IO_default_seekpos __P ((_IO_FILE *, - _IO_fpos64_t, int)); +extern _IO_size_t _IO_wdefault_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); +extern _IO_off64_t _IO_default_seekoff __P ((_IO_FILE *, + _IO_off64_t, int, int)); +extern _IO_off64_t _IO_default_seekpos __P ((_IO_FILE *, _IO_off64_t, int)); extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *, _IO_ssize_t)); extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t)); extern int _IO_default_stat __P ((_IO_FILE *, void *)); -extern _IO_fpos64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int)); +extern _IO_off64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int)); extern int _IO_default_sync __P ((_IO_FILE *)); #define _IO_default_close ((_IO_close_t) _IO_default_sync) extern int _IO_default_showmanyc __P ((_IO_FILE *)); extern void _IO_default_imbue __P ((_IO_FILE *, void *)); extern struct _IO_jump_t _IO_file_jumps; +extern struct _IO_jump_t _IO_wfile_jumps; extern struct _IO_jump_t _IO_old_file_jumps; extern struct _IO_jump_t _IO_streambuf_jumps; extern struct _IO_jump_t _IO_proc_jumps; extern struct _IO_jump_t _IO_old_proc_jumps; extern struct _IO_jump_t _IO_str_jumps; +extern struct _IO_jump_t _IO_wstr_jumps; extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); extern int _IO_new_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); extern int _IO_old_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); +extern int _IO_wdo_write __P ((_IO_FILE *, const wchar_t *, _IO_size_t)); extern int _IO_flush_all __P ((void)); extern int _IO_cleanup __P ((void)); extern void _IO_flush_all_linebuffered __P ((void)); +extern int _IO_new_fgetpos __P ((_IO_FILE *, _IO_fpos_t *)); +extern int _IO_old_fgetpos __P ((_IO_FILE *, _IO_fpos_t *)); +extern int _IO_new_fsetpos __P ((_IO_FILE *, const _IO_fpos_t *)); +extern int _IO_old_fsetpos __P ((_IO_FILE *, const _IO_fpos_t *)); +extern int _IO_new_fgetpos64 __P ((_IO_FILE *, _IO_fpos64_t *)); +extern int _IO_old_fgetpos64 __P ((_IO_FILE *, _IO_fpos64_t *)); +extern int _IO_new_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *)); +extern int _IO_old_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *)); + #define _IO_do_flush(_f) \ - _IO_do_write(_f, (_f)->_IO_write_base, \ - (_f)->_IO_write_ptr-(_f)->_IO_write_base) + ((_f)->_mode <= 0 \ + ? _IO_do_write(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) \ + : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \ + ((_f)->_wide_data->_IO_write_ptr \ + - (_f)->_wide_data->_IO_write_base))) #define _IO_old_do_flush(_f) \ _IO_old_do_write(_f, (_f)->_IO_write_base, \ (_f)->_IO_write_ptr-(_f)->_IO_write_base) @@ -357,18 +393,29 @@ extern void _IO_flush_all_linebuffered __P ((void)); ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask))) #define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\ (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg)) +#define _IO_wsetg(fp, eb, g, eg) ((fp)->_wide_data->_IO_read_base = (eb),\ + (fp)->_wide_data->_IO_read_ptr = (g), \ + (fp)->_wide_data->_IO_read_end = (eg)) #define _IO_setp(__fp, __p, __ep) \ - ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep)) + ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr \ + = __p, (__fp)->_IO_write_end = (__ep)) +#define _IO_wsetp(__fp, __p, __ep) \ + ((__fp)->_wide_data->_IO_write_base \ + = (__fp)->_wide_data->_IO_write_ptr = __p, \ + (__fp)->_wide_data->_IO_write_end = (__ep)) #define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) +#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) #define _IO_have_markers(fp) ((fp)->_markers != NULL) #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) +#define _IO_wblen(fp) ((fp)->_wide_data->_IO_buf_end \ + - (fp)->_wide_data->_IO_buf_base) /* Jumptable functions for files. */ extern int _IO_file_doallocate __P ((_IO_FILE *)); extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); -extern _IO_fpos64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_off64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); extern int _IO_file_stat __P ((_IO_FILE *, void *)); @@ -387,7 +434,7 @@ extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *, extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t)); extern int _IO_file_sync __P ((_IO_FILE *)); extern int _IO_file_close_it __P ((_IO_FILE *)); -extern _IO_fpos64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int)); +extern _IO_off64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int)); extern void _IO_file_finish __P ((_IO_FILE *, int)); extern _IO_FILE* _IO_new_file_attach __P ((_IO_FILE *, int)); @@ -395,19 +442,21 @@ extern int _IO_new_file_close_it __P ((_IO_FILE *)); extern void _IO_new_file_finish __P ((_IO_FILE *, int)); extern _IO_FILE* _IO_new_file_fopen __P ((_IO_FILE *, const char *, const char *, int)); +extern void _IO_no_init __P ((_IO_FILE *, int, int, struct _IO_wide_data *, + struct _IO_jump_t *)); extern void _IO_new_file_init __P ((_IO_FILE *)); extern _IO_FILE* _IO_new_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); extern int _IO_new_file_sync __P ((_IO_FILE *)); extern int _IO_new_file_underflow __P ((_IO_FILE *)); extern int _IO_new_file_overflow __P ((_IO_FILE *, int)); -extern _IO_fpos64_t _IO_new_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_off64_t _IO_new_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_ssize_t _IO_new_file_write __P ((_IO_FILE *, const void *, _IO_ssize_t)); extern _IO_size_t _IO_new_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern _IO_FILE* _IO_old_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); -extern _IO_fpos64_t _IO_old_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, - int)); +extern _IO_off64_t _IO_old_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, + int)); extern _IO_size_t _IO_old_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern int _IO_old_file_underflow __P ((_IO_FILE *)); @@ -422,6 +471,15 @@ extern int _IO_old_file_sync __P ((_IO_FILE *)); extern int _IO_old_file_close_it __P ((_IO_FILE *)); extern void _IO_old_file_finish __P ((_IO_FILE *, int)); +extern int _IO_wfile_doallocate __P ((_IO_FILE *)); +extern _IO_size_t _IO_wfile_xsputn __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_FILE* _IO_wfile_setbuf __P ((_IO_FILE *, wchar_t *, _IO_ssize_t)); +extern wint_t _IO_wfile_sync __P ((_IO_FILE *)); +extern wint_t _IO_wfile_underflow __P ((_IO_FILE *)); +extern wint_t _IO_wfile_overflow __P ((_IO_FILE *, wint_t)); +extern _IO_off64_t _IO_wfile_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); + /* Jumptable functions for proc_files. */ extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *)); extern _IO_FILE* _IO_new_proc_open __P ((_IO_FILE *, const char *, const char *)); @@ -434,7 +492,7 @@ extern int _IO_old_proc_close __P ((_IO_FILE *)); extern int _IO_str_underflow __P ((_IO_FILE *)); extern int _IO_str_overflow __P ((_IO_FILE *, int)); extern int _IO_str_pbackfail __P ((_IO_FILE *, int)); -extern _IO_fpos64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_off64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern void _IO_str_finish __P ((_IO_FILE *, int)); /* Other strfile functions */ @@ -442,6 +500,16 @@ extern void _IO_str_init_static __P ((_IO_FILE *, char *, int, char *)); extern void _IO_str_init_readonly __P ((_IO_FILE *, const char *, int)); extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *)); +/* And the wide character versions. */ +extern void _IO_wstr_init_static __P ((_IO_FILE *, wchar_t *, int, wchar_t *)); +extern void _IO_wstr_init_readonly __P ((_IO_FILE *, const char *, int)); +extern _IO_ssize_t _IO_wstr_count __P ((_IO_FILE *)); +extern _IO_wint_t _IO_wstr_overflow __P ((_IO_FILE *, _IO_wint_t)); +extern _IO_wint_t _IO_wstr_underflow __P ((_IO_FILE *)); +extern _IO_off64_t _IO_wstr_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_wint_t _IO_wstr_pbackfail __P ((_IO_FILE *, _IO_wint_t)); +extern void _IO_wstr_finish __P ((_IO_FILE *, int)); + extern int _IO_vasprintf __P ((char **result_ptr, __const char *format, _IO_va_list args)); extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg)); @@ -453,6 +521,10 @@ extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int)); extern _IO_size_t _IO_getline_info __P ((_IO_FILE *,char *, _IO_size_t, int, int, int *)); extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *)); +extern _IO_size_t _IO_getwline __P ((_IO_FILE *,wchar_t *, _IO_size_t, wint_t, + int)); +extern _IO_size_t _IO_getwline_info __P ((_IO_FILE *,wchar_t *, _IO_size_t, + wint_t, int, wint_t *)); extern double _IO_strtod __P ((const char *, char **)); extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits, int *__decpt, int *__sign, char **__rve)); @@ -516,7 +588,15 @@ extern void (*_IO_cleanup_registration_needed) __PMT ((void)); (_B) = (char *) mmap (0, ROUND_TO_PAGE (_S), \ PROT_READ | PROT_WRITE, \ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ - if ((_B) == (char *) -1) \ + if ((_B) == (char *) MAP_FAILED) \ + return (_R); \ + } while (0) +# define ALLOC_WBUF(_B, _S, _R) \ + do { \ + (_B) = (wchar_t *) mmap (0, ROUND_TO_PAGE (_S), \ + PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + if ((_B) == (wchar_t *) MAP_FAILED) \ return (_R); \ } while (0) @@ -544,26 +624,17 @@ extern int _IO_close __P ((int)); extern int _IO_fstat __P ((int, struct stat *)); extern int _IO_vscanf __P ((const char *, _IO_va_list)); -/* Operations on _IO_fpos64_t. - Normally, these are trivial, but we provide hooks for configurations - where an _IO_fpos64_t is a struct. - Note that _IO_off64_t must be an integral type. */ - -/* _IO_pos_BAD is an _IO_fpos64_t value indicating error, unknown, or EOF. */ +/* _IO_pos_BAD is an _IO_off64_t value indicating error, unknown, or EOF. */ #ifndef _IO_pos_BAD -# define _IO_pos_BAD ((_IO_fpos64_t) -1) +# define _IO_pos_BAD ((_IO_off64_t) -1) #endif -/* _IO_pos_as_off converts an _IO_fpos64_t value to an _IO_off64_t value. */ -#ifndef _IO_pos_as_off -# define _IO_pos_as_off(__pos) ((_IO_off64_t) (__pos)) -#endif -/* _IO_pos_adjust adjust an _IO_fpos64_t by some number of bytes. */ +/* _IO_pos_adjust adjust an _IO_off64_t by some number of bytes. */ #ifndef _IO_pos_adjust -# define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta)) +# define _IO_pos_adjust(pos, delta) ((pos) += (delta)) #endif -/* _IO_pos_0 is an _IO_fpos64_t value indicating beginning of file. */ +/* _IO_pos_0 is an _IO_off64_t value indicating beginning of file. */ #ifndef _IO_pos_0 -# define _IO_pos_0 ((_IO_fpos64_t) 0) +# define _IO_pos_0 ((_IO_off64_t) 0) #endif #ifdef __cplusplus @@ -573,15 +644,16 @@ extern int _IO_vscanf __P ((const char *, _IO_va_list)); #ifdef _IO_MTSAFE_IO /* check following! */ # ifdef _IO_USE_OLD_IO_FILE -# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \ +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \ 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock } # else -# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \ +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \ - 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD } + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ + NULL, WDP, 0 } # endif #else # ifdef _IO_USE_OLD_IO_FILE @@ -592,7 +664,8 @@ extern int _IO_vscanf __P ((const char *, _IO_va_list)); # define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \ - 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD } + 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ + NULL, WDP, 0 } # endif #endif diff --git a/libio/memstream.c b/libio/memstream.c index 71aab2f..840d0e6 100644 --- a/libio/memstream.c +++ b/libio/memstream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1999 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 @@ -32,9 +32,11 @@ struct _IO_FILE_memstream static int _IO_mem_sync __P ((_IO_FILE* fp)); static void _IO_mem_finish __P ((_IO_FILE* fp, int)); +static int _IO_wmem_sync __P ((_IO_FILE* fp)); +static void _IO_wmem_finish __P ((_IO_FILE* fp, int)); -static const struct _IO_jump_t _IO_mem_jumps = +static struct _IO_jump_t _IO_mem_jumps = { JUMP_INIT_DUMMY, JUMP_INIT (finish, _IO_mem_finish), @@ -58,6 +60,30 @@ static const struct _IO_jump_t _IO_mem_jumps = JUMP_INIT(imbue, _IO_default_imbue) }; +static struct _IO_jump_t _IO_wmem_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT (finish, (_IO_finish_t) _IO_wmem_finish), + JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow), + JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT (xsputn, (_IO_xsputn_t) _IO_wdefault_xsputn), + JUMP_INIT (xsgetn, (_IO_xsgetn_t) _IO_wdefault_xsgetn), + JUMP_INIT (seekoff, _IO_wstr_seekoff), + JUMP_INIT (seekpos, _IO_default_seekpos), + JUMP_INIT (setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf), + JUMP_INIT (sync, (_IO_sync_t) _IO_wmem_sync), + JUMP_INIT (doallocate, _IO_wdefault_doallocate), + JUMP_INIT (read, _IO_default_read), + JUMP_INIT (write, _IO_default_write), + JUMP_INIT (seek, _IO_default_seek), + JUMP_INIT (close, _IO_default_close), + JUMP_INIT (stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + /* Open a stream that writes into a malloc'd buffer that is expanded as necessary. *BUFLOC and *SIZELOC are updated with the buffer's location and the number of characters written on fflush or fclose. */ @@ -72,6 +98,7 @@ open_memstream (bufloc, sizeloc) #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif + struct _IO_wide_data wd; } *new_f; char *buf; @@ -85,7 +112,7 @@ open_memstream (bufloc, sizeloc) buf = malloc (_IO_BUFSIZ); if (buf == NULL) return NULL; - _IO_init (&new_f->fp._sf._sbf._f, 0); + _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps); _IO_JUMPS (&new_f->fp._sf._sbf._f) = &_IO_mem_jumps; _IO_str_init_static (&new_f->fp._sf._sbf._f, buf, _IO_BUFSIZ, buf); new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF; @@ -144,3 +171,55 @@ _IO_mem_finish (fp, dummy) _IO_default_finish (fp, 0); } + + +static int +_IO_wmem_sync (fp) + _IO_FILE* fp; +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + int res; + + res = _IO_default_sync (fp); + if (res < 0) + return res; + + if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end) + { + _IO_wstr_overflow (fp, L'\0'); + --fp->_wide_data->_IO_write_ptr; + } + else + *fp->_wide_data->_IO_write_ptr = '\0'; + + *mp->bufloc = (char *) fp->_wide_data->_IO_write_base; + *mp->sizeloc = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + + return 0; +} + + +static void +_IO_wmem_finish (fp, dummy) + _IO_FILE* fp; + int dummy; +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + + *mp->bufloc = (char *) realloc (fp->_wide_data->_IO_write_base, + (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base + 1) + * sizeof (wchar_t)); + if (*mp->bufloc != NULL) + { + ((wchar_t *) (*mp->bufloc))[fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base] = '\0'; + *mp->sizeloc = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + } + + fp->_wide_data->_IO_buf_base = NULL; + + _IO_default_finish (fp, 0); +} diff --git a/libio/obprintf.c b/libio/obprintf.c index 0e947b2..29e09d4 100644 --- a/libio/obprintf.c +++ b/libio/obprintf.c @@ -127,11 +127,11 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) new_f.ofile.file.file._lock = &new_f.lock; #endif - _IO_init (&new_f.ofile.file.file, 0); - _IO_JUMPS (&new_f.ofile.file.file) = &_IO_obstack_jumps; + _IO_no_init (&new_f.ofile.file.file, 0, -1, NULL, NULL); + _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; _IO_str_init_static (&new_f.ofile.file.file, obstack_base (obstack), - obstack_object_size (obstack) + obstack_room (obstack), - obstack_next_free (obstack)); + (obstack_object_size (obstack) + + obstack_room (obstack)), obstack_next_free (obstack)); /* Now allocate the rest of the current chunk. */ obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_end diff --git a/libio/oldfileops.c b/libio/oldfileops.c index fe29a79..d65c272 100644 --- a/libio/oldfileops.c +++ b/libio/oldfileops.c @@ -285,7 +285,7 @@ old_do_write (fp, data, to_do) fp->_old_offset = _IO_pos_BAD; else if (fp->_IO_read_end != fp->_IO_write_base) { - _IO_pos_t new_pos + _IO_off_t new_pos = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); if (new_pos == _IO_pos_BAD) return 0; @@ -449,14 +449,14 @@ _IO_old_file_sync (fp) return retval; } -_IO_fpos64_t +_IO_off64_t _IO_old_file_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off64_t offset; int dir; int mode; { - _IO_pos_t result; + _IO_off_t result; _IO_off64_t delta, new_offset; long count; /* POSIX.1 8.2.3.7 says that after a call the fflush() the file @@ -500,7 +500,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode) if (fp->_old_offset == _IO_pos_BAD) goto dumb; /* Make offset absolute, assuming current pointer is file_ptr(). */ - offset += _IO_pos_as_off (fp->_old_offset); + offset += fp->_old_offset; dir = _IO_seek_set; break; @@ -529,7 +529,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode) && !_IO_in_backup (fp)) { /* Offset relative to start of main get area. */ - _IO_pos_t rel_offset = (offset - fp->_old_offset + _IO_off_t rel_offset = (offset - fp->_old_offset + (fp->_IO_read_end - fp->_IO_read_base)); if (rel_offset >= 0) { diff --git a/libio/oldiofgetpos.c b/libio/oldiofgetpos.c new file mode 100644 index 0000000..2b4d10a --- /dev/null +++ b/libio/oldiofgetpos.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <errno.h> + +int +_IO_old_fgetpos (fp, posp) + _IO_FILE *fp; + _IO_fpos_t *posp; +{ + _IO_off_t pos; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + pos -= fp->_IO_save_end - fp->_IO_save_base; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return EOF; + } + posp->__pos = pos; + return 0; +} + +#ifdef weak_alias +symbol_version (_IO_old_fgetpos, _IO_fgetpos, GLIBC_2.0); +strong_alias (_IO_old_fgetpos, __old_fgetpos) +symbol_version (__old_fgetpos, fgetpos, GLIBC_2.0); +#endif diff --git a/libio/oldiofgetpos64.c b/libio/oldiofgetpos64.c new file mode 100644 index 0000000..9695c6f --- /dev/null +++ b/libio/oldiofgetpos64.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <errno.h> + +int +_IO_old_fgetpos64 (fp, posp) + _IO_FILE *fp; + _IO_fpos64_t *posp; +{ +#ifdef _G_LSEEK64 + _IO_off64_t pos; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + pos -= fp->_IO_save_end - fp->_IO_save_base; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return EOF; + } + posp->__pos = pos; + return 0; +#else + __set_errno (ENOSYS); + return EOF; +#endif +} + +#ifdef weak_alias +symbol_version (_IO_old_fgetpos64, _IO_fgetpos64, GLIBC_2.0); +strong_alias (_IO_old_fgetpos64, __old_fgetpos64) +symbol_version (__old_fgetpos64, fgetpos64, GLIBC_2.0); +#endif diff --git a/libio/oldiofsetpos.c b/libio/oldiofsetpos.c new file mode 100644 index 0000000..87a78d2 --- /dev/null +++ b/libio/oldiofsetpos.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include <libioP.h> +#include <errno.h> + +int +_IO_old_fsetpos (fp, posp) + _IO_FILE *fp; + const _IO_fpos_t *posp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + result = 0; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#ifdef weak_alias +symbol_version (_IO_old_fsetpos, _IO_fsetpos, GLIBC_2.0); +strong_alias (_IO_old_fsetpos, __old_fsetpos) +symbol_version (__old_fsetpos, fsetpos, GLIBC_2.0); +#endif diff --git a/libio/oldiofsetpos64.c b/libio/oldiofsetpos64.c new file mode 100644 index 0000000..9207dd7 --- /dev/null +++ b/libio/oldiofsetpos64.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include <libioP.h> +#include <errno.h> + +int +_IO_old_fsetpos64 (fp, posp) + _IO_FILE *fp; + const _IO_fpos64_t *posp; +{ +#ifdef _G_LSEEK64 + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + result = 0; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +#else + __set_errno (ENOSYS); + return EOF; +#endif +} + +#ifdef weak_alias +symbol_version (_IO_old_fsetpos64, _IO_fsetpos64, GLIBC_2.0); +strong_alias (_IO_fsetpos64, __old_fsetpos64) +symbol_version (__old_fsetpos64, _IO_fsetpos64, GLIBC_2.0); +#endif diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c index 7781a17..3629ab8 100644 --- a/libio/oldstdfiles.c +++ b/libio/oldstdfiles.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -37,11 +37,12 @@ #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ struct _IO_FILE_plus NAME \ - = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps}; + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps}; #else #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static struct _IO_wide_data _IO_wide_data_##FD; \ struct _IO_FILE_plus NAME \ - = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps}; + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps}; #endif DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES); diff --git a/libio/putwc.c b/libio/putwc.c new file mode 100644 index 0000000..07557ac --- /dev/null +++ b/libio/putwc.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 95, 96, 97, 98, 99 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +putwc (wc, fp) + wint_t wc; + _IO_FILE *fp; +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_putwc_unlocked (wc, fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/putwc_u.c b/libio/putwc_u.c new file mode 100644 index 0000000..3f7a26f --- /dev/null +++ b/libio/putwc_u.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +putwc_unlocked (wc, fp) + wint_t wc; + _IO_FILE *fp; +{ + CHECK_FILE (fp, WEOF); + return _IO_putc_unlocked (wc, fp); +} diff --git a/libio/putwchar.c b/libio/putwchar.c new file mode 100644 index 0000000..0a2854f --- /dev/null +++ b/libio/putwchar.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 95, 96, 97, 98, 99 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "libioP.h" +#include "stdio.h" + +wint_t +putwchar (wc) + wint_t wc; +{ + wint_t result; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdout); + _IO_flockfile (_IO_stdout); + result = _IO_putwc_unlocked (wc, _IO_stdout); + _IO_funlockfile (_IO_stdout); + _IO_cleanup_region_end (0); + return result; +} diff --git a/libio/putwchar_u.c b/libio/putwchar_u.c new file mode 100644 index 0000000..0da7dcf --- /dev/null +++ b/libio/putwchar_u.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "libioP.h" +#include "stdio.h" + +wint_t +putwchar_unlocked (c) + wint_t c; +{ + CHECK_FILE (stdout, WEOF); + return _IO_putwc_unlocked (wc, stdout); +} diff --git a/libio/stdfiles.c b/libio/stdfiles.c index 8c09c2c..6feff4d 100644 --- a/libio/stdfiles.c +++ b/libio/stdfiles.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -35,12 +35,18 @@ #ifdef _IO_MTSAFE_IO #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + static struct _IO_wide_data _IO_wide_data_##FD \ + = { ._wide_vtable = &_IO_wfile_jumps }; \ struct _IO_FILE_plus NAME \ - = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}; + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ + &_IO_file_jumps}; #else #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static struct _IO_wide_data _IO_wide_data_##FD \ + = { ._wide_vtable = &_IO_wfile_jumps }; \ struct _IO_FILE_plus NAME \ - = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}; + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ + &_IO_file_jumps}; #endif DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES); diff --git a/libio/strops.c b/libio/strops.c index c3e245f..83fd794 100644 --- a/libio/strops.c +++ b/libio/strops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -147,10 +147,10 @@ _IO_str_overflow (fp, c) /* __ferror(fp) = 1; */ return EOF; } - if (fp->_IO_buf_base) + if (old_buf) { memcpy (new_buf, old_buf, _IO_blen (fp)); - (*((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base); + (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_IO_buf_base = NULL; } @@ -205,14 +205,14 @@ _IO_str_count (fp) - fp->_IO_read_base); } -_IO_fpos64_t +_IO_off64_t _IO_str_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off64_t offset; int dir; int mode; { - _IO_fpos64_t new_pos; + _IO_off64_t new_pos; if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); diff --git a/libio/swprintf.c b/libio/swprintf.c new file mode 100644 index 0000000..f0cb637 --- /dev/null +++ b/libio/swprintf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1995, 1997, 1998, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#include <wchar.h> + +/* Write formatted output into S, according to the format string FORMAT. */ +/* VARARGS3 */ +int +swprintf (s, n, format) + wchar_t *s; + size_t n; + const wchar_t *format; +{ + va_list arg; + int done; + + va_start (arg, format); + done = vswprintf (s, n, format, arg); + va_end (arg); + + return done; +} diff --git a/libio/swscanf.c b/libio/swscanf.c new file mode 100644 index 0000000..6876d4b --- /dev/null +++ b/libio/swscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1995, 1996, 1998, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#include <wchar.h> + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +swscanf (s, format) + const wchar_t *s; + const wchar_t *format; +{ + va_list arg; + int done; + + va_start (arg, format); + done = vswscanf (s, format, arg); + va_end (arg); + + return done; +} diff --git a/libio/tst_swprintf.c b/libio/tst_swprintf.c new file mode 100644 index 0000000..67d10a0 --- /dev/null +++ b/libio/tst_swprintf.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + wchar_t buf[100]; + int n; + int result = 0; + + puts ("test 1"); + n = swprintf (buf, sizeof (buf) / sizeof (buf[0]), L"Hello %s", "world"); + if (n != 11) + { + printf ("incorrect return value: %d instead of 11\n", n); + result = 1; + } + + if (wcscmp (buf, L"Hello world") != 0) + { + printf ("incorrect string: L\"%ls\" instead of L\"Hello world\"\n", buf); + result = 1; + } + + puts ("test 2"); + n = swprintf (buf, sizeof (buf) / sizeof (buf[0]), L"Is this >%g< 3.1?", + 3.1); + if (n != 18) +{ + printf ("incorrect return value: %d instead of 18\n", n); + result = 1; + } + + if (wcscmp (buf, L"Is this >3.1< 3.1?") != 0) + { + printf ("incorrect string: L\"%ls\" instead of L\"Is this >3.1< 3.1?\"\n", + buf); + result = 1; + } + + return result; +} diff --git a/libio/tst_swscanf.c b/libio/tst_swscanf.c new file mode 100644 index 0000000..ce56144 --- /dev/null +++ b/libio/tst_swscanf.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + const wchar_t in[] = L"7 + 35 is 42"; + size_t n; + int a, b, c; + int result = 0; + char buf1[20]; + wchar_t wbuf2[20]; + char buf3[20]; + char c4; + wchar_t wc5; + + puts ("Test 1"); + a = b = c = 0; + n = swscanf (in, L"%d + %d is %d", &a, &b, &c); + if (n != 3 || a + b != c || c != 42) + { + printf ("*** FAILED, n = %Zu, a = %d, b = %d, c = %d\n", n, a, b, c); + result = 1; + } + + puts ("Test 2"); + n = swscanf (L"one two three !!", L"%s %S %s %c%C", + buf1, wbuf2, buf3, &c4, &wc5); + if (n != 5 || strcmp (buf1, "one") != 0 || wcscmp (wbuf2, L"two") != 0 + || strcmp (buf3, "three") != 0 || c4 != '!' || wc5 != L'!') + { + printf ("*** FAILED, n = %Zu, buf1 = \"%s\", wbuf2 = L\"%S\", buf3 = \"%s\", c4 = '%c', wc5 = L'%C'\n", + n, buf1, wbuf2, buf3, c4, wc5); + result = 1; + } + + return result; +} diff --git a/libio/tst_wprintf.c b/libio/tst_wprintf.c new file mode 100644 index 0000000..0838441 --- /dev/null +++ b/libio/tst_wprintf.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + fputws (L"Hello world!\n", stdout); + wprintf (L"This %s a %ls string: %d\n", "is", L"mixed", 42); + return 0; +} diff --git a/libio/tst_wscanf.c b/libio/tst_wscanf.c new file mode 100644 index 0000000..719f3786 --- /dev/null +++ b/libio/tst_wscanf.c @@ -0,0 +1,28 @@ +#include <stdio.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + int n; + int result = 0; + char buf1[20]; + wchar_t wbuf2[20]; + char c3; + wchar_t wc4; + int d; + + puts ("Test 1"); + + n = wscanf (L"%s %S %c%C %d", buf1, wbuf2, &c3, &wc4, &d); + + if (n != 5 || strcmp (buf1, "Hello") != 0 || wcscmp (wbuf2, L"World") != 0 + || c3 != '!' || wc4 != L'!' || d != 42) + { + printf ("*** FAILED, n = %d, buf1 = \"%s\", wbuf2 = L\"%S\", c3 = '%c', wc4 = L'%C', d = %d\n", + n, buf1, wbuf2, c3, wc4, d); + result = 1; + } + + return result; +} diff --git a/libio/tst_wscanf.input b/libio/tst_wscanf.input new file mode 100644 index 0000000..93e1eb5 --- /dev/null +++ b/libio/tst_wscanf.input @@ -0,0 +1 @@ +Hello World !! 42 diff --git a/libio/vasprintf.c b/libio/vasprintf.c index 15513d0..a656961 100644 --- a/libio/vasprintf.c +++ b/libio/vasprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -49,7 +49,7 @@ _IO_vasprintf (result_ptr, format, args) #ifdef _IO_MTSAFE_IO sf._sbf._f._lock = &lock; #endif - _IO_init ((_IO_FILE *) &sf, 0); + _IO_no_init ((_IO_FILE *) &sf, 0, -1, NULL, NULL); _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps; _IO_str_init_static ((_IO_FILE *) &sf, string, init_string_size, string); sf._sbf._f._flags &= ~_IO_USER_BUF; diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c index e223e5d..2b82df5 100644 --- a/libio/vsnprintf.c +++ b/libio/vsnprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -122,7 +122,7 @@ _IO_vsnprintf (string, maxlen, format, args) maxlen = sizeof (sf.overflow_buf); } - _IO_init ((_IO_FILE *) &sf, 0); + _IO_no_init ((_IO_FILE *) &sf, 0, -1, NULL, NULL); _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_strn_jumps; string[0] = '\0'; _IO_str_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string); diff --git a/libio/vswprintf.c b/libio/vswprintf.c new file mode 100644 index 0000000..addf390 --- /dev/null +++ b/libio/vswprintf.c @@ -0,0 +1,144 @@ +/* Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include "strfile.h" + + +typedef struct +{ + _IO_strfile f; + /* This is used for the characters which do not fit in the buffer + provided by the user. */ + wchar_t overflow_buf[64]; +} _IO_strnfile; + + +static wint_t _IO_wstrn_overflow __P ((_IO_FILE *fp, wint_t c)); + +static wint_t +_IO_wstrn_overflow (fp, c) + _IO_FILE *fp; + wint_t c; +{ + /* When we come to here this means the user supplied buffer is + filled. But since we must return the number of characters which + would have been written in total we must provide a buffer for + further use. We can do this by writing on and on in the overflow + buffer in the _IO_strnfile structure. */ + _IO_strnfile *snf = (_IO_strnfile *) fp; + + if (fp->_wide_data->_IO_buf_base != snf->overflow_buf) + { + /* Terminate the string. We know that there is room for at + least one more character since we initialized the stream with + a size to make this possible. */ + *fp->_wide_data->_IO_write_ptr = '\0'; + + _IO_wsetb (fp, snf->overflow_buf, + snf->overflow_buf + (sizeof (snf->overflow_buf) + / sizeof (wchar_t)), 0); + + fp->_wide_data->_IO_write_base = snf->overflow_buf; + fp->_wide_data->_IO_read_base = snf->overflow_buf; + fp->_wide_data->_IO_read_ptr = snf->overflow_buf; + fp->_wide_data->_IO_read_end = (snf->overflow_buf + + (sizeof (snf->overflow_buf) + / sizeof (wchar_t))); + } + + fp->_wide_data->_IO_write_ptr = snf->overflow_buf; + fp->_wide_data->_IO_write_end = snf->overflow_buf; + + /* Since we are not really interested in storing the characters + which do not fit in the buffer we simply ignore it. */ + return c; +} + + +static struct _IO_jump_t _IO_wstrn_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstrn_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT(xsputn, _IO_wdefault_xsputn), + JUMP_INIT(xsgetn, _IO_wdefault_xsgetn), + JUMP_INIT(seekoff, _IO_wstr_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_wdefault_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + + +int +_IO_vswprintf (string, maxlen, format, args) + wchar_t *string; + _IO_size_t maxlen; + const wchar_t *format; + _IO_va_list args; +{ + _IO_strnfile sf; + int ret; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; + sf.f._sbf._f._lock = &lock; +#endif + + /* We need to handle the special case where MAXLEN is 0. Use the + overflow buffer right from the start. */ + if (maxlen == 0) + { + string = sf.overflow_buf; + maxlen = sizeof (sf.overflow_buf) / sizeof (wchar_t); + } + + _IO_no_init ((_IO_FILE *) &sf, 0, 0, &wd, NULL); + _IO_WIDE_JUMPS ((_IO_FILE *) &sf) = &_IO_wstrn_jumps; + _IO_fwide (&sf.f._sbf._f, 1); + string[0] = L'\0'; + _IO_wstr_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string); + ret = _IO_vfwprintf ((_IO_FILE *) &sf, format, args); + + if (sf.f._sbf._f._wide_data->_IO_buf_base != sf.overflow_buf) + *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + return ret; +} + +#ifdef weak_alias +weak_alias (_IO_vswprintf, __vswprintf) +weak_alias (_IO_vswprintf, vswprintf) +#endif diff --git a/libio/vwprintf.c b/libio/vwprintf.c new file mode 100644 index 0000000..1f3102e --- /dev/null +++ b/libio/vwprintf.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1993, 1995, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#undef __OPTIMIZE__ /* Avoid inline `vwprintf' function. */ +#include <stdio.h> + +/* Write formatted output to stdout according to the + format string FORMAT, using the argument list in ARG. */ +int +vwprintf (format, arg) + const wchar_t *format; + __gnuc_va_list arg; +{ + return vfwprintf (stdout, format, arg); +} diff --git a/libio/vwscanf.c b/libio/vwscanf.c new file mode 100644 index 0000000..fb24fc9 --- /dev/null +++ b/libio/vwscanf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "libioP.h" +#include <wchar.h> + +int +vwscanf (format, args) + const wchar_t *format; + _IO_va_list args; +{ + return _IO_vfwscanf (_IO_stdin, format, args, NULL); +} diff --git a/libio/wfiledoalloc.c b/libio/wfiledoalloc.c new file mode 100644 index 0000000..7f5cb7f --- /dev/null +++ b/libio/wfiledoalloc.c @@ -0,0 +1,105 @@ +/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* Modified for GNU iostream by Per Bothner 1991, 1992. */ + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include <sys/types.h> +#include <sys/stat.h> +#ifdef __STDC__ +#include <stdlib.h> +#include <unistd.h> +#endif + +#ifdef _LIBC +# undef isatty +# define isatty(Fd) __isatty (Fd) +#endif + +/* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. + * + * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek + * optimisation) right after the _fstat() that finds the buffer size. + */ + +int +_IO_wfile_doallocate (fp) + _IO_FILE *fp; +{ + _IO_size_t size; + int couldbetty; + wchar_t *p; + struct _G_stat64 st; + + /* Allocate room for the external buffer. */ + _IO_file_doallocate (fp); + + if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0) + { + couldbetty = 0; + size = _IO_BUFSIZ * sizeof (wchar_t); +#if 0 + /* do not try to optimise fseek() */ + fp->_flags |= __SNPT; +#endif + } + else + { + couldbetty = S_ISCHR (st.st_mode); +#if _IO_HAVE_ST_BLKSIZE + size = ((st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize) + * sizeof (wchar_t)); +#else + size = _IO_BUFSIZ * sizeof (wchar_t); +#endif + } + ALLOC_WBUF (p, size, EOF); + _IO_wsetb (fp, p, p + size, 1); + if (couldbetty && isatty (fp->_fileno)) + fp->_flags |= _IO_LINE_BUF; + return 1; +} diff --git a/libio/wfileops.c b/libio/wfileops.c new file mode 100644 index 0000000..b040b97 --- /dev/null +++ b/libio/wfileops.c @@ -0,0 +1,716 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + Written by Ulrich Drepper <drepper@cygnus.com>. + Based on the single byte version by Per Bothner <bothner@cygnus.com>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include <assert.h> +#include <libioP.h> +#include <wchar.h> +#include <gconv.h> +#include <stdlib.h> +#include <string.h> + + +_IO_FILE * +_IO_wfile_setbuf (fp, p, len) + _IO_FILE *fp; + wchar_t *p; + _IO_ssize_t len; +{ + if (_IO_wdefault_setbuf (fp, p, len) == NULL) + return NULL; + + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr = + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base; + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + + return fp; +} + + +/* Convert TO_DO wide character from DATA to FP. + Then mark FP as having empty buffers. */ +int +_IO_wdo_write (fp, data, to_do) + _IO_FILE *fp; + const wchar_t *data; + _IO_size_t to_do; +{ + struct _IO_codecvt *cc = &fp->_wide_data->_codecvt; + _IO_size_t count = 0; + + while (to_do > 0) + { + enum __codecvt_result result; + const wchar_t *new_data; + + if (fp->_IO_write_end == fp->_IO_write_ptr) + { + _IO_new_file_overflow (fp, EOF); + assert (fp->_IO_write_end > fp->_IO_write_ptr); + } + + /* Now convert from the internal format into the external buffer. */ + result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, + data, data + to_do, &new_data, + fp->_IO_write_ptr, + fp->_IO_write_end, + &fp->_IO_write_ptr); + + /* Write out what we produced so far. */ + if (_IO_new_do_write (fp, fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base) == EOF) + /* Something went wrong. */ + return EOF; + + count += new_data - data; + to_do -= new_data - data; + data = new_data; + + /* Next see whether we had problems during the conversion. If yes, + we cannot go on. */ + if (result != __codecvt_ok) + break; + } + + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + ? fp->_wide_data->_IO_buf_base + : fp->_wide_data->_IO_buf_end); + + return count; +} + + +wint_t +_IO_wfile_underflow (fp) + _IO_FILE *fp; +{ + struct _IO_codecvt *cd; + enum __codecvt_result status; + _IO_ssize_t count; + int tries; + const char *read_ptr_copy; + + if (fp->_flags & _IO_NO_READS) + { + __set_errno (EBADF); + return WEOF; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + cd = &fp->_wide_data->_codecvt; + + /* Maybe there is something left in the external buffer. */ + if (fp->_IO_read_ptr < fp->_IO_read_end) + { + /* Convert it. */ + size_t avail_bytes = fp->_IO_read_end - fp->_IO_read_ptr; + + if (avail_bytes >= (*cd->__codecvt_do_max_length) (cd)) + { + /* There is more in the external. */ + const char *read_stop = (const char *) fp->_IO_read_ptr; + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_end, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_stop; + + /* If we managed to generate some text return the next character. */ + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + if (status == __codecvt_error) + { + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; + } + } + + /* Move the remaining content of the read buffer to the beginning. */ + memmove (fp->_IO_buf_base, fp->_IO_read_ptr, + fp->_IO_read_end - fp->_IO_read_ptr); + fp->_IO_read_end = (fp->_IO_buf_base + + (fp->_IO_read_end - fp->_IO_read_ptr)); + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + } + else + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = + fp->_IO_buf_base; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = + fp->_IO_buf_base; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + } + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_wide_data->_IO_save_base != NULL) + { + free (fp->_wide_data->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_wdoallocbuf (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) + _IO_flush_all_linebuffered (); + + _IO_switch_to_get_mode (fp); + + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_buf_base; + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr = + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base; + + tries = 0; + again: + count = _IO_SYSREAD (fp, fp->_IO_read_end, + fp->_IO_buf_end - fp->_IO_read_end); + if (count <= 0) + { + if (count == 0 && tries == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + { + if (tries != 0) + /* There are some bytes in the external buffer but they don't + convert to anything. */ + __set_errno (EILSEQ); + return WEOF; + } + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + + /* Now convert the read input. */ + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_IO_read_base = fp->_IO_read_ptr; + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_ptr_copy, + fp->_wide_data->_IO_read_end, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_ptr_copy; + if (fp->_wide_data->_IO_read_end == fp->_wide_data->_IO_buf_base) + { + if (status == __codecvt_error || fp->_IO_read_end == fp->_IO_buf_end) + { + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; + } + + /* The read bytes make no complete character. Try reading again. */ + assert (status == __codecvt_partial); + ++tries; + goto again; + } + + return *fp->_wide_data->_IO_read_ptr; +} + + +wint_t +_IO_wfile_overflow (f, wch) + _IO_FILE *f; + wint_t wch; +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) + { + /* Allocate a buffer if needed. */ + if (f->_wide_data->_IO_write_base == 0) + { + _IO_wdoallocbuf (f); + _IO_wsetg (f, f->_wide_data->_IO_buf_base, + f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base); + } + else + { + /* Otherwise must be currently reading. If _IO_read_ptr + (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting + the read pointers to all point at the beginning of the + block). This makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving + that alone, so it can continue to correspond to the + external position). */ + if (f->_wide_data->_IO_read_ptr == f->_wide_data->_IO_buf_end) + { + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_wide_data->_IO_read_end = f->_wide_data->_IO_read_ptr = + f->_wide_data->_IO_buf_base; + } + } + f->_wide_data->_IO_write_ptr = f->_wide_data->_IO_read_ptr; + f->_wide_data->_IO_write_base = f->_wide_data->_IO_write_ptr; + f->_wide_data->_IO_write_end = f->_wide_data->_IO_buf_end; + f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr = + f->_wide_data->_IO_read_end; + + f->_flags |= _IO_CURRENTLY_PUTTING; + if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + f->_wide_data->_IO_write_end = f->_wide_data->_IO_write_ptr; + } + if (wch == WEOF) + return _IO_do_flush (f); + if (f->_wide_data->_IO_write_ptr == f->_wide_data->_IO_buf_end ) + /* Buffer is really full */ + if (_IO_do_flush (f) == WEOF) + return WEOF; + *f->_wide_data->_IO_write_ptr++ = wch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && wch == L'\n')) + if (_IO_do_flush (f) == WEOF) + return WEOF; + return wch; +} + +wint_t +_IO_wfile_sync (fp) + _IO_FILE *fp; +{ + _IO_ssize_t delta; + wint_t retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) + if (_IO_do_flush (fp)) + return WEOF; + delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + if (delta != 0) + { + /* We have to find out how many bytes we have to go back in the + external buffer. */ + struct _IO_codecvt *cv = &fp->_wide_data->_codecvt; + _IO_off64_t new_pos; + + int clen = (*cv->__codecvt_do_encoding) (cv); + + if (clen > 0) + /* It is easy, a fixed number of input bytes are used for each + wide character. */ + delta *= clen; + else + { + /* We have to find out the hard way how much to back off. + To do this we determine how much input we needed to + generate the wide characters up to the current reading + position. */ + int nread; + + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); + } + + new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off64_t) EOF) + { + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + fp->_IO_read_end = fp->_IO_read_ptr; + } +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = WEOF; + } + if (retval != WEOF) + fp->_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} + +_IO_off64_t +_IO_wfile_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t result; + _IO_off64_t delta, new_offset; + long int count; + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = ((fp->_wide_data->_IO_read_base + == fp->_wide_data->_IO_read_end) + && (fp->_wide_data->_IO_write_base + == fp->_wide_data->_IO_write_ptr)); + + if (mode == 0) + dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to ptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-papped files. */ + + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base + || _IO_in_put_mode (fp)) + if (_IO_switch_to_get_mode (fp)) + return WEOF; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_wide_data->_IO_read_base != NULL) + { + free (fp->_wide_data->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + } + + switch (dir) + { + struct _IO_codecvt *cv; + int clen; + + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). To do this we must + find out which position in the external buffer corresponds to + the current position in the internal buffer. */ + cv = &fp->_wide_data->_codecvt; + clen = (*cv->__codecvt_do_encoding) (cv); + + if (clen > 0) + offset -= (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr) * clen; + else + { + int nread; + + delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } + + if (fp->_offset == _IO_pos_BAD) + goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct _G_stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If we are only interested in the current position we've found it now. */ + if (mode == 0) + return offset; + + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + /* Offset relative to start of main get area. */ + _IO_off64_t rel_offset = (offset - fp->_offset + + (fp->_IO_read_end - fp->_IO_read_base)); + if (rel_offset >= 0) + { +#if 0 + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); +#endif + if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) + { + fp->_IO_read_ptr = fp->_IO_read_base + rel_offset; + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + + /* Now set the pointer for the internal buffer. This + might be an iterative process. Though the read + pointer is somewhere in the current external buffer + this does not mean we can convert this whole buffer + at once fitting in the internal buffer. */ + do + { + + } + while (0); + + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#ifdef TODO + /* If we have streammarkers, seek forward by reading ahead. */ + if (_IO_have_markers (fp)) + { + int to_skip = rel_offset + - (fp->_IO_read_ptr - fp->_IO_read_base); + if (ignore (to_skip) != to_skip) + goto dumb; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } +#ifdef TODO + if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ()) + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } + +#ifdef TODO + _IO_unsave_markers (fp); +#endif + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + _IO_unsave_markers (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + the file and the kernel file offset will be changed. */ + if (fp->_offset >= 0) + _IO_SYSSEEK (fp, fp->_offset, 0); + + return offset; +} + + +_IO_size_t +_IO_wfile_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + register const wchar_t *s = (const wchar_t *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + count = f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr; + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_wide_data->_IO_buf_end - f->_wide_data->_IO_write_ptr; + if (count >= n) + { + register const wchar_t *p; + for (p = s + n; p > s; ) + { + if (*--p == L'\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; + if (count > 20) + { +#ifdef _LIBC + f->_wide_data->_IO_write_ptr = + __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); +#else + wmemcpy (f->_wide_data->_IO_write_ptr, s, count); + f->_wide_data->_IO_write_ptr += count; +#endif + s += count; + } + else + { + register wchar_t *p = f->_wide_data->_IO_write_ptr; + register int i = (int) count; + while (--i >= 0) + *p++ = *s++; + f->_wide_data->_IO_write_ptr = p; + } + to_do -= count; + } + if (to_do > 0) + to_do -= _IO_wdefault_xsputn (f, s, to_do); + if (must_flush + && f->_wide_data->_IO_write_ptr != f->_wide_data->_IO_write_base) + _IO_wdo_write (f, f->_wide_data->_IO_write_base, + f->_wide_data->_IO_write_ptr + - f->_wide_data->_IO_write_base); + + return n - to_do; +} + + +struct _IO_jump_t _IO_wfile_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_wfile_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn), + JUMP_INIT(seekoff, _IO_wfile_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/libio/wgenops.c b/libio/wgenops.c new file mode 100644 index 0000000..496d080 --- /dev/null +++ b/libio/wgenops.c @@ -0,0 +1,747 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + Written by Ulrich Drepper <drepper@cygnus.com>. + Based on the single byte version by Per Bothner <bothner@cygnus.com>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Generic or default I/O operations. */ + +#include "libioP.h" +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <string.h> +#include <wchar.h> + + + +static int save_for_wbackup __P ((_IO_FILE *fp, wchar_t *end_p)) +#ifdef _LIBC + internal_function +#endif + ; + +/* Return minimum _pos markers + Assumes the current get area is the main get area. */ +_IO_ssize_t _IO_least_wmarker __P ((_IO_FILE *fp, wchar_t *end_p)); + +_IO_ssize_t +_IO_least_wmarker (fp, end_p) + _IO_FILE *fp; + wchar_t *end_p; +{ + _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base; + struct _IO_marker *mark; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + if (mark->_pos < least_so_far) + least_so_far = mark->_pos; + return least_so_far; +} + +/* Switch current get area from backup buffer to (start of) main get area. */ +void +_IO_switch_to_main_wget_area (fp) + _IO_FILE *fp; +{ + wchar_t *tmp; + fp->_flags &= ~_IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end; + fp->_wide_data->_IO_save_end= tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base; + fp->_wide_data->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base; +} + + +/* Switch current get area from main get area to (end of) backup area. */ +void +_IO_switch_to_wbackup_area (fp) + _IO_FILE *fp; +{ + wchar_t *tmp; + fp->_flags |= _IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end; + fp->_wide_data->_IO_save_end = tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base; + fp->_wide_data->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; +} + + +void +_IO_wsetb (f, b, eb, a) + _IO_FILE *f; + wchar_t *b; + wchar_t *eb; + int a; +{ + if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) + FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f)); + f->_wide_data->_IO_buf_base = b; + f->_wide_data->_IO_buf_end = eb; + if (a) + f->_flags &= ~_IO_USER_BUF; + else + f->_flags |= _IO_USER_BUF; +} + + +wint_t +_IO_wdefault_pbackfail (fp, c) + _IO_FILE *fp; + wint_t c; +{ + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && !_IO_in_backup (fp) + && (wint_t) fp->_IO_read_ptr[-1] == c) + --fp->_IO_read_ptr; + else + { + /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ + if (!_IO_in_backup (fp)) + { + /* We need to keep the invariant that the main get area + logically follows the backup area. */ + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && _IO_have_wbackup (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr)) + return WEOF; + } + else if (!_IO_have_wbackup (fp)) + { + /* No backup buffer: allocate one. */ + /* Use nshort buffer, if unused? (probably not) FIXME */ + int backup_size = 128; + wchar_t *bbuf = (wchar_t *) malloc (backup_size + * sizeof (wchar_t)); + if (bbuf == NULL) + return WEOF; + fp->_wide_data->_IO_save_base = bbuf; + fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base + + backup_size); + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end; + } + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr; + _IO_switch_to_wbackup_area (fp); + } + else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base) + { + /* Increase size of existing backup buffer. */ + _IO_size_t new_size; + _IO_size_t old_size = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_base); + wchar_t *new_buf; + new_size = 2 * old_size; + new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t)); + if (new_buf == NULL) + return WEOF; + __wmemcpy (new_buf + (new_size - old_size), + fp->_wide_data->_IO_read_base, old_size); + free (fp->_wide_data->_IO_read_base); + _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size), + new_buf + new_size); + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr; + } + + *--fp->_wide_data->_IO_read_ptr = c; + } + return c; +} + + +void +_IO_wdefault_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + struct _IO_marker *mark; + if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + { + FREE_BUF (fp->_wide_data->_IO_buf_base, + _IO_wblen (fp) * sizeof (wchar_t)); + fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL; + } + + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_sbuf = NULL; + + if (fp->_IO_save_base) + { + free (fp->_wide_data->_IO_save_base); + fp->_IO_save_base = NULL; + } + +#ifdef _IO_MTSAFE_IO + _IO_lock_fini (*fp->_lock); +#endif + + _IO_un_link (fp); +} + + +wint_t +_IO_wdefault_uflow (fp) + _IO_FILE *fp; +{ + wint_t wch; + wch = _IO_UNDERFLOW (fp); + if (wch == WEOF) + return WEOF; + return *fp->_wide_data->_IO_read_ptr++; +} + + +wint_t +__woverflow (f, wch) + _IO_FILE *f; + wint_t wch; +{ + if (f->_mode == 0) + _IO_fwide (f, 1); + return _IO_OVERFLOW (f, wch); +} + + +wint_t +__wuflow (fp) + _IO_FILE *fp; +{ + if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) + return EOF; + + if (fp->_mode == 0) + _IO_fwide (fp, 1); + if (_IO_in_put_mode (fp)) + if (_IO_switch_to_get_mode (fp) == EOF) + return WEOF; + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr++; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_wget_area (fp); + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr++; + } + if (_IO_have_markers (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) + return WEOF; + } + else if (_IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + return _IO_UFLOW (fp); +} + + +wint_t +__wunderflow (fp) + _IO_FILE *fp; +{ + if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) + return EOF; + + if (_IO_in_put_mode (fp)) + if (_IO_switch_to_wget_mode (fp) == WEOF) + return WEOF; + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_wget_area (fp); + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + } + if (_IO_have_markers (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) + return EOF; + } + else if (_IO_have_backup (fp)) + _IO_free_wbackup_area (fp); + return _IO_UNDERFLOW (fp); +} + + +_IO_size_t +_IO_wdefault_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + const wchar_t *s = (const wchar_t *) data; + _IO_size_t more = n; + if (more <= 0) + return 0; + for (;;) + { + /* Space available. */ + _IO_ssize_t count = (f->_wide_data->_IO_write_end + - f->_wide_data->_IO_write_ptr); + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + f->_wide_data->_IO_write_ptr = + __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); +#else + memcpy (f->_wide_data->_IO_write_ptr, s, count); + f->_wide_data->_IO_write_ptr += count; +#endif + s += count; + } + else if (count <= 0) + count = 0; + else + { + wchar_t *p = f->_wide_data->_IO_write_ptr; + _IO_ssize_t i; + for (i = count; --i >= 0; ) + *p++ = *s++; + f->_wide_data->_IO_write_ptr = p; + } + more -= count; + } + if (more == 0 || __woverflow (f, *s++) == WEOF) + break; + more--; + } + return n - more; +} + + +_IO_size_t +_IO_wdefault_xsgetn (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + _IO_size_t more = n; + wchar_t *s = (wchar_t*) data; + for (;;) + { + /* Data available. */ + _IO_ssize_t count = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count); +#else + memcpy (s, fp->_wide_data->_IO_read_ptr, count); + s += count; +#endif + fp->_wide_data->_IO_read_ptr += count; + } + else if (count <= 0) + count = 0; + else + { + wchar_t *p = fp->_wide_data->_IO_read_ptr; + int i = (int) count; + while (--i >= 0) + *s++ = *p++; + fp->_wide_data->_IO_read_ptr = p; + } + more -= count; + } + if (more == 0 || __wunderflow (fp) == WEOF) + break; + } + return n - more; +} + + +void +_IO_wdoallocbuf (fp) + _IO_FILE *fp; +{ + if (fp->_wide_data->_IO_buf_base) + return; + if (!(fp->_flags & _IO_UNBUFFERED)) + if (_IO_DOALLOCATE (fp) != WEOF) + return; + _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1, 0); +} + + +_IO_FILE * +_IO_wdefault_setbuf (fp, p, len) + _IO_FILE *fp; + wchar_t *p; + _IO_ssize_t len; +{ + if (_IO_SYNC (fp) == EOF) + return NULL; + if (p == NULL || len == 0) + { + fp->_flags |= _IO_UNBUFFERED; + _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1, + 0); + } + else + { + fp->_flags &= ~_IO_UNBUFFERED; + _IO_wsetb (fp, p, p + len, 0); + } + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_write_end = 0; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr + = fp->_wide_data->_IO_read_end = 0; + return fp; +} + + +int +_IO_wdefault_doallocate (fp) + _IO_FILE *fp; +{ + wchar_t *buf; + + ALLOC_WBUF (buf, _IO_BUFSIZ, EOF); + _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1); + return 1; +} + + +int +_IO_switch_to_wget_mode (fp) + _IO_FILE *fp; +{ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) + if (_IO_OVERFLOW (fp, EOF) == EOF) + return EOF; + if (_IO_in_backup (fp)) + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base; + else + { + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + } + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + return 0; +} + +void +_IO_free_wbackup_area (fp) + _IO_FILE *fp; +{ + if (_IO_in_backup (fp)) + _IO_switch_to_main_wget_area (fp); /* Just in case. */ + free (fp->_wide_data->_IO_save_base); + fp->_wide_data->_IO_save_base = NULL; + fp->_wide_data->_IO_save_end = NULL; + fp->_wide_data->_IO_backup_base = NULL; +} + +#if 0 +int +_IO_switch_to_wput_mode (fp) + _IO_FILE *fp; +{ + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; + /* Following is wrong if line- or un-buffered? */ + fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP + ? fp->_wide_data->_IO_read_end + : fp->_wide_data->_IO_buf_end); + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end; + + fp->_flags |= _IO_CURRENTLY_PUTTING; + return 0; +} +#endif + + +static int +#ifdef _LIBC +internal_function +#endif +save_for_wbackup (fp, end_p) + _IO_FILE *fp; + wchar_t *end_p; +{ + /* Append [_IO_read_base..end_p] to backup area. */ + _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p); + /* needed_size is how much space we need in the backup area. */ + _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base) + - least_mark); + /* FIXME: Dubious arithmetic if pointers are NULL */ + _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end + - fp->_wide_data->_IO_save_base); + _IO_size_t avail; /* Extra space available for future expansion. */ + _IO_ssize_t delta; + struct _IO_marker *mark; + if (needed_size > current_Bsize) + { + wchar_t *new_buffer; + avail = 100; + new_buffer = (wchar_t *) malloc ((avail + needed_size) + * sizeof (wchar_t)); + if (new_buffer == NULL) + return EOF; /* FIXME */ + if (least_mark < 0) + { +#ifdef _LIBC + __wmempcpy (__wmempcpy (new_buffer + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark), + fp->_wide_data->_IO_read_base, + end_p - fp->_wide_data->_IO_read_base); +#else + memcpy (new_buffer + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark * sizeof (wchar_t)); + memcpy (new_buffer + avail - least_mark, + fp->_wide_data->_IO_read_base, + (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); +#endif + } + else + { +#ifdef _LIBC + __wmemcpy (new_buffer + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size); +#else + memcpy (new_buffer + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size * sizeof (wchar_t)); +#endif + } + if (fp->_wide_data->_IO_save_base) + free (fp->_wide_data->_IO_save_base); + fp->_wide_data->_IO_save_base = new_buffer; + fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size; + } + else + { + avail = current_Bsize - needed_size; + if (least_mark < 0) + { +#ifdef _LIBC + __wmemmove (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark); + __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark, + fp->_wide_data->_IO_read_base, + end_p - fp->_wide_data->_IO_read_base); +#else + memmove (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark * sizeof (wchar_t)); + memcpy (fp->_wide_data->_IO_save_base + avail - least_mark, + fp->_wide_data->_IO_read_base, + (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); +#endif + } + else if (needed_size > 0) +#ifdef _LIBC + __wmemcpy (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size); +#else + memcpy (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size * sizeof (wchar_t)); +#endif + } + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail; + /* Adjust all the streammarkers. */ + delta = end_p - fp->_wide_data->_IO_read_base; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_pos -= delta; + return 0; +} + +wint_t +_IO_sputbackwc (fp, c) + _IO_FILE *fp; + wint_t c; +{ + wint_t result; + + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c) + { + fp->_wide_data->_IO_read_ptr--; + result = c; + } + else + result = _IO_PBACKFAIL (fp, c); + + if (result != EOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} + +wint_t +_IO_sungetwc (fp) + _IO_FILE *fp; +{ + int result; + + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base) + { + fp->_wide_data->_IO_read_ptr--; + result = *fp->_wide_data->_IO_read_ptr; + } + else + result = _IO_PBACKFAIL (fp, EOF); + + if (result != WEOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} + + +unsigned +_IO_adjust_wcolumn (start, line, count) + unsigned start; + const wchar_t *line; + int count; +{ + const wchar_t *ptr = line + count; + while (ptr > line) + if (*--ptr == L'\n') + return line + count - ptr - 1; + return start + count; +} + +void +_IO_init_wmarker (marker, fp) + struct _IO_marker *marker; + _IO_FILE *fp; +{ + marker->_sbuf = fp; + if (_IO_in_put_mode (fp)) + _IO_switch_to_get_mode (fp); + if (_IO_in_backup (fp)) + marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + else + marker->_pos = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + + /* Should perhaps sort the chain? */ + marker->_next = fp->_markers; + fp->_markers = marker; +} + +#define BAD_DELTA EOF + +/* Return difference between MARK and current position of MARK's stream. */ +int +_IO_wmarker_delta (mark) + struct _IO_marker *mark; +{ + int cur_pos; + if (mark->_sbuf == NULL) + return BAD_DELTA; + if (_IO_in_backup (mark->_sbuf)) + cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr + - mark->_sbuf->_wide_data->_IO_read_end); + else + cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr + - mark->_sbuf->_wide_data->_IO_read_base); + return mark->_pos - cur_pos; +} + +int +_IO_seekwmark (fp, mark, delta) + _IO_FILE *fp; + struct _IO_marker *mark; + int delta; +{ + if (mark->_sbuf != fp) + return EOF; + if (mark->_pos >= 0) + { + if (_IO_in_backup (fp)) + _IO_switch_to_main_wget_area (fp); + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + mark->_pos); + } + else + { + if (!_IO_in_backup (fp)) + _IO_switch_to_wbackup_area (fp); + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos; + } + return 0; +} + +void +_IO_unsave_wmarkers (fp) + _IO_FILE *fp; +{ + struct _IO_marker *mark = fp->_markers; + if (mark) + { +#ifdef TODO + streampos offset = seekoff (0, ios::cur, ios::in); + if (offset != EOF) + { + offset += eGptr () - Gbase (); + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (mark->_pos + offset); + } + else + { + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (EOF); + } +#endif + fp->_markers = 0; + } + + if (_IO_have_backup (fp)) + _IO_free_wbackup_area (fp); +} diff --git a/libio/wprintf.c b/libio/wprintf.c new file mode 100644 index 0000000..6fb6c32 --- /dev/null +++ b/libio/wprintf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#include <stdio.h> + +/* Write formatted output to stdout from the format string FORMAT. */ +/* VARARGS1 */ +int +wprintf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = vfwprintf (stdout, format, arg); + va_end (arg); + + return done; +} diff --git a/libio/wscanf.c b/libio/wscanf.c new file mode 100644 index 0000000..a530d6f --- /dev/null +++ b/libio/wscanf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdarg.h> +#include <stdio.h> + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int +wscanf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = _IO_vfwscanf (stdin, format, arg, NULL); + va_end (arg); + + return done; +} diff --git a/libio/wstrops.c b/libio/wstrops.c new file mode 100644 index 0000000..af2c957 --- /dev/null +++ b/libio/wstrops.c @@ -0,0 +1,330 @@ +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "strfile.h" +#include "libioP.h" +#include <string.h> +#include <wchar.h> + +#if 0 +/* The following definitions are for exposition only. + They map the terminology used in the ANSI/ISO C++ draft standard + to the implementation. */ + +/* allocated: set when a dynamic array object has been allocated, and + hence should be freed by the destructor for the strstreambuf object. */ +#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP)) + +/* constant: set when the array object has const elements, + so the output sequence cannot be written. */ +#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES) + +/* alsize: the suggested minimum size for a dynamic array object. */ +#define ALSIZE(FP) ??? /* not stored */ + +/* palloc: points to the function to call to allocate a dynamic array object.*/ +#define PALLOC(FP) \ + ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer) + +/* pfree: points to the function to call to free a dynamic array object. */ +#define PFREE(FP) \ + ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer) + +#endif + +#ifdef TODO +/* An "unbounded buffer" is when a buffer is supplied, but with no + specified length. An example is the buffer argument to sprintf. + */ +#endif + +void +_IO_wstr_init_static (fp, ptr, size, pstart) + _IO_FILE *fp; + wchar_t *ptr; + int size; + wchar_t *pstart; +{ + if (size == 0) + size = __wcslen (ptr); + else if (size < 0) + { + /* If size is negative 'the characters are assumed to + continue indefinitely.' This is kind of messy ... */ + int s; + size = 512; + /* Try increasing powers of 2, as long as we don't wrap around. */ + for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; ) + size = s; + /* Try increasing size as much as we can without wrapping around. */ + for (s = size >> 1; s > 0; s >>= 1) + { + if (ptr + size + s > ptr) + size += s; + } + } + _IO_wsetb (fp, ptr, ptr + size, 0); + + fp->_wide_data->_IO_write_base = ptr; + fp->_wide_data->_IO_read_base = ptr; + fp->_wide_data->_IO_read_ptr = ptr; + if (pstart) + { + fp->_wide_data->_IO_write_ptr = pstart; + fp->_wide_data->_IO_write_end = ptr + size; + fp->_wide_data->_IO_read_end = pstart; + } + else + { + fp->_wide_data->_IO_write_ptr = ptr; + fp->_wide_data->_IO_write_end = ptr; + fp->_wide_data->_IO_read_end = ptr + size; + } + /* A null _allocate_buffer function flags the strfile as being static. */ + (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0; +} + +void +_IO_wstr_init_readonly (fp, ptr, size) + _IO_FILE *fp; + const char *ptr; + int size; +{ + _IO_wstr_init_static (fp, (wchar_t *) ptr, size, NULL); + fp->_IO_file_flags |= _IO_NO_WRITES; +} + +_IO_wint_t +_IO_wstr_overflow (fp, c) + _IO_FILE *fp; + _IO_wint_t c; +{ + int flush_only = c == WEOF; + _IO_size_t pos; + if (fp->_flags & _IO_NO_WRITES) + return flush_only ? 0 : WEOF; + if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags |= _IO_CURRENTLY_PUTTING; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + } + pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; + if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only)) + { + if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ + return WEOF; + else + { + wchar_t *new_buf; + wchar_t *old_buf = fp->_wide_data->_IO_buf_base; + _IO_size_t new_size = 2 * _IO_wblen (fp) + 100; + new_buf + = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size + * sizeof (wchar_t)); + if (new_buf == NULL) + { + /* __ferror(fp) = 1; */ + return WEOF; + } + if (old_buf) + { + __wmemcpy (new_buf, old_buf, _IO_wblen (fp)); + (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + /* Make sure _IO_setb won't try to delete _IO_buf_base. */ + fp->_wide_data->_IO_buf_base = NULL; + } + _IO_wsetb (fp, new_buf, new_buf + new_size, 1); + fp->_wide_data->_IO_read_base = + new_buf + (fp->_wide_data->_IO_read_base - old_buf); + fp->_wide_data->_IO_read_ptr = + new_buf + (fp->_wide_data->_IO_read_ptr - old_buf); + fp->_wide_data->_IO_read_end = + new_buf + (fp->_wide_data->_IO_read_end - old_buf); + fp->_wide_data->_IO_write_ptr = + new_buf + (fp->_wide_data->_IO_write_ptr - old_buf); + + fp->_wide_data->_IO_write_base = new_buf; + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end; + } + } + + if (!flush_only) + *fp->_wide_data->_IO_write_ptr++ = c; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + return c; +} + +_IO_wint_t +_IO_wstr_underflow (fp) + _IO_FILE *fp; +{ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_end; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + else + return WEOF; +} + +/* The size of the valid part of the buffer. */ + +_IO_ssize_t +_IO_wstr_count (fp) + _IO_FILE *fp; +{ + return ((fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end + ? fp->_wide_data->_IO_write_ptr : fp->_wide_data->_IO_read_end) + - fp->_wide_data->_IO_read_base); +} + +_IO_off64_t +_IO_wstr_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t new_pos; + + if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) + mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + + if (mode == 0) + { + /* Don't move any pointers. But there is no clear indication what + mode FP is in. Let's guess. */ + if (fp->_IO_file_flags & _IO_NO_WRITES) + new_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base; + else + new_pos = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + } + else + { + _IO_ssize_t cur_size = _IO_wstr_count (fp); + new_pos = EOF; + + /* Move the get pointer, if requested. */ + if (mode & _IOS_INPUT) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + offset); + fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base + + cur_size); + new_pos = offset; + } + + /* Move the put pointer, if requested. */ + if (mode & _IOS_OUTPUT) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base + + offset); + new_pos = offset; + } + } + return new_pos; +} + +_IO_wint_t +_IO_wstr_pbackfail (fp, c) + _IO_FILE *fp; + _IO_wint_t c; +{ + if ((fp->_flags & _IO_NO_WRITES) && c != EOF) + return WEOF; + return _IO_wdefault_pbackfail (fp, c); +} + +void +_IO_wstr_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_buf_base = NULL; + + _IO_wdefault_finish (fp, 0); +} + +struct _IO_jump_t _IO_wstr_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT(xsputn, _IO_wdefault_xsputn), + JUMP_INIT(xsgetn, _IO_wdefault_xsgetn), + JUMP_INIT(seekoff, _IO_wstr_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_wdefault_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/locale/C-time.c b/locale/C-time.c index 673d9bd..6a846e4 100644 --- a/locale/C-time.c +++ b/locale/C-time.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1995. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -27,7 +27,7 @@ const struct locale_data _nl_C_LC_TIME = _nl_C_name, NULL, 0, 0, /* no file mapped */ UNDELETABLE, - 54, + 104, { { string: "Sun" }, { string: "Mon" }, @@ -83,5 +83,55 @@ const struct locale_data _nl_C_LC_TIME = { word: 0 }, { string: "" }, { string: "" }, + { wstr: L"Sun" }, + { wstr: L"Mon" }, + { wstr: L"Tue" }, + { wstr: L"Wed" }, + { wstr: L"Thu" }, + { wstr: L"Fri" }, + { wstr: L"Sat" }, + { wstr: L"Sunday" }, + { wstr: L"Monday" }, + { wstr: L"Tuesday" }, + { wstr: L"Wednesday" }, + { wstr: L"Thursday" }, + { wstr: L"Friday" }, + { wstr: L"Saturday" }, + { wstr: L"Jan" }, + { wstr: L"Feb" }, + { wstr: L"Mar" }, + { wstr: L"Apr" }, + { wstr: L"May" }, + { wstr: L"Jun" }, + { wstr: L"Jul" }, + { wstr: L"Aug" }, + { wstr: L"Sep" }, + { wstr: L"Oct" }, + { wstr: L"Nov" }, + { wstr: L"Dec" }, + { wstr: L"January" }, + { wstr: L"February" }, + { wstr: L"March" }, + { wstr: L"April" }, + { wstr: L"May" }, + { wstr: L"June" }, + { wstr: L"July" }, + { wstr: L"August" }, + { wstr: L"September" }, + { wstr: L"October" }, + { wstr: L"November" }, + { wstr: L"December" }, + { wstr: L"AM" }, + { wstr: L"PM" }, + { wstr: L"%a %b %e %H:%M:%S %Y" }, + { wstr: L"%m/%d/%y" }, + { wstr: L"%H:%M:%S" }, + { wstr: L"%I:%M:%S %p" }, + { string: NULL }, + { string: "" }, + { string: "" }, + { string: "" }, + { string: "" }, + { string: "" }, } }; diff --git a/locale/categories.def b/locale/categories.def index 098d712..71cb86d 100644 --- a/locale/categories.def +++ b/locale/categories.def @@ -1,5 +1,5 @@ /* Definition of all available locale categories and their items. -*- C -*- - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -147,6 +147,21 @@ DEFINE_CATEGORY DEFINE_ELEMENT (_NL_TIME_ERA_NUM_ENTRIES, "time-era-num-entries", opt, word) DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES_EB, "time-era-entries-eb", opt, string) DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES_EL, "time-era-entries-el", opt, string) + DEFINE_ELEMENT (_NL_WABDAY_1, "wide-abday", std, stringarray, 7, 7) + DEFINE_ELEMENT (_NL_WDAY_1, "wide-day", std, stringarray, 7, 7) + DEFINE_ELEMENT (_NL_WABMON_1, "wide-abmon", std, stringarray, 12, 12) + DEFINE_ELEMENT (_NL_WMON_1, "wide-mon", std, stringarray, 12, 12) + DEFINE_ELEMENT (_NL_WAM_STR, "wide-am_pm", std, stringarray, 2, 2) + DEFINE_ELEMENT (_NL_WD_T_FMT, "wide-d_t_fmt", std, string) + DEFINE_ELEMENT (_NL_WD_FMT, "wide-d_fmt", std, string) + DEFINE_ELEMENT (_NL_WT_FMT, "wide-t_fmt", std, string) + DEFINE_ELEMENT (_NL_WT_FMT_AMPM, "wide-t_fmt_ampm", std, string) + DEFINE_ELEMENT (_NL_WERA, "wide-era", opt, stringarray) + DEFINE_ELEMENT (_NL_WERA_YEAR, "wide-era_year", opt, string) + DEFINE_ELEMENT (_NL_WERA_D_FMT, "wide-era_d_fmt", opt, string) + DEFINE_ELEMENT (_NL_WALT_DIGITS, "wide-alt_digits", opt, stringarray, 0, 100) + DEFINE_ELEMENT (_NL_WERA_D_T_FMT, "wide-era_d_t_fmt", opt, string) + DEFINE_ELEMENT (_NL_WERA_T_FMT, "wide-era_t_fmt", opt, string) ), _nl_postload_time, NULL, NULL, NULL) diff --git a/locale/langinfo.h b/locale/langinfo.h index a96e52f..935a381 100644 --- a/locale/langinfo.h +++ b/locale/langinfo.h @@ -161,6 +161,66 @@ enum _NL_TIME_ERA_ENTRIES_EB, /* Structure with era entries in usable form.*/ _NL_TIME_ERA_ENTRIES_EL, + _NL_WABDAY_1, /* Sun */ + _NL_WABDAY_2, + _NL_WABDAY_3, + _NL_WABDAY_4, + _NL_WABDAY_5, + _NL_WABDAY_6, + _NL_WABDAY_7, + + /* Long-named days of the week. */ + _NL_WDAY_1, /* Sunday */ + _NL_WDAY_2, /* Monday */ + _NL_WDAY_3, /* Tuesday */ + _NL_WDAY_4, /* Wednesday */ + _NL_WDAY_5, /* Thursday */ + _NL_WDAY_6, /* Friday */ + _NL_WDAY_7, /* Saturday */ + + /* Abbreviated month names. */ + _NL_WABMON_1, /* Jan */ + _NL_WABMON_2, + _NL_WABMON_3, + _NL_WABMON_4, + _NL_WABMON_5, + _NL_WABMON_6, + _NL_WABMON_7, + _NL_WABMON_8, + _NL_WABMON_9, + _NL_WABMON_10, + _NL_WABMON_11, + _NL_WABMON_12, + + /* Long month names. */ + _NL_WMON_1, /* January */ + _NL_WMON_2, + _NL_WMON_3, + _NL_WMON_4, + _NL_WMON_5, + _NL_WMON_6, + _NL_WMON_7, + _NL_WMON_8, + _NL_WMON_9, + _NL_WMON_10, + _NL_WMON_11, + _NL_WMON_12, + + _NL_WAM_STR, /* Ante meridian string. */ + _NL_WPM_STR, /* Post meridian string. */ + + _NL_WD_T_FMT, /* Date and time format for strftime. */ + _NL_WD_FMT, /* Date format for strftime. */ + _NL_WT_FMT, /* Time format for strftime. */ + _NL_WT_FMT_AMPM, /* 12-hour time format for strftime. */ + + _NL_WERA, /* Alternate era. */ + _NL_WERA_YEAR, /* Year in alternate era format. */ + _NL_WERA_D_FMT, /* Date in alternate era format. */ + _NL_WALT_DIGITS, /* Alternate symbols for digits. */ + _NL_WERA_D_T_FMT, /* Date and time in alternate era format. */ + _NL_WERA_T_FMT, /* Time in alternate era format. */ + _NL_NUM_LC_TIME, /* Number of indices in LC_TIME category. */ /* LC_COLLATE category: text sorting. diff --git a/locale/localeinfo.h b/locale/localeinfo.h index dddacfe..2c1ce65 100644 --- a/locale/localeinfo.h +++ b/locale/localeinfo.h @@ -112,9 +112,14 @@ extern struct locale_data * *const _nl_current[LC_ALL + 1]; extern const char _nl_C_name[]; extern const char _nl_POSIX_name[]; +/* XXX Temporily until the locale data has everything. */ +extern struct locale_data _nl_C_LC_TIME; + /* Extract the current CATEGORY locale's string for ITEM. */ #define _NL_CURRENT(category, item) \ - (_nl_current_##category->values[_NL_ITEM_INDEX (item)].string) + ((item) < _NL_WABDAY_1 || (item) > _NL_WALT_DIGITS \ + ? (_nl_current_##category->values[_NL_ITEM_INDEX (item)].string) \ + : _nl_C_LC_TIME.values[_NL_ITEM_INDEX (item)].string) /* Extract the current CATEGORY locale's word for ITEM. */ #define _NL_CURRENT_WORD(category, item) \ diff --git a/localedata/Makefile b/localedata/Makefile index f4260cb..099a301 100644 --- a/localedata/Makefile +++ b/localedata/Makefile @@ -72,7 +72,7 @@ $(inst_i18ndir)/repertoiremaps/%: repertoiremaps/% $(+force); $(do-install) ifeq (no,$(cross-compiling)) ifeq (yes,$(build-shared)) .PHONY: do-collate-test do-tst-fmon do-tst-locale do-tst-rpmatch -tests: do-collate-test do-tst-fmon do-tst-locale do-tst-rpmatch +#tests: do-collate-test do-tst-fmon do-tst-locale do-tst-rpmatch do-collate-test: sort-test.sh $(objpfx)collate-test $(objpfx)xfrm-test \ $(test-input-data) $(SHELL) -e $< $(common-objpfx) $(test-input) diff --git a/manual/stdio.texi b/manual/stdio.texi index 8c6c009..75c3937 100644 --- a/manual/stdio.texi +++ b/manual/stdio.texi @@ -2170,6 +2170,9 @@ type modifier was specified. For integer conversions, this indicates @code{long long int}, as opposed to @code{long double} for floating point conversions. +@item unsigned int is_char +This is a boolean that is true if the @samp{hh} type modifier was specified. + @item unsigned int is_short This is a boolean that is true if the @samp{h} type modifier was specified. @@ -2197,6 +2200,9 @@ be used freely by the user-defined handlers but when called from the @code{printf} function this variable always contains the value @code{0}. +@item unsigned int wide +This flag is set if the stream is wide oriented. + @item wchar_t pad This is the character to use for padding the output to the minimum field width. The value is @code{'0'} if the @samp{0} flag was specified, and diff --git a/manual/time.texi b/manual/time.texi index e9548b9..7d5cfda 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -1005,6 +1005,31 @@ is examined before any output is produced. For an example of @code{strftime}, see @ref{Time Functions Example}. @end deftypefun +@comment time.h +@comment ISO/Amend1 +@deftypefun size_t wcsftime (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, const struct tm *@var{brokentime}) +The @code{wcsftime} function is equivalent to the @code{strftime} +function with the difference that it operates one wide character +strings. The buffer where the result is stored, pointed to by @var{s}, +must be an array of wide characters. The parameter @var{size} which +specifies the size of the output buffer gives the number of wide +character, not the number of bytes. + +Also the format string @var{template} is a wide character string. Since +all characters needed to specify the format string are in the basic +characater set it is portably possible to write format strings in the C +source code using the @code{L"..."} notation. The parameter +@var{brokentime} has the same meaning as in the @code{strftime} call. + +The @code{wcsftime} function supports the same flags, modifiers, and +format specifiers as the @code{strftime} function. + +The return value of @code{wcsftime} is the number of wide characters +stored in @code{s}. When more characters would have to be written than +can be placed in the buffer @var{s} the return value is zero, with the +same problems indicated in the @code{strftime} documentation. +@end deftypefun + @node Parsing Date and Time @subsection Convert textual time and date information back diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 9fb0c5d..7490018 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -25,11 +25,12 @@ headers := printf.h routines := \ ctermid cuserid \ - _itoa itoa-digits \ + _itoa _itowa itoa-digits itowa-digits \ vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \ printf_size fprintf printf snprintf sprintf asprintf dprintf \ vfscanf \ fscanf scanf sscanf \ + vfwprintf vfwscanf \ perror psignal \ tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ getline getw putw \ diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c index 3a7cd78..2eca838 100644 --- a/stdio-common/_itoa.c +++ b/stdio-common/_itoa.c @@ -78,7 +78,7 @@ struct base_table_t /* Local variables. */ -static const struct base_table_t base_table[] = +const struct base_table_t _itoa_base_table[] = { #if BITS_PER_MP_LIMB == 64 /* 2 */ {SEL1(0ul) 1, 1}, @@ -171,7 +171,7 @@ _itoa (value, buflim, base, upper_case) { const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits; char *bp = buflim; - const struct base_table_t *brec = &base_table[base - 2]; + const struct base_table_t *brec = &_itoa_base_table[base - 2]; switch (base) { diff --git a/stdio-common/_itowa.c b/stdio-common/_itowa.c new file mode 100644 index 0000000..430415b --- /dev/null +++ b/stdio-common/_itowa.c @@ -0,0 +1,346 @@ +/* Internal function for converting integers to ASCII. + Copyright (C) 1994, 1995, 1996, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund <tege@matematik.su.se> + and Ulrich Drepper <drepper@gnu.org>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <gmp-mparam.h> +#include <stdlib/gmp.h> +#include <stdlib/gmp-impl.h> +#include <stdlib/longlong.h> + +#include "_itowa.h" + + +/* Canonize environment. For some architectures not all values might + be defined in the GMP header files. */ +#ifndef UMUL_TIME +# define UMUL_TIME 1 +#endif +#ifndef UDIV_TIME +# define UDIV_TIME 3 +#endif + +/* Control memory layout. */ +#ifdef PACK +# undef PACK +# define PACK __attribute__ ((packed)) +#else +# define PACK +#endif + + +/* Declare local types. */ +struct base_table_t +{ +#if (UDIV_TIME > 2 * UMUL_TIME) + mp_limb_t base_multiplier; +#endif + char flag; + char post_shift; +#if BITS_PER_MP_LIMB == 32 + struct + { + char normalization_steps; + char ndigits; + mp_limb_t base PACK; +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb_t base_ninv PACK; +#endif + } big; +#endif +}; + +/* To reduce the memory needed we include some fields of the tables + only conditionally. */ +#if UDIV_TIME > 2 * UMUL_TIME +# define SEL1(X) X, +# define SEL2(X) ,X +#else +# define SEL1(X) +# define SEL2(X) +#endif + +/* Factor table for the different bases. */ +extern const struct base_table_t _itoa_base_table[]; + +/* Lower-case digits. */ +extern const wchar_t _itowa_lower_digits[]; +/* Upper-case digits. */ +extern const wchar_t _itowa_upper_digits[]; + + +wchar_t * +_itowa (value, buflim, base, upper_case) + unsigned long long int value; + wchar_t *buflim; + unsigned int base; + int upper_case; +{ + const wchar_t *digits = (upper_case + ? _itowa_upper_digits : _itowa_lower_digits); + wchar_t *bp = buflim; + const struct base_table_t *brec = &_itoa_base_table[base - 2]; + + switch (base) + { +#define RUN_2N(BITS) \ + do \ + { \ + /* `unsigned long long int' always has 64 bits. */ \ + mp_limb_t work_hi = value >> (64 - BITS_PER_MP_LIMB); \ + \ + if (BITS_PER_MP_LIMB == 32) \ + { \ + if (work_hi != 0) \ + { \ + mp_limb_t work_lo; \ + int cnt; \ + \ + work_lo = value & 0xfffffffful; \ + for (cnt = BITS_PER_MP_LIMB / BITS; cnt > 0; --cnt) \ + { \ + *--bp = digits[work_lo & ((1ul << BITS) - 1)]; \ + work_lo >>= BITS; \ + } \ + if (BITS_PER_MP_LIMB % BITS != 0) \ + { \ + work_lo \ + |= ((work_hi \ + & ((1 << (BITS - BITS_PER_MP_LIMB%BITS)) \ + - 1)) \ + << BITS_PER_MP_LIMB % BITS); \ + work_hi >>= BITS - BITS_PER_MP_LIMB % BITS; \ + if (work_hi == 0) \ + work_hi = work_lo; \ + else \ + *--bp = digits[work_lo]; \ + } \ + } \ + else \ + work_hi = value & 0xfffffffful; \ + } \ + do \ + { \ + *--bp = digits[work_hi & ((1 << BITS) - 1)]; \ + work_hi >>= BITS; \ + } \ + while (work_hi != 0); \ + } \ + while (0) + case 8: + RUN_2N (3); + break; + + case 16: + RUN_2N (4); + break; + + default: + { +#if BITS_PER_MP_LIMB == 64 + mp_limb_t base_multiplier = brec->base_multiplier; + if (brec->flag) + while (value != 0) + { + mp_limb_t quo, rem, x, dummy; + + umul_ppmm (x, dummy, value, base_multiplier); + quo = (x + ((value - x) >> 1)) >> (brec->post_shift - 1); + rem = value - quo * base; + *--bp = digits[rem]; + value = quo; + } + else + while (value != 0) + { + mp_limb_t quo, rem, x, dummy; + + umul_ppmm (x, dummy, value, base_multiplier); + quo = x >> brec->post_shift; + rem = value - quo * base; + *--bp = digits[rem]; + value = quo; + } +#endif +#if BITS_PER_MP_LIMB == 32 + mp_limb_t t[3]; + int n; + + /* First convert x0 to 1-3 words in base s->big.base. + Optimize for frequent cases of 32 bit numbers. */ + if ((mp_limb_t) (value >> 32) >= 1) + { +#if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION + int big_normalization_steps = brec->big.normalization_steps; + mp_limb_t big_base_norm + = brec->big.base << big_normalization_steps; +#endif + if ((mp_limb_t) (value >> 32) >= brec->big.base) + { + mp_limb_t x1hi, x1lo, r; + /* If you want to optimize this, take advantage of + that the quotient in the first udiv_qrnnd will + always be very small. It might be faster just to + subtract in a tight loop. */ + +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb_t x, xh, xl; + + if (big_normalization_steps == 0) + xh = 0; + else + xh = (mp_limb_t) (value >> (64 - big_normalization_steps)); + xl = (mp_limb_t) (value >> (32 - big_normalization_steps)); + udiv_qrnnd_preinv (x1hi, r, xh, xl, big_base_norm, + brec->big.base_ninv); + + xl = ((mp_limb_t) value) << big_normalization_steps; + udiv_qrnnd_preinv (x1lo, x, r, xl, big_base_norm, + brec->big.base_ninv); + t[2] = x >> big_normalization_steps; + + if (big_normalization_steps == 0) + xh = x1hi; + else + xh = ((x1hi << big_normalization_steps) + | (x1lo >> (32 - big_normalization_steps))); + xl = x1lo << big_normalization_steps; + udiv_qrnnd_preinv (t[0], x, xh, xl, big_base_norm, + brec->big.base_ninv); + t[1] = x >> big_normalization_steps; +#elif UDIV_NEEDS_NORMALIZATION + mp_limb_t x, xh, xl; + + if (big_normalization_steps == 0) + xh = 0; + else + xh = (mp_limb_t) (value >> 64 - big_normalization_steps); + xl = (mp_limb_t) (value >> 32 - big_normalization_steps); + udiv_qrnnd (x1hi, r, xh, xl, big_base_norm); + + xl = ((mp_limb_t) value) << big_normalization_steps; + udiv_qrnnd (x1lo, x, r, xl, big_base_norm); + t[2] = x >> big_normalization_steps; + + if (big_normalization_steps == 0) + xh = x1hi; + else + xh = ((x1hi << big_normalization_steps) + | (x1lo >> 32 - big_normalization_steps)); + xl = x1lo << big_normalization_steps; + udiv_qrnnd (t[0], x, xh, xl, big_base_norm); + t[1] = x >> big_normalization_steps; +#else + udiv_qrnnd (x1hi, r, 0, (mp_limb_t) (value >> 32), + brec->big.base); + udiv_qrnnd (x1lo, t[2], r, (mp_limb_t) value, brec->big.base); + udiv_qrnnd (t[0], t[1], x1hi, x1lo, brec->big.base); +#endif + n = 3; + } + else + { +#if (UDIV_TIME > 2 * UMUL_TIME) + mp_limb_t x; + + value <<= brec->big.normalization_steps; + udiv_qrnnd_preinv (t[0], x, (mp_limb_t) (value >> 32), + (mp_limb_t) value, big_base_norm, + brec->big.base_ninv); + t[1] = x >> brec->big.normalization_steps; +#elif UDIV_NEEDS_NORMALIZATION + mp_limb_t x; + + value <<= big_normalization_steps; + udiv_qrnnd (t[0], x, (mp_limb_t) (value >> 32), + (mp_limb_t) value, big_base_norm); + t[1] = x >> big_normalization_steps; +#else + udiv_qrnnd (t[0], t[1], (mp_limb_t) (value >> 32), + (mp_limb_t) value, brec->big.base); +#endif + n = 2; + } + } + else + { + t[0] = value; + n = 1; + } + + /* Convert the 1-3 words in t[], word by word, to ASCII. */ + do + { + mp_limb_t ti = t[--n]; + int ndig_for_this_limb = 0; + +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb_t base_multiplier = brec->base_multiplier; + if (brec->flag) + while (ti != 0) + { + mp_limb_t quo, rem, x, dummy; + + umul_ppmm (x, dummy, ti, base_multiplier); + quo = (x + ((ti - x) >> 1)) >> (brec->post_shift - 1); + rem = ti - quo * base; + *--bp = digits[rem]; + ti = quo; + ++ndig_for_this_limb; + } + else + while (ti != 0) + { + mp_limb_t quo, rem, x, dummy; + + umul_ppmm (x, dummy, ti, base_multiplier); + quo = x >> brec->post_shift; + rem = ti - quo * base; + *--bp = digits[rem]; + ti = quo; + ++ndig_for_this_limb; + } +#else + while (ti != 0) + { + mp_limb_t quo, rem; + + quo = ti / base; + rem = ti % base; + *--bp = digits[rem]; + ti = quo; + ++ndig_for_this_limb; + } +#endif + /* If this wasn't the most significant word, pad with zeros. */ + if (n != 0) + while (ndig_for_this_limb < brec->big.ndigits) + { + *--bp = '0'; + ++ndig_for_this_limb; + } + } + while (n != 0); +#endif + } + break; + } + + return bp; +} diff --git a/stdio-common/_itowa.h b/stdio-common/_itowa.h new file mode 100644 index 0000000..e219f29 --- /dev/null +++ b/stdio-common/_itowa.h @@ -0,0 +1,63 @@ +/* Internal function for converting integers to ASCII. + Copyright (C) 1994, 95, 96, 97, 98, 99 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _ITOWA_H +#define _ITOWA_H 1 +#include <features.h> +#include <wchar.h> + +/* Convert VALUE into ASCII in base BASE (2..36). + Write backwards starting the character just before BUFLIM. + Return the address of the first (left-to-right) character in the number. + Use upper case letters iff UPPER_CASE is nonzero. */ + +extern wchar_t *_itowa __P ((unsigned long long int value, wchar_t *buflim, + unsigned int base, int upper_case)); + +static inline wchar_t * +__attribute__ ((unused)) +_itowa_word (unsigned long value, wchar_t *buflim, + unsigned int base, int upper_case) +{ + extern const wchar_t _itowa_upper_digits[], _itowa_lower_digits[]; + const wchar_t *digits = (upper_case + ? _itowa_upper_digits : _itowa_lower_digits); + wchar_t *bp = buflim; + + switch (base) + { +#define SPECIAL(Base) \ + case Base: \ + do \ + *--bp = digits[value % Base]; \ + while ((value /= Base) != 0); \ + break + + SPECIAL (10); + SPECIAL (16); + SPECIAL (8); + default: + do + *--bp = digits[value % base]; + while ((value /= base) != 0); + } + return bp; +} + +#endif /* itowa.h */ diff --git a/stdio-common/itoa-digits.c b/stdio-common/itoa-digits.c index b475bbc..34699db 100644 --- a/stdio-common/itoa-digits.c +++ b/stdio-common/itoa-digits.c @@ -1,5 +1,5 @@ /* Digits. - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1996, 1999 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 @@ -18,9 +18,8 @@ Boston, MA 02111-1307, USA. */ /* Lower-case digits. */ -const char _itoa_lower_digits[] +const char _itoa_lower_digits[36] = "0123456789abcdefghijklmnopqrstuvwxyz"; /* Upper-case digits. */ -const char _itoa_upper_digits[] +const char _itoa_upper_digits[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - diff --git a/stdio-common/itowa-digits.c b/stdio-common/itowa-digits.c new file mode 100644 index 0000000..60a8578 --- /dev/null +++ b/stdio-common/itowa-digits.c @@ -0,0 +1,27 @@ +/* Digits. + Copyright (C) 1994, 1995, 1996, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <wchar.h> + +/* Lower-case digits. */ +const wchar_t _itowa_lower_digits[36] + = L"0123456789abcdefghijklmnopqrstuvwxyz"; +/* Upper-case digits. */ +const wchar_t _itowa_upper_digits[36] + = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h index a915f03..d62f3a8 100644 --- a/stdio-common/printf-parse.h +++ b/stdio-common/printf-parse.h @@ -35,7 +35,7 @@ struct printf_spec /* Pointers into the format string for the end of this format spec and the next (or to the end of the string if no more). */ - const char *end_of_fmt, *next_fmt; + const UCHAR_T *end_of_fmt, *next_fmt; /* Position of arguments for precision and width, or -1 if `info' has the constant value. */ @@ -90,21 +90,29 @@ read_int (const UCHAR_T * *pstr) /* Find the next spec in FORMAT, or the end of the string. Returns a pointer into FORMAT, to a '%' or a '\0'. */ -static inline const char * -find_spec (const char *format, mbstate_t *ps) +static inline const UCHAR_T * +#ifdef COMPILE_WPRINTF +find_spec (const UCHAR_T *format) +#else +find_spec (const UCHAR_T *format, mbstate_t *ps) +#endif { - while (*format != '\0' && *format != '%') +#ifdef COMPILE_WPRINTF + return (const UCHAR_T *) __wcschrnul ((const CHAR_T *) format, L'%'); +#else + while (*format != L_('\0') && *format != L_('%')) { int len; /* Remove any hints of a wrong encoding. */ ps->count = 0; - if (isascii (*format) || (len = mbrlen (format, MB_CUR_MAX, ps)) <= 0) - ++format; - else + if (! ISASCII (*format) && (len = MBRLEN (format, MB_CUR_MAX, ps)) > 0) format += len; + else + ++format; } return format; +#endif } @@ -119,8 +127,13 @@ extern printf_function **__printf_function_table; the number of args consumed by this spec; *MAX_REF_ARG is updated so it remains the highest argument index used. */ static inline size_t +#ifdef COMPILE_WPRINTF +parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, + size_t *max_ref_arg) +#else parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, size_t *max_ref_arg, mbstate_t *ps) +#endif { unsigned int n; size_t nargs = 0; @@ -342,12 +355,12 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, switch (spec->info.spec) { - case L'i': - case L'd': - case L'u': - case L'o': - case L'X': - case L'x': + case L_('i'): + case L_('d'): + case L_('u'): + case L_('o'): + case L_('X'): + case L_('x'): #if LONG_MAX != LONG_LONG_MAX if (spec->info.is_long_double) spec->data_arg_type = PA_INT|PA_FLAG_LONG_LONG; @@ -362,38 +375,38 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, else spec->data_arg_type = PA_INT; break; - case L'e': - case L'E': - case L'f': - case L'g': - case L'G': - case L'a': - case L'A': + case L_('e'): + case L_('E'): + case L_('f'): + case L_('g'): + case L_('G'): + case L_('a'): + case L_('A'): if (spec->info.is_long_double) spec->data_arg_type = PA_DOUBLE|PA_FLAG_LONG_DOUBLE; else spec->data_arg_type = PA_DOUBLE; break; - case L'c': + case L_('c'): spec->data_arg_type = PA_CHAR; break; - case L'C': + case L_('C'): spec->data_arg_type = PA_WCHAR; break; - case L's': + case L_('s'): spec->data_arg_type = PA_STRING; break; - case L'S': + case L_('S'): spec->data_arg_type = PA_WSTRING; break; - case L'p': + case L_('p'): spec->data_arg_type = PA_POINTER; break; - case L'n': + case L_('n'): spec->data_arg_type = PA_INT|PA_FLAG_PTR; break; - case L'm': + case L_('m'): default: /* An unknown spec will consume no args. */ spec->ndata_args = 0; @@ -416,7 +429,11 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, { /* Find the next format spec. */ spec->end_of_fmt = format; +#ifdef COMPILE_WPRINTF + spec->next_fmt = find_spec (format); +#else spec->next_fmt = find_spec (format, ps); +#endif } return nargs; diff --git a/stdio-common/printf-prs.c b/stdio-common/printf-prs.c index 4f15373..19869ca 100644 --- a/stdio-common/printf-prs.c +++ b/stdio-common/printf-prs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1995, 1996, 1999 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 @@ -29,6 +29,8 @@ # define INT_T int # define L_(Str) Str # define ISDIGIT(Ch) isdigit (Ch) +# define ISASCII(Ch) isascii (Ch) +# define MBRLEN(Cp, L, St) mbrlen (Cp, L, St) # ifdef USE_IN_LIBIO # define PUT(F, S, N) _IO_sputn (F, S, N) diff --git a/stdio-common/printf.h b/stdio-common/printf.h index 18b2f4a..66ac5d0 100644 --- a/stdio-common/printf.h +++ b/stdio-common/printf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,95,96,97,98,99 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 @@ -45,6 +45,7 @@ struct printf_info unsigned int group:1; /* ' flag. */ unsigned int extra:1; /* For special use. */ unsigned int is_char:1; /* hh flag. */ + unsigned int wide:1; /* Nonzero for wide character streams. */ wchar_t pad; /* Padding character. */ }; diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c index c75289a..1b550ab 100644 --- a/stdio-common/printf_fp.c +++ b/stdio-common/printf_fp.c @@ -52,11 +52,12 @@ the GNU I/O library. */ #ifdef USE_IN_LIBIO # define PUT(f, s, n) _IO_sputn (f, s, n) -# define PAD(f, c, n) _IO_padn (f, c, n) +# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n)) /* We use this file GNU C library and GNU I/O library. So make names equal. */ # undef putc -# define putc(c, f) _IO_putc_unlocked (c, f) +# define putc(c, f) (wide \ + ? _IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f)) # define size_t _IO_size_t # define FILE _IO_FILE #else /* ! USE_IN_LIBIO */ @@ -188,6 +189,9 @@ __printf_fp (FILE *fp, /* General helper (carry limb). */ mp_limb_t cy; + /* Nonzero if this is output on a wide character stream. */ + int wide = info->wide; + char hack_digit (void) { mp_limb_t hi; @@ -765,7 +769,10 @@ __printf_fp (FILE *fp, if ((expsign == 0 && exponent >= dig_max) || (expsign != 0 && exponent > 4)) { - type = isupper (info->spec) ? 'E' : 'e'; + if ('g' - 'G' == 'e' - 'E') + type = 'E' + (info->spec - 'G'); + else + type = isupper (info->spec) ? 'E' : 'e'; fracdig_max = dig_max - 1; intdig_max = 1; chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4; diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c index 3458106..654675a 100644 --- a/stdio-common/printf_size.c +++ b/stdio-common/printf_size.c @@ -1,5 +1,5 @@ /* Print size value using units for orders of magnitude. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. Based on a proposal by Larry McVoy <lm@sgi.com>. @@ -212,6 +212,7 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args) fp_info.group = info->group; fp_info.extra = info->extra; fp_info.pad = info->pad; + fp_info.wide = 0; if (fp_info.left && fp_info.pad == L' ') { diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 390ce91..fe145d6 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -36,74 +36,16 @@ Beside this it is also shared between the normal and wide character implementation as defined in ISO/IEC 9899:1990/Amendment 1:1995. */ -#ifndef COMPILE_WPRINTF -# define CHAR_T char -# define UCHAR_T unsigned char -# define INT_T int -# define L_(Str) Str -# define ISDIGIT(Ch) isdigit (Ch) - -# ifdef USE_IN_LIBIO -# define PUT(F, S, N) _IO_sputn ((F), (S), (N)) -# define PAD(Padchar) \ - if (width > 0) \ - done += _IO_padn (s, (Padchar), width) -# else -# define PUTC(C, F) putc (C, F) -ssize_t __printf_pad __P ((FILE *, char pad, size_t n)); -# define PAD(Padchar) \ - if (width > 0) \ - { ssize_t __res = __printf_pad (s, (Padchar), width); \ - if (__res == -1) \ - { \ - done = -1; \ - goto all_done; \ - } \ - done += __res; } -# endif -#else -# define vfprintf vfwprintf -# define CHAR_T wchar_t -# define UCHAR_T uwchar_t -# define INT_T wint_t -# define L_(Str) L##Str -# define ISDIGIT(Ch) iswdigit (Ch) - -# ifdef USE_IN_LIBIO -# define PUT(F, S, N) _IO_sputn ((F), (S), (N)) -# define PAD(Padchar) \ - if (width > 0) \ - done += _IO_wpadn (s, (Padchar), width) -# else -# define PUTC(C, F) wputc (C, F) -ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n)); -# define PAD(Padchar) \ - if (width > 0) \ - { ssize_t __res = __wprintf_pad (s, (Padchar), width); \ - if (__res == -1) \ - { \ - done = -1; \ - goto all_done; \ - } \ - done += __res; } -# endif -#endif - -/* Include the shared code for parsing the format string. */ -#include "printf-parse.h" - #ifdef USE_IN_LIBIO /* This code is for use in libio. */ # include <libioP.h> -# define PUTC(C, F) _IO_putc_unlocked (C, F) -# define vfprintf _IO_vfprintf # define FILE _IO_FILE # undef va_list # define va_list _IO_va_list -# undef BUFSIZ +# undef BUFSIZ # define BUFSIZ _IO_BUFSIZ -# define ARGCHECK(S, Format) \ +# define ARGCHECK(S, Format) \ do \ { \ /* Check file argument for consistence. */ \ @@ -120,11 +62,54 @@ ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n)); } \ } while (0) # define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED) + +# ifndef COMPILE_WPRINTF +# define vfprintf _IO_vfprintf +# define CHAR_T char +# define UCHAR_T unsigned char +# define INT_T int +# define L_(Str) Str +# define ISDIGIT(Ch) isdigit (Ch) +# define ISASCII(Ch) isascii (Ch) +# define MBRLEN(Cp, L, St) mbrlen (Cp, L, St) + +# define PUT(F, S, N) _IO_sputn ((F), (S), (N)) +# define PAD(Padchar) \ + if (width > 0) \ + done += _IO_padn (s, (Padchar), width) +# define PUTC(C, F) _IO_putc_unlocked (C, F) +# define ORIENT if (_IO_fwide (s, -1) != -1) return -1 +# else +# include "_itowa.h" + +# define vfprintf _IO_vfwprintf +# define CHAR_T wchar_t +/* This is a hack!!! There should be a type uwchar_t. */ +# define UCHAR_T unsigned int /* uwchar_t */ +# define INT_T wint_t +# define L_(Str) L##Str +# define ISDIGIT(Ch) iswdigit (Ch) +# define ISASCII(Ch) (((unsigned int) (Ch) & ~0x7f) == 0) +# define MBRLEN(Cp, L, St) wcslen ((const wchar_t *) (Cp)) + +# define PUT(F, S, N) _IO_sputn ((F), (S), (N)) +# define PAD(Padchar) \ + if (width > 0) \ + done += _IO_wpadn (s, (Padchar), width) +# define PUTC(C, F) _IO_putwc_unlocked (C, F) +# define ORIENT if (_IO_fwide (s, 1) != 1) return -1 + +# define _itoa(Val, Buf, Base, Case) _itowa (Val, (wchar_t *) Buf, Base, Case) +# define _itoa_word(Val, Buf, Base, Case) _itowa_word (Val, (wchar_t *) Buf, \ + Base, Case) +# undef EOF +# define EOF WEOF +# endif #else /* ! USE_IN_LIBIO */ /* This code is for use in the GNU C library. */ # include <stdio.h> # define PUT(F, S, N) fwrite (S, 1, N, F) -# define ARGCHECK(S, Format) \ +# define ARGCHECK(S, Format) \ do \ { \ /* Check file argument for consistence. */ \ @@ -153,11 +138,14 @@ extern void __flockfile (FILE *); extern void __funlockfile (FILE *); #endif /* USE_IN_LIBIO */ +/* Include the shared code for parsing the format string. */ +#include "printf-parse.h" + #define outchar(Ch) \ do \ { \ - register const int outc = (Ch); \ + register const INT_T outc = (Ch); \ if (PUTC (outc, s) == EOF) \ { \ done = -1; \ @@ -199,7 +187,7 @@ extern void __funlockfile (FILE *); /* Global variables. */ -static const char null[] = "(null)"; +static const CHAR_T null[] = L_("(null)"); /* Helper function to provide temporary buffering for unbuffered streams. */ @@ -211,7 +199,8 @@ static int printf_unknown __P ((FILE *, const struct printf_info *, const void *const *)); /* Group digits of number string. */ -static char *group_number __P ((CHAR_T *, CHAR_T *, const CHAR_T *, wchar_t)) +static UCHAR_T *group_number __P ((UCHAR_T *, UCHAR_T *, const char *, + wchar_t)) internal_function; @@ -238,11 +227,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) const UCHAR_T *end_of_spec; /* Buffer intermediate results. */ - char work_buffer[1000]; - char *workend; + UCHAR_T work_buffer[1000]; + UCHAR_T *workend; /* State for restartable multibyte character handling functions. */ +#ifndef COMPILE_WPRINTF mbstate_t mbstate; +#endif /* We have to save the original argument pointer. */ va_list ap_save; @@ -505,7 +496,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) now process the wanted format specifier. */ \ LABEL (form_percent): \ /* Write a literal "%". */ \ - outchar ('%'); \ + outchar (L_('%')); \ break; \ \ LABEL (form_integer): \ @@ -588,7 +579,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) else \ /* We have to take care for the '0' flag. If a precision \ is given it must be ignored. */ \ - pad = ' '; \ + pad = L_(' '); \ \ /* If the precision is 0 and the number is 0 nothing has to \ be written for the number, except for the 'o' format in \ @@ -597,13 +588,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ string = workend; \ if (base == 8 && alt) \ - *string-- = '0'; \ + *string-- = L_('0'); \ } \ else \ { \ /* Put the number in WORK. */ \ - string = _itoa (number.longlong, workend + 1, base, \ - spec == 'X'); \ + string = (UCHAR_T *) _itoa (number.longlong, workend + 1, base, \ + spec == L_('X')); \ string -= 1; \ if (group && grouping) \ string = group_number (string, workend, grouping, \ @@ -642,7 +633,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) else \ /* We have to take care for the '0' flag. If a precision \ is given it must be ignored. */ \ - pad = ' '; \ + pad = L_(' '); \ \ /* If the precision is 0 and the number is 0 nothing has to \ be written for the number, except for the 'o' format in \ @@ -651,13 +642,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ string = workend; \ if (base == 8 && alt) \ - *string-- = '0'; \ + *string-- = L_('0'); \ } \ else \ { \ /* Put the number in WORK. */ \ - string = _itoa_word (number.word, workend + 1, base, \ - spec == 'X'); \ + string = (UCHAR_T *) _itoa_word (number.word, workend + 1, \ + base, spec == L_('X')); \ string -= 1; \ if (group && grouping) \ string = group_number (string, workend, grouping, \ @@ -670,10 +661,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (prec > 0) \ /* Add zeros to the precision. */ \ while (prec-- > 0) \ - *string-- = '0'; \ + *string-- = L_('0'); \ else if (number.word != 0 && alt && base == 8) \ /* Add octal marker. */ \ - *string-- = '0'; \ + *string-- = L_('0'); \ \ if (!left) \ { \ @@ -686,41 +677,41 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (is_negative || showsign || space) \ --width; \ \ - if (pad == '0') \ + if (pad == L_('0')) \ { \ while (width-- > 0) \ - *string-- = '0'; \ + *string-- = L_('0'); \ \ if (number.word != 0 && alt && base == 16) \ { \ *string-- = spec; \ - *string-- = '0'; \ + *string-- = L_('0'); \ } \ \ if (is_negative) \ - *string-- = '-'; \ + *string-- = L_('-'); \ else if (showsign) \ - *string-- = '+'; \ + *string-- = L_('+'); \ else if (space) \ - *string-- = ' '; \ + *string-- = L_(' '); \ } \ else \ { \ if (number.word != 0 && alt && base == 16) \ { \ *string-- = spec; \ - *string-- = '0'; \ + *string-- = L_('0'); \ } \ \ if (is_negative) \ - *string-- = '-'; \ + *string-- = L_('-'); \ else if (showsign) \ - *string-- = '+'; \ + *string-- = L_('+'); \ else if (space) \ - *string-- = ' '; \ + *string-- = L_(' '); \ \ while (width-- > 0) \ - *string-- = ' '; \ + *string-- = L_(' '); \ } \ \ outstring (string + 1, workend - string); \ @@ -732,20 +723,20 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (number.word != 0 && alt && base == 16) \ { \ *string-- = spec; \ - *string-- = '0'; \ + *string-- = L_('0'); \ } \ \ if (is_negative) \ - *string-- = '-'; \ + *string-- = L_('-'); \ else if (showsign) \ - *string-- = '+'; \ + *string-- = L_('+'); \ else if (space) \ - *string-- = ' '; \ + *string-- = L_(' '); \ \ width -= workend - string; \ outstring (string + 1, workend - string); \ \ - PAD (' '); \ + PAD (L_(' ')); \ break; \ } \ \ @@ -771,7 +762,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) showsign: showsign, \ group: group, \ pad: pad, \ - extra: 0 }; \ + extra: 0, \ + wide: sizeof (CHAR_T) != 1 }; \ \ if (is_long_double) \ the_arg.pa_long_double = va_arg (ap, long double); \ @@ -821,7 +813,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) showsign: showsign, \ group: group, \ pad: pad, \ - extra: 0 }; \ + extra: 0, \ + wide: sizeof (CHAR_T) != 1 }; \ \ if (is_long_double) \ the_arg.pa_long_double = va_arg (ap, long double); \ @@ -849,6 +842,178 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) } \ break; \ \ + LABEL (form_pointer): \ + /* Generic pointer. */ \ + { \ + const void *ptr; \ + if (fspec == NULL) \ + ptr = va_arg (ap, void *); \ + else \ + ptr = args_value[fspec->data_arg].pa_pointer; \ + if (ptr != NULL) \ + { \ + /* If the pointer is not NULL, write it as a %#x spec. */ \ + base = 16; \ + number.word = (unsigned long int) ptr; \ + is_negative = 0; \ + alt = 1; \ + group = 0; \ + spec = 'x'; \ + goto LABEL (number); \ + } \ + else \ + { \ + /* Write "(nil)" for a nil pointer. */ \ + string = (UCHAR_T *) L_("(nil)"); \ + /* Make sure the full string "(nil)" is printed. */ \ + if (prec < 5) \ + prec = 5; \ + is_long = 0; /* This is no wide-char string. */ \ + goto LABEL (print_string); \ + } \ + } \ + /* NOTREACHED */ \ + \ + LABEL (form_number): \ + /* Answer the count of characters written. */ \ + if (fspec == NULL) \ + { \ + if (is_longlong) \ + *(long long int *) va_arg (ap, void *) = done; \ + else if (is_long_num) \ + *(long int *) va_arg (ap, void *) = done; \ + else if (!is_short) \ + *(int *) va_arg (ap, void *) = done; \ + else \ + *(short int *) va_arg (ap, void *) = done; \ + } \ + else \ + if (is_longlong) \ + *(long long int *) args_value[fspec->data_arg].pa_pointer = done; \ + else if (is_long_num) \ + *(long int *) args_value[fspec->data_arg].pa_pointer = done; \ + else if (!is_short) \ + *(int *) args_value[fspec->data_arg].pa_pointer = done; \ + else \ + *(short int *) args_value[fspec->data_arg].pa_pointer = done; \ + break; \ + \ + LABEL (form_strerror): \ + /* Print description of error ERRNO. */ \ + string = \ + (UCHAR_T *) __strerror_r (save_errno, (char *) work_buffer, \ + sizeof work_buffer); \ + is_long = 0; /* This is no wide-char string. */ \ + goto LABEL (print_string) + +#ifdef COMPILE_WPRINTF +# define process_string_arg(fspec) \ + LABEL (form_character): \ + /* Character. */ \ + if (is_long) \ + goto LABEL (form_wcharacter); \ + --width; /* Account for the character itself. */ \ + if (!left) \ + PAD (L' '); \ + if (fspec == NULL) \ + outchar (btowc ((unsigned char) va_arg (ap, int))); /* Promoted. */ \ + else \ + outchar (btowc ((unsigned char) args_value[fspec->data_arg].pa_char));\ + if (left) \ + PAD (L' '); \ + break; \ + \ + LABEL (form_wcharacter): \ + { \ + /* Wide character. */ \ + --width; \ + if (!left) \ + PAD (L' '); \ + if (fspec == NULL) \ + outchar (va_arg (ap, wint_t)); \ + else \ + outchar (args_value[fspec->data_arg].pa_wchar); \ + if (left) \ + PAD (L' '); \ + } \ + break; \ + \ + LABEL (form_string): \ + { \ + size_t len; \ + \ + /* The string argument could in fact be `char *' or `wchar_t *'. \ + But this should not make a difference here. */ \ + if (fspec == NULL) \ + string = (UCHAR_T *) va_arg (ap, const wchar_t *); \ + else \ + string = (UCHAR_T *) args_value[fspec->data_arg].pa_wstring; \ + \ + /* Entry point for printing other strings. */ \ + LABEL (print_string): \ + \ + if (string == NULL) \ + { \ + /* Write "(null)" if there's space. */ \ + if (prec == -1 \ + || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) \ + { \ + string = (UCHAR_T *) null; \ + len = (sizeof (null) / sizeof (null[0])) - 1; \ + } \ + else \ + { \ + string = (UCHAR_T *) L""; \ + len = 0; \ + } \ + } \ + else if (!is_long && spec != L_('S')) \ + { \ + /* This is complicated. We have to transform the multibyte \ + string into a wide character string. */ \ + const char *mbs = (const char *) string; \ + mbstate_t mbstate; \ + \ + len = prec == -1 ? strnlen (mbs, prec) : strlen (mbs); \ + \ + /* Allocate dynamically an array which definitely is long \ + enough for the wide character version. */ \ + string = (UCHAR_T *) alloca ((len + 1) * sizeof (wchar_t)); \ + \ + memset (&mbstate, '\0', sizeof (mbstate_t)); \ + len = __mbsrtowcs ((wchar_t *) string, &mbs, len + 1, &mbstate); \ + if (len == (size_t) -1) \ + { \ + /* Illegal multibyte character. */ \ + done = -1; \ + goto all_done; \ + } \ + } \ + else \ + { \ + if (prec != -1) \ + /* Search for the end of the string, but don't search past \ + the length specified by the precision. */ \ + len = __wcsnlen ((wchar_t *) string, prec); \ + else \ + len = __wcslen ((wchar_t *) string); \ + } \ + \ + if ((width -= len) < 0) \ + { \ + outstring (string, len); \ + break; \ + } \ + \ + if (!left) \ + PAD (L' '); \ + outstring (string, len); \ + if (left) \ + PAD (L' '); \ + } \ + break; +#else +# define process_string_arg(fspec) \ LABEL (form_character): \ /* Character. */ \ if (is_long) \ @@ -917,7 +1082,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (prec != -1) \ /* Search for the end of the string, but don't search past \ the length specified by the precision. */ \ - len = strnlen (string, prec); \ + len = __strnlen (string, prec); \ else \ len = strlen (string); \ } \ @@ -939,7 +1104,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) s2 = (const wchar_t *) string; \ string = alloca (len + 1); \ (void) __wcsrtombs (string, &s2, len + 1, &mbstate); \ - if (prec < len) \ + if (prec > 0 && prec < len) \ len = prec; \ } \ \ @@ -955,75 +1120,23 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (left) \ PAD (' '); \ } \ - break; \ - \ - LABEL (form_pointer): \ - /* Generic pointer. */ \ - { \ - const void *ptr; \ - if (fspec == NULL) \ - ptr = va_arg (ap, void *); \ - else \ - ptr = args_value[fspec->data_arg].pa_pointer; \ - if (ptr != NULL) \ - { \ - /* If the pointer is not NULL, write it as a %#x spec. */ \ - base = 16; \ - number.word = (unsigned long int) ptr; \ - is_negative = 0; \ - alt = 1; \ - group = 0; \ - spec = 'x'; \ - goto LABEL (number); \ - } \ - else \ - { \ - /* Write "(nil)" for a nil pointer. */ \ - string = (char *) "(nil)"; \ - /* Make sure the full string "(nil)" is printed. */ \ - if (prec < 5) \ - prec = 5; \ - is_long = 0; /* This is no wide-char string. */ \ - goto LABEL (print_string); \ - } \ - } \ - /* NOTREACHED */ \ - \ - LABEL (form_number): \ - /* Answer the count of characters written. */ \ - if (fspec == NULL) \ - { \ - if (is_longlong) \ - *(long long int *) va_arg (ap, void *) = done; \ - else if (is_long_num) \ - *(long int *) va_arg (ap, void *) = done; \ - else if (!is_short) \ - *(int *) va_arg (ap, void *) = done; \ - else \ - *(short int *) va_arg (ap, void *) = done; \ - } \ - else \ - if (is_longlong) \ - *(long long int *) args_value[fspec->data_arg].pa_pointer = done; \ - else if (is_long_num) \ - *(long int *) args_value[fspec->data_arg].pa_pointer = done; \ - else if (!is_short) \ - *(int *) args_value[fspec->data_arg].pa_pointer = done; \ - else \ - *(short int *) args_value[fspec->data_arg].pa_pointer = done; \ - break; \ - \ - LABEL (form_strerror): \ - /* Print description of error ERRNO. */ \ - string = \ - (char *) __strerror_r (save_errno, work_buffer, sizeof work_buffer); \ - is_long = 0; /* This is no wide-char string. */ \ - goto LABEL (print_string) + break; +#endif + /* Orient the stream. */ +#ifdef ORIENT + ORIENT; +#endif /* Sanity check of arguments. */ ARGCHECK (s, format); + /* Check for correct orientation. */ + if (_IO_fwide (s, sizeof (CHAR_T) == 1 ? -1 : 1) + != (sizeof (CHAR_T) == 1 ? -1 : 1)) + /* The stream is already oriented otherwise. */ + return EOF; + if (UNBUFFERED_P (s)) /* Use a helper function which will allocate a local temporary buffer for the stream and then call us again. */ @@ -1041,11 +1154,16 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) #endif nspecs_done = 0; +#ifdef COMPILE_WPRINTF + /* Find the first format specifier. */ + f = lead_str_end = find_spec ((const UCHAR_T *) format); +#else /* Put state for processing format string in initial state. */ memset (&mbstate, '\0', sizeof (mbstate_t)); /* Find the first format specifier. */ f = lead_str_end = find_spec (format, &mbstate); +#endif /* Lock stream. */ #ifdef USE_IN_LIBIO @@ -1081,7 +1199,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) } number; int base; union printf_arg the_arg; - char *string; /* Pointer to argument string. */ + UCHAR_T *string; /* Pointer to argument string. */ int alt = 0; /* Alternate format. */ int space = 0; /* Use space prefix if no sign is needed. */ int left = 0; /* Left-justify output. */ @@ -1093,10 +1211,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) int is_char = 0; /* Argument is promoted (unsigned) char. */ int width = 0; /* Width of output; 0 means none specified. */ int prec = -1; /* Precision of output; -1 means none specified. */ - char pad = ' '; /* Padding character. */ + UCHAR_T pad = L_(' ');/* Padding character. */ CHAR_T spec; - workend = &work_buffer[sizeof (work_buffer) - 1]; + workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T) - 1]; /* Get current character in format string. */ JUMP (*++f, step0_jumps); @@ -1172,10 +1290,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) left = 1; } - if (width + 32 >= sizeof (work_buffer)) + if (width + 32 >= sizeof (work_buffer) / sizeof (work_buffer[0])) /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - workend = alloca (width + 32) + (width + 31); + workend = ((UCHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + + (width + 31)); } JUMP (*f, step1_jumps); @@ -1183,10 +1302,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) LABEL (width): width = read_int (&f); - if (width + 32 >= sizeof (work_buffer)) + if (width + 32 >= sizeof (work_buffer) / sizeof (work_buffer[0])) /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - workend = alloca (width + 32) + (width + 31); + workend = ((UCHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + + (width + 31)); if (*f == L_('$')) /* Oh, oh. The argument comes from a positional parameter. */ goto do_positional; @@ -1213,7 +1333,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) prec = read_int (&f); else prec = 0; - if (prec > width && prec + 32 > sizeof (work_buffer)) + if (prec > width + && prec + 32 > sizeof (work_buffer) / sizeof (work_buffer[0])) workend = alloca (spec + 32) + (spec + 31); JUMP (*f, step2_jumps); @@ -1258,6 +1379,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) while (1) { process_arg (((struct printf_spec *) NULL)); + process_string_arg (((struct printf_spec *) NULL)); LABEL (form_unknown): if (spec == L_('\0')) @@ -1276,7 +1398,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) ++nspecs_done; /* Look for next format specifier. */ +#ifdef COMPILE_WPRINTF + f = find_spec ((end_of_spec = ++f)); +#else f = find_spec ((end_of_spec = ++f), &mbstate); +#endif /* Write the following constant string. */ outstring (end_of_spec, f - end_of_spec); @@ -1301,7 +1427,7 @@ do_positional: attributes. */ size_t nargs = 0; int *args_type; - union printf_arg *args_value; + union printf_arg *args_value = NULL; /* Positional parameters refer to arguments directly. This could also determine the maximum number of arguments. Track the @@ -1329,7 +1455,7 @@ do_positional: grouping = NULL; } - for (f = lead_str_end; *f != '\0'; f = specs[nspecs++].next_fmt) + for (f = lead_str_end; *f != L_('\0'); f = specs[nspecs++].next_fmt) { if (nspecs >= nspecs_max) { @@ -1356,8 +1482,12 @@ do_positional: } /* Parse the format specifier. */ +#ifdef COMPILE_WPRINTF + nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg); +#else nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg, &mbstate); +#endif } /* Determine the number of arguments the format string consumes. */ @@ -1449,7 +1579,7 @@ do_positional: } number; int base; union printf_arg the_arg; - char *string; /* Pointer to argument string. */ + UCHAR_T *string; /* Pointer to argument string. */ /* Fill variables from values in struct. */ int alt = specs[nspecs_done].info.alt; @@ -1498,8 +1628,10 @@ do_positional: } /* Maybe the buffer is too small. */ - if (MAX (prec, width) + 32 > sizeof (work_buffer)) - workend = alloca (MAX (prec, width) + 32) + (MAX (prec, width) + 31); + if (MAX (prec, width) + 32 > sizeof (work_buffer) / sizeof (UCHAR_T)) + workend = ((UCHAR_T *) alloca ((MAX (prec, width) + 32) + * sizeof (UCHAR_T)) + + (MAX (prec, width) + 31)); /* Process format specifiers. */ while (1) @@ -1507,6 +1639,7 @@ do_positional: JUMP (spec, step4_jumps); process_arg ((&specs[nspecs_done])); + process_string_arg ((&specs[nspecs_done])); LABEL (form_unknown): { @@ -1564,21 +1697,6 @@ all_done: return done; } - -#ifdef USE_IN_LIBIO -# undef vfprintf -# ifdef strong_alias -/* This is for glibc. */ -strong_alias (_IO_vfprintf, vfprintf); -# else -# if defined __ELF__ || defined __GNU_LIBRARY__ -# include <gnu-stabs.h> -# ifdef weak_alias -weak_alias (_IO_vfprintf, vfprintf); -# endif -# endif -# endif -#endif /* Handle an unknown format specifier. This prints out a canonicalized representation of the format spec itself. */ @@ -1588,24 +1706,25 @@ printf_unknown (FILE *s, const struct printf_info *info, { int done = 0; - char work_buffer[MAX (info->width, info->spec) + 32]; - char *const workend = &work_buffer[sizeof (work_buffer) - 1]; - register char *w; + CHAR_T work_buffer[MAX (info->width, info->spec) + 32]; + CHAR_T *const workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T) + - 1]; + register CHAR_T *w; - outchar ('%'); + outchar (L_('%')); if (info->alt) - outchar ('#'); + outchar (L_('#')); if (info->group) - outchar ('\''); + outchar (L_('\'')); if (info->showsign) - outchar ('+'); + outchar (L_('+')); else if (info->space) - outchar (' '); + outchar (L_(' ')); if (info->left) - outchar ('-'); + outchar (L_('-')); if (info->pad == '0') - outchar ('0'); + outchar (L_('0')); if (info->width != 0) { @@ -1622,7 +1741,7 @@ printf_unknown (FILE *s, const struct printf_info *info, outchar (*w++); } - if (info->spec != '\0') + if (info->spec != L_('\0')) outchar (info->spec); all_done: @@ -1631,13 +1750,13 @@ printf_unknown (FILE *s, const struct printf_info *info, /* Group the digits according to the grouping rules of the current locale. The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */ -static char * +static UCHAR_T * internal_function -group_number (CHAR_T *w, CHAR_T *rear_ptr, const CHAR_T *grouping, +group_number (UCHAR_T *w, UCHAR_T *rear_ptr, const char *grouping, wchar_t thousands_sep) { int len; - char *src, *s; + UCHAR_T *src, *s; /* We treat all negative values like CHAR_MAX. */ @@ -1648,8 +1767,9 @@ group_number (CHAR_T *w, CHAR_T *rear_ptr, const CHAR_T *grouping, len = *grouping; /* Copy existing string so that nothing gets overwritten. */ - src = (char *) alloca (rear_ptr - w); - s = (char *) __mempcpy (src, w + 1, rear_ptr - w) - 1; + src = (UCHAR_T *) alloca ((rear_ptr - w) * sizeof (UCHAR_T)); + s = (UCHAR_T *) __mempcpy (src, w + 1, + (rear_ptr - w) * sizeof (UCHAR_T)) - 1; w = rear_ptr; /* Process all characters in the string. */ @@ -1699,12 +1819,22 @@ static int _IO_helper_overflow (_IO_FILE *s, int c) { _IO_FILE *target = ((struct helper_file*) s)->_put_stream; +#ifdef COMPILE_WPRINTF + int used = s->_wide_data->_IO_write_ptr - s->_wide_data->_IO_write_base; + if (used) + { + _IO_size_t written = _IO_sputn (target, s->_wide_data->_IO_write_base, + used); + s->_wide_data->_IO_write_ptr -= written; + } +#else int used = s->_IO_write_ptr - s->_IO_write_base; if (used) { _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used); s->_IO_write_ptr -= written; } +#endif return PUTC (c, s); } @@ -1735,16 +1865,18 @@ internal_function buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format, _IO_va_list args) { - char buf[_IO_BUFSIZ]; + CHAR_T buf[_IO_BUFSIZ]; struct helper_file helper; register _IO_FILE *hp = (_IO_FILE *) &helper; int result, to_flush; /* Initialize helper. */ helper._put_stream = s; - hp->_IO_write_base = buf; - hp->_IO_write_ptr = buf; - hp->_IO_write_end = buf + sizeof buf; +#ifdef COMPILE_WPRINTF + _IO_wsetp (hp, buf, buf + sizeof buf / sizeof (CHAR_T)); +#else + _IO_setp (hp, buf, buf + sizeof buf); +#endif hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS; #if _IO_JUMPS_OFFSET hp->_vtable_offset = 0; @@ -1756,14 +1888,24 @@ buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format, _IO_JUMPS (hp) = (struct _IO_jump_t *) &_IO_helper_jumps; /* Now print to helper instead. */ - result = _IO_vfprintf (hp, format, args); + result = vfprintf (hp, format, args); /* Now flush anything from the helper to the S. */ +#ifdef COMPILE_WPRINTF + if ((to_flush = (hp->_wide_data->_IO_write_ptr + - hp->_wide_data->_IO_write_base)) > 0) + { + if ((int) _IO_sputn (s, hp->_wide_data->_IO_write_base, to_flush) + != to_flush) + return -1; + } +#else if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0) { if ((int) _IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush) return -1; } +#endif return result; } @@ -1826,3 +1968,26 @@ __wprintf_pad (FILE *s, wchar_t pad, size_t count) } #undef PADSIZE #endif /* USE_IN_LIBIO */ + +#ifdef USE_IN_LIBIO +# undef vfprintf +# ifdef strong_alias +/* This is for glibc. */ +# ifdef COMPILE_WPRINTF +strong_alias (_IO_vfwprintf, vfwprintf); +# else +strong_alias (_IO_vfprintf, vfprintf); +# endif +# else +# if defined __ELF__ || defined __GNU_LIBRARY__ +# include <gnu-stabs.h> +# ifdef weak_alias +# ifdef COMPILE_WPRINTF +weak_alias (_IO_vfwprintf, vfwprintf); +# else +weak_alias (_IO_vfprintf, vfprintf); +# endif +# endif +# endif +# endif +#endif diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index 0339edb..5caf616 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -16,6 +16,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <assert.h> #include <errno.h> #include <limits.h> #include <ctype.h> @@ -69,13 +70,56 @@ # undef va_list # define va_list _IO_va_list -# define ungetc(c, s) ((void) ((int) c == EOF \ + +# ifdef COMPILE_WPRINTF +# define ungetc(c, s) ((void) ((int) c == WEOF \ + || (--read_in, \ + _IO_sputbackwc (s, (unsigned char) c)))) +# define inchar() (c == EOF ? EOF \ + : ((c = _IO_getwc_unlocked (s)), \ + (void) (c != EOF && ++read_in), 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 UNGETC(Ch, S) ungetwc (Ch, S) +# define TOLOWER(Ch) towlower (Ch) +# define ORIENT if (_IO_fwide (s, 1) != 1) return EOF +# 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 +# else +# define ungetc(c, s) ((void) ((int) c == EOF \ || (--read_in, \ _IO_sputbackc (s, (unsigned char) c)))) -# define inchar() (c == EOF ? EOF \ +# define inchar() (c == EOF ? EOF \ : ((c = _IO_getc_unlocked (s)), \ (void) (c != EOF && ++read_in), c)) -# define encode_error() do { \ +# 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 UNGETC(Ch, S) ungetc (Ch, S) +# define TOLOWER(Ch) tolower (Ch) +# define ORIENT if (_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 encode_error() do { \ if (errp != NULL) *errp |= 4; \ _IO_funlockfile (s); \ __libc_cleanup_end (0); \ @@ -94,7 +138,7 @@ __libc_cleanup_end (0); \ return done ?: EOF; \ } while (0) -# define memory_error() do { \ +# define memory_error() do { \ _IO_funlockfile (s); \ __set_errno (ENOMEM); \ __libc_cleanup_end (0); \ @@ -180,30 +224,39 @@ 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_WPRINTF +int +_IO_vfwscanf (s, format, argptr, errp) + _IO_FILE *s; + const wchar_t *format; + _IO_va_list argptr; + int *errp; +# 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; - register const char *f = format; - register unsigned char fc; /* Current character of the format. */ + register const CHAR_T *f = format; + register UCHAR_T fc; /* Current character of the format. */ register size_t done = 0; /* Assignments done. */ register size_t read_in = 0; /* Chars read in. */ - register int c = 0; /* Last char read. */ + register WINT_T c = 0; /* Last char read. */ register int width; /* Maximum field width. */ register int flags; /* Modifiers for current format element. */ /* Status for reading F-P nums. */ char got_dot, got_e, negative; /* If a [...] is a [^...]. */ - char not_in; + CHAR_T not_in; #define exp_char not_in /* Base for integral numbers. */ int base; @@ -236,8 +289,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Nonzero if we are reading a pointer. */ int read_pointer; /* Workspace. */ - char *tw; /* Temporary pointer. */ - char *wp = NULL; /* Workspace. */ + CHAR_T *tw; /* Temporary pointer. */ + CHAR_T *wp = NULL; /* Workspace. */ size_t wpmax = 0; /* Maximal size of workspace. */ size_t wpsize; /* Currently used bytes in workspace. */ #define ADDW(Ch) \ @@ -245,11 +298,11 @@ __vfscanf (FILE *s, const char *format, va_list argptr) { \ if (wpsize == wpmax) \ { \ - char *old = wp; \ + CHAR_T *old = wp; \ wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax; \ - wp = (char *) alloca (wpmax); \ + wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \ if (old != NULL) \ - memcpy (wp, old, wpsize); \ + MEMCPY (wp, old, wpsize); \ } \ wp[wpsize++] = (Ch); \ } \ @@ -261,6 +314,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr) arg = (va_list) argptr; #endif +#ifdef ORIENT + ORIENT; +#endif + ARGCHECK (s, format); /* Figure out the decimal point character. */ @@ -280,8 +337,10 @@ __vfscanf (FILE *s, const char *format, va_list argptr) LOCK_STREAM (s); +#ifndef COMPILE_WPRINTF /* From now on we use `state' to convert the format string. */ memset (&state, '\0', sizeof (state)); +#endif /* Run through the format string. */ while (*f != '\0') @@ -320,6 +379,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) # endif #endif +#ifndef COMPILE_WPRINTF if (!isascii (*f)) { /* Non-ASCII, may be a multibyte. */ @@ -341,12 +401,13 @@ __vfscanf (FILE *s, const char *format, va_list argptr) continue; } } +#endif fc = *f++; if (fc != '%') { /* Remember to skip spaces. */ - if (isspace (fc)) + if (ISSPACE (fc)) { skip_space = 1; continue; @@ -363,7 +424,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) string. Now it's time to skip all leading white space. */ if (skip_space) { - while (isspace (c)) + while (ISSPACE (c)) if (inchar () == EOF && errno == EINTR) conv_error (); skip_space = 0; @@ -371,7 +432,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) if (c != fc) { - ungetc (c, s); + UNGETC (c, s); conv_error (); } @@ -391,12 +452,12 @@ __vfscanf (FILE *s, const char *format, va_list argptr) wpsize = 0; /* Check for a positional parameter specification. */ - if (isdigit (*f)) + if (ISDIGIT (*f)) { - argpos = *f++ - '0'; - while (isdigit (*f)) - argpos = argpos * 10 + (*f++ - '0'); - if (*f == '$') + argpos = *f++ - L_('0'); + while (ISDIGIT (*f)) + argpos = argpos * 10 + (*f++ - L_('0')); + if (*f == L_('$')) ++f; else { @@ -409,27 +470,27 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } /* Check for the assignment-suppressing and the number grouping flag. */ - while (*f == '*' || *f == '\'') + while (*f == L_('*') || *f == L_('\'')) switch (*f++) { - case '*': + case L_('*'): flags |= SUPPRESS; break; - case '\'': + case L_('\''): flags |= GROUP; break; } /* We have seen width. */ - if (isdigit (*f)) + if (ISDIGIT (*f)) flags |= WIDTH; /* Find the maximum field width. */ width = 0; - while (isdigit (*f)) + while (ISDIGIT (*f)) { width *= 10; - width += *f++ - '0'; + width += *f++ - L_('0'); } got_width: if (width == 0) @@ -438,9 +499,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Check for type modifiers. */ switch (*f++) { - case 'h': + case L_('h'): /* ints are short ints or chars. */ - if (*f == 'h') + if (*f == L_('h')) { ++f; flags |= CHAR; @@ -448,8 +509,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) else flags |= SHORT; break; - case 'l': - if (*f == 'l') + case L_('l'): + if (*f == L_('l')) { /* A double `l' is equivalent to an `L'. */ ++f; @@ -459,15 +520,15 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* ints are long ints. */ flags |= LONG; break; - case 'q': - case 'L': + case L_('q'): + case L_('L'): /* doubles are long doubles, and ints are long long ints. */ flags |= LONGDBL | LONG; break; - case 'a': + case L_('a'): /* The `a' is used as a flag only if followed by `s', `S' or `['. */ - if (*f != 's' && *f != 'S' && *f != '[') + if (*f != L_('s') && *f != L_('S') && *f != L_('[')) { --f; break; @@ -476,19 +537,19 @@ __vfscanf (FILE *s, const char *format, va_list argptr) arg and fill it in with a malloc'd pointer. */ flags |= MALLOC; break; - case 'z': + case L_('z'): if (need_longlong && sizeof (size_t) > sizeof (unsigned long int)) flags |= LONGDBL; else if (sizeof (size_t) > sizeof (unsigned int)) flags |= LONG; break; - case 'j': + case L_('j'): if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int)) flags |= LONGDBL; else if (sizeof (uintmax_t) > sizeof (unsigned int)) flags |= LONG; break; - case 't': + case L_('t'): if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int)) flags |= LONGDBL; else if (sizeof (ptrdiff_t) > sizeof (int)) @@ -501,12 +562,13 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } /* End of the format string? */ - if (*f == '\0') + if (*f == L_('\0')) conv_error (); /* Find the conversion specifier. */ fc = *f++; - if (skip_space || (fc != '[' && fc != 'c' && fc != 'C' && fc != 'n')) + if (skip_space || (fc != L_('[') && fc != L_('c') + && fc != L_('C') && fc != L_('n'))) { /* Eat whitespace. */ int save_errno = errno; @@ -514,15 +576,15 @@ __vfscanf (FILE *s, const char *format, va_list argptr) do if (inchar () == EOF && errno == EINTR) input_error (); - while (isspace (c)); + while (ISSPACE (c)); errno = save_errno; - ungetc (c, s); + UNGETC (c, s); skip_space = 0; } switch (fc) { - case '%': /* Must match a literal '%'. */ + case L_('%'): /* Must match a literal '%'. */ c = inchar (); if (c == EOF) input_error (); @@ -533,7 +595,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } break; - case 'n': /* Answer number of assignments done. */ + case L_('n'): /* Answer number of assignments done. */ /* Corrigendum 1 to ISO C 1990 describes the allowed flags with the 'n' conversion specifier. */ if (!(flags & SUPPRESS)) @@ -581,7 +643,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } break; - case 'c': /* Match characters. */ + case L_('c'): /* Match characters. */ if ((flags & LONG) == 0) { if (!(flags & SUPPRESS)) @@ -598,6 +660,26 @@ __vfscanf (FILE *s, const char *format, va_list argptr) if (width == -1) width = 1; +#ifdef COMPILE_WPRINTF + /* We have to convert the wide character(s) into multibyte + characters and store the result. */ + memset (&state, '\0', sizeof (state)); + + do + { + size_t n; + + n = wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); + if (n == (size_t) -1) + /* No valid wide character. */ + input_error (); + + /* Increment the output pointer. Even if we don't + write anything. */ + str += n; + } + while (--width > 0 && inchar () != EOF); +#else if (!(flags & SUPPRESS)) { do @@ -606,6 +688,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } else while (--width > 0 && inchar () != EOF); +#endif if (!(flags & SUPPRESS)) ++done; @@ -613,238 +696,448 @@ __vfscanf (FILE *s, const char *format, va_list argptr) break; } /* FALLTHROUGH */ - case 'C': - /* Get UTF-8 encoded wide character. Here we assume (as in - other parts of the libc) that we only have to handle - UTF-8. */ + case L_('C'): + if (!(flags & SUPPRESS)) + { + wstr = ARG (wchar_t *); + if (str == NULL) + conv_error (); + } + + c = inchar (); + if (c == EOF) + input_error (); + +#ifdef COMPILE_WPRINTF + /* Just store the incoming wide characters. */ + if (!(flags & SUPPRESS)) + { + do + *wstr++ = c; + while (--width > 0 && inchar () != EOF); + } + else + while (--width > 0 && inchar () != EOF); +#else { - wint_t val; - size_t cnt = 0; - int first = 1; + /* We have to convert the multibyte input sequence to wide + characters. */ + char buf[MB_LEN_MAX]; + mbstate_t cstate; - if (!(flags & SUPPRESS)) - { - wstr = ARG (wchar_t *); - if (str == NULL) - conv_error (); - } + memset (&cstate, '\0', sizeof (cstate)); do { -#define NEXT_WIDE_CHAR(First) \ - c = inchar (); \ - if (c == EOF) \ - { \ - /* EOF is only an error for the first character. */ \ - if (First) \ - input_error (); \ - else \ - break; \ - } \ - val = c; \ - if (val >= 0x80) \ - { \ - if ((c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \ - encode_error (); \ - if ((c & 0xe0) == 0xc0) \ - { \ - /* We expect two bytes. */ \ - cnt = 1; \ - val &= 0x1f; \ - } \ - else if ((c & 0xf0) == 0xe0) \ - { \ - /* We expect three bytes. */ \ - cnt = 2; \ - val &= 0x0f; \ - } \ - else if ((c & 0xf8) == 0xf0) \ - { \ - /* We expect four bytes. */ \ - cnt = 3; \ - val &= 0x07; \ - } \ - else if ((c & 0xfc) == 0xf8) \ - { \ - /* We expect five bytes. */ \ - cnt = 4; \ - val &= 0x03; \ - } \ - else \ - { \ - /* We expect six bytes. */ \ - cnt = 5; \ - val &= 0x01; \ - } \ - \ - do \ - { \ - c = inchar (); \ - if (c == EOF \ - || (c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \ - encode_error (); \ - val <<= 6; \ - val |= c & 0x3f; \ - } \ - while (--cnt > 0); \ - } \ - \ - if (!(flags & SUPPRESS)) \ - *wstr++ = val; \ - First = 0 - - NEXT_WIDE_CHAR (first); - } - while (--width > 0); + size_t cnt; - if (!(flags & SUPPRESS)) - ++done; + /* This is what we present the mbrtowc function first. */ + buf[0] = c; + cnt = 1; + + while (1) + { + size_t n; + + n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL, + buf, cnt, &cstate); + + if (n == (size_t) -2) + { + /* Possibly correct character, just not enough + input. */ + assert (cnt < MB_CUR_MAX); + + if (inchar () == EOF) + encode_error (); + + buf[cnt++] = c; + continue; + } + + if (n != cnt) + encode_error (); + + /* We have a match. */ + break; + } + + /* Advance the result pointer. */ + ++wstr; + } + while (--width > 0 && inchar () != EOF); } - break; +#endif - case 's': /* Read a string. */ - if (flags & LONG) - /* We have to process a wide character string. */ - goto wide_char_string; + if (!(flags & SUPPRESS)) + ++done; + break; + + case L_('s'): /* Read a string. */ + if (!(flags & LONG)) + { #define STRING_ARG(Str, Type) \ - if (!(flags & SUPPRESS)) \ - { \ - if (flags & MALLOC) \ + do if (!(flags & SUPPRESS)) \ { \ - /* The string is to be stored in a malloc'd buffer. */ \ - strptr = ARG (char **); \ - if (strptr == NULL) \ + if (flags & MALLOC) \ + { \ + /* The string is to be stored in a malloc'd buffer. */ \ + strptr = ARG (char **); \ + if (strptr == NULL) \ + conv_error (); \ + /* Allocate an initial buffer. */ \ + strsize = 100; \ + *strptr = (char *) malloc (strsize * sizeof (Type)); \ + Str = (Type *) *strptr; \ + } \ + else \ + Str = ARG (Type *); \ + if (Str == NULL) \ conv_error (); \ - /* Allocate an initial buffer. */ \ - strsize = 100; \ - *strptr = malloc (strsize * sizeof (Type)); \ - Str = (Type *) *strptr; \ - } \ - else \ - Str = ARG (Type *); \ - if (Str == NULL) \ - conv_error (); \ - } - STRING_ARG (str, char); + } while (0) + STRING_ARG (str, char); - c = inchar (); - if (c == EOF) - input_error (); + c = inchar (); + if (c == EOF) + input_error (); - do - { - if (isspace (c)) +#ifdef COMPILE_WPRINTF + memset (&state, '\0', sizeof (state)); +#endif + + do { - ungetc (c, s); - break; - } -#define STRING_ADD_CHAR(Str, c, Type) \ - if (!(flags & SUPPRESS)) \ - { \ - *Str++ = c; \ - if ((flags & MALLOC) && (char *) Str == *strptr + strsize) \ - { \ - /* Enlarge the buffer. */ \ - Str = realloc (*strptr, strsize * 2 * sizeof (Type)); \ - if (Str == NULL) \ - { \ - /* Can't allocate that much. Last-ditch effort. */\ - Str = realloc (*strptr, \ - (strsize + 1) * sizeof (Type)); \ - if (Str == NULL) \ - { \ - /* We lose. Oh well. \ - Terminate the string and stop converting, \ - so at least we don't skip any input. */ \ - ((Type *) (*strptr))[strsize] = '\0'; \ - ++done; \ - conv_error (); \ - } \ - else \ - { \ - *strptr = (char *) Str; \ - Str = ((Type *) *strptr) + strsize; \ - ++strsize; \ - } \ - } \ - else \ - { \ - *strptr = (char *) Str; \ - Str = ((Type *) *strptr) + strsize; \ - strsize *= 2; \ - } \ - } \ + if (ISSPACE (c)) + { + UNGETC (c, s); + break; + } + +#ifdef COMPILE_WPRINTF + /* This is quite complicated. We have to convert the + wide characters into multibyte characters and then + store them. */ + { + size_t n; + + if (!(flags & SUPPRESS) && (flags & MALLOC) + && str + MB_CUR_MAX >= *strptr + strsize) + { + /* We have to enlarge the buffer if the `a' flag + was given. */ + str = (char *) realloc (*strptr, strsize * 2); + if (str == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + str = (char *) realloc (*strptr, strsize + 1); + if (str == NULL) + { + /* 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; + } + } + else + { + *strptr = (char *) str; + str += strsize; + strsize *= 2; + } + } + + n = wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); + if (n == (size_t) -1) + encode_error (); + + assert (n <= MB_CUR_MAX); + str += n; + } +#else + /* This is easy. */ + if (!(flags & SUPPRESS)) + { + *str++ = c; + if ((flags & MALLOC) + && (char *) str == *strptr + strsize) + { + /* Enlarge the buffer. */ + str = (char *) realloc (*strptr, 2 * strsize); + if (str == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + str = (char *) realloc (*strptr, strsize + 1); + if (str == NULL) + { + /* 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; + } + } + else + { + *strptr = (char *) str; + str += strsize; + strsize *= 2; + } + } + } +#endif } - STRING_ADD_CHAR (str, c, char); - } while ((width <= 0 || --width > 0) && inchar () != EOF); + while ((width <= 0 || --width > 0) && inchar () != EOF); - if (!(flags & SUPPRESS)) - { - *str = '\0'; - ++done; + if (!(flags & SUPPRESS)) + { +#ifdef COMPILE_WPRINTF + /* We have to emit the code to get into the intial + state. */ + char buf[MB_LEN_MAX]; + size_t n = wcrtomb (buf, L'\0', &state); + if (n > 0 && (flags & MALLOC) + && str + n >= *strptr + strsize) + { + /* Enlarge the buffer. */ + str = (char *) realloc (*strptr, + (str + n + 1) - *strptr); + if (str == NULL) + { + /* 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 = ((char *) *strptr) + strsize; + strsize = (str + n + 1) - *strptr; + } + } + + str = __mempcpy (str, buf, n); +#endif + *str = '\0'; + + if ((flags & MALLOC) && str - *strptr != strsize) + { + char *cp = (char *) realloc (*strptr, str - *strptr); + if (cp != NULL) + *strptr = cp; + } + + ++done; + } + break; } - break; + /* FALLTHROUGH */ - case 'S': - /* Wide character string. */ - wide_char_string: + case L_('S'): { - wint_t val; - int first = 1; +#ifndef COMPILE_WPRINTF + mbstate_t cstate; +#endif + + /* Wide character string. */ STRING_ARG (wstr, wchar_t); + c = inchar (); + if (c == EOF) + input_error (); + +#ifndef COMPILE_WPRINTF + memset (&cstate, '\0', sizeof (cstate)); +#endif + do { - size_t cnt = 0; - NEXT_WIDE_CHAR (first); - - if (__iswspace (val)) + if (ISSPACE (c)) { - /* XXX We would have to push back the whole wide char - with possibly many bytes. But since scanf does - not make a difference for white space characters - we can simply push back a simple <SP> which is - guaranteed to be in the [:space:] class. */ - ungetc (' ', s); + UNGETC (c, s); break; } - STRING_ADD_CHAR (wstr, val, wchar_t); - first = 0; +#ifdef COMPILE_WPRINTF + /* This is easy. */ + if (!(flags & SUPPRESS)) + { + *wstr++ = c; + if ((flags & MALLOC) + && wstr == (wchar_t *) *strptr + strsize) + { + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + (2 * strsize) + * sizeof (wchar_t)); + if (wstr == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + wstr = (wchar_t *) realloc (*strptr, + (strsize + + sizeof (wchar_t))); + if (wstr == NULL) + { + /* We lose. Oh well. Terminate the string + and stop converting, so at least we don't + skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + ++done; + conv_error (); + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + strsize *= 2; + } + } + } +#else + { + char buf[MB_LEN_MAX]; + size_t cnt; + + buf[0] = c; + cnt = 1; + + while (1) + { + size_t n; + + n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL, + buf, cnt, &cstate); + + if (n == (size_t) -2) + { + /* Possibly correct character, just not enough + input. */ + assert (cnt < MB_CUR_MAX); + + if (inchar () == EOF) + encode_error (); + + buf[cnt++] = c; + continue; + } + + if (n != cnt) + encode_error (); + + /* We have a match. */ + break; + } + + if (!(flags & SUPPRESS) && (flags & MALLOC) + && wstr == (wchar_t *) *strptr + strsize) + { + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + (2 * strsize + * sizeof (wchar_t))); + if (wstr == NULL) + { + /* Can't allocate that much. Last-ditch effort. */ + wstr = (wchar_t *) realloc (*strptr, + ((strsize + 1) + * sizeof (wchar_t))); + if (wstr == NULL) + { + /* We lose. Oh well. Terminate the + string and stop converting, so at + least we don't skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + ++done; + conv_error (); + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + strsize *= 2; + } + } + } +#endif } - while (width <= 0 || --width > 0); + while ((width <= 0 || --width > 0) && inchar () != EOF); if (!(flags & SUPPRESS)) { - *wstr = L'\0'; + *wstr++ = L'\0'; + + if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) + { + wchar_t *cp = (wchar_t *) realloc (*strptr, + ((wstr + - (wchar_t *) *strptr) + * sizeof(wchar_t))); + if (cp != NULL) + *strptr = (char *) cp; + } + ++done; } } break; - case 'x': /* Hexadecimal integer. */ - case 'X': /* Ditto. */ + case L_('x'): /* Hexadecimal integer. */ + case L_('X'): /* Ditto. */ base = 16; number_signed = 0; goto number; - case 'o': /* Octal integer. */ + case L_('o'): /* Octal integer. */ base = 8; number_signed = 0; goto number; - case 'u': /* Unsigned decimal integer. */ + case L_('u'): /* Unsigned decimal integer. */ base = 10; number_signed = 0; goto number; - case 'd': /* Signed decimal integer. */ + case L_('d'): /* Signed decimal integer. */ base = 10; number_signed = 1; goto number; - case 'i': /* Generic number. */ + case L_('i'): /* Generic number. */ base = 0; number_signed = 1; @@ -854,7 +1147,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) input_error (); /* Check for a sign. */ - if (c == '-' || c == '+') + if (c == L_('-') || c == L_('+')) { ADDW (c); if (width > 0) @@ -863,7 +1156,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } /* Look for a leading indication of base. */ - if (width != 0 && c == '0') + if (width != 0 && c == L_('0')) { if (width > 0) --width; @@ -871,7 +1164,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) ADDW (c); c = inchar (); - if (width != 0 && _tolower (c) == 'x') + if (width != 0 && TOLOWER (c) == L_('x')) { if (base == 0) base = 16; @@ -892,8 +1185,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Read the number into workspace. */ while (c != EOF && width != 0) { - if (base == 16 ? !isxdigit (c) : - ((!isdigit (c) || c - '0' >= base) && + if (base == 16 ? !ISXDIGIT (c) : + ((!ISDIGIT (c) || c - L_('0') >= base) && !((flags & GROUP) && base == 10 && c == thousands))) break; ADDW (c); @@ -904,34 +1197,34 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } if (wpsize == 0 || - (wpsize == 1 && (wp[0] == '+' || wp[0] == '-'))) + (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-')))) { /* There was no number. If we are supposed to read a pointer we must recognize "(nil)" as well. */ if (wpsize == 0 && read_pointer && (width < 0 || width >= 0) && c == '(' - && _tolower (inchar ()) == 'n' - && _tolower (inchar ()) == 'i' - && _tolower (inchar ()) == 'l' - && inchar () == ')') + && TOLOWER (inchar ()) == L_('n') + && TOLOWER (inchar ()) == L_('i') + && TOLOWER (inchar ()) == L_('l') + && inchar () == L_(')')) /* We must produce the value of a NULL pointer. A single '0' digit is enough. */ - ADDW ('0'); + ADDW (L_('0')); else { /* The last read character is not part of the number anymore. */ - ungetc (c, s); + UNGETC (c, s); conv_error (); } } else /* The just read character is not part of the number anymore. */ - ungetc (c, s); + UNGETC (c, s); /* Convert the number. */ - ADDW ('\0'); + ADDW (L_('\0')); if (need_longlong && (flags & LONGDBL)) { if (number_signed) @@ -982,28 +1275,28 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } break; - case 'e': /* Floating-point numbers. */ - case 'E': - case 'f': - case 'g': - case 'G': - case 'a': - case 'A': + case L_('e'): /* Floating-point numbers. */ + case L_('E'): + case L_('f'): + case L_('g'): + case L_('G'): + case L_('a'): + case L_('A'): c = inchar (); if (c == EOF) input_error (); /* Check for a sign. */ - if (c == '-' || c == '+') + if (c == L_('-') || c == L_('+')) { - negative = c == '-'; + negative = c == L_('-'); if (inchar () == EOF) /* EOF is only an input error before we read any chars. */ conv_error (); - if (! isdigit (c) && c != decimal) + if (! ISDIGIT (c) && c != decimal) { /* This is no valid number. */ - ungetc (c, s); + UNGETC (c, s); input_error (); } if (width > 0) @@ -1013,69 +1306,69 @@ __vfscanf (FILE *s, const char *format, va_list argptr) negative = 0; /* Take care for the special arguments "nan" and "inf". */ - if (_tolower (c) == 'n') + if (TOLOWER (c) == L_('n')) { /* Maybe "nan". */ ADDW (c); - if (inchar () == EOF || _tolower (c) != 'a') + if (inchar () == EOF || TOLOWER (c) != L_('a')) input_error (); ADDW (c); - if (inchar () == EOF || _tolower (c) != 'n') + if (inchar () == EOF || TOLOWER (c) != L_('n')) input_error (); ADDW (c); /* It is "nan". */ goto scan_float; } - else if (_tolower (c) == 'i') + else if (TOLOWER (c) == L_('i')) { /* Maybe "inf" or "infinity". */ ADDW (c); - if (inchar () == EOF || _tolower (c) != 'n') + if (inchar () == EOF || TOLOWER (c) != L_('n')) input_error (); ADDW (c); - if (inchar () == EOF || _tolower (c) != 'f') + if (inchar () == EOF || TOLOWER (c) != L_('f')) input_error (); ADDW (c); /* It is as least "inf". */ if (inchar () != EOF) { - if (_tolower (c) == 'i') + if (TOLOWER (c) == L_('i')) { /* Now we have to read the rest as well. */ ADDW (c); - if (inchar () == EOF || _tolower (c) != 'n') + if (inchar () == EOF || TOLOWER (c) != L_('n')) input_error (); ADDW (c); - if (inchar () == EOF || _tolower (c) != 'i') + if (inchar () == EOF || TOLOWER (c) != L_('i')) input_error (); ADDW (c); - if (inchar () == EOF || _tolower (c) != 't') + if (inchar () == EOF || TOLOWER (c) != L_('t')) input_error (); ADDW (c); - if (inchar () == EOF || _tolower (c) != 'y') + if (inchar () == EOF || TOLOWER (c) != L_('y')) input_error (); ADDW (c); } else /* Never mind. */ - ungetc (c, s); + UNGETC (c, s); } goto scan_float; } is_hexa = 0; - exp_char = 'e'; - if (c == '0') + exp_char = L_('e'); + if (c == L_('0')) { ADDW (c); c = inchar (); - if (_tolower (c) == 'x') + if (TOLOWER (c) == L_('x')) { /* It is a number in hexadecimal format. */ ADDW (c); is_hexa = 1; - exp_char = 'p'; + exp_char = L_('p'); /* Grouping is not allowed. */ flags &= ~GROUP; @@ -1086,14 +1379,14 @@ __vfscanf (FILE *s, const char *format, va_list argptr) got_dot = got_e = 0; do { - if (isdigit (c)) + if (ISDIGIT (c)) ADDW (c); - else if (!got_e && is_hexa && isxdigit (c)) + else if (!got_e && is_hexa && ISXDIGIT (c)) ADDW (c); else if (got_e && wp[wpsize - 1] == exp_char - && (c == '-' || c == '+')) + && (c == L_('-') || c == L_('+'))) ADDW (c); - else if (wpsize > 0 && !got_e && _tolower (c) == exp_char) + else if (wpsize > 0 && !got_e && TOLOWER (c) == exp_char) { ADDW (exp_char); got_e = got_dot = 1; @@ -1109,7 +1402,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) { /* The last read character is not part of the number anymore. */ - ungetc (c, s); + UNGETC (c, s); break; } if (width > 0) @@ -1125,7 +1418,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) scan_float: /* Convert the number. */ - ADDW ('\0'); + ADDW (L_('\0')); if (flags & LONGDBL) { long double d = __strtold_internal (wp, &tw, flags & GROUP); @@ -1152,22 +1445,13 @@ __vfscanf (FILE *s, const char *format, va_list argptr) ++done; break; - case '[': /* Character class. */ + case L_('['): /* Character class. */ if (flags & LONG) - { - STRING_ARG (wstr, wchar_t); - c = '\0'; /* This is to keep gcc quiet. */ - } + STRING_ARG (wstr, wchar_t); else - { - STRING_ARG (str, char); + STRING_ARG (str, char); - c = inchar (); - if (c == EOF) - input_error (); - } - - if (*f == '^') + if (*f == L_('^')) { ++f; not_in = 1; @@ -1175,6 +1459,29 @@ __vfscanf (FILE *s, const char *format, va_list argptr) else not_in = 0; + if (width < 0) + /* There is no width given so there is also no limit on the + number of characters we read. Therefore we set width to + a very high value to make the algorithm easier. */ + width = INT_MAX; + +#ifdef COMPILE_WPRINTF + /* Find the beginning and the end of the scanlist. We are not + creating a lookup table since it would have to be too large. + Instead we search each time through the string. This is not + a constant lookup time but who uses this feature deserves to + be punished. */ + tw = (wchar_t *) f; /* Marks the beginning. */ + + if (*f == ']' || *f == '-') + ++f; + + while ((fc = *f++) != L'\0' && fc != L']'); + + if (fc == L'\0') + conv_error (); + wp = (wchar_t *) f - 1; +#else /* Fill WP with byte flags indexed by character. We will use this flag map for matching input characters. */ if (wpmax < UCHAR_MAX) @@ -1182,7 +1489,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) wpmax = UCHAR_MAX; wp = (char *) alloca (wpmax); } - memset (wp, 0, UCHAR_MAX); + memset (wp, '\0', UCHAR_MAX); fc = *f; if (fc == ']' || fc == '-') @@ -1194,85 +1501,433 @@ __vfscanf (FILE *s, const char *format, va_list argptr) ++f; } + tw = (char *) f; while ((fc = *f++) != '\0' && fc != ']') - { - if (fc == '-' && *f != '\0' && *f != ']' && - (unsigned char) f[-2] <= (unsigned char) *f) - { - /* Add all characters from the one before the '-' - up to (but not including) the next format char. */ - for (fc = f[-2]; fc < *f; ++fc) - wp[fc] = 1; - } - else - /* Add the character to the flag map. */ - wp[fc] = 1; - } + if (fc == '-' && *f != '\0' && *f != ']' && f - 2 != tw + && (unsigned char) f[-2] <= (unsigned char) *f) + { + /* Add all characters from the one before the '-' + up to (but not including) the next format char. */ + for (fc = f[-2]; fc < *f; ++fc) + wp[fc] = 1; + } + else + /* Add the character to the flag map. */ + wp[fc] = 1; + if (fc == '\0') - { - if (!(flags & LONG)) - ungetc (c, s); - conv_error(); - } + conv_error(); +#endif if (flags & LONG) { - wint_t val; - int first = 1; + size_t now = read_in; +#ifdef COMPILE_WPRINTF + do + { + wchar_t *runp; + + if (inchar () == WEOF) + break; + + /* Test whether it's in the scanlist. */ + runp = tw; + while (runp < wp) + { + if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']' + && runp != tw + && (unsigned int) runp[-1] <= (unsigned int) runp[1]) + { + /* Match against all characters in between the + first and last character of the sequence. */ + wchar_t wc; + + for (wc = runp[-1] + 1; wc < runp[1]; ++wc) + if (wc == c) + break; + + if (wc == runp[1] && !not_in) + break; + if (wc == runp[1] && not_in) + { + /* The current character is not in the + scanset. */ + ungetwc (c, s); + goto out; + } + } + else + { + if (*runp == runp[1] && !not_in) + break; + if (*runp != runp[1] && not_in) + { + ungetwc (c ,s); + goto out; + } + } + + ++runp; + } + + if (!(flags & SUPPRESS)) + { + *wstr++ = c; + + if ((flags & MALLOC) + && wstr == (wchar_t *) *strptr + strsize) + { + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + (2 * strsize) + * sizeof (wchar_t)); + if (wstr == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + wstr = (wchar_t *) + realloc (*strptr, (strsize + + sizeof (wchar_t))); + if (wstr == NULL) + { + /* We lose. Oh well. Terminate the string + and stop converting, so at least we don't + skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + ++done; + conv_error (); + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + strsize *= 2; + } + } + } + } + while (--width > 0); + out: +#else + char buf[MB_LEN_MAX]; + size_t cnt = 0; + mbstate_t cstate; + + memset (&cstate, '\0', sizeof (cstate)); do { - size_t cnt = 0; - NEXT_WIDE_CHAR (first); - if (val <= 255 && wp[val] == not_in) + again: + if (inchar () == EOF) + break; + + if (wp[c] == not_in) { - ungetc (val, s); + ungetc (c, s); break; } - STRING_ADD_CHAR (wstr, val, wchar_t); - if (width > 0) - --width; - first = 0; + + /* This is easy. */ + if (!(flags & SUPPRESS)) + { + size_t n; + + /* Convert it into a wide character. */ + n = __mbrtowc (wstr, buf, cnt, &cstate); + + if (n == (size_t) -2) + { + /* Possibly correct character, just not enough + input. */ + assert (cnt < MB_CUR_MAX); + goto again; + } + + if (n != cnt) + encode_error (); + + ++wstr; + if ((flags & MALLOC) + && wstr == (wchar_t *) *strptr + strsize) + { + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + (2 * strsize + * sizeof (wchar_t))); + if (wstr == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + wstr = (wchar_t *) + realloc (*strptr, ((strsize + 1) + * sizeof (wchar_t))); + if (wstr == NULL) + { + /* We lose. Oh well. Terminate the + string and stop converting, + so at least we don't skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + ++done; + conv_error (); + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + strsize *= 2; + } + } + } } - while (width != 0); + while (--width > 0); + + if (cnt != 0) + /* We stopped in the middle of recognizing another + character. That's a problem. */ + encode_error (); +#endif - if (first) + if (now == read_in) + /* We haven't succesfully read any character. */ conv_error (); if (!(flags & SUPPRESS)) { - *wstr = L'\0'; + *wstr++ = L'\0'; + + if ((flags & MALLOC) + && wstr - (wchar_t *) *strptr != strsize) + { + wchar_t *cp = (wchar_t *) + realloc (*strptr, ((wstr - (wchar_t *) *strptr) + * sizeof(wchar_t))); + if (cp != NULL) + *strptr = (char *) cp; + } + ++done; } } else { - num.ul = read_in - 1; /* -1 because we already read one char. */ + size_t now = read_in; +#ifdef COMPILE_WPRINTF + + memset (&state, '\0', sizeof (state)); + + do + { + wchar_t *runp; + size_t n; + + if (inchar () == WEOF) + break; + + /* Test whether it's in the scanlist. */ + runp = tw; + while (runp < wp) + { + if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']' + && runp != tw + && (unsigned int) runp[-1] <= (unsigned int) runp[1]) + { + /* Match against all characters in between the + first and last character of the sequence. */ + wchar_t wc; + + for (wc = runp[-1] + 1; wc < runp[1]; ++wc) + if (wc == c) + break; + + if (wc == runp[1] && !not_in) + break; + if (wc == runp[1] && not_in) + { + /* The current character is not in the + scanset. */ + ungetwc (c, s); + goto out2; + } + } + else + { + if (*runp == runp[1] && !not_in) + break; + if (*runp != runp[1] && not_in) + { + ungetwc (c ,s); + goto out2; + } + } + + ++runp; + } + + if (!(flags & SUPPRESS)) + { + if ((flags & MALLOC) + && str + MB_CUR_MAX >= *strptr + strsize) + { + /* Enlarge the buffer. */ + str = (char *) realloc (*strptr, 2 * strsize); + if (str == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + str = (char *) realloc (*strptr, strsize + 1); + if (str == NULL) + { + /* We lose. Oh well. Terminate the string + and stop converting, so at least we don't + skip any input. */ + (*strptr)[strsize - 1] = '\0'; + ++done; + conv_error (); + } + else + { + *strptr = str; + str += strsize; + ++strsize; + } + } + else + { + *strptr = str; + str += strsize; + strsize *= 2; + } + } + } + + n = wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); + if (n == (size_t) -1) + encode_error (); + + assert (n <= MB_CUR_MAX); + str += n; + } + while (--width > 0); + out2: +#else do { + if (inchar () == EOF) + break; + if (wp[c] == not_in) { ungetc (c, s); break; } - STRING_ADD_CHAR (str, c, char); - if (width > 0) - --width; + + /* This is easy. */ + if (!(flags & SUPPRESS)) + { + *str++ = c; + if ((flags & MALLOC) + && (char *) str == *strptr + strsize) + { + /* Enlarge the buffer. */ + str = (char *) realloc (*strptr, 2 * strsize); + if (str == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + str = (char *) realloc (*strptr, strsize + 1); + if (str == NULL) + { + /* 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; + } + } + else + { + *strptr = (char *) str; + str += strsize; + strsize *= 2; + } + } + } } - while (width != 0 && inchar () != EOF); + while (--width > 0); +#endif - if (read_in == num.ul) + if (now == read_in) + /* We haven't succesfully read any character. */ conv_error (); if (!(flags & SUPPRESS)) { +#ifdef COMPILE_WPRINTF + /* We have to emit the code to get into the intial + state. */ + char buf[MB_LEN_MAX]; + size_t n = wcrtomb (buf, L'\0', &state); + if (n > 0 && (flags & MALLOC) + && str + n >= *strptr + strsize) + { + /* Enlarge the buffer. */ + str = (char *) realloc (*strptr, + (str + n + 1) - *strptr); + if (str == NULL) + { + /* 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 = ((char *) *strptr) + strsize; + strsize = (str + n + 1) - *strptr; + } + } + + str = __mempcpy (str, buf, n); +#endif *str = '\0'; + + if ((flags & MALLOC) && str - *strptr != strsize) + { + char *cp = (char *) realloc (*strptr, str - *strptr); + if (cp != NULL) + *strptr = cp; + } + ++done; } } break; - case 'p': /* Generic pointer. */ + case L_('p'): /* Generic pointer. */ base = 16; /* A PTR must be the same size as a `long int'. */ flags &= ~(SHORT|LONGDBL); @@ -1305,11 +1960,23 @@ __vfscanf (FILE *s, const char *format, va_list argptr) } #ifdef USE_IN_LIBIO +# ifdef COMPILE_WPRINTF +int +__vfwscanf (FILE *s, const wchar_t *format, va_list argptr) +{ + return _IO_vfwscanf (s, format, argptr, NULL); +} +# else int __vfscanf (FILE *s, const char *format, va_list argptr) { return _IO_vfscanf (s, format, argptr, NULL); } +# endif #endif +#ifdef COMPILE_WPRINTF +weak_alias (__vfwscanf, vfwscanf) +#else weak_alias (__vfscanf, vfscanf) +#endif diff --git a/stdio-common/vfwprintf.c b/stdio-common/vfwprintf.c new file mode 100644 index 0000000..2c3cd06 --- /dev/null +++ b/stdio-common/vfwprintf.c @@ -0,0 +1,3 @@ +#include <wctype.h> +#define COMPILE_WPRINTF 1 +#include "vfprintf.c" diff --git a/stdio-common/vfwscanf.c b/stdio-common/vfwscanf.c new file mode 100644 index 0000000..62220bd --- /dev/null +++ b/stdio-common/vfwscanf.c @@ -0,0 +1,2 @@ +#define COMPILE_WPRINTF 1 +#include "vfscanf.c" diff --git a/stdlib/mblen.c b/stdlib/mblen.c index 9d8d0cc..3a9755b 100644 --- a/stdlib/mblen.c +++ b/stdlib/mblen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1997, 1998, 1999 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 @@ -40,7 +40,7 @@ mblen (const char *s, size_t n) /* Make sure we use the correct value. */ update_conversion_ptrs (); - result = __wcsmbs_gconv_fcts.towc->stateful; + result = __wcsmbs_gconv_fcts.towc->__stateful; } else if (*s == '\0') /* According to the ISO C 89 standard this is the expected behaviour. diff --git a/stdlib/mbtowc.c b/stdlib/mbtowc.c index 938d547..a8df154 100644 --- a/stdlib/mbtowc.c +++ b/stdlib/mbtowc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 95, 96, 97, 98, 99 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 @@ -46,7 +46,7 @@ mbtowc (wchar_t *pwc, const char *s, size_t n) /* Make sure we use the correct value. */ update_conversion_ptrs (); - result = __wcsmbs_gconv_fcts.towc->stateful; + result = __wcsmbs_gconv_fcts.towc->__stateful; } else if (*s == '\0') { diff --git a/stdlib/strfmon.c b/stdlib/strfmon.c index 187e33f..7041994 100644 --- a/stdlib/strfmon.c +++ b/stdlib/strfmon.c @@ -1,5 +1,5 @@ /* Formatting a monetary value according to the current locale. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com> and Jochen Hein <Jochen.Hein@informatik.TU-Clausthal.de>, 1996. @@ -454,6 +454,7 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...) info.group = group; info.pad = pad; info.extra = 1; /* This means use values from LC_MONETARY. */ + info.wide = 0; ptr = &fpnum; done = __printf_fp ((FILE *) &f, &info, &ptr); diff --git a/stdlib/wctomb.c b/stdlib/wctomb.c index b7132e0..2df8b99 100644 --- a/stdlib/wctomb.c +++ b/stdlib/wctomb.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 95, 96, 97, 98, 99 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 @@ -42,7 +42,7 @@ wctomb (char *s, wchar_t wchar) /* Make sure we use the correct value. */ update_conversion_ptrs (); - return __wcsmbs_gconv_fcts.tomb->stateful; + return __wcsmbs_gconv_fcts.tomb->__stateful; } return __wcrtomb (s, wchar, &__no_r_state); diff --git a/sysdeps/generic/_G_config.h b/sysdeps/generic/_G_config.h index d63b0d7..04bc4ed 100644 --- a/sysdeps/generic/_G_config.h +++ b/sysdeps/generic/_G_config.h @@ -21,8 +21,16 @@ typedef unsigned int wint_t; #endif #define _G_size_t size_t -#define _G_fpos_t __off_t -#define _G_fpos64_t __off_t +typedef struct +{ + __off_t __pos; + __mbstate_t __state; +} _G_fpos_t; +typedef struct +{ + __off64_t __pos; + __mbstate_t __state; +} _G_fpos64_t; #define _G_ssize_t __ssize_t #define _G_off_t __off_t #define _G_off64_t __off_t @@ -31,6 +39,12 @@ typedef unsigned int wint_t; #define _G_wchar_t wchar_t #define _G_wint_t wint_t #define _G_stat64 stat +#include <gconv.h> +typedef struct +{ + __gconv_t __cd; + struct __gconv_step_data __data; +} _G_iconv_t; typedef int _G_int16_t __attribute__ ((__mode__ (__HI__))); typedef int _G_int32_t __attribute__ ((__mode__ (__SI__))); diff --git a/sysdeps/generic/printf_fphex.c b/sysdeps/generic/printf_fphex.c index b306220..9e9fd07 100644 --- a/sysdeps/generic/printf_fphex.c +++ b/sysdeps/generic/printf_fphex.c @@ -38,11 +38,12 @@ #ifdef USE_IN_LIBIO # include <libioP.h> # define PUT(f, s, n) _IO_sputn (f, s, n) -# define PAD(f, c, n) _IO_padn (f, c, n) +# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n)) /* We use this file GNU C library and GNU I/O library. So make names equal. */ # undef putc -# define putc(c, f) _IO_putc_unlocked (c, f) +# define putc(c, f) (wide \ + ? _IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f)) # define size_t _IO_size_t # define FILE _IO_FILE #else /* ! USE_IN_LIBIO */ @@ -132,6 +133,9 @@ __printf_fphex (FILE *fp, /* Number of characters written. */ int done = 0; + /* Nonzero if this is output on a wide character stream. */ + int wide = info->wide; + /* Figure out the decimal point character. */ if (info->extra == 0) diff --git a/sysdeps/unix/sysv/linux/_G_config.h b/sysdeps/unix/sysv/linux/_G_config.h index e829a73..edd29ea 100644 --- a/sysdeps/unix/sysv/linux/_G_config.h +++ b/sysdeps/unix/sysv/linux/_G_config.h @@ -20,9 +20,19 @@ # define _WINT_T typedef unsigned int wint_t; #endif +#define __need_mbstate_t +#include <wchar.h> #define _G_size_t size_t -#define _G_fpos_t __off_t -#define _G_fpos64_t __off64_t +typedef struct +{ + __off_t __pos; + __mbstate_t __state; +} _G_fpos_t; +typedef struct +{ + __off64_t __pos; + __mbstate_t __state; +} _G_fpos64_t; #define _G_ssize_t __ssize_t #define _G_off_t __off_t #define _G_off64_t __off64_t @@ -31,6 +41,16 @@ typedef unsigned int wint_t; #define _G_wchar_t wchar_t #define _G_wint_t wint_t #define _G_stat64 stat64 +#include <gconv.h> +typedef union +{ + struct __gconv_info __cd; + struct + { + struct __gconv_info __cd; + struct __gconv_step_data __data; + } __combined; +} _G_iconv_t; typedef int _G_int16_t __attribute__ ((__mode__ (__HI__))); typedef int _G_int32_t __attribute__ ((__mode__ (__SI__))); diff --git a/time/Makefile b/time/Makefile index 08b783f..c0cbb91 100644 --- a/time/Makefile +++ b/time/Makefile @@ -28,9 +28,9 @@ routines := offtime asctime clock ctime ctime_r difftime \ gettimeofday settimeofday adjtime tzset \ tzfile getitimer setitimer \ stime dysize timegm ftime \ - strptime getdate + strptime getdate wcsftime -tests := test_time clocktest tst-posixtz tst-strptime +tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime include ../Rules diff --git a/time/Versions b/time/Versions index e117a4a..ed6429e 100644 --- a/time/Versions +++ b/time/Versions @@ -46,4 +46,8 @@ libc { # g* getdate; getdate_r; getitimer; } + GLIBC_2.2 { + # w* + wcsftime; + } } diff --git a/time/strftime.c b/time/strftime.c index bb19bab..60c8123 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,94,95,96,97,98,99 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 @@ -83,22 +83,41 @@ extern char *tzname[]; # include <stddef.h> # include <stdlib.h> # include <string.h> -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy ((s), (d), (n)) -# endif #endif -#ifdef _LIBC -# define MEMPCPY(d, s, n) __mempcpy (d, s, n) +#ifdef COMPILE_WIDE +# define CHAR_T wchar_t +# define UCHAR_T unsigned int +# 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) + #else -# ifndef HAVE_MEMPCPY -# define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n))) +# define CHAR_T char +# define UCHAR_T unsigned char +# define L_(Str) Str +# define NLW(Sym) Sym + +# if !defined STDC_HEADERS && !defined HAVE_MEMCPY +# define MEMCPY(d, s, n) bcopy ((s), (d), (n)) +# else +# define MEMCPY(d, s, n) memcpy ((d), (s), (n)) +# endif +# define STRLEN(s) strlen (s) + +# ifdef _LIBC +# define MEMPCPY(d, s, n) __mempcpy (d, s, n) +# else +# ifndef HAVE_MEMPCPY +# define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n))) +# endif # endif #endif #ifndef __P -# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# if defined __GNUC__ || (defined __STDC__ && __STDC__) # define __P(args) args # else # define __P(args) () @@ -187,10 +206,16 @@ my_strftime_localtime_r (t, tp) introduce additional dependencies. */ /* The SGI compiler reportedly barfs on the trailing null if we use a string constant as the initializer. 28 June 1997, rms. */ -static const char spaces[16] = /* " " */ - { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' }; -static const char zeroes[16] = /* "0000000000000000" */ - { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' }; +static const CHAR_T spaces[16] = /* " " */ +{ + L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '), + L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ') +}; +static const CHAR_T zeroes[16] = /* "0000000000000000" */ +{ + L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'), + L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0') +}; # define memset_space(P, Len) \ do { \ @@ -199,7 +224,7 @@ static const char zeroes[16] = /* "0000000000000000" */ do \ { \ int _this = _len > 16 ? 16 : _len; \ - (P) = MEMPCPY ((P), spaces, _this); \ + (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \ _len -= _this; \ } \ while (_len > 0); \ @@ -212,14 +237,19 @@ static const char zeroes[16] = /* "0000000000000000" */ do \ { \ int _this = _len > 16 ? 16 : _len; \ - (P) = MEMPCPY ((P), zeroes, _this); \ + (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \ _len -= _this; \ } \ while (_len > 0); \ } while (0) #else -# define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len)) -# define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len)) +# ifdef COMPILE_WIDE +# define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len)) +# define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len)) +# else +# define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len)) +# define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len)) +# endif #endif #define add(n, f) \ @@ -234,7 +264,7 @@ static const char zeroes[16] = /* "0000000000000000" */ { \ if (_delta > 0) \ { \ - if (pad == '0') \ + if (pad == L_('0')) \ memset_zero (p, _delta); \ else \ memset_space (p, _delta); \ @@ -252,46 +282,64 @@ static const char zeroes[16] = /* "0000000000000000" */ else if (to_uppcase) \ memcpy_uppcase (p, (s), _n); \ else \ - memcpy ((PTR) p, (PTR) (s), _n)) - + MEMCPY ((PTR) p, (PTR) (s), _n)) + +#ifdef COMPILE_WIDE +# define widen(os, ws, l) \ + { \ + mbstate_t __st; \ + const char *__s = os; \ + memset (&__st, '\0', sizeof (__st)); \ + l = __mbsrtowcs (NULL, &__s, 0, &__st); \ + ws = alloca ((l + 1) * sizeof (wchar_t)); \ + (void) __mbsrtowcs (ws, &__s, l, &__st); \ + } +#endif -#ifdef _LIBC -# define TOUPPER(Ch) toupper (Ch) -# define TOLOWER(Ch) tolower (Ch) +#ifdef COMPILE_WIDE +# define TOUPPER(Ch) towupper (Ch) +# define TOLOWER(Ch) towlower (Ch) #else -# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch)) -# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) +# ifdef _LIBC +# define TOUPPER(Ch) toupper (Ch) +# define TOLOWER(Ch) tolower (Ch) +# else +# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch)) +# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) +# endif #endif /* We don't use `isdigit' here since the locale dependent interpretation is not what we want here. We only need to accept the arabic digits in the ASCII range. One day there is perhaps a more reliable way to accept other sets of digits. */ -#define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9) +#define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9) -static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len)); +static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src, + size_t len)); -static char * +static CHAR_T * memcpy_lowcase (dest, src, len) - char *dest; - const char *src; + CHAR_T *dest; + const CHAR_T *src; size_t len; { while (len-- > 0) - dest[len] = TOLOWER ((unsigned char) src[len]); + dest[len] = TOLOWER ((UCHAR_T) src[len]); return dest; } -static char *memcpy_uppcase __P ((char *dest, const char *src, size_t len)); +static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src, + size_t len)); -static char * +static CHAR_T * memcpy_uppcase (dest, src, len) - char *dest; - const char *src; + CHAR_T *dest; + const CHAR_T *src; size_t len; { while (len-- > 0) - dest[len] = TOUPPER ((unsigned char) src[len]); + dest[len] = TOUPPER ((UCHAR_T) src[len]); return dest; } @@ -352,15 +400,16 @@ iso_week_days (yday, wday) #if !(defined _NL_CURRENT || HAVE_STRFTIME) -static char const weekday_name[][10] = +static CHAR_T const weekday_name[][10] = { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" + L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"), + L_("Thursday"), L_("Friday"), L_("Saturday") }; -static char const month_name[][10] = +static CHAR_T const month_name[][10] = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" + L_("January"), L_("February"), L_("March"), L_("April"), L_("May"), + L_("June"), L_("July"), L_("August"), L_("September"), L_("October"), + L_("November"), L_("December") }; #endif @@ -371,7 +420,11 @@ static char const month_name[][10] = # define ut_argument_spec int ut; # define ut_argument_spec_iso , int ut #else -# define my_strftime strftime +# 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 @@ -386,9 +439,9 @@ static char const month_name[][10] = const struct tm * ut_argument_spec_iso)); size_t my_strftime (s, maxsize, format, tp ut_argument) - char *s; + CHAR_T *s; size_t maxsize; - const char *format; + const CHAR_T *format; const struct tm *tp; ut_argument_spec { @@ -410,9 +463,9 @@ static char const month_name[][10] = written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ size_t my_strftime (s, maxsize, format, tp ut_argument) - char *s; + CHAR_T *s; size_t maxsize; - const char *format; + const CHAR_T *format; const struct tm *tp; ut_argument_spec { @@ -424,22 +477,28 @@ my_strftime (s, maxsize, format, tp ut_argument) might be generated by a strptime() call that initialized only a few elements. Dereference the pointers only if the format requires this. Then it is ok to fail if the pointers are invalid. */ -# define a_wkday _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday) -# define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday) -# define a_month _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon) -# define f_month _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon) -# define ampm _NL_CURRENT (LC_TIME, tp->tm_hour > 11 ? PM_STR : AM_STR) - -# define aw_len strlen (a_wkday) -# define am_len strlen (a_month) -# define ap_len strlen (ampm) +# define a_wkday \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) +# define f_wkday \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) +# define a_month \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) +# define f_month \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) +# define ampm \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ + ? NLW(PM_STR) : NLW(AM_STR))) + +# define aw_len STRLEN (a_wkday) +# define am_len STRLEN (a_month) +# define ap_len STRLEN (ampm) #else # if !HAVE_STRFTIME # define f_wkday (weekday_name[tp->tm_wday]) # define f_month (month_name[tp->tm_mon]) # define a_wkday f_wkday # define a_month f_month -# define ampm ("AMPM" + 2 * (tp->tm_hour > 11)) +# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) size_t aw_len = 3; size_t am_len = 3; @@ -448,8 +507,8 @@ my_strftime (s, maxsize, format, tp ut_argument) #endif const char *zone; size_t i = 0; - char *p = s; - const char *f; + CHAR_T *p = s; + const CHAR_T *f; zone = NULL; #if HAVE_TM_ZONE @@ -491,42 +550,44 @@ my_strftime (s, maxsize, format, tp ut_argument) int digits; /* Max digits for numeric format. */ int number_value; /* Numeric value to be printed. */ int negative_number; /* 1 if the number is negative. */ - const char *subfmt; - char *bufp; - char buf[1 + (sizeof (int) < sizeof (time_t) - ? INT_STRLEN_BOUND (time_t) - : INT_STRLEN_BOUND (int))]; + const CHAR_T *subfmt; + CHAR_T *bufp; + CHAR_T buf[1 + (sizeof (int) < sizeof (time_t) + ? INT_STRLEN_BOUND (time_t) + : INT_STRLEN_BOUND (int))]; int width = -1; int to_lowcase = 0; int to_uppcase = 0; int change_case = 0; int format_char; -#if DO_MULTIBYTE - - switch (*f) +#if DO_MULTIBYTE && !defined COMPILE_WIDE + switch (*f) { - case '%': + case L_('%'): break; - case '\a': case '\b': case '\t': case '\n': - case '\v': case '\f': case '\r': - case ' ': case '!': case '"': case '#': case '&': case'\'': - case '(': case ')': case '*': case '+': case ',': case '-': - case '.': case '/': case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': case '8': case '9': - case ':': case ';': case '<': case '=': case '>': case '?': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': case '[': case'\\': case ']': case '^': - case '_': case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': - case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': - case 'r': case 's': case 't': case 'u': case 'v': case 'w': - case 'x': case 'y': case 'z': case '{': case '|': case '}': - case '~': + case L_('\a'): case L_('\b'): case L_('\t'): case L_('\n'): + case L_('\v'): case L_('\f'): case L_('\r'): + case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'): + case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'): + case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'): + case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'): + case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'): + case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'): + case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'): + case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'): + case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'): + case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'): + case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'): + case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'): + case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'): + case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'): + case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'): + case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'): + case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'): + case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'): + case L_('~'): /* The C Standard requires these 98 characters (plus '%') to be in the basic execution character set. None of these characters can start a multibyte sequence, so they need @@ -572,9 +633,10 @@ my_strftime (s, maxsize, format, tp ut_argument) #else /* ! DO_MULTIBYTE */ - /* Either multibyte encodings are not supported, or they are - safe for formats, so any non-'%' byte can be copied through. */ - if (*f != '%') + /* Either multibyte encodings are not supported, they are + safe for formats, so any non-'%' byte can be copied through, + or this is the wide character version. */ + if (*f != L_('%')) { add (1, *p = *f); continue; @@ -588,17 +650,17 @@ my_strftime (s, maxsize, format, tp ut_argument) switch (*++f) { /* This influences the number formats. */ - case '_': - case '-': - case '0': + case L_('_'): + case L_('-'): + case L_('0'): pad = *f; continue; /* This changes textual output. */ - case '^': + case L_('^'): to_uppcase = 1; continue; - case '#': + case L_('#'): change_case = 1; continue; @@ -615,7 +677,7 @@ my_strftime (s, maxsize, format, tp ut_argument) do { width *= 10; - width += *f - '0'; + width += *f - L_('0'); ++f; } while (ISDIGIT (*f)); @@ -624,8 +686,8 @@ my_strftime (s, maxsize, format, tp ut_argument) /* Check for modifiers. */ switch (*f) { - case 'E': - case 'O': + case L_('E'): + case L_('O'): modifier = *f++; break; @@ -645,13 +707,13 @@ my_strftime (s, maxsize, format, tp ut_argument) digits = width == -1 ? d : width; \ number_value = v; goto do_number_spacepad - case '%': + case L_('%'): if (modifier != 0) goto bad_format; add (1, *p = *f); break; - case 'a': + case L_('a'): if (modifier != 0) goto bad_format; if (change_case) @@ -675,14 +737,14 @@ my_strftime (s, maxsize, format, tp ut_argument) to_lowcase = 0; } #if defined _NL_CURRENT || !HAVE_STRFTIME - cpy (strlen (f_wkday), f_wkday); + cpy (STRLEN (f_wkday), f_wkday); break; #else goto underlying_strftime; #endif - case 'b': - case 'h': /* POSIX.2 extension. */ + case L_('b'): + case L_('h'): /* POSIX.2 extension. */ if (modifier != 0) goto bad_format; #if defined _NL_CURRENT || !HAVE_STRFTIME @@ -692,7 +754,7 @@ my_strftime (s, maxsize, format, tp ut_argument) goto underlying_strftime; #endif - case 'B': + case L_('B'): if (modifier != 0) goto bad_format; if (change_case) @@ -701,37 +763,39 @@ my_strftime (s, maxsize, format, tp ut_argument) to_lowcase = 0; } #if defined _NL_CURRENT || !HAVE_STRFTIME - cpy (strlen (f_month), f_month); + cpy (STRLEN (f_month), f_month); break; #else goto underlying_strftime; #endif - case 'c': - if (modifier == 'O') + case L_('c'): + if (modifier == L_('O')) goto bad_format; #ifdef _NL_CURRENT if (! (modifier == 'E' - && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0')) - subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); + && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(ERA_D_T_FMT))) + != '\0'))) + subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT)); #else # if HAVE_STRFTIME goto underlying_strftime; # else - subfmt = "%a %b %e %H:%M:%S %Y"; + subfmt = L_("%a %b %e %H:%M:%S %Y"); # endif #endif subformat: { - char *old_start = p; + 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)); if (to_uppcase) while (old_start < p) { - *old_start = TOUPPER ((unsigned char) *old_start); + *old_start = TOUPPER ((UCHAR_T) *old_start); ++old_start; } } @@ -759,17 +823,26 @@ my_strftime (s, maxsize, format, tp ut_argument) break; #endif - case 'C': /* POSIX.2 extension. */ - if (modifier == 'O') + case L_('C'): /* POSIX.2 extension. */ + if (modifier == L_('O')) goto bad_format; - if (modifier == 'E') + if (modifier == L_('E')) { #if HAVE_STRUCT_ERA_ENTRY struct era_entry *era = _nl_get_era_entry (tp); if (era) { +# ifdef COMPILE_WIDE + /* XXX For the time being there is no equivalent to + _nl_get_era_entry to get a wide character variant. */ + wchar_t *ws; + size_t len; + widen (era->name_fmt, ws, len); + cpy (len, ws); +# else size_t len = strlen (era->name_fmt); cpy (len, era->name_fmt); +# endif break; } #else @@ -784,13 +857,15 @@ my_strftime (s, maxsize, format, tp ut_argument) DO_NUMBER (1, year / 100 - (year % 100 < 0)); } - case 'x': - if (modifier == 'O') + case L_('x'): + if (modifier == L_('O')) goto bad_format; #ifdef _NL_CURRENT - if (! (modifier == 'E' - && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0')) - subfmt = _NL_CURRENT (LC_TIME, D_FMT); + if (! (modifier == L_('E') + && (*(subfmt = (CHAR_T *)_NL_CURRENT (LC_TIME, + NLW(ERA_D_FMT))) + != L_('\0')))) + subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT)); goto subformat; #else # if HAVE_STRFTIME @@ -799,20 +874,20 @@ my_strftime (s, maxsize, format, tp ut_argument) /* Fall through. */ # endif #endif - case 'D': /* POSIX.2 extension. */ + case L_('D'): /* POSIX.2 extension. */ if (modifier != 0) goto bad_format; - subfmt = "%m/%d/%y"; + subfmt = L_("%m/%d/%y"); goto subformat; - case 'd': - if (modifier == 'E') + case L_('d'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_mday); - case 'e': /* POSIX.2 extension. */ - if (modifier == 'E') + case L_('e'): /* POSIX.2 extension. */ + if (modifier == L_('E')) goto bad_format; DO_NUMBER_SPACEPAD (2, tp->tm_mday); @@ -822,22 +897,32 @@ my_strftime (s, maxsize, format, tp ut_argument) do_number_spacepad: /* Force `_' flag unless overwritten by `0' flag. */ - if (pad != '0') - pad = '_'; + if (pad != L_('0')) + pad = L_('_'); do_number: /* Format the number according to the MODIFIER flag. */ - if (modifier == 'O' && 0 <= number_value) + if (modifier == L_('O') && 0 <= number_value) { #ifdef _NL_CURRENT /* Get the locale specific alternate representation of the number NUMBER_VALUE. If none exist NULL is returned. */ +# ifdef COMPILE_WIDE + const char *ncp = _nl_get_alt_digit (number_value); + wchar_t *cp = NULL; + if (ncp != NULL) + { + size_t len; + widen (ncp, cp, len); + } +# else const char *cp = _nl_get_alt_digit (number_value); +# endif if (cp != NULL) { - size_t digitlen = strlen (cp); + size_t digitlen = STRLEN (cp); if (digitlen != 0) { cpy (digitlen, cp); @@ -853,103 +938,104 @@ my_strftime (s, maxsize, format, tp ut_argument) { unsigned int u = number_value; - bufp = buf + sizeof (buf); + bufp = buf + sizeof (buf) / sizeof (buf[0]); negative_number = number_value < 0; if (negative_number) u = -u; do - *--bufp = u % 10 + '0'; + *--bufp = u % 10 + L_('0'); while ((u /= 10) != 0); } do_number_sign_and_padding: if (negative_number) - *--bufp = '-'; + *--bufp = L_('-'); - if (pad != '-') + if (pad != L_('-')) { - int padding = digits - (buf + sizeof (buf) - bufp); + int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0])) + - bufp); - if (pad == '_') + if (pad == L_('_')) { while (0 < padding--) - *--bufp = ' '; + *--bufp = L_(' '); } else { bufp += negative_number; while (0 < padding--) - *--bufp = '0'; + *--bufp = L_('0'); if (negative_number) - *--bufp = '-'; + *--bufp = L_('-'); } } - cpy (buf + sizeof (buf) - bufp, bufp); + cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp); break; - case 'F': + case L_('F'): if (modifier != 0) goto bad_format; - subfmt = "%Y-%m-%d"; + subfmt = L_("%Y-%m-%d"); goto subformat; - case 'H': - if (modifier == 'E') + case L_('H'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_hour); - case 'I': - if (modifier == 'E') + case L_('I'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, hour12); - case 'k': /* GNU extension. */ - if (modifier == 'E') + case L_('k'): /* GNU extension. */ + if (modifier == L_('E')) goto bad_format; DO_NUMBER_SPACEPAD (2, tp->tm_hour); - case 'l': /* GNU extension. */ - if (modifier == 'E') + case L_('l'): /* GNU extension. */ + if (modifier == L_('E')) goto bad_format; DO_NUMBER_SPACEPAD (2, hour12); - case 'j': - if (modifier == 'E') + case L_('j'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (3, 1 + tp->tm_yday); - case 'M': - if (modifier == 'E') + case L_('M'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_min); - case 'm': - if (modifier == 'E') + case L_('m'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_mon + 1); - case 'n': /* POSIX.2 extension. */ - add (1, *p = '\n'); + case L_('n'): /* POSIX.2 extension. */ + add (1, *p = L_('\n')); break; - case 'P': + case L_('P'): to_lowcase = 1; #if !defined _NL_CURRENT && HAVE_STRFTIME - format_char = 'p'; + format_char = L_('p'); #endif /* FALLTHROUGH */ - case 'p': + case L_('p'): if (change_case) { to_uppcase = 0; @@ -962,24 +1048,25 @@ my_strftime (s, maxsize, format, tp ut_argument) goto underlying_strftime; #endif - case 'R': /* GNU extension. */ - subfmt = "%H:%M"; + case L_('R'): /* GNU extension. */ + subfmt = L_("%H:%M"); goto subformat; - case 'r': /* POSIX.2 extension. */ + case L_('r'): /* POSIX.2 extension. */ #ifdef _NL_CURRENT - if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0') + if (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(T_FMT_AMPM))) == L_('\0')) #endif - subfmt = "%I:%M:%S %p"; + subfmt = L_("%I:%M:%S %p"); goto subformat; - case 'S': - if (modifier == 'E') + case L_('S'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_sec); - case 's': /* GNU extension. */ + case L_('s'): /* GNU extension. */ { struct tm ltm; time_t t; @@ -990,7 +1077,7 @@ my_strftime (s, maxsize, format, tp ut_argument) /* Generate string value for T using time_t arithmetic; this works even if sizeof (long) < sizeof (time_t). */ - bufp = buf + sizeof (buf); + bufp = buf + sizeof (buf) / sizeof (buf[0]); negative_number = t < 0; do @@ -1010,7 +1097,7 @@ my_strftime (s, maxsize, format, tp ut_argument) } } - *--bufp = d + '0'; + *--bufp = d + L_('0'); } while (t != 0); @@ -1018,13 +1105,15 @@ my_strftime (s, maxsize, format, tp ut_argument) goto do_number_sign_and_padding; } - case 'X': - if (modifier == 'O') + case L_('X'): + if (modifier == L_('O')) goto bad_format; #ifdef _NL_CURRENT - if (! (modifier == 'E' - && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0')) - subfmt = _NL_CURRENT (LC_TIME, T_FMT); + if (! (modifier == L_('E') + && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(ERA_T_FMT))) + != L_('\0')))) + subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT)); goto subformat; #else # if HAVE_STRFTIME @@ -1033,27 +1122,27 @@ my_strftime (s, maxsize, format, tp ut_argument) /* Fall through. */ # endif #endif - case 'T': /* POSIX.2 extension. */ - subfmt = "%H:%M:%S"; + case L_('T'): /* POSIX.2 extension. */ + subfmt = L_("%H:%M:%S"); goto subformat; - case 't': /* POSIX.2 extension. */ - add (1, *p = '\t'); + case L_('t'): /* POSIX.2 extension. */ + add (1, *p = L_('\t')); break; - case 'u': /* POSIX.2 extension. */ + case L_('u'): /* POSIX.2 extension. */ DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1); - case 'U': - if (modifier == 'E') + case L_('U'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7); - case 'V': - case 'g': /* GNU extension. */ - case 'G': /* GNU extension. */ - if (modifier == 'E') + case L_('V'): + case L_('g'): /* GNU extension. */ + case L_('G'): /* GNU extension. */ + if (modifier == L_('E')) goto bad_format; { int year = tp->tm_year + TM_YEAR_BASE; @@ -1080,10 +1169,10 @@ my_strftime (s, maxsize, format, tp ut_argument) switch (*f) { - case 'g': + case L_('g'): DO_NUMBER (2, (year % 100 + 100) % 100); - case 'G': + case L_('G'): DO_NUMBER (1, year); default: @@ -1091,26 +1180,36 @@ my_strftime (s, maxsize, format, tp ut_argument) } } - case 'W': - if (modifier == 'E') + case L_('W'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7); - case 'w': - if (modifier == 'E') + case L_('w'): + if (modifier == L_('E')) goto bad_format; DO_NUMBER (1, tp->tm_wday); - case 'Y': + case L_('Y'): if (modifier == 'E') { #if HAVE_STRUCT_ERA_ENTRY struct era_entry *era = _nl_get_era_entry (tp); if (era) { +# ifdef COMPILE_WIDE + /* XXX For the time being there is no wide character + equivalent or _nl_get_era_entry. */ + const char *ncp = strchr (era->name_fmt, '\0') + 1; + size_t len; + wchar_t *s; + widen (ncp, s, len); + subfmt = s; +# else subfmt = strchr (era->name_fmt, '\0') + 1; +# endif goto subformat; } #else @@ -1119,13 +1218,13 @@ my_strftime (s, maxsize, format, tp ut_argument) # endif #endif } - if (modifier == 'O') + if (modifier == L_('O')) goto bad_format; else DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE); - case 'y': - if (modifier == 'E') + case L_('y'): + if (modifier == L_('E')) { #if HAVE_STRUCT_ERA_ENTRY struct era_entry *era = _nl_get_era_entry (tp); @@ -1143,7 +1242,7 @@ my_strftime (s, maxsize, format, tp ut_argument) } DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); - case 'Z': + case L_('Z'): if (change_case) { to_uppcase = 0; @@ -1158,10 +1257,21 @@ my_strftime (s, maxsize, format, tp ut_argument) if (! zone) zone = ""; /* POSIX.2 requires the empty string here. */ +#ifdef COMPILE_WIDE + { + /* The zone string is always given in multibyte form. We have + to transform it first. */ + wchar_t *wczone; + size_t len; + widen (zone, wczone, len); + cpy (len, wczone); + } +#else cpy (strlen (zone), zone); +#endif break; - case 'z': /* GNU extension. */ + case L_('z'): /* GNU extension. */ if (tp->tm_isdst < 0) break; @@ -1207,17 +1317,17 @@ my_strftime (s, maxsize, format, tp ut_argument) if (diff < 0) { - add (1, *p = '-'); + add (1, *p = L_('-')); diff = -diff; } else - add (1, *p = '+'); + add (1, *p = L_('+')); diff /= 60; DO_NUMBER (4, (diff / 60) * 100 + diff % 60); } - case '\0': /* GNU extension: % at end of format. */ + case L_('\0'): /* GNU extension: % at end of format. */ --f; /* Fall through. */ default: @@ -1227,7 +1337,7 @@ my_strftime (s, maxsize, format, tp ut_argument) bad_format: { int flen; - for (flen = 1; f[1 - flen] != '%'; flen++) + for (flen = 1; f[1 - flen] != L_('%'); flen++) continue; cpy (flen, &f[1 - flen]); } @@ -1236,7 +1346,7 @@ my_strftime (s, maxsize, format, tp ut_argument) } if (p && maxsize != 0) - *p = '\0'; + *p = L_('\0'); return i; } diff --git a/time/tst_wcsftime.c b/time/tst_wcsftime.c new file mode 100644 index 0000000..3f6f0d9 --- /dev/null +++ b/time/tst_wcsftime.c @@ -0,0 +1,28 @@ +#include <time.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + wchar_t buf[200]; + time_t t; + struct tm *tp; + int result = 0; + size_t n; + + time (&t); + tp = gmtime (&t); + + n = wcsftime (buf, sizeof (buf) / sizeof (buf[0]), + L"%H:%M:%S %Y-%m-%d\n", tp); + if (n != 21) + result = 1; + + wprintf (L"It is now %ls", buf); + + wcsftime (buf, sizeof (buf) / sizeof (buf[0]), L"%A\n", tp); + + wprintf (L"The weekday is %ls", buf); + + return result; +} diff --git a/time/wcsftime.c b/time/wcsftime.c new file mode 100644 index 0000000..17bb53e --- /dev/null +++ b/time/wcsftime.c @@ -0,0 +1,4 @@ +#include <wctype.h> +#include <wchar.h> +#define COMPILE_WIDE 1 +#include "strftime.c" diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile index fa5dbef..f1dc651 100644 --- a/wcsmbs/Makefile +++ b/wcsmbs/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1995, 1996, 1997, 1998, 1999 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 @@ -26,10 +26,10 @@ distribute := wcwidth.h wcsmbsload.h routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \ - wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy \ + wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \ btowc wctob mbsinit \ mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \ - mbsnrtowcs wcsnrtombs wcsnlen \ + mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \ wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \ wcstol_l wcstoul_l wcstoll_l wcstoull_l \ wcstod_l wcstold_l wcstof_l \ diff --git a/wcsmbs/Versions b/wcsmbs/Versions index 54195ba..d0ba267 100644 --- a/wcsmbs/Versions +++ b/wcsmbs/Versions @@ -20,4 +20,8 @@ libc { wcscasecmp; wcsncasecmp; wcsnlen; wcstoll; wcstoimax; wcstoumax; wcstoull; wcswcs; wmemrtombs; wmemrtowcs; } + GLIBC_2.2 { + # w* + wcschrnul; wmempcpy; + } } diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c index 1c6332e..bec0d48 100644 --- a/wcsmbs/btowc.c +++ b/wcsmbs/btowc.c @@ -30,7 +30,7 @@ __btowc (c) int c; { wchar_t result; - struct gconv_step_data data; + struct __gconv_step_data data; unsigned char inbuf[1]; const unsigned char *inptr = inbuf; size_t dummy; @@ -42,12 +42,12 @@ __btowc (c) return WEOF; /* Tell where we want the result. */ - data.outbuf = (unsigned char *) &result; - data.outbufend = data.outbuf + sizeof (wchar_t); - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = &data.__state; + data.__outbuf = (unsigned char *) &result; + data.__outbufend = data.__outbuf + sizeof (wchar_t); + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = &data.__state; /* Make sure we start in the initial state. */ memset (&data.__state, '\0', sizeof (mbstate_t)); @@ -58,11 +58,11 @@ __btowc (c) /* Create the input string. */ inbuf[0] = c; - status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc, &data, - &inptr, inptr + 1, &dummy, 0); + status = (*__wcsmbs_gconv_fcts.towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, + &inptr, inptr + 1, &dummy, 0); /* The conversion failed. */ - if (status != GCONV_OK && status != GCONV_FULL_OUTPUT - && status != GCONV_EMPTY_INPUT) + if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) result = WEOF; return result; diff --git a/wcsmbs/mbrtowc.c b/wcsmbs/mbrtowc.c index 78ff2a2..a68b0f2 100644 --- a/wcsmbs/mbrtowc.c +++ b/wcsmbs/mbrtowc.c @@ -35,7 +35,7 @@ size_t __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) { wchar_t buf[1]; - struct gconv_step_data data; + struct __gconv_step_data data; int status; size_t result; size_t dummy; @@ -43,18 +43,18 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) char *outbuf = (char *) (pwc ?: buf); /* Tell where we want the result. */ - data.outbuf = outbuf; - data.outbufend = outbuf + sizeof (wchar_t); - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = ps ?: &state; + data.__outbuf = outbuf; + data.__outbufend = outbuf + sizeof (wchar_t); + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = ps ?: &state; /* A first special case is if S is NULL. This means put PS in the initial state. */ if (s == NULL) { - data.outbuf = (char *) buf; + data.__outbuf = (char *) buf; s = ""; n = 1; } @@ -64,27 +64,27 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) /* Do a normal conversion. */ inbuf = (const unsigned char *) s; - status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc, - &data, &inbuf, inbuf + n, - &dummy, 0); + status = (*__wcsmbs_gconv_fcts.towc->__fct) (__wcsmbs_gconv_fcts.towc, + &data, &inbuf, inbuf + n, + &dummy, 0); /* There must not be any problems with the conversion but illegal input characters. The output buffer must be large enough, otherwise the definition of MB_CUR_MAX is not correct. All the other possible errors also must not happen. */ - assert (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_ILLEGAL_INPUT - || status == GCONV_INCOMPLETE_INPUT - || status == GCONV_FULL_OUTPUT); + assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_ILLEGAL_INPUT + || status == __GCONV_INCOMPLETE_INPUT + || status == __GCONV_FULL_OUTPUT); - if (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_FULL_OUTPUT) + if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_FULL_OUTPUT) { - if (data.outbuf != (unsigned char *) outbuf + if (data.__outbuf != (unsigned char *) outbuf && *(wchar_t *) outbuf == L'\0') { /* The converted character is the NUL character. */ - assert (__mbsinit (data.statep)); + assert (__mbsinit (data.__statep)); result = 0; } else @@ -92,7 +92,7 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) } else { - result = status == GCONV_INCOMPLETE_INPUT ? (size_t) -2 : (size_t) -1; + result = status == __GCONV_INCOMPLETE_INPUT ? (size_t) -2 : (size_t) -1; __set_errno (EILSEQ); } diff --git a/wcsmbs/mbsnrtowcs.c b/wcsmbs/mbsnrtowcs.c index cb2d41c..b58a467 100644 --- a/wcsmbs/mbsnrtowcs.c +++ b/wcsmbs/mbsnrtowcs.c @@ -45,15 +45,16 @@ __mbsnrtowcs (dst, src, nmc, len, ps) mbstate_t *ps; { const unsigned char *srcend; - struct gconv_step_data data; + struct __gconv_step_data data; size_t result = 0; int status; + struct __gconv_step *towc; /* Tell where we want the result. */ - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = ps ?: &state; + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = ps ?: &state; if (nmc == 0) return 0; @@ -62,25 +63,27 @@ __mbsnrtowcs (dst, src, nmc, len, ps) /* Make sure we use the correct function. */ update_conversion_ptrs (); + /* Get the structure with the function pointers. */ + towc = __wcsmbs_gconv_fcts.towc; + /* We have to handle DST == NULL special. */ if (dst == NULL) { wchar_t buf[64]; /* Just an arbitrary size. */ const unsigned char *inbuf = *src; - data.outbufend = (char *) buf + sizeof (buf); + data.__outbufend = (char *) buf + sizeof (buf); do { - data.outbuf = (char *) buf; + data.__outbuf = (char *) buf; - status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc, - &data, &inbuf, srcend, - &result, 0); + status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, &inbuf, + srcend, &result, 0); } - while (status == GCONV_FULL_OUTPUT); + while (status == __GCONV_FULL_OUTPUT); - if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT) - && ((wchar_t *) data.outbuf)[-1] == L'\0') + if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) + && ((wchar_t *) data.__outbuf)[-1] == L'\0') /* Don't count the NUL character in. */ --result; } @@ -89,21 +92,20 @@ __mbsnrtowcs (dst, src, nmc, len, ps) /* This code is based on the safe assumption that all internal multi-byte encodings use the NUL byte only to mark the end of the string. */ - data.outbuf = (unsigned char *) dst; - data.outbufend = data.outbuf + len * sizeof (wchar_t); + data.__outbuf = (unsigned char *) dst; + data.__outbufend = data.__outbuf + len * sizeof (wchar_t); - status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc, - &data, - (const unsigned char **) src, - srcend, &result, 0); + status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, + (const unsigned char **) src, srcend, + &result, 0); /* We have to determine whether the last character converted is the NUL character. */ - if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT) + if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) && ((wchar_t *) dst)[result - 1] == L'\0') { assert (result > 0); - assert (__mbsinit (data.statep)); + assert (__mbsinit (data.__statep)); *src = NULL; --result; } @@ -111,12 +113,13 @@ __mbsnrtowcs (dst, src, nmc, len, ps) /* There must not be any problems with the conversion but illegal input characters. */ - assert (status == GCONV_OK || status != GCONV_EMPTY_INPUT - || status == GCONV_ILLEGAL_INPUT - || status == GCONV_INCOMPLETE_INPUT || status == GCONV_FULL_OUTPUT); + assert (status == __GCONV_OK || status != __GCONV_EMPTY_INPUT + || status == __GCONV_ILLEGAL_INPUT + || status == __GCONV_INCOMPLETE_INPUT + || status == __GCONV_FULL_OUTPUT); - if (status != GCONV_OK && status != GCONV_FULL_OUTPUT - && status != GCONV_EMPTY_INPUT) + if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) { result = (size_t) -1; __set_errno (EILSEQ); diff --git a/wcsmbs/mbsrtowcs.c b/wcsmbs/mbsrtowcs.c index 84b7a38..f69247f 100644 --- a/wcsmbs/mbsrtowcs.c +++ b/wcsmbs/mbsrtowcs.c @@ -41,19 +41,23 @@ __mbsrtowcs (dst, src, len, ps) size_t len; mbstate_t *ps; { - struct gconv_step_data data; + struct __gconv_step_data data; size_t result = 0; int status; + struct __gconv_step *towc; /* Tell where we want the result. */ - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = ps ?: &state; + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = ps ?: &state; /* Make sure we use the correct function. */ update_conversion_ptrs (); + /* Get the structure with the function pointers. */ + towc = __wcsmbs_gconv_fcts.towc; + /* We have to handle DST == NULL special. */ if (dst == NULL) { @@ -61,21 +65,20 @@ __mbsrtowcs (dst, src, len, ps) const unsigned char *inbuf = (const unsigned char *) *src; const unsigned char *srcend = inbuf + strlen (inbuf) + 1; - data.outbufend = (char *) buf + sizeof (buf); + data.__outbufend = (char *) buf + sizeof (buf); do { - data.outbuf = (char *) buf; + data.__outbuf = (char *) buf; - status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc, - &data, &inbuf, srcend, - &result, 0); + status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, &inbuf, + srcend, &result, 0); } - while (status == GCONV_FULL_OUTPUT); + while (status == __GCONV_FULL_OUTPUT); - if (status == GCONV_OK || status == GCONV_EMPTY_INPUT) + if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) { /* There better should be a NUL wide char at the end. */ - assert (((wchar_t *) data.outbuf)[-1] == L'\0'); + assert (((wchar_t *) data.__outbuf)[-1] == L'\0'); /* Don't count the NUL character in. */ --result; } @@ -91,21 +94,20 @@ __mbsrtowcs (dst, src, len, ps) + __strnlen (*src, len * MB_CUR_MAX) + 1); - data.outbuf = (unsigned char *) dst; - data.outbufend = data.outbuf + len * sizeof (wchar_t); + data.__outbuf = (unsigned char *) dst; + data.__outbufend = data.__outbuf + len * sizeof (wchar_t); - status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc, - &data, - (const unsigned char **) src, - srcend, &result, 0); + status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, + (const unsigned char **) src, srcend, + &result, 0); /* We have to determine whether the last character converted is the NUL character. */ - if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT) + if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) && ((wchar_t *) dst)[result - 1] == L'\0') { assert (result > 0); - assert (__mbsinit (data.statep)); + assert (__mbsinit (data.__statep)); *src = NULL; --result; } @@ -113,12 +115,13 @@ __mbsrtowcs (dst, src, len, ps) /* There must not be any problems with the conversion but illegal input characters. */ - assert (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_ILLEGAL_INPUT - || status == GCONV_INCOMPLETE_INPUT || status == GCONV_FULL_OUTPUT); + assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_ILLEGAL_INPUT + || status == __GCONV_INCOMPLETE_INPUT + || status == __GCONV_FULL_OUTPUT); - if (status != GCONV_OK && status != GCONV_FULL_OUTPUT - && status != GCONV_EMPTY_INPUT) + if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) { result = (size_t) -1; __set_errno (EILSEQ); diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h index fddb3d6..8be3f10 100644 --- a/wcsmbs/wchar.h +++ b/wcsmbs/wchar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1998, 1999 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 @@ -22,19 +22,24 @@ */ #ifndef _WCHAR_H -#define _WCHAR_H 1 -#include <features.h> +#ifndef __need_mbstate_t +# define _WCHAR_H 1 +# include <features.h> +#endif +#ifdef _WCHAR_H /* Get FILE definition. */ -#define __need_FILE -#include <stdio.h> +# define __need_FILE +# include <stdio.h> +# include <stdarg.h> /* Get size_t, wchar_t, wint_t and NULL from <stddef.h>. */ -#define __need_size_t -#define __need_wchar_t +# define __need_size_t +# define __need_wchar_t +# define __need_NULL +#endif #define __need_wint_t -#define __need_NULL #include <stddef.h> /* We try to get wint_t from <stddef.h>, but not all GCC versions define it @@ -49,12 +54,24 @@ typedef unsigned int wint_t; #endif +#ifndef __mbstate_t_defined +# define __mbstate_t_defined 1 /* Conversion state information. */ typedef struct { int count; /* Number of bytes needed for the current character. */ wint_t value; /* Value so far. */ -} mbstate_t; +} __mbstate_t; +#endif +#undef __need_mbstate_t + + +/* The rest of the file is only used if used if __need_mbstate_t is not + defined. */ +#ifdef _WCHAR_H + +/* Public type. */ +typedef __mbstate_t mbstate_t; #ifndef WCHAR_MIN /* These constants might also be defined in <inttypes.h>. */ @@ -150,6 +167,12 @@ extern wchar_t *wcschr __P ((__const wchar_t *__wcs, wchar_t __wc)); /* Find the last occurrence of WC in WCS. */ extern wchar_t *wcsrchr __P ((__const wchar_t *__wcs, wchar_t __wc)); +#ifdef __USE_GNU +/* This funciton is similar to `wcschr'. But it returns a pointer to + the closing NUL wide character in case C is not found in S. */ +extern wchar_t *wcschrnul __P ((__const wchar_t *__s, wchar_t __wc)); +#endif + /* Return the length of the initial segmet of WCS which consists entirely of wide characters not in REJECT. */ extern size_t wcscspn __P ((__const wchar_t *__wcs, @@ -204,6 +227,13 @@ extern wchar_t *wmemmove __P ((wchar_t *__s1, __const wchar_t *__s2, /* Set N wide characters of S to C. */ extern wchar_t *wmemset __P ((wchar_t *__s, wchar_t __c, size_t __n)); +#ifdef __USE_GNU +/* Copy N wide characters of SRC to DEST and return pointer to following + wide character. */ +extern wchar_t *wmempcpy __P ((wchar_t *__restrict __s1, + __const wchar_t *__restrict __s2, size_t __n)); +#endif + /* Determine whether C constitutes a valid (one-byte) multibyte character. */ @@ -488,6 +518,137 @@ extern wchar_t *wcpncpy __P ((wchar_t *__dest, __const wchar_t *__src, #endif /* use GNU */ +/* Wide character I/O functions. */ + +/* Select orientation for stream. */ +extern int fwide __P ((FILE *__fp, int __mode)); + + +/* Write formatted output to STREAM. */ +extern int fwprintf __P ((FILE *__restrict __stream, + __const wchar_t *__restrict __format, ...)) + /* __attribute__ ((__format__ (__wprintf__, 2, 3))) */; +/* Write formatted output to stdout. */ +extern int wprintf __P ((__const wchar_t *__restrict __format, ...)) + /* __attribute__ ((__format__ (__wprintf__, 1, 2))) */; +/* Write formatted output of at most N characters to S. */ +extern int swprintf __P ((wchar_t *__restrict __s, size_t __n, + __const wchar_t *__restrict __format, ...)) + /* __attribute__ ((__format__ (__wprintf__, 3, 4))) */; + +/* Write formatted output to S from argument list ARG. */ +extern int vfwprintf __P ((FILE *__restrict __s, + __const wchar_t *__restrict __format, + va_list __arg)) + /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */; +/* Write formatted output to stdout from argument list ARG. */ +extern int vwprintf __P ((__const wchar_t *__restrict __format, + va_list __arg)) + /* __attribute__ ((__format__ (__wprintf__, 1, 0))) */; +/* Write formatted output of at most N character to S from argument + list ARG. */ +extern int vswprintf __P ((wchar_t *__restrict __s, size_t __n, + __const wchar_t *__restrict __format, + va_list __arg)) + /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */; + + +/* Read formatted input from STREAM. */ +extern int fwscanf __P ((FILE *__restrict __stream, + __const wchar_t *__restrict __format, ...)) + /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; +/* Read formatted input from stdin. */ +extern int wscanf __P ((__const wchar_t *__restrict __format, ...)) + /* __attribute__ ((__format__ (__wscanf__, 1, 2))) */; +/* Read formatted input from S. */ +extern int swscanf __P ((__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, ...)) + /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; + +/* Read formatted input from S into argument list ARG. */ +extern int vfwscanf __P ((FILE *__restrict __s, + __const wchar_t *__restrict __format, va_list __arg)) + /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; +/* Read formatted input from stdin into argument list ARG. */ +extern int vwscanf __P ((__const wchar_t *__restrict __format, va_list __arg)) + /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */; +/* Read formatted input from S into argument list ARG. */ +extern int vswscanf __P ((__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, va_list __arg)) + /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; + + +/* Read a character from STREAM. */ +extern wint_t fgetwc __P ((FILE *__stream)); +extern wint_t getwc __P ((FILE *__stream)); + +/* Read a character from stdin. */ +extern wint_t getwchar __P ((void)); + +#ifdef __USE_GNU +/* These are defined to be equivalent to the `char' functions defined + in POSIX.1:1996. */ +extern wint_t getwc_unlocked __P ((FILE *__stream)); +extern wint_t getwchar_unlocked __P ((void)); + +/* This is the wide character version of a GNU extension. */ +extern wint_t fgetwc_unlocked __P ((FILE *__stream)); +#endif /* Use POSIX or MISC. */ + + +/* Write a character to STREAM. */ +extern wint_t fputwc __P ((wint_t __wc, FILE *__stream)); +extern wint_t putwc __P ((wint_t __wc, FILE *__stream)); + +/* Write a character to stdout. */ +extern wint_t putwchar __P ((wint_t __wc)); + +#ifdef __USE_GNU +/* Faster version when locking is not necessary. */ +extern wint_t fputwc_unlocked __P ((wint_t __wc, FILE *__stream)); + +/* These are defined to be equivalent to the `char' functions defined + in POSIX.1:1996. */ +extern wint_t putwc_unlocked __P ((wint_t __wc, FILE *__stream)); +extern wint_t putwchar_unlocked __P ((wint_t __wc)); +#endif + + +/* Get a newline-terminated wide character string of finite length + from STREAM. */ +extern wchar_t *fgetws __P ((wchar_t *__restrict __ws, int __n, + FILE *__restrict __stream)); + +#ifdef __USE_GNU +/* This function does the same as `fgetws' but does not lock the stream. */ +extern wchar_t *fgetws_unlocked __P ((wchar_t *__restrict __ws, int __n, + FILE *__restrict __stream)); +#endif + + +/* Write a string to STREAM. */ +extern int fputws __P ((__const wchar_t *__restrict __ws, + FILE *__restrict __stream)); + +#ifdef __USE_GNU +/* This function does the same as `fputws' but does not lock the stream. */ +extern int fputws_unlocked __P ((__const wchar_t *__restrict __ws, + FILE *__restrict __stream)); +#endif + + +/* Push a character back onto the input buffer of STREAM. */ +extern wint_t ungetwc __P ((wint_t __wc, FILE *__stream)); + + +/* Format TP into S according to FORMAT. + Write no more than MAXSIZE wide characters and return the number + of wide characters written, or 0 if it would exceed MAXSIZE. */ +extern size_t wcsftime __P ((wchar_t *__restrict __s, size_t __maxsize, + __const wchar_t *__restrict __format, + __const struct tm *__restrict __tp)); + + /* The X/Open standard demands that most of the functions defined in the <wctype.h> header must also appear here. This is probably because some X/Open members wrote their implementation before the @@ -501,4 +662,6 @@ extern wchar_t *wcpncpy __P ((wchar_t *__dest, __const wchar_t *__src, __END_DECLS +#endif /* _WCHAR_H defined */ + #endif /* wchar.h */ diff --git a/wcsmbs/wcrtomb.c b/wcsmbs/wcrtomb.c index b546c7a..91daf4d 100644 --- a/wcsmbs/wcrtomb.c +++ b/wcsmbs/wcrtomb.c @@ -37,24 +37,24 @@ size_t __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) { char buf[MB_CUR_MAX]; - struct gconv_step_data data; + struct __gconv_step_data data; int status; size_t result; size_t dummy; /* Tell where we want the result. */ - data.outbuf = s; - data.outbufend = s + MB_CUR_MAX; - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = ps ?: &state; + data.__outbuf = s; + data.__outbufend = s + MB_CUR_MAX; + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = ps ?: &state; /* A first special case is if S is NULL. This means put PS in the initial state. */ if (s == NULL) { - data.outbuf = buf; + data.__outbuf = buf; wc = L'\0'; } @@ -66,35 +66,36 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) by a NUL byte. */ if (wc == L'\0') { - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, - &data, NULL, NULL, &dummy, 1); + status = (*__wcsmbs_gconv_fcts.tomb->__fct) (__wcsmbs_gconv_fcts.tomb, + &data, NULL, NULL, + &dummy, 1); - if (status == GCONV_OK || status == GCONV_EMPTY_INPUT) - *data.outbuf++ = '\0'; + if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) + *data.__outbuf++ = '\0'; } else { /* Do a normal conversion. */ const unsigned char *inbuf = (const unsigned char *) &wc; - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, - &data, &inbuf, - inbuf + sizeof (wchar_t), - &dummy, 0); + status = (*__wcsmbs_gconv_fcts.tomb->__fct) (__wcsmbs_gconv_fcts.tomb, + &data, &inbuf, + inbuf + sizeof (wchar_t), + &dummy, 0); } /* There must not be any problems with the conversion but illegal input characters. The output buffer must be large enough, otherwise the definition of MB_CUR_MAX is not correct. All the other possible errors also must not happen. */ - assert (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_ILLEGAL_INPUT - || status == GCONV_INCOMPLETE_INPUT - || status == GCONV_FULL_OUTPUT); - - if (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_FULL_OUTPUT) - result = data.outbuf - (unsigned char *) s; + assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_ILLEGAL_INPUT + || status == __GCONV_INCOMPLETE_INPUT + || status == __GCONV_FULL_OUTPUT); + + if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_FULL_OUTPUT) + result = data.__outbuf - (unsigned char *) s; else { result = (size_t) -1; diff --git a/wcsmbs/wcschrnul.c b/wcsmbs/wcschrnul.c new file mode 100644 index 0000000..2ea9b2c --- /dev/null +++ b/wcsmbs/wcschrnul.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1995, 1996, 1999 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 + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <wchar.h> + + +/* Find the first occurrence of WC in WCS. */ +wchar_t * +__wcschrnul (wcs, wc) + register const wchar_t *wcs; + register const wchar_t wc; +{ + while (*wcs != L'\0') + if (*wcs == wc) + break; + else + ++wcs; + + return wcs; +} +weak_alias (__wcschrnul, wcschrnul) diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c index b16aa6c..b02acad 100644 --- a/wcsmbs/wcsmbsload.c +++ b/wcsmbs/wcsmbsload.c @@ -36,64 +36,76 @@ const struct locale_data *__wcsmbs_last_locale = &_nl_C_LC_CTYPE; /* These are the descriptions for the default conversion functions. */ -static struct gconv_step to_wc = +static struct __gconv_step to_wc = { - shlib_handle: NULL, - modname: NULL, - counter: INT_MAX, - from_name: "ANSI_X3.4-1968//", - to_name: "INTERNAL", - fct: __gconv_transform_ascii_internal, - init_fct: NULL, - end_fct: NULL, - min_needed_from: 1, - max_needed_from: 1, - min_needed_to: 4, - max_needed_to: 4, - stateful: 0, - data: NULL + .__shlib_handle = NULL, + .__modname = NULL, + .__counter = INT_MAX, + .__from_name = "ANSI_X3.4-1968//", + .__to_name = "INTERNAL", + .__fct = __gconv_transform_ascii_internal, + .__init_fct = NULL, + .__end_fct = NULL, + .__min_needed_from = 1, + .__max_needed_from = 1, + .__min_needed_to = 4, + .__max_needed_to = 4, + .__stateful = 0, + .__data = NULL }; -static struct gconv_step to_mb = +static struct __gconv_step to_mb = { - shlib_handle: NULL, - modname: NULL, - counter: INT_MAX, - from_name: "INTERNAL", - to_name: "ANSI_X3.4-1968//", - fct: __gconv_transform_internal_ascii, - init_fct: NULL, - end_fct: NULL, - min_needed_from: 4, - max_needed_from: 4, - min_needed_to: 1, - max_needed_to: 1, - stateful: 0, - data: NULL + .__shlib_handle = NULL, + .__modname = NULL, + .__counter = INT_MAX, + .__from_name = "INTERNAL", + .__to_name = "ANSI_X3.4-1968//", + .__fct = __gconv_transform_internal_ascii, + .__init_fct = NULL, + .__end_fct = NULL, + .__min_needed_from = 4, + .__max_needed_from = 4, + .__min_needed_to = 1, + .__max_needed_to = 1, + .__stateful = 0, + .__data = NULL }; /* For the default locale we only have to handle ANSI_X3.4-1968. */ struct gconv_fcts __wcsmbs_gconv_fcts = { - towc: &to_wc, - tomb: &to_mb + .towc = &to_wc, + .tomb = &to_mb }; -static inline struct gconv_step * +static inline struct __gconv_step * getfct (const char *to, const char *from) { size_t nsteps; - struct gconv_step *result; + struct __gconv_step *result; + size_t nstateful; + size_t cnt; - if (__gconv_find_transform (to, from, &result, &nsteps) != GCONV_OK) + if (__gconv_find_transform (to, from, &result, &nsteps) != __GCONV_OK) /* Loading the conversion step is not possible. */ return NULL; - /* We must only have one step in this conversion. */ - if (nsteps != 1) - return NULL; + /* Count the number of stateful conversions. Since we will only + have one 'mbstate_t' object available we can only deal with one + stateful conversion. */ + nstateful = 0; + for (cnt = 0; cnt < nsteps; ++cnt) + if (result[cnt].__stateful) + ++nstateful; + if (nstateful > 1) + { + /* We cannot handle this case. */ + __gconv_close_transform (result, nsteps); + result = NULL; + } return result; } @@ -148,14 +160,15 @@ getfct (const char *to, const char *from) }) +/* We must modify global data. */ +__libc_lock_define_initialized (static, lock) + + /* Load conversion functions for the currently selected locale. */ void internal_function __wcsmbs_load_conv (const struct locale_data *new_category) { - /* We must modify global data. */ - __libc_lock_define_initialized (static, lock) - /* Acquire the lock. */ __libc_lock_lock (lock); @@ -174,6 +187,12 @@ __wcsmbs_load_conv (const struct locale_data *new_category) /* We must find the real functions. */ const char *charset_name; const char *complete_name; + struct __gconv_step *new_towc; + struct __gconv_step *new_tomb; + + /* Free the old conversions. */ + __gconv_close_transform (__wcsmbs_gconv_fcts.tomb, 1); + __gconv_close_transform (__wcsmbs_gconv_fcts.towc, 1); /* Get name of charset of the locale. We first examine whether we have a character set mentioned in the locale @@ -188,15 +207,23 @@ __wcsmbs_load_conv (const struct locale_data *new_category) complete lookup. */ complete_name = norm_add_slashes (charset_name); - __wcsmbs_gconv_fcts.tomb = getfct (complete_name, "INTERNAL"); - __wcsmbs_gconv_fcts.towc = getfct ("INTERNAL", complete_name); + new_towc = getfct ("INTERNAL", complete_name); + if (new_towc != NULL) + new_tomb = getfct (complete_name, "INTERNAL"); /* If any of the conversion functions is not available we don't use any since this would mean we cannot convert back and forth.*/ - if (__wcsmbs_gconv_fcts.towc == NULL - || __wcsmbs_gconv_fcts.tomb == NULL) - goto failed; + if (new_towc == NULL || new_tomb == NULL) + { + if (new_towc != NULL) + __gconv_close_transform (new_towc, 1); + + goto failed; + } + + __wcsmbs_gconv_fcts.tomb = new_tomb; + __wcsmbs_gconv_fcts.towc = new_towc; } /* Set last-used variable for current locale. */ @@ -205,3 +232,24 @@ __wcsmbs_load_conv (const struct locale_data *new_category) __libc_lock_unlock (lock); } + + +/* Clone the current conversion function set. */ +void +internal_function +__wcsmbs_clone_conv (struct gconv_fcts *copy) +{ + /* Make sure the data structures remain the same until we are finished. */ + __libc_lock_lock (lock); + + /* Copy the data. */ + *copy = __wcsmbs_gconv_fcts; + + /* Now increment the usage counters. */ + if (copy->towc->__shlib_handle != NULL) + ++copy->towc->__counter; + if (copy->tomb->__shlib_handle != NULL) + ++copy->tomb->__counter; + + __libc_lock_unlock (lock); +} diff --git a/wcsmbs/wcsmbsload.h b/wcsmbs/wcsmbsload.h index df0ba7b..a3652d2 100644 --- a/wcsmbs/wcsmbsload.h +++ b/wcsmbs/wcsmbsload.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1998 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -25,8 +25,8 @@ /* Contains pointers to the used functions in the `gconv' modules. */ struct gconv_fcts { - struct gconv_step *towc; - struct gconv_step *tomb; + struct __gconv_step *towc; + struct __gconv_step *tomb; }; /* Set of currently active conversion functions. */ @@ -41,6 +41,10 @@ extern const struct locale_data *__wcsmbs_last_locale; extern void __wcsmbs_load_conv (const struct locale_data *new_category) internal_function; +/* Clone the current `__wcsmbs_load_conv' value. */ +extern void __wcsmbs_clone_conv (struct gconv_fcts *copy) + internal_function; + /* Check whether the LC_CTYPE locale changed since the last call. Update the pointers appropriately. */ diff --git a/wcsmbs/wcsnrtombs.c b/wcsmbs/wcsnrtombs.c index f93d404..fb86992 100644 --- a/wcsmbs/wcsnrtombs.c +++ b/wcsmbs/wcsnrtombs.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -43,16 +43,17 @@ __wcsnrtombs (dst, src, nwc, len, ps) size_t len; mbstate_t *ps; { - struct gconv_step_data data; + struct __gconv_step_data data; const wchar_t *srcend; int status; size_t result; + struct __gconv_step *tomb; /* Tell where we want the result. */ - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = ps ?: &state; + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = ps ?: &state; if (nwc == 0) return 0; @@ -61,6 +62,9 @@ __wcsnrtombs (dst, src, nwc, len, ps) /* Make sure we use the correct function. */ update_conversion_ptrs (); + /* Get the structure with the function pointers. */ + tomb = __wcsmbs_gconv_fcts.tomb; + /* We have to handle DST == NULL special. */ if (dst == NULL) { @@ -69,25 +73,23 @@ __wcsnrtombs (dst, src, nwc, len, ps) size_t dummy; result = 0; - data.outbufend = buf + sizeof (buf); + data.__outbufend = buf + sizeof (buf); do { - data.outbuf = buf; + data.__outbuf = buf; - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, - &data, - (const unsigned char **) &inbuf, - (const unsigned char *) srcend, - &dummy, 0); + status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, + (const unsigned char **) &inbuf, + (const unsigned char *) srcend, &dummy, 0); /* Count the number of bytes. */ - result += data.outbuf - buf; + result += data.__outbuf - buf; } - while (status == GCONV_FULL_OUTPUT); + while (status == __GCONV_FULL_OUTPUT); - if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT) - && data.outbuf[-1] == '\0') + if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) + && data.__outbuf[-1] == '\0') /* Don't count the NUL character in. */ --result; } @@ -98,25 +100,23 @@ __wcsnrtombs (dst, src, nwc, len, ps) of the string. */ size_t dummy; - data.outbuf = dst; - data.outbufend = dst + len; + data.__outbuf = dst; + data.__outbufend = dst + len; - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, - &data, - (const unsigned char **) src, - (const unsigned char *) srcend, - &dummy, 0); + status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, + (const unsigned char **) src, + (const unsigned char *) srcend, &dummy, 0); /* Count the number of bytes. */ - result = data.outbuf - (unsigned char *) dst; + result = data.__outbuf - (unsigned char *) dst; /* We have to determine whether the last character converted is the NUL character. */ - if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT) - && data.outbuf[-1] == '\0') + if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) + && data.__outbuf[-1] == '\0') { - assert (data.outbuf != (unsigned char *) dst); - assert (__mbsinit (data.statep)); + assert (data.__outbuf != (unsigned char *) dst); + assert (__mbsinit (data.__statep)); *src = NULL; --result; } @@ -124,12 +124,13 @@ __wcsnrtombs (dst, src, nwc, len, ps) /* There must not be any problems with the conversion but illegal input characters. */ - assert (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_ILLEGAL_INPUT - || status == GCONV_INCOMPLETE_INPUT || status == GCONV_FULL_OUTPUT); + assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_ILLEGAL_INPUT + || status == __GCONV_INCOMPLETE_INPUT + || status == __GCONV_FULL_OUTPUT); - if (status != GCONV_OK && status != GCONV_FULL_OUTPUT - && status != GCONV_EMPTY_INPUT) + if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) { result = (size_t) -1; __set_errno (EILSEQ); diff --git a/wcsmbs/wcsrtombs.c b/wcsmbs/wcsrtombs.c index 0257599..5ab8481 100644 --- a/wcsmbs/wcsrtombs.c +++ b/wcsmbs/wcsrtombs.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -40,19 +40,23 @@ __wcsrtombs (dst, src, len, ps) size_t len; mbstate_t *ps; { - struct gconv_step_data data; + struct __gconv_step_data data; int status; size_t result; + struct __gconv_step *tomb; /* Tell where we want the result. */ - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = ps ?: &state; + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = ps ?: &state; /* Make sure we use the correct function. */ update_conversion_ptrs (); + /* Get the structure with the function pointers. */ + tomb = __wcsmbs_gconv_fcts.tomb; + /* We have to handle DST == NULL special. */ if (dst == NULL) { @@ -62,27 +66,25 @@ __wcsrtombs (dst, src, len, ps) size_t dummy; result = 0; - data.outbufend = buf + sizeof (buf); + data.__outbufend = buf + sizeof (buf); do { - data.outbuf = buf; + data.__outbuf = buf; - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, - &data, - (const unsigned char **) &inbuf, - (const unsigned char *) srcend, - &dummy, 0); + status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, + (const unsigned char **) &inbuf, + (const unsigned char *) srcend, &dummy, 0); /* Count the number of bytes. */ - result += data.outbuf - buf; + result += data.__outbuf - buf; } - while (status == GCONV_FULL_OUTPUT); + while (status == __GCONV_FULL_OUTPUT); - if (status == GCONV_OK || status == GCONV_EMPTY_INPUT) + if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) { /* There better should be a NUL byte at the end. */ - assert (data.outbuf[-1] == '\0'); + assert (data.__outbuf[-1] == '\0'); /* Don't count the NUL character in. */ --result; } @@ -95,26 +97,24 @@ __wcsrtombs (dst, src, len, ps) const wchar_t *srcend = *src + __wcsnlen (*src, len * MB_CUR_MAX) + 1; size_t dummy; - data.outbuf = dst; - data.outbufend = dst + len; + data.__outbuf = dst; + data.__outbufend = dst + len; - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, - &data, - (const unsigned char **) src, - (const unsigned char *) srcend, - &dummy, 0); + status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, + (const unsigned char **) src, + (const unsigned char *) srcend, &dummy, 0); /* Count the number of bytes. */ - result = data.outbuf - (unsigned char *) dst; + result = data.__outbuf - (unsigned char *) dst; /* We have to determine whether the last character converted is the NUL character. */ - if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_FULL_OUTPUT) - && data.outbuf[-1] == '\0') + if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_FULL_OUTPUT) + && data.__outbuf[-1] == '\0') { - assert (data.outbuf != (unsigned char *) dst); - assert (__mbsinit (data.statep)); + assert (data.__outbuf != (unsigned char *) dst); + assert (__mbsinit (data.__statep)); *src = NULL; --result; } @@ -122,12 +122,13 @@ __wcsrtombs (dst, src, len, ps) /* There must not be any problems with the conversion but illegal input characters. */ - assert (status == GCONV_OK || status == GCONV_EMPTY_INPUT - || status == GCONV_ILLEGAL_INPUT - || status == GCONV_INCOMPLETE_INPUT || status == GCONV_FULL_OUTPUT); + assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT + || status == __GCONV_ILLEGAL_INPUT + || status == __GCONV_INCOMPLETE_INPUT + || status == __GCONV_FULL_OUTPUT); - if (status != GCONV_OK && status != GCONV_FULL_OUTPUT - && status != GCONV_EMPTY_INPUT) + if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) { result = (size_t) -1; __set_errno (EILSEQ); diff --git a/wcsmbs/wctob.c b/wcsmbs/wctob.c index 0fba46a..565cbea 100644 --- a/wcsmbs/wctob.c +++ b/wcsmbs/wctob.c @@ -29,19 +29,19 @@ wctob (c) wint_t c; { char buf[MB_LEN_MAX]; - struct gconv_step_data data; + struct __gconv_step_data data; wchar_t inbuf[1]; wchar_t *inptr = inbuf; size_t dummy; int status; /* Tell where we want the result. */ - data.outbuf = buf; - data.outbufend = buf + MB_LEN_MAX; - data.invocation_counter = 0; - data.internal_use = 1; - data.is_last = 1; - data.statep = &data.__state; + data.__outbuf = buf; + data.__outbufend = buf + MB_LEN_MAX; + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__is_last = 1; + data.__statep = &data.__state; /* Make sure we start in the initial state. */ memset (&data.__state, '\0', sizeof (mbstate_t)); @@ -52,14 +52,14 @@ wctob (c) /* Create the input string. */ inbuf[0] = c; - status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, &data, - (const unsigned char **) &inptr, - (const unsigned char *) &inbuf[1], - &dummy, 0); + status = (*__wcsmbs_gconv_fcts.tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, + (const unsigned char **) &inptr, + (const unsigned char *) &inbuf[1], + &dummy, 0); /* The conversion failed or the output is too long. */ - if ((status != GCONV_OK && status != GCONV_FULL_OUTPUT - && status != GCONV_EMPTY_INPUT) - || data.outbuf != (unsigned char *) (buf + 1)) + if ((status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) + || data.__outbuf != (unsigned char *) (buf + 1)) return EOF; return buf[0]; diff --git a/wcsmbs/wmemcpy.c b/wcsmbs/wmemcpy.c index 6133a5a..8530a71 100644 --- a/wcsmbs/wmemcpy.c +++ b/wcsmbs/wmemcpy.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -22,10 +22,11 @@ wchar_t * -wmemcpy (s1, s2, n) +__wmemcpy (s1, s2, n) wchar_t *s1; const wchar_t *s2; size_t n; { return (wchar_t *) memcpy ((char *) s1, (char *) s2, n * sizeof (wchar_t)); } +weak_alias (__wmemcpy, wmemcpy) diff --git a/wcsmbs/wmemmove.c b/wcsmbs/wmemmove.c index fc4cead..5d41601 100644 --- a/wcsmbs/wmemmove.c +++ b/wcsmbs/wmemmove.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu> @@ -22,10 +22,11 @@ wchar_t * -wmemmove (s1, s2, n) +__wmemmove (s1, s2, n) wchar_t *s1; const wchar_t *s2; size_t n; { return (wchar_t *) memmove ((char *) s1, (char *) s2, n * sizeof (wchar_t)); } +weak_alias (__wmemmove, wmemmove) diff --git a/wcsmbs/wmempcpy.c b/wcsmbs/wmempcpy.c new file mode 100644 index 0000000..46cb958 --- /dev/null +++ b/wcsmbs/wmempcpy.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <wchar.h> +#include <string.h> + + +wchar_t * +__wmempcpy (s1, s2, n) + wchar_t *s1; + const wchar_t *s2; + size_t n; +{ + return (wchar_t *) __mempcpy ((char *) s1, (char *) s2, + n * sizeof (wchar_t)); +} +weak_alias (__wmempcpy, wmempcpy) |