OSDN Git Service

2003-05-28 Jeff Johnston <jjohnstn@redhat.com>
[pf3gnuchains/pf3gnuchains4x.git] / newlib / iconvdata / euc-jp.c
1 /* Mapping tables for EUC-JP handling.
2    Copyright (C) 1998, 1999, 2000, 2001 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 Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the 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    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <dlfcn.h>
22 #include <stdint.h>
23 #include <gconv.h>
24 #include <jis0201.h>
25 #include <jis0208.h>
26 #include <jis0212.h>
27
28 /* Definitions used in the body of the `gconv' function.  */
29 #define CHARSET_NAME            "EUC-JP//"
30 #define FROM_LOOP               from_euc_jp
31 #define TO_LOOP                 to_euc_jp
32 #define DEFINE_INIT             1
33 #define DEFINE_FINI             1
34 #define MIN_NEEDED_FROM         1
35 #define MAX_NEEDED_FROM         3
36 #define MIN_NEEDED_TO           4
37
38
39 /* First define the conversion function from EUC-JP to UCS4.  */
40 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
41 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
42 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
43 #define LOOPFCT                 FROM_LOOP
44 #define BODY \
45   {                                                                           \
46     uint32_t ch = *inptr;                                                     \
47                                                                               \
48     if (ch < 0x8e || (ch >= 0x90 && ch <= 0x9f))                              \
49       ++inptr;                                                                \
50     else if (ch == 0xff)                                                      \
51       {                                                                       \
52         /* This is illegal.  */                                               \
53         if (! ignore_errors_p ())                                             \
54           {                                                                   \
55             result = __GCONV_ILLEGAL_INPUT;                                   \
56             break;                                                            \
57           }                                                                   \
58                                                                               \
59         ++inptr;                                                              \
60         ++*irreversible;                                                      \
61         continue;                                                             \
62       }                                                                       \
63     else                                                                      \
64       {                                                                       \
65         /* Two or more byte character.  First test whether the next           \
66            character is also available.  */                                   \
67         int ch2;                                                              \
68                                                                               \
69         if (__builtin_expect (inptr + 1 >= inend, 0))                         \
70           {                                                                   \
71             /* The second character is not available.  Store the              \
72                intermediate result.  */                                       \
73             result = __GCONV_INCOMPLETE_INPUT;                                \
74             break;                                                            \
75           }                                                                   \
76                                                                               \
77         ch2 = inptr[1];                                                       \
78                                                                               \
79         /* All second bytes of a multibyte character must be >= 0xa1. */      \
80         if (__builtin_expect (ch2 < 0xa1, 0))                                 \
81           {                                                                   \
82             /* This is an illegal character.  */                              \
83             if (! ignore_errors_p ())                                         \
84               {                                                               \
85                 result = __GCONV_ILLEGAL_INPUT;                               \
86                 break;                                                        \
87               }                                                               \
88                                                                               \
89             ++inptr;                                                          \
90             ++*irreversible;                                                  \
91             continue;                                                         \
92           }                                                                   \
93                                                                               \
94         if (ch == 0x8e)                                                       \
95           {                                                                   \
96             /* This is code set 2: half-width katakana.  */                   \
97             ch = jisx0201_to_ucs4 (ch2);                                      \
98             if (__builtin_expect (ch, 0) == __UNKNOWN_10646_CHAR)             \
99               {                                                               \
100                 /* Illegal character.  */                                     \
101                 if (! ignore_errors_p ())                                     \
102                   {                                                           \
103                     /* This is an illegal character.  */                      \
104                     result = __GCONV_ILLEGAL_INPUT;                           \
105                     break;                                                    \
106                   }                                                           \
107               }                                                               \
108                                                                               \
109             inptr += 2;                                                       \
110           }                                                                   \
111         else                                                                  \
112           {                                                                   \
113             const unsigned char *endp;                                        \
114                                                                               \
115             if (ch == 0x8f)                                                   \
116               {                                                               \
117                 /* This is code set 3: JIS X 0212-1990.  */                   \
118                 endp = inptr + 1;                                             \
119                                                                               \
120                 ch = jisx0212_to_ucs4 (&endp, inend - endp, 0x80);            \
121               }                                                               \
122             else                                                              \
123               {                                                               \
124                 /* This is code set 1: JIS X 0208.  */                        \
125                 endp = inptr;                                                 \
126                                                                               \
127                 ch = jisx0208_to_ucs4 (&endp, inend - inptr, 0x80);           \
128               }                                                               \
129                                                                               \
130             if (__builtin_expect (ch, 1) == 0)                                \
131               {                                                               \
132                 /* Not enough input available.  */                            \
133                 result = __GCONV_INCOMPLETE_INPUT;                            \
134                 break;                                                        \
135               }                                                               \
136             if (__builtin_expect (ch, 0) == __UNKNOWN_10646_CHAR)             \
137               {                                                               \
138                 /* Illegal character.  */                                     \
139                 if (! ignore_errors_p ())                                     \
140                   {                                                           \
141                     /* This is an illegal character.  */                      \
142                     result = __GCONV_ILLEGAL_INPUT;                           \
143                     break;                                                    \
144                   }                                                           \
145                                                                               \
146                 inptr += 2;                                                   \
147                 ++*irreversible;                                              \
148                 continue;                                                     \
149               }                                                               \
150             inptr = endp;                                                     \
151           }                                                                   \
152       }                                                                       \
153                                                                               \
154     put32 (outptr, ch);                                                       \
155     outptr += 4;                                                              \
156   }
157 #define LOOP_NEED_FLAGS
158 #include <iconv/loop.c>
159
160
161 /* Next, define the other direction.  */
162 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
163 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
164 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_FROM
165 #define LOOPFCT                 TO_LOOP
166 #define BODY \
167   {                                                                           \
168     uint32_t ch = get32 (inptr);                                              \
169                                                                               \
170     if (ch < 0x8e || (ch >= 0x90 && ch <= 0x9f))                              \
171       /* It's plain ASCII or C1.  */                                          \
172       *outptr++ = ch;                                                         \
173     else if (ch == 0xa5)                                                      \
174       /* YEN sign => backslash  */                                            \
175       *outptr++ = 0x5c;                                                       \
176     else if (ch == 0x203e)                                                    \
177       /* overscore => asciitilde */                                           \
178       *outptr++ = 0x7e;                                                       \
179     else                                                                      \
180       {                                                                       \
181         /* Try the JIS character sets.  */                                    \
182         size_t found;                                                         \
183                                                                               \
184         /* See whether we have room for at least two characters.  */          \
185         if (__builtin_expect (outptr + 1 >= outend, 0))                       \
186           {                                                                   \
187             result = __GCONV_FULL_OUTPUT;                                     \
188             break;                                                            \
189           }                                                                   \
190                                                                               \
191         found = ucs4_to_jisx0201 (ch, outptr + 1);                            \
192         if (found != __UNKNOWN_10646_CHAR)                                    \
193           {                                                                   \
194             /* Yes, it's a JIS 0201 character.  Store the shift byte.  */     \
195             *outptr = 0x8e;                                                   \
196             outptr += 2;                                                      \
197           }                                                                   \
198         else                                                                  \
199           {                                                                   \
200             /* No JIS 0201 character.  */                                     \
201             found = ucs4_to_jisx0208 (ch, outptr, 2);                         \
202             /* Please note that we always have enough room for the output. */ \
203             if (found != __UNKNOWN_10646_CHAR)                                \
204               {                                                               \
205                 /* It's a JIS 0208 character, adjust it for EUC-JP.  */       \
206                 *outptr++ += 0x80;                                            \
207                 *outptr++ += 0x80;                                            \
208               }                                                               \
209             else                                                              \
210               {                                                               \
211                 /* No JIS 0208 character.  */                                 \
212                 found = ucs4_to_jisx0212 (ch, outptr + 1,                     \
213                                           outend - outptr - 1);               \
214                                                                               \
215                 if (__builtin_expect (found, 1) == 0)                         \
216                   {                                                           \
217                     /* We ran out of space.  */                               \
218                     result = __GCONV_FULL_OUTPUT;                             \
219                     break;                                                    \
220                   }                                                           \
221                 else if (__builtin_expect (found, 0) != __UNKNOWN_10646_CHAR) \
222                   {                                                           \
223                     /* It's a JIS 0212 character, adjust it for EUC-JP.  */   \
224                     *outptr++ = 0x8f;                                         \
225                     *outptr++ += 0x80;                                        \
226                     *outptr++ += 0x80;                                        \
227                   }                                                           \
228                 else                                                          \
229                   {                                                           \
230                     UNICODE_TAG_HANDLER (ch, 4);                              \
231                                                                               \
232                     /* Illegal character.  */                                 \
233                     STANDARD_ERR_HANDLER (4);                                 \
234                   }                                                           \
235               }                                                               \
236           }                                                                   \
237       }                                                                       \
238                                                                               \
239     inptr += 4;                                                               \
240   }
241 #define LOOP_NEED_FLAGS
242 #include <iconv/loop.c>
243
244
245 /* Now define the toplevel functions.  */
246 #include <iconv/skeleton.c>