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, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 /* The implementation of the conversion which can be performed by this
22 module are not very sophisticated and not tuned at all. There are
23 zillions of ISO 646 derivates and supporting them all in a separate
24 module is overkill since these coded character sets are hardly ever
25 used anymore (except ANSI_X3.4-1968 == ASCII, which is compatible
26 with ISO 8859-1). The European variants are superceded by the
27 various ISO 8859-? standards and the Asian variants are embedded in
28 larger character sets. Therefore this implementation is simply
29 here to make it possible to do the conversion if it is necessary.
30 The cost in the gconv-modules file is set to `2' and therefore
31 allows one to easily provide a tuned implementation in case this
32 proofs to be necessary. */
40 /* Definitions used in the body of the `gconv' function. */
41 #define FROM_LOOP from_ascii
42 #define TO_LOOP to_ascii
45 #define MIN_NEEDED_FROM 1
46 #define MIN_NEEDED_TO 4
47 #define FROM_DIRECTION (dir == from_iso646)
48 #define PREPARE_LOOP \
49 enum direction dir = ((struct iso646_data *) step->__data)->dir; \
50 enum variant var = ((struct iso646_data *) step->__data)->var;
51 #define EXTRA_LOOP_ARGS , var
54 /* Direction of the transformation. */
66 CA
, /* CSA_Z243.4-1985-1 */
67 CA2
, /* CSA_Z243.4-1985-2 */
74 JP
, /* JIS_C6220-1969-RO */
75 JP_OCR_B
, /* JIS_C6229-1984-B */
76 YU
, /* JUS_I.B1.002 */
81 FR1
, /* NF_Z_62-010_(1973) */
86 SE
, /* SEN_850200_B */
87 SE2
/* SEN_850200_C */
90 static const char *names
[] =
93 [CA
] = "CSA_Z243.4-1985-1//",
94 [CA2
] = "CSA_Z243.4-1985-2//",
99 [CN
] = "GB_1988-80//",
101 [JP
] = "JIS_C6220-1969-RO//",
102 [JP_OCR_B
] = "JIS_C6229-1984-B//",
103 [YU
] = "JUS_I.B1.002//",
105 [HU
] = "MSZ_7795.3//",
106 [CU
] = "NC_NC00-10//",
107 [FR
] = "NF_Z_62-010//",
108 [FR1
] = "NF_Z_62-010_1973//", /* Note that we don't have the parenthesis
110 [NO
] = "NS_4551-1//",
111 [NO2
] = "NS_4551-2//",
114 [SE
] = "SEN_850200_B//",
115 [SE2
] = "SEN_850200_C//"
125 extern int gconv_init (struct __gconv_step
*step
);
127 gconv_init (struct __gconv_step
*step
)
129 /* Determine which direction. */
130 struct iso646_data
*new_data
;
131 enum direction dir
= illegal_dir
;
135 for (var
= sizeof (names
) / sizeof (names
[0]) - 1; var
> illegal_var
; --var
)
136 if (__strcasecmp (step
->__from_name
, names
[var
]) == 0)
141 else if (__strcasecmp (step
->__to_name
, names
[var
]) == 0)
147 result
= __GCONV_NOCONV
;
148 if (__builtin_expect (dir
, from_iso646
) != illegal_dir
)
150 new_data
= (struct iso646_data
*) malloc (sizeof (struct iso646_data
));
152 result
= __GCONV_NOMEM
;
153 if (new_data
!= NULL
)
157 step
->__data
= new_data
;
159 if (var
== from_iso646
)
161 step
->__min_needed_from
= MIN_NEEDED_FROM
;
162 step
->__max_needed_from
= MIN_NEEDED_FROM
;
163 step
->__min_needed_to
= MIN_NEEDED_TO
;
164 step
->__max_needed_to
= MIN_NEEDED_TO
;
168 step
->__min_needed_from
= MIN_NEEDED_TO
;
169 step
->__max_needed_from
= MIN_NEEDED_TO
;
170 step
->__min_needed_to
= MIN_NEEDED_FROM
;
171 step
->__max_needed_to
= MIN_NEEDED_FROM
;
174 step
->__stateful
= 0;
184 extern void gconv_end (struct __gconv_step
*data
);
186 gconv_end (struct __gconv_step
*data
)
192 /* First define the conversion function from ASCII to UCS4. */
193 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
194 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
195 #define LOOPFCT FROM_LOOP
199 int failure = __GCONV_OK; \
205 if (var == GB || var == ES || var == IT || var == FR || var == FR1) \
207 else if (var == NO2) \
213 else if (var == HU || var == CU || var == SE || var == SE2) \
217 if (var == CA || var == CA2 || var == FR || var == FR1) \
219 else if (var == DE || var == ES || var == IT || var == PT) \
221 else if (var == ES2) \
223 else if (var == YU) \
225 else if (var == HU) \
227 else if (var == PT2) \
229 else if (var == SE2) \
233 if (var == CA || var == CA2) \
235 else if (var == DE || var == SE || var == SE2) \
237 else if (var == DK || var == NO || var == NO2) \
239 else if (var == ES || var == ES2 || var == CU) \
241 else if (var == IT || var == FR || var == FR1) \
243 else if (var == JP_OCR_B) \
245 else if (var == YU) \
247 else if (var == HU) \
249 else if (var == PT || var == PT2) \
253 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
255 else if (var == DE || var == HU || var == SE || var == SE2) \
257 else if (var == DK || var == NO || var == NO2) \
259 else if (var == ES || var == ES2 || var == CU) \
261 else if (var == JP || var == JP_OCR_B) \
263 else if (var == YU) \
265 else if (var == KR) \
267 else if (var == PT || var == PT2) \
271 if (var == CA || var == CA2) \
273 else if (var == DE || var == HU) \
275 else if (var == DK || var == NO || var == NO2 || var == SE \
278 else if (var == ES) \
280 else if (var == ES2) \
282 else if (var == IT) \
284 else if (var == JP_OCR_B) \
286 else if (var == YU) \
288 else if (var == FR || var == FR1) \
290 else if (var == PT || var == PT2) \
296 else if (var == CA2) \
298 else if (var == ES2 || var == CU) \
300 else if (var == YU) \
302 else if (var == SE2) \
306 if (var == CA || var == CA2) \
308 else if (var == IT) \
310 else if (var == JP_OCR_B) \
311 /* Illegal character. */ \
312 failure = __GCONV_ILLEGAL_INPUT; \
313 else if (var == YU) \
315 else if (var == HU) \
317 else if (var == FR) \
319 else if (var == SE2) \
323 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
325 else if (var == DE || var == SE || var == SE2) \
327 else if (var == DK || var == NO || var == NO2) \
329 else if (var == ES) \
331 else if (var == ES2 || var == CU) \
333 else if (var == IT) \
335 else if (var == YU) \
337 else if (var == PT || var == PT2) \
341 if (var == CA || var == CA2 || var == FR || var == FR1) \
343 else if (var == DE || var == HU || var == SE || var == SE2) \
345 else if (var == DK || var == NO || var == NO2) \
347 else if (var == ES || var == ES2 || var == CU) \
349 else if (var == IT) \
351 else if (var == YU) \
353 else if (var == PT || var == PT2) \
357 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
359 else if (var == DE || var == HU) \
361 else if (var == DK || var == NO || var == NO2 || var == SE \
364 else if (var == ES || var == ES2) \
366 else if (var == YU) \
368 else if (var == CU) \
370 else if (var == PT || var == PT2) \
374 if (var == GB || var == CN || var == JP || var == NO || var == SE) \
376 else if (var == CA || var == CA2) \
378 else if (var == DE) \
380 else if (var == ES2 || var == CU || var == FR || var == FR1) \
382 else if (var == IT) \
384 else if (var == JP_OCR_B) \
385 /* Illegal character. */ \
386 failure = __GCONV_ILLEGAL_INPUT; \
387 else if (var == YU) \
389 else if (var == HU) \
391 else if (var == NO2) \
393 else if (var == PT) \
395 else if (var == SE2) \
400 case 0x80 ... 0xff: \
401 /* Illegal character. */ \
402 failure = __GCONV_ILLEGAL_INPUT; \
406 /* Hopefully gcc can recognize that the following `if' is only true \
407 when we reach the default case in the `switch' statement. */ \
408 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
410 STANDARD_FROM_LOOP_ERR_HANDLER (1); \
414 put32 (outptr, ch); \
419 #define LOOP_NEED_FLAGS
420 #define EXTRA_LOOP_DECLS , enum variant var
421 #include <iconv/loop.c>
424 /* Next, define the other direction. */
425 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
426 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
427 #define LOOPFCT TO_LOOP
431 int failure = __GCONV_OK; \
433 ch = get32 (inptr); \
437 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
439 failure = __GCONV_ILLEGAL_INPUT; \
442 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
443 failure = __GCONV_ILLEGAL_INPUT; \
446 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
447 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
448 || var == PT || var == PT2 || var == SE2) \
449 failure = __GCONV_ILLEGAL_INPUT; \
452 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
453 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
454 || var == HU || var == FR || var == FR1 || var == NO \
455 || var == NO2 || var == PT || var == PT2 || var == SE \
457 failure = __GCONV_ILLEGAL_INPUT; \
458 else if (var == CU) \
462 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
463 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
464 || var == YU || var == KR || var == HU || var == CU || var == FR \
465 || var == FR1 || var == NO || var == NO2 || var == PT \
466 || var == PT2 || var == SE || var == SE2) \
467 failure = __GCONV_ILLEGAL_INPUT; \
470 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
471 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
472 || var == HU || var == FR || var == FR1 || var == NO \
473 || var == NO2 || var == PT || var == PT2 || var == SE \
475 failure = __GCONV_ILLEGAL_INPUT; \
478 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
480 failure = __GCONV_ILLEGAL_INPUT; \
483 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
484 || var == YU || var == HU || var == FR || var == SE2) \
485 failure = __GCONV_ILLEGAL_INPUT; \
488 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
489 || var == ES2 || var == IT || var == YU || var == HU \
490 || var == CU || var == FR || var == FR1 || var == NO \
491 || var == NO2 || var == PT || var == PT2 || var == SE \
493 failure = __GCONV_ILLEGAL_INPUT; \
496 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
497 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
498 || var == FR || var == FR1 || var == NO || var == PT \
499 || var == PT2 || var == SE || var == SE2) \
500 failure = __GCONV_ILLEGAL_INPUT; \
501 else if (var == NO2) \
505 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
506 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
507 || var == FR || var == FR1 || var == NO || var == NO2 \
508 || var == PT || var == PT2 || var == SE || var == SE2) \
509 failure = __GCONV_ILLEGAL_INPUT; \
512 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
513 || var == CN || var == IT || var == JP || var == JP_OCR_B \
514 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
515 || var == NO || var == NO2 || var == PT || var == SE \
517 failure = __GCONV_ILLEGAL_INPUT; \
520 if (var != ES && var != ES2 && var != CU) \
521 failure = __GCONV_ILLEGAL_INPUT; \
525 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
526 failure = __GCONV_ILLEGAL_INPUT; \
530 if (var != HU && var != CU && var != SE && var != SE2) \
531 failure = __GCONV_ILLEGAL_INPUT; \
537 else if (var == JP || var == JP_OCR_B) \
540 failure = __GCONV_ILLEGAL_INPUT; \
543 if (var == DE || var == ES || var == IT || var == PT) \
545 else if (var == FR || var == FR1) \
547 else if (var == NO2) \
550 failure = __GCONV_ILLEGAL_INPUT; \
553 if (var != ES2 && var != CU && var != FR && var != FR1) \
554 failure = __GCONV_ILLEGAL_INPUT; \
560 else if (var == IT || var == FR || var == FR1) \
562 else if (var == PT) \
565 failure = __GCONV_ILLEGAL_INPUT; \
568 if (var == ES2 || var == CU) \
570 else if (var == PT2) \
573 failure = __GCONV_ILLEGAL_INPUT; \
577 failure = __GCONV_ILLEGAL_INPUT; \
583 else if (var == ES2 || var == CU) \
586 failure = __GCONV_ILLEGAL_INPUT; \
590 failure = __GCONV_ILLEGAL_INPUT; \
594 if (var != PT && var != PT2) \
595 failure = __GCONV_ILLEGAL_INPUT; \
599 if (var != DE && var != SE && var != SE2) \
600 failure = __GCONV_ILLEGAL_INPUT; \
604 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
605 failure = __GCONV_ILLEGAL_INPUT; \
609 if (var != DK && var != NO && var != NO2) \
610 failure = __GCONV_ILLEGAL_INPUT; \
616 else if (var == PT || var == PT2) \
619 failure = __GCONV_ILLEGAL_INPUT; \
624 else if (var == HU) \
626 else if (var == SE2) \
629 failure = __GCONV_ILLEGAL_INPUT; \
632 if (var != ES && var != ES2 && var != CU) \
633 failure = __GCONV_ILLEGAL_INPUT; \
637 if (var != PT && var != PT2) \
638 failure = __GCONV_ILLEGAL_INPUT; \
642 if (var != DE && var != HU && var != SE && var != SE2) \
643 failure = __GCONV_ILLEGAL_INPUT; \
647 if (var != DK && var != NO && var != NO2) \
648 failure = __GCONV_ILLEGAL_INPUT; \
652 if (var == DE || var == HU) \
654 else if (var == SE2) \
657 failure = __GCONV_ILLEGAL_INPUT; \
661 failure = __GCONV_ILLEGAL_INPUT; \
665 if (var == CA || var == CA2 || var == FR || var == FR1) \
667 else if (var == IT) \
670 failure = __GCONV_ILLEGAL_INPUT; \
674 failure = __GCONV_ILLEGAL_INPUT; \
678 if (var != CA && var != CA2) \
679 failure = __GCONV_ILLEGAL_INPUT; \
683 if (var != PT && var != PT2) \
684 failure = __GCONV_ILLEGAL_INPUT; \
688 if (var != DE && var != SE && var != SE2) \
689 failure = __GCONV_ILLEGAL_INPUT; \
693 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
694 failure = __GCONV_ILLEGAL_INPUT; \
698 if (var != DK && var != NO && var != NO2) \
699 failure = __GCONV_ILLEGAL_INPUT; \
703 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
705 else if (var == ES || var == ES2) \
707 else if (var == PT || var == PT2) \
710 failure = __GCONV_ILLEGAL_INPUT; \
713 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
714 failure = __GCONV_ILLEGAL_INPUT; \
718 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
720 else if (var == IT) \
722 else if (var == SE2) \
725 failure = __GCONV_ILLEGAL_INPUT; \
728 if (var != CA && var != CA2) \
729 failure = __GCONV_ILLEGAL_INPUT; \
734 failure = __GCONV_ILLEGAL_INPUT; \
739 failure = __GCONV_ILLEGAL_INPUT; \
743 if (var != ES && var != ES2 && var != CU) \
744 failure = __GCONV_ILLEGAL_INPUT; \
749 failure = __GCONV_ILLEGAL_INPUT; \
753 if (var != CA && var != CA2) \
754 failure = __GCONV_ILLEGAL_INPUT; \
758 if (var != PT && var != PT2) \
759 failure = __GCONV_ILLEGAL_INPUT; \
763 if (var != DE && var != HU && var != SE && var != SE2) \
764 failure = __GCONV_ILLEGAL_INPUT; \
768 if (var != DK && var != NO && var != NO2) \
769 failure = __GCONV_ILLEGAL_INPUT; \
773 if (var == CA || var == CA2 || var == FR || var == FR1) \
775 else if (var == IT) \
778 failure = __GCONV_ILLEGAL_INPUT; \
781 if (var != CA && var != CA2) \
782 failure = __GCONV_ILLEGAL_INPUT; \
786 if (var == DE || var == HU) \
788 else if (var == SE2) \
791 failure = __GCONV_ILLEGAL_INPUT; \
795 failure = __GCONV_ILLEGAL_INPUT; \
800 failure = __GCONV_ILLEGAL_INPUT; \
805 failure = __GCONV_ILLEGAL_INPUT; \
810 failure = __GCONV_ILLEGAL_INPUT; \
815 failure = __GCONV_ILLEGAL_INPUT; \
820 failure = __GCONV_ILLEGAL_INPUT; \
825 failure = __GCONV_ILLEGAL_INPUT; \
830 failure = __GCONV_ILLEGAL_INPUT; \
835 failure = __GCONV_ILLEGAL_INPUT; \
840 failure = __GCONV_ILLEGAL_INPUT; \
845 failure = __GCONV_ILLEGAL_INPUT; \
850 failure = __GCONV_ILLEGAL_INPUT; \
854 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
855 failure = __GCONV_ILLEGAL_INPUT; \
860 failure = __GCONV_ILLEGAL_INPUT; \
864 if (var != JP_OCR_B) \
865 failure = __GCONV_ILLEGAL_INPUT; \
869 if (var != JP_OCR_B) \
870 failure = __GCONV_ILLEGAL_INPUT; \
874 if (__builtin_expect (ch > 0x7f, 0)) \
876 UNICODE_TAG_HANDLER (ch, 4); \
877 failure = __GCONV_ILLEGAL_INPUT; \
882 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
884 STANDARD_TO_LOOP_ERR_HANDLER (4); \
887 *outptr++ = (unsigned char) ch; \
890 #define LOOP_NEED_FLAGS
891 #define EXTRA_LOOP_DECLS , enum variant var
892 #include <iconv/loop.c>
895 /* Now define the toplevel functions. */
896 #include <iconv/skeleton.c>