Blame SOURCES/saplocales-2.2.5-rhel5.patch

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