diff -up saplocales-2.2.5/ASIANUNI.c-sap saplocales-2.2.5/ASIANUNI.c --- saplocales-2.2.5/ASIANUNI.c-sap 2009-02-18 15:07:53.000000000 -0800 +++ saplocales-2.2.5/ASIANUNI.c 2009-02-18 15:09:57.000000000 -0800 @@ -14151,7 +14151,8 @@ static const char from_ucs4_asianuni[0x7 } \ } \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -14163,7 +14164,7 @@ static const char from_ucs4_asianuni[0x7 #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ const char *cp; \ \ if (ch <= 0x7f) \ diff -up saplocales-2.2.5/DIOCLETIAN.c-sap saplocales-2.2.5/DIOCLETIAN.c --- saplocales-2.2.5/DIOCLETIAN.c-sap 2009-02-18 15:13:56.000000000 -0800 +++ saplocales-2.2.5/DIOCLETIAN.c 2009-02-18 15:15:09.000000000 -0800 @@ -561,7 +561,8 @@ static const uint32_t from_ucs4_diocleti uint32_t ch = to_ucs4_diocletian[*inptr]; \ ++inptr; \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -572,7 +573,7 @@ static const uint32_t from_ucs4_diocleti #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ \ if (ch != 0 && from_ucs4_diocletian[ch] == '\0') \ { \ diff -up saplocales-2.2.5/EUROJAPAN.c-sap saplocales-2.2.5/EUROJAPAN.c --- saplocales-2.2.5/EUROJAPAN.c-sap 2009-02-18 15:10:30.000000000 -0800 +++ saplocales-2.2.5/EUROJAPAN.c 2009-02-18 15:11:37.000000000 -0800 @@ -3679,7 +3679,8 @@ static const char from_ucs4_double[0x1eb } \ } \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -3691,7 +3692,7 @@ static const char from_ucs4_double[0x1eb #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ const char *cp; \ \ if (ch <= 0xff) \ diff -up saplocales-2.2.5/iconv/loop.c-sap saplocales-2.2.5/iconv/loop.c --- saplocales-2.2.5/iconv/loop.c-sap 2002-04-30 05:45:10.000000000 -0700 +++ saplocales-2.2.5/iconv/loop.c 2009-02-18 14:47:18.000000000 -0800 @@ -1,5 +1,5 @@ /* Conversion loop frame work. - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998-2002, 2003, 2005, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -43,6 +43,9 @@ INIT_PARAMS code to define and initialize variables from params. UPDATE_PARAMS code to store result in params. + + ONEBYTE_BODY body of the specialized conversion function for a + single byte from the current character set to INTERNAL. */ #include @@ -133,6 +136,8 @@ /* We need at least one byte for the next round. */ #ifndef MIN_NEEDED_INPUT # error "MIN_NEEDED_INPUT definition missing" +#elif MIN_NEEDED_INPUT < 1 +# error "MIN_NEEDED_INPUT must be >= 1" #endif /* Let's see how many bytes we produce. */ @@ -143,6 +148,8 @@ /* We produce at least one byte in the next round. */ #ifndef MIN_NEEDED_OUTPUT # error "MIN_NEEDED_OUTPUT definition missing" +#elif MIN_NEEDED_OUTPUT < 1 +# error "MIN_NEEDED_OUTPUT must be >= 1" #endif /* Let's see how many bytes we produce. */ @@ -167,6 +174,15 @@ # define EXTRA_LOOP_DECLS #endif +/* Allow using UPDATE_PARAMS in macros where #ifdef UPDATE_PARAMS test + isn't possible. */ +#ifndef UPDATE_PARAMS +# define UPDATE_PARAMS do { } while (0) +#endif +#ifndef REINIT_PARAMS +# define REINIT_PARAMS do { } while (0) +#endif + /* To make it easier for the writers of the modules, we define a macro to test whether we have to ignore errors. */ @@ -174,10 +190,29 @@ (irreversible != NULL && (flags & __GCONV_IGNORE_ERRORS)) -/* Error handling with transliteration/transcription function use and - ignoring of errors. Note that we cannot use the do while (0) trick - since `break' and `continue' must reach certain points. */ -#define STANDARD_ERR_HANDLER(Incr) \ +/* Error handling for the FROM_LOOP direction, with ignoring of errors. + Note that we cannot use the do while (0) trick since `break' and + `continue' must reach certain points. */ +#define STANDARD_FROM_LOOP_ERR_HANDLER(Incr) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + \ + if (! ignore_errors_p ()) \ + break; \ + \ + /* We ignore the invalid input byte sequence. */ \ + inptr += (Incr); \ + ++*irreversible; \ + /* But we keep result == __GCONV_ILLEGAL_INPUT, because of the constraint \ + that "iconv -c" must give the same exitcode as "iconv". */ \ + continue; \ + } + +/* Error handling for the TO_LOOP direction, with use of transliteration/ + transcription functions and ignoring of errors. Note that we cannot use + the do while (0) trick since `break' and `continue' must reach certain + points. */ +#define STANDARD_TO_LOOP_ERR_HANDLER(Incr) \ { \ struct __gconv_trans_data *trans; \ \ @@ -188,6 +223,10 @@ case we are not doing any error recovery outself. */ \ break; \ \ + /* If needed, flush any conversion state, so that __gconv_transliterate \ + starts with current shift state. */ \ + UPDATE_PARAMS; \ + \ /* First try the transliteration methods. */ \ for (trans = step_data->__trans; trans != NULL; trans = trans->__next) \ { \ @@ -197,9 +236,17 @@ if (result != __GCONV_ILLEGAL_INPUT) \ break; \ } \ + \ + REINIT_PARAMS; \ + \ /* If any of them recognized the input continue with the loop. */ \ if (result != __GCONV_ILLEGAL_INPUT) \ - continue; \ + { \ + if (__builtin_expect (result == __GCONV_FULL_OUTPUT, 0)) \ + break; \ + \ + continue; \ + } \ \ /* Next see whether we have to ignore the error. If not, stop. */ \ if (! ignore_errors_p ()) \ @@ -208,14 +255,16 @@ /* When we come here it means we ignore the character. */ \ ++*irreversible; \ inptr += Incr; \ + /* But we keep result == __GCONV_ILLEGAL_INPUT, because of the constraint \ + that "iconv -c" must give the same exitcode as "iconv". */ \ continue; \ } /* Handling of Unicode 3.1 TAG characters. Unicode recommends "If language codes are not relevant to the particular processing - operation, then they should be ignored." - This macro is usually called right before STANDARD_ERR_HANDLER (Incr). */ + operation, then they should be ignored." This macro is usually + called right before STANDARD_TO_LOOP_ERR_HANDLER (Incr). */ #define UNICODE_TAG_HANDLER(Character, Incr) \ { \ /* TAG characters are those in the range U+E0000..U+E007F. */ \ @@ -229,6 +278,7 @@ /* The function returns the status, as defined in gconv.h. */ static inline int +__attribute ((always_inline)) FCTNAME (LOOPFCT) (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, @@ -257,6 +307,14 @@ FCTNAME (LOOPFCT) (struct __gconv_step * /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the compiler generating better code. They will be optimized away since MIN_NEEDED_OUTPUT is always a constant. */ + if (MIN_NEEDED_INPUT > 1 + && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0)) + { + /* We don't have enough input for another complete input + character. */ + result = __GCONV_INCOMPLETE_INPUT; + break; + } if ((MIN_NEEDED_OUTPUT != 1 && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0)) || (MIN_NEEDED_OUTPUT == 1 @@ -266,14 +324,6 @@ FCTNAME (LOOPFCT) (struct __gconv_step * result = __GCONV_FULL_OUTPUT; break; } - if (MIN_NEEDED_INPUT > 1 - && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0)) - { - /* We don't have enough input for another complete input - character. */ - result = __GCONV_INCOMPLETE_INPUT; - break; - } /* Here comes the body the user provides. It can stop with RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the @@ -285,9 +335,7 @@ FCTNAME (LOOPFCT) (struct __gconv_step * /* Update the pointers pointed to by the parameters. */ *inptrp = inptr; *outptrp = outptr; -#ifdef UPDATE_PARAMS UPDATE_PARAMS; -#endif return result; } @@ -296,8 +344,8 @@ FCTNAME (LOOPFCT) (struct __gconv_step * /* Include the file a second time to define the function to handle unaligned access. */ #if !defined DEFINE_UNALIGNED && !defined _STRING_ARCH_unaligned \ - && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ - && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 + && MIN_NEEDED_INPUT != 1 && MAX_NEEDED_INPUT % MIN_NEEDED_INPUT == 0 \ + && MIN_NEEDED_OUTPUT != 1 && MAX_NEEDED_OUTPUT % MIN_NEEDED_OUTPUT == 0 # undef get16 # undef get32 # undef put16 @@ -314,6 +362,7 @@ FCTNAME (LOOPFCT) (struct __gconv_step * # define SINGLE(fct) SINGLE2 (fct) # define SINGLE2(fct) fct##_single static inline int +__attribute ((always_inline)) SINGLE(LOOPFCT) (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, @@ -400,7 +449,11 @@ SINGLE(LOOPFCT) (struct __gconv_step *st result = __GCONV_OK; /* Clear the state buffer. */ +#ifdef CLEAR_STATE + CLEAR_STATE; +#else state->__count &= ~7; +#endif } else if (result == __GCONV_INCOMPLETE_INPUT) { @@ -416,6 +469,10 @@ SINGLE(LOOPFCT) (struct __gconv_step *st #else /* We don't have enough input for another complete input character. */ + assert (inend - inptr > (state->__count & ~7)); + assert (inend - inptr <= 7); + state->__count = (state->__count & ~7) | (inend - inptr); + inlen = 0; while (inptr < inend) state->__value.__wchb[inlen++] = *inptr++; #endif @@ -428,6 +485,15 @@ SINGLE(LOOPFCT) (struct __gconv_step *st #endif +#ifdef ONEBYTE_BODY +/* Define the shortcut function for btowc. */ +static wint_t +gconv_btowc (struct __gconv_step *step, unsigned char c) + ONEBYTE_BODY +# define FROM_ONEBYTE gconv_btowc +#endif + + /* We remove the macro definitions so that we can include this file again for the definition of another function. */ #undef MIN_NEEDED_INPUT @@ -440,7 +506,10 @@ SINGLE(LOOPFCT) (struct __gconv_step *st #undef EXTRA_LOOP_DECLS #undef INIT_PARAMS #undef UPDATE_PARAMS +#undef REINIT_PARAMS +#undef ONEBYTE_BODY #undef UNPACK_BYTES +#undef CLEAR_STATE #undef LOOP_NEED_STATE #undef LOOP_NEED_FLAGS #undef LOOP_NEED_DATA diff -up saplocales-2.2.5/iconv/skeleton.c-sap saplocales-2.2.5/iconv/skeleton.c --- saplocales-2.2.5/iconv/skeleton.c-sap 2002-04-30 05:45:10.000000000 -0700 +++ saplocales-2.2.5/iconv/skeleton.c 2009-02-18 14:47:14.000000000 -0800 @@ -1,5 +1,5 @@ /* Skeleton for a conversion module. - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998-2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -37,12 +37,26 @@ This macro is optional, it defaults to MIN_NEEDED_FROM. MAX_NEEDED_TO likewise for the to-charset. - DEFINE_DIRECTION_OBJECTS - two objects will be defined to be used when the - `gconv' function must only distinguish two - directions. This is implied by DEFINE_INIT. - If this macro is not defined the following - macro must be available. + FROM_LOOP_MIN_NEEDED_FROM + FROM_LOOP_MAX_NEEDED_FROM + minimal/maximal number of bytes needed on input + of one round through the FROM_LOOP. Defaults + to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively. + FROM_LOOP_MIN_NEEDED_TO + FROM_LOOP_MAX_NEEDED_TO + minimal/maximal number of bytes needed on output + of one round through the FROM_LOOP. Defaults + to MIN_NEEDED_TO and MAX_NEEDED_TO, respectively. + TO_LOOP_MIN_NEEDED_FROM + TO_LOOP_MAX_NEEDED_FROM + minimal/maximal number of bytes needed on input + of one round through the TO_LOOP. Defaults + to MIN_NEEDED_TO and MAX_NEEDED_TO, respectively. + TO_LOOP_MIN_NEEDED_TO + TO_LOOP_MAX_NEEDED_TO + minimal/maximal number of bytes needed on output + of one round through the TO_LOOP. Defaults + to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively. FROM_DIRECTION this macro is supposed to return a value != 0 if we convert from the current character set, @@ -50,11 +64,11 @@ EMIT_SHIFT_TO_INIT this symbol is optional. If it is defined it defines some code which writes out a sequence - of characters which bring the current state into + of bytes which bring the current state into the initial state. FROM_LOOP name of the function implementing the conversion - from the current characters. + from the current character set. TO_LOOP likewise for the other direction ONE_DIRECTION optional. If defined to 1, only one conversion @@ -79,6 +93,44 @@ EXTRA_LOOP_ARGS optional macro specifying extra arguments passed to loop function. + + STORE_REST optional, needed only when MAX_NEEDED_FROM > 4. + This macro stores the seen but unconverted input bytes + in the state. + + FROM_ONEBYTE optional. If defined, should be the name of a + specialized conversion function for a single byte + from the current character set to INTERNAL. This + function has prototype + wint_t + FROM_ONEBYTE (struct __gconv_step *, unsigned char); + and does a special conversion: + - The input is a single byte. + - The output is a single uint32_t. + - The state before the conversion is the initial state; + the state after the conversion is irrelevant. + - No transliteration. + - __invocation_counter = 0. + - __internal_use = 1. + - do_flush = 0. + + Modules can use mbstate_t to store conversion state as follows: + + * Bits 2..0 of '__count' contain the number of lookahead input bytes + stored in __value.__wchb. Always zero if the converter never + returns __GCONV_INCOMPLETE_INPUT. + + * Bits 31..3 of '__count' are module dependent shift state. + + * __value: When STORE_REST/UNPACK_BYTES aren't defined and when the + converter has returned __GCONV_INCOMPLETE_INPUT, this contains + at most 4 lookahead bytes. Converters with an mb_cur_max > 4 + (currently only UTF-8) must find a way to store their state + in __value.__wch and define STORE_REST/UNPACK_BYTES appropriately. + + When __value contains lookahead, __count must not be zero, because + the converter is not in the initial state then, and mbsinit() -- + defined as a (__count == 0) test -- must reflect this. */ #include @@ -92,21 +144,22 @@ # include #endif +#include + #ifndef DL_CALL_FCT # define DL_CALL_FCT(fct, args) fct args #endif /* The direction objects. */ -#if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT -static int from_object; -static int to_object; - +#if DEFINE_INIT # ifndef FROM_DIRECTION -# define FROM_DIRECTION (step->__data == &from_object) +# define FROM_DIRECTION_VAL NULL +# define TO_DIRECTION_VAL ((void *) ~((uintptr_t) 0)) +# define FROM_DIRECTION (step->__data == FROM_DIRECTION_VAL) # endif #else # ifndef FROM_DIRECTION -# error "FROM_DIRECTION must be provided if direction objects are not used" +# error "FROM_DIRECTION must be provided if non-default init is used" # endif #endif @@ -121,6 +174,32 @@ static int to_object; # define MAX_NEEDED_TO MIN_NEEDED_TO #endif +/* Defaults for the per-direction min/max constants. */ +#ifndef FROM_LOOP_MIN_NEEDED_FROM +# define FROM_LOOP_MIN_NEEDED_FROM MIN_NEEDED_FROM +#endif +#ifndef FROM_LOOP_MAX_NEEDED_FROM +# define FROM_LOOP_MAX_NEEDED_FROM MAX_NEEDED_FROM +#endif +#ifndef FROM_LOOP_MIN_NEEDED_TO +# define FROM_LOOP_MIN_NEEDED_TO MIN_NEEDED_TO +#endif +#ifndef FROM_LOOP_MAX_NEEDED_TO +# define FROM_LOOP_MAX_NEEDED_TO MAX_NEEDED_TO +#endif +#ifndef TO_LOOP_MIN_NEEDED_FROM +# define TO_LOOP_MIN_NEEDED_FROM MIN_NEEDED_TO +#endif +#ifndef TO_LOOP_MAX_NEEDED_FROM +# define TO_LOOP_MAX_NEEDED_FROM MAX_NEEDED_TO +#endif +#ifndef TO_LOOP_MIN_NEEDED_TO +# define TO_LOOP_MIN_NEEDED_TO MIN_NEEDED_FROM +#endif +#ifndef TO_LOOP_MAX_NEEDED_TO +# define TO_LOOP_MAX_NEEDED_TO MAX_NEEDED_FROM +#endif + /* Define macros which can access unaligned buffers. These macros are supposed to be used only in code outside the inner loops. For the inner @@ -192,16 +271,40 @@ static int to_object; /* For conversions from a fixed width character set to another fixed width character set we can define RESET_INPUT_BUFFER in a very fast way. */ #if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE -# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO +# if FROM_LOOP_MIN_NEEDED_FROM == FROM_LOOP_MAX_NEEDED_FROM \ + && FROM_LOOP_MIN_NEEDED_TO == FROM_LOOP_MAX_NEEDED_TO \ + && TO_LOOP_MIN_NEEDED_FROM == TO_LOOP_MAX_NEEDED_FROM \ + && TO_LOOP_MIN_NEEDED_TO == TO_LOOP_MAX_NEEDED_TO /* We have to use these `if's here since the compiler cannot know that - (outbuf - outerr) is always divisible by MIN_NEEDED_TO. */ + (outbuf - outerr) is always divisible by FROM/TO_LOOP_MIN_NEEDED_TO. + The ?:1 avoids division by zero warnings that gcc 3.2 emits even for + obviously unreachable code. */ # define RESET_INPUT_BUFFER \ - if (MIN_NEEDED_FROM % MIN_NEEDED_TO == 0) \ - *inptrp -= (outbuf - outerr) * (MIN_NEEDED_FROM / MIN_NEEDED_TO); \ - else if (MIN_NEEDED_TO % MIN_NEEDED_FROM == 0) \ - *inptrp -= (outbuf - outerr) / (MIN_NEEDED_TO / MIN_NEEDED_FROM); \ + if (FROM_DIRECTION) \ + { \ + if (FROM_LOOP_MIN_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_TO == 0) \ + *inptrp -= (outbuf - outerr) \ + * (FROM_LOOP_MIN_NEEDED_FROM / FROM_LOOP_MIN_NEEDED_TO); \ + else if (FROM_LOOP_MIN_NEEDED_TO % FROM_LOOP_MIN_NEEDED_FROM == 0) \ + *inptrp -= (outbuf - outerr) \ + / (FROM_LOOP_MIN_NEEDED_TO / FROM_LOOP_MIN_NEEDED_FROM \ + ? : 1); \ + else \ + *inptrp -= ((outbuf - outerr) / FROM_LOOP_MIN_NEEDED_TO) \ + * FROM_LOOP_MIN_NEEDED_FROM; \ + } \ else \ - *inptrp -= ((outbuf - outerr) / MIN_NEEDED_TO) * MIN_NEEDED_FROM + { \ + if (TO_LOOP_MIN_NEEDED_FROM % TO_LOOP_MIN_NEEDED_TO == 0) \ + *inptrp -= (outbuf - outerr) \ + * (TO_LOOP_MIN_NEEDED_FROM / TO_LOOP_MIN_NEEDED_TO); \ + else if (TO_LOOP_MIN_NEEDED_TO % TO_LOOP_MIN_NEEDED_FROM == 0) \ + *inptrp -= (outbuf - outerr) \ + / (TO_LOOP_MIN_NEEDED_TO / TO_LOOP_MIN_NEEDED_FROM ? : 1); \ + else \ + *inptrp -= ((outbuf - outerr) / TO_LOOP_MIN_NEEDED_TO) \ + * TO_LOOP_MIN_NEEDED_FROM; \ + } # endif #endif @@ -220,21 +323,25 @@ gconv_init (struct __gconv_step *step) /* Determine which direction. */ if (strcmp (step->__from_name, CHARSET_NAME) == 0) { - step->__data = &from_object; + step->__data = FROM_DIRECTION_VAL; + + step->__min_needed_from = FROM_LOOP_MIN_NEEDED_FROM; + step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM; + step->__min_needed_to = FROM_LOOP_MIN_NEEDED_TO; + step->__max_needed_to = FROM_LOOP_MAX_NEEDED_TO; - step->__min_needed_from = MIN_NEEDED_FROM; - step->__max_needed_from = MAX_NEEDED_FROM; - step->__min_needed_to = MIN_NEEDED_TO; - step->__max_needed_to = MAX_NEEDED_TO; +#ifdef FROM_ONEBYTE + step->__btowc_fct = FROM_ONEBYTE; +#endif } else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0) { - step->__data = &to_object; + step->__data = TO_DIRECTION_VAL; - step->__min_needed_from = MIN_NEEDED_TO; - step->__max_needed_from = MAX_NEEDED_TO; - step->__min_needed_to = MIN_NEEDED_FROM; - step->__max_needed_to = MAX_NEEDED_FROM; + step->__min_needed_from = TO_LOOP_MIN_NEEDED_FROM; + step->__max_needed_from = TO_LOOP_MAX_NEEDED_FROM; + step->__min_needed_to = TO_LOOP_MIN_NEEDED_TO; + step->__max_needed_to = TO_LOOP_MAX_NEEDED_TO; } else return __GCONV_NOCONV; @@ -288,10 +395,17 @@ FUNCTION_NAME (struct __gconv_step *step { struct __gconv_step *next_step = step + 1; struct __gconv_step_data *next_data = data + 1; - __gconv_fct fct; + __gconv_fct fct = NULL; int status; - fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct; + if ((data->__flags & __GCONV_IS_LAST) == 0) + { + fct = next_step->__fct; +#ifdef PTR_DEMANGLE + if (next_step->__shlib_handle != NULL) + PTR_DEMANGLE (fct); +#endif + } /* If the function is called with no input this means we have to reset to the initial state. The possibly partly converted input is @@ -398,27 +512,45 @@ FUNCTION_NAME (struct __gconv_step *step actually converted. */ size_t lirreversible = 0; size_t *lirreversiblep = irreversible ? &lirreversible : NULL; -#if defined _STRING_ARCH_unaligned \ - || MIN_NEEDED_FROM == 1 || MAX_NEEDED_FROM % MIN_NEEDED_FROM != 0 \ - || MIN_NEEDED_TO == 1 || MAX_NEEDED_TO % MIN_NEEDED_TO != 0 -# define unaligned 0 -#else + + /* The following assumes that encodings, which have a variable length + what might unalign a buffer even though it is a aligned in the + beginning, either don't have the minimal number of bytes as a divisor + of the maximum length or have a minimum length of 1. This is true + for all known and supported encodings. + We use && instead of || to combine the subexpression for the FROM + encoding and for the TO encoding, because usually one of them is + INTERNAL, for which the subexpression evaluates to 1, but INTERNAL + buffers are always aligned correctly. */ +#define POSSIBLY_UNALIGNED \ + (!defined _STRING_ARCH_unaligned \ + && (((FROM_LOOP_MIN_NEEDED_FROM != 1 \ + && FROM_LOOP_MAX_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_FROM == 0) \ + && (FROM_LOOP_MIN_NEEDED_TO != 1 \ + && FROM_LOOP_MAX_NEEDED_TO % FROM_LOOP_MIN_NEEDED_TO == 0)) \ + || ((TO_LOOP_MIN_NEEDED_FROM != 1 \ + && TO_LOOP_MAX_NEEDED_FROM % TO_LOOP_MIN_NEEDED_FROM == 0) \ + && (TO_LOOP_MIN_NEEDED_TO != 1 \ + && TO_LOOP_MAX_NEEDED_TO % TO_LOOP_MIN_NEEDED_TO == 0)))) +#if POSSIBLY_UNALIGNED int unaligned; # define GEN_unaligned(name) GEN_unaligned2 (name) # define GEN_unaligned2(name) name##_unaligned +#else +# define unaligned 0 #endif #ifdef PREPARE_LOOP PREPARE_LOOP #endif -#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1 +#if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1 /* If the function is used to implement the mb*towc*() or wc*tomb*() functions we must test whether any bytes from the last call are stored in the `state' object. */ - if (((MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1) - || (MAX_NEEDED_FROM > 1 && FROM_DIRECTION) - || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION)) + if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1) + || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION) + || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION)) && consume_incomplete && (data->__statep->__count & 7) != 0) { /* Yep, we have some bytes left over. Process them now. @@ -426,18 +558,20 @@ FUNCTION_NAME (struct __gconv_step *step error handler. */ assert (outbufstart == NULL); -# if MAX_NEEDED_FROM > 1 - if (MAX_NEEDED_TO == 1 || FROM_DIRECTION) +# if FROM_LOOP_MAX_NEEDED_FROM > 1 + if (TO_LOOP_MAX_NEEDED_FROM == 1 || FROM_DIRECTION) status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf, outend, lirreversiblep EXTRA_LOOP_ARGS); # endif -# if MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1 && !ONE_DIRECTION +# if !ONE_DIRECTION +# if FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1 else -# endif -# if MAX_NEEDED_TO > 1 && !ONE_DIRECTION +# endif +# if TO_LOOP_MAX_NEEDED_FROM > 1 status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf, outend, lirreversiblep EXTRA_LOOP_ARGS); +# endif # endif if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK) @@ -445,22 +579,16 @@ FUNCTION_NAME (struct __gconv_step *step } #endif -#if !defined _STRING_ARCH_unaligned \ - && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ - && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 - /* The following assumes that encodings, which have a variable length - what might unalign a buffer even though it is a aligned in the - beginning, either don't have the minimal number of bytes as a divisor - of the maximum length or have a minimum length of 1. This is true - for all known and supported encodings. */ - unaligned = ((FROM_DIRECTION - && ((uintptr_t) inptr % MIN_NEEDED_FROM != 0 - || ((data->__flags & __GCONV_IS_LAST) - && (uintptr_t) outbuf % MIN_NEEDED_TO != 0))) - || (!FROM_DIRECTION - && (((data->__flags & __GCONV_IS_LAST) - && (uintptr_t) outbuf % MIN_NEEDED_FROM != 0) - || (uintptr_t) inptr % MIN_NEEDED_TO != 0))); +#if POSSIBLY_UNALIGNED + unaligned = + ((FROM_DIRECTION + && ((uintptr_t) inptr % FROM_LOOP_MIN_NEEDED_FROM != 0 + || ((data->__flags & __GCONV_IS_LAST) + && (uintptr_t) outbuf % FROM_LOOP_MIN_NEEDED_TO != 0))) + || (!FROM_DIRECTION + && (((data->__flags & __GCONV_IS_LAST) + && (uintptr_t) outbuf % TO_LOOP_MIN_NEEDED_TO != 0) + || (uintptr_t) inptr % TO_LOOP_MIN_NEEDED_FROM != 0))); #endif while (1) @@ -487,9 +615,7 @@ FUNCTION_NAME (struct __gconv_step *step status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend, lirreversiblep EXTRA_LOOP_ARGS); } -#if !defined _STRING_ARCH_unaligned \ - && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ - && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 +#if POSSIBLY_UNALIGNED else { if (FROM_DIRECTION) @@ -556,8 +682,8 @@ FUNCTION_NAME (struct __gconv_step *step #ifdef RESET_INPUT_BUFFER RESET_INPUT_BUFFER; #else - /* We have a problem with the in on of the functions - below. Undo the conversion upto the error point. */ + /* We have a problem in one of the functions below. + Undo the conversion upto the error point. */ size_t nstatus; /* Reload the pointers. */ @@ -584,9 +710,7 @@ FUNCTION_NAME (struct __gconv_step *step lirreversiblep EXTRA_LOOP_ARGS); } -# if !defined _STRING_ARCH_unaligned \ - && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ - && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 +# if POSSIBLY_UNALIGNED else { if (FROM_DIRECTION) @@ -645,10 +769,10 @@ FUNCTION_NAME (struct __gconv_step *step /* If we are supposed to consume all character store now all of the remaining characters in the `state' object. */ -#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1 - if (((MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1) - || (MAX_NEEDED_FROM > 1 && FROM_DIRECTION) - || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION)) +#if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1 + if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1) + || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION) + || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION)) && __builtin_expect (consume_incomplete, 0) && status == __GCONV_INCOMPLETE_INPUT) { @@ -657,12 +781,11 @@ FUNCTION_NAME (struct __gconv_step *step STORE_REST # else - size_t cnt; - /* Make sure the remaining bytes fit into the state objects buffer. */ assert (inend - *inptrp < 4); + size_t cnt; for (cnt = 0; *inptrp < inend; ++cnt) data->__statep->__value.__wchb[cnt] = *(*inptrp)++; data->__statep->__count &= ~7; @@ -670,6 +793,8 @@ FUNCTION_NAME (struct __gconv_step *step # endif } #endif +#undef unaligned +#undef POSSIBLY_UNALIGNED } return status; @@ -682,15 +807,24 @@ FUNCTION_NAME (struct __gconv_step *step #undef MIN_NEEDED_TO #undef MAX_NEEDED_FROM #undef MAX_NEEDED_TO -#undef DEFINE_DIRECTION_OBJECTS +#undef FROM_LOOP_MIN_NEEDED_FROM +#undef FROM_LOOP_MAX_NEEDED_FROM +#undef FROM_LOOP_MIN_NEEDED_TO +#undef FROM_LOOP_MAX_NEEDED_TO +#undef TO_LOOP_MIN_NEEDED_FROM +#undef TO_LOOP_MAX_NEEDED_FROM +#undef TO_LOOP_MIN_NEEDED_TO +#undef TO_LOOP_MAX_NEEDED_TO #undef FROM_DIRECTION #undef EMIT_SHIFT_TO_INIT #undef FROM_LOOP #undef TO_LOOP +#undef ONE_DIRECTION #undef SAVE_RESET_STATE #undef RESET_INPUT_BUFFER #undef FUNCTION_NAME #undef PREPARE_LOOP #undef END_LOOP -#undef ONE_DIRECTION +#undef EXTRA_LOOP_ARGS #undef STORE_REST +#undef FROM_ONEBYTE diff -up saplocales-2.2.5/Makefile-sap saplocales-2.2.5/Makefile --- saplocales-2.2.5/Makefile-sap 2009-02-18 15:34:56.000000000 -0800 +++ saplocales-2.2.5/Makefile 2009-02-18 15:51:43.000000000 -0800 @@ -20,13 +20,16 @@ gconv/NAGAMASA.so \ gconv/SILKROAD.so \ gconv/SAPSJIS.so +# Uncomment when building for glibc 2.6 and newer +# NEWFLAGS = -DFOR_GLIBC_2_6_AND_LATER + CFLAGS = \ -O \ -Wall -Winline -Wstrict-prototypes -Wwrite-strings \ -fno-strength-reduce -fPIC \ -D_LIBC_REENTRANT -DPIC -DSHARED -D_GNU_SOURCE=1 -D_REENTRANT=1 \ -include compiler.h \ --I. +-I. -Iiconv $(NEWFLAGS) LDFLAGS= -shared diff -up saplocales-2.2.5/NAGAMASA.c-sap saplocales-2.2.5/NAGAMASA.c --- saplocales-2.2.5/NAGAMASA.c-sap 2009-02-18 15:15:18.000000000 -0800 +++ saplocales-2.2.5/NAGAMASA.c 2009-02-18 15:16:01.000000000 -0800 @@ -3679,7 +3679,8 @@ static const char from_ucs4_double[0x1eb } \ } \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -3691,7 +3692,7 @@ static const char from_ucs4_double[0x1eb #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ const char *cp; \ \ if (ch <= 0xff) \ diff -up saplocales-2.2.5/SAPSJIS.c-sap saplocales-2.2.5/SAPSJIS.c --- saplocales-2.2.5/SAPSJIS.c-sap 2009-02-18 15:17:37.000000000 -0800 +++ saplocales-2.2.5/SAPSJIS.c 2009-02-18 15:19:04.000000000 -0800 @@ -4492,7 +4492,7 @@ static const char from_ucs4_extra[0x100] if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - STANDARD_ERR_HANDLER (4); \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ } \ else \ { \ diff -up saplocales-2.2.5/SAPUNI.c-sap saplocales-2.2.5/SAPUNI.c --- saplocales-2.2.5/SAPUNI.c-sap 2009-02-18 15:11:52.000000000 -0800 +++ saplocales-2.2.5/SAPUNI.c 2009-02-18 15:12:44.000000000 -0800 @@ -3679,7 +3679,8 @@ static const char from_ucs4_double[0x1eb } \ } \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -3691,7 +3692,7 @@ static const char from_ucs4_double[0x1eb #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ const char *cp; \ \ if (ch <= 0xff) \ diff -up saplocales-2.2.5/SILKROAD.c-sap saplocales-2.2.5/SILKROAD.c --- saplocales-2.2.5/SILKROAD.c-sap 2009-02-18 15:16:09.000000000 -0800 +++ saplocales-2.2.5/SILKROAD.c 2009-02-18 15:16:45.000000000 -0800 @@ -3679,7 +3679,8 @@ static const char from_ucs4_double[0x1eb } \ } \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -3691,7 +3692,7 @@ static const char from_ucs4_double[0x1eb #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ const char *cp; \ \ if (ch <= 0xff) \ diff -up saplocales-2.2.5/TRANSSIBERIAN.c-sap saplocales-2.2.5/TRANSSIBERIAN.c --- saplocales-2.2.5/TRANSSIBERIAN.c-sap 2009-02-18 15:13:00.000000000 -0800 +++ saplocales-2.2.5/TRANSSIBERIAN.c 2009-02-18 15:13:46.000000000 -0800 @@ -3679,7 +3679,8 @@ static const char from_ucs4_double[0x1eb } \ } \ \ - *((uint32_t *) outptr)++ = ch; \ + put32 (outptr, ch); \ + outptr += 4; \ } #include @@ -3691,7 +3692,7 @@ static const char from_ucs4_double[0x1eb #define LOOPFCT TO_LOOP #define BODY \ { \ - uint32_t ch = *((uint32_t *) inptr); \ + uint32_t ch = get32 (inptr); \ const char *cp; \ \ if (ch <= 0xff) \ diff -up saplocales-2.2.5/transsiberian.src-sap saplocales-2.2.5/transsiberian.src --- saplocales-2.2.5/transsiberian.src-sap 2009-02-18 17:44:55.000000000 -0800 +++ saplocales-2.2.5/transsiberian.src 2009-02-18 17:45:15.000000000 -0800 @@ -9230,7 +9230,7 @@ order_end END LC_COLLATE LC_MONETARY -int_curr_symbol "" +int_curr_symbol "" currency_symbol "" mon_decimal_point "" mon_thousands_sep "" diff -up saplocales-2.2.5/tr_TR-sap saplocales-2.2.5/tr_TR --- saplocales-2.2.5/tr_TR-sap 2009-02-18 15:22:43.000000000 -0800 +++ saplocales-2.2.5/tr_TR 2009-02-18 15:23:14.000000000 -0800 @@ -3430,8 +3430,8 @@ nostr "" -currency_symbol "" +int_curr_symbol "" +currency_symbol "" mon_decimal_point "" mon_thousands_sep "" mon_grouping 3