Generic gethostid.c.
[kopensolaris-gnu/glibc.git] / iconv / skeleton.c
1 /* Skeleton for a conversion module.
2    Copyright (C) 1998-2002, 2005 Free Software Foundation, Inc.
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 Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the 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    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    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      FROM_LOOP_MIN_NEEDED_FROM
41      FROM_LOOP_MAX_NEEDED_FROM
42                         minimal/maximal number of bytes needed on input
43                         of one round through the FROM_LOOP.  Defaults
44                         to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively.
45      FROM_LOOP_MIN_NEEDED_TO
46      FROM_LOOP_MAX_NEEDED_TO
47                         minimal/maximal number of bytes needed on output
48                         of one round through the FROM_LOOP.  Defaults
49                         to MIN_NEEDED_TO and MAX_NEEDED_TO, respectively.
50      TO_LOOP_MIN_NEEDED_FROM
51      TO_LOOP_MAX_NEEDED_FROM
52                         minimal/maximal number of bytes needed on input
53                         of one round through the TO_LOOP.  Defaults
54                         to MIN_NEEDED_TO and MAX_NEEDED_TO, respectively.
55      TO_LOOP_MIN_NEEDED_TO
56      TO_LOOP_MAX_NEEDED_TO
57                         minimal/maximal number of bytes needed on output
58                         of one round through the TO_LOOP.  Defaults
59                         to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively.
60
61      FROM_DIRECTION     this macro is supposed to return a value != 0
62                         if we convert from the current character set,
63                         otherwise it return 0.
64
65      EMIT_SHIFT_TO_INIT this symbol is optional.  If it is defined it
66                         defines some code which writes out a sequence
67                         of bytes which bring the current state into
68                         the initial state.
69
70      FROM_LOOP          name of the function implementing the conversion
71                         from the current character set.
72      TO_LOOP            likewise for the other direction
73
74      ONE_DIRECTION      optional.  If defined to 1, only one conversion
75                         direction is defined instead of two.  In this
76                         case, FROM_DIRECTION should be defined to 1, and
77                         FROM_LOOP and TO_LOOP should have the same value.
78
79      SAVE_RESET_STATE   in case of an error we must reset the state for
80                         the rerun so this macro must be defined for
81                         stateful encodings.  It takes an argument which
82                         is nonzero when saving.
83
84      RESET_INPUT_BUFFER If the input character sets allow this the macro
85                         can be defined to reset the input buffer pointers
86                         to cover only those characters up to the error.
87
88      FUNCTION_NAME      if not set the conversion function is named `gconv'.
89
90      PREPARE_LOOP       optional code preparing the conversion loop.  Can
91                         contain variable definitions.
92      END_LOOP           also optional, may be used to store information
93
94      EXTRA_LOOP_ARGS    optional macro specifying extra arguments passed
95                         to loop function.
96
97      STORE_REST         optional, needed only when MAX_NEEDED_FROM > 4.
98                         This macro stores the seen but unconverted input bytes
99                         in the state.
100
101      FROM_ONEBYTE       optional.  If defined, should be the name of a
102                         specialized conversion function for a single byte
103                         from the current character set to INTERNAL.  This
104                         function has prototype
105                            wint_t
106                            FROM_ONEBYTE (struct __gconv_step *, unsigned char);
107                         and does a special conversion:
108                         - The input is a single byte.
109                         - The output is a single uint32_t.
110                         - The state before the conversion is the initial state;
111                           the state after the conversion is irrelevant.
112                         - No transliteration.
113                         - __invocation_counter = 0.
114                         - __internal_use = 1.
115                         - do_flush = 0.
116
117    Modules can use mbstate_t to store conversion state as follows:
118
119    * Bits 2..0 of '__count' contain the number of lookahead input bytes
120      stored in __value.__wchb.  Always zero if the converter never
121      returns __GCONV_INCOMPLETE_INPUT.
122
123    * Bits 31..3 of '__count' are module dependent shift state.
124
125    * __value: When STORE_REST/UNPACK_BYTES aren't defined and when the
126      converter has returned __GCONV_INCOMPLETE_INPUT, this contains
127      at most 4 lookahead bytes. Converters with an mb_cur_max > 4
128      (currently only UTF-8) must find a way to store their state
129      in __value.__wch and define STORE_REST/UNPACK_BYTES appropriately.
130
131    When __value contains lookahead, __count must not be zero, because
132    the converter is not in the initial state then, and mbsinit() --
133    defined as a (__count == 0) test -- must reflect this.
134  */
135
136 #include <assert.h>
137 #include <gconv.h>
138 #include <string.h>
139 #define __need_size_t
140 #define __need_NULL
141 #include <stddef.h>
142
143 #ifndef STATIC_GCONV
144 # include <dlfcn.h>
145 #endif
146
147 #ifndef DL_CALL_FCT
148 # define DL_CALL_FCT(fct, args) fct args
149 #endif
150
151 /* The direction objects.  */
152 #if DEFINE_INIT
153 # ifndef FROM_DIRECTION
154 #  define FROM_DIRECTION_VAL NULL
155 #  define TO_DIRECTION_VAL ((void *) ~((uintptr_t) 0))
156 #  define FROM_DIRECTION (step->__data == FROM_DIRECTION_VAL)
157 # endif
158 #else
159 # ifndef FROM_DIRECTION
160 #  error "FROM_DIRECTION must be provided if non-default init is used"
161 # endif
162 #endif
163
164
165 /* How many bytes are needed at most for the from-charset.  */
166 #ifndef MAX_NEEDED_FROM
167 # define MAX_NEEDED_FROM        MIN_NEEDED_FROM
168 #endif
169
170 /* Same for the to-charset.  */
171 #ifndef MAX_NEEDED_TO
172 # define MAX_NEEDED_TO          MIN_NEEDED_TO
173 #endif
174
175 /* Defaults for the per-direction min/max constants.  */
176 #ifndef FROM_LOOP_MIN_NEEDED_FROM
177 # define FROM_LOOP_MIN_NEEDED_FROM      MIN_NEEDED_FROM
178 #endif
179 #ifndef FROM_LOOP_MAX_NEEDED_FROM
180 # define FROM_LOOP_MAX_NEEDED_FROM      MAX_NEEDED_FROM
181 #endif
182 #ifndef FROM_LOOP_MIN_NEEDED_TO
183 # define FROM_LOOP_MIN_NEEDED_TO        MIN_NEEDED_TO
184 #endif
185 #ifndef FROM_LOOP_MAX_NEEDED_TO
186 # define FROM_LOOP_MAX_NEEDED_TO        MAX_NEEDED_TO
187 #endif
188 #ifndef TO_LOOP_MIN_NEEDED_FROM
189 # define TO_LOOP_MIN_NEEDED_FROM        MIN_NEEDED_TO
190 #endif
191 #ifndef TO_LOOP_MAX_NEEDED_FROM
192 # define TO_LOOP_MAX_NEEDED_FROM        MAX_NEEDED_TO
193 #endif
194 #ifndef TO_LOOP_MIN_NEEDED_TO
195 # define TO_LOOP_MIN_NEEDED_TO          MIN_NEEDED_FROM
196 #endif
197 #ifndef TO_LOOP_MAX_NEEDED_TO
198 # define TO_LOOP_MAX_NEEDED_TO          MAX_NEEDED_FROM
199 #endif
200
201
202 /* Define macros which can access unaligned buffers.  These macros are
203    supposed to be used only in code outside the inner loops.  For the inner
204    loops we have other definitions which allow optimized access.  */
205 #ifdef _STRING_ARCH_unaligned
206 /* We can handle unaligned memory access.  */
207 # define get16u(addr) *((__const uint16_t *) (addr))
208 # define get32u(addr) *((__const uint32_t *) (addr))
209
210 /* We need no special support for writing values either.  */
211 # define put16u(addr, val) *((uint16_t *) (addr)) = (val)
212 # define put32u(addr, val) *((uint32_t *) (addr)) = (val)
213 #else
214 /* Distinguish between big endian and little endian.  */
215 # if __BYTE_ORDER == __LITTLE_ENDIAN
216 #  define get16u(addr) \
217      (((__const unsigned char *) (addr))[1] << 8                              \
218       | ((__const unsigned char *) (addr))[0])
219 #  define get32u(addr) \
220      (((((__const unsigned char *) (addr))[3] << 8                            \
221         | ((__const unsigned char *) (addr))[2]) << 8                         \
222        | ((__const unsigned char *) (addr))[1]) << 8                          \
223       | ((__const unsigned char *) (addr))[0])
224
225 #  define put16u(addr, val) \
226      ({ uint16_t __val = (val);                                               \
227         ((unsigned char *) (addr))[0] = __val;                                \
228         ((unsigned char *) (addr))[1] = __val >> 8;                           \
229         (void) 0; })
230 #  define put32u(addr, val) \
231      ({ uint32_t __val = (val);                                               \
232         ((unsigned char *) (addr))[0] = __val;                                \
233         __val >>= 8;                                                          \
234         ((unsigned char *) (addr))[1] = __val;                                \
235         __val >>= 8;                                                          \
236         ((unsigned char *) (addr))[2] = __val;                                \
237         __val >>= 8;                                                          \
238         ((unsigned char *) (addr))[3] = __val;                                \
239         (void) 0; })
240 # else
241 #  define get16u(addr) \
242      (((__const unsigned char *) (addr))[0] << 8                              \
243       | ((__const unsigned char *) (addr))[1])
244 #  define get32u(addr) \
245      (((((__const unsigned char *) (addr))[0] << 8                            \
246         | ((__const unsigned char *) (addr))[1]) << 8                         \
247        | ((__const unsigned char *) (addr))[2]) << 8                          \
248       | ((__const unsigned char *) (addr))[3])
249
250 #  define put16u(addr, val) \
251      ({ uint16_t __val = (val);                                               \
252         ((unsigned char *) (addr))[1] = __val;                                \
253         ((unsigned char *) (addr))[0] = __val >> 8;                           \
254         (void) 0; })
255 #  define put32u(addr, val) \
256      ({ uint32_t __val = (val);                                               \
257         ((unsigned char *) (addr))[3] = __val;                                \
258         __val >>= 8;                                                          \
259         ((unsigned char *) (addr))[2] = __val;                                \
260         __val >>= 8;                                                          \
261         ((unsigned char *) (addr))[1] = __val;                                \
262         __val >>= 8;                                                          \
263         ((unsigned char *) (addr))[0] = __val;                                \
264         (void) 0; })
265 # endif
266 #endif
267
268
269 /* For conversions from a fixed width character set to another fixed width
270    character set we can define RESET_INPUT_BUFFER in a very fast way.  */
271 #if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
272 # if FROM_LOOP_MIN_NEEDED_FROM == FROM_LOOP_MAX_NEEDED_FROM \
273      && FROM_LOOP_MIN_NEEDED_TO == FROM_LOOP_MAX_NEEDED_TO \
274      && TO_LOOP_MIN_NEEDED_FROM == TO_LOOP_MAX_NEEDED_FROM \
275      && TO_LOOP_MIN_NEEDED_TO == TO_LOOP_MAX_NEEDED_TO
276 /* We have to use these `if's here since the compiler cannot know that
277    (outbuf - outerr) is always divisible by FROM/TO_LOOP_MIN_NEEDED_TO.
278    The ?:1 avoids division by zero warnings that gcc 3.2 emits even for
279    obviously unreachable code.  */
280 #  define RESET_INPUT_BUFFER \
281   if (FROM_DIRECTION)                                                         \
282     {                                                                         \
283       if (FROM_LOOP_MIN_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_TO == 0)           \
284         *inptrp -= (outbuf - outerr)                                          \
285                    * (FROM_LOOP_MIN_NEEDED_FROM / FROM_LOOP_MIN_NEEDED_TO);   \
286       else if (FROM_LOOP_MIN_NEEDED_TO % FROM_LOOP_MIN_NEEDED_FROM == 0)      \
287         *inptrp -= (outbuf - outerr)                                          \
288                    / (FROM_LOOP_MIN_NEEDED_TO / FROM_LOOP_MIN_NEEDED_FROM     \
289                       ? : 1);                                                 \
290       else                                                                    \
291         *inptrp -= ((outbuf - outerr) / FROM_LOOP_MIN_NEEDED_TO)              \
292                    * FROM_LOOP_MIN_NEEDED_FROM;                               \
293     }                                                                         \
294   else                                                                        \
295     {                                                                         \
296       if (TO_LOOP_MIN_NEEDED_FROM % TO_LOOP_MIN_NEEDED_TO == 0)               \
297         *inptrp -= (outbuf - outerr)                                          \
298                    * (TO_LOOP_MIN_NEEDED_FROM / TO_LOOP_MIN_NEEDED_TO);       \
299       else if (TO_LOOP_MIN_NEEDED_TO % TO_LOOP_MIN_NEEDED_FROM == 0)          \
300         *inptrp -= (outbuf - outerr)                                          \
301                    / (TO_LOOP_MIN_NEEDED_TO / TO_LOOP_MIN_NEEDED_FROM ? : 1); \
302       else                                                                    \
303         *inptrp -= ((outbuf - outerr) / TO_LOOP_MIN_NEEDED_TO)                \
304                    * TO_LOOP_MIN_NEEDED_FROM;                                 \
305     }
306 # endif
307 #endif
308
309
310 /* The default init function.  It simply matches the name and initializes
311    the step data to point to one of the objects above.  */
312 #if DEFINE_INIT
313 # ifndef CHARSET_NAME
314 #  error "CHARSET_NAME not defined"
315 # endif
316
317 extern int gconv_init (struct __gconv_step *step);
318 int
319 gconv_init (struct __gconv_step *step)
320 {
321   /* Determine which direction.  */
322   if (strcmp (step->__from_name, CHARSET_NAME) == 0)
323     {
324       step->__data = FROM_DIRECTION_VAL;
325
326       step->__min_needed_from = FROM_LOOP_MIN_NEEDED_FROM;
327       step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM;
328       step->__min_needed_to = FROM_LOOP_MIN_NEEDED_TO;
329       step->__max_needed_to = FROM_LOOP_MAX_NEEDED_TO;
330
331 #ifdef FROM_ONEBYTE
332       step->__btowc_fct = FROM_ONEBYTE;
333 #endif
334     }
335   else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
336     {
337       step->__data = TO_DIRECTION_VAL;
338
339       step->__min_needed_from = TO_LOOP_MIN_NEEDED_FROM;
340       step->__max_needed_from = TO_LOOP_MAX_NEEDED_FROM;
341       step->__min_needed_to = TO_LOOP_MIN_NEEDED_TO;
342       step->__max_needed_to = TO_LOOP_MAX_NEEDED_TO;
343     }
344   else
345     return __GCONV_NOCONV;
346
347 #ifdef SAVE_RESET_STATE
348   step->__stateful = 1;
349 #else
350   step->__stateful = 0;
351 #endif
352
353   return __GCONV_OK;
354 }
355 #endif
356
357
358 /* The default destructor function does nothing in the moment and so
359    we don't define it at all.  But we still provide the macro just in
360    case we need it some day.  */
361 #if DEFINE_FINI
362 #endif
363
364
365 /* If no arguments have to passed to the loop function define the macro
366    as empty.  */
367 #ifndef EXTRA_LOOP_ARGS
368 # define EXTRA_LOOP_ARGS
369 #endif
370
371
372 /* This is the actual conversion function.  */
373 #ifndef FUNCTION_NAME
374 # define FUNCTION_NAME  gconv
375 #endif
376
377 /* The macros are used to access the function to convert single characters.  */
378 #define SINGLE(fct) SINGLE2 (fct)
379 #define SINGLE2(fct) fct##_single
380
381
382 extern int FUNCTION_NAME (struct __gconv_step *step,
383                           struct __gconv_step_data *data,
384                           const unsigned char **inptrp,
385                           const unsigned char *inend,
386                           unsigned char **outbufstart, size_t *irreversible,
387                           int do_flush, int consume_incomplete);
388 int
389 FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
390                const unsigned char **inptrp, const unsigned char *inend,
391                unsigned char **outbufstart, size_t *irreversible, int do_flush,
392                int consume_incomplete)
393 {
394   struct __gconv_step *next_step = step + 1;
395   struct __gconv_step_data *next_data = data + 1;
396   __gconv_fct fct;
397   int status;
398
399   fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct;
400
401   /* If the function is called with no input this means we have to reset
402      to the initial state.  The possibly partly converted input is
403      dropped.  */
404   if (__builtin_expect (do_flush, 0))
405     {
406       /* This should never happen during error handling.  */
407       assert (outbufstart == NULL);
408
409       status = __GCONV_OK;
410
411 #ifdef EMIT_SHIFT_TO_INIT
412       if (do_flush == 1)
413         {
414           /* We preserve the initial values of the pointer variables.  */
415           unsigned char *outbuf = data->__outbuf;
416           unsigned char *outstart = outbuf;
417           unsigned char *outend = data->__outbufend;
418
419 # ifdef PREPARE_LOOP
420           PREPARE_LOOP
421 # endif
422
423 # ifdef SAVE_RESET_STATE
424           SAVE_RESET_STATE (1);
425 # endif
426
427           /* Emit the escape sequence to reset the state.  */
428           EMIT_SHIFT_TO_INIT;
429
430           /* Call the steps down the chain if there are any but only if we
431              successfully emitted the escape sequence.  This should only
432              fail if the output buffer is full.  If the input is invalid
433              it should be discarded since the user wants to start from a
434              clean state.  */
435           if (status == __GCONV_OK)
436             {
437               if (data->__flags & __GCONV_IS_LAST)
438                 /* Store information about how many bytes are available.  */
439                 data->__outbuf = outbuf;
440               else
441                 {
442                   /* Write out all output which was produced.  */
443                   if (outbuf > outstart)
444                     {
445                       const unsigned char *outerr = outstart;
446                       int result;
447
448                       result = DL_CALL_FCT (fct, (next_step, next_data,
449                                                   &outerr, outbuf, NULL,
450                                                   irreversible, 0,
451                                                   consume_incomplete));
452
453                       if (result != __GCONV_EMPTY_INPUT)
454                         {
455                           if (__builtin_expect (outerr != outbuf, 0))
456                             {
457                               /* We have a problem.  Undo the conversion.  */
458                               outbuf = outstart;
459
460                               /* Restore the state.  */
461 # ifdef SAVE_RESET_STATE
462                               SAVE_RESET_STATE (0);
463 # endif
464                             }
465
466                           /* Change the status.  */
467                           status = result;
468                         }
469                     }
470
471                   if (status == __GCONV_OK)
472                     /* Now flush the remaining steps.  */
473                     status = DL_CALL_FCT (fct, (next_step, next_data, NULL,
474                                                 NULL, NULL, irreversible, 1,
475                                                 consume_incomplete));
476                 }
477             }
478         }
479       else
480 #endif
481         {
482           /* Clear the state object.  There might be bytes in there from
483              previous calls with CONSUME_INCOMPLETE == 1.  But don't emit
484              escape sequences.  */
485           memset (data->__statep, '\0', sizeof (*data->__statep));
486
487           if (! (data->__flags & __GCONV_IS_LAST))
488             /* Now flush the remaining steps.  */
489             status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL,
490                                         NULL, irreversible, do_flush,
491                                         consume_incomplete));
492         }
493     }
494   else
495     {
496       /* We preserve the initial values of the pointer variables.  */
497       const unsigned char *inptr = *inptrp;
498       unsigned char *outbuf = (__builtin_expect (outbufstart == NULL, 1)
499                                ? data->__outbuf : *outbufstart);
500       unsigned char *outend = data->__outbufend;
501       unsigned char *outstart;
502       /* This variable is used to count the number of characters we
503          actually converted.  */
504       size_t lirreversible = 0;
505       size_t *lirreversiblep = irreversible ? &lirreversible : NULL;
506
507       /* The following assumes that encodings, which have a variable length
508          what might unalign a buffer even though it is a aligned in the
509          beginning, either don't have the minimal number of bytes as a divisor
510          of the maximum length or have a minimum length of 1.  This is true
511          for all known and supported encodings.
512          We use && instead of || to combine the subexpression for the FROM
513          encoding and for the TO encoding, because usually one of them is
514          INTERNAL, for which the subexpression evaluates to 1, but INTERNAL
515          buffers are always aligned correctly.  */
516 #define POSSIBLY_UNALIGNED \
517   (!defined _STRING_ARCH_unaligned                                            \
518    && (((FROM_LOOP_MIN_NEEDED_FROM != 1                                       \
519          && FROM_LOOP_MAX_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_FROM == 0)       \
520         && (FROM_LOOP_MIN_NEEDED_TO != 1                                      \
521             && FROM_LOOP_MAX_NEEDED_TO % FROM_LOOP_MIN_NEEDED_TO == 0))       \
522        || ((TO_LOOP_MIN_NEEDED_FROM != 1                                      \
523             && TO_LOOP_MAX_NEEDED_FROM % TO_LOOP_MIN_NEEDED_FROM == 0)        \
524            && (TO_LOOP_MIN_NEEDED_TO != 1                                     \
525                && TO_LOOP_MAX_NEEDED_TO % TO_LOOP_MIN_NEEDED_TO == 0))))
526 #if POSSIBLY_UNALIGNED
527       int unaligned;
528 # define GEN_unaligned(name) GEN_unaligned2 (name)
529 # define GEN_unaligned2(name) name##_unaligned
530 #else
531 # define unaligned 0
532 #endif
533
534 #ifdef PREPARE_LOOP
535       PREPARE_LOOP
536 #endif
537
538 #if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1
539       /* If the function is used to implement the mb*towc*() or wc*tomb*()
540          functions we must test whether any bytes from the last call are
541          stored in the `state' object.  */
542       if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1)
543            || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
544            || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION))
545           && consume_incomplete && (data->__statep->__count & 7) != 0)
546         {
547           /* Yep, we have some bytes left over.  Process them now.
548              But this must not happen while we are called from an
549              error handler.  */
550           assert (outbufstart == NULL);
551
552 # if FROM_LOOP_MAX_NEEDED_FROM > 1
553           if (TO_LOOP_MAX_NEEDED_FROM == 1 || FROM_DIRECTION)
554             status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf,
555                                         outend, lirreversiblep
556                                         EXTRA_LOOP_ARGS);
557 # endif
558 # if !ONE_DIRECTION
559 #  if FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1
560           else
561 #  endif
562 #  if TO_LOOP_MAX_NEEDED_FROM > 1
563             status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf,
564                                       outend, lirreversiblep EXTRA_LOOP_ARGS);
565 #  endif
566 # endif
567
568           if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
569             return status;
570         }
571 #endif
572
573 #if POSSIBLY_UNALIGNED
574       unaligned =
575         ((FROM_DIRECTION
576           && ((uintptr_t) inptr % FROM_LOOP_MIN_NEEDED_FROM != 0
577               || ((data->__flags & __GCONV_IS_LAST)
578                   && (uintptr_t) outbuf % FROM_LOOP_MIN_NEEDED_TO != 0)))
579          || (!FROM_DIRECTION
580              && (((data->__flags & __GCONV_IS_LAST)
581                   && (uintptr_t) outbuf % TO_LOOP_MIN_NEEDED_TO != 0)
582                  || (uintptr_t) inptr % TO_LOOP_MIN_NEEDED_FROM != 0)));
583 #endif
584
585       while (1)
586         {
587           struct __gconv_trans_data *trans;
588
589           /* Remember the start value for this round.  */
590           inptr = *inptrp;
591           /* The outbuf buffer is empty.  */
592           outstart = outbuf;
593
594 #ifdef SAVE_RESET_STATE
595           SAVE_RESET_STATE (1);
596 #endif
597
598           if (__builtin_expect (!unaligned, 1))
599             {
600               if (FROM_DIRECTION)
601                 /* Run the conversion loop.  */
602                 status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
603                                     lirreversiblep EXTRA_LOOP_ARGS);
604               else
605                 /* Run the conversion loop.  */
606                 status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
607                                   lirreversiblep EXTRA_LOOP_ARGS);
608             }
609 #if POSSIBLY_UNALIGNED
610           else
611             {
612               if (FROM_DIRECTION)
613                 /* Run the conversion loop.  */
614                 status = GEN_unaligned (FROM_LOOP) (step, data, inptrp, inend,
615                                                     &outbuf, outend,
616                                                     lirreversiblep
617                                                     EXTRA_LOOP_ARGS);
618               else
619                 /* Run the conversion loop.  */
620                 status = GEN_unaligned (TO_LOOP) (step, data, inptrp, inend,
621                                                   &outbuf, outend,
622                                                   lirreversiblep
623                                                   EXTRA_LOOP_ARGS);
624             }
625 #endif
626
627           /* If we were called as part of an error handling module we
628              don't do anything else here.  */
629           if (__builtin_expect (outbufstart != NULL, 0))
630             {
631               *outbufstart = outbuf;
632               return status;
633             }
634
635           /* Give the transliteration module the chance to store the
636              original text and the result in case it needs a context.  */
637           for (trans = data->__trans; trans != NULL; trans = trans->__next)
638             if (trans->__trans_context_fct != NULL)
639               DL_CALL_FCT (trans->__trans_context_fct,
640                            (trans->__data, inptr, *inptrp, outstart, outbuf));
641
642           /* We finished one use of the loops.  */
643           ++data->__invocation_counter;
644
645           /* If this is the last step leave the loop, there is nothing
646              we can do.  */
647           if (__builtin_expect (data->__flags & __GCONV_IS_LAST, 0))
648             {
649               /* Store information about how many bytes are available.  */
650               data->__outbuf = outbuf;
651
652               /* Remember how many non-identical characters we
653                  converted in a irreversible way.  */
654               *irreversible += lirreversible;
655
656               break;
657             }
658
659           /* Write out all output which was produced.  */
660           if (__builtin_expect (outbuf > outstart, 1))
661             {
662               const unsigned char *outerr = data->__outbuf;
663               int result;
664
665               result = DL_CALL_FCT (fct, (next_step, next_data, &outerr,
666                                           outbuf, NULL, irreversible, 0,
667                                           consume_incomplete));
668
669               if (result != __GCONV_EMPTY_INPUT)
670                 {
671                   if (__builtin_expect (outerr != outbuf, 0))
672                     {
673 #ifdef RESET_INPUT_BUFFER
674                       RESET_INPUT_BUFFER;
675 #else
676                       /* We have a problem in one of the functions below.
677                          Undo the conversion upto the error point.  */
678                       size_t nstatus;
679
680                       /* Reload the pointers.  */
681                       *inptrp = inptr;
682                       outbuf = outstart;
683
684                       /* Restore the state.  */
685 # ifdef SAVE_RESET_STATE
686                       SAVE_RESET_STATE (0);
687 # endif
688
689                       if (__builtin_expect (!unaligned, 1))
690                         {
691                           if (FROM_DIRECTION)
692                             /* Run the conversion loop.  */
693                             nstatus = FROM_LOOP (step, data, inptrp, inend,
694                                                  &outbuf, outerr,
695                                                  lirreversiblep
696                                                  EXTRA_LOOP_ARGS);
697                           else
698                             /* Run the conversion loop.  */
699                             nstatus = TO_LOOP (step, data, inptrp, inend,
700                                                &outbuf, outerr,
701                                                lirreversiblep
702                                                EXTRA_LOOP_ARGS);
703                         }
704 # if POSSIBLY_UNALIGNED
705                       else
706                         {
707                           if (FROM_DIRECTION)
708                             /* Run the conversion loop.  */
709                             nstatus = GEN_unaligned (FROM_LOOP) (step, data,
710                                                                  inptrp, inend,
711                                                                  &outbuf,
712                                                                  outerr,
713                                                                  lirreversiblep
714                                                                  EXTRA_LOOP_ARGS);
715                           else
716                             /* Run the conversion loop.  */
717                             nstatus = GEN_unaligned (TO_LOOP) (step, data,
718                                                                inptrp, inend,
719                                                                &outbuf, outerr,
720                                                                lirreversiblep
721                                                                EXTRA_LOOP_ARGS);
722                         }
723 # endif
724
725                       /* We must run out of output buffer space in this
726                          rerun.  */
727                       assert (outbuf == outerr);
728                       assert (nstatus == __GCONV_FULL_OUTPUT);
729
730                       /* If we haven't consumed a single byte decrement
731                          the invocation counter.  */
732                       if (__builtin_expect (outbuf == outstart, 0))
733                         --data->__invocation_counter;
734 #endif  /* reset input buffer */
735                     }
736
737                   /* Change the status.  */
738                   status = result;
739                 }
740               else
741                 /* All the output is consumed, we can make another run
742                    if everything was ok.  */
743                 if (status == __GCONV_FULL_OUTPUT)
744                   {
745                     status = __GCONV_OK;
746                     outbuf = data->__outbuf;
747                   }
748             }
749
750           if (status != __GCONV_OK)
751             break;
752
753           /* Reset the output buffer pointer for the next round.  */
754           outbuf = data->__outbuf;
755         }
756
757 #ifdef END_LOOP
758       END_LOOP
759 #endif
760
761       /* If we are supposed to consume all character store now all of the
762          remaining characters in the `state' object.  */
763 #if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1
764       if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1)
765            || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
766            || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION))
767           && __builtin_expect (consume_incomplete, 0)
768           && status == __GCONV_INCOMPLETE_INPUT)
769         {
770 # ifdef STORE_REST
771           mbstate_t *state = data->__statep;
772
773           STORE_REST
774 # else
775           /* Make sure the remaining bytes fit into the state objects
776              buffer.  */
777           assert (inend - *inptrp < 4);
778
779           size_t cnt;
780           for (cnt = 0; *inptrp < inend; ++cnt)
781             data->__statep->__value.__wchb[cnt] = *(*inptrp)++;
782           data->__statep->__count &= ~7;
783           data->__statep->__count |= cnt;
784 # endif
785         }
786 #endif
787 #undef unaligned
788 #undef POSSIBLY_UNALIGNED
789     }
790
791   return status;
792 }
793
794 #undef DEFINE_INIT
795 #undef CHARSET_NAME
796 #undef DEFINE_FINI
797 #undef MIN_NEEDED_FROM
798 #undef MIN_NEEDED_TO
799 #undef MAX_NEEDED_FROM
800 #undef MAX_NEEDED_TO
801 #undef FROM_LOOP_MIN_NEEDED_FROM
802 #undef FROM_LOOP_MAX_NEEDED_FROM
803 #undef FROM_LOOP_MIN_NEEDED_TO
804 #undef FROM_LOOP_MAX_NEEDED_TO
805 #undef TO_LOOP_MIN_NEEDED_FROM
806 #undef TO_LOOP_MAX_NEEDED_FROM
807 #undef TO_LOOP_MIN_NEEDED_TO
808 #undef TO_LOOP_MAX_NEEDED_TO
809 #undef FROM_DIRECTION
810 #undef EMIT_SHIFT_TO_INIT
811 #undef FROM_LOOP
812 #undef TO_LOOP
813 #undef ONE_DIRECTION
814 #undef SAVE_RESET_STATE
815 #undef RESET_INPUT_BUFFER
816 #undef FUNCTION_NAME
817 #undef PREPARE_LOOP
818 #undef END_LOOP
819 #undef EXTRA_LOOP_ARGS
820 #undef STORE_REST
821 #undef FROM_ONEBYTE