]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/extra/uconv/uconv.cpp
ICU-551.24.tar.gz
[apple/icu.git] / icuSources / extra / uconv / uconv.cpp
index 633bbca3a5241841a333cd05af9399f6bcf03b69..1fd2565831d77796038290805b99d1d474442318 100644 (file)
@@ -1,6 +1,6 @@
 /*****************************************************************************
 *
-*   Copyright (C) 1999-2004, International Business Machines
+*   Copyright (C) 1999-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************/
@@ -8,7 +8,7 @@
 /*
  * uconv(1): an iconv(1)-like converter using ICU.
  *
- * Original code by Jonas Utterstrรถm <jonas.utterstrom@vittran.norrnod.se>
+ * Original code by Jonas Utterstr&#x00F6;m <jonas.utterstrom@vittran.norrnod.se>
  * contributed in 1999.
  *
  * Conversion to the C conversion API and many improvements by
@@ -26,6 +26,7 @@
 #include <unicode/translit.h>
 #include <unicode/uset.h>
 #include <unicode/uclean.h>
+#include <unicode/utf16.h>
 
 #include <stdio.h>
 #include <errno.h>
 
 #include "unicode/uwmsg.h"
 
-#if (defined(WIN32) || defined(U_CYGWIN)) && !defined(__STRICT_ANSI__)
+U_NAMESPACE_USE
+
+#if U_PLATFORM_USES_ONLY_WIN32_API && !defined(__STRICT_ANSI__)
 #include <io.h>
 #include <fcntl.h>
+#if U_PLATFORM_USES_ONLY_WIN32_API
 #define USE_FILENO_BINARY_MODE 1
+/* Windows likes to rename Unix-like functions */
+#ifndef fileno
+#define fileno _fileno
+#endif
+#ifndef setmode
+#define setmode _setmode
+#endif
+#ifndef O_BINARY
+#define O_BINARY _O_BINARY
+#endif
+#endif
 #endif
 
 #ifdef UCONVMSG_LINK
@@ -51,8 +66,6 @@
 U_CFUNC char uconvmsg_dat[];
 #endif
 
-#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
-
 #define DEFAULT_BUFSZ   4096
 #define UCONVMSG "uconvmsg"
 
