Blob Blame History Raw
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 <iconv/loop.c>
 
@@ -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 <iconv/loop.c>
 
@@ -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 <iconv/loop.c>
 
@@ -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 <drepper@cygnus.com>, 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 <assert.h>
@@ -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 <drepper@cygnus.com>, 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 <assert.h>
@@ -92,21 +144,22 @@
 # include <dlfcn.h>
 #endif
 
+#include <sysdep.h>
+
 #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 <iconv/loop.c>
 
@@ -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 <iconv/loop.c>
 
@@ -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 <iconv/loop.c>
 
@@ -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 <iconv/loop.c>
 
@@ -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	"<U0052><U0055><U0052><U0020>"
+int_curr_symbol	"<U0052><U0055><U0042><U0020>"
 currency_symbol	"<U00C0><U00C3><U00B1><U002E>"
 mon_decimal_point	"<U002E>"
 mon_thousands_sep	"<U0020>"
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	"<U0068><U0061><U0079><U0131><U007
 END LC_MESSAGES
 
 LC_MONETARY
-int_curr_symbol           "<U0054><U0052><U004C><U0020>"
-currency_symbol           "<U0054><U004C>"
+int_curr_symbol           "<U0054><U0052><U0059><U0020>"
+currency_symbol           "<U0059><U0054><U004C>"
 mon_decimal_point         "<U002C>"
 mon_thousands_sep         "<U002E>"
 mon_grouping              3