From 8119dc1622611078f2fca227cf94d65ab1765ce5 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 31 Mar 2007 21:00:19 +0000 Subject: [PATCH] New module 'iconv_open'. --- ChangeLog | 23 ++++++++++ lib/iconv_.h | 42 ++++++++++++++++++ lib/iconv_open-aix.gperf | 44 ++++++++++++++++++ lib/iconv_open-hpux.gperf | 56 +++++++++++++++++++++++ lib/iconv_open-irix.gperf | 31 +++++++++++++ lib/iconv_open-osf.gperf | 50 +++++++++++++++++++++ lib/iconv_open.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++ m4/iconv_h.m4 | 28 ++++++++++++ m4/iconv_open.m4 | 40 +++++++++++++++++ modules/iconv_open | 64 ++++++++++++++++++++++++++ 10 files changed, 489 insertions(+) create mode 100644 lib/iconv_.h create mode 100644 lib/iconv_open-aix.gperf create mode 100644 lib/iconv_open-hpux.gperf create mode 100644 lib/iconv_open-irix.gperf create mode 100644 lib/iconv_open-osf.gperf create mode 100644 lib/iconv_open.c create mode 100644 m4/iconv_h.m4 create mode 100644 m4/iconv_open.m4 create mode 100644 modules/iconv_open diff --git a/ChangeLog b/ChangeLog index 87531f289..78287bc93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,28 @@ 2007-03-31 Bruno Haible + Support old proprietary implementations of iconv. + * modules/iconv_open: New file. + * lib/iconv_.h: New file. + * m4/iconv_h.m4: New file. + * lib/iconv_open.c: New file. + * lib/iconv_open-aix.gperf: New file. + * lib/iconv_open-hpux.gperf: New file. + * lib/iconv_open-irix.gperf: New file. + * lib/iconv_open-osf.gperf: New file. + * m4/iconv_open.m4: New file. + * modules/linebreak (Depends-on): Add iconv_open. + * modules/striconv (Depends-on): Likewise. + * modules/striconveh (Depends-on): Likewise. + * modules/unicodeio (Depends-on): Likewise. + * lib/striconveh.h (mem_cd_iconveh, str_cd_iconveh): Allow cd to be + (iconv_t)(-1). + * lib/striconveh.c (mem_cd_iconveh_internal): Use an indirect + conversion if cd is (iconv_t)(-1). + (mem_iconveh, str_iconveh): Don't fail just because a direct conversion + is not possible. + +2007-03-31 Bruno Haible + * tests/test-striconveha.c (main): Don't expect "autodetect_jp" to work on Solaris either. Protect also second use of "autodetect_jp". diff --git a/lib/iconv_.h b/lib/iconv_.h new file mode 100644 index 000000000..9d4ecefe4 --- /dev/null +++ b/lib/iconv_.h @@ -0,0 +1,42 @@ +/* A GNU-like . + + Copyright (C) 2007 Free Software Foundation, Inc. + + This program 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 program 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 program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_ICONV_H +#define _GL_ICONV_H + +#include @ABSOLUTE_ICONV_H@ + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if @REPLACE_ICONV_OPEN@ +/* An iconv_open wrapper that supports the IANA standardized encoding names + ("ISO-8859-1" etc.) as far as possible. */ +# define iconv_open rpl_iconv_open +extern iconv_t iconv_open (const char *tocode, const char *fromcode); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/iconv_open-aix.gperf b/lib/iconv_open-aix.gperf new file mode 100644 index 000000000..6782b9956 --- /dev/null +++ b/lib/iconv_open-aix.gperf @@ -0,0 +1,44 @@ +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On AIX 5.1, look in /usr/lib/nls/loc/uconvTable. +ISO-8859-1, "ISO8859-1" +ISO-8859-2, "ISO8859-2" +ISO-8859-3, "ISO8859-3" +ISO-8859-4, "ISO8859-4" +ISO-8859-5, "ISO8859-5" +ISO-8859-6, "ISO8859-6" +ISO-8859-7, "ISO8859-7" +ISO-8859-8, "ISO8859-8" +ISO-8859-9, "ISO8859-9" +ISO-8859-15, "ISO8859-15" +CP437, "IBM-437" +CP850, "IBM-850" +CP852, "IBM-852" +CP856, "IBM-856" +CP857, "IBM-857" +CP861, "IBM-861" +CP865, "IBM-865" +CP869, "IBM-869" +ISO-8859-13, "IBM-921" +CP922, "IBM-922" +CP932, "IBM-932" +CP943, "IBM-943" +CP1046, "IBM-1046" +CP1124, "IBM-1124" +CP1125, "IBM-1125" +CP1129, "IBM-1129" +CP1252, "IBM-1252" +GB2312, "IBM-eucCN" +EUC-JP, "IBM-eucJP" +EUC-KR, "IBM-eucKR" +EUC-TW, "IBM-eucTW" +BIG5, "big5" diff --git a/lib/iconv_open-hpux.gperf b/lib/iconv_open-hpux.gperf new file mode 100644 index 000000000..5a35c83e1 --- /dev/null +++ b/lib/iconv_open-hpux.gperf @@ -0,0 +1,56 @@ +struct mapping { int standard_name; const char vendor_name[9 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On HP-UX 11.11, look in /usr/lib/nls/iconv. +ISO-8859-1, "iso88591" +ISO-8859-2, "iso88592" +ISO-8859-5, "iso88595" +ISO-8859-6, "iso88596" +ISO-8859-7, "iso88597" +ISO-8859-8, "iso88598" +ISO-8859-9, "iso88599" +ISO-8859-15, "iso885915" +CP437, "cp437" +CP775, "cp775" +CP850, "cp850" +CP852, "cp852" +CP855, "cp855" +CP857, "cp857" +CP861, "cp861" +CP862, "cp862" +CP864, "cp864" +CP865, "cp865" +CP866, "cp866" +CP869, "cp869" +CP874, "cp874" +CP1250, "cp1250" +CP1251, "cp1251" +CP1252, "cp1252" +CP1253, "cp1253" +CP1254, "cp1254" +CP1255, "cp1255" +CP1256, "cp1256" +CP1257, "cp1257" +CP1258, "cp1258" +HP-ROMAN8, "roman8" +HP-ARABIC8, "arabic8" +HP-GREEK8, "greek8" +HP-HEBREW8, "hebrew8" +HP-TURKISH8, "turkish8" +HP-KANA8, "kana8" +TIS-620, "tis620" +GB2312, "hp15CN" +EUC-JP, "eucJP" +EUC-KR, "eucKR" +EUC-TW, "eucTW" +BIG5, "big5" +SHIFT_JIS, "sjis" +UTF-8, "utf8" diff --git a/lib/iconv_open-irix.gperf b/lib/iconv_open-irix.gperf new file mode 100644 index 000000000..3672a8013 --- /dev/null +++ b/lib/iconv_open-irix.gperf @@ -0,0 +1,31 @@ +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On IRIX 6.5, look in /usr/lib/iconv and /usr/lib/international/encodings. +ISO-8859-1, "ISO8859-1" +ISO-8859-2, "ISO8859-2" +ISO-8859-3, "ISO8859-3" +ISO-8859-4, "ISO8859-4" +ISO-8859-5, "ISO8859-5" +ISO-8859-6, "ISO8859-6" +ISO-8859-7, "ISO8859-7" +ISO-8859-8, "ISO8859-8" +ISO-8859-9, "ISO8859-9" +ISO-8859-15, "ISO8859-15" +KOI8-R, "KOI8" +CP855, "DOS855" +CP1251, "WIN1251" +GB2312, "eucCN" +EUC-JP, "eucJP" +EUC-KR, "eucKR" +EUC-TW, "eucTW" +SHIFT_JIS, "sjis" +TIS-620, "TIS620" diff --git a/lib/iconv_open-osf.gperf b/lib/iconv_open-osf.gperf new file mode 100644 index 000000000..f468ff609 --- /dev/null +++ b/lib/iconv_open-osf.gperf @@ -0,0 +1,50 @@ +struct mapping { int standard_name; const char vendor_name[10 + 1]; }; +%struct-type +%language=ANSI-C +%define slot-name standard_name +%define hash-function-name mapping_hash +%define lookup-function-name mapping_lookup +%readonly-tables +%global-table +%define word-array-name mappings +%pic +%% +# On OSF/1 5.1, look in /usr/lib/nls/loc/iconv. +ISO-8859-1, "ISO8859-1" +ISO-8859-2, "ISO8859-2" +ISO-8859-3, "ISO8859-3" +ISO-8859-4, "ISO8859-4" +ISO-8859-5, "ISO8859-5" +ISO-8859-6, "ISO8859-6" +ISO-8859-7, "ISO8859-7" +ISO-8859-8, "ISO8859-8" +ISO-8859-9, "ISO8859-9" +ISO-8859-15, "ISO8859-15" +CP437, "cp437" +CP775, "cp775" +CP850, "cp850" +CP852, "cp852" +CP855, "cp855" +CP857, "cp857" +CP861, "cp861" +CP862, "cp862" +CP865, "cp865" +CP866, "cp866" +CP869, "cp869" +CP874, "cp874" +CP949, "KSC5601" +CP1250, "cp1250" +CP1251, "cp1251" +CP1252, "cp1252" +CP1253, "cp1253" +CP1254, "cp1254" +CP1255, "cp1255" +CP1256, "cp1256" +CP1257, "cp1257" +CP1258, "cp1258" +EUC-JP, "eucJP" +EUC-KR, "eucKR" +EUC-TW, "eucTW" +BIG5, "big5" +SHIFT_JIS, "SJIS" +TIS-620, "TACTIS" diff --git a/lib/iconv_open.c b/lib/iconv_open.c new file mode 100644 index 000000000..f78cbb48d --- /dev/null +++ b/lib/iconv_open.c @@ -0,0 +1,111 @@ +/* Character set conversion. + Copyright (C) 2007 Free Software Foundation, Inc. + + This program 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 program 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 program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +#include +#include +#include "c-ctype.h" + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + +/* Namespace cleanliness. */ +#define mapping_lookup rpl_iconv_open_mapping_lookup + +/* The macro ICONV_FLAVOR is defined to one of these. */ + +#define ICONV_FLAVOR_AIX "iconv_open-aix.h" +#define ICONV_FLAVOR_HPUX "iconv_open-hpux.h" +#define ICONV_FLAVOR_IRIX "iconv_open-irix.h" +#define ICONV_FLAVOR_OSF "iconv_open-osf.h" + +#include ICONV_FLAVOR + +iconv_t +rpl_iconv_open (const char *tocode, const char *fromcode) +#undef iconv_open +{ + char fromcode_upper[32]; + char tocode_upper[32]; + char *fromcode_upper_end; + char *tocode_upper_end; + + /* Try with the original names first. + This covers the case when fromcode or tocode is a lowercase encoding name + that is understood by the system's iconv_open but not listed in our + mappings table. */ + { + iconv_t cd = iconv_open (tocode, fromcode); + if (cd != (iconv_t)(-1)) + return cd; + } + + /* Convert the encodings to upper case, because + 1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case + matters, + 2. it makes searching in the table faster. */ + { + const char *p = fromcode; + char *q = fromcode_upper; + while ((*q = c_toupper (*p)) != '\0') + { + p++; + q++; + if (q == &fromcode_upper[SIZEOF (fromcode_upper)]) + { + errno = EINVAL; + return (iconv_t)(-1); + } + } + fromcode_upper_end = q; + } + + { + const char *p = tocode; + char *q = tocode_upper; + while ((*q = c_toupper (*p)) != '\0') + { + p++; + q++; + if (q == &tocode_upper[SIZEOF (tocode_upper)]) + { + errno = EINVAL; + return (iconv_t)(-1); + } + } + tocode_upper_end = q; + } + + /* Apply the mappings. */ + { + const struct mapping *m = + mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper); + + fromcode = (m != NULL ? m->vendor_name : fromcode_upper); + } + { + const struct mapping *m = + mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper); + + tocode = (m != NULL ? m->vendor_name : tocode_upper); + } + + return iconv_open (tocode, fromcode); +} diff --git a/m4/iconv_h.m4 b/m4/iconv_h.m4 new file mode 100644 index 000000000..a4324f96b --- /dev/null +++ b/m4/iconv_h.m4 @@ -0,0 +1,28 @@ +# iconv_h.m4 serial 1 +dnl Copyright (C) 2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ICONV_H], +[ + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + gl_ABSOLUTE_HEADER([iconv.h]) + ABSOLUTE_ICONV_H=\"$gl_cv_absolute_iconv_h\" + AC_SUBST([ABSOLUTE_ICONV_H]) + ICONV_H= + AC_SUBST([ICONV_H]) +]) + +AC_DEFUN([gl_ICONV_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1 +]) + +AC_DEFUN([gl_ICONV_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + REPLACE_ICONV_OPEN=0; AC_SUBST([REPLACE_ICONV_OPEN]) +]) diff --git a/m4/iconv_open.m4 b/m4/iconv_open.m4 new file mode 100644 index 000000000..7ed808ab3 --- /dev/null +++ b/m4/iconv_open.m4 @@ -0,0 +1,40 @@ +# iconv_open.m4 serial 1 +dnl Copyright (C) 2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_ICONV_OPEN], +[ + AC_REQUIRE([AM_ICONV]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test "$am_cv_func_iconv" = yes; then + dnl Test whether iconv_open accepts standardized encoding names. + dnl We know that GNU libiconv and GNU libc do. + AC_EGREP_CPP([gnu_iconv], [ + #include + #if defined _LIBICONV_VERSION || defined __GLIBC__ + gnu_iconv + #endif + ], [gl_func_iconv_gnu=yes], [gl_func_iconv_gnu=no]) + if test $gl_func_iconv_gnu = no; then + iconv_flavor= + case "$host_os" in + aix*) iconv_flavor=ICONV_FLAVOR_AIX ;; + irix*) iconv_flavor=ICONV_FLAVOR_IRIX ;; + hpux*) iconv_flavor=ICONV_FLAVOR_HPUX ;; + osf*) iconv_flavor=ICONV_FLAVOR_OSF ;; + esac + if test -n "$iconv_flavor"; then + AC_DEFINE_UNQUOTED([ICONV_FLAVOR], [$iconv_flavor], + [Define to a symbolic name denoting the flavor of iconv_open() + implementation.]) + REPLACE_ICONV_OPEN=1 + AC_LIBOBJ([iconv_open]) + ICONV_H='iconv.h' + fi + fi + fi +]) + diff --git a/modules/iconv_open b/modules/iconv_open new file mode 100644 index 000000000..420f56277 --- /dev/null +++ b/modules/iconv_open @@ -0,0 +1,64 @@ +Description: +Character set conversion. + +Files: +lib/iconv_.h +lib/iconv_open.c +lib/iconv_open-aix.gperf +lib/iconv_open-hpux.gperf +lib/iconv_open-irix.gperf +lib/iconv_open-osf.gperf +m4/iconv_h.m4 +m4/iconv_open.m4 + +Depends-on: +absolute-header +iconv +c-ctype + +configure.ac: +gl_ICONV_H +gl_FUNC_ICONV_OPEN + +Makefile.am: +BUILT_SOURCES += $(ICONV_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +iconv.h: iconv_.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''ABSOLUTE_ICONV_H''@|$(ABSOLUTE_ICONV_H)|g' \ + -e 's|@''REPLACE_ICONV_OPEN''@|$(REPLACE_ICONV_OPEN)|g' \ + < $(srcdir)/iconv_.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += iconv.h iconv.h-t + +GPERF = gperf +iconv_open-aix.h: iconv_open-aix.gperf + $(GPERF) -m 10 iconv_open-aix.gperf > $@-t + mv $@-t $@ +iconv_open-hpux.h: iconv_open-hpux.gperf + $(GPERF) -m 10 iconv_open-hpux.gperf > $@-t + mv $@-t $@ +iconv_open-irix.h: iconv_open-irix.gperf + $(GPERF) -m 10 iconv_open-irix.gperf > $@-t + mv $@-t $@ +iconv_open-osf.h: iconv_open-osf.gperf + $(GPERF) -m 10 iconv_open-osf.gperf > $@-t + mv $@-t $@ +BUILT_SOURCES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h +MOSTLYCLEANFILES += iconv_open-aix.h-t iconv_open-hpux.h-t iconv_open-irix.h-t iconv_open-osf.h-t +MAINTAINERCLEANFILES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h +EXTRA_DIST += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h + +Include: + + +License: +LGPL + +Maintainer: +Bruno Haible + -- 2.11.0