bug-gnulib
[Top][All Lists]
Advanced

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

[bug-gnulib] Re: iconv made easy


From: Simon Josefsson
Subject: [bug-gnulib] Re: iconv made easy
Date: Thu, 16 Dec 2004 02:04:09 +0100
User-agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3.50 (gnu/linux)

Simon Josefsson <address@hidden> writes:

> Should I propose a patch, or do you want to merge it?

Or how about installing the following subset of Bruno's more complete
interface?  The public interface is the same, so the implementation
could be modified to use the gettext iconv approach later on.

This is what just released GNU SASL 0.2.3 uses.

(I had problems merging the implementations myself, based on Bruno's
message, it seems some parts of the functions had been cut out.  For
example, there where two functions called iconv_string, and one of
them used variables that weren't declared.)

Thanks.

Index: lib/iconvme.c
===================================================================
RCS file: lib/iconvme.c
diff -N lib/iconvme.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/iconvme.c       16 Dec 2004 01:00:06 -0000
@@ -0,0 +1,150 @@
+/* Recode strings between character sets, using iconv.
+   Copyright (C) 2002, 2003, 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Get prototype. */
+#include "iconvme.h"
+
+/* Get malloc. */
+#include <stdlib.h>
+
+/* Get strcmp. */
+#include <string.h>
+
+/* Get errno. */
+#include <errno.h>
+
+#if HAVE_ICONV
+/* Get iconv etc. */
+# include <iconv.h>
+/* Get MB_LEN_MAX. */
+# include <limits.h>
+#endif
+
+/* Convert a zero-terminated string from one code set to another.  The
+   returned string is allocated using malloc, and must be dellocated
+   by the caller using free.  On failure, NULL is returned and errno
+   holds the error reason.  Note that this function does not handle
+   embedded zero's in the output well.  */
+char *
+iconv_string (const char *str, const char *from_codeset, const char 
*to_codeset)
+{
+  char *dest = NULL;
+#if HAVE_ICONV
+  iconv_t cd;
+  char *outp;
+  ICONV_CONST char *p;
+  size_t inbytes_remaining;
+  size_t outbytes_remaining;
+  size_t err;
+  size_t outbuf_size;
+  int have_error = 0;
+#endif
+
+  if (strcmp (to_codeset, from_codeset) == 0)
+    {
+      char *q;
+
+      q = malloc (strlen (str) + 1);
+      if (!q)
+       return NULL;
+
+      return strcpy (q, str);
+    }
+
+#if HAVE_ICONV
+  cd = iconv_open (to_codeset, from_codeset);
+
+  if (cd == (iconv_t) - 1)
+    return NULL;
+
+  p = (ICONV_CONST char *) str;
+
+  inbytes_remaining = strlen (p);
+  /* Guess the maximum length the output string can have.  */
+  outbuf_size = (inbytes_remaining + 1) * MB_LEN_MAX;
+
+  outp = dest = malloc (outbuf_size);
+  if (dest == NULL)
+    goto out;
+  outbytes_remaining = outbuf_size - 1;        /* -1 for NUL */
+
+again:
+
+  err = iconv (cd, &p, &inbytes_remaining, &outp, &outbytes_remaining);
+
+  if (err == (size_t) - 1)
+    {
+      switch (errno)
+       {
+       case EINVAL:
+         /* Incomplete text, do not report an error */
+         break;
+
+       case E2BIG:
+         {
+           size_t used = outp - dest;
+           char *newdest;
+
+           outbuf_size *= 2;
+           newdest = realloc (dest, outbuf_size);
+           if (newdest == NULL)
+             {
+               have_error = 1;
+               goto out;
+             }
+           dest = newdest;
+
+           outp = dest + used;
+           outbytes_remaining = outbuf_size - used - 1;        /* -1 for NUL */
+
+           goto again;
+         }
+         break;
+
+       case EILSEQ:
+         have_error = 1;
+         break;
+
+       default:
+         have_error = 1;
+         break;
+       }
+    }
+
+  *outp = '\0';
+
+  if (*p != '\0')
+    have_error = 1;
+
+out:
+  iconv_close (cd);
+
+  if (have_error)
+    {
+      free (dest);
+      dest = NULL;
+    }
+#else
+  errno = ENOSYS;
+#endif
+
+  return dest;
+}
Index: lib/iconvme.h
===================================================================
RCS file: lib/iconvme.h
diff -N lib/iconvme.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/iconvme.h       16 Dec 2004 01:00:06 -0000
@@ -0,0 +1,25 @@
+/* Recode strings between character sets, using iconv.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   Written by Simon Josefsson.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef ICONVME_H
+# define ICONVME_H
+
+extern char *iconv_string (const char *string, const char *from_code,
+                          const char *to_code);
+
+#endif /* ICONVME_H */
Index: m4/iconvme.m4
===================================================================
RCS file: m4/iconvme.m4
diff -N m4/iconvme.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/iconvme.m4       16 Dec 2004 01:00:06 -0000
@@ -0,0 +1,17 @@
+# iconvme.m4 serial 1
+dnl Copyright (C) 2004 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+AC_DEFUN([gl_ICONVME],
+[
+  gl_PREREQ_ICONVME
+])
+
+# Prerequisites of lib/iconvme.c.
+AC_DEFUN([gl_PREREQ_ICONVME], [
+  AC_REQUIRE([AM_ICONV])
+])
Index: modules/iconvme
===================================================================
RCS file: modules/iconvme
diff -N modules/iconvme
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ modules/iconvme     16 Dec 2004 01:00:06 -0000
@@ -0,0 +1,26 @@
+Description:
+Character set conversion of strings made easy, uses iconv.
+
+Files:
+lib/iconvme.h
+lib/iconvme.c
+m4/iconvme.m4
+
+Depends-on:
+iconv
+
+configure.ac:
+gl_ICONVME
+
+Makefile.am:
+lib_SOURCES += iconvme.h iconvme.c
+lib_LIBADD += $(LTLIBICONV)
+
+Include:
+"iconvme.h"
+
+License:
+LGPL
+
+Maintainer:
+Simon Josefsson
Index: tests/test-iconvme.c
===================================================================
RCS file: tests/test-iconvme.c
diff -N tests/test-iconvme.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/test-iconvme.c        16 Dec 2004 01:00:06 -0000
@@ -0,0 +1,81 @@
+/* Recode strings between character sets, using iconv.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   Written by Simon Josefsson.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "iconvme.h"
+
+int main (int ac, char *av[])
+{
+  char *in = NULL, *out = NULL;
+  char *to = NULL, *from = NULL;
+
+  if (ac > 1)
+    from = av[1];
+
+  if (ac > 2)
+    to = av[2];
+
+  if (ac > 3)
+    in = av[3];
+
+  if (!in)
+    {
+      size_t len = 0;
+      printf ("Enter string to convert:\n\t> ");
+      if (getline (&in, &len, stdin) < 0)
+       perror ("getline");
+      if (in[strlen (in) - 1] == '\n')
+       in[strlen (in) - 1] = '\0';
+    }
+
+  if (!to)
+    {
+      size_t len = 0;
+      printf ("Enter destination code set:\n\t> ");
+      if (getline (&to, &len, stdin) < 0)
+       perror ("getline");
+      if (to[strlen (to) - 1] == '\n')
+       to[strlen (to) - 1] = '\0';
+    }
+
+  if (!from)
+    {
+      size_t len = 0;
+      printf ("Enter source code set:\n\t> ");
+      if (getline (&from, &len, stdin) < 0)
+       perror ("getline");
+      if (from[strlen (from) - 1] == '\n')
+       from[strlen (from) - 1] = '\0';
+    }
+
+  printf (" Input string: `%s'\n"
+         "From code set: `%s'\n"
+         "  To code set: `%s'\n",
+         in, from, to);
+
+  out = iconv_string (in, from, to);
+
+  if (out == NULL)
+    perror ("iconv");
+  else
+    printf ("\nOutput: `%s'\n", out);
+
+  return EXIT_SUCCESS;
+}





reply via email to

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