stdlib: Undo post review change to 16adc58e73f3 [BZ #27749]
[glibc.git] / iconv / skeleton.c
blob61cff234acbb0e8b9e2367ee9de9b0217aaeb5a3
1 /* Skeleton for a conversion module.
2 Copyright (C) 1998-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* This file can be included to provide definitions of several things
20 many modules have in common. It can be customized using the following
21 macros:
23 DEFINE_INIT define the default initializer. This requires the
24 following symbol to be defined.
26 CHARSET_NAME string with official name of the coded character
27 set (in all-caps)
29 DEFINE_FINI define the default destructor function.
31 MIN_NEEDED_FROM minimal number of bytes needed for the from-charset.
32 MIN_NEEDED_TO likewise for the to-charset.
34 MAX_NEEDED_FROM maximal number of bytes needed for the from-charset.
35 This macro is optional, it defaults to MIN_NEEDED_FROM.
36 MAX_NEEDED_TO likewise for the to-charset.
38 FROM_LOOP_MIN_NEEDED_FROM
39 FROM_LOOP_MAX_NEEDED_FROM
40 minimal/maximal number of bytes needed on input
41 of one round through the FROM_LOOP. Defaults
42 to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively.
43 FROM_LOOP_MIN_NEEDED_TO
44 FROM_LOOP_MAX_NEEDED_TO
45 minimal/maximal number of bytes needed on output
46 of one round through the FROM_LOOP. Defaults
47 to MIN_NEEDED_TO and MAX_NEEDED_TO, respectively.
48 TO_LOOP_MIN_NEEDED_FROM
49 TO_LOOP_MAX_NEEDED_FROM
50 minimal/maximal number of bytes needed on input
51 of one round through the TO_LOOP. Defaults
52 to MIN_NEEDED_TO and MAX_NEEDED_TO, respectively.
53 TO_LOOP_MIN_NEEDED_TO
54 TO_LOOP_MAX_NEEDED_TO
55 minimal/maximal number of bytes needed on output
56 of one round through the TO_LOOP. Defaults
57 to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively.
59 FROM_DIRECTION this macro is supposed to return a value != 0
60 if we convert from the current character set,
61 otherwise it return 0.
63 EMIT_SHIFT_TO_INIT this symbol is optional. If it is defined it
64 defines some code which writes out a sequence
65 of bytes which bring the current state into
66 the initial state.
68 FROM_LOOP name of the function implementing the conversion
69 from the current character set.
70 TO_LOOP likewise for the other direction
72 ONE_DIRECTION optional. If defined to 1, only one conversion
73 direction is defined instead of two. In this
74 case, FROM_DIRECTION should be defined to 1, and
75 FROM_LOOP and TO_LOOP should have the same value.
77 SAVE_RESET_STATE in case of an error we must reset the state for
78 the rerun so this macro must be defined for
79 stateful encodings. It takes an argument which
80 is nonzero when saving.
82 RESET_INPUT_BUFFER If the input character sets allow this the macro
83 can be defined to reset the input buffer pointers
84 to cover only those characters up to the error.
85 Note that if the conversion has skipped over
86 irreversible characters (due to
87 __GCONV_IGNORE_ERRORS) there is no longer a direct
88 correspondence between input and output pointers,
89 and this macro is not called.
91 FUNCTION_NAME if not set the conversion function is named `gconv'.
93 PREPARE_LOOP optional code preparing the conversion loop. Can
94 contain variable definitions.
95 END_LOOP also optional, may be used to store information
97 EXTRA_LOOP_ARGS optional macro specifying extra arguments passed
98 to loop function.
100 STORE_REST optional, needed only when MAX_NEEDED_FROM > 4.
101 This macro stores the seen but unconverted input bytes
102 in the state.
104 FROM_ONEBYTE optional. If defined, should be the name of a
105 specialized conversion function for a single byte
106 from the current character set to INTERNAL. This
107 function has prototype
108 wint_t
109 FROM_ONEBYTE (struct __gconv_step *, unsigned char);
110 and does a special conversion:
111 - The input is a single byte.
112 - The output is a single uint32_t.
113 - The state before the conversion is the initial state;
114 the state after the conversion is irrelevant.
115 - No transliteration.
116 - __invocation_counter = 0.
117 - __internal_use = 1.
118 - do_flush = 0.
120 Modules can use mbstate_t to store conversion state as follows:
122 * Bits 2..0 of '__count' contain the number of lookahead input bytes
123 stored in __value.__wchb. Always zero if the converter never
124 returns __GCONV_INCOMPLETE_INPUT.
126 * Bits 31..3 of '__count' are module dependent shift state.
128 * __value: When STORE_REST/UNPACK_BYTES aren't defined and when the
129 converter has returned __GCONV_INCOMPLETE_INPUT, this contains
130 at most 4 lookahead bytes. Converters with an mb_cur_max > 4
131 (currently only UTF-8) must find a way to store their state
132 in __value.__wch and define STORE_REST/UNPACK_BYTES appropriately.
134 When __value contains lookahead, __count must not be zero, because
135 the converter is not in the initial state then, and mbsinit() --
136 defined as a (__count == 0) test -- must reflect this.
139 #include <assert.h>
140 #include <iconv/gconv_int.h>
141 #include <string.h>
142 #define __need_size_t
143 #define __need_NULL
144 #include <stddef.h>
146 #ifndef STATIC_GCONV
147 # include <dlfcn.h>
148 #endif
150 #include <pointer_guard.h>
151 #include <stdint.h>
153 #ifndef DL_CALL_FCT
154 # define DL_CALL_FCT(fct, args) fct args
155 #endif
157 /* The direction objects. */
158 #if DEFINE_INIT
159 # ifndef FROM_DIRECTION
160 # define FROM_DIRECTION_VAL NULL
161 # define TO_DIRECTION_VAL ((void *) ~((uintptr_t) 0))
162 # define FROM_DIRECTION (step->__data == FROM_DIRECTION_VAL)
163 # endif
164 #else
165 # ifndef FROM_DIRECTION
166 # error "FROM_DIRECTION must be provided if non-default init is used"
167 # endif
168 #endif
170 /* How many bytes are needed at most for the from-charset. */
171 #ifndef MAX_NEEDED_FROM
172 # define MAX_NEEDED_FROM MIN_NEEDED_FROM
173 #endif
175 /* Same for the to-charset. */
176 #ifndef MAX_NEEDED_TO
177 # define MAX_NEEDED_TO MIN_NEEDED_TO
178 #endif
180 /* Defaults for the per-direction min/max constants. */
181 #ifndef FROM_LOOP_MIN_NEEDED_FROM
182 # define FROM_LOOP_MIN_NEEDED_FROM MIN_NEEDED_FROM
183 #endif
184 #ifndef FROM_LOOP_MAX_NEEDED_FROM
185 # define FROM_LOOP_MAX_NEEDED_FROM MAX_NEEDED_FROM
186 #endif
187 #ifndef FROM_LOOP_MIN_NEEDED_TO
188 # define FROM_LOOP_MIN_NEEDED_TO MIN_NEEDED_TO
189 #endif
190 #ifndef FROM_LOOP_MAX_NEEDED_TO
191 # define FROM_LOOP_MAX_NEEDED_TO MAX_NEEDED_TO
192 #endif
193 #ifndef TO_LOOP_MIN_NEEDED_FROM
194 # define TO_LOOP_MIN_NEEDED_FROM MIN_NEEDED_TO
195 #endif
196 #ifndef TO_LOOP_MAX_NEEDED_FROM
197 # define TO_LOOP_MAX_NEEDED_FROM MAX_NEEDED_TO
198 #endif
199 #ifndef TO_LOOP_MIN_NEEDED_TO
200 # define TO_LOOP_MIN_NEEDED_TO MIN_NEEDED_FROM
201 #endif
202 #ifndef TO_LOOP_MAX_NEEDED_TO
203 # define TO_LOOP_MAX_NEEDED_TO MAX_NEEDED_FROM
204 #endif
207 /* For conversions from a fixed width character set to another fixed width
208 character set we can define RESET_INPUT_BUFFER in a very fast way. */
209 #if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
210 # if FROM_LOOP_MIN_NEEDED_FROM == FROM_LOOP_MAX_NEEDED_FROM \
211 && FROM_LOOP_MIN_NEEDED_TO == FROM_LOOP_MAX_NEEDED_TO \
212 && TO_LOOP_MIN_NEEDED_FROM == TO_LOOP_MAX_NEEDED_FROM \
213 && TO_LOOP_MIN_NEEDED_TO == TO_LOOP_MAX_NEEDED_TO
214 /* We have to use these `if's here since the compiler cannot know that
215 (outbuf - outerr) is always divisible by FROM/TO_LOOP_MIN_NEEDED_TO.
216 The ?:1 avoids division by zero warnings that gcc 3.2 emits even for
217 obviously unreachable code. */
218 # define RESET_INPUT_BUFFER \
219 if (FROM_DIRECTION) \
221 if (FROM_LOOP_MIN_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_TO == 0) \
222 *inptrp -= (outbuf - outerr) \
223 * (FROM_LOOP_MIN_NEEDED_FROM / FROM_LOOP_MIN_NEEDED_TO); \
224 else if (FROM_LOOP_MIN_NEEDED_TO % FROM_LOOP_MIN_NEEDED_FROM == 0) \
225 *inptrp -= (outbuf - outerr) \
226 / (FROM_LOOP_MIN_NEEDED_TO / FROM_LOOP_MIN_NEEDED_FROM \
227 ? : 1); \
228 else \
229 *inptrp -= ((outbuf - outerr) / FROM_LOOP_MIN_NEEDED_TO) \
230 * FROM_LOOP_MIN_NEEDED_FROM; \
232 else \
234 if (TO_LOOP_MIN_NEEDED_FROM % TO_LOOP_MIN_NEEDED_TO == 0) \
235 *inptrp -= (outbuf - outerr) \
236 * (TO_LOOP_MIN_NEEDED_FROM / TO_LOOP_MIN_NEEDED_TO); \
237 else if (TO_LOOP_MIN_NEEDED_TO % TO_LOOP_MIN_NEEDED_FROM == 0) \
238 *inptrp -= (outbuf - outerr) \
239 / (TO_LOOP_MIN_NEEDED_TO / TO_LOOP_MIN_NEEDED_FROM ? : 1); \
240 else \
241 *inptrp -= ((outbuf - outerr) / TO_LOOP_MIN_NEEDED_TO) \
242 * TO_LOOP_MIN_NEEDED_FROM; \
244 # endif
245 #endif
248 /* The default init function. It simply matches the name and initializes
249 the step data to point to one of the objects above. */
250 #if DEFINE_INIT
251 # ifndef CHARSET_NAME
252 # error "CHARSET_NAME not defined"
253 # endif
255 extern int gconv_init (struct __gconv_step *step);
257 gconv_init (struct __gconv_step *step)
259 /* Determine which direction. */
260 if (strcmp (step->__from_name, CHARSET_NAME) == 0)
262 step->__data = FROM_DIRECTION_VAL;
264 step->__min_needed_from = FROM_LOOP_MIN_NEEDED_FROM;
265 step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM;
266 step->__min_needed_to = FROM_LOOP_MIN_NEEDED_TO;
267 step->__max_needed_to = FROM_LOOP_MAX_NEEDED_TO;
269 #ifdef FROM_ONEBYTE
270 step->__btowc_fct = FROM_ONEBYTE;
271 #endif
273 else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
275 step->__data = TO_DIRECTION_VAL;
277 step->__min_needed_from = TO_LOOP_MIN_NEEDED_FROM;
278 step->__max_needed_from = TO_LOOP_MAX_NEEDED_FROM;
279 step->__min_needed_to = TO_LOOP_MIN_NEEDED_TO;
280 step->__max_needed_to = TO_LOOP_MAX_NEEDED_TO;
282 else
283 return __GCONV_NOCONV;
285 #ifdef SAVE_RESET_STATE
286 step->__stateful = 1;
287 #else
288 step->__stateful = 0;
289 #endif
291 return __GCONV_OK;
293 #endif
296 /* The default destructor function does nothing in the moment and so
297 we don't define it at all. But we still provide the macro just in
298 case we need it some day. */
299 #if DEFINE_FINI
300 #endif
303 /* If no arguments have to passed to the loop function define the macro
304 as empty. */
305 #ifndef EXTRA_LOOP_ARGS
306 # define EXTRA_LOOP_ARGS
307 #endif
310 /* This is the actual conversion function. */
311 #ifndef FUNCTION_NAME
312 # define FUNCTION_NAME gconv
313 #endif
315 /* The macros are used to access the function to convert single characters. */
316 #define SINGLE(fct) SINGLE2 (fct)
317 #define SINGLE2(fct) fct##_single
320 extern int FUNCTION_NAME (struct __gconv_step *step,
321 struct __gconv_step_data *data,
322 const unsigned char **inptrp,
323 const unsigned char *inend,
324 unsigned char **outbufstart, size_t *irreversible,
325 int do_flush, int consume_incomplete);
327 FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
328 const unsigned char **inptrp, const unsigned char *inend,
329 unsigned char **outbufstart, size_t *irreversible, int do_flush,
330 int consume_incomplete)
332 struct __gconv_step *next_step = step + 1;
333 struct __gconv_step_data *next_data = data + 1;
334 __gconv_fct fct = NULL;
335 int status;
337 if ((data->__flags & __GCONV_IS_LAST) == 0)
339 fct = next_step->__fct;
340 if (next_step->__shlib_handle != NULL)
341 PTR_DEMANGLE (fct);
344 /* If the function is called with no input this means we have to reset
345 to the initial state. The possibly partly converted input is
346 dropped. */
347 if (__glibc_unlikely (do_flush))
349 /* This should never happen during error handling. */
350 assert (outbufstart == NULL);
352 status = __GCONV_OK;
354 #ifdef EMIT_SHIFT_TO_INIT
355 if (do_flush == 1)
357 /* We preserve the initial values of the pointer variables. */
358 unsigned char *outbuf = data->__outbuf;
359 unsigned char *outstart = outbuf;
360 unsigned char *outend = data->__outbufend;
362 # ifdef PREPARE_LOOP
363 PREPARE_LOOP
364 # endif
366 # ifdef SAVE_RESET_STATE
367 SAVE_RESET_STATE (1);
368 # endif
370 /* Emit the escape sequence to reset the state. */
371 EMIT_SHIFT_TO_INIT;
373 /* Call the steps down the chain if there are any but only if we
374 successfully emitted the escape sequence. This should only
375 fail if the output buffer is full. If the input is invalid
376 it should be discarded since the user wants to start from a
377 clean state. */
378 if (status == __GCONV_OK)
380 if (data->__flags & __GCONV_IS_LAST)
381 /* Store information about how many bytes are available. */
382 data->__outbuf = outbuf;
383 else
385 /* Write out all output which was produced. */
386 if (outbuf > outstart)
388 const unsigned char *outerr = outstart;
389 int result;
391 result = DL_CALL_FCT (fct, (next_step, next_data,
392 &outerr, outbuf, NULL,
393 irreversible, 0,
394 consume_incomplete));
396 if (result != __GCONV_EMPTY_INPUT)
398 if (__glibc_unlikely (outerr != outbuf))
400 /* We have a problem. Undo the conversion. */
401 outbuf = outstart;
403 /* Restore the state. */
404 # ifdef SAVE_RESET_STATE
405 SAVE_RESET_STATE (0);
406 # endif
409 /* Change the status. */
410 status = result;
414 if (status == __GCONV_OK)
415 /* Now flush the remaining steps. */
416 status = DL_CALL_FCT (fct, (next_step, next_data, NULL,
417 NULL, NULL, irreversible, 1,
418 consume_incomplete));
422 else
423 #endif
425 /* Clear the state object. There might be bytes in there from
426 previous calls with CONSUME_INCOMPLETE == 1. But don't emit
427 escape sequences. */
428 memset (data->__statep, '\0', sizeof (*data->__statep));
430 if (! (data->__flags & __GCONV_IS_LAST))
431 /* Now flush the remaining steps. */
432 status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL,
433 NULL, irreversible, do_flush,
434 consume_incomplete));
437 else
439 /* We preserve the initial values of the pointer variables,
440 but only some conversion modules need it. */
441 const unsigned char *inptr __attribute__ ((__unused__)) = *inptrp;
442 unsigned char *outbuf = (__builtin_expect (outbufstart == NULL, 1)
443 ? data->__outbuf : *outbufstart);
444 unsigned char *outend = data->__outbufend;
445 unsigned char *outstart;
446 /* This variable is used to count the number of characters we
447 actually converted. */
448 size_t lirreversible = 0;
449 size_t *lirreversiblep = irreversible ? &lirreversible : NULL;
451 #ifdef PREPARE_LOOP
452 PREPARE_LOOP
453 #endif
455 #if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1
456 /* If the function is used to implement the mb*towc*() or wc*tomb*()
457 functions we must test whether any bytes from the last call are
458 stored in the `state' object. */
459 if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1)
460 || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
461 || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION))
462 && consume_incomplete && (data->__statep->__count & 7) != 0)
464 /* Yep, we have some bytes left over. Process them now.
465 But this must not happen while we are called from an
466 error handler. */
467 assert (outbufstart == NULL);
469 # if FROM_LOOP_MAX_NEEDED_FROM > 1
470 if (TO_LOOP_MAX_NEEDED_FROM == 1 || FROM_DIRECTION)
471 status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf,
472 outend, lirreversiblep
473 EXTRA_LOOP_ARGS);
474 # endif
475 # if !ONE_DIRECTION
476 # if FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1
477 else
478 # endif
479 # if TO_LOOP_MAX_NEEDED_FROM > 1
480 status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf,
481 outend, lirreversiblep EXTRA_LOOP_ARGS);
482 # endif
483 # endif
485 if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
486 return status;
488 #endif
490 while (1)
492 /* Remember the start value for this round. */
493 inptr = *inptrp;
494 /* The outbuf buffer is empty. */
495 outstart = outbuf;
496 #ifdef RESET_INPUT_BUFFER
497 /* Remember how many irreversible characters were skipped before
498 this round. */
499 size_t loop_irreversible
500 = lirreversible + (irreversible ? *irreversible : 0);
501 #endif
503 #ifdef SAVE_RESET_STATE
504 SAVE_RESET_STATE (1);
505 #endif
507 if (FROM_DIRECTION)
508 /* Run the conversion loop. */
509 status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
510 lirreversiblep EXTRA_LOOP_ARGS);
511 else
512 /* Run the conversion loop. */
513 status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
514 lirreversiblep EXTRA_LOOP_ARGS);
516 /* If we were called as part of an error handling module we
517 don't do anything else here. */
518 if (__glibc_unlikely (outbufstart != NULL))
520 *outbufstart = outbuf;
521 return status;
524 /* We finished one use of the loops. */
525 ++data->__invocation_counter;
527 /* If this is the last step leave the loop, there is nothing
528 we can do. */
529 if (__glibc_unlikely (data->__flags & __GCONV_IS_LAST))
531 /* Store information about how many bytes are available. */
532 data->__outbuf = outbuf;
534 /* Remember how many non-identical characters we
535 converted in an irreversible way. */
536 *irreversible += lirreversible;
538 break;
541 /* Write out all output which was produced. */
542 if (__glibc_likely (outbuf > outstart))
544 const unsigned char *outerr = data->__outbuf;
545 int result;
547 result = DL_CALL_FCT (fct, (next_step, next_data, &outerr,
548 outbuf, NULL, irreversible, 0,
549 consume_incomplete));
551 if (result != __GCONV_EMPTY_INPUT)
553 if (__glibc_unlikely (outerr != outbuf))
555 #ifdef RESET_INPUT_BUFFER
556 /* RESET_INPUT_BUFFER can only work when there were
557 no new irreversible characters skipped during
558 this round. */
559 if (loop_irreversible
560 == lirreversible + (irreversible ? *irreversible : 0))
562 RESET_INPUT_BUFFER;
563 goto done_reset;
565 #endif
566 /* We have a problem in one of the functions below.
567 Undo the conversion upto the error point. */
568 size_t nstatus __attribute__ ((unused));
570 /* Reload the pointers. */
571 *inptrp = inptr;
572 outbuf = outstart;
574 /* Restore the state. */
575 #ifdef SAVE_RESET_STATE
576 SAVE_RESET_STATE (0);
577 #endif
579 if (FROM_DIRECTION)
580 /* Run the conversion loop. */
581 nstatus = FROM_LOOP (step, data, inptrp, inend,
582 &outbuf, outerr,
583 lirreversiblep
584 EXTRA_LOOP_ARGS);
585 else
586 /* Run the conversion loop. */
587 nstatus = TO_LOOP (step, data, inptrp, inend,
588 &outbuf, outerr,
589 lirreversiblep
590 EXTRA_LOOP_ARGS);
592 /* We must run out of output buffer space in this
593 rerun. */
594 assert (outbuf == outerr);
595 assert (nstatus == __GCONV_FULL_OUTPUT);
597 /* If we haven't consumed a single byte decrement
598 the invocation counter. */
599 if (__glibc_unlikely (outbuf == outstart))
600 --data->__invocation_counter;
603 #ifdef RESET_INPUT_BUFFER
604 done_reset:
605 #endif
606 /* Change the status. */
607 status = result;
609 else
610 /* All the output is consumed, we can make another run
611 if everything was ok. */
612 if (status == __GCONV_FULL_OUTPUT)
614 status = __GCONV_OK;
615 outbuf = data->__outbuf;
619 if (status != __GCONV_OK)
620 break;
622 /* Reset the output buffer pointer for the next round. */
623 outbuf = data->__outbuf;
626 #ifdef END_LOOP
627 END_LOOP
628 #endif
630 /* If we are supposed to consume all character store now all of the
631 remaining characters in the `state' object. */
632 #if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1
633 if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1)
634 || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
635 || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION))
636 && __builtin_expect (consume_incomplete, 0)
637 && status == __GCONV_INCOMPLETE_INPUT)
639 # ifdef STORE_REST
640 mbstate_t *state = data->__statep;
642 STORE_REST
643 # else
644 /* Make sure the remaining bytes fit into the state objects
645 buffer. */
646 size_t cnt_after = inend - *inptrp;
647 assert (cnt_after <= sizeof (data->__statep->__value.__wchb));
649 size_t cnt;
650 for (cnt = 0; cnt < cnt_after; ++cnt)
651 data->__statep->__value.__wchb[cnt] = (*inptrp)[cnt];
652 *inptrp = inend;
653 data->__statep->__count &= ~7;
654 data->__statep->__count |= cnt;
655 # endif
657 #endif
658 #undef unaligned
659 #undef POSSIBLY_UNALIGNED
662 return status;
665 #undef DEFINE_INIT
666 #undef CHARSET_NAME
667 #undef DEFINE_FINI
668 #undef MIN_NEEDED_FROM
669 #undef MIN_NEEDED_TO
670 #undef MAX_NEEDED_FROM
671 #undef MAX_NEEDED_TO
672 #undef FROM_LOOP_MIN_NEEDED_FROM
673 #undef FROM_LOOP_MAX_NEEDED_FROM
674 #undef FROM_LOOP_MIN_NEEDED_TO
675 #undef FROM_LOOP_MAX_NEEDED_TO
676 #undef TO_LOOP_MIN_NEEDED_FROM
677 #undef TO_LOOP_MAX_NEEDED_FROM
678 #undef TO_LOOP_MIN_NEEDED_TO
679 #undef TO_LOOP_MAX_NEEDED_TO
680 #undef FROM_DIRECTION
681 #undef EMIT_SHIFT_TO_INIT
682 #undef FROM_LOOP
683 #undef TO_LOOP
684 #undef ONE_DIRECTION
685 #undef SAVE_RESET_STATE
686 #undef RESET_INPUT_BUFFER
687 #undef FUNCTION_NAME
688 #undef PREPARE_LOOP
689 #undef END_LOOP
690 #undef EXTRA_LOOP_ARGS
691 #undef STORE_REST
692 #undef FROM_ONEBYTE