diff options
author | Ulrich Drepper <drepper@redhat.com> | 2001-07-27 08:29:06 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2001-07-27 08:29:06 +0000 |
commit | 129d706d77587e4d6627cc1ebef9be0f7cbc65f0 (patch) | |
tree | 219bd622277bf2262d16cd4fd0400bd1ef7aea7e /libio/fileops.c | |
parent | 6a904bbfc610f98ee2f467844434117a7bca5982 (diff) | |
download | glibc-129d706d77587e4d6627cc1ebef9be0f7cbc65f0.tar glibc-129d706d77587e4d6627cc1ebef9be0f7cbc65f0.tar.gz glibc-129d706d77587e4d6627cc1ebef9be0f7cbc65f0.tar.bz2 glibc-129d706d77587e4d6627cc1ebef9be0f7cbc65f0.zip |
Update.
* libio/fileops.c (_IO_new_file_fopen): Correctly locate ccs=
substring. Don't handle ccs= if no descriptor was allocated.
Normalize codeset name before calling __wcsmbs_named_conv.
Initialize transliteration elements. Free step data structure.
* libio/iofclose.c (_IO_new_fclose): Correct freeing of the step data.
* libio/iofwide.c (__libio_translit): Renamed from libio_translit
and made public. Various little cleanup changes.
* wcsmbs/wcsmbsload.h (struct gconv_fcts): Add towc_nsteps and
tomb_nsteps member.
* wcsmbs/wcsmbsload.c: Add some casts to avoid warnings.
(__wcsmbs_gconv_fcts): Initialize towc_nsteps and tomb_nsteps member.
(getfct): Take additional parameter with pointer to variable where the
number of steps is stored in. Disable code which allows to use more
than one step for now. Adjust all callers.
(free_mem): New function. Frees data associated with currently
selected converters.
Diffstat (limited to 'libio/fileops.c')
-rw-r--r-- | libio/fileops.c | 120 |
1 files changed, 86 insertions, 34 deletions
diff --git a/libio/fileops.c b/libio/fileops.c index 03f71d71c0..3947fa8d6c 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -31,6 +31,7 @@ # define _POSIX_SOURCE #endif #include "libioP.h" +#include <assert.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> @@ -42,6 +43,8 @@ #endif #if _LIBC # include "../wcsmbs/wcsmbsload.h" +# include "../iconv/gconv_charset.h" +# include "../iconv/gconv_int.h" # include <shlib-compat.h> #endif #ifndef errno @@ -74,6 +77,12 @@ extern int errno; # define _IO_new_file_xsputn _IO_file_xsputn #endif + +#ifdef _LIBC +extern struct __gconv_trans_data __libio_translit; +#endif + + /* An fstream can be in at most one of put mode, get mode, or putback mode. Putback mode is a variant of get mode. @@ -238,8 +247,9 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) int oprot = 0666; int i; _IO_FILE *result; -#if _LIBC +#ifdef _LIBC const char *cs; + const char *last_recognized; #endif if (_IO_file_is_open (fp)) @@ -264,6 +274,9 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) __set_errno (EINVAL); return NULL; } +#ifdef _LIBC + last_recognized = mode; +#endif for (i = 1; i < 4; ++i) { switch (*++mode) @@ -273,11 +286,20 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) case '+': omode = O_RDWR; read_write &= _IO_IS_APPENDING; +#ifdef _LIBC + last_recognized = mode; +#endif continue; case 'x': oflags |= O_EXCL; +#ifdef _LIBC + last_recognized = mode; +#endif continue; case 'b': +#ifdef _LIBC + last_recognized = mode; +#endif default: /* Ignore. */ continue; @@ -289,48 +311,78 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) is32not64); -#if _LIBC - /* Test whether the mode string specifies the conversion. */ - cs = strstr (mode, ",ccs="); - if (cs != NULL) +#ifdef _LIBC + if (result != NULL) { - /* Yep. Load the appropriate conversions and set the orientation - to wide. */ - struct gconv_fcts fcts; - struct _IO_codecvt *cc; + /* Test whether the mode string specifies the conversion. */ + cs = strstr (last_recognized + 1, ",ccs="); + if (cs != NULL) + { + /* Yep. Load the appropriate conversions and set the orientation + to wide. */ + struct gconv_fcts fcts; + struct _IO_codecvt *cc; + char *endp = __strchrnul (cs + 5, ','); + char ccs[endp - (cs + 5) + 3]; + + *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0'; + strip (ccs, ccs); + + if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0' + ? upstr (ccs, cs + 5) : ccs) != 0) + { + /* Something went wrong, we cannot load the conversion modules. + This means we cannot proceed since the user explicitly asked + for these. */ + __set_errno (EINVAL); + return NULL; + } - if (! _IO_CHECK_WIDE (fp) || __wcsmbs_named_conv (&fcts, cs + 5) != 0) - { - /* Something went wrong, we cannot load the conversion modules. - This means we cannot proceed since the user explicitly asked - for these. */ - _IO_new_fclose (result); - return NULL; - } + assert (fcts.towc_nsteps == 1); + assert (fcts.tomb_nsteps == 1); + + 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)); + + cc = fp->_codecvt = &fp->_wide_data->_codecvt; - cc = fp->_codecvt = &fp->_wide_data->_codecvt; + /* The functions are always the same. */ + *cc = __libio_codecvt; - /* The functions are always the same. */ - *cc = __libio_codecvt; + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; - 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].__flags = __GCONV_IS_LAST; + cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state; - cc->__cd_in.__cd.__data[0].__invocation_counter = 0; - cc->__cd_in.__cd.__data[0].__internal_use = 1; - cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; - cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state; + /* XXX For now no transliteration. */ + cc->__cd_in.__cd.__data[0].__trans = NULL; - cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */ - cc->__cd_out.__cd.__steps = fcts.tomb; + cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps; + 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].__flags = __GCONV_IS_LAST; - cc->__cd_out.__cd.__data[0].__statep = &result->_wide_data->_IO_state; + cc->__cd_out.__cd.__data[0].__invocation_counter = 0; + cc->__cd_out.__cd.__data[0].__internal_use = 1; + cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_out.__cd.__data[0].__statep = + &result->_wide_data->_IO_state; - /* Set the mode now. */ - result->_mode = 1; + /* And now the transliteration. */ + cc->__cd_out.__cd.__data[0].__trans = &__libio_translit; + + /* Set the mode now. */ + result->_mode = 1; + + /* We don't need the step data structure anymore. */ + __gconv_release_cache (fcts.towc, fcts.towc_nsteps); + __gconv_release_cache (fcts.tomb, fcts.tomb_nsteps); + } } #endif /* GNU libc */ |