bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new module 'iconv_open'


From: Bruno Haible
Subject: new module 'iconv_open'
Date: Sat, 31 Mar 2007 22:59:47 +0200
User-agent: KMail/1.5.4

Some proprietary iconv() implementations (IRIX, OSF/1, Solaris) are
actually usable if
  1. one is willing to do an indirect conversion (through UTF-8) if a direct
     conversion between two encodings doesn't exist,
  2. one maps the standardized encoding names to the implementation specific
     ones (not needed on Solaris).

2007-03-31  Bruno Haible  <address@hidden>

        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.

=========================== modules/iconv_open ===============================
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 <iconv.h> when the system
# doesn't have one that works with the given compiler.
iconv.h: iconv_.h
        rm -f address@hidden $@
        { 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; \
        } > address@hidden
        mv address@hidden $@
MOSTLYCLEANFILES += iconv.h iconv.h-t

GPERF = gperf
iconv_open-aix.h: iconv_open-aix.gperf
        $(GPERF) -m 10 iconv_open-aix.gperf > address@hidden
        mv address@hidden $@
iconv_open-hpux.h: iconv_open-hpux.gperf
        $(GPERF) -m 10 iconv_open-hpux.gperf > address@hidden
        mv address@hidden $@
iconv_open-irix.h: iconv_open-irix.gperf
        $(GPERF) -m 10 iconv_open-irix.gperf > address@hidden
        mv address@hidden $@
iconv_open-osf.h: iconv_open-osf.gperf
        $(GPERF) -m 10 iconv_open-osf.gperf > address@hidden
        mv address@hidden $@
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:
<iconv.h>

License:
LGPL

Maintainer:
Bruno Haible

============================= lib/iconv_.h ===================================
/* A GNU-like <iconv.h>.

   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
============================= m4/iconv_h.m4 ==================================
# 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])
])
=========================== lib/ionv_open.c ==================================
/* 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 <config.h>

/* Specification.  */
#include <iconv.h>

#include <errno.h>
#include <string.h>
#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);
}
========================= lib/iconv_open-aix.gperf ===========================
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"
========================= lib/iconv_open-hpux.gperf ==========================
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"
========================= lib/iconv_open-irix.gperf ==========================
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"
========================= lib/iconv_open-osf.gperf ===========================
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"
============================ m4/iconv_open.m4 ================================
# 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 <iconv.h>
      #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
])

==============================================================================
*** modules/linebreak   28 Jan 2007 02:04:41 -0000      1.5
--- modules/linebreak   31 Mar 2007 20:46:36 -0000
***************
*** 11,16 ****
--- 11,17 ----
  localcharset
  c-ctype
  iconv
+ iconv_open
  utf8-ucs4-unsafe
  utf16-ucs4-unsafe
  xsize
*** modules/striconv    9 Sep 2006 19:02:08 -0000       1.2
--- modules/striconv    31 Mar 2007 20:46:36 -0000
***************
*** 7,12 ****
--- 7,13 ----
  
  Depends-on:
  iconv
+ iconv_open
  strdup
  c-strcase
  
*** modules/striconveh  28 Mar 2007 21:50:51 -0000      1.5
--- modules/striconveh  31 Mar 2007 20:46:36 -0000
***************
*** 8,13 ****
--- 8,14 ----
  Depends-on:
  stdbool
  iconv
+ iconv_open
  unistr/u8-prev
  unistr/u8-mbtouc-unsafe
  unistr/u8-mbtouc
*** modules/unicodeio   6 Jul 2005 15:58:47 -0000       1.6
--- modules/unicodeio   31 Mar 2007 20:46:36 -0000
***************
*** 8,13 ****
--- 8,14 ----
  
  Depends-on:
  iconv
+ iconv_open
  gettext-h
  localcharset
  error
