1 /* Conversion to and from the various ISO 646 CCS.
2 Copyright (C) 1998 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 Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 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 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
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. */
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. */
64 US
, /* ANSI_X3.4-1968 */
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
[] =
92 [US
] = "ANSI_X3.4-1968//",
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)//",
110 [NO
] = "NS_4551-1//",
111 [NO2
] = "NS_4551-2//",
114 [SE
] = "SEN_850200_B//",
115 [SE2
] = "SEN_850200_C//"
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 (dir
!= illegal_dir
149 = (struct iso646_data
*) malloc (sizeof (struct iso646_data
)))
154 step
->data
= new_data
;
156 if (var
== from_iso646
)
158 step
->min_needed_from
= MIN_NEEDED_FROM
;
159 step
->max_needed_from
= MIN_NEEDED_FROM
;
160 step
->min_needed_to
= MIN_NEEDED_TO
;
161 step
->max_needed_to
= MIN_NEEDED_TO
;
165 step
->min_needed_from
= MIN_NEEDED_TO
;
166 step
->max_needed_from
= MIN_NEEDED_TO
;
167 step
->min_needed_to
= MIN_NEEDED_FROM
;
168 step
->max_needed_to
= MIN_NEEDED_FROM
;
181 gconv_end (struct gconv_step
*data
)
187 /* First define the conversion function from ASCII to UCS4. */
188 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
189 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
190 #define LOOPFCT FROM_LOOP
194 int failure = GCONV_OK; \
200 if (var == GB || var == ES || var == IT || var == FR || var == FR1) \
202 else if (var == NO2) \
208 else if (var == HU || var == CU || var == SE || var == SE2) \
212 if (var == CA || var == CA2 || var == FR || var == FR1) \
214 else if (var == DE || var == ES || var == IT || var == PT) \
216 else if (var == ES2) \
218 else if (var == YU) \
220 else if (var == HU) \
222 else if (var == PT2) \
224 else if (var == SE2) \
228 if (var == CA || var == CA2) \
230 else if (var == DE || var == SE || var == SE2) \
232 else if (var == DK || var == NO || var == NO2) \
234 else if (var == ES || var == ES2 || var == CU) \
236 else if (var == IT || var == FR || var == FR1) \
238 else if (var == JP_OCR_B) \
240 else if (var == YU) \
242 else if (var == HU) \
244 else if (var == PT || var == PT2) \
248 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
250 else if (var == DE || var == HU || var == SE || var == SE2) \
252 else if (var == DK || var == NO || var == NO2) \
254 else if (var == ES || var == ES2 || var == CU) \
256 else if (var == JP || var == JP_OCR_B) \
258 else if (var == YU) \
260 else if (var == KR) \
262 else if (var == PT || var == PT2) \
266 if (var == CA || var == CA2) \
268 else if (var == DE || var == HU) \
270 else if (var == DK || var == NO || var == NO2 || var == SE \
273 else if (var == ES) \
275 else if (var == ES2) \
277 else if (var == IT) \
279 else if (var == JP_OCR_B) \
281 else if (var == YU) \
283 else if (var == FR || var == FR1) \
285 else if (var == PT || var == PT2) \
291 else if (var == CA2) \
293 else if (var == ES2 || var == CU) \
295 else if (var == YU) \
297 else if (var == SE2) \
301 if (var == CA || var == CA2) \
303 else if (var == IT) \
305 else if (var == JP_OCR_B) \
306 /* Illegal character. */ \
307 failure = GCONV_ILLEGAL_INPUT; \
308 else if (var == YU) \
310 else if (var == HU) \
312 else if (var == FR) \
314 else if (var == SE2) \
318 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
320 else if (var == DE || var == SE || var == SE2) \
322 else if (var == DK || var == NO || var == NO2) \
324 else if (var == ES) \
326 else if (var == ES2 || var == CU) \
328 else if (var == IT) \
330 else if (var == YU) \
332 else if (var == PT || var == PT2) \
336 if (var == CA || var == CA2 || var == FR || var == FR1) \
338 else if (var == DE || var == HU || var == SE || var == SE2) \
340 else if (var == DK || var == NO || var == NO2) \
342 else if (var == ES || var == ES2 || var == CU) \
344 else if (var == IT) \
346 else if (var == YU) \
348 else if (var == PT || var == PT2) \
352 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
354 else if (var == DE || var == HU) \
356 else if (var == DK || var == NO || var == NO2 || var == SE \
359 else if (var == ES || var == ES2) \
361 else if (var == YU) \
363 else if (var == CU) \
365 else if (var == PT || var == PT2) \
369 if (var == GB || var == CN || var == JP || var == NO || var == SE) \
371 else if (var == CA || var == CA2) \
373 else if (var == DE) \
375 else if (var == ES2 || var == CU || var == FR || var == FR1) \
377 else if (var == IT) \
379 else if (var == JP_OCR_B) \
380 /* Illegal character. */ \
381 failure = GCONV_ILLEGAL_INPUT; \
382 else if (var == YU) \
384 else if (var == HU) \
386 else if (var == NO2) \
388 else if (var == PT) \
390 else if (var == SE2) \
395 case 0x80 ... 0xff: \
396 /* Illegal character. */ \
397 failure = GCONV_ILLEGAL_INPUT; \
401 /* Hopefully gcc can recognize that the following `if' is only true \
402 when we reach the default case in the `switch' statement. */ \
403 if (failure == GCONV_ILLEGAL_INPUT) \
405 /* Exit the loop with an error. */ \
409 *((uint32_t *) outptr)++ = ch; \
412 #define EXTRA_LOOP_DECLS , enum variant var
413 #include <iconv/loop.c>
416 /* Next, define the other direction. */
417 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
418 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
419 #define LOOPFCT TO_LOOP
423 int failure = GCONV_OK; \
425 ch = *((uint32_t *) inptr); \
426 switch (*((uint32_t *) inptr)) \
429 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
431 failure = GCONV_ILLEGAL_INPUT; \
434 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
435 failure = GCONV_ILLEGAL_INPUT; \
438 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
439 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
440 || var == PT || var == PT2 || var == SE2) \
441 failure = GCONV_ILLEGAL_INPUT; \
444 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
445 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
446 || var == HU || var == FR || var == FR1 || var == NO \
447 || var == NO2 || var == PT || var == PT2 || var == SE \
449 failure = GCONV_ILLEGAL_INPUT; \
450 else if (var == CU) \
454 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
455 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
456 || var == YU || var == KR || var == HU || var == CU || var == FR \
457 || var == FR1 || var == NO || var == NO2 || var == PT \
458 || var == PT2 || var == SE || var == SE2) \
459 failure = GCONV_ILLEGAL_INPUT; \
462 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
463 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
464 || var == HU || var == FR || var == FR1 || var == NO \
465 || var == NO2 || var == PT || var == PT2 || var == SE \
467 failure = GCONV_ILLEGAL_INPUT; \
470 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
472 failure = GCONV_ILLEGAL_INPUT; \
475 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
476 || var == YU || var == HU || var == FR || var == SE2) \
477 failure = GCONV_ILLEGAL_INPUT; \
480 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
481 || var == ES2 || var == IT || var == YU || var == HU \
482 || var == CU || var == FR || var == FR1 || var == NO \
483 || var == NO2 || var == PT || var == PT2 || var == SE \
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 || var == CU \
490 || var == FR || var == FR1 || var == NO || var == PT \
491 || var == PT2 || var == SE || var == SE2) \
492 failure = GCONV_ILLEGAL_INPUT; \
493 else if (var == NO2) \
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 == NO2 \
500 || var == PT || var == PT2 || var == SE || var == SE2) \
501 failure = GCONV_ILLEGAL_INPUT; \
504 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
505 || var == CN || var == IT || var == JP || var == JP_OCR_B \
506 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
507 || var == NO || var == NO2 || var == PT || var == SE \
509 failure = GCONV_ILLEGAL_INPUT; \
512 if (var != ES && var != ES2 && var != CU) \
513 failure = GCONV_ILLEGAL_INPUT; \
517 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
518 failure = GCONV_ILLEGAL_INPUT; \
522 if (var != HU && var != CU && var != SE && var != SE2) \
523 failure = GCONV_ILLEGAL_INPUT; \
529 else if (var == JP || var == JP_OCR_B) \
532 failure = GCONV_ILLEGAL_INPUT; \
535 if (var == DE || var == ES || var == IT || var == PT) \
537 else if (var == FR || var == FR1) \
539 else if (var == NO2) \
542 failure = GCONV_ILLEGAL_INPUT; \
545 if (var != ES2 && var != CU && var != FR && var != FR1) \
546 failure = GCONV_ILLEGAL_INPUT; \
552 else if (var == IT || var == FR || var == FR1) \
554 else if (var == PT) \
557 failure = GCONV_ILLEGAL_INPUT; \
560 if (var == ES2 || var == CU) \
562 else if (var == PT2) \
565 failure = GCONV_ILLEGAL_INPUT; \
569 failure = GCONV_ILLEGAL_INPUT; \
575 else if (var == ES2 || var == CU) \
578 failure = GCONV_ILLEGAL_INPUT; \
582 failure = GCONV_ILLEGAL_INPUT; \
586 if (var != PT && var != PT2) \
587 failure = GCONV_ILLEGAL_INPUT; \
591 if (var != DE && var != SE && var != SE2) \
592 failure = GCONV_ILLEGAL_INPUT; \
596 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
597 failure = GCONV_ILLEGAL_INPUT; \
601 if (var != DK && var != NO && var != NO2) \
602 failure = GCONV_ILLEGAL_INPUT; \
608 else if (var == PT || var == PT2) \
611 failure = GCONV_ILLEGAL_INPUT; \
616 else if (var == HU) \
618 else if (var == SE2) \
621 failure = GCONV_ILLEGAL_INPUT; \
624 if (var != ES && var != ES2 && var != CU) \
625 failure = GCONV_ILLEGAL_INPUT; \
629 if (var != PT && var != PT2) \
630 failure = GCONV_ILLEGAL_INPUT; \
634 if (var != DE && var != HU && var != SE && var != SE2) \
635 failure = GCONV_ILLEGAL_INPUT; \
639 if (var != DK && var != NO && var != NO2) \
640 failure = GCONV_ILLEGAL_INPUT; \
644 if (var == DE || var == HU) \
646 else if (var == SE2) \
649 failure = GCONV_ILLEGAL_INPUT; \
653 failure = GCONV_ILLEGAL_INPUT; \
657 if (var == CA || var == CA2 || var == FR || var == FR1) \
659 else if (var == IT) \
662 failure = GCONV_ILLEGAL_INPUT; \
666 failure = GCONV_ILLEGAL_INPUT; \
670 if (var != CA && var != CA2) \
671 failure = GCONV_ILLEGAL_INPUT; \
675 if (var != PT && var != PT2) \
676 failure = GCONV_ILLEGAL_INPUT; \
680 if (var != DE && var != SE && var != SE2) \
681 failure = GCONV_ILLEGAL_INPUT; \
685 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
686 failure = GCONV_ILLEGAL_INPUT; \
690 if (var != DK && var != NO && var != NO2) \
691 failure = GCONV_ILLEGAL_INPUT; \
695 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
697 else if (var == ES || var == ES2) \
699 else if (var == PT || var == PT2) \
702 failure = GCONV_ILLEGAL_INPUT; \
705 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
706 failure = GCONV_ILLEGAL_INPUT; \
710 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
712 else if (var == IT) \
714 else if (var == SE2) \
717 failure = GCONV_ILLEGAL_INPUT; \
720 if (var != CA && var != CA2) \
721 failure = GCONV_ILLEGAL_INPUT; \
726 failure = GCONV_ILLEGAL_INPUT; \
731 failure = GCONV_ILLEGAL_INPUT; \
735 if (var != ES && var != ES2 && var != CU) \
736 failure = GCONV_ILLEGAL_INPUT; \
741 failure = GCONV_ILLEGAL_INPUT; \
745 if (var != CA && var != CA2) \
746 failure = GCONV_ILLEGAL_INPUT; \
750 if (var != PT && var != PT2) \
751 failure = GCONV_ILLEGAL_INPUT; \
755 if (var != DE && var != HU && var != SE && var != SE2) \
756 failure = GCONV_ILLEGAL_INPUT; \
760 if (var != DK && var != NO && var != NO2) \
761 failure = GCONV_ILLEGAL_INPUT; \
765 if (var == CA || var == CA2 || var == FR || var == FR1) \
767 else if (var == IT) \
770 failure = GCONV_ILLEGAL_INPUT; \
773 if (var != CA && var != CA2) \
774 failure = GCONV_ILLEGAL_INPUT; \
778 if (var == DE || var == HU) \
780 else if (var == SE2) \
783 failure = GCONV_ILLEGAL_INPUT; \
787 failure = GCONV_ILLEGAL_INPUT; \
792 failure = GCONV_ILLEGAL_INPUT; \
797 failure = GCONV_ILLEGAL_INPUT; \
802 failure = GCONV_ILLEGAL_INPUT; \
807 failure = GCONV_ILLEGAL_INPUT; \
812 failure = GCONV_ILLEGAL_INPUT; \
817 failure = GCONV_ILLEGAL_INPUT; \
822 failure = GCONV_ILLEGAL_INPUT; \
827 failure = GCONV_ILLEGAL_INPUT; \
832 failure = GCONV_ILLEGAL_INPUT; \
837 failure = GCONV_ILLEGAL_INPUT; \
842 failure = GCONV_ILLEGAL_INPUT; \
846 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
847 failure = GCONV_ILLEGAL_INPUT; \
852 failure = GCONV_ILLEGAL_INPUT; \
856 if (var != JP_OCR_B) \
857 failure = GCONV_ILLEGAL_INPUT; \
861 if (var != JP_OCR_B) \
862 failure = GCONV_ILLEGAL_INPUT; \
866 if (*((uint32_t *) inptr) > 0x7f) \
867 failure = GCONV_ILLEGAL_INPUT; \
871 if (failure == GCONV_ILLEGAL_INPUT) \
873 /* Exit the loop with an error. */ \
877 *outptr++ = (unsigned char) ch; \
880 #define EXTRA_LOOP_DECLS , enum variant var
881 #include <iconv/loop.c>
884 /* Now define the toplevel functions. */
885 #include <iconv/skeleton.c>