]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - iconvdata/johab.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / iconvdata / johab.c
index ca4d0538976719462049617cb25c79aba5032393..e52fc24022942aa407e056f801cd446ca2cb9344 100644 (file)
@@ -1,24 +1,24 @@
 /* Mapping tables for JOHAB handling.
-   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1998-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
    and Ulrich Drepper <drepper@cygnus.com>, 1998.
 
    The GNU C Library 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 of the
-   License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
    The GNU C Library 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.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
+#include <dlfcn.h>
 #include <stdint.h>
 #include <ksc5601.h>
 
@@ -67,8 +67,8 @@ static const uint32_t init_to_ucs[19] =
 static const uint32_t final_to_ucs[31] =
 {
   L'\0', L'\0', 0x3133, L'\0', 0x3135, 0x3136, L'\0', L'\0',
-  0x313a, 0x313b, 0x314c, 0x313d, 0x313e, 0x313f,
-  0x3140, L'\0', L'\0', L'\0', 0x3144, L'\0', L'\0', L'\0',
+  0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
+  0x3140, L'\0', L'\0', 0x3144, L'\0', L'\0', L'\0', L'\0',
   L'\0', L'\0', L'\0', L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'
 };
 
@@ -92,7 +92,7 @@ static const int init_to_bit[19] =
 
 static const int mid_to_bit[21] =
 {
-          0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
+         0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
   0x0140, 0x0160, 0x0180, 0x01a0, 0x01c0, 0x1e0,
   0x0240, 0x0260, 0x0280, 0x02a0, 0x02c0, 0x02e0,
   0x0340, 0x0360, 0x0380, 0x03a0
@@ -119,11 +119,11 @@ static const uint16_t jamo_from_ucs_table[51] =
   0x9041,
   0x8446, 0x8447,
   0x9441, 0x9841, 0x9c41,
-  0x844a, 0x844b, 0x844c, 0x844d, 0x884e, 0x884f, 0x8450,
+  0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 0x8450,
   0xa041, 0xa441, 0xa841,
   0x8454,
   0xac41, 0xb041, 0xb441, 0xb841, 0xbc41,
-  0xc041, 0xc441, 0xc841, 0xca41, 0xd041,
+  0xc041, 0xc441, 0xc841, 0xcc41, 0xd041,
   0x8461, 0x8481, 0x84a1, 0x84c1, 0x84e1,
   0x8541, 0x8561, 0x8581, 0x85a1, 0x85c1, 0x85e1,
   0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1,
@@ -131,7 +131,7 @@ static const uint16_t jamo_from_ucs_table[51] =
 };
 
 
-static inline uint32_t
+static uint32_t
 johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 {
   if (idx <= 0xdefe)
@@ -150,6 +150,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 #define MIN_NEEDED_FROM                1
 #define MAX_NEEDED_FROM                2
 #define MIN_NEEDED_TO          4
+#define ONE_DIRECTION          0
 
 
 /* First define the conversion function from JOHAB to UCS4.  */
