Index: trunk/src/emx/src/lib/iconv/iconv.c
===================================================================
--- trunk/src/emx/src/lib/iconv/iconv.c	(revision 493)
+++ trunk/src/emx/src/lib/iconv/iconv.c	(revision 493)
@@ -0,0 +1,162 @@
+/* OS/2 iconv() implementation through OS/2 Unicode API
+   Copyright (C) 2001-2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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.  */
+
+/*
+   This file implements an iconv wrapper based on OS/2 Unicode API.
+*/
+
+#include <uconv.h>
+
+typedef struct _iconv_t
+{
+  UconvObject from;		/* "From" conversion handle */
+  UconvObject to;		/* "To" conversion handle */
+} *iconv_t;
+
+/* Tell "iconv.h" to not define iconv_t by itself.  */
+#define _ICONV_T
+#include "iconv.h"
+
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <alloca.h>
+
+extern void
+__convert_codepage (const char *cp, UniChar *ucp);
+
+iconv_t
+iconv_open (const char *cp_to, const char *cp_from)
+{
+  UniChar *ucp;
+  iconv_t conv;
+  uconv_attribute_t attr;
+
+  conv = (iconv_t) malloc (sizeof (struct _iconv_t));
+  if (conv == NULL)
+    {
+      errno = ENOMEM;
+      return (iconv_t)(-1);
+    }
+
+  ucp = (UniChar *) alloca ((strlen (cp_from) + 2 + 1) * sizeof (UniChar));
+  __convert_codepage (cp_from, ucp);
+  if (UniCreateUconvObject (ucp, &conv->from))
+    {
+      free (conv);
+      errno = EINVAL;
+      return (iconv_t)(-1);
+    }
+
+  ucp = (UniChar *) alloca ((strlen (cp_to) + 2 + 1) * sizeof (UniChar));
+  __convert_codepage (cp_to, ucp);
+  if (UniCreateUconvObject (ucp, &conv->to))
+    {
+      UniFreeUconvObject (conv->from);
+      free (conv);
+      errno = EINVAL;
+      return (iconv_t)(-1);
+    }
+
+  UniQueryUconvObject (conv->from, &attr, sizeof (attr), NULL, NULL, NULL);
+  /* Do not treat 0x7f as a control character
+     (don't understand what it exactly means but without it MBCS prefix
+     character detection sometimes could fail (when 0x7f is a prefix)).
+     And don't treat the string as a path (the docs also don't explain
+     what it exactly means, but I'm pretty sure converted texts will
+     mostly not be paths).  */
+  attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
+  UniSetUconvObject (conv->from, &attr);
+
+  return conv;
+}
+
+size_t
+iconv (iconv_t conv,
+       const char **in, size_t *in_left,
+       char **out, size_t *out_left)
+{
+  int rc;
+  size_t sl = *in_left, nonid;
+  UniChar *ucs = (UniChar *) alloca (sl * sizeof (UniChar));
+  UniChar *orig_ucs = ucs;
+  size_t retval = 0;
+
+  rc = UniUconvToUcs (conv->from, (void **)in, in_left, &ucs, &sl, &retval);
+  if (rc)
+    goto error;
+  sl = ucs - orig_ucs;
+  ucs = orig_ucs;
+  /* UniUconvFromUcs will stop at first null byte (huh? indeed?)
+     while we want ALL the bytes converted.  */
+#if 1
+  rc = UniUconvFromUcs (conv->to, &ucs, &sl, (void **)out, out_left, &nonid);
+  if (rc)
+    goto error;
+  retval += nonid;
+#else
+  while (sl)
+    {
+      size_t usl = 0;
+      while (sl && (ucs[usl] != 0))
+        usl++, sl--;
+      rc = UniUconvFromUcs (conv->to, &ucs, &usl, (void **)out, out_left, &nonid);
+      if (rc)
+        goto error;
+      retval += nonid;
+      if (sl && *out_left)
+        {
+          *(*out)++ = 0;
+          (*out_left)--;
+          ucs++; sl--;
+        }
+    }
+#endif
+  return 0;
+
+error:
+  /* Convert OS/2 error code to errno.  */
+  switch (rc)
+  {
+    case ULS_ILLEGALSEQUENCE:
+      errno = EILSEQ;
+      break;
+    case ULS_INVALID:
+      errno = EINVAL;
+      break;
+    case ULS_BUFFERFULL:
+      errno = E2BIG;
+      break;
+    default:
+      errno = EBADF;
+      break;
+  }
+  return (size_t)(-1);
+}
+
+int
+iconv_close (iconv_t conv)
+{
+  if (conv != (iconv_t)(-1))
+    {
+      UniFreeUconvObject (conv->to);
+      UniFreeUconvObject (conv->from);
+      free (conv);
+    }
+  return 0;
+}
Index: trunk/src/emx/src/lib/iconv/iconv.smak
===================================================================
--- trunk/src/emx/src/lib/iconv/iconv.smak	(revision 493)
+++ trunk/src/emx/src/lib/iconv/iconv.smak	(revision 493)
@@ -0,0 +1,14 @@
+# This is the top-level submakefile for building EMX C runtime library
+include comend.smak
+
+.MODULE	:= iconv
+.MDESC	:= POSIX iconv API library
+
+.TARGET	:= libiconv.a
+.TKIND	:= aout
+.TSRC	:= $(wildcard src/lib/iconv/*.c)
+.INSDIR	= lib/
+include mklib.smak
+
+# Forget temporary variables
+include comend.smak
Index: trunk/src/emx/src/libiconv/iconv.c
===================================================================
--- trunk/src/emx/src/libiconv/iconv.c	(revision 493)
+++ trunk/src/emx/src/libiconv/iconv.c	(revision 493)
@@ -0,0 +1,162 @@
+/* OS/2 iconv() implementation through OS/2 Unicode API
+   Copyright (C) 2001-2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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.  */
+
+/*
+   This file implements an iconv wrapper based on OS/2 Unicode API.
+*/
+
+#include <uconv.h>
+
+typedef struct _iconv_t
+{
+  UconvObject from;		/* "From" conversion handle */
+  UconvObject to;		/* "To" conversion handle */
+} *iconv_t;
+
+/* Tell "iconv.h" to not define iconv_t by itself.  */
+#define _ICONV_T
+#include "iconv.h"
+
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <alloca.h>
+
+extern void
+__convert_codepage (const char *cp, UniChar *ucp);
+
+iconv_t
+iconv_open (const char *cp_to, const char *cp_from)
+{
+  UniChar *ucp;
+  iconv_t conv;
+  uconv_attribute_t attr;
+
+  conv = (iconv_t) malloc (sizeof (struct _iconv_t));
+  if (conv == NULL)
+    {
+      errno = ENOMEM;
+      return (iconv_t)(-1);
+    }
+
+  ucp = (UniChar *) alloca ((strlen (cp_from) + 2 + 1) * sizeof (UniChar));
+  __convert_codepage (cp_from, ucp);
+  if (UniCreateUconvObject (ucp, &conv->from))
+    {
+      free (conv);
+      errno = EINVAL;
+      return (iconv_t)(-1);
+    }
+
+  ucp = (UniChar *) alloca ((strlen (cp_to) + 2 + 1) * sizeof (UniChar));
+  __convert_codepage (cp_to, ucp);
+  if (UniCreateUconvObject (ucp, &conv->to))
+    {
+      UniFreeUconvObject (conv->from);
+      free (conv);
+      errno = EINVAL;
+      return (iconv_t)(-1);
+    }
+
+  UniQueryUconvObject (conv->from, &attr, sizeof (attr), NULL, NULL, NULL);
+  /* Do not treat 0x7f as a control character
+     (don't understand what it exactly means but without it MBCS prefix
+     character detection sometimes could fail (when 0x7f is a prefix)).
+     And don't treat the string as a path (the docs also don't explain
+     what it exactly means, but I'm pretty sure converted texts will
+     mostly not be paths).  */
+  attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
+  UniSetUconvObject (conv->from, &attr);
+
+  return conv;
+}
+
+size_t
+iconv (iconv_t conv,
+       const char **in, size_t *in_left,
+       char **out, size_t *out_left)
+{
+  int rc;
+  size_t sl = *in_left, nonid;
+  UniChar *ucs = (UniChar *) alloca (sl * sizeof (UniChar));
+  UniChar *orig_ucs = ucs;
+  size_t retval = 0;
+
+  rc = UniUconvToUcs (conv->from, (void **)in, in_left, &ucs, &sl, &retval);
+  if (rc)
+    goto error;
+  sl = ucs - orig_ucs;
+  ucs = orig_ucs;
+  /* UniUconvFromUcs will stop at first null byte (huh? indeed?)
+     while we want ALL the bytes converted.  */
+#if 1
+  rc = UniUconvFromUcs (conv->to, &ucs, &sl, (void **)out, out_left, &nonid);
+  if (rc)
+    goto error;
+  retval += nonid;
+#else
+  while (sl)
+    {
+      size_t usl = 0;
+      while (sl && (ucs[usl] != 0))
+        usl++, sl--;
+      rc = UniUconvFromUcs (conv->to, &ucs, &usl, (void **)out, out_left, &nonid);
+      if (rc)
+        goto error;
+      retval += nonid;
+      if (sl && *out_left)
+        {
+          *(*out)++ = 0;
+          (*out_left)--;
+          ucs++; sl--;
+        }
+    }
+#endif
+  return 0;
+
+error:
+  /* Convert OS/2 error code to errno.  */
+  switch (rc)
+  {
+    case ULS_ILLEGALSEQUENCE:
+      errno = EILSEQ;
+      break;
+    case ULS_INVALID:
+      errno = EINVAL;
+      break;
+    case ULS_BUFFERFULL:
+      errno = E2BIG;
+      break;
+    default:
+      errno = EBADF;
+      break;
+  }
+  return (size_t)(-1);
+}
+
+int
+iconv_close (iconv_t conv)
+{
+  if (conv != (iconv_t)(-1))
+    {
+      UniFreeUconvObject (conv->to);
+      UniFreeUconvObject (conv->from);
+      free (conv);
+    }
+  return 0;
+}
Index: trunk/src/emx/src/libiconv/iconv.smak
===================================================================
--- trunk/src/emx/src/libiconv/iconv.smak	(revision 493)
+++ trunk/src/emx/src/libiconv/iconv.smak	(revision 493)
@@ -0,0 +1,14 @@
+# This is the top-level submakefile for building EMX C runtime library
+include comend.smak
+
+.MODULE	:= iconv
+.MDESC	:= POSIX iconv API library
+
+.TARGET	:= libiconv.a
+.TKIND	:= aout
+.TSRC	:= $(wildcard src/lib/iconv/*.c)
+.INSDIR	= lib/
+include mklib.smak
+
+# Forget temporary variables
+include comend.smak
