Update.
[platform/upstream/glibc.git] / iconvdata / euc-tw.c
1 /* Mapping tables for EUC-TW handling.
2    Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include <dlfcn.h>
22 #include <stdint.h>
23 #include <cns11643l1.h>
24 #include <cns11643.h>
25
26 /* Definitions used in the body of the `gconv' function.  */
27 #define CHARSET_NAME            "EUC-TW//"
28 #define FROM_LOOP               from_euc_tw
29 #define TO_LOOP                 to_euc_tw
30 #define DEFINE_INIT             1
31 #define DEFINE_FINI             1
32 #define MIN_NEEDED_FROM         1
33 #define MAX_NEEDED_FROM         4
34 #define MIN_NEEDED_TO           4
35
36
37 /* First define the conversion function from EUC-TW to UCS4.  */
38 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
39 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
40 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
41 #define LOOPFCT                 FROM_LOOP
42 #define BODY \
43   {                                                                           \
44     uint32_t ch = *inptr;                                                     \
45                                                                               \
46     if (ch <= 0x7f)                                                           \
47       /* Plain ASCII.  */                                                     \
48       ++inptr;                                                                \
49     else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e)                         \
50       {                                                                       \
51         /* This is illegal.  */                                               \
52         if (! ignore_errors_p ())                                             \
53           {                                                                   \
54             result = __GCONV_ILLEGAL_INPUT;                                   \
55             break;                                                            \
56           }                                                                   \
57                                                                               \
58         ++inptr;                                                              \
59         ++*irreversible;                                                      \
60         continue;                                                             \
61       }                                                                       \
62     else                                                                      \
63       {                                                                       \
64         /* Two or more byte character.  First test whether the next           \
65            character is also available.  */                                   \
66         uint32_t ch2;                                                         \
67                                                                               \
68         if (inptr + (ch == 0x8e ? 3 : 1) >= inend)                            \
69           {                                                                   \
70             /* The second character is not available.  Store the              \
71                intermediate result.  */                                       \
72             result = __GCONV_INCOMPLETE_INPUT;                                \
73             break;                                                            \
74           }                                                                   \
75                                                                               \
76         ch2 = *inptr;                                                         \
77                                                                               \
78         /* All second bytes of a multibyte character must be >= 0xa1. */      \
79         if (ch2 < 0xa1 || ch2 == 0xff)                                        \
80           {                                                                   \
81             /* This is illegal.  */                                           \
82             if (! ignore_errors_p ())                                         \
83               {                                                               \
84                 result = __GCONV_ILLEGAL_INPUT;                               \
85                 break;                                                        \
86               }                                                               \
87                                                                               \
88             ++inptr;                                                          \
89             ++*irreversible;                                                  \
90             continue;                                                         \
91           }                                                                   \
92                                                                               \
93         if (ch == 0x8e)                                                       \
94           {                                                                   \
95             /* This is code set 2: CNS 11643, planes 1 to 16.  */             \
96             const char *endp = inptr + 1;                                     \
97                                                                               \
98             ch = cns11643_to_ucs4 (&endp, inend - inptr - 1, 0x80);           \
99             /* Please note that we need not test for the missing input        \
100                characters here anymore.  */                                   \
101             if (ch == __UNKNOWN_10646_CHAR)                                   \
102               {                                                               \
103                 /* Illegal input.  */                                         \
104                 if (! ignore_errors_p ())                                     \
105                   {                                                           \
106                     /* This is an illegal character.  */                      \
107                     result = __GCONV_ILLEGAL_INPUT;                           \
108                     break;                                                    \
109                   }                                                           \
110                                                                               \
111                 ++inptr;                                                      \
112                 ++*irreversible;                                              \
113                 continue;                                                     \
114               }                                                               \
115                                                                               \
116             inptr += 4;                                                       \
117           }                                                                   \
118         else                                                                  \
119           {                                                                   \
120             /* This is code set 1: CNS 11643, plane 1.  */                    \
121             const unsigned char *endp = inptr;                                \
122                                                                               \
123             ch = cns11643l1_to_ucs4 (&endp, inend - inptr, 0x80);             \
124             /* Please note that we need not test for the missing input        \
125                characters here anymore.  */                                   \
126             if (ch == __UNKNOWN_10646_CHAR)                                   \
127               {                                                               \
128                 /* Illegal input.  */                                         \
129                 if (! ignore_errors_p ())                                     \
130                   {                                                           \
131                     /* This is an illegal character.  */                      \
132                     result = __GCONV_ILLEGAL_INPUT;                           \
133                     break;                                                    \
134                   }                                                           \
135                                                                               \
136                 inptr += 2;                                                   \
137                 ++*irreversible;                                              \
138                 continue;                                                     \
139               }                                                               \
140                                                                               \
141             inptr += 2;                                                       \
142           }                                                                   \
143       }                                                                       \
144                                                                               \
145     put32 (outptr, ch);                                                       \
146     outptr += 4;                                                              \
147   }
148 #define LOOP_NEED_FLAGS
149 #include <iconv/loop.c>
150
151
152 /* Next, define the other direction.  */
153 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
154 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
155 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_FROM
156 #define LOOPFCT                 TO_LOOP
157 #define BODY \
158   {                                                                           \
159     uint32_t ch = get32 (inptr);                                              \
160                                                                               \
161     if (ch <= 0x7f)                                                           \
162       /* It's plain ASCII.  */                                                \
163       *outptr++ = ch;                                                         \
164     else                                                                      \
165       {                                                                       \
166         /* Try the JIS character sets.  */                                    \
167         size_t found;                                                         \
168                                                                               \
169         found = ucs4_to_cns11643l1 (ch, outptr, outend - outptr);             \
170         if (__builtin_expect (found, 1) == 0)                                 \
171           {                                                                   \
172             /* We ran out of space.  */                                       \
173             result = __GCONV_INCOMPLETE_INPUT;                                \
174             break;                                                            \
175           }                                                                   \
176         if (__builtin_expect (found, 1) != __UNKNOWN_10646_CHAR)              \
177           {                                                                   \
178             /* It's a CNS 11643, plane 1 character, adjust it for EUC-TW.  */ \
179             *outptr++ += 0x80;                                                \
180             *outptr++ += 0x80;                                                \
181           }                                                                   \
182         else                                                                  \
183           {                                                                   \
184             /* No CNS 11643, plane 1 character.  */                           \
185                                                                               \
186             found = ucs4_to_cns11643 (ch, outptr + 1, outend - outptr - 1);   \
187             if (__builtin_expect (found, 1) == 0)                             \
188               {                                                               \
189                 /* We ran out of space.  */                                   \
190                 result = __GCONV_INCOMPLETE_INPUT;                            \
191                 break;                                                        \
192               }                                                               \
193             if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR)          \
194               {                                                               \
195                 /* Illegal character.  */                                     \
196                 if (step_data->__trans.__trans_fct != NULL)                   \
197                   {                                                           \
198                     result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
199                                           (step, step_data, *inptrp, &inptr,  \
200                                            inend, *outptrp, &outptr, outend,  \
201                                            irreversible));                    \
202                     if (result != __GCONV_OK)                                 \
203                       break;                                                  \
204                   }                                                           \
205                 else if (! ignore_errors_p ())                                \
206                   {                                                           \
207                     result = __GCONV_ILLEGAL_INPUT;                           \
208                     break;                                                    \
209                   }                                                           \
210                 else                                                          \
211                   {                                                           \
212                     inptr += 4;                                               \
213                     ++*irreversible;                                          \
214                   }                                                           \
215                 continue;                                                     \
216               }                                                               \
217                                                                               \
218             /* It's a CNS 11643 character, adjust it for EUC-TW.  */          \
219             *outptr++ = '\x8e';                                               \
220             *outptr++ += 0xa0;                                                \
221             *outptr++ += 0x80;                                                \
222             *outptr++ += 0x80;                                                \
223           }                                                                   \
224       }                                                                       \
225                                                                               \
226     inptr += 4;                                                               \
227   }
228 #define LOOP_NEED_FLAGS
229 #include <iconv/loop.c>
230
231
232 /* Now define the toplevel functions.  */
233 #include <iconv/skeleton.c>