| 1 | /* Conversion module for ISO-2022-JP-3. | 
|---|
| 2 | Copyright (C) 1998-2020 Free Software Foundation, Inc. | 
|---|
| 3 | This file is part of the GNU C Library. | 
|---|
| 4 | Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998, | 
|---|
| 5 | and Bruno Haible <bruno@clisp.org>, 2002. | 
|---|
| 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, see | 
|---|
| 19 | <https://www.gnu.org/licenses/>.  */ | 
|---|
| 20 |  | 
|---|
| 21 | #include <assert.h> | 
|---|
| 22 | #include <dlfcn.h> | 
|---|
| 23 | #include <gconv.h> | 
|---|
| 24 | #include <stdint.h> | 
|---|
| 25 | #include <string.h> | 
|---|
| 26 |  | 
|---|
| 27 | #include "jis0201.h" | 
|---|
| 28 | #include "jis0208.h" | 
|---|
| 29 | #include "jisx0213.h" | 
|---|
| 30 |  | 
|---|
| 31 | /* This makes obvious what everybody knows: 0x1b is the Esc character.  */ | 
|---|
| 32 | #define ESC 0x1b | 
|---|
| 33 |  | 
|---|
| 34 | /* Definitions used in the body of the `gconv' function.  */ | 
|---|
| 35 | #define CHARSET_NAME		"ISO-2022-JP-3//" | 
|---|
| 36 | #define FROM_LOOP		from_iso2022jp3_loop | 
|---|
| 37 | #define TO_LOOP			to_iso2022jp3_loop | 
|---|
| 38 | #define DEFINE_INIT		1 | 
|---|
| 39 | #define DEFINE_FINI		1 | 
|---|
| 40 | #define ONE_DIRECTION		0 | 
|---|
| 41 | #define FROM_LOOP_MIN_NEEDED_FROM	1 | 
|---|
| 42 | #define FROM_LOOP_MAX_NEEDED_FROM	4 | 
|---|
| 43 | #define FROM_LOOP_MIN_NEEDED_TO		4 | 
|---|
| 44 | #define FROM_LOOP_MAX_NEEDED_TO		8 | 
|---|
| 45 | #define TO_LOOP_MIN_NEEDED_FROM		4 | 
|---|
| 46 | #define TO_LOOP_MAX_NEEDED_FROM		4 | 
|---|
| 47 | #define TO_LOOP_MIN_NEEDED_TO		1 | 
|---|
| 48 | #define TO_LOOP_MAX_NEEDED_TO		6 | 
|---|
| 49 | #define PREPARE_LOOP \ | 
|---|
| 50 | int saved_state;							      \ | 
|---|
| 51 | int *statep = &data->__statep->__count; | 
|---|
| 52 | #define 		, statep | 
|---|
| 53 |  | 
|---|
| 54 |  | 
|---|
| 55 | /* The COUNT element of the state keeps track of the currently selected | 
|---|
| 56 | character set.  The possible values are:  */ | 
|---|
| 57 | enum | 
|---|
| 58 | { | 
|---|
| 59 | ASCII_set = 0,		/* Esc ( B */ | 
|---|
| 60 | JISX0208_1978_set = 1 << 3,	/* Esc $ @ */ | 
|---|
| 61 | JISX0208_1983_set = 2 << 3,	/* Esc $ B */ | 
|---|
| 62 | JISX0201_Roman_set = 3 << 3,	/* Esc ( J */ | 
|---|
| 63 | JISX0201_Kana_set = 4 << 3,	/* Esc ( I */ | 
|---|
| 64 | JISX0213_1_2000_set = 5 << 3,	/* Esc $ ( O */ | 
|---|
| 65 | JISX0213_2_set = 6 << 3,	/* Esc $ ( P */ | 
|---|
| 66 | JISX0213_1_2004_set = 7 << 3,	/* Esc $ ( Q */ | 
|---|
| 67 | CURRENT_SEL_MASK = 7 << 3 | 
|---|
| 68 | }; | 
|---|
| 69 |  | 
|---|
| 70 | /* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the state | 
|---|
| 71 | also contains the last two bytes to be output, shifted by 6 bits, and a | 
|---|
| 72 | one-bit indicator whether they must be preceded by the shift sequence, | 
|---|
| 73 | in bit 22.  */ | 
|---|
| 74 |  | 
|---|
| 75 | /* Since this is a stateful encoding we have to provide code which resets | 
|---|
| 76 | the output state to the initial state.  This has to be done during the | 
|---|
| 77 | flushing.  */ | 
|---|
| 78 | #define EMIT_SHIFT_TO_INIT \ | 
|---|
| 79 | if ((data->__statep->__count & ~7) != ASCII_set)			      \ | 
|---|
| 80 | {									      \ | 
|---|
| 81 | if (FROM_DIRECTION)						      \ | 
|---|
| 82 | {								      \ | 
|---|
| 83 | /* It's easy, we don't have to emit anything, we just reset the     \ | 
|---|
| 84 | state for the input.  */					      \ | 
|---|
| 85 | data->__statep->__count &= 7;					      \ | 
|---|
| 86 | data->__statep->__count |= ASCII_set;				      \ | 
|---|
| 87 | }								      \ | 
|---|
| 88 | else								      \ | 
|---|
| 89 | {								      \ | 
|---|
| 90 | /* We are not in the initial state.  To switch back we have	      \ | 
|---|
| 91 | to write out the buffered character and/or emit the sequence     \ | 
|---|
| 92 | `Esc ( B'.  */						      \ | 
|---|
| 93 | size_t need =							      \ | 
|---|
| 94 | (data->__statep->__count >> 6				      \ | 
|---|
| 95 | ? (data->__statep->__count >> 22 ? 3 : 0) + 2		      \ | 
|---|
| 96 | : 0)							      \ | 
|---|
| 97 | + ((data->__statep->__count & CURRENT_SEL_MASK) != ASCII_set      \ | 
|---|
| 98 | ? 3 : 0);						      \ | 
|---|
| 99 | \ | 
|---|
| 100 | if (__glibc_unlikely (outbuf + need > outend))		      \ | 
|---|
| 101 | /* We don't have enough room in the output buffer.  */	      \ | 
|---|
| 102 | status = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 103 | else								      \ | 
|---|
| 104 | {								      \ | 
|---|
| 105 | if (data->__statep->__count >> 6)				      \ | 
|---|
| 106 | {							      \ | 
|---|
| 107 | uint32_t lasttwo = data->__statep->__count >> 6;	      \ | 
|---|
| 108 | \ | 
|---|
| 109 | if (lasttwo >> 16)					      \ | 
|---|
| 110 | {							      \ | 
|---|
| 111 | /* Write out the shift sequence before the last	      \ | 
|---|
| 112 | character.  */					      \ | 
|---|
| 113 | assert ((data->__statep->__count & CURRENT_SEL_MASK)    \ | 
|---|
| 114 | == JISX0208_1983_set);			      \ | 
|---|
| 115 | *outbuf++ = ESC;					      \ | 
|---|
| 116 | *outbuf++ = '$';					      \ | 
|---|
| 117 | *outbuf++ = 'B';					      \ | 
|---|
| 118 | }							      \ | 
|---|
| 119 | /* Write out the last character.  */			      \ | 
|---|
| 120 | *outbuf++ = (lasttwo >> 8) & 0xff;			      \ | 
|---|
| 121 | *outbuf++ = lasttwo & 0xff;				      \ | 
|---|
| 122 | }							      \ | 
|---|
| 123 | if ((data->__statep->__count & CURRENT_SEL_MASK) != ASCII_set)  \ | 
|---|
| 124 | {							      \ | 
|---|
| 125 | /* Write out the shift sequence.  */			      \ | 
|---|
| 126 | *outbuf++ = ESC;					      \ | 
|---|
| 127 | *outbuf++ = '(';					      \ | 
|---|
| 128 | *outbuf++ = 'B';					      \ | 
|---|
| 129 | }							      \ | 
|---|
| 130 | data->__statep->__count &= 7;				      \ | 
|---|
| 131 | data->__statep->__count |= ASCII_set;			      \ | 
|---|
| 132 | }								      \ | 
|---|
| 133 | }								      \ | 
|---|
| 134 | } | 
|---|
| 135 |  | 
|---|
| 136 |  | 
|---|
| 137 | /* Since we might have to reset input pointer we must be able to save | 
|---|
| 138 | and retore the state.  */ | 
|---|
| 139 | #define SAVE_RESET_STATE(Save) \ | 
|---|
| 140 | if (Save)								      \ | 
|---|
| 141 | saved_state = *statep;						      \ | 
|---|
| 142 | else									      \ | 
|---|
| 143 | *statep = saved_state | 
|---|
| 144 |  | 
|---|
| 145 |  | 
|---|
| 146 | /* First define the conversion function from ISO-2022-JP-3 to UCS-4.  */ | 
|---|
| 147 | #define MIN_NEEDED_INPUT	FROM_LOOP_MIN_NEEDED_FROM | 
|---|
| 148 | #define MAX_NEEDED_INPUT	FROM_LOOP_MAX_NEEDED_FROM | 
|---|
| 149 | #define MIN_NEEDED_OUTPUT	FROM_LOOP_MIN_NEEDED_TO | 
|---|
| 150 | #define MAX_NEEDED_OUTPUT	FROM_LOOP_MAX_NEEDED_TO | 
|---|
| 151 | #define LOOPFCT			FROM_LOOP | 
|---|
| 152 | #define BODY \ | 
|---|
| 153 | {									      \ | 
|---|
| 154 | uint32_t ch = *inptr;						      \ | 
|---|
| 155 | \ | 
|---|
| 156 | /* Recognize escape sequences.  */					      \ | 
|---|
| 157 | if (__glibc_unlikely (ch == ESC))					      \ | 
|---|
| 158 | {									      \ | 
|---|
| 159 | /* We now must be prepared to read two to three more bytes.	      \ | 
|---|
| 160 | If we have a match in the first byte but then the input buffer     \ | 
|---|
| 161 | ends we terminate with an error since we must not risk missing     \ | 
|---|
| 162 | an escape sequence just because it is not entirely in the	      \ | 
|---|
| 163 | current input buffer.  */					      \ | 
|---|
| 164 | if (__builtin_expect (inptr + 2 >= inend, 0)			      \ | 
|---|
| 165 | || (inptr[1] == '$' && inptr[2] == '('			      \ | 
|---|
| 166 | && __builtin_expect (inptr + 3 >= inend, 0)))		      \ | 
|---|
| 167 | {								      \ | 
|---|
| 168 | /* Not enough input available.  */				      \ | 
|---|
| 169 | result = __GCONV_INCOMPLETE_INPUT;				      \ | 
|---|
| 170 | break;							      \ | 
|---|
| 171 | }								      \ | 
|---|
| 172 | \ | 
|---|
| 173 | if (inptr[1] == '(')						      \ | 
|---|
| 174 | {								      \ | 
|---|
| 175 | if (inptr[2] == 'B')					      \ | 
|---|
| 176 | {								      \ | 
|---|
| 177 | /* ASCII selected.  */					      \ | 
|---|
| 178 | set = ASCII_set;					      \ | 
|---|
| 179 | inptr += 3;						      \ | 
|---|
| 180 | continue;						      \ | 
|---|
| 181 | }								      \ | 
|---|
| 182 | else if (inptr[2] == 'J')					      \ | 
|---|
| 183 | {								      \ | 
|---|
| 184 | /* JIS X 0201 selected.  */				      \ | 
|---|
| 185 | set = JISX0201_Roman_set;				      \ | 
|---|
| 186 | inptr += 3;						      \ | 
|---|
| 187 | continue;						      \ | 
|---|
| 188 | }								      \ | 
|---|
| 189 | else if (inptr[2] == 'I')					      \ | 
|---|
| 190 | {								      \ | 
|---|
| 191 | /* JIS X 0201 selected.  */				      \ | 
|---|
| 192 | set = JISX0201_Kana_set;				      \ | 
|---|
| 193 | inptr += 3;						      \ | 
|---|
| 194 | continue;						      \ | 
|---|
| 195 | }								      \ | 
|---|
| 196 | }								      \ | 
|---|
| 197 | else if (inptr[1] == '$')					      \ | 
|---|
| 198 | {								      \ | 
|---|
| 199 | if (inptr[2] == '@')					      \ | 
|---|
| 200 | {								      \ | 
|---|
| 201 | /* JIS X 0208-1978 selected.  */			      \ | 
|---|
| 202 | set = JISX0208_1978_set;				      \ | 
|---|
| 203 | inptr += 3;						      \ | 
|---|
| 204 | continue;						      \ | 
|---|
| 205 | }								      \ | 
|---|
| 206 | else if (inptr[2] == 'B')					      \ | 
|---|
| 207 | {								      \ | 
|---|
| 208 | /* JIS X 0208-1983 selected.  */			      \ | 
|---|
| 209 | set = JISX0208_1983_set;				      \ | 
|---|
| 210 | inptr += 3;						      \ | 
|---|
| 211 | continue;						      \ | 
|---|
| 212 | }								      \ | 
|---|
| 213 | else if (inptr[2] == '(')					      \ | 
|---|
| 214 | {								      \ | 
|---|
| 215 | if (inptr[3] == 'O' || inptr[3] == 'Q')			      \ | 
|---|
| 216 | {							      \ | 
|---|
| 217 | /* JIS X 0213 plane 1 selected.  */			      \ | 
|---|
| 218 | /* In this direction we don't need to distinguish the     \ | 
|---|
| 219 | versions from 2000 and 2004. */			      \ | 
|---|
| 220 | set = JISX0213_1_2004_set;				      \ | 
|---|
| 221 | inptr += 4;						      \ | 
|---|
| 222 | continue;						      \ | 
|---|
| 223 | }							      \ | 
|---|
| 224 | else if (inptr[3] == 'P')				      \ | 
|---|
| 225 | {							      \ | 
|---|
| 226 | /* JIS X 0213 plane 2 selected.  */			      \ | 
|---|
| 227 | set = JISX0213_2_set;				      \ | 
|---|
| 228 | inptr += 4;						      \ | 
|---|
| 229 | continue;						      \ | 
|---|
| 230 | }							      \ | 
|---|
| 231 | }								      \ | 
|---|
| 232 | }								      \ | 
|---|
| 233 | }									      \ | 
|---|
| 234 | \ | 
|---|
| 235 | if (ch >= 0x80)							      \ | 
|---|
| 236 | {									      \ | 
|---|
| 237 | STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \ | 
|---|
| 238 | }									      \ | 
|---|
| 239 | else if (set == ASCII_set || (ch < 0x21 || ch == 0x7f))		      \ | 
|---|
| 240 | /* Almost done, just advance the input pointer.  */		      \ | 
|---|
| 241 | ++inptr;								      \ | 
|---|
| 242 | else if (set == JISX0201_Roman_set)					      \ | 
|---|
| 243 | {									      \ | 
|---|
| 244 | /* Use the JIS X 0201 table.  */				      \ | 
|---|
| 245 | ch = jisx0201_to_ucs4 (ch);					      \ | 
|---|
| 246 | if (__glibc_unlikely (ch == __UNKNOWN_10646_CHAR))		      \ | 
|---|
| 247 | {								      \ | 
|---|
| 248 | STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \ | 
|---|
| 249 | }								      \ | 
|---|
| 250 | ++inptr;							      \ | 
|---|
| 251 | }									      \ | 
|---|
| 252 | else if (set == JISX0201_Kana_set)					      \ | 
|---|
| 253 | {									      \ | 
|---|
| 254 | /* Use the JIS X 0201 table.  */				      \ | 
|---|
| 255 | ch = jisx0201_to_ucs4 (ch + 0x80);				      \ | 
|---|
| 256 | if (__glibc_unlikely (ch == __UNKNOWN_10646_CHAR))		      \ | 
|---|
| 257 | {								      \ | 
|---|
| 258 | STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \ | 
|---|
| 259 | }								      \ | 
|---|
| 260 | ++inptr;							      \ | 
|---|
| 261 | }									      \ | 
|---|
| 262 | else if (set == JISX0208_1978_set || set == JISX0208_1983_set)	      \ | 
|---|
| 263 | {									      \ | 
|---|
| 264 | /* XXX I don't have the tables for these two old variants of	      \ | 
|---|
| 265 | JIS X 0208.  Therefore I'm using the tables for JIS X	      \ | 
|---|
| 266 | 0208-1990.  If somebody has problems with this please	      \ | 
|---|
| 267 | provide the appropriate tables.  */				      \ | 
|---|
| 268 | ch = jisx0208_to_ucs4 (&inptr, inend - inptr, 0);		      \ | 
|---|
| 269 | \ | 
|---|
| 270 | if (__glibc_unlikely (ch == 0))					      \ | 
|---|
| 271 | {								      \ | 
|---|
| 272 | result = __GCONV_INCOMPLETE_INPUT;				      \ | 
|---|
| 273 | break;							      \ | 
|---|
| 274 | }								      \ | 
|---|
| 275 | else if (__glibc_unlikely (ch == __UNKNOWN_10646_CHAR))		      \ | 
|---|
| 276 | {								      \ | 
|---|
| 277 | STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \ | 
|---|
| 278 | }								      \ | 
|---|
| 279 | }									      \ | 
|---|
| 280 | else /* (set == JISX0213_1_2004_set || set == JISX0213_2_set) */	      \ | 
|---|
| 281 | {									      \ | 
|---|
| 282 | if (__glibc_unlikely (inptr + 1 >= inend))			      \ | 
|---|
| 283 | {								      \ | 
|---|
| 284 | result = __GCONV_INCOMPLETE_INPUT;				      \ | 
|---|
| 285 | break;							      \ | 
|---|
| 286 | }								      \ | 
|---|
| 287 | \ | 
|---|
| 288 | ch = jisx0213_to_ucs4 (						      \ | 
|---|
| 289 | ((JISX0213_1_2004_set - set + (1 << 3)) << 5) + ch,	      \ | 
|---|
| 290 | inptr[1]);						      \ | 
|---|
| 291 | if (ch == 0)							      \ | 
|---|
| 292 | STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \ | 
|---|
| 293 | \ | 
|---|
| 294 | if (ch < 0x80)							      \ | 
|---|
| 295 | {								      \ | 
|---|
| 296 | /* It's a combining character.  */				      \ | 
|---|
| 297 | uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0];	      \ | 
|---|
| 298 | uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1];	      \ | 
|---|
| 299 | \ | 
|---|
| 300 | /* See whether we have room for two characters.  */		      \ | 
|---|
| 301 | if (outptr + 8 <= outend)					      \ | 
|---|
| 302 | {								      \ | 
|---|
| 303 | inptr += 2;						      \ | 
|---|
| 304 | put32 (outptr, u1);					      \ | 
|---|
| 305 | outptr += 4;						      \ | 
|---|
| 306 | put32 (outptr, u2);					      \ | 
|---|
| 307 | outptr += 4;						      \ | 
|---|
| 308 | continue;						      \ | 
|---|
| 309 | }								      \ | 
|---|
| 310 | else							      \ | 
|---|
| 311 | {								      \ | 
|---|
| 312 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 313 | break;							      \ | 
|---|
| 314 | }								      \ | 
|---|
| 315 | }								      \ | 
|---|
| 316 | \ | 
|---|
| 317 | inptr += 2;							      \ | 
|---|
| 318 | }									      \ | 
|---|
| 319 | \ | 
|---|
| 320 | put32 (outptr, ch);							      \ | 
|---|
| 321 | outptr += 4;							      \ | 
|---|
| 322 | } | 
|---|
| 323 | #define LOOP_NEED_FLAGS | 
|---|
| 324 | #define 	, int *statep | 
|---|
| 325 | #define INIT_PARAMS		int set = *statep | 
|---|
| 326 | #define UPDATE_PARAMS		*statep = set | 
|---|
| 327 | #include <iconv/loop.c> | 
|---|
| 328 |  | 
|---|
| 329 |  | 
|---|
| 330 | /* Next, define the other direction, from UCS-4 to ISO-2022-JP-3.  */ | 
|---|
| 331 |  | 
|---|
| 332 | /* Composition tables for each of the relevant combining characters.  */ | 
|---|
| 333 | static const struct | 
|---|
| 334 | { | 
|---|
| 335 | uint16_t base; | 
|---|
| 336 | uint16_t composed; | 
|---|
| 337 | } comp_table_data[] = | 
|---|
| 338 | { | 
|---|
| 339 | #define COMP_TABLE_IDX_02E5 0 | 
|---|
| 340 | #define COMP_TABLE_LEN_02E5 1 | 
|---|
| 341 | { 0x2b64, 0x2b65 }, /* 0x12B65 = 0x12B64 U+02E5 */ | 
|---|
| 342 | #define COMP_TABLE_IDX_02E9 (COMP_TABLE_IDX_02E5 + COMP_TABLE_LEN_02E5) | 
|---|
| 343 | #define COMP_TABLE_LEN_02E9 1 | 
|---|
| 344 | { 0x2b60, 0x2b66 }, /* 0x12B66 = 0x12B60 U+02E9 */ | 
|---|
| 345 | #define COMP_TABLE_IDX_0300 (COMP_TABLE_IDX_02E9 + COMP_TABLE_LEN_02E9) | 
|---|
| 346 | #define COMP_TABLE_LEN_0300 5 | 
|---|
| 347 | { 0x295c, 0x2b44 }, /* 0x12B44 = 0x1295C U+0300 */ | 
|---|
| 348 | { 0x2b38, 0x2b48 }, /* 0x12B48 = 0x12B38 U+0300 */ | 
|---|
| 349 | { 0x2b37, 0x2b4a }, /* 0x12B4A = 0x12B37 U+0300 */ | 
|---|
| 350 | { 0x2b30, 0x2b4c }, /* 0x12B4C = 0x12B30 U+0300 */ | 
|---|
| 351 | { 0x2b43, 0x2b4e }, /* 0x12B4E = 0x12B43 U+0300 */ | 
|---|
| 352 | #define COMP_TABLE_IDX_0301 (COMP_TABLE_IDX_0300 + COMP_TABLE_LEN_0300) | 
|---|
| 353 | #define COMP_TABLE_LEN_0301 4 | 
|---|
| 354 | { 0x2b38, 0x2b49 }, /* 0x12B49 = 0x12B38 U+0301 */ | 
|---|
| 355 | { 0x2b37, 0x2b4b }, /* 0x12B4B = 0x12B37 U+0301 */ | 
|---|
| 356 | { 0x2b30, 0x2b4d }, /* 0x12B4D = 0x12B30 U+0301 */ | 
|---|
| 357 | { 0x2b43, 0x2b4f }, /* 0x12B4F = 0x12B43 U+0301 */ | 
|---|
| 358 | #define COMP_TABLE_IDX_309A (COMP_TABLE_IDX_0301 + COMP_TABLE_LEN_0301) | 
|---|
| 359 | #define COMP_TABLE_LEN_309A 14 | 
|---|
| 360 | { 0x242b, 0x2477 }, /* 0x12477 = 0x1242B U+309A */ | 
|---|
| 361 | { 0x242d, 0x2478 }, /* 0x12478 = 0x1242D U+309A */ | 
|---|
| 362 | { 0x242f, 0x2479 }, /* 0x12479 = 0x1242F U+309A */ | 
|---|
| 363 | { 0x2431, 0x247a }, /* 0x1247A = 0x12431 U+309A */ | 
|---|
| 364 | { 0x2433, 0x247b }, /* 0x1247B = 0x12433 U+309A */ | 
|---|
| 365 | { 0x252b, 0x2577 }, /* 0x12577 = 0x1252B U+309A */ | 
|---|
| 366 | { 0x252d, 0x2578 }, /* 0x12578 = 0x1252D U+309A */ | 
|---|
| 367 | { 0x252f, 0x2579 }, /* 0x12579 = 0x1252F U+309A */ | 
|---|
| 368 | { 0x2531, 0x257a }, /* 0x1257A = 0x12531 U+309A */ | 
|---|
| 369 | { 0x2533, 0x257b }, /* 0x1257B = 0x12533 U+309A */ | 
|---|
| 370 | { 0x253b, 0x257c }, /* 0x1257C = 0x1253B U+309A */ | 
|---|
| 371 | { 0x2544, 0x257d }, /* 0x1257D = 0x12544 U+309A */ | 
|---|
| 372 | { 0x2548, 0x257e }, /* 0x1257E = 0x12548 U+309A */ | 
|---|
| 373 | { 0x2675, 0x2678 }, /* 0x12678 = 0x12675 U+309A */ | 
|---|
| 374 | }; | 
|---|
| 375 |  | 
|---|
| 376 | #define MIN_NEEDED_INPUT	TO_LOOP_MIN_NEEDED_FROM | 
|---|
| 377 | #define MAX_NEEDED_INPUT	TO_LOOP_MAX_NEEDED_FROM | 
|---|
| 378 | #define MIN_NEEDED_OUTPUT	TO_LOOP_MIN_NEEDED_TO | 
|---|
| 379 | #define MAX_NEEDED_OUTPUT	TO_LOOP_MAX_NEEDED_TO | 
|---|
| 380 | #define LOOPFCT			TO_LOOP | 
|---|
| 381 | #define BODY \ | 
|---|
| 382 | {									      \ | 
|---|
| 383 | uint32_t ch = get32 (inptr);					      \ | 
|---|
| 384 | \ | 
|---|
| 385 | if (lasttwo != 0)							      \ | 
|---|
| 386 | {									      \ | 
|---|
| 387 | /* Attempt to combine the last character with this one.  */	      \ | 
|---|
| 388 | unsigned int idx;						      \ | 
|---|
| 389 | unsigned int len;						      \ | 
|---|
| 390 | \ | 
|---|
| 391 | if (ch == 0x02e5)						      \ | 
|---|
| 392 | idx = COMP_TABLE_IDX_02E5, len = COMP_TABLE_LEN_02E5;		      \ | 
|---|
| 393 | else if (ch == 0x02e9)						      \ | 
|---|
| 394 | idx = COMP_TABLE_IDX_02E9, len = COMP_TABLE_LEN_02E9;		      \ | 
|---|
| 395 | else if (ch == 0x0300)						      \ | 
|---|
| 396 | idx = COMP_TABLE_IDX_0300, len = COMP_TABLE_LEN_0300;		      \ | 
|---|
| 397 | else if (ch == 0x0301)						      \ | 
|---|
| 398 | idx = COMP_TABLE_IDX_0301, len = COMP_TABLE_LEN_0301;		      \ | 
|---|
| 399 | else if (ch == 0x309a)						      \ | 
|---|
| 400 | idx = COMP_TABLE_IDX_309A, len = COMP_TABLE_LEN_309A;		      \ | 
|---|
| 401 | else								      \ | 
|---|
| 402 | goto not_combining;						      \ | 
|---|
| 403 | \ | 
|---|
| 404 | do								      \ | 
|---|
| 405 | if (comp_table_data[idx].base == (uint16_t) lasttwo)		      \ | 
|---|
| 406 | break;							      \ | 
|---|
| 407 | while (++idx, --len > 0);					      \ | 
|---|
| 408 | \ | 
|---|
| 409 | if (len > 0)							      \ | 
|---|
| 410 | {								      \ | 
|---|
| 411 | /* Output the combined character.  */			      \ | 
|---|
| 412 | /* We know the combined character is in JISX0213 plane 1,	      \ | 
|---|
| 413 | but the buffered character may have been in JISX0208 or in     \ | 
|---|
| 414 | JISX0213 plane 1.  */					      \ | 
|---|
| 415 | size_t need =						      \ | 
|---|
| 416 | (lasttwo >> 16						      \ | 
|---|
| 417 | || (set != JISX0213_1_2000_set && set != JISX0213_1_2004_set)  \ | 
|---|
| 418 | ? 4 : 0);						      \ | 
|---|
| 419 | \ | 
|---|
| 420 | if (__glibc_unlikely (outptr + need + 2 > outend))		      \ | 
|---|
| 421 | {								      \ | 
|---|
| 422 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 423 | break;							      \ | 
|---|
| 424 | }								      \ | 
|---|
| 425 | if (need)							      \ | 
|---|
| 426 | {								      \ | 
|---|
| 427 | /* But first, output the escape sequence.  */		      \ | 
|---|
| 428 | *outptr++ = ESC;					      \ | 
|---|
| 429 | *outptr++ = '$';					      \ | 
|---|
| 430 | *outptr++ = '(';					      \ | 
|---|
| 431 | *outptr++ = 'O';					      \ | 
|---|
| 432 | set = JISX0213_1_2000_set;				      \ | 
|---|
| 433 | }								      \ | 
|---|
| 434 | lasttwo = comp_table_data[idx].composed;			      \ | 
|---|
| 435 | *outptr++ = (lasttwo >> 8) & 0xff;				      \ | 
|---|
| 436 | *outptr++ = lasttwo & 0xff;					      \ | 
|---|
| 437 | lasttwo = 0;						      \ | 
|---|
| 438 | inptr += 4;							      \ | 
|---|
| 439 | continue;							      \ | 
|---|
| 440 | }								      \ | 
|---|
| 441 | \ | 
|---|
| 442 | not_combining:							      \ | 
|---|
| 443 | /* Output the buffered character.  */				      \ | 
|---|
| 444 | /* We know it is in JISX0208 or in JISX0213 plane 1.  */	      \ | 
|---|
| 445 | {								      \ | 
|---|
| 446 | size_t need = (lasttwo >> 16 ? 3 : 0);			      \ | 
|---|
| 447 | \ | 
|---|
| 448 | if (__glibc_unlikely (outptr + need + 2 > outend))		      \ | 
|---|
| 449 | {								      \ | 
|---|
| 450 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 451 | break;							      \ | 
|---|
| 452 | }								      \ | 
|---|
| 453 | if (need)							      \ | 
|---|
| 454 | {								      \ | 
|---|
| 455 | /* But first, output the escape sequence.  */		      \ | 
|---|
| 456 | assert (set == JISX0208_1983_set);			      \ | 
|---|
| 457 | *outptr++ = ESC;						      \ | 
|---|
| 458 | *outptr++ = '$';						      \ | 
|---|
| 459 | *outptr++ = 'B';						      \ | 
|---|
| 460 | }								      \ | 
|---|
| 461 | *outptr++ = (lasttwo >> 8) & 0xff;				      \ | 
|---|
| 462 | *outptr++ = lasttwo & 0xff;					      \ | 
|---|
| 463 | lasttwo = 0;							      \ | 
|---|
| 464 | continue;							      \ | 
|---|
| 465 | }								      \ | 
|---|
| 466 | }									      \ | 
|---|
| 467 | \ | 
|---|
| 468 | /* First see whether we can write the character using the currently	      \ | 
|---|
| 469 | selected character set.  */					      \ | 
|---|
| 470 | if (set == ASCII_set)						      \ | 
|---|
| 471 | {									      \ | 
|---|
| 472 | /* Please note that the NUL byte is *not* matched if we are not	      \ | 
|---|
| 473 | currently using the ASCII charset.  This is because we must	      \ | 
|---|
| 474 | switch to the initial state whenever a NUL byte is written.  */    \ | 
|---|
| 475 | if (ch <= 0x7f)							      \ | 
|---|
| 476 | {								      \ | 
|---|
| 477 | *outptr++ = ch;						      \ | 
|---|
| 478 | inptr += 4;							      \ | 
|---|
| 479 | continue;							      \ | 
|---|
| 480 | }								      \ | 
|---|
| 481 | }									      \ | 
|---|
| 482 | /* ISO-2022-JP recommends to encode the newline character always in	      \ | 
|---|
| 483 | ASCII since this allows a context-free interpretation of the	      \ | 
|---|
| 484 | characters at the beginning of the next line.  Otherwise it would      \ | 
|---|
| 485 | have to be known whether the last line ended using ASCII or	      \ | 
|---|
| 486 | JIS X 0201.  */							      \ | 
|---|
| 487 | else if (set == JISX0201_Roman_set)					      \ | 
|---|
| 488 | {									      \ | 
|---|
| 489 | unsigned char buf[1];						      \ | 
|---|
| 490 | if (ucs4_to_jisx0201 (ch, buf) != __UNKNOWN_10646_CHAR		      \ | 
|---|
| 491 | && buf[0] > 0x20 && buf[0] < 0x80)				      \ | 
|---|
| 492 | {								      \ | 
|---|
| 493 | *outptr++ = buf[0];						      \ | 
|---|
| 494 | inptr += 4;							      \ | 
|---|
| 495 | continue;							      \ | 
|---|
| 496 | }								      \ | 
|---|
| 497 | }									      \ | 
|---|
| 498 | else if (set == JISX0201_Kana_set)					      \ | 
|---|
| 499 | {									      \ | 
|---|
| 500 | unsigned char buf[1];						      \ | 
|---|
| 501 | if (ucs4_to_jisx0201 (ch, buf) != __UNKNOWN_10646_CHAR		      \ | 
|---|
| 502 | && buf[0] >= 0x80)						      \ | 
|---|
| 503 | {								      \ | 
|---|
| 504 | *outptr++ = buf[0] - 0x80;					      \ | 
|---|
| 505 | inptr += 4;							      \ | 
|---|
| 506 | continue;							      \ | 
|---|
| 507 | }								      \ | 
|---|
| 508 | }									      \ | 
|---|
| 509 | else if (/*set == JISX0208_1978_set || */ set == JISX0208_1983_set)	      \ | 
|---|
| 510 | {									      \ | 
|---|
| 511 | size_t written = ucs4_to_jisx0208 (ch, outptr, outend - outptr);      \ | 
|---|
| 512 | \ | 
|---|
| 513 | if (written != __UNKNOWN_10646_CHAR)				      \ | 
|---|
| 514 | {								      \ | 
|---|
| 515 | uint32_t jch = ucs4_to_jisx0213 (ch);			      \ | 
|---|
| 516 | \ | 
|---|
| 517 | if (jch & 0x0080)						      \ | 
|---|
| 518 | {								      \ | 
|---|
| 519 | /* A possible match in comp_table_data.  Buffer it.  */	      \ | 
|---|
| 520 | lasttwo = jch & 0x7f7f;					      \ | 
|---|
| 521 | inptr += 4;						      \ | 
|---|
| 522 | continue;						      \ | 
|---|
| 523 | }								      \ | 
|---|
| 524 | if (__glibc_unlikely (written == 0))			      \ | 
|---|
| 525 | {								      \ | 
|---|
| 526 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 527 | break;							      \ | 
|---|
| 528 | }								      \ | 
|---|
| 529 | else							      \ | 
|---|
| 530 | {								      \ | 
|---|
| 531 | outptr += written;					      \ | 
|---|
| 532 | inptr += 4;						      \ | 
|---|
| 533 | continue;						      \ | 
|---|
| 534 | }								      \ | 
|---|
| 535 | }								      \ | 
|---|
| 536 | }									      \ | 
|---|
| 537 | else								      \ | 
|---|
| 538 | {									      \ | 
|---|
| 539 | /* (set == JISX0213_1_2000_set || set == JISX0213_1_2004_set	      \ | 
|---|
| 540 | || set == JISX0213_2_set) */				      \ | 
|---|
| 541 | uint32_t jch = ucs4_to_jisx0213 (ch);				      \ | 
|---|
| 542 | \ | 
|---|
| 543 | if (jch != 0							      \ | 
|---|
| 544 | && (jch & 0x8000						      \ | 
|---|
| 545 | ? set == JISX0213_2_set					      \ | 
|---|
| 546 | : (set == JISX0213_1_2004_set				      \ | 
|---|
| 547 | || (set == JISX0213_1_2000_set			      \ | 
|---|
| 548 | && !jisx0213_added_in_2004_p (jch)))))		      \ | 
|---|
| 549 | {								      \ | 
|---|
| 550 | if (jch & 0x0080)						      \ | 
|---|
| 551 | {								      \ | 
|---|
| 552 | /* A possible match in comp_table_data.  Buffer it.  */	      \ | 
|---|
| 553 | \ | 
|---|
| 554 | /* We know it's a JISX 0213 plane 1 character.  */	      \ | 
|---|
| 555 | assert ((jch & 0x8000) == 0);				      \ | 
|---|
| 556 | \ | 
|---|
| 557 | lasttwo = jch & 0x7f7f;					      \ | 
|---|
| 558 | inptr += 4;						      \ | 
|---|
| 559 | continue;						      \ | 
|---|
| 560 | }								      \ | 
|---|
| 561 | \ | 
|---|
| 562 | if (__glibc_unlikely (outptr + 1 >= outend))		      \ | 
|---|
| 563 | {								      \ | 
|---|
| 564 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 565 | break;							      \ | 
|---|
| 566 | }								      \ | 
|---|
| 567 | *outptr++ = (jch >> 8) & 0x7f;				      \ | 
|---|
| 568 | *outptr++ = jch & 0x7f;					      \ | 
|---|
| 569 | inptr += 4;							      \ | 
|---|
| 570 | continue;							      \ | 
|---|
| 571 | }								      \ | 
|---|
| 572 | }									      \ | 
|---|
| 573 | \ | 
|---|
| 574 | /* The attempts to use the currently selected character set failed,	      \ | 
|---|
| 575 | either because the character requires a different character set,	      \ | 
|---|
| 576 | or because the character is unknown.  */				      \ | 
|---|
| 577 | \ | 
|---|
| 578 | if (ch <= 0x7f)							      \ | 
|---|
| 579 | {									      \ | 
|---|
| 580 | /* We must encode using ASCII.  First write out the escape	      \ | 
|---|
| 581 | sequence.  */						      \ | 
|---|
| 582 | if (__glibc_unlikely (outptr + 3 > outend))			      \ | 
|---|
| 583 | {								      \ | 
|---|
| 584 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 585 | break;							      \ | 
|---|
| 586 | }								      \ | 
|---|
| 587 | \ | 
|---|
| 588 | *outptr++ = ESC;						      \ | 
|---|
| 589 | *outptr++ = '(';						      \ | 
|---|
| 590 | *outptr++ = 'B';						      \ | 
|---|
| 591 | set = ASCII_set;						      \ | 
|---|
| 592 | \ | 
|---|
| 593 | if (__glibc_unlikely (outptr >= outend))			      \ | 
|---|
| 594 | {								      \ | 
|---|
| 595 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 596 | break;							      \ | 
|---|
| 597 | }								      \ | 
|---|
| 598 | *outptr++ = ch;							      \ | 
|---|
| 599 | }									      \ | 
|---|
| 600 | else								      \ | 
|---|
| 601 | {									      \ | 
|---|
| 602 | unsigned char buf[2];						      \ | 
|---|
| 603 | \ | 
|---|
| 604 | /* Try JIS X 0201 Roman.  */					      \ | 
|---|
| 605 | if (ucs4_to_jisx0201 (ch, buf) != __UNKNOWN_10646_CHAR		      \ | 
|---|
| 606 | && buf[0] > 0x20 && buf[0] < 0x80)				      \ | 
|---|
| 607 | {								      \ | 
|---|
| 608 | if (set != JISX0201_Roman_set)				      \ | 
|---|
| 609 | {								      \ | 
|---|
| 610 | if (__glibc_unlikely (outptr + 3 > outend))		      \ | 
|---|
| 611 | {							      \ | 
|---|
| 612 | result = __GCONV_FULL_OUTPUT;			      \ | 
|---|
| 613 | break;						      \ | 
|---|
| 614 | }							      \ | 
|---|
| 615 | *outptr++ = ESC;					      \ | 
|---|
| 616 | *outptr++ = '(';					      \ | 
|---|
| 617 | *outptr++ = 'J';					      \ | 
|---|
| 618 | set = JISX0201_Roman_set;				      \ | 
|---|
| 619 | }								      \ | 
|---|
| 620 | \ | 
|---|
| 621 | if (__glibc_unlikely (outptr >= outend))			      \ | 
|---|
| 622 | {								      \ | 
|---|
| 623 | result = __GCONV_FULL_OUTPUT;				      \ | 
|---|
| 624 | break;							      \ | 
|---|
| 625 | }								      \ | 
|---|
| 626 | *outptr++ = buf[0];						      \ | 
|---|
| 627 | }								      \ | 
|---|
| 628 | else								      \ | 
|---|
| 629 | {								      \ | 
|---|
| 630 | uint32_t jch = ucs4_to_jisx0213 (ch);			      \ | 
|---|
| 631 | \ | 
|---|
| 632 | /* Try JIS X 0208.  */					      \ | 
|---|
| 633 | size_t written = ucs4_to_jisx0208 (ch, buf, 2);		      \ | 
|---|
| 634 | if (written != __UNKNOWN_10646_CHAR)			      \ | 
|---|
| 635 | {								      \ | 
|---|
| 636 | if (jch & 0x0080)					      \ | 
|---|
| 637 | {							      \ | 
|---|
| 638 | /* A possible match in comp_table_data.  Buffer it.  */   \ | 
|---|
| 639 | lasttwo = ((set != JISX0208_1983_set ? 1 : 0) << 16)      \ | 
|---|
| 640 | | (jch & 0x7f7f);				      \ | 
|---|
| 641 | set = JISX0208_1983_set;				      \ | 
|---|
| 642 | inptr += 4;						      \ | 
|---|
| 643 | continue;						      \ | 
|---|
| 644 | }							      \ | 
|---|
| 645 | \ | 
|---|
| 646 | if (set != JISX0208_1983_set)				      \ | 
|---|
| 647 | {							      \ | 
|---|
| 648 | if (__glibc_unlikely (outptr + 3 > outend))		      \ | 
|---|
| 649 | {							      \ | 
|---|
| 650 | result = __GCONV_FULL_OUTPUT;			      \ | 
|---|
| 651 | break;						      \ | 
|---|
| 652 | }							      \ | 
|---|
| 653 | *outptr++ = ESC;					      \ | 
|---|
| 654 | *outptr++ = '$';					      \ | 
|---|
| 655 | *outptr++ = 'B';					      \ | 
|---|
| 656 | set = JISX0208_1983_set;				      \ | 
|---|
| 657 | }							      \ | 
|---|
| 658 | \ | 
|---|
| 659 | if (__glibc_unlikely (outptr + 2 > outend))		      \ | 
|---|
| 660 | {							      \ | 
|---|
| 661 | result = __GCONV_FULL_OUTPUT;			      \ | 
|---|
| 662 | break;						      \ | 
|---|
| 663 | }							      \ | 
|---|
| 664 | *outptr++ = buf[0];					      \ | 
|---|
| 665 | *outptr++ = buf[1];					      \ | 
|---|
| 666 | }								      \ | 
|---|
| 667 | else							      \ | 
|---|
| 668 | {								      \ | 
|---|
| 669 | /* Try JIS X 0213.  */					      \ | 
|---|
| 670 | if (jch != 0)						      \ | 
|---|
| 671 | {							      \ | 
|---|
| 672 | int new_set =					      \ | 
|---|
| 673 | (jch & 0x8000					      \ | 
|---|
| 674 | ? JISX0213_2_set					      \ | 
|---|
| 675 | : jisx0213_added_in_2004_p (jch)			      \ | 
|---|
| 676 | ? JISX0213_1_2004_set				      \ | 
|---|
| 677 | : JISX0213_1_2000_set);			      \ | 
|---|
| 678 | \ | 
|---|
| 679 | if (set != new_set)					      \ | 
|---|
| 680 | {							      \ | 
|---|
| 681 | if (__glibc_unlikely (outptr + 4 > outend))	      \ | 
|---|
| 682 | {						      \ | 
|---|
| 683 | result = __GCONV_FULL_OUTPUT;		      \ | 
|---|
| 684 | break;					      \ | 
|---|
| 685 | }						      \ | 
|---|
| 686 | *outptr++ = ESC;				      \ | 
|---|
| 687 | *outptr++ = '$';				      \ | 
|---|
| 688 | *outptr++ = '(';				      \ | 
|---|
| 689 | *outptr++ =					      \ | 
|---|
| 690 | ((new_set - JISX0213_1_2000_set) >> 3) + 'O';	      \ | 
|---|
| 691 | set = new_set;					      \ | 
|---|
| 692 | }							      \ | 
|---|
| 693 | \ | 
|---|
| 694 | if (jch & 0x0080)					      \ | 
|---|
| 695 | {							      \ | 
|---|
| 696 | /* A possible match in comp_table_data.		      \ | 
|---|
| 697 | Buffer it.  */				      \ | 
|---|
| 698 | \ | 
|---|
| 699 | /* We know it's a JIS X 0213 plane 1 character.  */   \ | 
|---|
| 700 | assert ((jch & 0x8000) == 0);			      \ | 
|---|
| 701 | \ | 
|---|
| 702 | lasttwo = jch & 0x7f7f;				      \ | 
|---|
| 703 | inptr += 4;					      \ | 
|---|
| 704 | continue;					      \ | 
|---|
| 705 | }							      \ | 
|---|
| 706 | \ | 
|---|
| 707 | if (__glibc_unlikely (outptr + 1 >= outend))	      \ | 
|---|
| 708 | {							      \ | 
|---|
| 709 | result = __GCONV_FULL_OUTPUT;			      \ | 
|---|
| 710 | break;						      \ | 
|---|
| 711 | }							      \ | 
|---|
| 712 | *outptr++ = (jch >> 8) & 0x7f;			      \ | 
|---|
| 713 | *outptr++ = jch & 0x7f;				      \ | 
|---|
| 714 | }							      \ | 
|---|
| 715 | else							      \ | 
|---|
| 716 | {							      \ | 
|---|
| 717 | /* Try JIS X 0201 Katakana.  This is officially not part  \ | 
|---|
| 718 | of ISO-2022-JP-3.  Therefore we try it after all other \ | 
|---|
| 719 | attempts.  */					      \ | 
|---|
| 720 | if (ucs4_to_jisx0201 (ch, buf) != __UNKNOWN_10646_CHAR    \ | 
|---|
| 721 | && buf[0] >= 0x80)				      \ | 
|---|
| 722 | {							      \ | 
|---|
| 723 | if (set != JISX0201_Kana_set)			      \ | 
|---|
| 724 | {						      \ | 
|---|
| 725 | if (__builtin_expect (outptr + 3 > outend, 0))    \ | 
|---|
| 726 | {						      \ | 
|---|
| 727 | result = __GCONV_FULL_OUTPUT;		      \ | 
|---|
| 728 | break;					      \ | 
|---|
| 729 | }						      \ | 
|---|
| 730 | *outptr++ = ESC;				      \ | 
|---|
| 731 | *outptr++ = '(';				      \ | 
|---|
| 732 | *outptr++ = 'I';				      \ | 
|---|
| 733 | set = JISX0201_Kana_set;			      \ | 
|---|
| 734 | }						      \ | 
|---|
| 735 | \ | 
|---|
| 736 | if (__glibc_unlikely (outptr >= outend))	      \ | 
|---|
| 737 | {						      \ | 
|---|
| 738 | result = __GCONV_FULL_OUTPUT;		      \ | 
|---|
| 739 | break;					      \ | 
|---|
| 740 | }						      \ | 
|---|
| 741 | *outptr++ = buf[0] - 0x80;			      \ | 
|---|
| 742 | }							      \ | 
|---|
| 743 | else						      \ | 
|---|
| 744 | {							      \ | 
|---|
| 745 | UNICODE_TAG_HANDLER (ch, 4);			      \ | 
|---|
| 746 | \ | 
|---|
| 747 | /* Illegal character.  */			      \ | 
|---|
| 748 | STANDARD_TO_LOOP_ERR_HANDLER (4);		      \ | 
|---|
| 749 | }							      \ | 
|---|
| 750 | }							      \ | 
|---|
| 751 | }								      \ | 
|---|
| 752 | }								      \ | 
|---|
| 753 | }									      \ | 
|---|
| 754 | \ | 
|---|
| 755 | /* Now that we wrote the output increment the input pointer.  */	      \ | 
|---|
| 756 | inptr += 4;								      \ | 
|---|
| 757 | } | 
|---|
| 758 | #define LOOP_NEED_FLAGS | 
|---|
| 759 | #define 	, int *statep | 
|---|
| 760 | #define INIT_PARAMS		int set = *statep & CURRENT_SEL_MASK;	      \ | 
|---|
| 761 | uint32_t lasttwo = *statep >> 6 | 
|---|
| 762 | #define REINIT_PARAMS		do					      \ | 
|---|
| 763 | {					      \ | 
|---|
| 764 | set = *statep & CURRENT_SEL_MASK;	      \ | 
|---|
| 765 | lasttwo = *statep >> 6;		      \ | 
|---|
| 766 | }					      \ | 
|---|
| 767 | while (0) | 
|---|
| 768 | #define UPDATE_PARAMS		*statep = set | (lasttwo << 6) | 
|---|
| 769 | #include <iconv/loop.c> | 
|---|
| 770 |  | 
|---|
| 771 |  | 
|---|
| 772 | /* Now define the toplevel functions.  */ | 
|---|
| 773 | #include <iconv/skeleton.c> | 
|---|
| 774 |  | 
|---|