1 /* Conversion to and from the various ISO 646 CCS.
2 Copyright (C) 1998, 1999 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//", /* 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//"
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 (dir
!= 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;
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 (failure == __GCONV_ILLEGAL_INPUT) \
409 /* Exit the loop with an error. */ \
413 *((uint32_t *) outptr)++ = ch; \
416 #define EXTRA_LOOP_DECLS , enum variant var
417 #include <iconv/loop.c>
420 /* Next, define the other direction. */
421 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
422 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
423 #define LOOPFCT TO_LOOP
427 int failure = __GCONV_OK; \
429 ch = *((uint32_t *) inptr); \
430 switch (*((uint32_t *) inptr)) \
433 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
435 failure = __GCONV_ILLEGAL_INPUT; \
438 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
439 failure = __GCONV_ILLEGAL_INPUT; \
442 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
443 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
444 || var == PT || var == PT2 || var == SE2) \
445 failure = __GCONV_ILLEGAL_INPUT; \
448 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
449 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
450 || var == HU || var == FR || var == FR1 || var == NO \
451 || var == NO2 || var == PT || var == PT2 || var == SE \
453 failure = __GCONV_ILLEGAL_INPUT; \
454 else if (var == CU) \
458 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
459 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
460 || var == YU || var == KR || var == HU || var == CU || var == FR \
461 || var == FR1 || var == NO || var == NO2 || var == PT \
462 || var == PT2 || var == SE || var == SE2) \
463 failure = __GCONV_ILLEGAL_INPUT; \
466 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
467 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
468 || var == HU || var == FR || var == FR1 || var == NO \
469 || var == NO2 || var == PT || var == PT2 || var == SE \
471 failure = __GCONV_ILLEGAL_INPUT; \
474 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
476 failure = __GCONV_ILLEGAL_INPUT; \
479 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
480 || var == YU || var == HU || var == FR || var == SE2) \
481 failure = __GCONV_ILLEGAL_INPUT; \
484 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
485 || var == ES2 || var == IT || var == YU || var == HU \
486 || var == CU || var == FR || var == FR1 || var == NO \
487 || var == NO2 || var == PT || var == PT2 || var == SE \
489 failure = __GCONV_ILLEGAL_INPUT; \
492 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
493 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
494 || var == FR || var == FR1 || var == NO || var == PT \
495 || var == PT2 || var == SE || var == SE2) \
496 failure = __GCONV_ILLEGAL_INPUT; \
497 else if (var == NO2) \
501 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
502 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
503 || var == FR || var == FR1 || var == NO || var == NO2 \
504 || var == PT || var == PT2 || var == SE || var == SE2) \
505 failure = __GCONV_ILLEGAL_INPUT; \
508 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
509 || var == CN || var == IT || var == JP || var == JP_OCR_B \
510 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
511 || var == NO || var == NO2 || var == PT || var == SE \
513 failure = __GCONV_ILLEGAL_INPUT; \
516 if (var != ES && var != ES2 && var != CU) \
517 failure = __GCONV_ILLEGAL_INPUT; \
521 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
522 failure = __GCONV_ILLEGAL_INPUT; \
526 if (var != HU && var != CU && var != SE && var != SE2) \
527 failure = __GCONV_ILLEGAL_INPUT; \
533 else if (var == JP || var == JP_OCR_B) \
536 failure = __GCONV_ILLEGAL_INPUT; \
539 if (var == DE || var == ES || var == IT || var == PT) \
541 else if (var == FR || var == FR1) \
543 else if (var == NO2) \
546 failure = __GCONV_ILLEGAL_INPUT; \
549 if (var != ES2 && var != CU && var != FR && var != FR1) \
550 failure = __GCONV_ILLEGAL_INPUT; \
556 else if (var == IT || var == FR || var == FR1) \
558 else if (var == PT) \
561 failure = __GCONV_ILLEGAL_INPUT; \
564 if (var == ES2 || var == CU) \
566 else if (var == PT2) \
569 failure = __GCONV_ILLEGAL_INPUT; \
573 failure = __GCONV_ILLEGAL_INPUT; \
579 else if (var == ES2 || var == CU) \
582 failure = __GCONV_ILLEGAL_INPUT; \
586 failure = __GCONV_ILLEGAL_INPUT; \
590 if (var != PT && var != PT2) \
591 failure = __GCONV_ILLEGAL_INPUT; \
595 if (var != DE && var != SE && var != SE2) \
596 failure = __GCONV_ILLEGAL_INPUT; \
600 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
601 failure = __GCONV_ILLEGAL_INPUT; \
605 if (var != DK && var != NO && var != NO2) \
606 failure = __GCONV_ILLEGAL_INPUT; \
612 else if (var == PT || var == PT2) \
615 failure = __GCONV_ILLEGAL_INPUT; \
620 else if (var == HU) \
622 else if (var == SE2) \
625 failure = __GCONV_ILLEGAL_INPUT; \
628 if (var != ES && var != ES2 && var != CU) \
629 failure = __GCONV_ILLEGAL_INPUT; \
633 if (var != PT && var != PT2) \
634 failure = __GCONV_ILLEGAL_INPUT; \
638 if (var != DE && var != HU && var != SE && var != SE2) \
639 failure = __GCONV_ILLEGAL_INPUT; \
643 if (var != DK && var != NO && var != NO2) \
644 failure = __GCONV_ILLEGAL_INPUT; \
648 if (var == DE || var == HU) \
650 else if (var == SE2) \
653 failure = __GCONV_ILLEGAL_INPUT; \
657 failure = __GCONV_ILLEGAL_INPUT; \
661 if (var == CA || var == CA2 || var == FR || var == FR1) \
663 else if (var == IT) \
666 failure = __GCONV_ILLEGAL_INPUT; \
670 failure = __GCONV_ILLEGAL_INPUT; \
674 if (var != CA && var != CA2) \
675 failure = __GCONV_ILLEGAL_INPUT; \
679 if (var != PT && var != PT2) \
680 failure = __GCONV_ILLEGAL_INPUT; \
684 if (var != DE && var != SE && var != SE2) \
685 failure = __GCONV_ILLEGAL_INPUT; \
689 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
690 failure = __GCONV_ILLEGAL_INPUT; \
694 if (var != DK && var != NO && var != NO2) \
695 failure = __GCONV_ILLEGAL_INPUT; \
699 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
701 else if (var == ES || var == ES2) \
703 else if (var == PT || var == PT2) \
706 failure = __GCONV_ILLEGAL_INPUT; \
709 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
710 failure = __GCONV_ILLEGAL_INPUT; \
714 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
716 else if (var == IT) \
718 else if (var == SE2) \
721 failure = __GCONV_ILLEGAL_INPUT; \
724 if (var != CA && var != CA2) \
725 failure = __GCONV_ILLEGAL_INPUT; \
730 failure = __GCONV_ILLEGAL_INPUT; \
735 failure = __GCONV_ILLEGAL_INPUT; \
739 if (var != ES && var != ES2 && var != CU) \
740 failure = __GCONV_ILLEGAL_INPUT; \
745 failure = __GCONV_ILLEGAL_INPUT; \
749 if (var != CA && var != CA2) \
750 failure = __GCONV_ILLEGAL_INPUT; \
754 if (var != PT && var != PT2) \
755 failure = __GCONV_ILLEGAL_INPUT; \
759 if (var != DE && var != HU && var != SE && var != SE2) \
760 failure = __GCONV_ILLEGAL_INPUT; \
764 if (var != DK && var != NO && var != NO2) \
765 failure = __GCONV_ILLEGAL_INPUT; \
769 if (var == CA || var == CA2 || var == FR || var == FR1) \
771 else if (var == IT) \
774 failure = __GCONV_ILLEGAL_INPUT; \
777 if (var != CA && var != CA2) \
778 failure = __GCONV_ILLEGAL_INPUT; \
782 if (var == DE || var == HU) \
784 else if (var == SE2) \
787 failure = __GCONV_ILLEGAL_INPUT; \
791 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; \
850 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
851 failure = __GCONV_ILLEGAL_INPUT; \
856 failure = __GCONV_ILLEGAL_INPUT; \
860 if (var != JP_OCR_B) \
861 failure = __GCONV_ILLEGAL_INPUT; \
865 if (var != JP_OCR_B) \
866 failure = __GCONV_ILLEGAL_INPUT; \
870 if (*((uint32_t *) inptr) > 0x7f) \
871 failure = __GCONV_ILLEGAL_INPUT; \
875 if (failure == __GCONV_ILLEGAL_INPUT) \
877 /* Exit the loop with an error. */ \
881 *outptr++ = (unsigned char) ch; \
884 #define EXTRA_LOOP_DECLS , enum variant var
885 #include <iconv/loop.c>
888 /* Now define the toplevel functions. */
889 #include <iconv/skeleton.c>