[glib] winiconv: update to upstream version
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] winiconv: update to upstream version
- Date: Tue, 26 Jan 2016 11:56:23 +0000 (UTC)
commit 9e805ffd4381cded7a53e29dc66d4a4b6d2b152d
Author: Ignacio Casal Quinteiro <icq gnome org>
Date: Tue Jan 26 10:57:44 2016 +0100
winiconv: update to upstream version
To update this code you need to fetch the last version of the code
from: https://github.com/win-iconv/win-iconv
Then you need to ensure 3 things:
- the line ends are in unix format
- some of the methods do not expose a const on the prototype
refer to the commit b8c13a01b6bd5601eb3519dd3b20daed4bbc2e72
on how to fix it
- fix one uninitialized variable if not yet fixed upstream
refer to 7e0cb48dee9a8ecd87d403b7941ad3209eee658c
https://bugzilla.gnome.org/show_bug.cgi?id=761126
glib/win_iconv.c | 616 ++++++++++++++++++++++++++++++++----------------------
1 files changed, 371 insertions(+), 245 deletions(-)
---
diff --git a/glib/win_iconv.c b/glib/win_iconv.c
index e04a315..63023ca 100644
--- a/glib/win_iconv.c
+++ b/glib/win_iconv.c
@@ -30,6 +30,17 @@
#include <string.h>
#include <stdlib.h>
+#ifdef __GNUC__
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
+/* WORKAROUND: */
+#ifndef UNDER_CE
+#define GetProcAddressA GetProcAddress
+#endif
+
#if 0
# define MAKE_EXE
# define MAKE_DLL
@@ -45,29 +56,9 @@
#define UNICODE_MODE_BOM_DONE 1
#define UNICODE_MODE_SWAPPED 2
-#define FLAG_USE_BOM_ENDIAN 1
+#define FLAG_USE_BOM 1
#define FLAG_TRANSLIT 2 /* //TRANSLIT */
-#define FLAG_IGNORE 4 /* //IGNORE (not implemented) */
-
-#define return_error(code) \
- do { \
- errno = code; \
- return -1; \
- } while (0)
-
-#define xstrlcpy(dst, src, size) \
- do { \
- strncpy(dst, src, size); \
- dst[size - 1] = 0; \
- } while (0)
-
-#define xstrlcpyn(dst, src, srclen, size) \
- xstrlcpy(dst, src, xmin((srclen) + 1, size))
-
-#define xmin(a, b) ((a) < (b) ? (a) : (b))
-#define xmax(a, b) ((a) > (b) ? (a) : (b))
-
-#define STATIC_STRLEN(arr) (sizeof(arr) - 1)
+#define FLAG_IGNORE 4 /* //IGNORE */
typedef unsigned char uchar;
typedef unsigned short ushort;
@@ -140,23 +131,22 @@ static int win_iconv_close(iconv_t cd);
static size_t win_iconv(iconv_t cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf, size_t
*outbytesleft);
static int load_mlang(void);
-static csconv_t make_csconv(const char *name);
+static int make_csconv(const char *name, csconv_t *cv);
static int name_to_codepage(const char *name);
static uint utf16_to_ucs4(const ushort *wbuf);
static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize);
-static int is_unicode(int codepage);
static int mbtowc_flags(int codepage);
static int must_use_null_useddefaultchar(int codepage);
-static void check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize);
static char *strrstr(const char *str, const char *token);
+static char *xstrndup(const char *s, size_t n);
+static int seterror(int err);
#if defined(USE_LIBICONV_DLL)
static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG
Size);
-static HMODULE find_imported_module_by_funcname(HMODULE hModule, const char *funcname);
+static FARPROC find_imported_function(HMODULE hModule, const char *funcname);
static HMODULE hwiniconv;
-static HMODULE hlastdll; /* keep dll loaded for efficiency (unnecessary?) */
#endif
static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
@@ -217,6 +207,8 @@ static struct {
*/
{1201, "UTF16"},
{1201, "UTF-16"},
+ {1201, "UCS2"},
+ {1201, "UCS-2"},
{12001, "UTF32"},
{12001, "UTF-32"},
{12001, "UCS-4"},
@@ -357,6 +349,8 @@ static struct {
{950, "CP950"},
{950, "BIG5"},
+ {950, "BIG5HKSCS"},
+ {950, "BIG5-HKSCS"},
{949, "CP949"},
{949, "UHC"},
@@ -465,6 +459,8 @@ static struct {
{936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */
{949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */
{950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5)
*/
+ {950, "big5hkscs"}, /* ANSI/OEM Traditional Chinese (Hong Kong SAR); Chinese Traditional (Big5-HKSCS) */
+ {950, "big5-hkscs"}, /* alternative name for it */
{1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */
{1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */
{1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */
@@ -542,29 +538,53 @@ static struct {
{21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */
{28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
{28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
+ {28591, "iso_8859-1"},
+ {28591, "iso_8859_1"},
{28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
{28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
+ {28592, "iso_8859-2"},
+ {28592, "iso_8859_2"},
{28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */
{28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */
+ {28593, "iso_8859-3"},
+ {28593, "iso_8859_3"},
{28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */
{28594, "iso8859-4"}, /* ISO 8859-4 Baltic */
+ {28594, "iso_8859-4"},
+ {28594, "iso_8859_4"},
{28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */
{28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */
+ {28595, "iso_8859-5"},
+ {28595, "iso_8859_5"},
{28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */
{28596, "iso8859-6"}, /* ISO 8859-6 Arabic */
+ {28596, "iso_8859-6"},
+ {28596, "iso_8859_6"},
{28597, "iso-8859-7"}, /* ISO 8859-7 Greek */
{28597, "iso8859-7"}, /* ISO 8859-7 Greek */
+ {28597, "iso_8859-7"},
+ {28597, "iso_8859_7"},
{28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
{28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
+ {28598, "iso_8859-8"},
+ {28598, "iso_8859_8"},
{28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */
{28599, "iso8859-9"}, /* ISO 8859-9 Turkish */
+ {28599, "iso_8859-9"},
+ {28599, "iso_8859_9"},
{28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */
{28603, "iso8859-13"}, /* ISO 8859-13 Estonian */
+ {28603, "iso_8859-13"},
+ {28603, "iso_8859_13"},
{28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */
{28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */
+ {28605, "iso_8859-15"},
+ {28605, "iso_8859_15"},
{29001, "x-Europa"}, /* Europa 3 */
{38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
{38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
+ {38598, "iso_8859-8-i"},
+ {38598, "iso_8859_8-i"},
{50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */
{50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */
{50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */
@@ -706,28 +726,18 @@ static RFC1766TOLCIDA Rfc1766ToLcidA;
static int
load_mlang(void)
{
- HMODULE h = NULL;
- char mlang_dll[MAX_PATH + 100];
- int n;
+ HMODULE h;
if (ConvertINetString != NULL)
return TRUE;
- n = GetSystemDirectory(mlang_dll, MAX_PATH);
- if (n > 0 && n < MAX_PATH)
- {
- if (mlang_dll[n-1] != '\\' &&
- mlang_dll[n-1] != '/')
- strcat(mlang_dll, "\\");
- strcat(mlang_dll, "mlang.dll");
- h = LoadLibrary(mlang_dll);
- }
+ h = LoadLibrary(TEXT("mlang.dll"));
if (!h)
return FALSE;
- ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString");
- ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h,
"ConvertINetMultiByteToUnicode");
- ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h,
"ConvertINetUnicodeToMultiByte");
- IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddress(h,
"IsConvertINetStringAvailable");
- LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddress(h, "LcidToRfc1766A");
- Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddress(h, "Rfc1766ToLcidA");
+ ConvertINetString = (CONVERTINETSTRING)GetProcAddressA(h, "ConvertINetString");
+ ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddressA(h,
"ConvertINetMultiByteToUnicode");
+ ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddressA(h,
"ConvertINetUnicodeToMultiByte");
+ IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddressA(h,
"IsConvertINetStringAvailable");
+ LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddressA(h, "LcidToRfc1766A");
+ Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddressA(h, "Rfc1766ToLcidA");
return TRUE;
}
@@ -738,21 +748,22 @@ iconv_open(const char *tocode, const char *fromcode)
cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t));
if (cd == NULL)
- {
- errno = ENOMEM;
return (iconv_t)(-1);
- }
#if defined(USE_LIBICONV_DLL)
+ errno = 0;
if (libiconv_iconv_open(cd, tocode, fromcode))
return (iconv_t)cd;
#endif
+ /* reset the errno to prevent reporting wrong error code.
+ * 0 for unsorted error. */
+ errno = 0;
if (win_iconv_open(cd, tocode, fromcode))
return (iconv_t)cd;
free(cd);
- errno = EINVAL;
+
return (iconv_t)(-1);
}
@@ -783,9 +794,7 @@ iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf,
static int
win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
{
- cd->from = make_csconv(fromcode);
- cd->to = make_csconv(tocode);
- if (cd->from.codepage == -1 || cd->to.codepage == -1)
+ if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to))
return FALSE;
cd->iconv_close = win_iconv_close;
cd->iconv = win_iconv;
@@ -795,7 +804,7 @@ win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
}
static int
-win_iconv_close(iconv_t cd)
+win_iconv_close(iconv_t cd UNUSED)
{
return 0;
}
@@ -808,7 +817,8 @@ win_iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **out
int insize;
int outsize;
int wsize;
- DWORD mode;
+ DWORD frommode;
+ DWORD tomode;
uint wc;
compat_t *cp;
int i;
@@ -817,14 +827,23 @@ win_iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **out
{
if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL)
{
+ tomode = cd->to.mode;
outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft);
if (outsize == -1)
- return (size_t)(-1);
+ {
+ if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
+ {
+ outsize = 0;
+ }
+ else
+ {
+ cd->to.mode = tomode;
+ return (size_t)(-1);
+ }
+ }
*outbuf += outsize;
*outbytesleft -= outsize;
}
- if (is_unicode(cd->from.codepage) && (cd->from.mode & UNICODE_MODE_SWAPPED))
- cd->from.codepage ^= 1;
cd->from.mode = 0;
cd->to.mode = 0;
return 0;
@@ -832,17 +851,24 @@ win_iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **out
while (*inbytesleft != 0)
{
- mode = cd->from.mode;
+ frommode = cd->from.mode;
+ tomode = cd->to.mode;
wsize = MB_CHAR_MAX;
insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize);
if (insize == -1)
- return (size_t)(-1);
-
- if (is_unicode(cd->from.codepage) && !(cd->from.mode & UNICODE_MODE_BOM_DONE))
{
- check_utf_bom(cd, wbuf, &wsize);
- cd->from.mode |= UNICODE_MODE_BOM_DONE;
+ if (cd->to.flags & FLAG_IGNORE)
+ {
+ cd->from.mode = frommode;
+ insize = 1;
+ wsize = 0;
+ }
+ else
+ {
+ cd->from.mode = frommode;
+ return (size_t)(-1);
+ }
}
if (wsize == 0)
@@ -883,8 +909,17 @@ win_iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **out
outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft);
if (outsize == -1)
{
- cd->from.mode = mode;
- return (size_t)(-1);
+ if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
+ {
+ cd->to.mode = tomode;
+ outsize = 0;
+ }
+ else
+ {
+ cd->from.mode = frommode;
+ cd->to.mode = tomode;
+ return (size_t)(-1);
+ }
}
*inbuf += insize;
@@ -896,17 +931,18 @@ win_iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **out
return 0;
}
-static csconv_t
-make_csconv(const char *_name)
+static int
+make_csconv(const char *_name, csconv_t *cv)
{
- CPINFOEX cpinfoex;
- csconv_t cv;
+ CPINFO cpinfo;
int use_compat = TRUE;
int flag = 0;
- char name[128];
+ char *name;
char *p;
- xstrlcpy(name, _name, sizeof(name));
+ name = xstrndup(_name, strlen(_name));
+ if (name == NULL)
+ return FALSE;
/* check for option "enc_name//opt1//opt2" */
while ((p = strrstr(name, "//")) != NULL)
@@ -920,78 +956,80 @@ make_csconv(const char *_name)
*p = 0;
}
- cv.mode = 0;
- cv.flags = flag;
- cv.mblen = NULL;
- cv.flush = NULL;
- cv.compat = NULL;
- cv.codepage = name_to_codepage(name);
- if (cv.codepage == 1200 || cv.codepage == 1201)
+ cv->mode = 0;
+ cv->flags = flag;
+ cv->mblen = NULL;
+ cv->flush = NULL;
+ cv->compat = NULL;
+ cv->codepage = name_to_codepage(name);
+ if (cv->codepage == 1200 || cv->codepage == 1201)
{
- cv.mbtowc = utf16_mbtowc;
- cv.wctomb = utf16_wctomb;
- if (_stricmp(name, "UTF-16") == 0 ||
- _stricmp(name, "UTF16") == 0 ||
- _stricmp(name, "UCS-2") == 0 ||
- _stricmp(name, "UCS2") == 0)
- cv.flags |= FLAG_USE_BOM_ENDIAN;
+ cv->mbtowc = utf16_mbtowc;
+ cv->wctomb = utf16_wctomb;
+ if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0 ||
+ _stricmp(name, "UCS-2") == 0 || _stricmp(name, "UCS2") == 0)
+ cv->flags |= FLAG_USE_BOM;
}
- else if (cv.codepage == 12000 || cv.codepage == 12001)
+ else if (cv->codepage == 12000 || cv->codepage == 12001)
{
- cv.mbtowc = utf32_mbtowc;
- cv.wctomb = utf32_wctomb;
- if (_stricmp(name, "UTF-32") == 0 ||
- _stricmp(name, "UTF32") == 0 ||
- _stricmp(name, "UCS-4") == 0 ||
- _stricmp(name, "UCS4") == 0)
- cv.flags |= FLAG_USE_BOM_ENDIAN;
+ cv->mbtowc = utf32_mbtowc;
+ cv->wctomb = utf32_wctomb;
+ if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0 ||
+ _stricmp(name, "UCS-4") == 0 || _stricmp(name, "UCS4") == 0)
+ cv->flags |= FLAG_USE_BOM;
}
- else if (cv.codepage == 65001)
+ else if (cv->codepage == 65001)
{
- cv.mbtowc = kernel_mbtowc;
- cv.wctomb = kernel_wctomb;
- cv.mblen = utf8_mblen;
+ cv->mbtowc = kernel_mbtowc;
+ cv->wctomb = kernel_wctomb;
+ cv->mblen = utf8_mblen;
}
- else if ((cv.codepage == 50220 || cv.codepage == 50221 || cv.codepage == 50222) && load_mlang())
+ else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang())
{
- cv.mbtowc = iso2022jp_mbtowc;
- cv.wctomb = iso2022jp_wctomb;
- cv.flush = iso2022jp_flush;
+ cv->mbtowc = iso2022jp_mbtowc;
+ cv->wctomb = iso2022jp_wctomb;
+ cv->flush = iso2022jp_flush;
}
- else if (cv.codepage == 51932 && load_mlang())
+ else if (cv->codepage == 51932 && load_mlang())
{
- cv.mbtowc = mlang_mbtowc;
- cv.wctomb = mlang_wctomb;
- cv.mblen = eucjp_mblen;
+ cv->mbtowc = mlang_mbtowc;
+ cv->wctomb = mlang_wctomb;
+ cv->mblen = eucjp_mblen;
}
- else if (IsValidCodePage(cv.codepage)
- && GetCPInfoEx(cv.codepage, 0, &cpinfoex) != 0)
+ else if (IsValidCodePage(cv->codepage)
+ && GetCPInfo(cv->codepage, &cpinfo) != 0)
{
- cv.mbtowc = kernel_mbtowc;
- cv.wctomb = kernel_wctomb;
- if (cpinfoex.MaxCharSize == 1)
- cv.mblen = sbcs_mblen;
- else if (cpinfoex.MaxCharSize == 2)
- cv.mblen = dbcs_mblen;
- else
- cv.mblen = mbcs_mblen;
+ cv->mbtowc = kernel_mbtowc;
+ cv->wctomb = kernel_wctomb;
+ if (cpinfo.MaxCharSize == 1)
+ cv->mblen = sbcs_mblen;
+ else if (cpinfo.MaxCharSize == 2)
+ cv->mblen = dbcs_mblen;
+ else
+ cv->mblen = mbcs_mblen;
}
else
{
/* not supported */
- cv.codepage = -1;
+ free(name);
+ errno = EINVAL;
+ return FALSE;
}
+
if (use_compat)
{
- switch (cv.codepage)
+ switch (cv->codepage)
{
- case 932: cv.compat = cp932_compat; break;
- case 20932: cv.compat = cp20932_compat; break;
- case 51932: cv.compat = cp51932_compat; break;
- case 50220: case 50221: case 50222: cv.compat = cp5022x_compat; break;
+ case 932: cv->compat = cp932_compat; break;
+ case 20932: cv->compat = cp20932_compat; break;
+ case 51932: cv->compat = cp51932_compat; break;
+ case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break;
}
}
- return cv;
+
+ free(name);
+
+ return TRUE;
}
static int
@@ -1046,14 +1084,6 @@ ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)
}
}
-static int
-is_unicode(int codepage)
-{
- return (codepage == 1200 || codepage == 1201 ||
- codepage == 12000 || codepage == 12001 ||
- codepage == 65000 || codepage == 65001);
-}
-
/*
* Check if codepage is one of those for which the dwFlags parameter
* to MultiByteToWideChar() must be zero. Return zero or
@@ -1078,7 +1108,7 @@ mbtowc_flags(int codepage)
/*
* Check if codepage is one those for which the lpUsedDefaultChar
* parameter to WideCharToMultiByte() must be NULL. The docs in
- * Platform SDK for for Windows Server 2003 R2 claims that this is the
+ * Platform SDK for Windows Server 2003 R2 claims that this is the
* list below, while the MSDN docs for MSVS2008 claim that it is only
* for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform
* SDK seems to be correct, at least for XP.
@@ -1095,27 +1125,6 @@ must_use_null_useddefaultchar(int codepage)
codepage == 42);
}
-static void
-check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize)
-{
- /* If we have a BOM, trust it, despite what the caller said */
- if (wbuf[0] == 0xFFFE && (cd->from.flags & FLAG_USE_BOM_ENDIAN))
- {
- /* swap endian: 1200 <-> 1201 or 12000 <-> 12001 */
- cd->from.codepage ^= 1;
- cd->from.mode |= UNICODE_MODE_SWAPPED;
- wbuf[0] = 0xFEFF;
- }
-
- /*
- * Remove BOM.
- * Don't do this if "to" is Unicode,
- * except if "to" is UTF-8.
- */
- if (wbuf[0] == 0xFEFF && (!is_unicode(cd->to.codepage) || cd->to.codepage == 65001))
- *wbufsize = 0;
-}
-
static char *
strrstr(const char *str, const char *token)
{
@@ -1128,13 +1137,32 @@ strrstr(const char *str, const char *token)
return NULL;
}
+static char *
+xstrndup(const char *s, size_t n)
+{
+ char *p;
+
+ p = (char *)malloc(n + 1);
+ if (p == NULL)
+ return NULL;
+ memcpy(p, s, n);
+ p[n] = '\0';
+ return p;
+}
+
+static int
+seterror(int err)
+{
+ errno = err;
+ return -1;
+}
+
#if defined(USE_LIBICONV_DLL)
static int
-libiconv_iconv_open(rec_iconv_t *cd, const char *fromcode, const char *tocode)
+libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
{
HMODULE hlibiconv = NULL;
- HMODULE hmsvcrt = NULL;
- char dllname[_MAX_PATH];
+ char *dllname;
const char *p;
const char *e;
f_iconv_open _iconv_open;
@@ -1155,8 +1183,11 @@ libiconv_iconv_open(rec_iconv_t *cd, const char *fromcode, const char *tocode)
continue;
else if (e == NULL)
e = p + strlen(p);
- xstrlcpyn(dllname, p, e - p, sizeof(dllname));
- hlibiconv = LoadLibrary(dllname);
+ dllname = xstrndup(p, e - p);
+ if (dllname == NULL)
+ return FALSE;
+ hlibiconv = LoadLibraryA(dllname);
+ free(dllname);
if (hlibiconv != NULL)
{
if (hlibiconv == hwiniconv)
@@ -1169,37 +1200,23 @@ libiconv_iconv_open(rec_iconv_t *cd, const char *fromcode, const char *tocode)
}
}
- if (hlastdll != NULL)
- {
- /* decrement reference count */
- FreeLibrary(hlastdll);
- hlastdll = NULL;
- }
-
if (hlibiconv == NULL)
goto failed;
- hmsvcrt = find_imported_module_by_funcname(hlibiconv, "_errno");
- if (hmsvcrt == NULL)
- goto failed;
-
- _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "libiconv_open");
+ _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "libiconv_open");
if (_iconv_open == NULL)
- _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "iconv_open");
- cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "libiconv_close");
+ _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "iconv_open");
+ cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "libiconv_close");
if (cd->iconv_close == NULL)
- cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "iconv_close");
- cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "libiconv");
+ cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "iconv_close");
+ cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "libiconv");
if (cd->iconv == NULL)
- cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "iconv");
- cd->_errno = (f_errno)GetProcAddress(hmsvcrt, "_errno");
+ cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "iconv");
+ cd->_errno = (f_errno)find_imported_function(hlibiconv, "_errno");
if (_iconv_open == NULL || cd->iconv_close == NULL
|| cd->iconv == NULL || cd->_errno == NULL)
goto failed;
- /* increment reference count */
- hlastdll = LoadLibrary(dllname);
-
cd->cd = _iconv_open(tocode, fromcode);
if (cd->cd == (iconv_t)(-1))
goto failed;
@@ -1210,7 +1227,6 @@ libiconv_iconv_open(rec_iconv_t *cd, const char *fromcode, const char *tocode)
failed:
if (hlibiconv != NULL)
FreeLibrary(hlibiconv);
- /* do not free hmsvcrt which is obtained by GetModuleHandle() */
return FALSE;
}
@@ -1240,17 +1256,18 @@ MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT Directory
return (PVOID)((LPBYTE)Base + p->VirtualAddress);
}
-static HMODULE
-find_imported_module_by_funcname(HMODULE hModule, const char *funcname)
+static FARPROC
+find_imported_function(HMODULE hModule, const char *funcname)
{
- DWORD Base;
+ DWORD_PTR Base;
ULONG Size;
PIMAGE_IMPORT_DESCRIPTOR Imp;
+ PIMAGE_THUNK_DATA Address; /* Import Address Table */
PIMAGE_THUNK_DATA Name; /* Import Name Table */
PIMAGE_IMPORT_BY_NAME ImpName;
- Base = (DWORD)hModule;
- Imp = MyImageDirectoryEntryToData(
+ Base = (DWORD_PTR)hModule;
+ Imp = (PIMAGE_IMPORT_DESCRIPTOR)MyImageDirectoryEntryToData(
(LPVOID)Base,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
@@ -1259,15 +1276,16 @@ find_imported_module_by_funcname(HMODULE hModule, const char *funcname)
return NULL;
for ( ; Imp->OriginalFirstThunk != 0; ++Imp)
{
+ Address = (PIMAGE_THUNK_DATA)(Base + Imp->FirstThunk);
Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk);
- for ( ; Name->u1.Ordinal != 0; ++Name)
+ for ( ; Name->u1.Ordinal != 0; ++Name, ++Address)
{
if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal))
{
ImpName = (PIMAGE_IMPORT_BY_NAME)
- (Base + (DWORD)Name->u1.AddressOfData);
+ (Base + (DWORD_PTR)Name->u1.AddressOfData);
if (strcmp((char *)ImpName->Name, funcname) == 0)
- return GetModuleHandle((char *)(Base + Imp->Name));
+ return (FARPROC)Address->u1.Function;
}
}
}
@@ -1276,7 +1294,7 @@ find_imported_module_by_funcname(HMODULE hModule, const char *funcname)
#endif
static int
-sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+sbcs_mblen(csconv_t *cv UNUSED, const uchar *buf UNUSED, int bufsize UNUSED)
{
return 1;
}
@@ -1286,7 +1304,7 @@ dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
{
int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1;
if (bufsize < len)
- return_error(EINVAL);
+ return seterror(EINVAL);
return len;
}
@@ -1305,15 +1323,15 @@ mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
bufsize >= 4 &&
buf[1] >= 0x30 && buf[1] <= 0x39) len = 4;
else
- return_error(EINVAL);
+ return seterror(EINVAL);
return len;
}
else
- return_error(EINVAL);
+ return seterror(EINVAL);
}
static int
-utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+utf8_mblen(csconv_t *cv UNUSED, const uchar *buf, int bufsize)
{
int len = 0;
@@ -1325,41 +1343,41 @@ utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize)
else if ((buf[0] & 0xFE) == 0xFC) len = 6;
if (len == 0)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
else if (bufsize < len)
- return_error(EINVAL);
+ return seterror(EINVAL);
return len;
}
static int
-eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+eucjp_mblen(csconv_t *cv UNUSED, const uchar *buf, int bufsize)
{
if (buf[0] < 0x80) /* ASCII */
return 1;
else if (buf[0] == 0x8E) /* JIS X 0201 */
{
if (bufsize < 2)
- return_error(EINVAL);
+ return seterror(EINVAL);
else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
return 2;
}
else if (buf[0] == 0x8F) /* JIS X 0212 */
{
if (bufsize < 3)
- return_error(EINVAL);
+ return seterror(EINVAL);
else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE)
|| !(0xA1 <= buf[2] && buf[2] <= 0xFE))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
return 3;
}
else /* JIS X 0208 */
{
if (bufsize < 2)
- return_error(EINVAL);
+ return seterror(EINVAL);
else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE)
|| !(0xA1 <= buf[1] && buf[1] <= 0xFE))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
return 2;
}
}
@@ -1377,11 +1395,11 @@ kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wb
* know that the mblen function is sbcs_mblen() so len is 1.
*/
if (cv->codepage == 20127 && buf[0] >= 0x80)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
*wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage),
(const char *)buf, len, (wchar_t *)wbuf, *wbufsize);
if (*wbufsize == 0)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
return len;
}
@@ -1394,7 +1412,7 @@ kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
int len;
if (bufsize == 0)
- return_error(E2BIG);
+ return seterror(E2BIG);
if (!must_use_null_useddefaultchar(cv->codepage))
{
p = &usedDefaultChar;
@@ -1408,13 +1426,13 @@ kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
if (len == 0)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- return_error(E2BIG);
- return_error(EILSEQ);
+ return seterror(E2BIG);
+ return seterror(EILSEQ);
}
- else if (usedDefaultChar)
- return_error(EILSEQ);
+ else if (usedDefaultChar && !(cv->flags & FLAG_TRANSLIT))
+ return seterror(EILSEQ);
else if (cv->mblen(cv, buf, len) != len) /* validate result */
- return_error(EILSEQ);
+ return seterror(EILSEQ);
return len;
}
@@ -1440,7 +1458,7 @@ mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbu
hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage,
(const char *)buf, &insize, (wchar_t *)wbuf, wbufsize);
if (hr != S_OK || insize != len)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
return len;
}
@@ -1455,11 +1473,11 @@ mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage,
(const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize);
if (hr != S_OK || insize != wbufsize)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
else if (bufsize < tmpsize)
- return_error(E2BIG);
+ return seterror(E2BIG);
else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
memcpy(buf, tmpbuf, tmpsize);
return tmpsize;
}
@@ -1467,24 +1485,47 @@ mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
static int
utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
{
+ int codepage = cv->codepage;
+
+ /* swap endian: 1200 <-> 1201 */
+ if (cv->mode & UNICODE_MODE_SWAPPED)
+ codepage ^= 1;
+
if (bufsize < 2)
- return_error(EINVAL);
- if (cv->codepage == 1200) /* little endian */
+ return seterror(EINVAL);
+ if (codepage == 1200) /* little endian */
wbuf[0] = (buf[1] << 8) | buf[0];
- else if (cv->codepage == 1201) /* big endian */
+ else if (codepage == 1201) /* big endian */
wbuf[0] = (buf[0] << 8) | buf[1];
+
+ if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
+ {
+ cv->mode |= UNICODE_MODE_BOM_DONE;
+ if (wbuf[0] == 0xFFFE)
+ {
+ cv->mode |= UNICODE_MODE_SWAPPED;
+ *wbufsize = 0;
+ return 2;
+ }
+ else if (wbuf[0] == 0xFEFF)
+ {
+ *wbufsize = 0;
+ return 2;
+ }
+ }
+
if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
{
if (bufsize < 4)
- return_error(EINVAL);
- if (cv->codepage == 1200) /* little endian */
+ return seterror(EINVAL);
+ if (codepage == 1200) /* little endian */
wbuf[1] = (buf[3] << 8) | buf[2];
- else if (cv->codepage == 1201) /* big endian */
+ else if (codepage == 1201) /* big endian */
wbuf[1] = (buf[2] << 8) | buf[3];
if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
*wbufsize = 2;
return 4;
}
@@ -1495,8 +1536,26 @@ utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbu
static int
utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
{
+ if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
+ {
+ int r;
+
+ cv->mode |= UNICODE_MODE_BOM_DONE;
+ if (bufsize < 2)
+ return seterror(E2BIG);
+ if (cv->codepage == 1200) /* little endian */
+ memcpy(buf, "\xFF\xFE", 2);
+ else if (cv->codepage == 1201) /* big endian */
+ memcpy(buf, "\xFE\xFF", 2);
+
+ r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2);
+ if (r == -1)
+ return -1;
+ return r + 2;
+ }
+
if (bufsize < 2)
- return_error(E2BIG);
+ return seterror(E2BIG);
if (cv->codepage == 1200) /* little endian */
{
buf[0] = (wbuf[0] & 0x00FF);
@@ -1510,7 +1569,7 @@ utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
{
if (bufsize < 4)
- return_error(E2BIG);
+ return seterror(E2BIG);
if (cv->codepage == 1200) /* little endian */
{
buf[2] = (wbuf[1] & 0x00FF);
@@ -1529,16 +1588,38 @@ utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
static int
utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
{
+ int codepage = cv->codepage;
uint wc = 0xD800;
+ /* swap endian: 12000 <-> 12001 */
+ if (cv->mode & UNICODE_MODE_SWAPPED)
+ codepage ^= 1;
+
if (bufsize < 4)
- return_error(EINVAL);
- if (cv->codepage == 12000) /* little endian */
+ return seterror(EINVAL);
+ if (codepage == 12000) /* little endian */
wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
- else if (cv->codepage == 12001) /* big endian */
+ else if (codepage == 12001) /* big endian */
wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+
+ if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
+ {
+ cv->mode |= UNICODE_MODE_BOM_DONE;
+ if (wc == 0xFFFE0000)
+ {
+ cv->mode |= UNICODE_MODE_SWAPPED;
+ *wbufsize = 0;
+ return 4;
+ }
+ else if (wc == 0x0000FEFF)
+ {
+ *wbufsize = 0;
+ return 4;
+ }
+ }
+
if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
ucs4_to_utf16(wc, wbuf, wbufsize);
return 4;
}
@@ -1548,8 +1629,26 @@ utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
{
uint wc;
+ if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
+ {
+ int r;
+
+ cv->mode |= UNICODE_MODE_BOM_DONE;
+ if (bufsize < 4)
+ return seterror(E2BIG);
+ if (cv->codepage == 12000) /* little endian */
+ memcpy(buf, "\xFF\xFE\x00\x00", 4);
+ else if (cv->codepage == 12001) /* big endian */
+ memcpy(buf, "\x00\x00\xFE\xFF", 4);
+
+ r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4);
+ if (r == -1)
+ return -1;
+ return r + 4;
+ }
+
if (bufsize < 4)
- return_error(E2BIG);
+ return seterror(E2BIG);
wc = utf16_to_ucs4(wbuf);
if (cv->codepage == 12000) /* little endian */
{
@@ -1640,7 +1739,7 @@ iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int
if (bufsize < esc_len)
{
if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0)
- return_error(EINVAL);
+ return seterror(EINVAL);
}
else
{
@@ -1653,7 +1752,7 @@ iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int
}
}
/* not supported escape sequence */
- return_error(EILSEQ);
+ return seterror(EILSEQ);
}
else if (buf[0] == iso2022_SO_seq[0])
{
@@ -1680,10 +1779,10 @@ iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int
len = iesc[cs].len;
if (bufsize < len)
- return_error(EINVAL);
+ return seterror(EINVAL);
for (i = 0; i < len; ++i)
if (!(buf[i] < 0x80))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
esc_len = iesc[cs].esc_len;
memcpy(tmp, iesc[cs].esc, esc_len);
if (shift == ISO2022_SO)
@@ -1707,13 +1806,13 @@ iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int
hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage,
(const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize);
if (hr != S_OK || insize != len + esc_len)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
/* Check for conversion error. Assuming defaultChar is 0x3F. */
/* ascii should be converted from ascii */
if (wbuf[0] == buf[0]
&& cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
/* reset the mode for informal sequence */
if (cv->mode != ISO2022_MODE(cs, shift))
@@ -1746,9 +1845,9 @@ iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsi
hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage,
(const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize);
if (hr != S_OK || insize != wbufsize)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
else if (bufsize < tmpsize)
- return_error(E2BIG);
+ return seterror(E2BIG);
if (tmpsize == 1)
{
@@ -1768,7 +1867,7 @@ iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsi
}
if (iesc[i].esc == NULL)
/* not supported escape sequence */
- return_error(EILSEQ);
+ return seterror(EILSEQ);
}
shift = ISO2022_SI;
@@ -1783,9 +1882,9 @@ iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsi
/* Check for converting error. Assuming defaultChar is 0x3F. */
/* ascii should be converted from ascii */
if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80))
- return_error(EILSEQ);
+ return seterror(EILSEQ);
else if (tmpsize < esc_len + len)
- return_error(EILSEQ);
+ return seterror(EILSEQ);
if (cv->mode == ISO2022_MODE(cs, shift))
{
@@ -1812,7 +1911,7 @@ iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsi
}
if (bufsize < len + esc_len)
- return_error(E2BIG);
+ return seterror(E2BIG);
memcpy(buf, tmp, len + esc_len);
cv->mode = ISO2022_MODE(cs, shift);
return len + esc_len;
@@ -1832,7 +1931,7 @@ iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize)
if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII)
esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
if (bufsize < esc_len)
- return_error(E2BIG);
+ return seterror(E2BIG);
esc_len = 0;
if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)
@@ -1889,6 +1988,9 @@ main(int argc, char **argv)
iconv_t cd;
size_t r;
FILE *in = stdin;
+ FILE *out = stdout;
+ int ignore = 0;
+ char *p;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
@@ -1906,6 +2008,17 @@ main(int argc, char **argv)
fromcode = argv[++i];
else if (strcmp(argv[i], "-t") == 0)
tocode = argv[++i];
+ else if (strcmp(argv[i], "-c") == 0)
+ ignore = 1;
+ else if (strcmp(argv[i], "--output") == 0)
+ {
+ out = fopen(argv[++i], "wb");
+ if(out == NULL)
+ {
+ fprintf(stderr, "cannot open %s\n", argv[i]);
+ return 1;
+ }
+ }
else
{
in = fopen(argv[i], "rb");
@@ -1920,10 +2033,23 @@ main(int argc, char **argv)
if (fromcode == NULL || tocode == NULL)
{
- printf("usage: %s -f from-enc -t to-enc [file]\n", argv[0]);
+ printf("usage: %s [-c] -f from-enc -t to-enc [file]\n", argv[0]);
return 0;
}
+ if (ignore)
+ {
+ p = tocode;
+ tocode = (char *)malloc(strlen(p) + strlen("//IGNORE") + 1);
+ if (tocode == NULL)
+ {
+ perror("fatal error");
+ return 1;
+ }
+ strcpy(tocode, p);
+ strcat(tocode, "//IGNORE");
+ }
+
cd = iconv_open(tocode, fromcode);
if (cd == (iconv_t)(-1))
{
@@ -1939,8 +2065,8 @@ main(int argc, char **argv)
pout = outbuf;
outbytesleft = sizeof(outbuf);
r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);
- fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout);
- if (r == (size_t)(-1) && errno != EINVAL && errno != E2BIG)
+ fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);
+ if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in)))
{
perror("conversion error");
return 1;
@@ -1951,7 +2077,7 @@ main(int argc, char **argv)
pout = outbuf;
outbytesleft = sizeof(outbuf);
r = iconv(cd, NULL, NULL, &pout, &outbytesleft);
- fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout);
+ fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);
if (r == (size_t)(-1))
{
perror("conversion error");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]