RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 21-Sep-2014 08:52:13 Branch: rpm-5_4 Handle: 2014092106521300 Modified files: (Branch: rpm-5_4) rpm/rpmio rpmiotypes.h strtolocale.c Log: - iconv: move from rpmdb/hdrfmt.c. Summary: Revision Changes Path 1.47.2.18 +8 -0 rpm/rpmio/rpmiotypes.h 1.10.6.2 +88 -1 rpm/rpmio/strtolocale.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmio/rpmiotypes.h ============================================================================ $ cvs diff -u -r1.47.2.17 -r1.47.2.18 rpmiotypes.h --- rpm/rpmio/rpmiotypes.h 28 Aug 2014 13:15:01 -0000 1.47.2.17 +++ rpm/rpmio/rpmiotypes.h 21 Sep 2014 06:52:13 -0000 1.47.2.18 @@ -595,6 +595,14 @@ const char * xstrtolocale(/*@only@*/ const char *str) /*@modifies *str @*/; +/** \ingroup rpmio + * Force encoding of string with strdup return. + */ +/*@only@*/ /*@null@*/ +char * xstrdup_iconv_check (/*@null@*/ const char * buffer, + /*@null@*/ const char * tocode) + /*@*/; + /** * Unreference a I/O buffer instance. * @param iob hash table @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/strtolocale.c ============================================================================ $ cvs diff -u -r1.10.6.1 -r1.10.6.2 strtolocale.c --- rpm/rpmio/strtolocale.c 15 Apr 2012 21:20:53 -0000 1.10.6.1 +++ rpm/rpmio/strtolocale.c 21 Sep 2014 06:52:13 -0000 1.10.6.2 @@ -3,6 +3,7 @@ */ #include "system.h" + #ifdef HAVE_LANGINFO_H #include <langinfo.h> #endif @@ -10,12 +11,12 @@ #include <iconv.h> #endif #include <rpmiotypes.h> + #include "debug.h" const char * xstrtolocale(const char *str) { #ifdef HAVE_ICONV - /*@only@*/ static char *locale_encoding = NULL; static int locale_encoding_is_utf8 = 0; iconv_t cd; @@ -77,3 +78,89 @@ return str; #endif } + +#if defined(__GLIBC__) /* XXX todo: find where iconv(3) was implemented. */ +/* XXX using "//TRANSLIT" instead assumes known fromcode? */ +static const char * _iconv_tocode = "UTF-8//IGNORE"; +static const char * _iconv_fromcode = "UTF-8"; +#else +static const char * _iconv_tocode = "UTF-8"; +static const char * _iconv_fromcode = NULL; +#endif + +char * xstrdup_iconv_check (const char * buffer, const char * tocode) +{ + const char *s = buffer; + char *t = NULL; +#if defined(HAVE_ICONV) + const char *fromcode = _iconv_fromcode; + iconv_t fd; + +assert(buffer != NULL); + + if (tocode == NULL) + tocode = _iconv_tocode; +assert(tocode != NULL); + +#ifdef HAVE_LANGINFO_H + /* XXX the current locale's encoding != package data encodings. */ + if (fromcode == NULL) + fromcode = nl_langinfo (CODESET); +#endif +assert(fromcode != NULL); + + if ((fd = iconv_open(tocode, fromcode)) != (iconv_t)-1) { + size_t ileft = strlen(s); + size_t nt = ileft; + char * te = t = xmalloc((nt + 1) * sizeof(*t)); + size_t oleft = ileft; + size_t err = iconv(fd, NULL, NULL, NULL, NULL); + const char *sprev = NULL; + int _iconv_errno = 0; + int done = 0; + + while (done == 0 && _iconv_errno == 0) { + err = iconv(fd, (char **)&s, &ileft, &te, &oleft); + if (err == (size_t)-1) { + switch (errno) { + case E2BIG: + { size_t used = (size_t)(te - t); + nt *= 2; + t = xrealloc(t, (nt + 1) * sizeof(*t)); + te = t + used; + oleft = nt - used; + } break; + case EINVAL: + done = 1; + _iconv_errno = errno; + break; + case EILSEQ: + default: + _iconv_errno = errno; + break; + } + } else + if (sprev == NULL) { + sprev = s; + s = NULL; + ileft = 0; + } else + done = 1; + } + if (iconv_close(fd)) + _iconv_errno = errno; + *te = '\0'; + te = xstrdup(t); + t = _free(t); + t = te; + +if (_iconv_errno) +fprintf(stderr, "warning: %s: from iconv(%s -> %s) for \"%s\" -> \"%s\"\n", strerror(_iconv_errno), fromcode, tocode, buffer, t); + + } else +#endif + t = xstrdup((s ? s : "")); + + return t; +} + @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org