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. */
38 /* Definitions used in the body of the `gconv' function. */
39 #define FROM_LOOP from_ascii
40 #define TO_LOOP to_ascii
43 #define MIN_NEEDED_FROM 1
44 #define MIN_NEEDED_TO 4
45 #define FROM_DIRECTION (dir == from_iso646)
46 #define PREPARE_LOOP \
47 enum direction dir = ((struct iso646_data *) step->data)->dir; \
48 enum variant var = ((struct iso646_data *) step->data)->var;
49 #define EXTRA_LOOP_ARGS , var
52 /* Direction of the transformation. */
63 US
, /* ANSI_X3.4-1968 */
65 CA
, /* CSA_Z243.4-1985-1 */
66 CA2
, /* CSA_Z243.4-1985-2 */
73 JP
, /* JIS_C6220-1969-RO */
74 JP_OCR_B
, /* JIS_C6229-1984-B */
75 YU
, /* JUS_I.B1.002 */
80 FR1
, /* NF_Z_62-010_(1973) */
85 SE
, /* SEN_850200_B */
86 SE2
/* SEN_850200_C */
89 static const char *names
[] =
91 [US
] = "ANSI_X3.4-1968//",
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)//",
109 [NO
] = "NS_4551-1//",
110 [NO2
] = "NS_4551-2//",
113 [SE
] = "SEN_850200_B//",
114 [SE2
] = "SEN_850200_C//"
125 gconv_init (struct gconv_step
*step
)
127 /* Determine which direction. */
128 struct iso646_data
*new_data
;
129 enum direction dir
= illegal_dir
;
133 for (var
= sizeof (names
) / sizeof (names
[0]) - 1; var
> illegal_var
; --var
)
134 if (__strcasecmp (step
->from_name
, names
[var
]) == 0)
139 else if (__strcasecmp (step
->to_name
, names
[var
]) == 0)
145 result
= GCONV_NOCONV
;
146 if (dir
!= illegal_dir
148 = (struct iso646_data
*) malloc (sizeof (struct iso646_data
)))
153 step
->data
= new_data
;
155 if (var
== from_iso646
)
157 step
->min_needed_from
= MIN_NEEDED_FROM
;
158 step
->max_needed_from
= MIN_NEEDED_FROM
;
159 step
->min_needed_to
= MIN_NEEDED_TO
;
160 step
->max_needed_to
= MIN_NEEDED_TO
;
164 step
->min_needed_from
= MIN_NEEDED_TO
;
165 step
->max_needed_from
= MIN_NEEDED_TO
;
166 step
->min_needed_to
= MIN_NEEDED_FROM
;
167 step
->max_needed_to
= MIN_NEEDED_FROM
;
180 gconv_end (struct gconv_step
*data
)
186 /* First define the conversion function from ASCII to UCS4. */
187 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
188 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
189 #define LOOPFCT FROM_LOOP
193 int failure = GCONV_OK; \
199 if (var == GB || var == ES || var == IT || var == FR || var == FR1) \
201 else if (var == NO2) \
207 else if (var == HU || var == CU || var == SE || var == SE2) \
211 if (var == CA || var == CA2 || var == FR || var == FR1) \
213 else if (var == DE || var == ES || var == IT || var == PT) \
215 else if (var == ES2) \
217 else if (var == YU) \
219 else if (var == HU) \
221 else if (var == PT2) \
223 else if (var == SE2) \
227 if (var == CA || var == CA2) \
229 else if (var == DE || var == SE || var == SE2) \
231 else if (var == DK || var == NO || var == NO2) \
233 else if (var == ES || var == ES2 || var == CU) \
235 else if (var == IT || var == FR || var == FR1) \
237 else if (var == JP_OCR_B) \
239 else if (var == YU) \
241 else if (var == HU) \
243 else if (var == PT || var == PT2) \
247 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
249 else if (var == DE || var == HU || var == SE || var == SE2) \
251 else if (var == DK || var == NO || var == NO2) \
253 else if (var == ES || var == ES2 || var == CU) \
255 else if (var == JP || var == JP_OCR_B) \
257 else if (var == YU) \
259 else if (var == KR) \
261 else if (var == PT || var == PT2) \
265 if (var == CA || var == CA2) \
267 else if (var == DE || var == HU) \
269 else if (var == DK || var == NO || var == NO2 || var == SE \
272 else if (var == ES) \
274 else if (var == ES2) \
276 else if (var == IT) \
278 else if (var == JP_OCR_B) \
280 else if (var == YU) \
282 else if (var == FR || var == FR1) \
284 else if (var == PT || var == PT2) \
290 else if (var == CA2) \
292 else if (var == ES2 || var == CU) \
294 else if (var == YU) \
296 else if (var == SE2) \
300 if (var == CA || var == CA2) \
302 else if (var == IT) \
304 else if (var == JP_OCR_B) \
305 /* Illegal character. */ \
306 failure = GCONV_ILLEGAL_INPUT; \
307 else if (var == YU) \
309 else if (var == HU) \
311 else if (var == FR) \
313 else if (var == SE2) \
317 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
319 else if (var == DE || var == SE || var == SE2) \
321 else if (var == DK || var == NO || var == NO2) \
323 else if (var == ES) \
325 else if (var == ES2 || var == CU) \
327 else if (var == IT) \
329 else if (var == YU) \
331 else if (var == PT || var == PT2) \
335 if (var == CA || var == CA2 || var == FR || var == FR1) \
337 else if (var == DE || var == HU || var == SE || var == SE2) \
339 else if (var == DK || var == NO || var == NO2) \
341 else if (var == ES || var == ES2 || var == CU) \
343 else if (var == IT) \
345 else if (var == YU) \
347 else if (var == PT || var == PT2) \
351 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
353 else if (var == DE || var == HU) \
355 else if (var == DK || var == NO || var == NO2 || var == SE \
358 else if (var == ES || var == ES2) \
360 else if (var == YU) \
362 else if (var == CU) \
364 else if (var == PT || var == PT2) \
368 if (var == GB || var == CN || var == JP || var == NO || var == SE) \
370 else if (var == CA || var == CA2) \
372 else if (var == DE) \
374 else if (var == ES2 || var == CU || var == FR || var == FR1) \
376 else if (var == IT) \
378 else if (var == JP_OCR_B) \
379 /* Illegal character. */ \
380 failure = GCONV_ILLEGAL_INPUT; \
381 else if (var == YU) \
383 else if (var == HU) \
385 else if (var == NO2) \
387 else if (var == PT) \
389 else if (var == SE2) \
394 case 0x80 ... 0xff: \
395 /* Illegal character. */ \
396 failure = GCONV_ILLEGAL_INPUT; \
400 /* Hopefully gcc can recognize that the following `if' is only true \
401 when we reach the default case in the `switch' statement. */ \
402 if (failure == GCONV_ILLEGAL_INPUT) \
404 /* Exit the loop with an error. */ \
408 *((uint32_t *) outptr)++ = ch; \
411 #define EXTRA_LOOP_DECLS , enum variant var
412 #include <iconv/loop.c>
415 /* Next, define the other direction. */
416 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
417 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
418 #define LOOPFCT TO_LOOP
422 int failure = GCONV_OK; \
424 ch = *((uint32_t *) inptr); \
425 switch (*((uint32_t *) inptr)) \
428 if (var == GB || var == ES || var == IT || var == FR || var == FR1 \
430 failure = GCONV_ILLEGAL_INPUT; \
433 if (var == CN || var == HU || var == CU || var == SE || var == SE2) \
434 failure = GCONV_ILLEGAL_INPUT; \
437 if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \
438 || var == IT || var == YU || var == HU || var == FR || var == FR1 \
439 || var == PT || var == PT2 || var == SE2) \
440 failure = GCONV_ILLEGAL_INPUT; \
443 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
444 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
445 || var == HU || var == FR || var == FR1 || var == NO \
446 || var == NO2 || var == PT || var == PT2 || var == SE \
448 failure = GCONV_ILLEGAL_INPUT; \
449 else if (var == CU) \
453 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
454 || var == ES2 || var == IT || var == JP || var == JP_OCR_B \
455 || var == YU || var == KR || var == HU || var == CU || var == FR \
456 || var == FR1 || var == NO || var == NO2 || var == PT \
457 || var == PT2 || var == SE || var == SE2) \
458 failure = GCONV_ILLEGAL_INPUT; \
461 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
462 || var == ES2 || var == IT || var == JP_OCR_B || var == YU \
463 || var == HU || var == FR || var == FR1 || var == NO \
464 || var == NO2 || var == PT || var == PT2 || var == SE \
466 failure = GCONV_ILLEGAL_INPUT; \
469 if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \
471 failure = GCONV_ILLEGAL_INPUT; \
474 if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \
475 || var == YU || var == HU || var == FR || var == SE2) \
476 failure = GCONV_ILLEGAL_INPUT; \
479 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
480 || var == ES2 || var == IT || var == YU || var == HU \
481 || var == CU || var == FR || var == FR1 || var == NO \
482 || var == NO2 || var == PT || var == PT2 || var == SE \
484 failure = GCONV_ILLEGAL_INPUT; \
487 if (var == CA || var == CA2 || var == DE || var == DK || var == ES \
488 || var == ES2 || var == IT || var == YU || var == HU || var == CU \
489 || var == FR || var == FR1 || var == NO || var == PT \
490 || var == PT2 || var == SE || var == SE2) \
491 failure = GCONV_ILLEGAL_INPUT; \
492 else if (var == NO2) \
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 == NO2 \
499 || var == PT || var == PT2 || var == SE || var == SE2) \
500 failure = GCONV_ILLEGAL_INPUT; \
503 if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \
504 || var == CN || var == IT || var == JP || var == JP_OCR_B \
505 || var == YU || var == HU || var == CU || var == FR || var == FR1 \
506 || var == NO || var == NO2 || var == PT || var == SE \
508 failure = GCONV_ILLEGAL_INPUT; \
511 if (var != ES && var != ES2 && var != CU) \
512 failure = GCONV_ILLEGAL_INPUT; \
516 if (var != GB && var != ES && var != IT && var != FR && var != FR1) \
517 failure = GCONV_ILLEGAL_INPUT; \
521 if (var != HU && var != CU && var != SE && var != SE2) \
522 failure = GCONV_ILLEGAL_INPUT; \
528 else if (var == JP || var == JP_OCR_B) \
531 failure = GCONV_ILLEGAL_INPUT; \
534 if (var == DE || var == ES || var == IT || var == PT) \
536 else if (var == FR || var == FR1) \
538 else if (var == NO2) \
541 failure = GCONV_ILLEGAL_INPUT; \
544 if (var != ES2 && var != CU && var != FR && var != FR1) \
545 failure = GCONV_ILLEGAL_INPUT; \
551 else if (var == IT || var == FR || var == FR1) \
553 else if (var == PT) \
556 failure = GCONV_ILLEGAL_INPUT; \
559 if (var == ES2 || var == CU) \
561 else if (var == PT2) \
564 failure = GCONV_ILLEGAL_INPUT; \
568 failure = GCONV_ILLEGAL_INPUT; \
574 else if (var == ES2 || var == CU) \
577 failure = GCONV_ILLEGAL_INPUT; \
581 failure = GCONV_ILLEGAL_INPUT; \
585 if (var != PT && var != PT2) \
586 failure = GCONV_ILLEGAL_INPUT; \
590 if (var != DE && var != SE && var != SE2) \
591 failure = GCONV_ILLEGAL_INPUT; \
595 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
596 failure = GCONV_ILLEGAL_INPUT; \
600 if (var != DK && var != NO && var != NO2) \
601 failure = GCONV_ILLEGAL_INPUT; \
607 else if (var == PT || var == PT2) \
610 failure = GCONV_ILLEGAL_INPUT; \
615 else if (var == HU) \
617 else if (var == SE2) \
620 failure = GCONV_ILLEGAL_INPUT; \
623 if (var != ES && var != ES2 && var != CU) \
624 failure = GCONV_ILLEGAL_INPUT; \
628 if (var != PT && var != PT2) \
629 failure = GCONV_ILLEGAL_INPUT; \
633 if (var != DE && var != HU && var != SE && var != SE2) \
634 failure = GCONV_ILLEGAL_INPUT; \
638 if (var != DK && var != NO && var != NO2) \
639 failure = GCONV_ILLEGAL_INPUT; \
643 if (var == DE || var == HU) \
645 else if (var == SE2) \
648 failure = GCONV_ILLEGAL_INPUT; \
652 failure = GCONV_ILLEGAL_INPUT; \
656 if (var == CA || var == CA2 || var == FR || var == FR1) \
658 else if (var == IT) \
661 failure = GCONV_ILLEGAL_INPUT; \
665 failure = GCONV_ILLEGAL_INPUT; \
669 if (var != CA && var != CA2) \
670 failure = GCONV_ILLEGAL_INPUT; \
674 if (var != PT && var != PT2) \
675 failure = GCONV_ILLEGAL_INPUT; \
679 if (var != DE && var != SE && var != SE2) \
680 failure = GCONV_ILLEGAL_INPUT; \
684 if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \
685 failure = GCONV_ILLEGAL_INPUT; \
689 if (var != DK && var != NO && var != NO2) \
690 failure = GCONV_ILLEGAL_INPUT; \
694 if (var == CA || var == CA2 || var == IT || var == FR || var == FR1) \
696 else if (var == ES || var == ES2) \
698 else if (var == PT || var == PT2) \
701 failure = GCONV_ILLEGAL_INPUT; \
704 if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \
705 failure = GCONV_ILLEGAL_INPUT; \
709 if (var == CA || var == CA2 || var == HU || var == FR || var == FR1) \
711 else if (var == IT) \
713 else if (var == SE2) \
716 failure = GCONV_ILLEGAL_INPUT; \
719 if (var != CA && var != CA2) \
720 failure = GCONV_ILLEGAL_INPUT; \
725 failure = GCONV_ILLEGAL_INPUT; \
730 failure = GCONV_ILLEGAL_INPUT; \
734 if (var != ES && var != ES2 && var != CU) \
735 failure = GCONV_ILLEGAL_INPUT; \
740 failure = GCONV_ILLEGAL_INPUT; \
744 if (var != CA && var != CA2) \
745 failure = GCONV_ILLEGAL_INPUT; \
749 if (var != PT && var != PT2) \
750 failure = GCONV_ILLEGAL_INPUT; \
754 if (var != DE && var != HU && var != SE && var != SE2) \
755 failure = GCONV_ILLEGAL_INPUT; \
759 if (var != DK && var != NO && var != NO2) \
760 failure = GCONV_ILLEGAL_INPUT; \
764 if (var == CA || var == CA2 || var == FR || var == FR1) \
766 else if (var == IT) \
769 failure = GCONV_ILLEGAL_INPUT; \
772 if (var != CA && var != CA2) \
773 failure = GCONV_ILLEGAL_INPUT; \
777 if (var == DE || var == HU) \
779 else if (var == SE2) \
782 failure = GCONV_ILLEGAL_INPUT; \
786 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; \
845 if (var != GB && var != CN && var != JP && var != NO && var != SE) \
846 failure = GCONV_ILLEGAL_INPUT; \
851 failure = GCONV_ILLEGAL_INPUT; \
855 if (var != JP_OCR_B) \
856 failure = GCONV_ILLEGAL_INPUT; \
860 if (var != JP_OCR_B) \
861 failure = GCONV_ILLEGAL_INPUT; \
865 if (*((uint32_t *) inptr) > 0x7f) \
866 failure = GCONV_ILLEGAL_INPUT; \
870 if (failure == GCONV_ILLEGAL_INPUT) \
872 /* Exit the loop with an error. */ \
876 *outptr++ = (unsigned char) ch; \
879 #define EXTRA_LOOP_DECLS , enum variant var
880 #include <iconv/loop.c>
883 /* Now define the toplevel functions. */
884 #include <iconv/skeleton.c>