]> git.ipfire.org Git - thirdparty/glibc.git/blame - iconv/skeleton.c
Update.
[thirdparty/glibc.git] / iconv / skeleton.c
CommitLineData
09376451 1/* Skeleton for a conversion module.
63e04088 2 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
8619129f
UD
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
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.
10
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.
15
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. */
20
21/* This file can be included to provide definitions of several things
22 many modules have in common. It can be customized using the following
23 macros:
24
25 DEFINE_INIT define the default initializer. This requires the
26 following symbol to be defined.
27
28 CHARSET_NAME string with official name of the coded character
29 set (in all-caps)
30
31 DEFINE_FINI define the default destructor function.
32
33 MIN_NEEDED_FROM minimal number of bytes needed for the from-charset.
34 MIN_NEEDED_TO likewise for the to-charset.
35
36 MAX_NEEDED_FROM maximal number of bytes needed for the from-charset.
37 This macro is optional, it defaults to MIN_NEEDED_FROM.
38 MAX_NEEDED_TO likewise for the to-charset.
39
40 DEFINE_DIRECTION_OBJECTS
41 two objects will be defined to be used when the
42 `gconv' function must only distinguish two
43 directions. This is implied by DEFINE_INIT.
44 If this macro is not defined the following
45 macro must be available.
46
47 FROM_DIRECTION this macro is supposed to return a value != 0
48 if we convert from the current character set,
49 otherwise it return 0.
50
51 EMIT_SHIFT_TO_INIT this symbol is optional. If it is defined it
52 defines some code which writes out a sequence
53 of characters which bring the current state into
54 the initial state.
55
56 FROM_LOOP name of the function implementing the conversion
57 from the current characters.
58 TO_LOOP likewise for the other direction
59
60 RESET_STATE in case of an error we must reset the state for
61 the rerun so this macro must be defined for
62 stateful encodings. It takes an argument which
63 is nonzero when saving.
64
65 RESET_INPUT_BUFFER If the input character sets allow this the macro
66 can be defined to reset the input buffer pointers
67 to cover only those characters up to the error.
68
69 FUNCTION_NAME if not set the conversion function is named `gconv'.
28f1c862
UD
70
71 PREPARE_LOOP optional code preparing the conversion loop. Can
72 contain variable definitions.
918b9d72 73 END_LOOP also optional, may be used to store information
28f1c862
UD
74
75 EXTRA_LOOP_ARGS optional macro specifying extra arguments passed
76 to loop function.
8619129f
UD
77 */
78
79#include <assert.h>
80#include <gconv.h>
81#include <string.h>
82#define __need_size_t
83#define __need_NULL
84#include <stddef.h>
c66dbe00
UD
85
86#ifndef STATIC_GCONV
87# include <dlfcn.h>
c66dbe00 88#endif
8619129f 89
a808d541
UD
90#ifndef DL_CALL_FCT
91# define DL_CALL_FCT(fct, args) fct args
92#endif
93
8619129f
UD
94/* The direction objects. */
95#if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT
96static int from_object;
97static int to_object;
98
99# ifndef FROM_DIRECTION
d64b6ad0 100# define FROM_DIRECTION (step->__data == &from_object)
8619129f
UD
101# endif
102#else
103# ifndef FROM_DIRECTION
104# error "FROM_DIRECTION must be provided if direction objects are not used"
105# endif
106#endif
107
108
109/* How many bytes are needed at most for the from-charset. */
110#ifndef MAX_NEEDED_FROM
111# define MAX_NEEDED_FROM MIN_NEEDED_FROM
112#endif
113
114/* Same for the to-charset. */
115#ifndef MAX_NEEDED_TO
116# define MAX_NEEDED_TO MIN_NEEDED_TO
117#endif
118
119
77e1d15a
UD
120/* Define macros which can access unaligned buffers. These macros are
121 supposed to be used only in code outside the inner loops. For the inner
122 loops we have other definitions which allow optimized access. */
123#ifdef _STRING_ARCH_unaligned
124/* We can handle unaligned memory access. */
c1db8b0d
UD
125# define get16u(addr) *((uint16_t *) (addr))
126# define get32u(addr) *((uint32_t *) (addr))
77e1d15a
UD
127
128/* We need no special support for writing values either. */
c1db8b0d
UD
129# define put16u(addr, val) *((uint16_t *) (addr)) = (val)
130# define put32u(addr, val) *((uint32_t *) (addr)) = (val)
77e1d15a
UD
131#else
132/* Distinguish between big endian and little endian. */
133# if __BYTE_ORDER == __LITTLE_ENDIAN
c1db8b0d 134# define get16u(addr) \
77e1d15a
UD
135 (((__const unsigned char *) (addr))[1] << 8 \
136 | ((__const unsigned char *) (addr))[0])
c1db8b0d 137# define get32u(addr) \
77e1d15a
UD
138 (((((__const unsigned char *) (addr))[3] << 8 \
139 | ((__const unsigned char *) (addr))[2]) << 8 \
140 | ((__const unsigned char *) (addr))[1]) << 8 \
141 | ((__const unsigned char *) (addr))[0])
142
c1db8b0d 143# define put16u(addr, val) \
77e1d15a 144 ({ uint16_t __val = (val); \
cb2c5501
UD
145 ((unsigned char *) (addr))[0] = __val; \
146 ((unsigned char *) (addr))[1] = __val >> 8; \
77e1d15a 147 (void) 0; })
c1db8b0d 148# define put32u(addr, val) \
cb2c5501
UD
149 ({ uint32_t __val = (val); \
150 ((unsigned char *) (addr))[0] = __val; \
77e1d15a 151 __val >>= 8; \
cb2c5501 152 ((unsigned char *) (addr))[1] = __val; \
77e1d15a 153 __val >>= 8; \
cb2c5501 154 ((unsigned char *) (addr))[2] = __val; \
77e1d15a 155 __val >>= 8; \
cb2c5501 156 ((unsigned char *) (addr))[3] = __val; \
77e1d15a
UD
157 (void) 0; })
158# else
c1db8b0d 159# define get16u(addr) \
77e1d15a
UD
160 (((__const unsigned char *) (addr))[0] << 8 \
161 | ((__const unsigned char *) (addr))[1])
c1db8b0d 162# define get32u(addr) \
77e1d15a
UD
163 (((((__const unsigned char *) (addr))[0] << 8 \
164 | ((__const unsigned char *) (addr))[1]) << 8 \
165 | ((__const unsigned char *) (addr))[2]) << 8 \
166 | ((__const unsigned char *) (addr))[3])
167
c1db8b0d 168# define put16u(addr, val) \
77e1d15a 169 ({ uint16_t __val = (val); \
cb2c5501 170 ((unsigned char *) (addr))[1] = __val; \
a1303dc8 171 ((unsigned char *) (addr))[0] = __val >> 8; \
77e1d15a 172 (void) 0; })
c1db8b0d 173# define put32u(addr, val) \
cb2c5501
UD
174 ({ uint32_t __val = (val); \
175 ((unsigned char *) (addr))[3] = __val; \
77e1d15a 176 __val >>= 8; \
cb2c5501 177 ((unsigned char *) (addr))[2] = __val; \
77e1d15a 178 __val >>= 8; \
cb2c5501 179 ((unsigned char *) (addr))[1] = __val; \
77e1d15a 180 __val >>= 8; \
cb2c5501 181 ((unsigned char *) (addr))[0] = __val; \
77e1d15a
UD
182 (void) 0; })
183# endif
184#endif
185
186
8619129f
UD
187/* For conversions from a fixed width character sets to another fixed width
188 character set we we can define RESET_INPUT_BUFFER is necessary. */
189#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
190# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO
390955cb 191/* We have to use these `if's here since the compiler cannot know that
8619129f
UD
192 (outbuf - outerr) is always divisible by MIN_NEEDED_TO. */
193# define RESET_INPUT_BUFFER \
194 if (MIN_NEEDED_FROM % MIN_NEEDED_TO == 0) \
fd1b5c0f 195 *inptrp -= (outbuf - outerr) * (MIN_NEEDED_FROM / MIN_NEEDED_TO); \
8619129f 196 else if (MIN_NEEDED_TO % MIN_NEEDED_FROM == 0) \
fd1b5c0f 197 *inptrp -= (outbuf - outerr) / (MIN_NEEDED_TO / MIN_NEEDED_FROM); \
8619129f 198 else \
fd1b5c0f 199 *inptrp -= ((outbuf - outerr) / MIN_NEEDED_TO) * MIN_NEEDED_FROM
8619129f
UD
200# endif
201#endif
202
203
204/* The default init function. It simply matches the name and initializes
205 the step data to point to one of the objects above. */
206#if DEFINE_INIT
207# ifndef CHARSET_NAME
208# error "CHARSET_NAME not defined"
209# endif
210
211int
d64b6ad0 212gconv_init (struct __gconv_step *step)
8619129f
UD
213{
214 /* Determine which direction. */
d64b6ad0 215 if (strcmp (step->__from_name, CHARSET_NAME) == 0)
918b9d72 216 {
d64b6ad0 217 step->__data = &from_object;
390955cb 218
d64b6ad0
UD
219 step->__min_needed_from = MIN_NEEDED_FROM;
220 step->__max_needed_from = MAX_NEEDED_FROM;
221 step->__min_needed_to = MIN_NEEDED_TO;
222 step->__max_needed_to = MAX_NEEDED_TO;
918b9d72 223 }
365afefc 224 else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
918b9d72 225 {
d64b6ad0 226 step->__data = &to_object;
390955cb 227
d64b6ad0
UD
228 step->__min_needed_from = MIN_NEEDED_TO;
229 step->__max_needed_from = MAX_NEEDED_TO;
230 step->__min_needed_to = MIN_NEEDED_FROM;
231 step->__max_needed_to = MAX_NEEDED_FROM;
918b9d72 232 }
390955cb 233 else
d64b6ad0 234 return __GCONV_NOCONV;
8619129f 235
9ce5071a 236#ifdef RESET_STATE
d64b6ad0 237 step->__stateful = 1;
9ce5071a 238#else
d64b6ad0 239 step->__stateful = 0;
9ce5071a
UD
240#endif
241
d64b6ad0 242 return __GCONV_OK;
8619129f
UD
243}
244#endif
245
246
247/* The default destructor function does nothing in the moment and so
248 be define it at all. But we still provide the macro just in case
249 we need it some day. */
250#if DEFINE_FINI
251#endif
252
253
28f1c862
UD
254/* If no arguments have to passed to the loop function define the macro
255 as empty. */
256#ifndef EXTRA_LOOP_ARGS
257# define EXTRA_LOOP_ARGS
258#endif
259
260
8619129f
UD
261/* This is the actual conversion function. */
262#ifndef FUNCTION_NAME
263# define FUNCTION_NAME gconv
264#endif
265
fd1b5c0f
UD
266/* The macros are used to access the function to convert single characters. */
267#define SINGLE(fct) SINGLE2 (fct)
268#define SINGLE2(fct) fct##_single
269
270
8619129f 271int
d64b6ad0 272FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
fd1b5c0f 273 const unsigned char **inptrp, const unsigned char *inend,
f1d5c60d 274 unsigned char **outbufstart, size_t *irreversible, int do_flush,
55985355 275 int consume_incomplete)
8619129f 276{
d64b6ad0
UD
277 struct __gconv_step *next_step = step + 1;
278 struct __gconv_step_data *next_data = data + 1;
85830c4c 279 __gconv_fct fct;
8619129f
UD
280 int status;
281
85830c4c
UD
282 fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct;
283
8619129f
UD
284 /* If the function is called with no input this means we have to reset
285 to the initial state. The possibly partly converted input is
286 dropped. */
978ce92b 287 if (__builtin_expect (do_flush, 0))
8619129f 288 {
d64b6ad0 289 status = __GCONV_OK;
8619129f 290
f1d5c60d
UD
291 /* This should never happen during error handling. */
292 assert (outbufstart == NULL);
293
390955cb
UD
294#ifdef EMIT_SHIFT_TO_INIT
295 /* Emit the escape sequence to reset the state. */
296 EMIT_SHIFT_TO_INIT;
777e222d
UD
297#else
298 /* Clear the state object. There might be bytes in there from
299 previous calls with CONSUME_INCOMPLETE == 1. */
300 memset (data->__statep, '\0', sizeof (*data->__statep));
8619129f 301#endif
390955cb 302 /* Call the steps down the chain if there are any but only if we
777e222d
UD
303 successfully emitted the escape sequence. This should only
304 fail if the output buffer is full. If the input is invalid
305 it should be discarded since the user wants to start from a
306 clean slate. */
85830c4c 307 if (status == __GCONV_OK && ! (data->__flags & __GCONV_IS_LAST))
390955cb 308 status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL,
f1d5c60d 309 NULL, irreversible, 1,
55985355 310 consume_incomplete));
8619129f
UD
311 }
312 else
313 {
8619129f 314 /* We preserve the initial values of the pointer variables. */
fd1b5c0f 315 const unsigned char *inptr = *inptrp;
f1d5c60d
UD
316 unsigned char *outbuf = (__builtin_expect (outbufstart == NULL, 1)
317 ? data->__outbuf : *outbufstart);
d64b6ad0 318 unsigned char *outend = data->__outbufend;
b117f744 319 unsigned char *outstart;
3aaad0b6
UD
320 /* This variable is used to count the number of characters we
321 actually converted. */
38677ace 322 size_t lirreversible = 0;
b572c2da 323 size_t *lirreversiblep = irreversible ? &lirreversible : NULL;
fdf64555
UD
324#if defined _STRING_ARCH_unaligned \
325 || MIN_NEEDED_FROM == 1 || MAX_NEEDED_FROM % MIN_NEEDED_FROM != 0 \
326 || MIN_NEEDED_TO == 1 || MAX_NEEDED_TO % MIN_NEEDED_TO != 0
77e1d15a
UD
327# define unaligned 0
328#else
3aaad0b6 329 int unaligned;
77e1d15a
UD
330# define GEN_unaligned(name) GEN_unaligned2 (name)
331# define GEN_unaligned2(name) name##_unaligned
332#endif
8619129f 333
28f1c862
UD
334#ifdef PREPARE_LOOP
335 PREPARE_LOOP
336#endif
337
fd1b5c0f
UD
338#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1
339 /* If the function is used to implement the mb*towc*() or wc*tomb*()
340 functions we must test whether any bytes from the last call are
341 stored in the `state' object. */
342 if (((MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
343 || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
344 && consume_incomplete && (data->__statep->__count & 7) != 0)
345 {
f1d5c60d
UD
346 /* Yep, we have some bytes left over. Process them now.
347 But this must not happen while we are called from an
348 error handler. */
349 assert (outbufstart == NULL);
fd1b5c0f
UD
350
351# if MAX_NEEDED_FROM > 1
352 if (MAX_NEEDED_TO == 1 || FROM_DIRECTION)
55985355 353 status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf,
b572c2da 354 outend, lirreversiblep
85830c4c 355 EXTRA_LOOP_ARGS);
fd1b5c0f
UD
356# endif
357# if MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1 && !ONE_DIRECTION
358 else
359# endif
360# if MAX_NEEDED_TO > 1 && !ONE_DIRECTION
55985355 361 status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf,
b572c2da 362 outend, lirreversiblep EXTRA_LOOP_ARGS);
fd1b5c0f
UD
363# endif
364
365afefc 365 if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
fd1b5c0f
UD
366 return status;
367 }
368#endif
369
3aaad0b6
UD
370#if !defined _STRING_ARCH_unaligned \
371 && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \
372 && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
373 /* The following assumes that encodings, which have a variable length
374 what might unalign a buffer even though it is a aligned in the
375 beginning, either don't have the minimal number of bytes as a divisor
376 of the maximum length or have a minimum length of 1. This is true
377 for all known and supported encodings. */
378 unaligned = ((FROM_DIRECTION
379 && ((uintptr_t) inptr % MIN_NEEDED_FROM != 0
85830c4c 380 || ((data->__flags & __GCONV_IS_LAST)
3aaad0b6
UD
381 && (uintptr_t) outbuf % MIN_NEEDED_TO != 0)))
382 || (!FROM_DIRECTION
85830c4c 383 && (((data->__flags & __GCONV_IS_LAST)
3aaad0b6
UD
384 && (uintptr_t) outbuf % MIN_NEEDED_FROM != 0)
385 || (uintptr_t) inptr % MIN_NEEDED_TO != 0)));
386#endif
387
8619129f
UD
388 do
389 {
d6204268
UD
390 struct __gconv_trans_data *trans;
391
8619129f 392 /* Remember the start value for this round. */
fd1b5c0f 393 inptr = *inptrp;
8619129f 394 /* The outbuf buffer is empty. */
b117f744 395 outstart = outbuf;
8619129f 396
8619129f
UD
397#ifdef SAVE_RESET_STATE
398 SAVE_RESET_STATE (1);
399#endif
400
365afefc 401 if (__builtin_expect (!unaligned, 1))
77e1d15a
UD
402 {
403 if (FROM_DIRECTION)
404 /* Run the conversion loop. */
55985355 405 status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
b572c2da 406 lirreversiblep EXTRA_LOOP_ARGS);
77e1d15a
UD
407 else
408 /* Run the conversion loop. */
55985355 409 status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
b572c2da 410 lirreversiblep EXTRA_LOOP_ARGS);
77e1d15a 411 }
c1db8b0d
UD
412#if !defined _STRING_ARCH_unaligned \
413 && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \
414 && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
8619129f 415 else
77e1d15a
UD
416 {
417 if (FROM_DIRECTION)
418 /* Run the conversion loop. */
55985355
UD
419 status = GEN_unaligned (FROM_LOOP) (step, data, inptrp, inend,
420 &outbuf, outend,
b572c2da 421 lirreversiblep
77e1d15a
UD
422 EXTRA_LOOP_ARGS);
423 else
424 /* Run the conversion loop. */
55985355
UD
425 status = GEN_unaligned (TO_LOOP) (step, data, inptrp, inend,
426 &outbuf, outend,
b572c2da 427 lirreversiblep
77e1d15a
UD
428 EXTRA_LOOP_ARGS);
429 }
430#endif
8619129f 431
f1d5c60d
UD
432 /* If we were called as part of an error handling module we
433 don't do anything else here. */
434 if (__builtin_expect (outbufstart != NULL, 0))
435 {
436 *outbufstart = outbuf;
437 return status;
438 }
439
4d37e19c
UD
440 /* Give the transliteration module the chance to store the
441 original text and the result in case it needs a context. */
d6204268
UD
442 for (trans = data->__trans; trans != NULL; trans = trans->__next)
443 if (trans->__trans_context_fct != NULL)
444 DL_CALL_FCT (trans->__trans_context_fct,
445 (trans->__data, inptr, *inptrp, outstart, outbuf));
4d37e19c 446
0aece08d
UD
447 /* We finished one use of the loops. */
448 ++data->__invocation_counter;
449
390955cb 450 /* If this is the last step leave the loop, there is nothing
8619129f 451 we can do. */
365afefc 452 if (__builtin_expect (data->__flags & __GCONV_IS_LAST, 0))
8619129f
UD
453 {
454 /* Store information about how many bytes are available. */
d64b6ad0 455 data->__outbuf = outbuf;
bf979eef 456
38677ace
UD
457 /* Remember how many non-identical characters we
458 converted in a irreversible way. */
459 *irreversible += lirreversible;
bf979eef 460
8619129f
UD
461 break;
462 }
463
464 /* Write out all output which was produced. */
365afefc 465 if (__builtin_expect (outbuf > outstart, 1))
8619129f 466 {
d64b6ad0 467 const unsigned char *outerr = data->__outbuf;
8619129f
UD
468 int result;
469
4bae5567 470 result = DL_CALL_FCT (fct, (next_step, next_data, &outerr,
f1d5c60d 471 outbuf, NULL, irreversible, 0,
fd1b5c0f 472 consume_incomplete));
8619129f 473
d64b6ad0 474 if (result != __GCONV_EMPTY_INPUT)
8619129f 475 {
978ce92b 476 if (__builtin_expect (outerr != outbuf, 0))
8619129f
UD
477 {
478#ifdef RESET_INPUT_BUFFER
479 RESET_INPUT_BUFFER;
480#else
481 /* We have a problem with the in on of the functions
482 below. Undo the conversion upto the error point. */
483 size_t nstatus;
484
485 /* Reload the pointers. */
fd1b5c0f 486 *inptrp = inptr;
b117f744 487 outbuf = outstart;
8619129f
UD
488
489 /* Reset the state. */
490# ifdef SAVE_RESET_STATE
491 SAVE_RESET_STATE (0);
492# endif
493
85830c4c 494 /* XXX Handle unaligned access here as well. */
8619129f
UD
495 if (FROM_DIRECTION)
496 /* Run the conversion loop. */
55985355
UD
497 nstatus = FROM_LOOP (step, data,
498 (const unsigned char **) inptrp,
fd1b5c0f 499 (const unsigned char *) inend,
8619129f
UD
500 (unsigned char **) &outbuf,
501 (unsigned char *) outerr,
b572c2da 502 lirreversiblep EXTRA_LOOP_ARGS);
8619129f
UD
503 else
504 /* Run the conversion loop. */
55985355
UD
505 nstatus = TO_LOOP (step, data,
506 (const unsigned char **) inptrp,
fd1b5c0f 507 (const unsigned char *) inend,
8619129f
UD
508 (unsigned char **) &outbuf,
509 (unsigned char *) outerr,
b572c2da 510 lirreversiblep EXTRA_LOOP_ARGS);
8619129f
UD
511
512 /* We must run out of output buffer space in this
513 rerun. */
5aa8ff62 514 assert (outbuf == outerr);
d64b6ad0 515 assert (nstatus == __GCONV_FULL_OUTPUT);
0aece08d
UD
516
517 /* If we haven't consumed a single byte decrement
518 the invocation counter. */
365afefc 519 if (__builtin_expect (outbuf == outstart, 0))
0aece08d 520 --data->__invocation_counter;
8619129f
UD
521#endif /* reset input buffer */
522 }
523
524 /* Change the status. */
525 status = result;
526 }
527 else
528 /* All the output is consumed, we can make another run
529 if everything was ok. */
d64b6ad0
UD
530 if (status == __GCONV_FULL_OUTPUT)
531 status = __GCONV_OK;
8619129f
UD
532 }
533 }
d64b6ad0 534 while (status == __GCONV_OK);
8619129f 535
918b9d72
UD
536#ifdef END_LOOP
537 END_LOOP
538#endif
fd1b5c0f
UD
539
540 /* If we are supposed to consume all character store now all of the
541 remaining characters in the `state' object. */
542#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1
543 if (((MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
544 || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
365afefc
UD
545 && __builtin_expect (consume_incomplete, 0)
546 && status == __GCONV_INCOMPLETE_INPUT)
fd1b5c0f
UD
547 {
548# ifdef STORE_REST
549 mbstate_t *state = data->__statep;
550
551 STORE_REST
552# else
553 size_t cnt;
554
555 /* Make sure the remaining bytes fit into the state objects
556 buffer. */
557 assert (inend - *inptrp < 4);
558
559 for (cnt = 0; *inptrp < inend; ++cnt)
560 data->__statep->__value.__wchb[cnt] = *(*inptrp)++;
561 data->__statep->__count &= ~7;
562 data->__statep->__count |= cnt;
563# endif
564 }
565#endif
8619129f
UD
566 }
567
568 return status;
569}
570
571#undef DEFINE_INIT
572#undef CHARSET_NAME
573#undef DEFINE_FINI
574#undef MIN_NEEDED_FROM
575#undef MIN_NEEDED_TO
576#undef MAX_NEEDED_FROM
577#undef MAX_NEEDED_TO
578#undef DEFINE_DIRECTION_OBJECTS
579#undef FROM_DIRECTION
580#undef EMIT_SHIFT_TO_INIT
581#undef FROM_LOOP
582#undef TO_LOOP
583#undef RESET_STATE
584#undef RESET_INPUT_BUFFER
585#undef FUNCTION_NAME
918b9d72
UD
586#undef PREPARE_LOOP
587#undef END_LOOP
fd1b5c0f
UD
588#undef ONE_DIRECTION
589#undef STORE_REST