Don't return error for invald error if ignore flag is set.
[kopensolaris-gnu/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 <stdint.h>
23 #include <ksc5601.h>
24
25
26 static inline void
27 euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
28 {
29   if (ch > 0x7f)
30     {
31       if (ucs4_to_ksc5601 (ch, cp, 2) != __UNKNOWN_10646_CHAR)
32         {
33           cp[0] |= 0x80;
34           cp[1] |= 0x80;
35         }
36       else
37         cp[0] = '\0';
38     }
39   /* XXX Think about 0x5c ; '\'.  */
40   else
41     {
42       cp[0] = (unsigned char) ch;
43       cp[1] = '\0';
44     }
45 }
46
47
48 /* Definitions used in the body of the `gconv' function.  */
49 #define CHARSET_NAME            "EUC-KR//"
50 #define FROM_LOOP               from_euc_kr
51 #define TO_LOOP                 to_euc_kr
52 #define DEFINE_INIT             1
53 #define DEFINE_FINI             1
54 #define MIN_NEEDED_FROM         1
55 #define MAX_NEEDED_FROM         2
56 #define MIN_NEEDED_TO           4
57
58
59 /* First define the conversion function from EUC-KR to UCS4.  */
60 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
61 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
62 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
63 #define LOOPFCT                 FROM_LOOP
64 #define BODY \
65   {                                                                           \
66     uint32_t ch = *inptr;                                                     \
67                                                                               \
68     /* Half-width Korean Currency WON sign                                    \
69                                                                               \
70        if (inchar == 0x5c)                                                    \
71          ch =  0x20a9;                                                        \
72        else if (inchar <= 0x7f)                                               \
73          ch = (uint32_t) inchar;                                              \
74     */                                                                        \
75                                                                               \
76     if (ch <= 0x7f)                                                           \
77       /* Plain ASCII.  */                                                     \
78       ++inptr;                                                                \
79     /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are                    \
80        user-defined areas.  */                                                \
81     else if (ch <= 0xa0 || ch > 0xfe || ch == 0xc9)                           \
82       {                                                                       \
83         /* This is illegal.  */                                               \
84         if (! ignore_errors_p ())                                             \
85           {                                                                   \
86             result = __GCONV_ILLEGAL_INPUT;                                   \
87             break;                                                            \
88           }                                                                   \
89                                                                               \
90         ++inptr;                                                              \
91         ++*converted;                                                         \
92         continue;                                                             \
93       }                                                                       \
94     else                                                                      \
95       {                                                                       \
96         /* Two-byte character.  First test whether the next character         \
97            is also available.  */                                             \
98         ch = ksc5601_to_ucs4 (&inptr,                                         \
99                               NEED_LENGTH_TEST ? inptr - inend : 2, 0x80);    \
100         if (NEED_LENGTH_TEST && ch == 0)                                      \
101           {                                                                   \
102             /* The second character is not available.  */                     \
103             result = __GCONV_INCOMPLETE_INPUT;                                \
104             break;                                                            \
105           }                                                                   \
106         if (ch == __UNKNOWN_10646_CHAR)                                       \
107           {                                                                   \
108             /* This is an illegal character.  */                              \
109             if (! ignore_errors_p ())                                         \
110               {                                                               \
111                 /* This is an illegal character.  */                          \
112                 result = __GCONV_ILLEGAL_INPUT;                               \
113                 break;                                                        \
114               }                                                               \
115                                                                               \
116             inptr += 2;                                                       \
117             ++*converted;                                                     \
118             continue;                                                         \
119           }                                                                   \
120       }                                                                       \
121                                                                               \
122     put32 (outptr, ch);                                                       \
123     outptr += 4;                                                              \
124   }
125 #include <iconv/loop.c>
126
127
128 /* Next, define the other direction.  */
129 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
130 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
131 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_FROM
132 #define LOOPFCT                 TO_LOOP
133 #define BODY \
134   {                                                                           \
135     uint32_t ch = get32 (inptr);                                              \
136     unsigned char cp[2];                                                      \
137                                                                               \
138     /* Decomposing Hangul syllables not available in KS C 5601 into           \
139        Jamos should be considered either here or in euckr_from_ucs4() */      \
140     euckr_from_ucs4 (ch, cp) ;                                                \
141                                                                               \
142     if (cp[0] == '\0' && ch != 0)                                             \
143       {                                                                       \
144         /* Illegal character.  */                                             \
145         if (! ignore_errors_p ())                                             \
146           {                                                                   \
147             result = __GCONV_ILLEGAL_INPUT;                                   \
148             break;                                                            \
149           }                                                                   \
150                                                                               \
151         inptr += 4;                                                           \
152         ++*converted;                                                         \
153         continue;                                                             \
154       }                                                                       \
155                                                                               \
156     *outptr++ = cp[0];                                                        \
157     /* Now test for a possible second byte and write this if possible.  */    \
158     if (cp[1] != '\0')                                                        \
159       {                                                                       \
160         if (NEED_LENGTH_TEST && outptr >= outend)                             \
161           {                                                                   \
162             /* The result does not fit into the buffer.  */                   \
163             --outptr;                                                         \
164             result = __GCONV_FULL_OUTPUT;                                     \
165             break;                                                            \
166           }                                                                   \
167         *outptr++ = cp[1];                                                    \
168       }                                                                       \
169                                                                               \
170     inptr += 4;                                                               \
171   }
172 #include <iconv/loop.c>
173
174
175 /* Now define the toplevel functions.  */
176 #include <iconv/skeleton.c>