1 /* Conversion to and from the various ISO 646 CCS.
2 Copyright (C) 1998, 1999, 2000-2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
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.
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.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
20 /* The implementation of the conversion which can be performed by this
21 module are not very sophisticated and not tuned at all. There are
22 zillions of ISO 646 derivates and supporting them all in a separate
23 module is overkill since these coded character sets are hardly ever
24 used anymore (except ANSI_X3.4-1968 == ASCII, which is compatible
25 with ISO 8859-1). The European variants are superceded by the
26 various ISO 8859-? standards and the Asian variants are embedded in
27 larger character sets. Therefore this implementation is simply
28 here to make it possible to do the conversion if it is necessary.
29 The cost in the gconv-modules file is set to `2' and therefore
30 allows one to easily provide a tuned implementation in case this
31 proofs to be necessary. */
39 /* Definitions used in the body of the `gconv' function. */
40 #define FROM_LOOP from_ascii
41 #define TO_LOOP to_ascii
44 #define MIN_NEEDED_FROM 1
45 #define MIN_NEEDED_TO 4
46 #define FROM_DIRECTION (dir == from_iso646)
47 #define PREPARE_LOOP \
48 enum direction dir = ((struct iso646_data *) step->__data)->dir; \
49 enum variant var = ((struct iso646_data *) step->__data)->var;
50 #define EXTRA_LOOP_ARGS , var
53 /* Direction of the transformation. */
65 CA
, /* CSA_Z243.4-1985-1 */
66 CA2
, /* CSA_Z243.4-1985-2 */
73 JP
, /* JIS_C6220-1969-RO */
74 JP_OCR_B
, /* JIS_C6229-1984-B */
75 YU
, /* JUS_I.B1.002 */
80 FR1
, /* NF_Z_62-010_(1973) */
85 SE
, /* SEN_850200_B */
86 SE2
/* SEN_850200_C */
89 static const char *names
[] =
92 [CA
] = "CSA_Z243.4-1985-1//",
93 [CA2
] = "CSA_Z243.4-1985-2//",
98 [CN
] = "GB_1988-80//",
100 [JP
] = "JIS_C6220-1969-RO//",
101 [JP_OCR_B
] = "JIS_C6229-1984-B//",
102 [YU
] = "JUS_I.B1.002//",
104 [HU
] = "MSZ_7795.3//",
105 [CU
] = "NC_NC00-10//",
106 [FR
] = "NF_Z_62-010//",
107 [FR1
] = "NF_Z_62-010_1973//", /* Note that we don't have the parenthesis
109 [NO
] = "NS_4551-1//",
110 [NO2
] = "NS_4551-2//",
113 [SE
] = "SEN_850200_B//",
114 [SE2
] = "SEN_850200_C//"
124 extern int gconv_init (struct __gconv_step
*step
);
126 gconv_init (struct __gconv_step
*step
)
128 /* Determine which direction. */
129 struct iso646_data
*new_data
;
130 enum direction dir
= illegal_dir
;
134 for (var
= sizeof (names
) / sizeof (names
[0]) - 1; var
> illegal_var
; --var
)
135 if (__strcasecmp (step
->__from_name
, names
[var
]) == 0)
140 else if (__strcasecmp (step
->__to_name
, names
[var
]) == 0)
146 result
= __GCONV_NOCONV
;
147 if (__builtin_expect (dir
, from_iso646
) != illegal_dir
)
149 new_data
= (struct iso646_data
*) malloc (sizeof (struct iso646_data
));
151 result
= __GCONV_NOMEM
;
152 if (new_data
!= NULL
)
156 step
->__data
= new_data
;
158 if (dir
== from_iso646
)
160 step
->__min_needed_from
= MIN_NEEDED_FROM
;
161 step
->__max_needed_from
= MIN_NEEDED_FROM
;
162 step
->__min_needed_to
= MIN_NEEDED_TO
;
163 step
->__max_needed_to
= MIN_NEEDED_TO
;
167 step
->__min_needed_from
= MIN_NEEDED_TO
;
168 step
->__max_needed_from
= MIN_NEEDED_TO
;
169 step
->__min_needed_to
= MIN_NEEDED_FROM
;
170 step
->__max_needed_to
= MIN_NEEDED_FROM
;
173 step
->__stateful
= 0;
183 extern void gconv_end (struct __gconv_step
*data
);
185 gconv_end (struct __gconv_step
*data
)
191 /* First define the conversion function from ASCII to UCS4. */
192 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
193 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
194 #define LOOPFCT FROM_LOOP
198 int failure = __GCONV_OK; \
204 if (var == GB || var == ES || var == IT || var == FR || var == FR1) \
206 else if (var == NO2) \
212 else if (var == HU || var == CU || var == SE || var == SE2) \
216 if (var == CA || var == CA2 || var == FR || var == FR1) \
218 else if (var == DE || var == ES || var == IT || var == PT) \
220 else if (var == ES2) \
222 else if (var == YU) \
224 else if (var == HU) \
226 else if (var == PT2) \
228 else if (var == SE2) \
232 if (var == CA || var == CA2) \
234 else if (var == DE || var == SE || var == SE2) \
236 else if (var == DK || var == NO || var == NO2) \
238 else if (var == ES || var == ES2 || var == CU) \
240 else if (var == IT || var == FR || var == FR1) \
242 else if (var == JP_OCR_B) \
244 else if (var == YU) \
246 else if (var == HU) \
248 else if (var == PT || var == PT2) \
252 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
254 else if (var == DE || var == HU || var == SE || var == SE2) \
256 else if (var == DK || var == NO || var == NO2) \
258 else if (var == ES || var == ES2 || var == CU) \
260 else if (var == JP || var == JP_OCR_B) \
262 else if (var == YU) \
264 else if (var == KR) \
266 else if (var == PT || var == PT2) \
270 if (var == CA || var == CA2) \
272 else if (var == DE || var == HU) \
274 else if (var == DK || var == NO || var == NO2 || var == SE \
277 else if (var == ES) \
279 else if (var == ES2) \
281 else if (var == IT) \
283 else if (var == JP_OCR_B) \
285 else if (var == YU) \
287 else if (var == FR || var == FR1) \
289 else if (var == PT || var == PT2) \
295 else if (var == CA2) \
297 else if (var == ES2 || var == CU) \
299 else if (var == YU) \
301 else if (var == SE2) \
305 if (var == CA || var == CA2) \
307 else if (var == IT) \
309 else if (var == JP_OCR_B) \
310 /* Illegal character. */ \
311 failure = __GCONV_ILLEGAL_INPUT; \
312 else if (var == YU) \
314 else if (var == HU) \
316 else if (var == FR) \
318 else if (var == SE2) \
322 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
324 else if (var == DE || var == SE || var == SE2) \
326 else if (var == DK || var == NO || var == NO2) \
328 else if (var == ES) \
330 else if (var == ES2 || var == CU) \
332 else if (var == IT) \
334 else if (var == YU) \
336 else if (var == PT || var == PT2) \
340 if (var == CA || var == CA2 || var == FR || var == FR1) \
342 else if (var == DE || var == HU || var == SE || var == SE2) \
344 else if (var == DK || var == NO || var == NO2) \
346 else if (var == ES || var == ES2 || var == CU) \
348 else if (var == IT) \
350 else if (var == YU) \
352 else if (var == PT || var == PT2) \
356 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
358 else if (var == DE || var == HU) \
360 else if (var == DK || var == NO || var == NO2 || var == SE \
363 else if (var == ES || var == ES2) \
365 else if (var == YU) \
367 else if (var == CU) \
369 else if (var == PT || var == PT2) \
373 if (var == GB || var == CN || var == JP || var == NO || var == SE) \
375 else if (var == CA || var == CA2) \
377 else if (var == DE) \
379 else if (var == ES2 || var == CU || var == FR || var == FR1) \
381 else if (var == IT) \
383 else if (var == JP_OCR_B) \
384 /* Illegal character. */ \
385 failure = __GCONV_ILLEGAL_INPUT; \
386 else if (var == YU) \
388 else if (var == HU) \
390 else if (var == NO2) \
392 else if (var == PT) \
394 else if (var == SE2) \
399 case 0x80 ... 0xff: \
400 /* Illegal character. */ \
401 failure = __GCONV_ILLEGAL_INPUT; \
405 /* Hopefully gcc can recognize that the following `if' is only true \
406 when we reach the default case in the `switch' statement. */ \
407 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
409 STANDARD_FROM_LOOP_ERR_HANDLER (1); \
413 put32 (outptr, ch); \
418 #define LOOP_NEED_FLAGS
419 #define EXTRA_LOOP_DECLS , enum variant var
420 #include <iconv/loop.c>
423 /* Next, define the other direction. */
424 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
425 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
426 #define LOOPFCT TO_LOOP
430 int failure = __GCONV_OK; \
432 ch = get32 (inptr); \
436 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
438 failure = __GCONV_ILLEGAL_INPUT; \
441 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
442 failure = __GCONV_ILLEGAL_INPUT; \
445 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
446 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
447 || var == PT || var == PT2 || var == SE2) \
448 failure = __GCONV_ILLEGAL_INPUT; \
451 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
452 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
453 || var == HU || var == FR || var == FR1 || var == NO \
454 || var == NO2 || var == PT || var == PT2 || var == SE \
456 failure = __GCONV_ILLEGAL_INPUT; \
457 else if (var == CU) \
461 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
462 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
463 || var == YU || var == KR || var == HU || var == CU || var == FR \
464 || var == FR1 || var == NO || var == NO2 || var == PT \
465 || var == PT2 || var == SE || var == SE2) \
466 failure = __GCONV_ILLEGAL_INPUT; \
469 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
470 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
471 || var == HU || var == FR || var == FR1 || var == NO \
472 || var == NO2 || var == PT || var == PT2 || var == SE \
474 failure = __GCONV_ILLEGAL_INPUT; \
477 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
479 failure = __GCONV_ILLEGAL_INPUT; \
482 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
483 || var == YU || var == HU || var == FR || var == SE2) \
484 failure = __GCONV_ILLEGAL_INPUT; \
487 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
488 || var == ES2 || var == IT || var == YU || var == HU \
489 || var == CU || var == FR || var == FR1 || var == NO \
490 || var == NO2 || var == PT || var == PT2 || var == SE \
492 failure = __GCONV_ILLEGAL_INPUT; \
495 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
496 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
497 || var == FR || var == FR1 || var == NO || var == PT \
498 || var == PT2 || var == SE || var == SE2) \
499 failure = __GCONV_ILLEGAL_INPUT; \
500 else if (var == NO2) \
504 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
505 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
506 || var == FR || var == FR1 || var == NO || var == NO2 \
507 || var == PT || var == PT2 || var == SE || var == SE2) \
508 failure = __GCONV_ILLEGAL_INPUT; \
511 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
512 || var == CN || var == IT || var == JP || var == JP_OCR_B \
513 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
514 || var == NO || var == NO2 || var == PT || var == SE \
516 failure = __GCONV_ILLEGAL_INPUT; \
519 if (var != ES && var != ES2 && var != CU) \
520 failure = __GCONV_ILLEGAL_INPUT; \
524 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
525 failure = __GCONV_ILLEGAL_INPUT; \
529 if (var != HU && var != CU && var != SE && var != SE2) \
530 failure = __GCONV_ILLEGAL_INPUT; \
536 else if (var == JP || var == JP_OCR_B) \
539 failure = __GCONV_ILLEGAL_INPUT; \
542 if (var == DE || var == ES || var == IT || var == PT) \
544 else if (var == FR || var == FR1) \
546 else if (var == NO2) \
549 failure = __GCONV_ILLEGAL_INPUT; \
552 if (var != ES2 && var != CU && var != FR && var != FR1) \
553 failure = __GCONV_ILLEGAL_INPUT; \
559 else if (var == IT || var == FR || var == FR1) \
561 else if (var == PT) \
564 failure = __GCONV_ILLEGAL_INPUT; \
567 if (var == ES2 || var == CU) \
569 else if (var == PT2) \
572 failure = __GCONV_ILLEGAL_INPUT; \
576 failure = __GCONV_ILLEGAL_INPUT; \
582 else if (var == ES2 || var == CU) \
585 failure = __GCONV_ILLEGAL_INPUT; \
589 failure = __GCONV_ILLEGAL_INPUT; \
593 if (var != PT && var != PT2) \
594 failure = __GCONV_ILLEGAL_INPUT; \
598 if (var != DE && var != SE && var != SE2) \
599 failure = __GCONV_ILLEGAL_INPUT; \
603 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
604 failure = __GCONV_ILLEGAL_INPUT; \
608 if (var != DK && var != NO && var != NO2) \
609 failure = __GCONV_ILLEGAL_INPUT; \
615 else if (var == PT || var == PT2) \
618 failure = __GCONV_ILLEGAL_INPUT; \
623 else if (var == HU) \
625 else if (var == SE2) \
628 failure = __GCONV_ILLEGAL_INPUT; \
631 if (var != ES && var != ES2 && var != CU) \
632 failure = __GCONV_ILLEGAL_INPUT; \
636 if (var != PT && var != PT2) \
637 failure = __GCONV_ILLEGAL_INPUT; \
641 if (var != DE && var != HU && var != SE && var != SE2) \
642 failure = __GCONV_ILLEGAL_INPUT; \
646 if (var != DK && var != NO && var != NO2) \
647 failure = __GCONV_ILLEGAL_INPUT; \
651 if (var == DE || var == HU) \
653 else if (var == SE2) \
656 failure = __GCONV_ILLEGAL_INPUT; \
660 failure = __GCONV_ILLEGAL_INPUT; \
664 if (var == CA || var == CA2 || var == FR || var == FR1) \
666 else if (var == IT) \
669 failure = __GCONV_ILLEGAL_INPUT; \
673 failure = __GCONV_ILLEGAL_INPUT; \
677 if (var != CA && var != CA2) \
678 failure = __GCONV_ILLEGAL_INPUT; \
682 if (var != PT && var != PT2) \
683 failure = __GCONV_ILLEGAL_INPUT; \
687 if (var != DE && var != SE && var != SE2) \
688 failure = __GCONV_ILLEGAL_INPUT; \
692 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
693 failure = __GCONV_ILLEGAL_INPUT; \
697 if (var != DK && var != NO && var != NO2) \
698 failure = __GCONV_ILLEGAL_INPUT; \
702 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
704 else if (var == ES || var == ES2) \
706 else if (var == PT || var == PT2) \
709 failure = __GCONV_ILLEGAL_INPUT; \
712 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
713 failure = __GCONV_ILLEGAL_INPUT; \
717 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
719 else if (var == IT) \
721 else if (var == SE2) \
724 failure = __GCONV_ILLEGAL_INPUT; \
727 if (var != CA && var != CA2) \
728 failure = __GCONV_ILLEGAL_INPUT; \
733 failure = __GCONV_ILLEGAL_INPUT; \
738 failure = __GCONV_ILLEGAL_INPUT; \
742 if (var != ES && var != ES2 && var != CU) \
743 failure = __GCONV_ILLEGAL_INPUT; \
748 failure = __GCONV_ILLEGAL_INPUT; \
752 if (var != CA && var != CA2) \
753 failure = __GCONV_ILLEGAL_INPUT; \
757 if (var != PT && var != PT2) \
758 failure = __GCONV_ILLEGAL_INPUT; \
762 if (var != DE && var != HU && var != SE && var != SE2) \
763 failure = __GCONV_ILLEGAL_INPUT; \
767 if (var != DK && var != NO && var != NO2) \
768 failure = __GCONV_ILLEGAL_INPUT; \
772 if (var == CA || var == CA2 || var == FR || var == FR1) \
774 else if (var == IT) \
777 failure = __GCONV_ILLEGAL_INPUT; \
780 if (var != CA && var != CA2) \
781 failure = __GCONV_ILLEGAL_INPUT; \
785 if (var == DE || var == HU) \
787 else if (var == SE2) \
790 failure = __GCONV_ILLEGAL_INPUT; \
794 failure = __GCONV_ILLEGAL_INPUT; \
799 failure = __GCONV_ILLEGAL_INPUT; \
804 failure = __GCONV_ILLEGAL_INPUT; \
809 failure = __GCONV_ILLEGAL_INPUT; \
814 failure = __GCONV_ILLEGAL_INPUT; \
819 failure = __GCONV_ILLEGAL_INPUT; \
824 failure = __GCONV_ILLEGAL_INPUT; \
829 failure = __GCONV_ILLEGAL_INPUT; \
834 failure = __GCONV_ILLEGAL_INPUT; \
839 failure = __GCONV_ILLEGAL_INPUT; \
844 failure = __GCONV_ILLEGAL_INPUT; \
849 failure = __GCONV_ILLEGAL_INPUT; \
853 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
854 failure = __GCONV_ILLEGAL_INPUT; \
859 failure = __GCONV_ILLEGAL_INPUT; \
863 if (var != JP_OCR_B) \
864 failure = __GCONV_ILLEGAL_INPUT; \
868 if (var != JP_OCR_B) \
869 failure = __GCONV_ILLEGAL_INPUT; \
873 if (__builtin_expect (ch > 0x7f, 0)) \
875 UNICODE_TAG_HANDLER (ch, 4); \
876 failure = __GCONV_ILLEGAL_INPUT; \
881 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
883 STANDARD_TO_LOOP_ERR_HANDLER (4); \
886 *outptr++ = (unsigned char) ch; \
889 #define LOOP_NEED_FLAGS
890 #define EXTRA_LOOP_DECLS , enum variant var
891 #include <iconv/loop.c>
894 /* Now define the toplevel functions. */
895 #include <iconv/skeleton.c>