@@ -161,15 +162,13 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
   {                                                                          \
     uint32_t ch = *inptr;                                                    \
                                                                              \
-    /* half-width Korean Currency WON sign                                   \
-       if (ch == 0x5c)                                                       \
-        ch =  0x20a9;                                                        \
-       else if (ch < 0x7f)                                                   \
-        ch = (uint32_t) ch;                                                  \
-    */                                                                       \
-    if (ch < 0x7f)                                                           \
-      /* Plain ASCII.  */                                                    \
-      ++inptr;                                                               \
+    if (ch <= 0x7f)                                                          \
+      {                                                                              \
+       /* Plain ISO646-KR.  */                                               \
+       if (ch == 0x5c)                                                       \
+         ch = 0x20a9; /* half-width Korean Currency WON sign */              \
+       ++inptr;                                                              \
+      }                                                                              \
     /* Johab : 1. Hangul                                                     \
        1st byte : 0x84-0xd3                                                  \
        2nd byte : 0x41-0x7e, 0x81-0xfe                                       \
@@ -179,20 +178,13 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
        0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */                      \
     else                                                                     \
       {                                                                              \
-       if (ch > 0xf9 || ch == 0xdf || (ch > 0x7e && ch < 0x84)               \
-           || (ch > 0xd3 && ch < 0xd9))                                      \
+       if (__builtin_expect (ch > 0xf9, 0)                                   \
+           || __builtin_expect (ch == 0xdf, 0)                               \
+           || (__builtin_expect (ch > 0x7e, 0) && ch < 0x84)                 \
+           || (__builtin_expect (ch > 0xd3, 0) && ch < 0xd9))                \
          {                                                                   \
            /* These are illegal.  */                                         \
-           if (! ignore_errors_p ())                                         \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-                                                                             \
-           ++inptr;                                                          \
-           ++*converted;                                                     \
-           continue;                                                         \
+           STANDARD_FROM_LOOP_ERR_HANDLER (1);                               \
          }                                                                   \
        else                                                                  \
          {                                                                   \
@@ -201,7 +193,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
            uint32_t ch2;                                                     \
            uint_fast32_t idx;                                                \
                                                                              \
-           if (NEED_LENGTH_TEST && inptr + 1 >= inend)                       \
+           if (__glibc_unlikely (inptr + 1 >= inend))                        \
              {                                                               \
                /* The second character is not available.  Store the          \
                   intermediate result.  */                                   \
@@ -211,28 +203,21 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
                                                                              \
            ch2 = inptr[1];                                                   \
            idx = ch * 256 + ch2;                                             \
-           if (ch <= 0xd3)                                                   \
+           if (__glibc_likely (ch <= 0xd3))                                  \
              {                                                               \
                /* Hangul */                                                  \
-               uint_fast32_t i, m, f;                                        \
+               int_fast32_t i, m, f;                                         \
                                                                              \
                i = init[(idx & 0x7c00) >> 10];                               \
                m = mid[(idx & 0x03e0) >> 5];                                 \
                f = final[idx & 0x001f];                                      \
                                                                              \
-               if (i == -1 || m == -1 || f == -1)                            \
+               if (__builtin_expect (i == -1, 0)                             \
+                   || __builtin_expect (m == -1, 0)                          \
+                   || __builtin_expect (f == -1, 0))                         \
                  {                                                           \
                    /* This is illegal.  */                                   \
-                   if (! ignore_errors_p ())                                 \
-                     {                                                       \
-                       /* This is an illegal character.  */                  \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                                                                             \
-                   ++inptr;                                                  \
-                   ++*converted;                                             \
-                   continue;                                                 \
+                   STANDARD_FROM_LOOP_ERR_HANDLER (1);                       \
                  }                                                           \
                else if (i > 0 && m > 0)                                      \
                  ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00;            \
@@ -240,53 +225,27 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
                  ch = init_to_ucs[i - 1];                                    \
                else if (i == 0 && m > 0 && f == 0)                           \
                  ch = 0x314e + m;      /* 0x314f + m - 1 */                  \
-               else if (i == 0 && m == 0 && f > 0)                           \
+               else if (__builtin_expect ((i | m) == 0, 1)                   \
+                        && __builtin_expect (f > 0, 1))                      \
                  ch = final_to_ucs[f - 1];     /* round trip?? */            \
                else                                                          \
                  {                                                           \
                    /* This is illegal.  */                                   \
-                   if (! ignore_errors_p ())                                 \
-                     {                                                       \
-                       /* This is an illegal character.  */                  \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                                                                             \
-                   ++inptr;                                                  \
-                   ++*converted;                                             \
-                   continue;                                                 \
+                   STANDARD_FROM_LOOP_ERR_HANDLER (1);                       \
                  }                                                           \
              }                                                               \
            else                                                              \
              {                                                               \
-               if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff)  \
+               if (__builtin_expect (ch2 < 0x31, 0)                          \
+                   || (__builtin_expect (ch2 > 0x7e, 0) && ch2 < 0x91)       \
+                   || __builtin_expect (ch2, 0) == 0xff                      \
+                   || (__builtin_expect (ch, 0) == 0xd9 && ch2 > 0xe8)       \
+                   || (__builtin_expect (ch, 0) == 0xda                      \
+                       && ch2 > 0xa0 && ch2 < 0xd4)                          \
+                   || (__builtin_expect (ch, 0) == 0xde && ch2 > 0xf1))      \
                  {                                                           \
                    /* This is illegal.  */                                   \
-                   if (! ignore_errors_p ())                                 \
-                     {                                                       \
-                       /* This is an illegal character.  */                  \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                                                                             \
-                   ++inptr;                                                  \
-                   ++*converted;                                             \
-                   continue;                                                 \
-                 }                                                           \
-               else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4)              \
-                 {                                                           \
-                   /* This is illegal.  Modern Hangul Jaso is defined        \
-                      elsewhere in Johab */                                  \
-                   if (! ignore_errors_p ())                                 \
-                     {                                                       \
-                       /* This is an illegal character.  */                  \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                                                                             \
-                   ++inptr;                                                  \
-                   ++*converted;                                             \
-                   continue;                                                 \
+                   STANDARD_FROM_LOOP_ERR_HANDLER (1);                       \
                  }                                                           \
                else                                                          \
                  {                                                           \
@@ -296,7 +255,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
                                                   + ch2 - (ch2 > 0x90        \
                                                            ? 0x43 : 0x31)];  \
                       else                                                   \
-                        ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192         \
+                        ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192         \
                                                     + ch2 -  (ch2 > 0x90     \
                                                               ?0x43 : 0x31)];\
                    */                                                        \
@@ -304,19 +263,10 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
              }                                                               \
          }                                                                   \
                                                                              \
-       if (ch == 0)                                                          \
+       if (__glibc_unlikely (ch == 0))                                       \
          {                                                                   \
            /* This is an illegal character.  */                              \
-           if (! ignore_errors_p ())                                         \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-                                                                             \
-           inptr += 2;                                                       \
-           ++*converted;                                                     \
-           continue;                                                         \
+           STANDARD_FROM_LOOP_ERR_HANDLER (2);                               \
          }                                                                   \
                                                                              \
        inptr += 2;                                                           \
@@ -325,6 +275,14 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
     put32 (outptr, ch);                                                              \
     outptr += 4;                                                             \
   }
+#define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {                                                                          \
+    if (c <= 0x7f)                                                           \
+      return (c == 0x5c ? 0x20a9 : c);                                       \
+    else                                                                     \
+      return WEOF;                                                           \
+  }
 #include <iconv/loop.c>
 
 
@@ -350,13 +308,13 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
         cp = from_ucs4_lat1[ch];                                             \
     */                                                                       \
                                                                              \
-    if (ch < 0x7f)                                                           \
+    if (ch <= 0x7f && ch != 0x5c)                                            \
       *outptr++ = ch;                                                        \
     else                                                                     \
       {                                                                              \
        if (ch >= 0xac00 && ch <= 0xd7a3)                                     \
          {                                                                   \
-           if (NEED_LENGTH_TEST && outptr + 2 > outend)                      \
+           if (__glibc_unlikely (outptr + 2 > outend))                       \
              {                                                               \
                result = __GCONV_FULL_OUTPUT;                                 \
                break;                                                        \
@@ -377,7 +335,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
          {                                                                   \
            ch = jamo_from_ucs_table[ch - 0x3131];                            \
                                                                              \
-           if (NEED_LENGTH_TEST && outptr + 2 > outend)                      \
+           if (__glibc_unlikely (outptr + 2 > outend))                       \
              {                                                               \
                result = __GCONV_FULL_OUTPUT;                                 \
                break;                                                        \
@@ -392,26 +350,15 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
            size_t written;                                                   \
            uint32_t temp;                                                    \
                                                                              \
-           written = ucs4_to_ksc5601_hanja (ch, outptr,                      \
-                                            (NEED_LENGTH_TEST                \
-                                             ? outend - outptr : 2));        \
-           if (NEED_LENGTH_TEST && written == 0)                             \
+           written = ucs4_to_ksc5601_hanja (ch, outptr, outend - outptr);    \
+           if (__builtin_expect (written, 1) == 0)                           \
              {                                                               \
                result = __GCONV_FULL_OUTPUT;                                 \
                break;                                                        \
              }                                                               \
-           if (written == __UNKNOWN_10646_CHAR)                              \
+           if (__glibc_unlikely (written == __UNKNOWN_10646_CHAR))           \
              {                                                               \
-               if (! ignore_errors_p ())                                     \
-                 {                                                           \
-                   /* This is an illegal character.  */                      \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-                                                                             \
-               inptr += 4;                                                   \
-               ++*converted;                                                 \
-               continue;                                                     \
+               STANDARD_TO_LOOP_ERR_HANDLER (4);                             \
              }                                                               \
                                                                              \
            outptr[0] -= 0x4a;                                                \
@@ -425,40 +372,30 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
                                                                              \
            outptr += 2;                                                      \
          }                                                                   \
+       else if (ch == 0x20a9)                                                \
+         *outptr++ = 0x5c;                                                   \
        else                                                                  \
          {                                                                   \
            size_t written;                                                   \
+           uint32_t temp;                                                    \
                                                                              \
-           written = ucs4_to_ksc5601_sym (ch, outptr,                        \
-                                          (NEED_LENGTH_TEST                  \
-                                           ? outend - outptr : 2));          \
-           if (NEED_LENGTH_TEST && written == 0)                             \
+           written = ucs4_to_ksc5601_sym (ch, outptr, outend - outptr);      \
+           if (__builtin_expect (written, 1) == 0)                           \
              {                                                               \
                result = __GCONV_FULL_OUTPUT;                                 \
                break;                                                        \
              }                                                               \
-           if (written == __UNKNOWN_10646_CHAR)                              \
+           if (__builtin_expect (written == __UNKNOWN_10646_CHAR, 0)         \
+               || (outptr[0] == 0x22 && outptr[1] > 0x68))                   \
              {                                                               \
-               if (! ignore_errors_p ())                                     \
-                 {                                                           \
-                   /* This is an illegal character.  */                      \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-                                                                             \
-               inptr += 4;                                                   \
-               ++*converted;                                                 \
-               continue;                                                     \
+               UNICODE_TAG_HANDLER (ch, 4);                                  \
+               STANDARD_TO_LOOP_ERR_HANDLER (4);                             \
              }                                                               \
                                                                              \
-           outptr[0] -= 0x4a;                                                \
-           outptr[1] += 0x80;                                                \
-                                                                             \
-           outptr[1] += (outptr[0] % 2                                       \
-                         ? 0 : (outptr[1] > 0xee ? 0x43 : 0x31));            \
-           outptr[1] -= 0xa1;                                                \
-           outptr[0] /= 2;                                                   \
-           outptr[0] += 0xe0;                                                \
+           temp = (outptr[0] < 0x4a ? outptr[0] + 0x191 : outptr[0] + 0x176);\
+           outptr[1] += (temp % 2 ? 0x5e : 0);                               \
+           outptr[1] += (outptr[1] < 0x6f ? 0x10 : 0x22);                    \
+           outptr[0] = temp / 2;                                             \
                                                                              \
            outptr += 2;                                                      \
          }                                                                   \
@@ -466,6 +403,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
                                                                              \
     inptr += 4;                                                                      \
   }
+#define LOOP_NEED_FLAGS
 #include <iconv/loop.c>