1 /* Conversion to and from the various ISO 646 CCS.
2 Copyright (C) 1998-2015 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 ONE_DIRECTION 0
48 #define FROM_DIRECTION (dir == from_iso646)
49 #define PREPARE_LOOP \
50 enum direction dir = ((struct iso646_data *) step->__data)->dir; \
51 enum variant var = ((struct iso646_data *) step->__data)->var;
52 #define EXTRA_LOOP_ARGS , var
55 /* Direction of the transformation. */
67 CA
, /* CSA_Z243.4-1985-1 */
68 CA2
, /* CSA_Z243.4-1985-2 */
75 JP
, /* JIS_C6220-1969-RO */
76 JP_OCR_B
, /* JIS_C6229-1984-B */
77 YU
, /* JUS_I.B1.002 */
82 FR1
, /* NF_Z_62-010_(1973) */
87 SE
, /* SEN_850200_B */
88 SE2
/* SEN_850200_C */
91 static const char *names
[] =
94 [CA
] = "CSA_Z243.4-1985-1//",
95 [CA2
] = "CSA_Z243.4-1985-2//",
100 [CN
] = "GB_1988-80//",
102 [JP
] = "JIS_C6220-1969-RO//",
103 [JP_OCR_B
] = "JIS_C6229-1984-B//",
104 [YU
] = "JUS_I.B1.002//",
106 [HU
] = "MSZ_7795.3//",
107 [CU
] = "NC_NC00-10//",
108 [FR
] = "NF_Z_62-010//",
109 [FR1
] = "NF_Z_62-010_1973//", /* Note that we don't have the parenthesis
111 [NO
] = "NS_4551-1//",
112 [NO2
] = "NS_4551-2//",
115 [SE
] = "SEN_850200_B//",
116 [SE2
] = "SEN_850200_C//"
126 extern int gconv_init (struct __gconv_step
*step
);
128 gconv_init (struct __gconv_step
*step
)
130 /* Determine which direction. */
131 struct iso646_data
*new_data
;
132 enum direction dir
= illegal_dir
;
136 for (var
= sizeof (names
) / sizeof (names
[0]) - 1; var
> illegal_var
; --var
)
137 if (__strcasecmp (step
->__from_name
, names
[var
]) == 0)
142 else if (__strcasecmp (step
->__to_name
, names
[var
]) == 0)
148 result
= __GCONV_NOCONV
;
149 if (__builtin_expect (dir
, from_iso646
) != illegal_dir
)
151 new_data
= (struct iso646_data
*) malloc (sizeof (struct iso646_data
));
153 result
= __GCONV_NOMEM
;
154 if (new_data
!= NULL
)
158 step
->__data
= new_data
;
160 if (dir
== from_iso646
)
162 step
->__min_needed_from
= MIN_NEEDED_FROM
;
163 step
->__max_needed_from
= MIN_NEEDED_FROM
;
164 step
->__min_needed_to
= MIN_NEEDED_TO
;
165 step
->__max_needed_to
= MIN_NEEDED_TO
;
169 step
->__min_needed_from
= MIN_NEEDED_TO
;
170 step
->__max_needed_from
= MIN_NEEDED_TO
;
171 step
->__min_needed_to
= MIN_NEEDED_FROM
;
172 step
->__max_needed_to
= MIN_NEEDED_FROM
;
175 step
->__stateful
= 0;
185 extern void gconv_end (struct __gconv_step
*data
);
187 gconv_end (struct __gconv_step
*data
)
193 /* First define the conversion function from ASCII to UCS4. */
194 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
195 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
196 #define LOOPFCT FROM_LOOP
200 int failure = __GCONV_OK; \
206 if (var == GB || var == ES || var == IT || var == FR || var == FR1) \
208 else if (var == NO2) \
214 else if (var == HU || var == CU || var == SE || var == SE2) \
218 if (var == CA || var == CA2 || var == FR || var == FR1) \
220 else if (var == DE || var == ES || var == IT || var == PT) \
222 else if (var == ES2) \
224 else if (var == YU) \
226 else if (var == HU) \
228 else if (var == PT2) \
230 else if (var == SE2) \
234 if (var == CA || var == CA2) \
236 else if (var == DE || var == SE || var == SE2) \
238 else if (var == DK || var == NO || var == NO2) \
240 else if (var == ES || var == ES2 || var == CU) \
242 else if (var == IT || var == FR || var == FR1) \
244 else if (var == JP_OCR_B) \
246 else if (var == YU) \
248 else if (var == HU) \
250 else if (var == PT || var == PT2) \
254 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
256 else if (var == DE || var == HU || var == SE || var == SE2) \
258 else if (var == DK || var == NO || var == NO2) \
260 else if (var == ES || var == ES2 || var == CU) \
262 else if (var == JP || var == JP_OCR_B) \
264 else if (var == YU) \
266 else if (var == KR) \
268 else if (var == PT || var == PT2) \
272 if (var == CA || var == CA2) \
274 else if (var == DE || var == HU) \
276 else if (var == DK || var == NO || var == NO2 || var == SE \
279 else if (var == ES) \
281 else if (var == ES2) \
283 else if (var == IT) \
285 else if (var == JP_OCR_B) \
287 else if (var == YU) \
289 else if (var == FR || var == FR1) \
291 else if (var == PT || var == PT2) \
297 else if (var == CA2) \
299 else if (var == ES2 || var == CU) \
301 else if (var == YU) \
303 else if (var == SE2) \
307 if (var == CA || var == CA2) \
309 else if (var == IT) \
311 else if (var == JP_OCR_B) \
312 /* Illegal character. */ \
313 failure = __GCONV_ILLEGAL_INPUT; \
314 else if (var == YU) \
316 else if (var == HU) \
318 else if (var == FR) \
320 else if (var == SE2) \
324 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
326 else if (var == DE || var == SE || var == SE2) \
328 else if (var == DK || var == NO || var == NO2) \
330 else if (var == ES) \
332 else if (var == ES2 || var == CU) \
334 else if (var == IT) \
336 else if (var == YU) \
338 else if (var == PT || var == PT2) \
342 if (var == CA || var == CA2 || var == FR || var == FR1) \
344 else if (var == DE || var == HU || var == SE || var == SE2) \
346 else if (var == DK || var == NO || var == NO2) \
348 else if (var == ES || var == ES2 || var == CU) \
350 else if (var == IT) \
352 else if (var == YU) \
354 else if (var == PT || var == PT2) \
358 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
360 else if (var == DE || var == HU) \
362 else if (var == DK || var == NO || var == NO2 || var == SE \
365 else if (var == ES || var == ES2) \
367 else if (var == YU) \
369 else if (var == CU) \
371 else if (var == PT || var == PT2) \
375 if (var == GB || var == CN || var == JP || var == NO || var == SE) \
377 else if (var == CA || var == CA2) \
379 else if (var == DE) \
381 else if (var == ES2 || var == CU || var == FR || var == FR1) \
383 else if (var == IT) \
385 else if (var == JP_OCR_B) \
386 /* Illegal character. */ \
387 failure = __GCONV_ILLEGAL_INPUT; \
388 else if (var == YU) \
390 else if (var == HU) \
392 else if (var == NO2) \
394 else if (var == PT) \
396 else if (var == SE2) \
401 case 0x80 ... 0xff: \
402 /* Illegal character. */ \
403 failure = __GCONV_ILLEGAL_INPUT; \
407 /* Hopefully gcc can recognize that the following `if' is only true \
408 when we reach the default case in the `switch' statement. */ \
409 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
411 STANDARD_FROM_LOOP_ERR_HANDLER (1); \
415 put32 (outptr, ch); \
420 #define LOOP_NEED_FLAGS
421 #define EXTRA_LOOP_DECLS , enum variant var
422 #include <iconv/loop.c>
425 /* Next, define the other direction. */
426 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
427 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
428 #define LOOPFCT TO_LOOP
432 int failure = __GCONV_OK; \
434 ch = get32 (inptr); \
438 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
440 failure = __GCONV_ILLEGAL_INPUT; \
443 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
444 failure = __GCONV_ILLEGAL_INPUT; \
447 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
448 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
449 || var == PT || var == PT2 || var == SE2) \
450 failure = __GCONV_ILLEGAL_INPUT; \
453 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
454 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
455 || var == HU || var == FR || var == FR1 || var == NO \
456 || var == NO2 || var == PT || var == PT2 || var == SE \
458 failure = __GCONV_ILLEGAL_INPUT; \
459 else if (var == CU) \
463 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
464 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
465 || var == YU || var == KR || var == HU || var == CU || var == FR \
466 || var == FR1 || var == NO || var == NO2 || var == PT \
467 || var == PT2 || var == SE || var == SE2) \
468 failure = __GCONV_ILLEGAL_INPUT; \
471 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
472 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
473 || var == HU || var == FR || var == FR1 || var == NO \
474 || var == NO2 || var == PT || var == PT2 || var == SE \
476 failure = __GCONV_ILLEGAL_INPUT; \
479 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
481 failure = __GCONV_ILLEGAL_INPUT; \
484 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
485 || var == YU || var == HU || var == FR || var == SE2) \
486 failure = __GCONV_ILLEGAL_INPUT; \
489 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
490 || var == ES2 || var == IT || var == YU || var == HU \
491 || var == CU || var == FR || var == FR1 || var == NO \
492 || var == NO2 || var == PT || var == PT2 || var == SE \
494 failure = __GCONV_ILLEGAL_INPUT; \
497 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
498 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
499 || var == FR || var == FR1 || var == NO || var == PT \
500 || var == PT2 || var == SE || var == SE2) \
501 failure = __GCONV_ILLEGAL_INPUT; \
502 else if (var == NO2) \
506 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
507 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
508 || var == FR || var == FR1 || var == NO || var == NO2 \
509 || var == PT || var == PT2 || var == SE || var == SE2) \
510 failure = __GCONV_ILLEGAL_INPUT; \
513 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
514 || var == CN || var == IT || var == JP || var == JP_OCR_B \
515 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
516 || var == NO || var == NO2 || var == PT || var == SE \
518 failure = __GCONV_ILLEGAL_INPUT; \
521 if (var != ES && var != ES2 && var != CU) \
522 failure = __GCONV_ILLEGAL_INPUT; \
526 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
527 failure = __GCONV_ILLEGAL_INPUT; \
531 if (var != HU && var != CU && var != SE && var != SE2) \
532 failure = __GCONV_ILLEGAL_INPUT; \
538 else if (var == JP || var == JP_OCR_B) \
541 failure = __GCONV_ILLEGAL_INPUT; \
544 if (var == DE || var == ES || var == IT || var == PT) \
546 else if (var == FR || var == FR1) \
548 else if (var == NO2) \
551 failure = __GCONV_ILLEGAL_INPUT; \
554 if (var != ES2 && var != CU && var != FR && var != FR1) \
555 failure = __GCONV_ILLEGAL_INPUT; \
561 else if (var == IT || var == FR || var == FR1) \
563 else if (var == PT) \
566 failure = __GCONV_ILLEGAL_INPUT; \
569 if (var == ES2 || var == CU) \
571 else if (var == PT2) \
574 failure = __GCONV_ILLEGAL_INPUT; \
578 failure = __GCONV_ILLEGAL_INPUT; \
584 else if (var == ES2 || var == CU) \
587 failure = __GCONV_ILLEGAL_INPUT; \
591 failure = __GCONV_ILLEGAL_INPUT; \
595 if (var != PT && var != PT2) \
596 failure = __GCONV_ILLEGAL_INPUT; \
600 if (var != DE && var != SE && var != SE2) \
601 failure = __GCONV_ILLEGAL_INPUT; \
605 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
606 failure = __GCONV_ILLEGAL_INPUT; \
610 if (var != DK && var != NO && var != NO2) \
611 failure = __GCONV_ILLEGAL_INPUT; \
617 else if (var == PT || var == PT2) \
620 failure = __GCONV_ILLEGAL_INPUT; \
625 else if (var == HU) \
627 else if (var == SE2) \
630 failure = __GCONV_ILLEGAL_INPUT; \
633 if (var != ES && var != ES2 && var != CU) \
634 failure = __GCONV_ILLEGAL_INPUT; \
638 if (var != PT && var != PT2) \
639 failure = __GCONV_ILLEGAL_INPUT; \
643 if (var != DE && var != HU && var != SE && var != SE2) \
644 failure = __GCONV_ILLEGAL_INPUT; \
648 if (var != DK && var != NO && var != NO2) \
649 failure = __GCONV_ILLEGAL_INPUT; \
653 if (var == DE || var == HU) \
655 else if (var == SE2) \
658 failure = __GCONV_ILLEGAL_INPUT; \
662 failure = __GCONV_ILLEGAL_INPUT; \
666 if (var == CA || var == CA2 || var == FR || var == FR1) \
668 else if (var == IT) \
671 failure = __GCONV_ILLEGAL_INPUT; \
675 failure = __GCONV_ILLEGAL_INPUT; \
679 if (var != CA && var != CA2) \
680 failure = __GCONV_ILLEGAL_INPUT; \
684 if (var != PT && var != PT2) \
685 failure = __GCONV_ILLEGAL_INPUT; \
689 if (var != DE && var != SE && var != SE2) \
690 failure = __GCONV_ILLEGAL_INPUT; \
694 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
695 failure = __GCONV_ILLEGAL_INPUT; \
699 if (var != DK && var != NO && var != NO2) \
700 failure = __GCONV_ILLEGAL_INPUT; \
704 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
706 else if (var == ES || var == ES2) \
708 else if (var == PT || var == PT2) \
711 failure = __GCONV_ILLEGAL_INPUT; \
714 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
715 failure = __GCONV_ILLEGAL_INPUT; \
719 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
721 else if (var == IT) \
723 else if (var == SE2) \
726 failure = __GCONV_ILLEGAL_INPUT; \
729 if (var != CA && var != CA2) \
730 failure = __GCONV_ILLEGAL_INPUT; \
735 failure = __GCONV_ILLEGAL_INPUT; \
740 failure = __GCONV_ILLEGAL_INPUT; \
744 if (var != ES && var != ES2 && var != CU) \
745 failure = __GCONV_ILLEGAL_INPUT; \
750 failure = __GCONV_ILLEGAL_INPUT; \
754 if (var != CA && var != CA2) \
755 failure = __GCONV_ILLEGAL_INPUT; \
759 if (var != PT && var != PT2) \
760 failure = __GCONV_ILLEGAL_INPUT; \
764 if (var != DE && var != HU && var != SE && var != SE2) \
765 failure = __GCONV_ILLEGAL_INPUT; \
769 if (var != DK && var != NO && var != NO2) \
770 failure = __GCONV_ILLEGAL_INPUT; \
774 if (var == CA || var == CA2 || var == FR || var == FR1) \
776 else if (var == IT) \
779 failure = __GCONV_ILLEGAL_INPUT; \
782 if (var != CA && var != CA2) \
783 failure = __GCONV_ILLEGAL_INPUT; \
787 if (var == DE || var == HU) \
789 else if (var == SE2) \
792 failure = __GCONV_ILLEGAL_INPUT; \
796 failure = __GCONV_ILLEGAL_INPUT; \
801 failure = __GCONV_ILLEGAL_INPUT; \
806 failure = __GCONV_ILLEGAL_INPUT; \
811 failure = __GCONV_ILLEGAL_INPUT; \
816 failure = __GCONV_ILLEGAL_INPUT; \
821 failure = __GCONV_ILLEGAL_INPUT; \
826 failure = __GCONV_ILLEGAL_INPUT; \
831 failure = __GCONV_ILLEGAL_INPUT; \
836 failure = __GCONV_ILLEGAL_INPUT; \
841 failure = __GCONV_ILLEGAL_INPUT; \
846 failure = __GCONV_ILLEGAL_INPUT; \
851 failure = __GCONV_ILLEGAL_INPUT; \
855 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
856 failure = __GCONV_ILLEGAL_INPUT; \
861 failure = __GCONV_ILLEGAL_INPUT; \
865 if (var != JP_OCR_B) \
866 failure = __GCONV_ILLEGAL_INPUT; \
870 if (var != JP_OCR_B) \
871 failure = __GCONV_ILLEGAL_INPUT; \
875 if (__glibc_unlikely (ch > 0x7f)) \
877 UNICODE_TAG_HANDLER (ch, 4); \
878 failure = __GCONV_ILLEGAL_INPUT; \
883 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
885 STANDARD_TO_LOOP_ERR_HANDLER (4); \
888 *outptr++ = (unsigned char) ch; \
891 #define LOOP_NEED_FLAGS
892 #define EXTRA_LOOP_DECLS , enum variant var
893 #include <iconv/loop.c>
896 /* Now define the toplevel functions. */
897 #include <iconv/skeleton.c>