Update.
[platform/upstream/glibc.git] / iconvdata / 8bit-gap.c
1 /* Generic conversion to and from 8bit charsets,
2    converting from UCS using gaps.
3    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library; if not, write to the Free
19    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20    02111-1307 USA.  */
21
22 #include <dlfcn.h>
23 #include <stdint.h>
24
25 struct gap
26 {
27   uint16_t start;
28   uint16_t end;
29   int32_t idx;
30 };
31
32 /* Now we can include the tables.  */
33 #include TABLES
34
35
36 #define FROM_LOOP               from_gap
37 #define TO_LOOP                 to_gap
38 #define DEFINE_INIT             1
39 #define DEFINE_FINI             1
40 #define MIN_NEEDED_FROM         1
41 #define MIN_NEEDED_TO           4
42
43
44 /* First define the conversion function from the 8bit charset to UCS4.  */
45 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
46 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
47 #define LOOPFCT                 FROM_LOOP
48 #define BODY \
49   {                                                                           \
50     uint32_t ch = to_ucs4[*inptr];                                            \
51                                                                               \
52     if (HAS_HOLES && __builtin_expect (ch, L'\1') == L'\0' && *inptr != '\0') \
53       {                                                                       \
54         /* This is an illegal character.  */                                  \
55         if (! ignore_errors_p ())                                             \
56           {                                                                   \
57             result = __GCONV_ILLEGAL_INPUT;                                   \
58             break;                                                            \
59           }                                                                   \
60                                                                               \
61         ++*irreversible;                                                      \
62       }                                                                       \
63     else                                                                      \
64       {                                                                       \
65         put32 (outptr, ch);                                                   \
66         outptr += 4;                                                          \
67       }                                                                       \
68                                                                               \
69     ++inptr;                                                                  \
70   }
71 #define LOOP_NEED_FLAGS
72 #include <iconv/loop.c>
73
74
75 /* Next, define the other direction.  */
76 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
77 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
78 #define LOOPFCT                 TO_LOOP
79 #define BODY \
80   {                                                                           \
81     const struct gap *rp = from_idx;                                          \
82     uint32_t ch = get32 (inptr);                                              \
83     unsigned char res;                                                        \
84                                                                               \
85     if (__builtin_expect (ch >= 0xffff, 0))                                   \
86       {                                                                       \
87         UNICODE_TAG_HANDLER (ch, 4);                                          \
88         rp = NULL;                                                            \
89       }                                                                       \
90     else                                                                      \
91       while (ch > rp->end)                                                    \
92         ++rp;                                                                 \
93     if (__builtin_expect (rp == NULL, 0)                                      \
94         || __builtin_expect (ch < rp->start, 0)                               \
95         || (res = from_ucs4[ch + rp->idx],                                    \
96             __builtin_expect (res, '\1') == '\0' && ch != 0))                 \
97       {                                                                       \
98         /* This is an illegal character.  */                                  \
99         STANDARD_ERR_HANDLER (4);                                             \
100       }                                                                       \
101                                                                               \
102     *outptr++ = res;                                                          \
103     inptr += 4;                                                               \
104   }
105 #define LOOP_NEED_FLAGS
106 #include <iconv/loop.c>
107
108
109 /* Now define the toplevel functions.  */
110 #include <iconv/skeleton.c>