@@ -74,7 +87,7 @@ static void initMsg(const char *pname) {
         ps = 1;
 
         /* Set up our static data - if any */
-#ifdef UCONVMSG_LINK
+#if defined(UCONVMSG_LINK) && U_PLATFORM != U_PF_OS390 /* On z/OS, this is failing. */
         udata_setAppData(UCONVMSG, (const void*) uconvmsg_dat, &err);
         if (U_FAILURE(err)) {
           fprintf(stderr, "%s: warning, problem installing our static resource bundle data uconvmsg: %s - trying anyways.\n",
@@ -245,7 +258,7 @@ static int printConverters(const char *pname, const char *lookfor,
             }
             if (U_FAILURE(err)) {
                 u_wmsg(stderr, "cantGetTag", u_wmsg_errorName(err));
-                return -1;
+                goto error_cleanup;
             }
         }
         if (canon) {
@@ -277,7 +290,7 @@ static int printConverters(const char *pname, const char *lookfor,
             putchar('\t');
             u_wmsg(stderr, "cantGetAliases", str.getTerminatedBuffer(),
                 u_wmsg_errorName(err));
-            return -1;
+            goto error_cleanup;
         } else {
             uint16_t a, s, t;
 
@@ -291,7 +304,7 @@ static int printConverters(const char *pname, const char *lookfor,
                     putchar('\t');
                     u_wmsg(stderr, "cantGetAliases", str.getTerminatedBuffer(),
                         u_wmsg_errorName(err));
-                    return -1;
+                    goto error_cleanup;
                 }
 
                 /* Print the current alias so that it looks right. */
@@ -349,6 +362,9 @@ static int printConverters(const char *pname, const char *lookfor,
     /* Success. */
 
     return 0;
+error_cleanup:
+    uprv_free(stds);
+    return -1;
 }
 
 /* Print all available transliterators. If canon is non zero, print
@@ -360,56 +376,30 @@ static int printTransliterators(UBool canon)
     printf("no transliterators available because of UCONFIG_NO_TRANSLITERATION, see uconfig.h\n");
     return 1;
 #else
-    int32_t numtrans = utrans_countAvailableIDs(), i;
-    int buflen = 512;
-    char *buf = (char *) uprv_malloc(buflen);
-    char staticbuf[512];
+    UErrorCode status = U_ZERO_ERROR;
+    UEnumeration *ids = utrans_openIDs(&status);
+    int32_t i, numtrans = uenum_count(ids, &status);
 
     char sepchar = canon ? '\n' : ' ';
 
-    if (!buf) {
-        buf = staticbuf;
-        buflen = sizeof(staticbuf);
-    }
+    for (i = 0; U_SUCCESS(status)&& (i < numtrans); ++i) {
+       int32_t len;
+       const char *nextTrans = uenum_next(ids, &len, &status);
 
-    for (i = 0; i < numtrans; ++i) {
-        int32_t len = utrans_getAvailableID(i, buf, buflen);
-        if (len >= buflen - 1) {
-            if (buf != staticbuf) {
-                buflen <<= 1;
-                if (buflen < len) {
-                    buflen = len + 64;
-                }
-                buf = (char *) uprv_realloc(buf, buflen);
-                if (!buf) {
-                    buf = staticbuf;
-                    buflen = sizeof(staticbuf);
-                }
-            }
-            utrans_getAvailableID(i, buf, buflen);
-            if (len >= buflen) {
-                uprv_strcpy(buf + buflen - 4, "..."); /* Truncate the name. */
-            }
-        }
-
-        printf("%s", buf);
+        printf("%s", nextTrans);
         if (i < numtrans - 1) {
             putchar(sepchar);
         }
     }
 
+    uenum_close(ids);
+
     /* Add a terminating newline if needed. */
 
     if (sepchar != '\n') {
         putchar('\n');
     }
 
-    /* Free temporary data. */
-
-    if (buf != staticbuf) {
-        uprv_free(buf);
-    }
-
     /* Success. */
 
     return 0;
@@ -602,6 +592,7 @@ ConvertFile::convertFile(const char *pname,
     UConverter *convto = 0;
     UErrorCode err = U_ZERO_ERROR;
     UBool flush;
+    UBool closeFile = FALSE;
     const char *cbufp, *prevbufp;
     char *bufp;
 
@@ -637,6 +628,7 @@ ConvertFile::convertFile(const char *pname,
             u_wmsg(stderr, "cantOpenInputF", str1.getBuffer(), str2.getBuffer());
             return FALSE;
         }
+        closeFile = TRUE;
     } else {
         infilestr = "-";
         infile = stdin;
@@ -665,9 +657,9 @@ ConvertFile::convertFile(const char *pname,
         parse.line = -1;
 
         if (uprv_strchr(translit, ':') || uprv_strchr(translit, '>') || uprv_strchr(translit, '<') || uprv_strchr(translit, '>')) {
-            t = Transliterator::createFromRules("Uconv", str, UTRANS_FORWARD, parse, err);
+            t = Transliterator::createFromRules(UNICODE_STRING_SIMPLE("Uconv"), str, UTRANS_FORWARD, parse, err);
         } else {
-            t = Transliterator::createInstance(translit, UTRANS_FORWARD, err);
+            t = Transliterator::createInstance(UnicodeString(translit, -1, US_INV), UTRANS_FORWARD, err);
         }
 
         if (U_FAILURE(err)) {
@@ -779,7 +771,7 @@ ConvertFile::convertFile(const char *pname,
                 buf + rd, useOffsets ? fromoffsets : NULL, flush, &err);
 
             ulen = (int32_t)(unibufp - unibuf);
-            u.releaseBuffer(ulen);
+            u.releaseBuffer(U_SUCCESS(err) ? ulen : 0);
 
             // fromSawEndOfBytes indicates that ucnv_toUnicode() is done
             // converting all of the input bytes.
@@ -952,7 +944,7 @@ ConvertFile::convertFile(const char *pname,
                     int8_t i, length, errorLength;
 
                     UErrorCode localError = U_ZERO_ERROR;
-                    errorLength = (int8_t)LENGTHOF(errorUChars);
+                    errorLength = (int8_t)UPRV_LENGTHOF(errorUChars);
                     ucnv_getInvalidUChars(convto, errorUChars, &errorLength, &localError);
                     if (U_FAILURE(localError) || errorLength == 0) {
                         // need at least 1 so that we don't access beyond the length of fromoffsets[]
@@ -1060,7 +1052,7 @@ normal_exit:
     delete t;
 #endif
 
-    if (infile != stdin) {
+    if (closeFile) {
         fclose(infile);
     }
 
@@ -1143,7 +1135,7 @@ main(int argc, char **argv)
 
     // Get and prettify pname.
     pname = uprv_strrchr(*argv, U_FILE_SEP_CHAR);
-#ifdef WIN32
+#if U_PLATFORM_USES_ONLY_WIN32_API
     if (!pname) {
         pname = uprv_strrchr(*argv, '/');
     }
@@ -1376,13 +1368,19 @@ main(int argc, char **argv)
 
     goto normal_exit;
 error_exit:
+#if !UCONFIG_NO_LEGACY_CONVERSION
     ret = 1;
+#else 
+    fprintf(stderr, "uconv error: UCONFIG_NO_LEGACY_CONVERSION is on. See uconfig.h\n");
+#endif
 normal_exit:
 
     if (outfile != stdout) {
         fclose(outfile);
     }
 
+    u_cleanup();
+
     return ret;
 }