summaryrefslogtreecommitdiff
path: root/libc/misc/wchar
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc/wchar')
-rw-r--r--libc/misc/wchar/Makefile.in20
-rw-r--r--libc/misc/wchar/wchar.c356
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
-/**********************************************************************/