*** lib/striconveh.h    23 Jan 2007 01:17:42 -0000      1.6
--- lib/striconveh.h    31 Mar 2007 20:46:36 -0000
***************
*** 42,48 ****
  
  /* Convert an entire string from one encoding to another, using iconv.
     The original string is at [SRC,...,SRC+SRCLEN-1].
!    The conversion descriptor from FROMCODE to TOCODE is passed as CD.
     CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or
     (iconv_t)(-1) if FROM_CODESET is UTF-8).
     CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1)
--- 42,49 ----
  
  /* Convert an entire string from one encoding to another, using iconv.
     The original string is at [SRC,...,SRC+SRCLEN-1].
!    CD is the conversion descriptor from FROMCODE to TOCODE, or (iconv_t)(-1) 
if
!    the system does not support a direct conversion from FROMCODE to TOCODE.
     CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or
     (iconv_t)(-1) if FROM_CODESET is UTF-8).
     CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1)
***************
*** 67,75 ****
  
  /* Convert an entire string from one encoding to another, using iconv.
     The original string is the NUL-terminated string starting at SRC.
!    The conversion descriptor is passed as CD.  Both the "from" and the "to"
!    encoding must use a single NUL byte at the end of the string (i.e. not
!    UCS-2, UCS-4, UTF-16, UTF-32).
     CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or
     (iconv_t)(-1) if FROM_CODESET is UTF-8).
     CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1)
--- 68,77 ----
  
  /* Convert an entire string from one encoding to another, using iconv.
     The original string is the NUL-terminated string starting at SRC.
!    CD is the conversion descriptor from FROMCODE to TOCODE, or (iconv_t)(-1) 
if
!    the system does not support a direct conversion from FROMCODE to TOCODE.
!    Both the "from" and the "to" encoding must use a single NUL byte at the end
!    of the string (i.e. not UCS-2, UCS-4, UTF-16, UTF-32).
     CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or
     (iconv_t)(-1) if FROM_CODESET is UTF-8).
     CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1)
*** lib/striconveh.c    28 Mar 2007 22:25:24 -0000      1.14
--- lib/striconveh.c    31 Mar 2007 20:46:36 -0000
***************
*** 283,288 ****
--- 283,292 ----
      }
    result = initial_result;
  
+   /* Test whether a direct conversion is possible at all.  */
+   if (cd == (iconv_t)(-1))
+     goto indirectly;
+ 
    if (offsets != NULL)
      {
        size_t i;
***************
*** 481,488 ****
    goto done;
  
   indirectly:
!   /* The direct conversion failed, handler != iconveh_error,
!      and cd2 != (iconv_t)(-1).
       Use a conversion through UTF-8.  */
    if (offsets != NULL)
      {
--- 485,491 ----
    goto done;
  
   indirectly:
!   /* The direct conversion failed.
       Use a conversion through UTF-8.  */
    if (offsets != NULL)
      {
***************
*** 495,500 ****
--- 498,504 ----
      }
    length = 0;
    {
+     const bool slowly = (offsets != NULL || handler == iconveh_error);
  # define utf8bufsize 4096 /* may also be smaller or larger than tmpbufsize */
      char utf8buf[utf8bufsize + 1];
      size_t utf8len = 0;
***************
*** 509,515 ****
      /* Set to the initial state.  */
      if (cd1 != (iconv_t)(-1))
        iconv (cd1, NULL, NULL, NULL, NULL);
!     iconv (cd2, NULL, NULL, NULL, NULL);
  # endif
  
      while (in1size > 0 || do_final_flush1 || utf8len > 0 || do_final_flush2)
--- 513,520 ----
      /* Set to the initial state.  */
      if (cd1 != (iconv_t)(-1))
        iconv (cd1, NULL, NULL, NULL, NULL);
!     if (cd2 != (iconv_t)(-1))
!       iconv (cd2, NULL, NULL, NULL, NULL);
  # endif
  
      while (in1size > 0 || do_final_flush1 || utf8len > 0 || do_final_flush2)
***************
*** 531,537 ****
              }
            if (cd1 != (iconv_t)(-1))
              {
!               if (offsets != NULL)
                  res1 = iconv_carefully_1 (cd1,
                                            &in1ptr, &in1size,
                                            &out1ptr, &out1size,
--- 536,542 ----
              }
            if (cd1 != (iconv_t)(-1))
              {
!               if (slowly)
                  res1 = iconv_carefully_1 (cd1,
                                            &in1ptr, &in1size,
                                            &out1ptr, &out1size,
***************
*** 545,551 ****
            else
              {
                /* FROM_CODESET is UTF-8.  */
!               res1 = utf8conv_carefully (offsets != NULL,
                                           &in1ptr, &in1size,
                                           &out1ptr, &out1size,
                                           &incremented1);
--- 550,556 ----
            else
              {
                /* FROM_CODESET is UTF-8.  */
!               res1 = utf8conv_carefully (slowly,
                                           &in1ptr, &in1size,
                                           &out1ptr, &out1size,
                                           &incremented1);
***************
*** 618,627 ****
                bool grow;
  
                if (in2size > 0)
!                 res2 = iconv_carefully (cd2,
!                                         &in2ptr, &in2size,
!                                         &out2ptr, &out2size,
!                                         &incremented2);
                else /* in1size == 0 && !do_final_flush1
                        && in2size == 0 && do_final_flush2 */
                  {
--- 623,641 ----
                bool grow;
  
                if (in2size > 0)
!                 {
!                   if (cd2 != (iconv_t)(-1))
!                     res2 = iconv_carefully (cd2,
!                                             &in2ptr, &in2size,
!                                             &out2ptr, &out2size,
!                                             &incremented2);
!                   else
!                     /* TO_CODESET is UTF-8.  */
!                     res2 = utf8conv_carefully (false,
!                                                &in2ptr, &in2size,
!                                                &out2ptr, &out2size,
!                                                &incremented2);
!                 }
                else /* in1size == 0 && !do_final_flush1
                        && in2size == 0 && do_final_flush2 */
                  {
***************
*** 629,638 ****
                       state.  But avoid glibc-2.1 bug and Solaris 2.7 bug.  */
  # if defined _LIBICONV_VERSION \
       || !((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) || defined __sun)
!                   res2 = iconv (cd2, NULL, NULL, &out2ptr, &out2size);
! # else
!                   res2 = 0;
  # endif
                    do_final_flush2 = false;
                    incremented2 = true;
                  }
--- 643,653 ----
                       state.  But avoid glibc-2.1 bug and Solaris 2.7 bug.  */
  # if defined _LIBICONV_VERSION \
       || !((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) || defined __sun)
!                   if (cd2 != (iconv_t)(-1))
!                     res2 = iconv (cd2, NULL, NULL, &out2ptr, &out2size);
!                   else
  # endif
+                     res2 = 0;
                    do_final_flush2 = false;
                    incremented2 = true;
                  }
***************
*** 703,711 ****
  
                        inptr = scratchbuf;
                        insize = scratchlen;
!                       res = iconv (cd2,
!                                    (ICONV_CONST char **) &inptr, &insize,
!                                    &out2ptr, &out2size);
                        length = out2ptr - result;
                        if (res == (size_t)(-1) && errno == E2BIG)
                          {
--- 718,745 ----
  
                        inptr = scratchbuf;
                        insize = scratchlen;
!                       if (cd2 != (iconv_t)(-1))
!                         res = iconv (cd2,
!                                      (ICONV_CONST char **) &inptr, &insize,
!                                      &out2ptr, &out2size);
!                       else
!                         {
!                           /* TO_CODESET is UTF-8.  */
!                           if (out2size >= insize)
!                             {
!                               memcpy (out2ptr, inptr, insize);
!                               out2ptr += insize;
!                               out2size -= insize;
!                               inptr += insize;
!                               insize = 0;
!                               res = 0;
!                             }
!                           else
!                             {
!                               errno = E2BIG;
!                               res = (size_t)(-1);
!                             }
!                         }
                        length = out2ptr - result;
                        if (res == (size_t)(-1) && errno == E2BIG)
                          {
***************
*** 732,740 ****
  
                            out2ptr = result + length;
                            out2size = allocated - extra_alloc - length;
!                           res = iconv (cd2,
!                                        (ICONV_CONST char **) &inptr, &insize,
!                                        &out2ptr, &out2size);
                            length = out2ptr - result;
                          }
  # if !defined _LIBICONV_VERSION && !defined __GLIBC__
--- 766,788 ----
  
                            out2ptr = result + length;
                            out2size = allocated - extra_alloc - length;
!                           if (cd2 != (iconv_t)(-1))
!                             res = iconv (cd2,
!                                          (ICONV_CONST char **) &inptr,
!                                          &insize,
!                                          &out2ptr, &out2size);
!                           else
!                             {
!                               /* TO_CODESET is UTF-8.  */
!                               if (!(out2size >= insize))
!                                 abort ();
!                               memcpy (out2ptr, inptr, insize);
!                               out2ptr += insize;
!                               out2size -= insize;
!                               inptr += insize;
!                               insize = 0;
!                               res = 0;
!                             }
                            length = out2ptr - result;
                          }
  # if !defined _LIBICONV_VERSION && !defined __GLIBC__
***************
*** 952,959 ****
  # endif
  
        cd = iconv_open (to_codeset, from_codeset);
-       if (cd == (iconv_t)(-1))
-       return -1;
  
        if (STRCASEEQ (from_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0))
        cd1 = (iconv_t)(-1);
--- 1000,1005 ----
***************
*** 963,969 ****
          if (cd1 == (iconv_t)(-1))
            {
              int saved_errno = errno;
!             iconv_close (cd);
              errno = saved_errno;
              return -1;
            }
--- 1009,1016 ----
          if (cd1 == (iconv_t)(-1))
            {
              int saved_errno = errno;
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              errno = saved_errno;
              return -1;
            }
***************
*** 979,985 ****
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             iconv_close (cd);
              errno = saved_errno;
              return -1;
            }
--- 1026,1033 ----
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              errno = saved_errno;
              return -1;
            }
***************
*** 998,1004 ****
            iconv_close (cd2);
          if (cd1 != (iconv_t)(-1))
            iconv_close (cd1);
!         iconv_close (cd);
          errno = saved_errno;
        }
        else
--- 1046,1053 ----
            iconv_close (cd2);
          if (cd1 != (iconv_t)(-1))
            iconv_close (cd1);
!         if (cd != (iconv_t)(-1))
!           iconv_close (cd);
          errno = saved_errno;
        }
        else
***************
*** 1010,1016 ****
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             iconv_close (cd);
              if (result != *resultp && result != NULL)
                free (result);
              errno = saved_errno;
--- 1059,1066 ----
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              if (result != *resultp && result != NULL)
                free (result);
              errno = saved_errno;
***************
*** 1021,1033 ****
              /* Return -1, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
              int saved_errno = errno;
!             iconv_close (cd);
              if (result != *resultp && result != NULL)
                free (result);
              errno = saved_errno;
              return -1;
            }
!         if (iconv_close (cd) < 0)
            {
              /* Return -1, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
--- 1071,1084 ----
              /* Return -1, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
              int saved_errno = errno;
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              if (result != *resultp && result != NULL)
                free (result);
              errno = saved_errno;
              return -1;
            }
!         if (cd != (iconv_t)(-1) && iconv_close (cd) < 0)
            {
              /* Return -1, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
***************
*** 1085,1092 ****
  # endif
  
        cd = iconv_open (to_codeset, from_codeset);
-       if (cd == (iconv_t)(-1))
-       return NULL;
  
        if (STRCASEEQ (from_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0))
        cd1 = (iconv_t)(-1);
--- 1136,1141 ----
***************
*** 1096,1102 ****
          if (cd1 == (iconv_t)(-1))
            {
              int saved_errno = errno;
!             iconv_close (cd);
              errno = saved_errno;
              return NULL;
            }
--- 1145,1152 ----
          if (cd1 == (iconv_t)(-1))
            {
              int saved_errno = errno;
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              errno = saved_errno;
              return NULL;
            }
***************
*** 1112,1118 ****
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             iconv_close (cd);
              errno = saved_errno;
              return NULL;
            }
--- 1162,1169 ----
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              errno = saved_errno;
              return NULL;
            }
***************
*** 1128,1134 ****
            iconv_close (cd2);
          if (cd1 != (iconv_t)(-1))
            iconv_close (cd1);
!         iconv_close (cd);
          errno = saved_errno;
        }
        else
--- 1179,1186 ----
            iconv_close (cd2);
          if (cd1 != (iconv_t)(-1))
            iconv_close (cd1);
!         if (cd != (iconv_t)(-1))
!           iconv_close (cd);
          errno = saved_errno;
        }
        else
***************
*** 1140,1146 ****
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             iconv_close (cd);
              free (result);
              errno = saved_errno;
              return NULL;
--- 1192,1199 ----
              int saved_errno = errno;
              if (cd1 != (iconv_t)(-1))
                iconv_close (cd1);
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              free (result);
              errno = saved_errno;
              return NULL;
***************
*** 1150,1161 ****
              /* Return NULL, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
              int saved_errno = errno;
!             iconv_close (cd);
              free (result);
              errno = saved_errno;
              return NULL;
            }
!         if (iconv_close (cd) < 0)
            {
              /* Return NULL, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
--- 1203,1215 ----
              /* Return NULL, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */
              int saved_errno = errno;
!             if (cd != (iconv_t)(-1))
!               iconv_close (cd);
              free (result);
              errno = saved_errno;
              return NULL;
            }
!         if (cd != (iconv_t)(-1) && iconv_close (cd) < 0)
            {
              /* Return NULL, but free the allocated memory, and while doing
                 that, preserve the errno from iconv_close.  */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]