1 /* Conversion to and from the various ISO 646 CCS.
2 Copyright (C) 1998, 1999, 2000, 2001 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 if (! ignore_errors_p ()) \
412 /* Exit the loop with an error. */ \
413 result = __GCONV_ILLEGAL_INPUT; \
421 put32 (outptr, ch); \
426 #define LOOP_NEED_FLAGS
427 #define EXTRA_LOOP_DECLS , enum variant var
428 #include <iconv/loop.c>
431 /* Next, define the other direction. */
432 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
433 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
434 #define LOOPFCT TO_LOOP
438 int failure = __GCONV_OK; \
440 ch = get32 (inptr); \
444 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
446 failure = __GCONV_ILLEGAL_INPUT; \
449 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
450 failure = __GCONV_ILLEGAL_INPUT; \
453 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
454 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
455 || var == PT || var == PT2 || var == SE2) \
456 failure = __GCONV_ILLEGAL_INPUT; \
459 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
460 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
461 || var == HU || var == FR || var == FR1 || var == NO \
462 || var == NO2 || var == PT || var == PT2 || var == SE \
464 failure = __GCONV_ILLEGAL_INPUT; \
465 else if (var == CU) \
469 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
470 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
471 || var == YU || var == KR || var == HU || var == CU || var == FR \
472 || var == FR1 || var == NO || var == NO2 || var == PT \
473 || var == PT2 || var == SE || var == SE2) \
474 failure = __GCONV_ILLEGAL_INPUT; \
477 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
478 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
479 || var == HU || var == FR || var == FR1 || var == NO \
480 || var == NO2 || var == PT || var == PT2 || var == SE \
482 failure = __GCONV_ILLEGAL_INPUT; \
485 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
487 failure = __GCONV_ILLEGAL_INPUT; \
490 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
491 || var == YU || var == HU || var == FR || var == SE2) \
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 \
497 || var == CU || var == FR || var == FR1 || var == NO \
498 || var == NO2 || var == PT || var == PT2 || var == SE \
500 failure = __GCONV_ILLEGAL_INPUT; \
503 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
504 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
505 || var == FR || var == FR1 || var == NO || var == PT \
506 || var == PT2 || var == SE || var == SE2) \
507 failure = __GCONV_ILLEGAL_INPUT; \
508 else if (var == NO2) \
512 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
513 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
514 || var == FR || var == FR1 || var == NO || var == NO2 \
515 || var == PT || var == PT2 || var == SE || var == SE2) \
516 failure = __GCONV_ILLEGAL_INPUT; \
519 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
520 || var == CN || var == IT || var == JP || var == JP_OCR_B \
521 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
522 || var == NO || var == NO2 || var == PT || var == SE \
524 failure = __GCONV_ILLEGAL_INPUT; \
527 if (var != ES && var != ES2 && var != CU) \
528 failure = __GCONV_ILLEGAL_INPUT; \
532 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
533 failure = __GCONV_ILLEGAL_INPUT; \
537 if (var != HU && var != CU && var != SE && var != SE2) \
538 failure = __GCONV_ILLEGAL_INPUT; \
544 else if (var == JP || var == JP_OCR_B) \
547 failure = __GCONV_ILLEGAL_INPUT; \
550 if (var == DE || var == ES || var == IT || var == PT) \
552 else if (var == FR || var == FR1) \
554 else if (var == NO2) \
557 failure = __GCONV_ILLEGAL_INPUT; \
560 if (var != ES2 && var != CU && var != FR && var != FR1) \
561 failure = __GCONV_ILLEGAL_INPUT; \
567 else if (var == IT || var == FR || var == FR1) \
569 else if (var == PT) \
572 failure = __GCONV_ILLEGAL_INPUT; \
575 if (var == ES2 || var == CU) \
577 else if (var == PT2) \
580 failure = __GCONV_ILLEGAL_INPUT; \
584 failure = __GCONV_ILLEGAL_INPUT; \
590 else if (var == ES2 || var == CU) \
593 failure = __GCONV_ILLEGAL_INPUT; \
597 failure = __GCONV_ILLEGAL_INPUT; \
601 if (var != PT && var != PT2) \
602 failure = __GCONV_ILLEGAL_INPUT; \
606 if (var != DE && var != SE && var != SE2) \
607 failure = __GCONV_ILLEGAL_INPUT; \
611 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
612 failure = __GCONV_ILLEGAL_INPUT; \
616 if (var != DK && var != NO && var != NO2) \
617 failure = __GCONV_ILLEGAL_INPUT; \
623 else if (var == PT || var == PT2) \
626 failure = __GCONV_ILLEGAL_INPUT; \
631 else if (var == HU) \
633 else if (var == SE2) \
636 failure = __GCONV_ILLEGAL_INPUT; \
639 if (var != ES && var != ES2 && var != CU) \
640 failure = __GCONV_ILLEGAL_INPUT; \
644 if (var != PT && var != PT2) \
645 failure = __GCONV_ILLEGAL_INPUT; \
649 if (var != DE && var != HU && var != SE && var != SE2) \
650 failure = __GCONV_ILLEGAL_INPUT; \
654 if (var != DK && var != NO && var != NO2) \
655 failure = __GCONV_ILLEGAL_INPUT; \
659 if (var == DE || var == HU) \
661 else if (var == SE2) \
664 failure = __GCONV_ILLEGAL_INPUT; \
668 failure = __GCONV_ILLEGAL_INPUT; \
672 if (var == CA || var == CA2 || var == FR || var == FR1) \
674 else if (var == IT) \
677 failure = __GCONV_ILLEGAL_INPUT; \
681 failure = __GCONV_ILLEGAL_INPUT; \
685 if (var != CA && var != CA2) \
686 failure = __GCONV_ILLEGAL_INPUT; \
690 if (var != PT && var != PT2) \
691 failure = __GCONV_ILLEGAL_INPUT; \
695 if (var != DE && var != SE && var != SE2) \
696 failure = __GCONV_ILLEGAL_INPUT; \
700 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
701 failure = __GCONV_ILLEGAL_INPUT; \
705 if (var != DK && var != NO && var != NO2) \
706 failure = __GCONV_ILLEGAL_INPUT; \
710 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
712 else if (var == ES || var == ES2) \
714 else if (var == PT || var == PT2) \
717 failure = __GCONV_ILLEGAL_INPUT; \
720 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
721 failure = __GCONV_ILLEGAL_INPUT; \
725 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
727 else if (var == IT) \
729 else if (var == SE2) \
732 failure = __GCONV_ILLEGAL_INPUT; \
735 if (var != CA && var != CA2) \
736 failure = __GCONV_ILLEGAL_INPUT; \
741 failure = __GCONV_ILLEGAL_INPUT; \
746 failure = __GCONV_ILLEGAL_INPUT; \
750 if (var != ES && var != ES2 && var != CU) \
751 failure = __GCONV_ILLEGAL_INPUT; \
756 failure = __GCONV_ILLEGAL_INPUT; \
760 if (var != CA && var != CA2) \
761 failure = __GCONV_ILLEGAL_INPUT; \
765 if (var != PT && var != PT2) \
766 failure = __GCONV_ILLEGAL_INPUT; \
770 if (var != DE && var != HU && var != SE && var != SE2) \
771 failure = __GCONV_ILLEGAL_INPUT; \
775 if (var != DK && var != NO && var != NO2) \
776 failure = __GCONV_ILLEGAL_INPUT; \
780 if (var == CA || var == CA2 || var == FR || var == FR1) \
782 else if (var == IT) \
785 failure = __GCONV_ILLEGAL_INPUT; \
788 if (var != CA && var != CA2) \
789 failure = __GCONV_ILLEGAL_INPUT; \
793 if (var == DE || var == HU) \
795 else if (var == SE2) \
798 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; \
847 failure = __GCONV_ILLEGAL_INPUT; \
852 failure = __GCONV_ILLEGAL_INPUT; \
857 failure = __GCONV_ILLEGAL_INPUT; \
861 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
862 failure = __GCONV_ILLEGAL_INPUT; \
867 failure = __GCONV_ILLEGAL_INPUT; \
871 if (var != JP_OCR_B) \
872 failure = __GCONV_ILLEGAL_INPUT; \
876 if (var != JP_OCR_B) \
877 failure = __GCONV_ILLEGAL_INPUT; \
881 if (__builtin_expect (ch > 0x7f, 0)) \
883 UNICODE_TAG_HANDLER (ch, 4); \
884 failure = __GCONV_ILLEGAL_INPUT; \
889 if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \
891 STANDARD_ERR_HANDLER (4); \
894 *outptr++ = (unsigned char) ch; \
897 #define LOOP_NEED_FLAGS
898 #define EXTRA_LOOP_DECLS , enum variant var
899 #include <iconv/loop.c>
902 /* Now define the toplevel functions. */
903 #include <iconv/skeleton.c>