diff options
Diffstat (limited to 'libc/misc/wchar')
| -rw-r--r-- | libc/misc/wchar/Makefile.in | 20 | ||||
| -rw-r--r-- | libc/misc/wchar/wchar.c | 356 |
2 files changed, 104 insertions, 272 deletions
diff --git a/libc/misc/wchar/Makefile.in b/libc/misc/wchar/Makefile.in index db01f97cc..32a8dbc62 100644 --- a/libc/misc/wchar/Makefile.in +++ b/libc/misc/wchar/Makefile.in @@ -1,6 +1,6 @@ # Makefile for uClibc # -# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # @@ -16,24 +16,24 @@ # wcsftime # +subdirs += libc/misc/wchar + # multi source wchar.c -CSRC := btowc.c wctob.c mbsinit.c mbrlen.c mbrtowc.c wcrtomb.c mbsrtowcs.c \ +CSRC-y := btowc.c wctob.c mbsinit.c mbrlen.c mbrtowc.c wcrtomb.c mbsrtowcs.c \ wcsrtombs.c _wchar_utf8sntowcs.c _wchar_wcsntoutf8s.c \ mbsnrtowcs.c wcsnrtombs.c wcwidth.c wcswidth.c -ifeq ($(UCLIBC_HAS_LOCALE),y) -CSRC += iconv.c -endif +CSRC-$(UCLIBC_HAS_LOCALE) += iconv.c MISC_WCHAR_DIR := $(top_srcdir)libc/misc/wchar MISC_WCHAR_OUT := $(top_builddir)libc/misc/wchar -MISC_WCHAR_SRC := $(patsubst %.c,$(MISC_WCHAR_DIR)/%.c,$(CSRC)) -MISC_WCHAR_OBJ := $(patsubst %.c,$(MISC_WCHAR_OUT)/%.o,$(CSRC)) +MISC_WCHAR_SRC := $(patsubst %.c,$(MISC_WCHAR_DIR)/%.c,$(CSRC-y)) +MISC_WCHAR_OBJ := $(patsubst %.c,$(MISC_WCHAR_OUT)/%.o,$(CSRC-y)) libc-$(UCLIBC_HAS_WCHAR) += $(MISC_WCHAR_OBJ) -objclean-y += misc_wchar_objclean +objclean-y += CLEAN_libc/misc/wchar -misc_wchar_objclean: - $(RM) $(MISC_WCHAR_OUT)/*.{o,os} +CLEAN_libc/misc/wchar: + $(do_rm) $(addprefix $(MISC_WCHAR_OUT)/*., o os) diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c index 567be8585..966f78d19 100644 --- a/libc/misc/wchar/wchar.c +++ b/libc/misc/wchar/wchar.c @@ -12,8 +12,8 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. */ /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! @@ -97,7 +97,7 @@ * * Manuel */ - +#ifdef _LIBC #include <errno.h> #include <stddef.h> #include <limits.h> @@ -119,7 +119,7 @@ #endif #endif /* __UCLIBC_MJN3_ONLY__ */ -#define ENCODING ((__UCLIBC_CURLOCALE_DATA).encoding) +#define ENCODING (__UCLIBC_CURLOCALE->encoding) #define Cc2wc_IDX_SHIFT __LOCALE_DATA_Cc2wc_IDX_SHIFT #define Cc2wc_ROW_LEN __LOCALE_DATA_Cc2wc_ROW_LEN @@ -170,13 +170,11 @@ extern size_t _wchar_utf8sntowcs(wchar_t *__restrict pwc, size_t wn, extern size_t _wchar_wcsntoutf8s(char *__restrict s, size_t n, const wchar_t **__restrict src, size_t wn) attribute_hidden; - +#endif /**********************************************************************/ #ifdef L_btowc -libc_hidden_proto(mbrtowc) -libc_hidden_proto(btowc) wint_t btowc(int c) { #ifdef __CTYPE_HAS_8_BIT_LOCALES @@ -188,24 +186,24 @@ wint_t btowc(int c) if (c != EOF) { *buf = (unsigned char) c; mbstate.__mask = 0; /* Initialize the mbstate. */ - if (mbrtowc(&wc, buf, 1, &mbstate) <= 1) { + if (mbrtowc(&wc, (char*) buf, 1, &mbstate) <= 1) { return wc; } } return WEOF; -#else /* __CTYPE_HAS_8_BIT_LOCALES */ +#else /* !__CTYPE_HAS_8_BIT_LOCALES */ #ifdef __UCLIBC_HAS_LOCALE__ assert((ENCODING == __ctype_encoding_7_bit) || (ENCODING == __ctype_encoding_utf8)); -#endif /* __UCLIBC_HAS_LOCALE__ */ +#endif /* If we don't have 8-bit locale support, then this is trivial since * anything outside of 0-0x7f is illegal in C/POSIX and UTF-8 locales. */ return (((unsigned int)c) < 0x80) ? c : WEOF; -#endif /* __CTYPE_HAS_8_BIT_LOCALES */ +#endif /* !__CTYPE_HAS_8_BIT_LOCALES */ } libc_hidden_def(btowc) @@ -215,7 +213,6 @@ libc_hidden_def(btowc) /* Note: We completely ignore ps in all currently supported conversions. */ -libc_hidden_proto(wcrtomb) int wctob(wint_t c) { @@ -223,7 +220,7 @@ int wctob(wint_t c) unsigned char buf[MB_LEN_MAX]; - return (wcrtomb(buf, c, NULL) == 1) ? *buf : EOF; + return (wcrtomb((char*) buf, c, NULL) == 1) ? *buf : EOF; #else /* __CTYPE_HAS_8_BIT_LOCALES */ @@ -246,7 +243,6 @@ int wctob(wint_t c) /**********************************************************************/ #ifdef L_mbsinit -libc_hidden_proto(mbsinit) int mbsinit(const mbstate_t *ps) { return !ps || !ps->__mask; @@ -257,9 +253,7 @@ libc_hidden_def(mbsinit) /**********************************************************************/ #ifdef L_mbrlen -libc_hidden_proto(mbrtowc) -libc_hidden_proto(mbrlen) size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps) { static mbstate_t mbstate; /* Rely on bss 0-init. */ @@ -272,9 +266,7 @@ libc_hidden_def(mbrlen) /**********************************************************************/ #ifdef L_mbrtowc -libc_hidden_proto(mbsnrtowcs) -libc_hidden_proto(mbrtowc) size_t mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, size_t n, mbstate_t *__restrict ps) { @@ -294,7 +286,9 @@ size_t mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, s = empty_string; n = 1; } else if (*s == '\0') { - /* According to the ISO C 89 standard this is the expected behaviour. */ + if (pwc) + *pwc = '\0'; + /* According to the ISO C 89 standard this is the expected behaviour. */ return 0; } else if (!n) { /* TODO: change error code? */ @@ -338,12 +332,10 @@ libc_hidden_def(mbrtowc) /**********************************************************************/ #ifdef L_wcrtomb -libc_hidden_proto(wcsnrtombs) /* Note: We completely ignore ps in all currently supported conversions. */ /* TODO: Check for valid state anyway? */ -libc_hidden_proto(wcrtomb) size_t wcrtomb(register char *__restrict s, wchar_t wc, mbstate_t *__restrict ps) { @@ -372,9 +364,7 @@ libc_hidden_def(wcrtomb) /**********************************************************************/ #ifdef L_mbsrtowcs -libc_hidden_proto(mbsnrtowcs) -libc_hidden_proto(mbsrtowcs) size_t mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src, size_t len, mbstate_t *__restrict ps) { @@ -393,9 +383,7 @@ libc_hidden_def(mbsrtowcs) * TODO: Check for valid state anyway? */ -libc_hidden_proto(wcsnrtombs) -libc_hidden_proto(wcsrtombs) size_t wcsrtombs(char *__restrict dst, const wchar_t **__restrict src, size_t len, mbstate_t *__restrict ps) { @@ -488,7 +476,8 @@ size_t attribute_hidden _wchar_utf8sntowcs(wchar_t *__restrict pwc, size_t wn, #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Fix range for 16 bit wchar_t case. #endif - if ( ((unsigned char)(s[-1] - 0xc0)) < (0xfe - 0xc0) ) { + if (( ((unsigned char)(s[-1] - 0xc0)) < (0xfe - 0xc0) ) && + (((unsigned char)s[-1] != 0xc0 ) && ((unsigned char)s[-1] != 0xc1 ))) { goto START; } BAD: @@ -613,7 +602,7 @@ size_t attribute_hidden _wchar_wcsntoutf8s(char *__restrict s, size_t n, if (!s) { n = SIZE_MAX; } - s = buf; + s = buf; store = 0; } @@ -699,7 +688,6 @@ size_t attribute_hidden _wchar_wcsntoutf8s(char *__restrict s, size_t n, /* WARNING: We treat len as SIZE_MAX when dst is NULL! */ -libc_hidden_proto(mbsnrtowcs) size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, size_t NMC, size_t len, mbstate_t *__restrict ps) { @@ -751,8 +739,8 @@ size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, while (count) { if ((wc = ((unsigned char)(*s))) >= 0x80) { /* Non-ASCII... */ wc -= 0x80; - wc = __UCLIBC_CURLOCALE_DATA.tbl8c2wc[ - (__UCLIBC_CURLOCALE_DATA.idx8c2wc[wc >> Cc2wc_IDX_SHIFT] + wc = __UCLIBC_CURLOCALE->tbl8c2wc[ + (__UCLIBC_CURLOCALE->idx8c2wc[wc >> Cc2wc_IDX_SHIFT] << Cc2wc_IDX_SHIFT) + (wc & (Cc2wc_ROW_LEN - 1))]; if (!wc) { goto BAD; @@ -809,7 +797,6 @@ libc_hidden_def(mbsnrtowcs) /* Note: We completely ignore ps in all currently supported conversions. * TODO: Check for valid state anyway? */ -libc_hidden_proto(wcsnrtombs) size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, size_t NWC, size_t len, mbstate_t *__restrict ps) { @@ -862,12 +849,12 @@ size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, } else { u = 0; if (wc <= Cwc2c_DOMAIN_MAX) { - u = __UCLIBC_CURLOCALE_DATA.idx8wc2c[wc >> (Cwc2c_TI_SHIFT + u = __UCLIBC_CURLOCALE->idx8wc2c[wc >> (Cwc2c_TI_SHIFT + Cwc2c_TT_SHIFT)]; - u = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[(u << Cwc2c_TI_SHIFT) + u = __UCLIBC_CURLOCALE->tbl8wc2c[(u << Cwc2c_TI_SHIFT) + ((wc >> Cwc2c_TT_SHIFT) & ((1 << Cwc2c_TI_SHIFT)-1))]; - u = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[Cwc2c_TI_LEN + u = __UCLIBC_CURLOCALE->tbl8wc2c[Cwc2c_TI_LEN + (u << Cwc2c_TT_SHIFT) + (wc & ((1 << Cwc2c_TT_SHIFT)-1))]; } @@ -923,7 +910,6 @@ libc_hidden_def(wcsnrtombs) /**********************************************************************/ #ifdef L_wcswidth -libc_hidden_proto(wcswidth) #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: If we start doing translit, wcwidth and wcswidth will need updating. @@ -1039,13 +1025,12 @@ static const signed char new_wtbl[] = { 0, 2, 1, 2, 1, 0, 1, }; -libc_hidden_proto(wcsnrtombs) int wcswidth(const wchar_t *pwcs, size_t n) { - int h, l, m, count; - wchar_t wc; - unsigned char b; + int h, l, m, count; + wchar_t wc; + unsigned char b; if (ENCODING == __ctype_encoding_7_bit) { size_t i; @@ -1081,7 +1066,7 @@ int wcswidth(const wchar_t *pwcs, size_t n) } #endif /* __CTYPE_HAS_UTF_8_LOCALES */ - for (count = 0 ; n && (wc = *pwcs++) ; n--) { + for (count = 0 ; n && (wc = *pwcs++) ; n--) { if (wc <= 0xff) { /* If we're here, wc != 0. */ if ((wc < 32) || ((wc >= 0x7f) && (wc < 0xa0))) { @@ -1131,9 +1116,9 @@ int wcswidth(const wchar_t *pwcs, size_t n) } ++count; - } + } - return count; + return count; } #else /* __UCLIBC_HAS_LOCALE__ */ @@ -1142,8 +1127,15 @@ int wcswidth(const wchar_t *pwcs, size_t n) { int count; wchar_t wc; + size_t i; - for (count = 0 ; n && (wc = *pwcs++) ; n--) { + for (i = 0 ; (i < n) && pwcs[i] ; i++) { + if (pwcs[i] != (pwcs[i] & 0x7f)) { + return -1; + } + } + + for (count = 0 ; n && (wc = *pwcs++) ; n--) { if (wc <= 0xff) { /* If we're here, wc != 0. */ if ((wc < 32) || ((wc >= 0x7f) && (wc < 0xa0))) { @@ -1167,11 +1159,10 @@ libc_hidden_def(wcswidth) /**********************************************************************/ #ifdef L_wcwidth -libc_hidden_proto(wcswidth) int wcwidth(wchar_t wc) { - return wcswidth(&wc, 1); + return wcswidth(&wc, 1); } #endif @@ -1191,45 +1182,6 @@ typedef struct { int skip_invalid_input; /* To support iconv -c option. */ } _UC_iconv_t; - - -#ifdef L_iconv - -#include <iconv.h> -#include <string.h> -#include <endian.h> -#include <byteswap.h> - -#if (__BYTE_ORDER != __BIG_ENDIAN) && (__BYTE_ORDER != __LITTLE_ENDIAN) -#error unsupported endianness for iconv -#endif - -#ifndef __CTYPE_HAS_8_BIT_LOCALES -#error currently iconv requires 8 bit locales -#endif -#ifndef __CTYPE_HAS_UTF_8_LOCALES -#error currently iconv requires UTF-8 locales -#endif - - -enum { - IC_WCHAR_T = 0xe0, - IC_MULTIBYTE = 0xe0, -#if __BYTE_ORDER == __BIG_ENDIAN - IC_UCS_4 = 0xec, - IC_UTF_32 = 0xe4, - IC_UCS_2 = 0xe2, - IC_UTF_16 = 0xea, -#else - IC_UCS_4 = 0xed, - IC_UTF_32 = 0xe5, - IC_UCS_2 = 0xe3, - IC_UTF_16 = 0xeb, -#endif - IC_UTF_8 = 2, - IC_ASCII = 1 -}; - /* For the multibyte * bit 0 means swap endian * bit 1 means 2 byte @@ -1237,15 +1189,23 @@ enum { * */ +#if defined L_iconv && defined _LIBC +/* Used externally only by iconv utility */ extern const unsigned char __iconv_codesets[]; libc_hidden_proto(__iconv_codesets) +#endif + +#if defined L_iconv || defined L_iconv_main +# ifdef L_iconv_main +static +# endif const unsigned char __iconv_codesets[] = "\x0a\xe0""WCHAR_T\x00" /* superset of UCS-4 but platform-endian */ #if __BYTE_ORDER == __BIG_ENDIAN "\x08\xec""UCS-4\x00" /* always BE */ "\x0a\xec""UCS-4BE\x00" "\x0a\xed""UCS-4LE\x00" - "\x09\fe4""UTF-32\x00" /* platform endian with BOM */ + "\x09\xe4""UTF-32\x00" /* platform endian with BOM */ "\x0b\xe4""UTF-32BE\x00" "\x0b\xe5""UTF-32LE\x00" "\x08\xe2""UCS-2\x00" /* always BE */ @@ -1271,17 +1231,57 @@ const unsigned char __iconv_codesets[] = "\x08\x02""UTF-8\x00" "\x0b\x01""US-ASCII\x00" "\x07\x01""ASCII"; /* Must be last! (special case to save a nul) */ +#endif +#if defined L_iconv && defined _LIBC libc_hidden_data_def(__iconv_codesets) +#endif + + +#ifdef L_iconv + +#include <iconv.h> +#include <string.h> +#include <endian.h> +#include <byteswap.h> + +#if (__BYTE_ORDER != __BIG_ENDIAN) && (__BYTE_ORDER != __LITTLE_ENDIAN) +#error unsupported endianness for iconv +#endif + +#ifndef __CTYPE_HAS_8_BIT_LOCALES +#error currently iconv requires 8 bit locales +#endif +#ifndef __CTYPE_HAS_UTF_8_LOCALES +#error currently iconv requires UTF-8 locales +#endif + + +enum { + IC_WCHAR_T = 0xe0, + IC_MULTIBYTE = 0xe0, +#if __BYTE_ORDER == __BIG_ENDIAN + IC_UCS_4 = 0xec, + IC_UTF_32 = 0xe4, + IC_UCS_2 = 0xe2, + IC_UTF_16 = 0xea, +#else + IC_UCS_4 = 0xed, + IC_UTF_32 = 0xe5, + IC_UCS_2 = 0xe3, + IC_UTF_16 = 0xeb, +#endif + IC_UTF_8 = 2, + IC_ASCII = 1 +}; -/* Experimentally off - libc_hidden_proto(strcasecmp) */ static int find_codeset(const char *name) { const unsigned char *s; int codeset; - for (s = __iconv_codesets ; *s ; s += *s) { - if (!strcasecmp(s+2, name)) { + for (s = __iconv_codesets; *s; s += *s) { + if (!strcasecmp((char*) (s + 2), name)) { return s[1]; } } @@ -1291,7 +1291,7 @@ static int find_codeset(const char *name) /* TODO: maybe CODESET_LIST + *s ??? */ /* 7bit is 1, UTF-8 is 2, 8-bit is >= 3 */ codeset = 2; - s = __LOCALE_DATA_CODESET_LIST; + s = (const unsigned char *) __LOCALE_DATA_CODESET_LIST; do { ++codeset; /* Increment codeset first. */ if (!strcasecmp(__LOCALE_DATA_CODESET_LIST+*s, name)) { @@ -1311,9 +1311,9 @@ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode) && ((fromcodeset = find_codeset(fromcode)) != 0)) { if ((px = malloc(sizeof(_UC_iconv_t))) != NULL) { px->tocodeset = tocodeset; - px->tobom0 = px->tobom = (tocodeset & 0x10) >> 4; + px->tobom0 = px->tobom = (tocodeset >= 0xe0) ? (tocodeset & 0x10) >> 4 : 0; px->fromcodeset0 = px->fromcodeset = fromcodeset; - px->frombom0 = px->frombom = (fromcodeset & 0x10) >> 4; + px->frombom0 = px->frombom = (fromcodeset >= 0xe0) ? (fromcodeset & 0x10) >> 4 : 0; px->skip_invalid_input = px->tostate.__mask = px->fromstate.__mask = 0; return (iconv_t) px; @@ -1458,7 +1458,7 @@ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf, const __codeset_8_bit_t *c8b = __locale_mmap->codeset_8_bit + px->fromcodeset - 3; wc -= 0x80; - wc = __UCLIBC_CURLOCALE_DATA.tbl8c2wc[ + wc = __UCLIBC_CURLOCALE->tbl8c2wc[ (c8b->idx8c2wc[wc >> Cc2wc_IDX_SHIFT] << Cc2wc_IDX_SHIFT) + (wc & (Cc2wc_ROW_LEN - 1))]; if (!wc) { @@ -1543,10 +1543,10 @@ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf, = __locale_mmap->codeset_8_bit + px->tocodeset - 3; __uwchar_t u; u = c8b->idx8wc2c[wc >> (Cwc2c_TI_SHIFT + Cwc2c_TT_SHIFT)]; - u = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[(u << Cwc2c_TI_SHIFT) + u = __UCLIBC_CURLOCALE->tbl8wc2c[(u << Cwc2c_TI_SHIFT) + ((wc >> Cwc2c_TT_SHIFT) & ((1 << Cwc2c_TI_SHIFT)-1))]; - wc = __UCLIBC_CURLOCALE_DATA.tbl8wc2c[Cwc2c_TI_LEN + wc = __UCLIBC_CURLOCALE->tbl8wc2c[Cwc2c_TI_LEN + (u << Cwc2c_TT_SHIFT) + (wc & ((1 << Cwc2c_TT_SHIFT)-1))]; if (wc) { @@ -1565,172 +1565,4 @@ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf, } return nrcount; } - #endif -/**********************************************************************/ -#ifdef L_iconv_main - -#include <string.h> -#include <iconv.h> -#include <stdarg.h> -#include <libgen.h> - -extern const unsigned char __iconv_codesets[]; - -#define IBUF BUFSIZ -#define OBUF BUFSIZ - -char *progname; -int hide_errors; - -static void error_msg(const char *fmt, ...) - __attribute__ ((noreturn, format (printf, 1, 2))); - -static void error_msg(const char *fmt, ...) -{ - va_list arg; - - if (!hide_errors) { - fprintf(stderr, "%s: ", progname); - va_start(arg, fmt); - vfprintf(stderr, fmt, arg); - va_end(arg); - } - - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) -{ - FILE *ifile; - FILE *ofile = stdout; - const char *p; - const char *s; - static const char opt_chars[] = "tfocsl"; - /* 012345 */ - const char *opts[sizeof(opt_chars)]; /* last is infile name */ - iconv_t ic; - char ibuf[IBUF]; - char obuf[OBUF]; - char *pi; - char *po; - size_t ni, no, r, pos; - - hide_errors = 0; - - for (s = opt_chars ; *s ; s++) { - opts[ s - opt_chars ] = NULL; - } - - progname = *argv; - while (--argc) { - p = *++argv; - if ((*p != '-') || (*++p == 0)) { - break; - } - do { - if ((s = strchr(opt_chars,*p)) == NULL) { - USAGE: - s = basename(progname); - fprintf(stderr, - "%s [-cs] -f fromcode -t tocode [-o outputfile] [inputfile ...]\n" - " or\n%s -l\n", s, s); - return EXIT_FAILURE; - } - if ((s - opt_chars) < 3) { - if ((--argc == 0) || opts[s - opt_chars]) { - goto USAGE; - } - opts[s - opt_chars] = *++argv; - } else { - opts[s - opt_chars] = p; - } - } while (*++p); - } - - if (opts[5]) { /* -l */ - fprintf(stderr, "Recognized codesets:\n"); - for (s = __iconv_codesets ; *s ; s += *s) { - fprintf(stderr," %s\n", s+2); - } - s = __LOCALE_DATA_CODESET_LIST; - do { - fprintf(stderr," %s\n", __LOCALE_DATA_CODESET_LIST+ (unsigned char)(*s)); - } while (*++s); - - return EXIT_SUCCESS; - } - - if (opts[4]) { - hide_errors = 1; - } - - if (!opts[0] || !opts[1]) { - goto USAGE; - } - if ((ic = iconv_open(opts[0],opts[1])) == ((iconv_t)(-1))) { - error_msg( "unsupported codeset in %s -> %s conversion\n", opts[0], opts[1]); - } - if (opts[3]) { /* -c */ - ((_UC_iconv_t *) ic)->skip_invalid_input = 1; - } - - if ((s = opts[2]) != NULL) { - if (!(ofile = fopen(s, "w"))) { - error_msg( "couldn't open %s for writing\n", s); - } - } - - pos = ni = 0; - do { - if (!argc || ((**argv == '-') && !((*argv)[1]))) { - ifile = stdin; /* we don't check for duplicates */ - } else if (!(ifile = fopen(*argv, "r"))) { - error_msg( "couldn't open %s for reading\n", *argv); - } - - while ((r = fread(ibuf + ni, 1, IBUF - ni, ifile)) > 0) { - pos += r; - ni += r; - no = OBUF; - pi = ibuf; - po = obuf; - if ((r = iconv(ic, &pi, &ni, &po, &no)) == ((size_t)(-1))) { - if ((errno != EINVAL) && (errno != E2BIG)) { - error_msg( "iconv failed at pos %lu : %m\n", (unsigned long) (pos - ni)); - } - } - if ((r = OBUF - no) > 0) { - if (fwrite(obuf, 1, OBUF - no, ofile) < r) { - error_msg( "write error\n"); - } - } - if (ni) { /* still bytes in buffer! */ - memmove(ibuf, pi, ni); - } - } - - if (ferror(ifile)) { - error_msg( "read error\n"); - } - - ++argv; - - if (ifile != stdin) { - fclose(ifile); - } - - } while (--argc > 0); - - iconv_close(ic); - - if (ni) { - error_msg( "incomplete sequence\n"); - } - - return (((_UC_iconv_t *) ic)->skip_invalid_input < 2) - ? EXIT_SUCCESS : EXIT_FAILURE; -} - -#endif -/**********************************************************************/ |
