1/* Skeleton for a conversion module.
2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
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:
22
23 DEFINE_INIT define the default initializer. This requires the
24 following symbol to be defined.
25
26 CHARSET_NAME string with official name of the coded character
27 set (in all-caps)
28
29 DEFINE_FINI define the default destructor function.
30
31 MIN_NEEDED_FROM minimal number of bytes needed for the from-charset.
32 MIN_NEEDED_TO likewise for the to-charset.
33
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.
37
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.
58
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.
62
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.
67
68 FROM_LOOP name of the function implementing the conversion
69 from the current character set.
70 TO_LOOP likewise for the other direction
71
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.
76
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.
81
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.
90
91 FUNCTION_NAME if not set the conversion function is named `gconv'.
92
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
96
97 EXTRA_LOOP_ARGS optional macro specifying extra arguments passed
98 to loop function.
99
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.
103
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.
119
120 Modules can use mbstate_t to store conversion state as follows:
121
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.
125
126 * Bits 31..3 of '__count' are module dependent shift state.
127
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.
133
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.
137 */
138
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>
145
146#ifndef STATIC_GCONV
147# include <dlfcn.h>
148#endif
149
150#include <pointer_guard.h>
151#include <stdint.h>
152
153#ifndef DL_CALL_FCT
154# define DL_CALL_FCT(fct, args) fct args
155#endif
156
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
169
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
174
175/* Same for the to-charset. */
176#ifndef MAX_NEEDED_TO
177# define MAX_NEEDED_TO MIN_NEEDED_TO
178#endif
179
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
205
206
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) \
220 { \
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; \
231 } \
232 else \
233 { \
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; \
243 }
244# endif
245#endif
246
247
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
254
255extern int gconv_init (struct __gconv_step *step);
256int
257gconv_init (struct __gconv_step *step)
258{
259 /* Determine which direction. */
260 if (strcmp (step->__from_name, CHARSET_NAME) == 0)
261 {
262 step->__data = FROM_DIRECTION_VAL;
263
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;
268
269#ifdef FROM_ONEBYTE
270 step->__btowc_fct = FROM_ONEBYTE;
271#endif
272 }
273 else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
274 {
275 step->__data = TO_DIRECTION_VAL;
276
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;
281 }
282 else
283 return __GCONV_NOCONV;
284
285#ifdef SAVE_RESET_STATE
286 step->__stateful = 1;
287#else
288 step->__stateful = 0;
289#endif
290
291 return __GCONV_OK;
292}
293#endif
294
295
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
301
302
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
308
309
310/* This is the actual conversion function. */
311#ifndef FUNCTION_NAME
312# define FUNCTION_NAME gconv
313#endif
314
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
318
319
320extern 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);
326int
327FUNCTION_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)
331{
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;
336
337 if ((data->__flags & __GCONV_IS_LAST) == 0)
338 {
339 fct = next_step->__fct;
340 if (next_step->__shlib_handle != NULL)
341 PTR_DEMANGLE (fct);
342 }
343
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))
348 {
349 /* This should never happen during error handling. */
350 assert (outbufstart == NULL);
351
352 status = __GCONV_OK;
353
354#ifdef EMIT_SHIFT_TO_INIT
355 if (do_flush == 1)
356 {
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;
361
362# ifdef PREPARE_LOOP
363 PREPARE_LOOP
364# endif
365
366# ifdef SAVE_RESET_STATE
367 SAVE_RESET_STATE (1);
368# endif
369
370 /* Emit the escape sequence to reset the state. */
371 EMIT_SHIFT_TO_INIT;
372
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)
379 {
380 if (data->__flags & __GCONV_IS_LAST)
381 /* Store information about how many bytes are available. */
382 data->__outbuf = outbuf;
383 else
384 {
385 /* Write out all output which was produced. */
386 if (outbuf > outstart)
387 {
388 const unsigned char *outerr = outstart;
389 int result;
390
391 result = DL_CALL_FCT (fct, (next_step, next_data,
392 &outerr, outbuf, NULL,
393 irreversible, 0,
394 consume_incomplete));
395
396 if (result != __GCONV_EMPTY_INPUT)
397 {
398 if (__glibc_unlikely (outerr != outbuf))
399 {
400 /* We have a problem. Undo the conversion. */
401 outbuf = outstart;
402
403 /* Restore the state. */
404# ifdef SAVE_RESET_STATE
405 SAVE_RESET_STATE (0);
406# endif
407 }
408
409 /* Change the status. */
410 status = result;
411 }
412 }
413
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));
419 }
420 }
421 }
422 else
423#endif
424 {
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));
429
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));
435 }
436 }
437 else
438 {
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;
450
451#ifdef PREPARE_LOOP
452 PREPARE_LOOP
453#endif
454
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)
463 {
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);
468
469# if FROM_LOOP_MAX_NEEDED_FROM > 1
470 if (TO_LOOP_MAX_NEEDED_FROM == 1 || FROM_DIRECTION)
471 status = SINGLE(FROM_LOOP) (step, step_data: data, inptrp, inend, outptrp: &outbuf,
472 outend, irreversible: 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, step_data: data, inptrp, inend, outptrp: &outbuf,
481 outend, irreversible: lirreversiblep EXTRA_LOOP_ARGS);
482# endif
483# endif
484
485 if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
486 return status;
487 }
488#endif
489
490 while (1)
491 {
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
502
503#ifdef SAVE_RESET_STATE
504 SAVE_RESET_STATE (1);
505#endif
506
507 if (FROM_DIRECTION)
508 /* Run the conversion loop. */
509 status = FROM_LOOP (step, step_data: data, inptrp, inend, outptrp: &outbuf, outend,
510 irreversible: lirreversiblep EXTRA_LOOP_ARGS);
511 else
512 /* Run the conversion loop. */
513 status = TO_LOOP (step, step_data: data, inptrp, inend, outptrp: &outbuf, outend,
514 irreversible: lirreversiblep EXTRA_LOOP_ARGS);
515
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))
519 {
520 *outbufstart = outbuf;
521 return status;
522 }
523
524 /* We finished one use of the loops. */
525 ++data->__invocation_counter;
526
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))
530 {
531 /* Store information about how many bytes are available. */
532 data->__outbuf = outbuf;
533
534 /* Remember how many non-identical characters we
535 converted in an irreversible way. */
536 *irreversible += lirreversible;
537
538 break;
539 }
540
541 /* Write out all output which was produced. */
542 if (__glibc_likely (outbuf > outstart))
543 {
544 const unsigned char *outerr = data->__outbuf;
545 int result;
546
547 result = DL_CALL_FCT (fct, (next_step, next_data, &outerr,
548 outbuf, NULL, irreversible, 0,
549 consume_incomplete));
550
551 if (result != __GCONV_EMPTY_INPUT)
552 {
553 if (__glibc_unlikely (outerr != outbuf))
554 {
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))
561 {
562 RESET_INPUT_BUFFER;
563 goto done_reset;
564 }
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));
569
570 /* Reload the pointers. */
571 *inptrp = inptr;
572 outbuf = outstart;
573
574 /* Restore the state. */
575#ifdef SAVE_RESET_STATE
576 SAVE_RESET_STATE (0);
577#endif
578
579 if (FROM_DIRECTION)
580 /* Run the conversion loop. */
581 nstatus = FROM_LOOP (step, step_data: data, inptrp, inend,
582 outptrp: &outbuf, outend: outerr,
583 irreversible: lirreversiblep
584 EXTRA_LOOP_ARGS);
585 else
586 /* Run the conversion loop. */
587 nstatus = TO_LOOP (step, step_data: data, inptrp, inend,
588 outptrp: &outbuf, outend: outerr,
589 irreversible: lirreversiblep
590 EXTRA_LOOP_ARGS);
591
592 /* We must run out of output buffer space in this
593 rerun. */
594 assert (outbuf == outerr);
595 assert (nstatus == __GCONV_FULL_OUTPUT);
596
597 /* If we haven't consumed a single byte decrement
598 the invocation counter. */
599 if (__glibc_unlikely (outbuf == outstart))
600 --data->__invocation_counter;
601 }
602
603#ifdef RESET_INPUT_BUFFER
604 done_reset:
605#endif
606 /* Change the status. */
607 status = result;
608 }
609 else
610 /* All the output is consumed, we can make another run
611 if everything was ok. */
612 if (status == __GCONV_FULL_OUTPUT)
613 {
614 status = __GCONV_OK;
615 outbuf = data->__outbuf;
616 }
617 }
618
619 if (status != __GCONV_OK)
620 break;
621
622 /* Reset the output buffer pointer for the next round. */
623 outbuf = data->__outbuf;
624 }
625
626#ifdef END_LOOP
627 END_LOOP
628#endif
629
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)
638 {
639# ifdef STORE_REST
640 mbstate_t *state = data->__statep;
641
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));
648
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
656 }
657#endif
658#undef unaligned
659#undef POSSIBLY_UNALIGNED
660 }
661
662 return status;
663}
664
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
693

source code of glibc/iconv/skeleton.c