(STANDARD_FROM_LOOP_ERR_HANDLER): New macro.
[kopensolaris-gnu/glibc.git] / iconv / loop.c
index 08ee600..2fb73da 100644 (file)
@@ -1,22 +1,22 @@
 /* Conversion loop frame work.
-   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 /* This file provides a frame for the reader loop in all conversion modules.
    The actual code must (of course) be provided in the actual module source
 #  define put16(addr, val) \
      ({ uint16_t __val = (val);                                                      \
        ((unsigned char *) (addr))[1] = __val;                                \
-       ((unsigned char *) (addr))[2] = __val >> 8;                           \
+       ((unsigned char *) (addr))[0] = __val >> 8;                           \
        (void) 0; })
 #  define put32(addr, val) \
      ({ uint32_t __val = (val);                                                      \
 /* 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.  */
 /* 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.  */
   (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;                                        \
                                                                              \
     /* 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.  */           \
@@ -296,8 +321,8 @@ FCTNAME (LOOPFCT) (struct __gconv_step *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