Update.
[platform/upstream/glibc.git] / iconvdata / euc-kr.c
1 /* Mapping tables for EUC-KR handling.
2    Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
5    and Ulrich Drepper <drepper@cygnus.com>, 1998.
6
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public
18    License along with the GNU C Library; see the file COPYING.LIB.  If not,
19    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include <dlfcn.h>
23 #include <stdint.h>
24 #include <ksc5601.h>
25
26
27 static inline void
28 euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
29 {
30   if (ch > 0x7f)
31     {
32       if (__builtin_expect (ucs4_to_ksc5601 (ch, cp, 2), 0)
33           != __UNKNOWN_10646_CHAR)
34         {
35           cp[0] |= 0x80;
36           cp[1] |= 0x80;
37         }
38       else
39         cp[0] = '\0';
40     }
41   /* XXX Think about 0x5c ; '\'.  */
42   else
43     {
44       cp[0] = (unsigned char) ch;
45       cp[1] = '\0';
46     }
47 }
48
49
50 /* Definitions used in the body of the `gconv' function.  */
51 #define CHARSET_NAME            "EUC-KR//"
52 #define FROM_LOOP               from_euc_kr
53 #define TO_LOOP                 to_euc_kr
54 #define DEFINE_INIT             1
55 #define DEFINE_FINI             1
56 #define MIN_NEEDED_FROM         1
57 #define MAX_NEEDED_FROM         2
58 #define MIN_NEEDED_TO           4
59
60
61 /* First define the conversion function from EUC-KR to UCS4.  */
62 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
63 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
64 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
65 #define LOOPFCT                 FROM_LOOP
66 #define BODY \
67   {                                                                           \
68     uint32_t ch = *inptr;                                                     \
69                                                                               \
70     /* Half-width Korean Currency WON sign                                    \
71                                                                               \
72        if (inchar == 0x5c)                                                    \
73          ch =  0x20a9;                                                        \
74        else if (inchar <= 0x7f)                                               \
75          ch = (uint32_t) inchar;                                              \
76     */                                                                        \
77                                                                               \
78     if (ch <= 0x7f)                                                           \
79       /* Plain ASCII.  */                                                     \
80       ++inptr;                                                                \
81     /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are                    \
82        user-defined areas.  */                                                \
83     else if (__builtin_expect (ch, 0xa1) <= 0xa0                              \
84              || __builtin_expect (ch, 0xa1) > 0xfe                            \
85              || __builtin_expect (ch, 0xa1) == 0xc9)                          \
86       {                                                                       \
87         /* This is illegal.  */                                               \
88         if (! ignore_errors_p ())                                             \
89           {                                                                   \
90             result = __GCONV_ILLEGAL_INPUT;                                   \
91             break;                                                            \
92           }                                                                   \
93                                                                               \
94         ++inptr;                                                              \
95         ++*irreversible;                                                      \
96         continue;                                                             \
97       }                                                                       \
98     else                                                                      \
99       {                                                                       \
100         /* Two-byte character.  First test whether the next character         \
101            is also available.  */                                             \
102         ch = ksc5601_to_ucs4 (&inptr, inptr - inend, 0x80);                   \
103         if (__builtin_expect (ch, 1) == 0)                                    \
104           {                                                                   \
105             /* The second character is not available.  */                     \
106             result = __GCONV_INCOMPLETE_INPUT;                                \
107             break;                                                            \
108           }                                                                   \
109         if (__builtin_expect (ch, 0) == __UNKNOWN_10646_CHAR)                 \
110           {                                                                   \
111             /* This is an illegal character.  */                              \
112             if (! ignore_errors_p ())                                         \
113               {                                                               \
114                 /* This is an illegal character.  */                          \
115                 result = __GCONV_ILLEGAL_INPUT;                               \
116                 break;                                                        \
117               }                                                               \
118                                                                               \
119             inptr += 2;                                                       \
120             ++*irreversible;                                                  \
121             continue;                                                         \
122           }                                                                   \
123       }                                                                       \
124                                                                               \
125     put32 (outptr, ch);                                                       \
126     outptr += 4;                                                              \
127   }
128 #define LOOP_NEED_FLAGS
129 #include <iconv/loop.c>
130
131
132 /* Next, define the other direction.  */
133 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
134 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
135 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_FROM
136 #define LOOPFCT                 TO_LOOP
137 #define BODY \
138   {                                                                           \
139     uint32_t ch = get32 (inptr);                                              \
140     unsigned char cp[2];                                                      \
141                                                                               \
142     /* Decomposing Hangul syllables not available in KS C 5601 into           \
143        Jamos should be considered either here or in euckr_from_ucs4() */      \
144     euckr_from_ucs4 (ch, cp) ;                                                \
145                                                                               \
146     if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                    \
147       {                                                                       \
148         /* Illegal character.  */                                             \
149         if (step_data->__trans.__trans_fct != NULL)                           \
150           {                                                                   \
151             result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
152                                   (step, step_data, *inptrp, &inptr, inend,   \
153                                    *outptrp, &outptr, outend, irreversible)); \
154             if (result != __GCONV_OK)                                         \
155               break;                                                          \
156           }                                                                   \
157         else if (! ignore_errors_p ())                                        \
158           {                                                                   \
159             result = __GCONV_ILLEGAL_INPUT;                                   \
160             break;                                                            \
161           }                                                                   \
162         else                                                                  \
163           {                                                                   \
164             inptr += 4;                                                       \
165             ++*irreversible;                                                  \
166           }                                                                   \
167         continue;                                                             \
168       }                                                                       \
169                                                                               \
170     *outptr++ = cp[0];                                                        \
171     /* Now test for a possible second byte and write this if possible.  */    \
172     if (cp[1] != '\0')                                                        \
173       {                                                                       \
174         if (__builtin_expect (outptr >= outend, 0))                           \
175           {                                                                   \
176             /* The result does not fit into the buffer.  */                   \
177             --outptr;                                                         \
178             result = __GCONV_FULL_OUTPUT;                                     \
179             break;                                                            \
180           }                                                                   \
181         *outptr++ = cp[1];                                                    \
182       }                                                                       \
183                                                                               \
184     inptr += 4;                                                               \
185   }
186 #define LOOP_NEED_FLAGS
187 #include <iconv/loop.c>
188
189
190 /* Now define the toplevel functions.  */
191 #include <iconv/skeleton.c>