Tue Apr 2 21:27:01 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
authorRoland McGrath <roland@gnu.org>
Wed, 3 Apr 1996 16:31:49 +0000 (16:31 +0000)
committerRoland McGrath <roland@gnu.org>
Wed, 3 Apr 1996 16:31:49 +0000 (16:31 +0000)
* posix/glob.c (glob_pattern_p): Avoid scanning past eos if
the pattern ends with a backslash and quoting is enabled.
* posix/fnmatch.c (fnmatch): Likewise; return FNM_NOMATCH for such
  patterns.

49 files changed:
ChangeLog
MakeTAGS
Makerules
locale/Makefile
locale/programs/config.h
locale/programs/ctypedump.c [deleted file]
locale/programs/locale.c
po/header.pot [new file with mode: 0644]
posix/fnmatch.c
posix/glob.c
setjmp/setjmp.h
stdio-common/_itoa.c
stdio-common/_itoa.h
stdio-common/printf-parse.h
stdio-common/printf-prs.c
stdio-common/printf.h
stdio-common/tst-printf.c
stdio-common/vfprintf.c
stdlib/strtod.c
sysdeps/generic/setenv.c
wcsmbs/Makefile
wcsmbs/mbsadvance.c [deleted file]
wcsmbs/mbscat.c [deleted file]
wcsmbs/mbschr.c [deleted file]
wcsmbs/mbscpy.c [deleted file]
wcsmbs/mbsdup.c [deleted file]
wcsmbs/mbslen.c [deleted file]
wcsmbs/mbsncat.c [deleted file]
wcsmbs/mbsncmp.c [deleted file]
wcsmbs/mbsncpy.c [deleted file]
wcsmbs/mbsrchr.c [deleted file]
wcsmbs/mbstomb.c [deleted file]
wcsmbs/mbstr.h [deleted file]
wcsmbs/wcscat.c
wcsmbs/wcschr.c
wcsmbs/wcscmp.c
wcsmbs/wcscpy.c
wcsmbs/wcscspn.c
wcsmbs/wcsdup.c
wcsmbs/wcslen.c
wcsmbs/wcsncat.c
wcsmbs/wcsncmp.c
wcsmbs/wcsncpy.c
wcsmbs/wcspbrk.c
wcsmbs/wcsrchr.c
wcsmbs/wcsspn.c
wcsmbs/wcstok.c
wcsmbs/wcstr.h [deleted file]
wcsmbs/wcswcs.c [deleted file]

index f8c952f..ac276db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Tue Apr  2 21:27:01 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * posix/glob.c (glob_pattern_p): Avoid scanning past eos if
+       the pattern ends with a backslash and quoting is enabled.
+       * posix/fnmatch.c (fnmatch): Likewise; return FNM_NOMATCH for such
+       patterns.
+
 Mon Apr  1 13:34:55 1996  Roland McGrath  <roland@whiz-bang.gnu.ai.mit.edu>
 
        * stdio-common/tst-printf.c (main): Add new test case.
index a9baba6..7aaf0ac 100644 (file)
--- a/MakeTAGS
+++ b/MakeTAGS
@@ -165,7 +165,9 @@ $P/subdirs.pot: $(subdirs:%=$P/%.pot)
 # Combine all the messages into the final sorted template translation file.
 $P/SYS_libc.pot: $(all-pot)
        @rm -f $@.new
-       $(XGETTEXT) -d - -n -s --omit-header $^ > $@.new
+       sed -e 's/VERSION/$(version)/' -e "s/DATE/`date +'%Y-%m-%d %k:%M'`" \
+           po/header.pot > $@.new
+       $(XGETTEXT) -d - -n -s --omit-header $^ >> $@.new
        mv -f $@.new $@
        test ! -d CVS || cvs ci -m'Regenerated from source files' $@
 
index 296e811..d7e82d9 100644 (file)
--- a/Makerules
+++ b/Makerules
@@ -610,8 +610,12 @@ cd $(@D); $(BUILD_CC) $(BUILD_CFLAGS) $(<:$(common-objpfx)%=%) -o $(@F)
 endef
 
 # We always want to use configuration definitions.
+ifdef objdir
 # This is always used in $(common-objdir), so we use no directory name.
 BUILD_CFLAGS = -include config.h
+else
+BUILD_CFLAGS = -include $(..)config.h
+endif
 
 # Support the GNU standard name for this target.
 .PHONY: check
index 675052a..0a30cd2 100644 (file)
@@ -31,8 +31,8 @@ distribute    = localeinfo.h categories.def \
 routines       = setlocale loadlocale localeconv nl_langinfo
 categories     = ctype messages monetary numeric time collate
 aux            = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc
-others         = localedef# locale
-install-bin    = localedef# locale
+others         = localedef locale
+install-bin    = localedef locale
 extra-objs     = $(localedef-modules:=.o) $(locale-modules:=.o) \
                  $(lib-modules:=.o)
 
@@ -41,7 +41,6 @@ vpath %.h programs
 
 localedef-modules      := $(categories:%=ld-%) charmap charset linereader \
                           locfile stringtrans
-locale-modules         := ctypedump
 lib-modules            := simple-hash xmalloc xstrdup
 
 
index 6405465..4aa406d 100644 (file)
@@ -27,7 +27,6 @@ typedef int wint_t;
 typedef unsigned short int u16_t;
 
 
-
-int euidaccess (__const char *__name, int __type);
+#include_next <config.h>
 
 #endif
diff --git a/locale/programs/ctypedump.c b/locale/programs/ctypedump.c
deleted file mode 100644 (file)
index 2a67534..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <ctype.h>
-#include <endian.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <netinet/in.h>        /* Just for htons() */
-
-/*#include "localedef.h"*/
-#include "localeinfo.h"
-
-
-/* FIXME: these values should be part of the LC_CTYPE information.  */
-#define mb_cur_max 1
-#define mb_cur_min 1
-
-
-#define SWAP32(v)                                                           \
-       ((u32_t) (((((u32_t) (v)) & 0x000000ff) << 24)                       \
-               | ((((u32_t) (v)) & 0x0000ff00) << 8)                        \
-               | ((((u32_t) (v)) & 0x00ff0000) >> 8)                        \
-               | ((((u32_t) (v)) & 0xff000000) >> 24)))
-
-
-
-static inline void
-print_short_in_char (unsigned short val)
-{
-  const unsigned char *p = (const unsigned char *) &val;
-  printf ("\"\\%03o\\%03o\"", p[0], p[1]);
-}
-
-
-static inline void
-print_int_in_char (unsigned int val)
-{
-  const unsigned char *p = (const unsigned char *) &val;
-  printf ("\"\\%03o\\%03o\\%03o\\%03o\"", p[0], p[1], p[2], p[3]);
-}
-
-
-int
-ctype_output (void)
-{
-  int ch;
-  int result = 0;
-  const char *locname = (getenv ("LC_ALL") ?: getenv ("LC_CTYPE") ?:
-                        getenv ("LANG") ?: "POSIX");
-
-  puts ("#include <endian.h>\n");
-
-  if (mb_cur_max == 1)
-    {
-      printf ("const char _nl_%s_LC_CTYPE_class[] = \n", locname);
-      for (ch = -128; ch < (1 << (8 * MB_CUR_MAX)); ++ch)
-        {
-         if (((ch + 128) % 6) == 0)
-           printf ("  /* 0x%02x */ ", ch < 0 ? 256 + ch : ch);
-         print_short_in_char (htons (__ctype_b [ch < 0 ? 256 + ch : ch]));
-         fputc (((ch + 128) % 6) == 5 ? '\n' : ' ', stdout);
-        }
-      puts (";");
-    }
-
-  printf ("#if BYTE_ORDER == %s\n",
-         BYTE_ORDER == LITTLE_ENDIAN ? "LITTLE_ENDIAN" : "BIG_ENDIAN");
-
-  if (mb_cur_max == 1)
-    {
-      printf ("const char _nl_%s_LC_CTYPE_toupper[] = \n", locname);
-      for (ch = -128; ch < (1 << (8 * MB_CUR_MAX)); ++ch)
-        {
-         if (((ch + 128) % 3) == 0)
-           printf ("  /* 0x%02x */ ", ch < 0 ? 256 + ch : ch);
-         print_int_in_char (__ctype_toupper[ch < 0 ? 256 + ch : ch]);
-         fputc (((ch + 128) % 3) == 2 ? '\n' : ' ', stdout);
-        }
-      puts (";");
-
-      printf ("const char _nl_%s_LC_CTYPE_tolower[] = \n", locname);
-      for (ch = -128; ch < (1 << (8 * MB_CUR_MAX)); ++ch)
-        {
-         if (((ch + 128) % 3) == 0)
-           printf ("  /* 0x%02x */ ", ch < 0 ? 256 + ch : ch);
-         print_int_in_char (__ctype_tolower[ch < 0 ? 256 + ch : ch]);
-         fputc (((ch + 128) % 3) == 2 ? '\n' : ' ', stdout);
-        }
-      puts (";");
-    }
-  else
-    /* not implemented */;
-
-  printf ("#elif BYTE_ORDER == %s\n",
-          BYTE_ORDER == LITTLE_ENDIAN ? "BIG_ENDIAN" : "LITTLE_ENDIAN");
-
-  if (mb_cur_max == 1)
-    {
-      printf ("const char _nl_%s_LC_CTYPE_toupper[] = \n", locname);
-      for (ch = -128; ch < (1 << (8 * MB_CUR_MAX)); ++ch)
-        {
-         if (((ch + 128) % 3) == 0)
-           printf ("  /* 0x%02x */ ", ch < 0 ? 256 + ch : ch);
-         print_int_in_char (SWAP32 (__ctype_toupper[ch < 0 ? 256 + ch : ch]));
-         fputc (((ch + 128) % 3) == 2 ? '\n' : ' ', stdout);
-        }
-      puts (";");
-
-      printf ("const char _nl_%s_LC_CTYPE_tolower[] = \n", locname);
-      for (ch = -128; ch < (1 << (8 * MB_CUR_MAX)); ++ch)
-        {
-         if (((ch + 128) % 3) == 0)
-           printf ("  /* 0x%02x */ ", ch < 0 ? 256 + ch : ch);
-         print_int_in_char (SWAP32 (__ctype_tolower[ch < 0 ? 256 + ch : ch]));
-         fputc (((ch + 128) % 3) == 2 ? '\n' : ' ', stdout);
-        }
-      puts (";");
-    }
-  else
-    /* not implemented */;
-
-  puts ("#else\n#error \"BYTE_ORDER\" BYTE_ORDER \" not handled.\"\n#endif\n");
-
-  printf("const struct locale_data _nl_%s_LC_CTYPE = \n\
-{\n\
-  NULL, 0, /* no file mapped */\n\
-  5,\n\
-  {\n\
-    _nl_C_LC_CTYPE_class,\n\
-#ifdef BYTE_ORDER == LITTLE_ENDIAN\n\
-    NULL, NULL,\n\
-#endif\n\
-    _nl_C_LC_CTYPE_toupper,\n\
-    _nl_C_LC_CTYPE_tolower,\n\
-#ifdef BYTE_ORDER == BIG_ENDIAN\n\
-    NULL, NULL,\n\
-#endif\n\
-  }\n\
-};\n", locname);
-
-  return result;
-}
-
-/*
- * Local Variables:
- *  mode:c
- *  c-basic-offset:2
- * End:
- */
index 4e4ff83..8254289 100644 (file)
@@ -15,7 +15,12 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include <dirent.h>
+#include <error.h>
 #include <getopt.h>
 #include <langinfo.h>
 #include <libintl.h>
@@ -26,13 +31,9 @@ Cambridge, MA 02139, USA.  */
 #include <unistd.h>
 #include <errno.h>
 
-/*#include "localedef.h"*/
 #include "localeinfo.h"
 
 
-/* If set dump C code describing the current locale.  */
-static int do_dump;
-
 /* If set print the name of the category.  */
 static int show_category_name;
 
@@ -45,7 +46,6 @@ static const struct option long_options[] =
   { "all-locales", no_argument, NULL, 'a' },
   { "category-name", no_argument, &show_category_name, 1 },
   { "charmaps", no_argument, NULL, 'm' },
-  { "dump", no_argument, &do_dump, 1 },
   { "help", no_argument, NULL, 'h' },
   { "keyword-name", no_argument, &show_keyword_name, 1 },
   { "version", no_argument, NULL, 'v' },
@@ -65,35 +65,48 @@ static const struct option long_options[] =
 #define CTYPE_TOUPPER_EL 0
 #define CTYPE_TOLOWER_EL 0
 
-/* XXX Hack */
-struct cat_item
+/* Definition of the data structure which represents a category and its
+   items.  */
+struct category
 {
-  int item_id;
+  int cat_id;
   const char *name;
-  enum { std, opt } status;
-  enum value_type value_type;
-  int min;
-  int max;
+  size_t number;
+  struct cat_item
+  {
+    int item_id;
+    const char *name;
+    enum { std, opt } status;
+    enum value_type value_type;
+    int min;
+    int max;
+  } *item_desc;
 };
 
+/* Simple helper macro.  */
+#define NELEMS(arr) ((sizeof (arr)) / (sizeof (arr[0])))
+
+/* For some tricky stuff.  */
+#define NO_PAREN(Item, More...) Item, ## More
 
 /* We have all categories defined in `categories.def'.  Now construct
    the description and data structure used for all categories.  */
+#define DEFINE_ELEMENT(Item, More...) { Item, ## More },
 #define DEFINE_CATEGORY(category, name, items, postload, in, check, out)      \
     static struct cat_item category##_desc[] =                               \
       {                                                                              \
         NO_PAREN items                                                       \
       };
 
-#include "locale/aux/categories.def"
+#include "categories.def"
 #undef DEFINE_CATEGORY
 
 static struct category category[] =
   {
 #define DEFINE_CATEGORY(category, name, items, postload, in, check, out)      \
     { _NL_NUM_##category, name, NELEMS (category##_desc) - 1,                 \
-      category##_desc, NULL, NULL, NULL, out },
-#include "locale/aux/categories.def"
+      category##_desc },
+#include "categories.def"
 #undef DEFINE_CATEGORY
   };
 #define NCATEGORIES NELEMS (category)
@@ -105,7 +118,6 @@ static void write_locales (void);
 static void write_charmaps (void);
 static void show_locale_vars (void);
 static void show_info (const char *name);
-static void dump_category (const char *name);
 
 
 int
@@ -118,7 +130,6 @@ main (int argc, char *argv[])
   int do_charmaps = 0;
 
   /* Set initial values for global varaibles.  */
-  do_dump = 0;
   show_category_name = 0;
   show_keyword_name = 0;
 
@@ -170,20 +181,6 @@ main (int argc, char *argv[])
   if (do_help)
     usage (EXIT_SUCCESS);
 
-  /* Dump C code.  */
-  if (do_dump)
-    {
-      printf ("\
-/* Generated by GNU %s %s.  */\n\
-\n\
-#include \"localeinfo.h\"\n", program_invocation_name, VERSION);
-
-      while (optind < argc)
-       dump_category (argv[optind++]);
-
-      exit (EXIT_SUCCESS);
-    }
-
   /* `-a' requests the names of all available locales.  */
   if (do_all != 0)
     {
@@ -235,8 +232,6 @@ Mandatory arguments to long options are mandatory for short options too.\n\
   -c, --category-name   write names of selected categories\n\
   -k, --keyword-name    write names of selected keywords\n\
 \n\
-      --dump            dump C code describing the current locale\n\
-                        (this code can be used in the C library)\n\
 "), program_invocation_name);
 
   exit (status);
@@ -389,6 +384,12 @@ show_info (const char *name)
            printf ("%d", cnt == 0 || *val == CHAR_MAX ? -1 : *val);
          }
          break;
+       case word:
+         {
+           unsigned int val = (unsigned int) nl_langinfo (item->item_id);
+           printf ("%d", val);
+         }
+         break;
        default:
        }
       putchar ('\n');
@@ -398,13 +399,6 @@ show_info (const char *name)
     {
       size_t item_no;
 
-      if (category[cat_no].outfct != NULL)
-       /* Categories which need special handling of the output are
-          not written.  This is especially for LC_CTYPE and LC_COLLATE.
-          It does not make sense to have this large number of cryptic
-          characters displayed.  */
-       continue;
-
       if (strcmp (name, category[cat_no].name) == 0)
        /* Print the whole category.  */
        {
@@ -428,117 +422,3 @@ show_info (const char *name)
          }
     }
 }
-
-
-static void
-dump_category (const char *name)
-{
-  char *locname;
-  size_t cat_no, item_no, nstrings;
-
-  for (cat_no = 0; cat_no < NCATEGORIES; ++cat_no)
-    if (strcmp (name, category[cat_no].name) == 0)
-      break;
-
-  if (cat_no >= NCATEGORIES)
-    return;
-
-  /* The NAME specifies a correct locale category.  */
-  if (category[cat_no].outfct != NULL)
-    {
-      category[cat_no].outfct ();
-      return;
-    }
-
-  locname = (getenv ("LC_ALL") ?: getenv (name) ?:
-            getenv ("LANG") ?: (char *) "POSIX");
-
-  /* Determine the number of strings in advance.  */
-  nstrings = 0;
-  for (item_no = 0; item_no < category[cat_no].number; ++item_no)
-    switch (category[cat_no].item_desc[item_no].value_type)
-      {
-      case string:
-      case byte:
-      case bytearray:
-       ++nstrings;
-       break;
-      case stringarray:
-       nstrings += category[cat_no].item_desc[item_no].max;
-      default:
-      }
-
-  printf ("\nconst struct locale_data _nl_%s_%s =\n{\n"
-         "  NULL, 0, /* no file mapped */\n  %Zu,\n  {\n",
-         locname, name, nstrings);
-
-  for (item_no = 0; item_no < category[cat_no].number; ++item_no)
-    switch (category[cat_no].item_desc[item_no].value_type)
-      {
-      case string:
-       {
-         const char *val = nl_langinfo (
-           category[cat_no].item_desc[item_no].item_id);
-
-         if (val != NULL)
-           printf ("    \"%s\",\n", val);
-         else
-           puts ("    NULL,");
-       }
-       break;
-      case stringarray:
-       {
-         const char *val;
-         int cnt;
-
-         for (cnt = 0; cnt < category[cat_no].item_desc[item_no].max; ++cnt)
-           {
-             val = nl_langinfo (
-               category[cat_no].item_desc[item_no].item_id + cnt);
-
-             if (val != NULL)
-               printf ("    \"%s\",\n", val);
-             else
-                puts ("    NULL,");
-           }
-       }
-       break;
-      case byte:
-       {
-         const char *val = nl_langinfo (
-           category[cat_no].item_desc[item_no].item_id);
-
-         if (val != NULL)
-           printf ("    \"\\%o\",\n",
-                   *(unsigned char *) val ? : UCHAR_MAX);
-         else
-           puts ("    NULL,");
-       }
-       break;
-      case bytearray:
-       {
-         const char *bytes = nl_langinfo (
-           category[cat_no].item_desc[item_no].item_id);
-
-         if (bytes != NULL)
-           {
-             fputs ("    \"", stdout);
-             if (*bytes != '\0')
-               do
-                 printf ("\\%o", *(unsigned char *) bytes++);
-               while (*bytes != '\0');
-             else
-               printf ("\\%o", UCHAR_MAX);
-
-             puts ("\",");
-           }
-         else
-           puts ("    NULL,");
-       }
-       break;
-      default:
-       break;
-      }
-
-  puts ("  }\n};");
-}
diff --git a/po/header.pot b/po/header.pot
new file mode 100644 (file)
index 0000000..c8d0c8a
--- /dev/null
@@ -0,0 +1,14 @@
+# GNU libc message catalog of translations
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Automatically generated; contact <bug-glibc@prep.ai.mit.edu>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: libc VERSION\n"
+"PO-Revision-Date: DATE\n"
+"Last-Translator: GNU libc maintainers <bug-glibc@prep.ai.mit.edu>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
index 1ddea80..08c1c94 100644 (file)
@@ -78,6 +78,9 @@ fnmatch (pattern, string, flags)
          if (!(flags & FNM_NOESCAPE))
            {
              c = *p++;
+             if (c == '\0')
+               /* Trailing \ loses.  */
+               return FNM_NOMATCH;
              c = FOLD (c);
            }
          if (FOLD (*n) != c)
@@ -129,7 +132,11 @@ fnmatch (pattern, string, flags)
                register char cstart = c, cend = c;
 
                if (!(flags & FNM_NOESCAPE) && c == '\\')
-                 cstart = cend = *p++;
+                 {
+                   if (*p == '\0')
+                     return FNM_NOMATCH;
+                   cstart = cend = *p++;
+                 }
 
                cstart = cend = FOLD (cstart);
 
@@ -176,8 +183,12 @@ fnmatch (pattern, string, flags)
 
                c = *p++;
                if (!(flags & FNM_NOESCAPE) && c == '\\')
-                 /* XXX 1003.2d11 is unclear if this is right.  */
-                 ++p;
+                 {
+                   if (*p == '\0')
+                     return FNM_NOMATCH;
+                   /* XXX 1003.2d11 is unclear if this is right.  */
+                   ++p;
+                 }
              }
            if (not)
              return FNM_NOMATCH;
index eea126d..1a00af6 100644 (file)
@@ -699,7 +699,7 @@ glob_pattern_p (pattern, quote)
        return 1;
 
       case '\\':
-       if (quote)
+       if (quote && p[1] != '\0')
          ++p;
        break;
 
index 12b05f1..1cd5bbd 100644 (file)
@@ -32,7 +32,7 @@ __BEGIN_DECLS
 #include <sigset.h>            /* Get `__sigset_t'.  */
 
 /* Calling environment, plus possibly a saved signal mask.  */
-typedef struct __jmp_buf       /* C++ doesn't like tagless structs.  */
+typedef struct __jmp_buf_tag   /* C++ doesn't like tagless structs.  */
   {
     /* NOTE: The machine-dependent definitions of `__sigsetjmp'
        assume that a `jmp_buf' begins with a `__jmp_buf'.
index caa8179..38d5367 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal function for converting integers to ASCII.
-Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 Contributed by Torbjorn Granlund <tege@matematik.su.se>
 and Ulrich Drepper <drepper@gnu.ai.mit.edu>.
@@ -159,10 +159,10 @@ static const struct base_table_t base_table[] =
 };
 
 /* Lower-case digits.  */
-static const char _itoa_lower_digits[]
+const char _itoa_lower_digits[]
        = "0123456789abcdefghijklmnopqrstuvwxyz";
 /* Upper-case digits.  */
-static const char _itoa_upper_digits[]
+const char _itoa_upper_digits[]
        = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
 
index ab3d1d1..75f5f85 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal function for converting integers to ASCII.
-Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -29,4 +29,31 @@ Cambridge, MA 02139, USA.  */
 extern char *_itoa __P ((unsigned long long int value, char *buflim,
                         unsigned int base, int upper_case));
 
+static inline char *_itoa_word (unsigned long value, char *buflim,
+                               unsigned int base, int upper_case)
+{
+  extern const char _itoa_upper_digits[], _itoa_lower_digits[];
+  const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits;
+  char *bp = buflim;
+
+  switch (base)
+    {
+#define SPECIAL(Base)                                                        \
+    case Base:                                                               \
+      do                                                                     \
+       *--bp = digits[value % Base];                                         \
+      while ((value /= Base) != 0);                                          \
+      break
+
+      SPECIAL (10);
+      SPECIAL (16);
+      SPECIAL (8);
+    default:
+      do
+       *--bp = digits[value % base];
+      while ((value /= base) != 0);
+    }
+  return bp;
+}
+
 #endif /* itoa.h */
index 9abbdba..a7960e6 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal header for parsing printf format strings.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of th GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -73,14 +73,14 @@ union printf_arg
 /* Read a simple integer from a string and update the string pointer.
    It is assumed that the first character is a digit.  */
 static inline unsigned int
-read_int (const char * *pstr)
+read_int (const UCHAR_T * *pstr)
 {
-  unsigned int retval = **pstr - '0';
+  unsigned int retval = **pstr - L_('0');
 
-  while (isdigit (*++(*pstr)))
+  while (ISDIGIT (*++(*pstr)))
     {
       retval *= 10;
-      retval += **pstr - '0';
+      retval += **pstr - L_('0');
     }
 
   return retval;
@@ -91,13 +91,13 @@ read_int (const char * *pstr)
 /* Find the next spec in FORMAT, or the end of the string.  Returns
    a pointer into FORMAT, to a '%' or a '\0'.  */
 static inline const char *
-find_spec (const char *format)
+find_spec (const char *format, mbstate_t *ps)
 {
   while (*format != '\0' && *format != '%')
     {
       int len;
 
-      if (isascii (*format) || (len = mblen (format, MB_CUR_MAX)) <= 0)
+      if (isascii (*format) || (len = mbrlen (format, MB_CUR_MAX, ps)) <= 0)
        ++format;
       else
        format += len;
@@ -116,8 +116,8 @@ extern printf_arginfo_function **__printf_arginfo_table;
    the number of args consumed by this spec; *MAX_REF_ARG is updated so it
    remains the highest argument index used.  */
 static inline size_t
-parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
-               size_t *max_ref_arg)
+parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
+               size_t *max_ref_arg, mbstate_t *ps)
 {
   unsigned int n;
   size_t nargs = 0;
@@ -135,13 +135,13 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   spec->info.pad = ' ';
 
   /* Test for positional argument.  */
-  if (isdigit (*format))
+  if (ISDIGIT (*format))
     {
-      const char *begin = format;
+      const UCHAR_T *begin = format;
 
       n = read_int (&format);
 
-      if (n > 0 && *format == '$')
+      if (n > 0 && *format == L_('$'))
        /* Is positional parameter.  */
        {
          ++format;             /* Skip the '$'.  */
@@ -155,32 +155,32 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
     }
 
   /* Check for spec modifiers.  */
-  while (*format == ' ' || *format == '+' || *format == '-' ||
-        *format == '#' || *format == '0' || *format == '\'')
+  while (*format == L_(' ') || *format == L_('+') || *format == L_('-') ||
+        *format == L_('#') || *format == L_('0') || *format == L_('\''))
     switch (*format++)
       {
-      case ' ':
+      case L_(' '):
        /* Output a space in place of a sign, when there is no sign.  */
        spec->info.space = 1;
        break;
-      case '+':
+      case L_('+'):
        /* Always output + or - for numbers.  */
        spec->info.showsign = 1;
        break;
-      case '-':
+      case L_('-'):
        /* Left-justify things.  */
        spec->info.left = 1;
        break;
-      case '#':
+      case L_('#'):
        /* Use the "alternate form":
           Hex has 0x or 0X, FP always has a decimal point.  */
        spec->info.alt = 1;
        break;
-      case '0':
+      case L_('0'):
        /* Pad with 0s.  */
        spec->info.pad = '0';
        break;
-      case '\'':
+      case L_('\''):
        /* Show grouping in numbers if the locale information
           indicates any.  */
        spec->info.group = 1;
@@ -192,18 +192,18 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   /* Get the field width.  */
   spec->width_arg = -1;
   spec->info.width = 0;
-  if (*format == '*')
+  if (*format == L_('*'))
     {
       /* The field width is given in an argument.
         A negative field width indicates left justification.  */
-      const char *begin = ++format;
+      const UCHAR_T *begin = ++format;
 
-      if (isdigit (*format))
+      if (ISDIGIT (*format))
        {
          /* The width argument might be found in a positional parameter.  */
          n = read_int (&format);
 
-         if (n > 0 && *format == '$')
+         if (n > 0 && *format == L_('$'))
            {
              spec->width_arg = n - 1;
              *max_ref_arg = MAX (*max_ref_arg, n);
@@ -219,7 +219,7 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
          format = begin;       /* Step back and reread.  */
        }
     }
-  else if (isdigit (*format))
+  else if (ISDIGIT (*format))
     /* Constant width specification.  */
     spec->info.width = read_int (&format);
 
@@ -227,19 +227,19 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   spec->prec_arg = -1;
   /* -1 means none given; 0 means explicit 0.  */
   spec->info.prec = -1;
-  if (*format == '.')
+  if (*format == L_('.'))
     {
       ++format;
-      if (*format == '*')
+      if (*format == L_('*'))
        {
          /* The precision is given in an argument.  */
-         const char *begin = ++format;
+         const UCHAR_T *begin = ++format;
 
-         if (isdigit (*format))
+         if (ISDIGIT (*format))
            {
              n = read_int (&format);
 
-             if (n > 0 && *format == '$')
+             if (n > 0 && *format == L_('$'))
                {
                  spec->prec_arg = n - 1;
                  *max_ref_arg = MAX (*max_ref_arg, n);
@@ -255,7 +255,7 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
              format = begin;
            }
        }
-      else if (isdigit (*format))
+      else if (ISDIGIT (*format))
        spec->info.prec = read_int (&format);
       else
        /* "%.?" is treated like "%.0?".  */
@@ -268,40 +268,41 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   spec->info.is_short = 0;
   spec->info.is_long = 0;
 
-  while (*format == 'h' || *format == 'l' || *format == 'L' ||
-        *format == 'Z' || *format == 'q')
+  if (*format == L_('h') || *format == L_('l') || *format == L_('L') ||
+      *format == L_('Z') || *format == L_('q'))
     switch (*format++)
       {
-      case 'h':
+      case L_('h'):
        /* int's are short int's.  */
        spec->info.is_short = 1;
        break;
-      case 'l':
-       if (spec->info.is_long)
-         /* A double `l' is equivalent to an `L'.  */
-         spec->info.is_longlong = 1;
-       else
-         /* int's are long int's.  */
-         spec->info.is_long = 1;
-       break;
-      case 'L':
+      case L_('l'):
+       /* int's are long int's.  */
+       spec->info.is_long = 1;
+       if (*format != L_('l'))
+         break;
+       ++format;
+       /* FALLTHROUGH */
+      case L_('L'):
        /* double's are long double's, and int's are long long int's.  */
+      case L_('q'):
+       /* 4.4 uses this for long long.  */
        spec->info.is_long_double = 1;
        break;
-      case 'Z':
+      case L_('Z'):
        /* int's are size_t's.  */
        assert (sizeof(size_t) <= sizeof(unsigned long long int));
        spec->info.is_longlong = sizeof(size_t) > sizeof(unsigned long int);
        spec->info.is_long = sizeof(size_t) > sizeof(unsigned int);
        break;
-      case 'q':
-       /* 4.4 uses this for long long.  */
-       spec->info.is_longlong = 1;
-       break;
       }
 
   /* Get the format specification.  */
-  spec->info.spec = *format++;
+#ifdef THIS_IS_INCOMPATIBLE_WITH_LINUX_LIBC
+  spec->info.spec = (wchar_t) *format++;
+#else
+  spec->info.spec = (char) *format++;
+#endif
   if (__printf_arginfo_table != NULL &&
       __printf_arginfo_table[spec->info.spec] != NULL)
     /* We don't try to get the types for all arguments if the format
@@ -315,12 +316,12 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
 
       switch (spec->info.spec)
        {
-       case 'i':
-       case 'd':
-       case 'u':
-       case 'o':
-       case 'X':
-       case 'x':
+       case L'i':
+       case L'd':
+       case L'u':
+       case L'o':
+       case L'X':
+       case L'x':
          if (spec->info.is_longlong)
            spec->data_arg_type = PA_INT|PA_FLAG_LONG_LONG;
          else if (spec->info.is_long)
@@ -330,30 +331,30 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
          else
            spec->data_arg_type = PA_INT;
          break;
-       case 'e':
-       case 'E':
-       case 'f':
-       case 'g':
-       case 'G':
+       case L'e':
+       case L'E':
+       case L'f':
+       case L'g':
+       case L'G':
          if (spec->info.is_long_double)
            spec->data_arg_type = PA_DOUBLE|PA_FLAG_LONG_DOUBLE;
          else
            spec->data_arg_type = PA_DOUBLE;
          break;
-       case 'c':
+       case L'c':
          spec->data_arg_type = PA_CHAR;
          break;
-       case 's':
+       case L's':
          spec->data_arg_type = PA_STRING;
          break;
-       case 'p':
+       case L'p':
          spec->data_arg_type = PA_POINTER;
          break;
-       case 'n':
+       case L'n':
          spec->data_arg_type = PA_INT|PA_FLAG_PTR;
          break;
 
-       case 'm':
+       case L'm':
        default:
          /* An unknown spec will consume no args.  */
          spec->ndata_args = 0;
@@ -370,14 +371,14 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
        }
     }
 
-  if (spec->info.spec == '\0')
+  if (spec->info.spec == L'\0')
     /* Format ended before this spec was complete.  */
     spec->end_of_fmt = spec->next_fmt = format - 1;
   else
     {
       /* Find the next format spec.  */
       spec->end_of_fmt = format;
-      spec->next_fmt = find_spec (format);
+      spec->next_fmt = find_spec (format, ps);
     }
 
   return nargs;
index 811a9cb..d0756de 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -20,6 +20,50 @@ Cambridge, MA 02139, USA.  */
 #include <printf.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
+
+#ifndef COMPILE_WPRINTF
+# define CHAR_T                char
+# define UCHAR_T       unsigned char
+# define INT_T         int
+# define L_(Str)       Str
+# define ISDIGIT(Ch)   isdigit (Ch)
+
+# ifdef USE_IN_LIBIO
+#  define PUT(F, S, N) _IO_sputn (F, S, N)
+#  define PAD(Padchar)                                                       \
+  if (width > 0)                                                             \
+    done += _IO_padn (s, Padchar, width)
+# else
+#  define PUTC(C, F)   putc (C, F)
+ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
+# define PAD(Padchar)                                                        \
+  if (width > 0)                                                             \
+    { if (__printf_pad (s, Padchar, width) == -1)                            \
+       return -1; else done += width; }
+# endif
+#else
+# define vfprintf      vfwprintf
+# define CHAR_T                wchar_t
+# define UCHAR_T       uwchar_t
+# define INT_T         wint_t
+# define L_(Str)       L##Str
+# define ISDIGIT(Ch)   iswdigit (Ch)
+
+# ifdef USE_IN_LIBIO
+# define PUT(F, S, N)  _IO_sputn (F, S, N)
+# define PAD(Padchar)                                                        \
+  if (width > 0)                                                             \
+    done += _IO_wpadn (s, Padchar, width)
+# else
+#  define PUTC(C, F)   wputc (C, F)
+ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
+# define PAD(Padchar)                                                        \
+  if (width > 0)                                                             \
+    { if (__wprintf_pad (s, Padchar, width) == -1)                           \
+       return -1; else done += width; }
+# endif
+#endif
 
 #include "printf-parse.h"
 
@@ -33,15 +77,17 @@ parse_printf_format (fmt, n, argtypes)
   size_t nargs;                        /* Number of arguments.  */
   size_t max_ref_arg;          /* Highest index used in a positional arg.  */
   struct printf_spec spec;
+  mbstate_t mbstate;
 
   nargs = 0;
   max_ref_arg = 0;
+  mbstate = 0;
 
   /* Search for format specifications.  */
-  for (fmt = find_spec (fmt); *fmt != '\0'; fmt = spec.next_fmt)
+  for (fmt = find_spec (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt)
     {
       /* Parse this spec.  */
-      nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg);
+      nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg, &mbstate);
 
       /* If the width is determined by an argument this is an int.  */
       if (spec.width_arg != -1 && spec.width_arg < n)
index df7747e..6e90154 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -26,6 +26,7 @@ __BEGIN_DECLS
 #define        __need_FILE
 #include <stdio.h>
 #define        __need_size_t
+#define __need_wchar_t
 #include <stddef.h>
 
 
@@ -33,7 +34,11 @@ struct printf_info
 {
   int prec;                    /* Precision.  */
   int width;                   /* Width.  */
-  unsigned char spec;          /* Format letter.  */
+#ifdef THIS_IS_INCOMPATIBLE_WITH_LINUX_LIBC
+  wchar_t spec;                        /* Format letter.  */
+#else
+  char spec;                   /* Format letter.  */
+#endif
   unsigned int is_long_double:1;/* L flag.  */
   unsigned int is_short:1;     /* h flag.  */
   unsigned int is_long:1;      /* l flag.  */
index c177da1..12212b8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -188,7 +188,7 @@ I am ready for my first lesson today.";
   {
     double d = FLT_MIN;
     int niter = 17;
-    
+
     while (niter-- != 0)
       printf ("%.17e\n", d / 2);
     fflush (stdout);
@@ -233,7 +233,18 @@ I am ready for my first lesson today.";
   rfg1 ();
   rfg2 ();
 
-  exit(EXIT_SUCCESS);
+  {
+    char buf[200];
+    int result;
+
+    sprintf(buf,"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
+
+    result = strcmp (buf,
+                    "onetwo                 three                         ");
+
+    puts (result != 0 ? "Test failed!" : "Test ok.");
+    return result != 0;
+  }
 }
 \f
 rfg1 ()
index d6b9f9a..26b31a6 100644 (file)
@@ -13,128 +13,162 @@ Library 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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
-#include <errno.h>
-#include <float.h>
 #include <limits.h>
-#include <math.h>
 #include <printf.h>
 #include <stdarg.h>
 #include <stdlib.h>
-#include <string.h>
-#include <printf.h>
-#include <stddef.h>
+#include <wchar.h>
 #include "_itoa.h"
 #include "../locale/localeinfo.h"
 
+/* This code is shared between the standard stdio implementation found
+   in GNU C library and the libio implementation originally found in
+   GNU libg++.
+
+   Beside this it is also shared between the normal and wide character
+   implementation as defined in ISO/IEC 9899:1990/Amendment 1:1995.  */
+
+#ifndef COMPILE_WPRINTF
+# define CHAR_T                char
+# define UCHAR_T       unsigned char
+# define INT_T         int
+# define L_(Str)       Str
+# define ISDIGIT(Ch)   isdigit (Ch)
+
+# ifdef USE_IN_LIBIO
+#  define PUT(F, S, N) _IO_sputn (F, S, N)
+#  define PAD(Padchar)                                                       \
+  if (width > 0)                                                             \
+    done += _IO_padn (s, Padchar, width)
+# else
+#  define PUTC(C, F)   putc (C, F)
+ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
+# define PAD(Padchar)                                                        \
+  if (width > 0)                                                             \
+    { if (__printf_pad (s, Padchar, width) == -1)                            \
+       return -1; else done += width; }
+# endif
+#else
+# define vfprintf      vfwprintf
+# define CHAR_T                wchar_t
+# define UCHAR_T       uwchar_t
+# define INT_T         wint_t
+# define L_(Str)       L##Str
+# define ISDIGIT(Ch)   iswdigit (Ch)
+
+# ifdef USE_IN_LIBIO
+# define PUT(F, S, N)  _IO_sputn (F, S, N)
+# define PAD(Padchar)                                                        \
+  if (width > 0)                                                             \
+    done += _IO_wpadn (s, Padchar, width)
+# else
+#  define PUTC(C, F)   wputc (C, F)
+ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
+# define PAD(Padchar)                                                        \
+  if (width > 0)                                                             \
+    { if (__wprintf_pad (s, Padchar, width) == -1)                           \
+       return -1; else done += width; }
+# endif
+#endif
+
 /* Include the shared code for parsing the format string.  */
 #include "printf-parse.h"
 
 
-/* This function from the GNU C library is also used in libio.
-   To compile for use in libio, compile with -DUSE_IN_LIBIO.  */
-
 #ifdef USE_IN_LIBIO
 /* This code is for use in libio.  */
-#include <libioP.h>
-#define PUT(f, s, n)   _IO_sputn (f, s, n)
-#define PAD(padchar)                                                         \
-  if (specs[cnt].info.width > 0)                                             \
-    done += _IO_padn (s, padchar, specs[cnt].info.width)
-#define PUTC(c, f)     _IO_putc (c, f)
-#define vfprintf       _IO_vfprintf
-#define size_t         _IO_size_t
-#define FILE           _IO_FILE
-#define va_list                _IO_va_list
-#undef BUFSIZ
-#define BUFSIZ         _IO_BUFSIZ
-#define ARGCHECK(s, format)                                                  \
+# include <libioP.h>
+# define PUTC(C, F)    _IO_putc (C, F)
+# define vfprintf      _IO_vfprintf
+# define size_t                _IO_size_t
+# define FILE          _IO_FILE
+# define va_list       _IO_va_list
+# undef        BUFSIZ
+# define BUFSIZ                _IO_BUFSIZ
+# define ARGCHECK(S, Format)                                                 \
   do                                                                         \
     {                                                                        \
       /* Check file argument for consistence.  */                            \
-      CHECK_FILE (s, -1);                                                    \
-      if (s->_flags & _IO_NO_WRITES || format == NULL)                       \
+      CHECK_FILE (S, -1);                                                    \
+      if (S->_flags & _IO_NO_WRITES || Format == NULL)                       \
        {                                                                     \
          MAYBE_SET_EINVAL;                                                   \
          return -1;                                                          \
        }                                                                     \
     } while (0)
-#define UNBUFFERED_P(s)        ((s)->_IO_file_flags & _IO_UNBUFFERED)
+# define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED)
 #else /* ! USE_IN_LIBIO */
 /* This code is for use in the GNU C library.  */
-#include <stdio.h>
-#define PUTC(c, f)     putc (c, f)
-#define PUT(f, s, n)   fwrite (s, 1, n, f)
-ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
-#define PAD(padchar)                                                         \
-  if (specs[cnt].info.width > 0)                                             \
-    { if (__printf_pad (s, padchar, specs[cnt].info.width) == -1)            \
-       return -1; else done += specs[cnt].info.width; }
-#define ARGCHECK(s, format) \
+# include <stdio.h>
+# define PUT(F, S, N)  fwrite (S, 1, N, F)
+# define ARGCHECK(S, Format)                                                 \
   do                                                                         \
     {                                                                        \
       /* Check file argument for consistence.  */                            \
-      if (!__validfp(s) || !s->__mode.__write || format == NULL)             \
+      if (!__validfp(S) || !S->__mode.__write || Format == NULL)             \
        {                                                                     \
          errno = EINVAL;                                                     \
          return -1;                                                          \
        }                                                                     \
-      if (!s->__seen)                                                        \
+      if (!S->__seen)                                                        \
        {                                                                     \
-         if (__flshfp (s, EOF) == EOF)                                       \
+         if (__flshfp (S, EOF) == EOF)                                       \
            return -1;                                                        \
        }                                                                     \
-    } while (0)
-#define UNBUFFERED_P(s)        ((s)->__buffer == NULL)
+    }                                                                        \
+   while (0)
+# define UNBUFFERED_P(s) ((s)->__buffer == NULL)
 #endif /* USE_IN_LIBIO */
 
 
-#define        outchar(x)                                                            \
+#define        outchar(Ch)                                                           \
   do                                                                         \
     {                                                                        \
-      register const int outc = (x);                                         \
+      register const int outc = (Ch);                                        \
       if (PUTC (outc, s) == EOF)                                             \
        return -1;                                                            \
       else                                                                   \
        ++done;                                                               \
-    } while (0)
+    }                                                                        \
+  while (0)
 
-#define outstring(string, len)                                               \
+#define outstring(String, Len)                                               \
   do                                                                         \
     {                                                                        \
-      if (len > 20)                                                          \
-       {                                                                     \
-         if (PUT (s, string, len) != len)                                    \
-           return -1;                                                        \
-         done += len;                                                        \
-       }                                                                     \
-      else                                                                   \
-       {                                                                     \
-         register const char *cp = string;                                   \
-         register int l = len;                                               \
-         while (l-- > 0)                                                     \
-           outchar (*cp++);                                                  \
-       }                                                                     \
-    } while (0)
+      if (PUT (s, String, Len) != Len)                                       \
+       return -1;                                                            \
+      done += Len;                                                           \
+    }                                                                        \
+  while (0)
 
-/* Helper function to provide temporary buffering for unbuffered streams.  */
-static int buffered_vfprintf __P ((FILE *stream, const char *fmt, va_list));
+/* For handling long_double and longlong we use the same flag.  */
+#ifndef is_longlong
+# define is_longlong is_long_double
+#endif
+
+
+/* Global variables.  */
+static const char null[] = "(null)";
 
-static printf_function printf_unknown;
 
-extern printf_function **__printf_function_table;
+/* Helper function to provide temporary buffering for unbuffered streams.  */
+static int buffered_vfprintf __P ((FILE *stream, const CHAR_T *fmt, va_list));
+
+/* Handle unknown format specifier.  */
+static int printf_unknown __P ((FILE *, const struct printf_info *,
+                               const void *const *));
 
-static char *group_number __P ((char *, char *, const char *, wchar_t));
+/* Group digits of number string.  */
+static char *group_number __P ((CHAR_T *, CHAR_T *, const CHAR_T *, wchar_t));
 
 
+/* The function itself.  */
 int
-vfprintf (s, format, ap)
-    register FILE *s;
-    const char *format;
-    va_list ap;
+vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 {
   /* The character used as thousands separator.  */
   wchar_t thousands_sep;
@@ -142,35 +176,613 @@ vfprintf (s, format, ap)
   /* The string describing the size of groups of digits.  */
   const char *grouping;
 
-  /* Array with information about the needed arguments.  This has to be
-     dynamically extendable.  */
-  size_t nspecs;
-  size_t nspecs_max;
-  struct printf_spec *specs;
+  /* Place to accumulate the result.  */
+  int done;
 
-  /* The number of arguments the format string requests.  This will
-     determine the size of the array needed to store the argument
-     attributes.  */
-  size_t nargs;
-  int *args_type;
-  union printf_arg *args_value;
-
-  /* Positional parameters refer to arguments directly.  This could also
-     determine the maximum number of arguments.  Track the maximum number.  */
-  size_t max_ref_arg;
+  /* Current character in format string.  */
+  const UCHAR_T *f;
 
   /* End of leading constant string.  */
-  const char *lead_str_end;
+  const UCHAR_T *lead_str_end;
+
+  /* Points to next format specifier.  */
+  const UCHAR_T *end_of_spec;
+
+  /* Buffer intermediate results.  */
+  char work_buffer[1000];
+#define workend (&work_buffer[sizeof (work_buffer) - 1])
+
+  /* State for restartable multibyte character handling functions.  */
+  mbstate_t mbstate;
+
+  /* We have to save the original argument pointer.  */
+  va_list ap_save;
 
-  /* Number of characters written.  */
-  register size_t done = 0;
+  /* Count number of specifiers we already processed.  */
+  int nspecs_done;
+
+
+  /* This table maps a character into a number representing a
+     class.  In each step there is a destination label for each
+     class.  */
+  static const int jump_table[] =
+  {
+    /* ' ' */  1,            0,            0, /* '#' */  4,
+              0, /* '%' */ 14,            0, /* '\''*/  6,
+              0,            0, /* '*' */  7, /* '+' */  2,
+              0, /* '-' */  3, /* '.' */  9,            0,
+    /* '0' */  5, /* '1' */  8, /* '2' */  8, /* '3' */  8,
+    /* '4' */  8, /* '5' */  8, /* '6' */  8, /* '7' */  8,
+    /* '8' */  8, /* '9' */  8,            0,            0,
+              0,            0,            0,            0,
+              0,            0,            0,            0,
+              0, /* 'E' */ 19,            0, /* 'G' */ 19,
+              0,            0,            0,            0,
+    /* 'L' */ 12,            0,            0,            0,
+              0,            0,            0,            0,
+              0,            0,            0,            0,
+    /* 'X' */ 18,            0, /* 'Z' */ 13,            0,
+              0,            0,            0,            0,
+              0,            0,            0, /* 'c' */ 20,
+    /* 'd' */ 15, /* 'e' */ 19, /* 'f' */ 19, /* 'g' */ 19,
+    /* 'h' */ 10, /* 'i' */ 15,            0,            0,
+    /* 'l' */ 11, /* 'm' */ 24, /* 'n' */ 23, /* 'o' */ 17,
+    /* 'p' */ 22, /* 'q' */ 12,            0, /* 's' */ 21,
+              0, /* 'u' */ 16,            0,            0,
+    /* 'x' */ 18
+  };
+
+#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < ' ' || (Ch) > 'x')
+#define CHAR_CLASS(Ch) (jump_table[(int) (Ch) - ' '])
+#define JUMP(ChExpr, table)                                                  \
+      do                                                                     \
+       {                                                                     \
+         const void *ptr;                                                    \
+         spec = (ChExpr);                                                    \
+         ptr = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown)                 \
+           : table[CHAR_CLASS (spec)];                                       \
+         goto *ptr;                                                          \
+       }                                                                     \
+      while (0)
+
+#define STEP0_3_TABLE                                                        \
+    /* Step 0: at the beginning.  */                                         \
+    static const void *step0_jumps[25] =                                     \
+    {                                                                        \
+      REF (form_unknown),                                                    \
+      REF (flag_space),                /* for ' ' */                                 \
+      REF (flag_plus),         /* for '+' */                                 \
+      REF (flag_minus),                /* for '-' */                                 \
+      REF (flag_hash),         /* for '<hash>' */                            \
+      REF (flag_zero),         /* for '0' */                                 \
+      REF (flag_quote),                /* for '\'' */                                \
+      REF (width_asterics),    /* for '*' */                                 \
+      REF (width),             /* for '1'...'9' */                           \
+      REF (precision),         /* for '.' */                                 \
+      REF (mod_half),          /* for 'h' */                                 \
+      REF (mod_long),          /* for 'l' */                                 \
+      REF (mod_longlong),      /* for 'L', 'q' */                            \
+      REF (mod_size_t),                /* for 'Z' */                                 \
+      REF (form_percent),      /* for '%' */                                 \
+      REF (form_integer),      /* for 'd', 'i' */                            \
+      REF (form_unsigned),     /* for 'u' */                                 \
+      REF (form_octal),                /* for 'o' */                                 \
+      REF (form_hexa),         /* for 'X', 'x' */                            \
+      REF (form_float),                /* for 'E', 'e', 'f', 'G', 'g' */             \
+      REF (form_character),    /* for 'c' */                                 \
+      REF (form_string),       /* for 's' */                                 \
+      REF (form_pointer),      /* for 'p' */                                 \
+      REF (form_number),       /* for 'n' */                                 \
+      REF (form_strerror)      /* for 'm' */                                 \
+    };                                                                       \
+    /* Step 1: after processing width.  */                                   \
+    static const void *step1_jumps[25] =                                     \
+    {                                                                        \
+      REF (form_unknown),                                                    \
+      REF (form_unknown),      /* for ' ' */                                 \
+      REF (form_unknown),      /* for '+' */                                 \
+      REF (form_unknown),      /* for '-' */                                 \
+      REF (form_unknown),      /* for '<hash>' */                            \
+      REF (form_unknown),      /* for '0' */                                 \
+      REF (form_unknown),      /* for '\'' */                                \
+      REF (form_unknown),      /* for '*' */                                 \
+      REF (form_unknown),      /* for '1'...'9' */                           \
+      REF (precision),         /* for '.' */                                 \
+      REF (mod_half),          /* for 'h' */                                 \
+      REF (mod_long),          /* for 'l' */                                 \
+      REF (mod_longlong),      /* for 'L', 'q' */                            \
+      REF (mod_size_t),                /* for 'Z' */                                 \
+      REF (form_percent),      /* for '%' */                                 \
+      REF (form_integer),      /* for 'd', 'i' */                            \
+      REF (form_unsigned),     /* for 'u' */                                 \
+      REF (form_octal),                /* for 'o' */                                 \
+      REF (form_hexa),         /* for 'X', 'x' */                            \
+      REF (form_float),                /* for 'E', 'e', 'f', 'G', 'g' */             \
+      REF (form_character),    /* for 'c' */                                 \
+      REF (form_string),       /* for 's' */                                 \
+      REF (form_pointer),      /* for 'p' */                                 \
+      REF (form_number),       /* for 'n' */                                 \
+      REF (form_strerror)      /* for 'm' */                                 \
+    };                                                                       \
+    /* Step 2: after processing precision.  */                               \
+    static const void *step2_jumps[25] =                                     \
+    {                                                                        \
+      REF (form_unknown),                                                    \
+      REF (form_unknown),      /* for ' ' */                                 \
+      REF (form_unknown),      /* for '+' */                                 \
+      REF (form_unknown),      /* for '-' */                                 \
+      REF (form_unknown),      /* for '<hash>' */                            \
+      REF (form_unknown),      /* for '0' */                                 \
+      REF (form_unknown),      /* for '\'' */                                \
+      REF (form_unknown),      /* for '*' */                                 \
+      REF (form_unknown),      /* for '1'...'9' */                           \
+      REF (form_unknown),      /* for '.' */                                 \
+      REF (mod_half),          /* for 'h' */                                 \
+      REF (mod_long),          /* for 'l' */                                 \
+      REF (mod_longlong),      /* for 'L', 'q' */                            \
+      REF (mod_size_t),                /* for 'Z' */                                 \
+      REF (form_percent),      /* for '%' */                                 \
+      REF (form_integer),      /* for 'd', 'i' */                            \
+      REF (form_unsigned),     /* for 'u' */                                 \
+      REF (form_octal),                /* for 'o' */                                 \
+      REF (form_hexa),         /* for 'X', 'x' */                            \
+      REF (form_float),                /* for 'E', 'e', 'f', 'G', 'g' */             \
+      REF (form_character),    /* for 'c' */                                 \
+      REF (form_string),       /* for 's' */                                 \
+      REF (form_pointer),      /* for 'p' */                                 \
+      REF (form_number),       /* for 'n' */                                 \
+      REF (form_strerror)      /* for 'm' */                                 \
+    };                                                                       \
+    /* Step 3: after processing first 'l' modifier.  */                              \
+    static const void *step3_jumps[25] =                                     \
+    {                                                                        \
+      REF (form_unknown),                                                    \
+      REF (form_unknown),      /* for ' ' */                                 \
+      REF (form_unknown),      /* for '+' */                                 \
+      REF (form_unknown),      /* for '-' */                                 \
+      REF (form_unknown),      /* for '<hash>' */                            \
+      REF (form_unknown),      /* for '0' */                                 \
+      REF (form_unknown),      /* for '\'' */                                \
+      REF (form_unknown),      /* for '*' */                                 \
+      REF (form_unknown),      /* for '1'...'9' */                           \
+      REF (form_unknown),      /* for '.' */                                 \
+      REF (form_unknown),      /* for 'h' */                                 \
+      REF (mod_longlong),      /* for 'l' */                                 \
+      REF (form_unknown),      /* for 'L', 'q' */                            \
+      REF (form_unknown),      /* for 'Z' */                                 \
+      REF (form_percent),      /* for '%' */                                 \
+      REF (form_integer),      /* for 'd', 'i' */                            \
+      REF (form_unsigned),     /* for 'u' */                                 \
+      REF (form_octal),                /* for 'o' */                                 \
+      REF (form_hexa),         /* for 'X', 'x' */                            \
+      REF (form_float),                /* for 'E', 'e', 'f', 'G', 'g' */             \
+      REF (form_character),    /* for 'c' */                                 \
+      REF (form_string),       /* for 's' */                                 \
+      REF (form_pointer),      /* for 'p' */                                 \
+      REF (form_number),       /* for 'n' */                                 \
+      REF (form_strerror)      /* for 'm' */                                 \
+    }
 
-  /* Running pointer through format string.  */
-  const char *f;
+#define STEP4_TABLE                                                          \
+    /* Step 4: processing format specifier.  */                                      \
+    static const void *step4_jumps[25] =                                     \
+    {                                                                        \
+      REF (form_unknown),                                                    \
+      REF (form_unknown),      /* for ' ' */                                 \
+      REF (form_unknown),      /* for '+' */                                 \
+      REF (form_unknown),      /* for '-' */                                 \
+      REF (form_unknown),      /* for '<hash>' */                            \
+      REF (form_unknown),      /* for '0' */                                 \
+      REF (form_unknown),      /* for '\'' */                                \
+      REF (form_unknown),      /* for '*' */                                 \
+      REF (form_unknown),      /* for '1'...'9' */                           \
+      REF (form_unknown),      /* for '.' */                                 \
+      REF (form_unknown),      /* for 'h' */                                 \
+      REF (form_unknown),      /* for 'l' */                                 \
+      REF (form_unknown),      /* for 'L', 'q' */                            \
+      REF (form_unknown),      /* for 'Z' */                                 \
+      REF (form_percent),      /* for '%' */                                 \
+      REF (form_integer),      /* for 'd', 'i' */                            \
+      REF (form_unsigned),     /* for 'u' */                                 \
+      REF (form_octal),                /* for 'o' */                                 \
+      REF (form_hexa),         /* for 'X', 'x' */                            \
+      REF (form_float),                /* for 'E', 'e', 'f', 'G', 'g' */             \
+      REF (form_character),    /* for 'c' */                                 \
+      REF (form_string),       /* for 's' */                                 \
+      REF (form_pointer),      /* for 'p' */                                 \
+      REF (form_number),       /* for 'n' */                                 \
+      REF (form_strerror)      /* for 'm' */                                 \
+    }
 
-  /* Just a counter.  */
-  int cnt;
 
+#define process_arg(fspec)                                                   \
+      /* Start real work.  We know about all flag and modifiers and          \
+        now process the wanted format specifier.  */                         \
+    LABEL (form_percent):                                                    \
+      /* Write a literal "%".  */                                            \
+      outchar ('%');                                                         \
+      break;                                                                 \
+                                                                             \
+    LABEL (form_integer):                                                    \
+      /* Signed decimal integer.  */                                         \
+      base = 10;                                                             \
+                                                                             \
+      if (is_longlong)                                                       \
+       {                                                                     \
+         long long int signed_number;                                        \
+                                                                             \
+         signed_number = va_arg (ap, long long int);                         \
+                                                                             \
+         is_negative = signed_number < 0;                                    \
+         number.longlong = is_negative ? (- signed_number) : signed_number;  \
+                                                                             \
+         goto LABEL (longlong_number);                                       \
+       }                                                                     \
+      else                                                                   \
+       {                                                                     \
+         long int signed_number;                                             \
+                                                                             \
+         if (is_long)                                                        \
+           signed_number = va_arg (ap, long int);                            \
+         else  /* `short int' will be promoted to `int'.  */                 \
+           signed_number = va_arg (ap, int);                                 \
+                                                                             \
+         is_negative = signed_number < 0;                                    \
+         number.word = is_negative ? (- signed_number) : signed_number;      \
+                                                                             \
+         goto LABEL (number);                                                \
+       }                                                                     \
+      /* NOTREACHED */                                                       \
+                                                                             \
+    LABEL (form_unsigned):                                                   \
+      /* Unsigned decimal integer.  */                                       \
+      base = 10;                                                             \
+      goto LABEL (unsigned_number);                                          \
+      /* NOTREACHED */                                                       \
+                                                                             \
+    LABEL (form_octal):                                                              \
+      /* Unsigned octal integer.  */                                         \
+      base = 8;                                                                      \
+      goto LABEL (unsigned_number);                                          \
+      /* NOTREACHED */                                                       \
+                                                                             \
+    LABEL (form_hexa):                                                       \
+      /* Unsigned hexadecimal integer.  */                                   \
+      base = 16;                                                             \
+                                                                             \
+    LABEL (unsigned_number):     /* Unsigned number of base BASE.  */        \
+                                                                             \
+      /* ANSI specifies the `+' and ` ' flags only for signed                \
+        conversions.  */                                                     \
+      is_negative = 0;                                                       \
+      showsign = 0;                                                          \
+      space = 0;                                                             \
+                                                                             \
+      if (is_longlong)                                                       \
+       {                                                                     \
+         number.longlong = va_arg (ap, unsigned long long int);              \
+                                                                             \
+       LABEL (longlong_number):                                              \
+         if (prec < 0)                                                       \
+           /* Supply a default precision if none was given.  */              \
+           prec = 1;                                                         \
+         else                                                                \
+           /* We have to take care for the '0' flag.  If a precision         \
+              is given it must be ignored.  */                               \
+           pad = ' ';                                                        \
+                                                                             \
+         /* If the precision is 0 and the number is 0 nothing has to         \
+            be written for the number.  */                                   \
+         if (prec == 0 && number.longlong == 0)                              \
+           string = workend;                                                 \
+         else                                                                \
+           {                                                                 \
+             /* Put the number in WORK.  */                                  \
+             string = _itoa (number.longlong, workend + 1, base,             \
+                             spec == 'X');                                   \
+             string -= 1;                                                    \
+             if (group && grouping)                                          \
+               string = group_number (string, workend, grouping,             \
+                                      thousands_sep);                        \
+           }                                                                 \
+         /* Simply further test for num != 0.  */                            \
+         number.word = number.longlong != 0;                                 \
+       }                                                                     \
+      else                                                                   \
+       {                                                                     \
+         if (is_long)                                                        \
+           number.word = va_arg (ap, unsigned long int);                     \
+         else                                                                \
+           number.word = va_arg (ap, unsigned int); /* Promoted.  */         \
+                                                                             \
+       LABEL (number):                                                       \
+         if (prec < 0)                                                       \
+           /* Supply a default precision if none was given.  */              \
+           prec = 1;                                                         \
+         else                                                                \
+           /* We have to take care for the '0' flag.  If a precision         \
+              is given it must be ignored.  */                               \
+           pad = ' ';                                                        \
+                                                                             \
+         /* If the precision is 0 and the number is 0 nothing has to         \
+            be written for the number.  */                                   \
+         if (prec == 0 && number.word == 0)                                  \
+           string = workend;                                                 \
+         else                                                                \
+           {                                                                 \
+             /* Put the number in WORK.  */                                  \
+             string = _itoa_word (number.word, workend + 1, base,            \
+                                  spec == 'X');                              \
+             string -= 1;                                                    \
+             if (group && grouping)                                          \
+               string = group_number (string, workend, grouping,             \
+                                      thousands_sep);                        \
+           }                                                                 \
+       }                                                                     \
+                                                                             \
+      prec -= workend - string;                                                      \
+                                                                             \
+      if (prec > 0)                                                          \
+       /* Add zeros to the precision.  */                                    \
+       while (prec-- > 0)                                                    \
+         *string-- = '0';                                                    \
+      else if (number.word != 0 && alt && base == 8)                         \
+       /* Add octal marker.  */                                              \
+       *string-- = '0';                                                      \
+                                                                             \
+      if (!left)                                                             \
+       {                                                                     \
+         width -= workend - string;                                          \
+                                                                             \
+         if (number.word != 0 && alt && base == 16)                          \
+           /* Account for 0X hex marker.  */                                 \
+           width -= 2;                                                       \
+                                                                             \
+         if (is_negative || showsign || space)                               \
+           --width;                                                          \
+                                                                             \
+         if (pad == '0')                                                     \
+           {                                                                 \
+             while (width-- > 0)                                             \
+               *string-- = '0';                                              \
+                                                                             \
+             if (number.word != 0 && alt && base == 16)                      \
+               {                                                             \
+                 *string-- = spec;                                           \
+                 *string-- = '0';                                            \
+               }                                                             \
+                                                                             \
+             if (is_negative)                                                \
+               *string-- = '-';                                              \
+             else if (showsign)                                              \
+               *string-- = '+';                                              \
+             else if (space)                                                 \
+               *string-- = ' ';                                              \
+           }                                                                 \
+         else                                                                \
+           {                                                                 \
+             if (number.word != 0 && alt && base == 16)                      \
+               {                                                             \
+                 *string-- = spec;                                           \
+                 *string-- = '0';                                            \
+               }                                                             \
+                                                                             \
+             if (is_negative)                                                \
+               *string-- = '-';                                              \
+             else if (showsign)                                              \
+               *string-- = '+';                                              \
+             else if (space)                                                 \
+               *string-- = ' ';                                              \
+                                                                             \
+             while (width-- > 0)                                             \
+               *string-- = ' ';                                              \
+           }                                                                 \
+                                                                             \
+         outstring (string + 1, workend - string);                           \
+                                                                             \
+         break;                                                              \
+       }                                                                     \
+      else                                                                   \
+       {                                                                     \
+         if (number.word != 0 && alt && base == 16)                          \
+           {                                                                 \
+             *string-- = spec;                                               \
+             *string-- = '0';                                                \
+           }                                                                 \
+                                                                             \
+         if (is_negative)                                                    \
+           *string-- = '-';                                                  \
+         else if (showsign)                                                  \
+           *string-- = '+';                                                  \
+         else if (space)                                                     \
+           *string-- = ' ';                                                  \
+                                                                             \
+         width -= workend - string;                                          \
+         outstring (string + 1, workend - string);                           \
+                                                                             \
+         PAD (' ');                                                          \
+         break;                                                              \
+       }                                                                     \
+                                                                             \
+    LABEL (form_float):                                                              \
+      {                                                                              \
+       /* Floating-point number.  This is handled by printf_fp.c.  */        \
+       extern int __printf_fp __P ((FILE *, const struct printf_info *,      \
+                                    const void **const));                    \
+       const void *ptr;                                                      \
+       int function_done;                                                    \
+                                                                             \
+       if (is_long_double)                                                   \
+         the_arg.pa_long_double = va_arg (ap, long double);                  \
+       else                                                                  \
+         the_arg.pa_double = va_arg (ap, double);                            \
+                                                                             \
+       ptr = (const void *) &the_arg;                                        \
+                                                                             \
+       if (fspec == NULL)                                                    \
+         {                                                                   \
+           struct printf_info info = { prec: prec,                           \
+                                       width: width,                         \
+                                       spec: spec,                           \
+                                       is_long_double: is_long_double,       \
+                                       is_short: is_short,                   \
+                                       is_long: is_long,                     \
+                                       alt: alt,                             \
+                                       space: space,                         \
+                                       left: left,                           \
+                                       showsign: showsign,                   \
+                                       group: group,                         \
+                                       pad: pad };                           \
+                                                                             \
+           function_done = __printf_fp (s, &info, &ptr);                     \
+         }                                                                   \
+       else                                                                  \
+         function_done = __printf_fp (s, &fspec->info, &ptr);                \
+                                                                             \
+       if (function_done < 0)                                                \
+         /* Error in print handler.  */                                      \
+         return -1;                                                          \
+                                                                             \
+       done += function_done;                                                \
+      }                                                                              \
+      break;                                                                 \
+                                                                             \
+    LABEL (form_character):                                                  \
+      /* Character.  */                                                              \
+      --width; /* Account for the character itself.  */                      \
+      if (!left)                                                             \
+       PAD (' ');                                                            \
+      outchar ((unsigned char) va_arg (ap, int));      /* Promoted.  */      \
+      if (left)                                                                      \
+       PAD (' ');                                                            \
+      break;                                                                 \
+                                                                             \
+    LABEL (form_string):                                                     \
+      {                                                                              \
+       size_t len;                                                           \
+                                                                             \
+       /* The string argument could in fact be `char *' or `wchar_t *'.      \
+          But this should not make a difference here.  */                    \
+       string = (char *) va_arg (ap, const char *);                          \
+                                                                             \
+       /* Entry point for printing other strings.  */                        \
+      LABEL (print_string):                                                  \
+                                                                             \
+       if (string == NULL)                                                   \
+         {                                                                   \
+           /* Write "(null)" if there's space.  */                           \
+           if (prec == -1 || prec >= (int) sizeof (null) - 1)                \
+             {                                                               \
+               string = (char *) null;                                       \
+               len = sizeof (null) - 1;                                      \
+             }                                                               \
+           else                                                              \
+             {                                                               \
+               string = (char *) "";                                         \
+               len = 0;                                                      \
+             }                                                               \
+         }                                                                   \
+       else if (!is_long)                                                    \
+         {                                                                   \
+           if (prec != -1)                                                   \
+             {                                                               \
+               /* Search for the end of the string, but don't search past    \
+                  the length specified by the precision.  */                 \
+               const char *end = memchr (string, '\0', prec);                \
+               if (end)                                                      \
+                 len = end - string;                                         \
+               else                                                          \
+                 len = prec;                                                 \
+             }                                                               \
+           else                                                              \
+             len = strlen (string);                                          \
+         }                                                                   \
+       else                                                                  \
+         {                                                                   \
+           const wchar_t *s2 = (const wchar_t *) string;                     \
+           mbstate_t mbstate = 0;                                            \
+                                                                             \
+           len = wcsrtombs (NULL, &s2, prec != -1 ? prec : UINT_MAX,         \
+                            &mbstate);                                       \
+           if (len == (size_t) -1)                                           \
+             /* Illegal wide-character string.  */                           \
+             return -1;                                                      \
+                                                                             \
+           s2 = (const wchar_t *) string;                                    \
+           mbstate = 0;                                                      \
+           string = alloca (len + 1);                                        \
+           (void) wcsrtombs (string, &s2, prec != -1 ? prec : UINT_MAX,      \
+                             &mbstate);                                      \
+         }                                                                   \
+                                                                             \
+       if ((width -= len) < 0)                                               \
+         {                                                                   \
+           outstring (string, len);                                          \
+           break;                                                            \
+         }                                                                   \
+                                                                             \
+       if (!left)                                                            \
+         PAD (' ');                                                          \
+       outstring (string, len);                                              \
+       if (left)                                                             \
+         PAD (' ');                                                          \
+      }                                                                              \
+      break;                                                                 \
+                                                                             \
+    LABEL (form_pointer):                                                    \
+      /* Generic pointer.  */                                                \
+      {                                                                              \
+       const void *ptr;                                                      \
+       ptr = va_arg (ap, void *);                                            \
+       if (ptr != NULL)                                                      \
+         {                                                                   \
+           /* If the pointer is not NULL, write it as a %#x spec.  */        \
+           base = 16;                                                        \
+           number.word = (unsigned long int) ptr;                            \
+           is_negative = 0;                                                  \
+           alt = 1;                                                          \
+           group = 0;                                                        \
+           spec = 'x';                                                       \
+           goto LABEL (number);                                              \
+         }                                                                   \
+       else                                                                  \
+         {                                                                   \
+           /* Write "(nil)" for a nil pointer.  */                           \
+           string = (char *) "(nil)";                                        \
+           /* Make sure the full string "(nil)" is printed.  */              \
+           if (prec < 5)                                                     \
+             prec = 5;                                                       \
+           is_long = 0;        /* This is no wide-char string.  */           \
+           goto LABEL (print_string);                                        \
+         }                                                                   \
+      }                                                                              \
+      /* NOTREACHED */                                                       \
+                                                                             \
+    LABEL (form_number):                                                     \
+      /* Answer the count of characters written.  */                         \
+      if (is_longlong)                                                       \
+       *(long long int *) va_arg (ap, void *) = done;                        \
+      else if (is_long)                                                              \
+       *(long int *) va_arg (ap, void *) = done;                             \
+      else if (!is_short)                                                    \
+       *(int *) va_arg (ap, void *) = done;                                  \
+      else                                                                   \
+       *(short int *) va_arg (ap, void *) = done;                            \
+      break;                                                                 \
+                                                                             \
+    LABEL (form_strerror):                                                   \
+      /* Print description of error ERRNO.  */                               \
+      {                                                                              \
+       extern char *_strerror_internal __P ((int, char *buf, size_t));       \
+                                                                             \
+       string = (char *)                                                     \
+         _strerror_internal (errno, work_buffer, sizeof work_buffer);        \
+      }                                                                              \
+      is_long = 0;             /* This is no wide-char string.  */           \
+      goto LABEL (print_string)
+
+
+  /* Sanity check of arguments.  */
   ARGCHECK (s, format);
 
   if (UNBUFFERED_P (s))
@@ -178,101 +790,326 @@ vfprintf (s, format, ap)
        for the stream and then call us again.  */
     return buffered_vfprintf (s, format, ap);
 
-  /* Reset multibyte characters to their initial state.  */
-  (void) mblen ((char *) NULL, 0);
+  /* Initialize local variables.  */
+  done = 0;
+  grouping = (const char *) -1;
+  mbstate = 0;
+  ap_save = ap;
+  nspecs_done = 0;
 
-  /* Figure out the thousands separator character.  */
-  if (mbtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
-              strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
-    thousands_sep = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
-  grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
-  if (*grouping == '\0' || *grouping == CHAR_MAX || thousands_sep == L'\0')
-    grouping = NULL;
+  /* Find the first format specifier.  */
+  f = lead_str_end = find_spec (format, &mbstate);
 
-  nspecs_max = 32;             /* A more or less arbitrary start value.  */
-  specs = alloca (nspecs_max * sizeof (struct printf_spec));
-  nspecs = 0;
-  nargs = 0;
-  max_ref_arg = 0;
+  /* Write the literal text before the first format.  */
+  outstring ((const UCHAR_T *) format,
+            lead_str_end - (const UCHAR_T *) format);
 
-  /* Find the first format specifier.  */
-  lead_str_end = find_spec (format);
+  /* If we only have to print a simple string, return now.  */
+  if (*f == L_('\0'))
+    return done;
 
-  for (f = lead_str_end; *f != '\0'; f = specs[nspecs++].next_fmt)
+  /* Process whole format string.  */
+  do
     {
-      if (nspecs >= nspecs_max)
+#define REF(Name) &&do_##Name
+#define LABEL(Name) do_##Name
+      STEP0_3_TABLE;
+      STEP4_TABLE;
+
+      int is_negative; /* Flag for negative number.  */
+      union
+      {
+       unsigned long long int longlong;
+       unsigned long int word;
+      } number;
+      int base;
+      union printf_arg the_arg;
+      char *string;    /* Pointer to argument string.  */
+      int alt = 0;     /* Alternate format.  */
+      int space = 0;   /* Use space prefix if no sign is needed.  */
+      int left = 0;    /* Left-justify output.  */
+      int showsign = 0;        /* Always begin with plus or minus sign.  */
+      int group = 0;   /* Print numbers according grouping rules.  */
+      int is_long_double = 0; /* Argument is long double/ long long int.  */
+      int is_short = 0;        /* Argument is long int.  */
+      int is_long = 0; /* Argument is short int.  */
+      int width = 0;   /* Width of output; 0 means none specified.  */
+      int prec = -1;   /* Precision of output; -1 means none specified.  */
+      char pad = ' ';  /* Padding character.  */
+      CHAR_T spec;
+
+      /* Get current character in format string.  */
+      JUMP (*++f, step0_jumps);
+
+      /* ' ' flag.  */
+    LABEL (flag_space):
+      space = 1;
+      JUMP (*++f, step0_jumps);
+
+      /* '+' flag.  */
+    LABEL (flag_plus):
+      showsign = 1;
+      JUMP (*++f, step0_jumps);
+
+      /* The '-' flag.  */
+    LABEL (flag_minus):
+      left = 1;
+      pad = L_(' ');
+      JUMP (*++f, step0_jumps);
+
+      /* The '#' flag.  */
+    LABEL (flag_hash):
+      alt = 1;
+      JUMP (*++f, step0_jumps);
+
+      /* The '0' flag.  */
+    LABEL (flag_zero):
+      if (!left)
+       pad = L_('0');
+      JUMP (*++f, step0_jumps);
+
+      /* The '\'' flag.  */
+    LABEL (flag_quote):
+      group = 1;
+
+      /* XXX Completely wrong.  Use wctob.  */
+      if (grouping == (const char *) -1)
        {
-         /* Extend the array of format specifiers.  */
-         struct printf_spec *old = specs;
-
-         nspecs_max *= 2;
-         specs = alloca (nspecs_max * sizeof (struct printf_spec));
-         if (specs == &old[nspecs])
-           /* Stack grows up, OLD was the last thing allocated; extend it.  */
-           nspecs_max += nspecs_max / 2;
-         else
-           {
-             /* Copy the old array's elements to the new space.  */
-             memcpy (specs, old, nspecs * sizeof (struct printf_spec));
-             if (old == &specs[nspecs])
-               /* Stack grows down, OLD was just below the new SPECS.
-                  We can use that space when the new space runs out.  */
-               nspecs_max += nspecs_max / 2;
-           }
+         /* Figure out the thousands separator character.  */
+         if (mbtowc (&thousands_sep,
+                     _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+                     strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+           thousands_sep = (wchar_t)
+             *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+         grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+         if (*grouping == '\0' || *grouping == CHAR_MAX
+             || thousands_sep == L'\0')
+           grouping = NULL;
        }
+      JUMP (*++f, step0_jumps);
 
-      /* Parse the format specifier.  */
-      nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg);
-    }
+      /* Get width from argument.  */
+    LABEL (width_asterics):
+      {
+       const UCHAR_T *tmp;     /* Temporary value.  */
 
-  /* Determine the number of arguments the format string consumes.  */
-  nargs = MAX (nargs, max_ref_arg);
+       tmp = ++f;
+       if (ISDIGIT (*tmp) && read_int (&tmp) && *tmp == L_('$'))
+         /* The width comes from an positional parameter.  */
+         goto do_positional;
 
-  /* Allocate memory for the argument descriptions.  */
-  args_type = alloca (nargs * sizeof (int));
-  memset (args_type, 0, nargs * sizeof (int));
-  args_value = alloca (nargs * sizeof (union printf_arg));
+       width = va_arg (ap, int);
 
-  /* XXX Could do sanity check here: If any element in ARGS_TYPE is
-     still zero after this loop, format is invalid.  For now we simply
-     use 0 as the value.  */
+       /* Negative width means left justified.  */
+       if (width < 0)
+         {
+           width = -width;
+           pad = L_(' ');
+           left = 1;
+         }
+      }
+      JUMP (*f, step1_jumps);
+
+      /* Given width in format string.  */
+    LABEL (width):
+      width = read_int (&f);
+      if (*f == L_('$'))
+       /* Oh, oh.  The argument comes from an positional parameter.  */
+       goto do_positional;
+      JUMP (*f, step1_jumps);
+
+    LABEL (precision):
+      ++f;
+      if (*f == L_('*'))
+       {
+         const UCHAR_T *tmp;   /* Temporary value.  */
 
-  /* Fill in the types of all the arguments.  */
-  for (cnt = 0; cnt < nspecs; ++cnt)
-    {
-      /* If the width is determined by an argument this is an int.  */
-      if (specs[cnt].width_arg != -1)
-       args_type[specs[cnt].width_arg] = PA_INT;
+         tmp = ++f;
+         if (ISDIGIT (*tmp) && read_int (&tmp) > 0 && *tmp == L_('$'))
+           /* The precision comes from an positional parameter.  */
+           goto do_positional;
 
-      /* If the precision is determined by an argument this is an int.  */
-      if (specs[cnt].prec_arg != -1)
-       args_type[specs[cnt].prec_arg] = PA_INT;
+         prec = va_arg (ap, int);
 
-      switch (specs[cnt].ndata_args)
+         /* If the precision is negative the precision is omitted.  */
+         if (prec < 0)
+           prec = -1;
+       }
+      else if (ISDIGIT (*f))
+       prec = read_int (&f);
+      else
+       prec = 0;
+      JUMP (*f, step2_jumps);
+
+      /* Process 'h' modifier.  No other modifier is allowed to
+        follow.  */
+    LABEL (mod_half):
+      is_short = 1;
+      JUMP (*++f, step4_jumps);
+
+      /* Process 'l' modifier.  There might another 'l' follow.  */
+    LABEL (mod_long):
+      is_long = 1;
+      JUMP (*++f, step3_jumps);
+
+      /* Process 'L', 'q', or 'll' modifier.  No other modifier is
+        allowed to follow.  */
+    LABEL (mod_longlong):
+      is_long_double = 1;
+      JUMP (*++f, step4_jumps);
+
+    LABEL (mod_size_t):
+      is_longlong = sizeof (size_t) > sizeof (unsigned long int);
+      is_long = sizeof (size_t) > sizeof (unsigned int);
+      JUMP (*++f, step4_jumps);
+
+
+      /* Process current format.  */
+      while (1)
        {
-       case 0:                 /* No arguments.  */
-         break;
-       case 1:                 /* One argument; we already have the type.  */
-         args_type[specs[cnt].data_arg] = specs[cnt].data_arg_type;
-         break;
-       default:
-         /* We have more than one argument for this format spec.  We must
-            call the arginfo function again to determine all the types.  */
-         (void) (*__printf_arginfo_table[specs[cnt].info.spec])
-           (&specs[cnt].info,
-            specs[cnt].ndata_args, &args_type[specs[cnt].data_arg]);
-         break;
+         process_arg (((struct printf_spec *) NULL));
+
+       LABEL (form_unknown):
+         if (spec == L_('\0'))
+           /* The format string ended before the specifier is complete.  */
+           return -1;
+
+         /* If we are in the fast loop force entering the complicated
+            one.  */
+         goto do_positional;
        }
+
+      /* Look for next format specifier.  */
+      f = find_spec ((end_of_spec = ++f), &mbstate);
+
+      /* Write the following constant string.  */
+      outstring (end_of_spec, f - end_of_spec);
     }
+  while (*f != L_('\0'));
 
-  /* Now we know all the types and the order.  Fill in the argument values.  */
-  for (cnt = 0; cnt < nargs; ++cnt)
-    switch (args_type[cnt])
+  /* We processed the whole format without any positional parameters.  */
+  return done;
+
+  /* Here starts the more complex loop to handle positional parameters.  */
+do_positional:
+  {
+    /* Array with information about the needed arguments.  This has to
+       be dynamically extendable.  */
+    size_t nspecs = 0;
+    size_t nspecs_max = 32;    /* A more or less arbitrary start value.  */
+    struct printf_spec *specs
+      = alloca (nspecs_max * sizeof (struct printf_spec));
+
+    /* The number of arguments the format string requests.  This will
+       determine the size of the array needed to store the argument
+       attributes.  */
+    size_t nargs = 0;
+    int *args_type;
+    union printf_arg *args_value;
+
+    /* Positional parameters refer to arguments directly.  This could
+       also determine the maximum number of arguments.  Track the
+       maximum number.  */
+    size_t max_ref_arg = 0;
+
+    /* Just a counter.  */
+    int cnt;
+
+
+    if (grouping == (const char *) -1)
       {
+       /* XXX Use wctob.  But this is incompatible for now.  */
+       /* Figure out the thousands separator character.  */
+       if (mbtowc (&thousands_sep,
+                   _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+                   strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+         thousands_sep = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+       grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+       if (*grouping == '\0' || *grouping == CHAR_MAX
+           || thousands_sep == L'\0')
+         grouping = NULL;
+      }
+
+    for (f = lead_str_end; *f != '\0'; f = specs[nspecs++].next_fmt)
+      {
+       if (nspecs >= nspecs_max)
+         {
+           /* Extend the array of format specifiers.  */
+           struct printf_spec *old = specs;
+
+           nspecs_max *= 2;
+           specs = alloca (nspecs_max * sizeof (struct printf_spec));
+
+           if (specs == &old[nspecs])
+             /* Stack grows up, OLD was the last thing allocated;
+                extend it.  */
+             nspecs_max += nspecs_max / 2;
+           else
+             {
+               /* Copy the old array's elements to the new space.  */
+               memcpy (specs, old, nspecs * sizeof (struct printf_spec));
+               if (old == &specs[nspecs])
+                 /* Stack grows down, OLD was just below the new
+                    SPECS.  We can use that space when the new space
+                    runs out.  */
+                 nspecs_max += nspecs_max / 2;
+             }
+         }
+
+       /* Parse the format specifier.  */
+       nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg, NULL);
+      }
+
+    /* Determine the number of arguments the format string consumes.  */
+    nargs = MAX (nargs, max_ref_arg);
+
+    /* Allocate memory for the argument descriptions.  */
+    args_type = alloca (nargs * sizeof (int));
+    memset (args_type, 0, nargs * sizeof (int));
+    args_value = alloca (nargs * sizeof (union printf_arg));
+
+    /* XXX Could do sanity check here: If any element in ARGS_TYPE is
+       still zero after this loop, format is invalid.  For now we
+       simply use 0 as the value.  */
+
+    /* Fill in the types of all the arguments.  */
+    for (cnt = 0; cnt < nspecs; ++cnt)
+      {
+       /* If the width is determined by an argument this is an int.  */
+       if (specs[cnt].width_arg != -1)
+         args_type[specs[cnt].width_arg] = PA_INT;
+
+       /* If the precision is determined by an argument this is an int.  */
+       if (specs[cnt].prec_arg != -1)
+         args_type[specs[cnt].prec_arg] = PA_INT;
+
+       switch (specs[cnt].ndata_args)
+         {
+         case 0:               /* No arguments.  */
+           break;
+         case 1:               /* One argument; we already have the type.  */
+           args_type[specs[cnt].data_arg] = specs[cnt].data_arg_type;
+           break;
+         default:
+           /* We have more than one argument for this format spec.
+              We must call the arginfo function again to determine
+              all the types.  */
+           (void) (*__printf_arginfo_table[specs[cnt].info.spec])
+             (&specs[cnt].info,
+              specs[cnt].ndata_args, &args_type[specs[cnt].data_arg]);
+           break;
+         }
+      }
+
+    /* Now we know all the types and the order.  Fill in the argument
+       values.  */
+    for (cnt = 0, ap = ap_save; cnt < nargs; ++cnt)
+      switch (args_type[cnt])
+       {
 #define T(tag, mem, type)                                                    \
-      case tag:                                                                      \
-       args_value[cnt].mem = va_arg (ap, type);                              \
-       break
+       case tag:                                                             \
+         args_value[cnt].mem = va_arg (ap, type);                            \
+         break
 
        T (PA_CHAR, pa_char, int); /* Promoted.  */
        T (PA_INT|PA_FLAG_SHORT, pa_short_int, int); /* Promoted.  */
@@ -285,349 +1122,126 @@ vfprintf (s, format, ap)
        T (PA_STRING, pa_string, const char *);
        T (PA_POINTER, pa_pointer, void *);
 #undef T
-      default:
-       if ((args_type[cnt] & PA_FLAG_PTR) != 0)
-         args_value[cnt].pa_pointer = va_arg (ap, void *);
-       else
-         args_value[cnt].pa_long_double = 0.0;
-       break;
-      }
-
-  /* Write the literal text before the first format.  */
-  outstring (format, lead_str_end - format);
+       default:
+         if ((args_type[cnt] & PA_FLAG_PTR) != 0)
+           args_value[cnt].pa_pointer = va_arg (ap, void *);
+         else
+           args_value[cnt].pa_long_double = 0.0;
+         break;
+       }
 
-  /* Now walk through all format specifiers and process them.  */
-  for (cnt = 0; cnt < nspecs; ++cnt)
-    {
-      printf_function *function; /* Auxiliary function to do output.  */
-      int is_neg;              /* Decimal integer is negative.  */
-      int base;                        /* Base of a number to be written.  */
-      unsigned long long int num; /* Integral number to be written.  */
-      const char *str;         /* String to be written.  */
-      char errorbuf[1024];      /* Buffer sometimes used by %m.  */
-
-      if (specs[cnt].width_arg != -1)
+    /* Now walk through all format specifiers and process them.  */
+    for (; nspecs_done < nspecs; ++nspecs_done)
+      {
+#undef REF
+#define REF(Name) &&do2_##Name
+#undef LABEL
+#define LABEL(Name) do2_##Name
+       STEP4_TABLE;
+
+       int is_negative;
+       union
        {
-         /* Extract the field width from an argument.  */
-         specs[cnt].info.width = args_value[specs[cnt].width_arg].pa_int;
+         unsigned long long int longlong;
+         unsigned long int word;
+       } number;
+       int base;
+       union printf_arg the_arg;
+       char *string;   /* Pointer to argument string.  */
+
+       /* Fill variables from values in struct.  */
+       int alt = specs[nspecs_done].info.alt;
+       int space = specs[nspecs_done].info.space;
+       int left = specs[nspecs_done].info.left;
+       int showsign = specs[nspecs_done].info.showsign;
+       int group = specs[nspecs_done].info.group;
+       int is_long_double = specs[nspecs_done].info.is_long_double;
+       int is_short = specs[nspecs_done].info.is_short;
+       int is_long = specs[nspecs_done].info.is_long;
+       int width = specs[nspecs_done].info.width;
+       int prec = specs[nspecs_done].info.prec;
+       char pad = specs[nspecs_done].info.pad;
+       CHAR_T spec = specs[nspecs_done].info.spec;
+
+       /* Fill in last information.  */
+       if (specs[nspecs_done].width_arg != -1)
+         {
+           /* Extract the field width from an argument.  */
+           specs[nspecs_done].info.width =
+             args_value[specs[nspecs_done].width_arg].pa_int;
+
+           if (specs[nspecs_done].info.width < 0)
+             /* If the width value is negative left justification is
+                selected and the value is taken as being positive.  */
+             {
+               specs[nspecs_done].info.width *= -1;
+               left = specs[nspecs_done].info.left = 1;
+             }
+           width = specs[nspecs_done].info.width;
+         }
 
-         if (specs[cnt].info.width < 0)
-           /* If the width value is negative left justification is selected
-              and the value is taken as being positive.  */
-           {
-             specs[cnt].info.width = -specs[cnt].info.width;
-             specs[cnt].info.left = 1;
-           }
-       }
+       if (specs[nspecs_done].prec_arg != -1)
+         {
+           /* Extract the precision from an argument.  */
+           specs[nspecs_done].info.prec =
+             args_value[specs[nspecs_done].prec_arg].pa_int;
 
-      if (specs[cnt].prec_arg != -1)
-       {
-         /* Extract the precision from an argument.  */
-         specs[cnt].info.prec = args_value[specs[cnt].prec_arg].pa_int;
+           if (specs[nspecs_done].info.prec < 0)
+             /* If the precision is negative the precision is
+                omitted.  */
+             specs[nspecs_done].info.prec = -1;
 
-         if (specs[cnt].info.prec < 0)
-           /* If the precision is negative the precision is omitted.  */
-           specs[cnt].info.prec = -1;
-       }
+           prec = specs[nspecs_done].info.prec;
+         }
 
-      /* Check for a user-defined handler for this spec.  */
-      function = (__printf_function_table == NULL ? NULL :
-                  __printf_function_table[specs[cnt].info.spec]);
+       /* Process format specifiers.  */
+       while (1)
+         {
+           JUMP (spec, step4_jumps);
 
-      if (function != NULL)
-      use_function:            /* Built-in formats with helpers use this.  */
-       {
-         int function_done;
-         unsigned int i;
-         const void *ptr[specs[cnt].ndata_args];
+           process_arg ((&specs[nspecs_done]));
 
-         /* Fill in an array of pointers to the argument values.  */
-         for (i = 0; i < specs[cnt].ndata_args; ++i)
-           ptr[i] = &args_value[specs[cnt].data_arg + i];
+         LABEL (form_unknown):
+           {
+             extern printf_function **__printf_function_table;
+             int function_done;
+             printf_function *function;
+             unsigned int i;
+             const void **ptr;
 
-         /* Call the function.  */
-         function_done = (*function) (s, &specs[cnt].info, ptr);
+             function =
+               (__printf_function_table == NULL ? NULL :
+                __printf_function_table[specs[nspecs_done].info.spec]);
 
-         /* If an error occured don't do any further work.  */
-         if (function_done < 0)
-           return -1;
+             if (function == NULL)
+               function = &printf_unknown;
 
-         done += function_done;
-       }
-      else
-       switch (specs[cnt].info.spec)
-         {
-         case '%':
-           /* Write a literal "%".  */
-           outchar ('%');
-           break;
-         case 'i':
-         case 'd':
-           {
-             long long int signed_num;
-
-             /* Decimal integer.  */
-             base = 10;
-             if (specs[cnt].info.is_longlong)
-               signed_num = args_value[specs[cnt].data_arg].pa_long_long_int;
-             else if (specs[cnt].info.is_long)
-               signed_num = args_value[specs[cnt].data_arg].pa_long_int;
-             else if (!specs[cnt].info.is_short)
-               signed_num = args_value[specs[cnt].data_arg].pa_int;
-             else
-               signed_num = args_value[specs[cnt].data_arg].pa_short_int;
-
-             is_neg = signed_num < 0;
-             num = is_neg ? (- signed_num) : signed_num;
-             goto number;
-           }
+             ptr = alloca (specs[nspecs_done].ndata_args
+                           * sizeof (const void *));
+
+             /* Fill in an array of pointers to the argument values.  */
+             for (i = 0; i < specs[nspecs_done].ndata_args; ++i)
+               ptr[i] = &args_value[specs[nspecs_done].data_arg + i];
 
-         case 'u':
-           /* Decimal unsigned integer.  */
-            base = 10;
-            goto unsigned_number;
-
-         case 'o':
-            /* Octal unsigned integer.  */
-            base = 8;
-            goto unsigned_number;
-
-          case 'X':
-            /* Hexadecimal unsigned integer.  */
-          case 'x':
-            /* Hex with lower-case digits.  */
-            base = 16;
-
-         unsigned_number:
-            /* Unsigned number of base BASE.  */
-
-            if (specs[cnt].info.is_longlong)
-             num = args_value[specs[cnt].data_arg].pa_u_long_long_int;
-            else if (specs[cnt].info.is_long)
-             num = args_value[specs[cnt].data_arg].pa_u_long_int;
-            else if (!specs[cnt].info.is_short)
-             num = args_value[specs[cnt].data_arg].pa_u_int;
-            else
-             num = args_value[specs[cnt].data_arg].pa_u_short_int;
-
-            /* ANSI only specifies the `+' and
-               ` ' flags for signed conversions.  */
-            is_neg = 0;
-           specs[cnt].info.showsign = 0;
-           specs[cnt].info.space = 0;
-
-         number:
-           /* Number of base BASE.  */
-            {
-              char work[BUFSIZ];
-              char *const workend = &work[sizeof(work) - 1];
-              register char *w;
-
-              if (specs[cnt].info.prec == -1)
-                 /* Supply a default precision if none was given.  */
-                 specs[cnt].info.prec = 1;
-             else
-               /* We have to take care for the '0' flag.  If a
-                  precision is given it must be ignored.  */
-               specs[cnt].info.pad = ' ';
-
-             /* If the precision is 0 and the number is 0 nothing has
-                to be written for the number.  */
-             if (specs[cnt].info.prec == 0 && num == 0)
-               w = workend;
-             else
-               {
-                 /* Put the number in WORK.  */
-                 w = _itoa (num, workend + 1, base,
-                            specs[cnt].info.spec == 'X');
-                 w -= 1;
-                 if (specs[cnt].info.group && grouping)
-                   w = group_number (w, workend, grouping, thousands_sep);
-               }
-              specs[cnt].info.width -= workend - w;
-              specs[cnt].info.prec -= workend - w;
-
-              if (num != 0 && specs[cnt].info.alt && base == 8
-                 && specs[cnt].info.prec <= 0)
-                {
-                 /* Add octal marker.  */
-                  *w-- = '0';
-                  --specs[cnt].info.width;
-                }
-
-              if (specs[cnt].info.prec > 0)
-                {
-                 /* Add zeros to the precision.  */
-                  specs[cnt].info.width -= specs[cnt].info.prec;
-                  while (specs[cnt].info.prec-- > 0)
-                    *w-- = '0';
-                }
-
-              if (num != 0 && specs[cnt].info.alt && base == 16)
-               /* Account for 0X hex marker.  */
-                specs[cnt].info.width -= 2;
-
-              if (is_neg || specs[cnt].info.showsign || specs[cnt].info.space)
-                --specs[cnt].info.width;
-
-              if (!specs[cnt].info.left && specs[cnt].info.pad == ' ')
-                PAD (' ');
-
-              if (is_neg)
-                outchar ('-');
-              else if (specs[cnt].info.showsign)
-                outchar ('+');
-              else if (specs[cnt].info.space)
-                outchar (' ');
-
-              if (num != 0 && specs[cnt].info.alt && base == 16)
-                {
-                  outchar ('0');
-                  outchar (specs[cnt].info.spec);
-                }
-
-              if (!specs[cnt].info.left && specs[cnt].info.pad == '0')
-                PAD ('0');
-
-              /* Write the number.  */
-              while (++w <= workend)
-                outchar (*w);
-
-              if (specs[cnt].info.left)
-                PAD (' ');
-            }
-            break;
-
-          case 'e':
-          case 'E':
-          case 'f':
-          case 'g':
-          case 'G':
-            {
-              /* Floating-point number.  This is handled by printf_fp.c.  */
-              extern printf_function __printf_fp;
-              function = __printf_fp;
-              goto use_function;
-            }
-
-          case 'c':
-            /* Character.  */
-           --specs[cnt].info.width;/* Account for the character itself.  */
-            if (!specs[cnt].info.left)
-             PAD (' ');
-            outchar ((unsigned char) args_value[specs[cnt].data_arg].pa_char);
-            if (specs[cnt].info.left)
-              PAD (' ');
-            break;
-
-          case 's':
-            {
-              static const char null[] = "(null)";
-              size_t len;
-
-             str = args_value[specs[cnt].data_arg].pa_string;
-
-           string:
-
-              if (str == NULL)
-               {
-                 /* Write "(null)" if there's space.  */
-                 if (specs[cnt].info.prec == -1
-                     || specs[cnt].info.prec >= (int) sizeof (null) - 1)
-                   {
-                     str = null;
-                     len = sizeof (null) - 1;
-                   }
-                 else
-                   {
-                     str = "";
-                     len = 0;
-                   }
-               }
-              else if (specs[cnt].info.prec != -1)
-               {
-                 /* Search for the end of the string, but don't search
-                    past the length specified by the precision.  */
-                 const char *end = memchr (str, '\0', specs[cnt].info.prec);
-                 if (end)
-                   len = end - str;
-                 else
-                   len = specs[cnt].info.prec;
-               }
-             else
-               len = strlen (str);
-
-              specs[cnt].info.width -= len;
-
-              if (!specs[cnt].info.left)
-                PAD (' ');
-              outstring (str, len);
-              if (specs[cnt].info.left)
-                PAD (' ');
-            }
-            break;
-
-          case 'p':
-            /* Generic pointer.  */
-            {
-              const void *ptr;
-              ptr = args_value[specs[cnt].data_arg].pa_pointer;
-              if (ptr != NULL)
-                {
-                  /* If the pointer is not NULL, write it as a %#x spec.  */
-                  base = 16;
-                  num = (unsigned long long int) (unsigned long int) ptr;
-                  is_neg = 0;
-                  specs[cnt].info.alt = 1;
-                 specs[cnt].info.spec = 'x';
-                  specs[cnt].info.group = 0;
-                  goto number;
-                }
-              else
-                {
-                  /* Write "(nil)" for a nil pointer.  */
-                  str = "(nil)";
-                 /* Make sure the full string "(nil)" is printed.  */
-                 if (specs[cnt].info.prec < 5)
-                   specs[cnt].info.prec = 5;
-                  goto string;
-                }
-            }
-            break;
-
-          case 'n':
-            /* Answer the count of characters written.  */
-            if (specs[cnt].info.is_longlong)
-             *(long long int *)
-               args_value[specs[cnt].data_arg].pa_pointer = done;
-            else if (specs[cnt].info.is_long)
-             *(long int *)
-               args_value[specs[cnt].data_arg].pa_pointer = done;
-            else if (!specs[cnt].info.is_short)
-             *(int *)
-               args_value[specs[cnt].data_arg].pa_pointer = done;
-            else
-             *(short int *)
-               args_value[specs[cnt].data_arg].pa_pointer = done;
-            break;
-
-          case 'm':
-            {
-              extern char *_strerror_internal __P ((int, char *buf, size_t));
-              str = _strerror_internal (errno, errorbuf, sizeof errorbuf);
-              goto string;
-            }
-
-          default:
-            /* Unrecognized format specifier.  */
-            function = printf_unknown;
-            goto use_function;
+             /* Call the function.  */
+             function_done = (*function) (s, &specs[nspecs_done].info, ptr);
+
+             /* If an error occured we don't have information about #
+                of chars.  */
+             if (function_done < 0)
+               return -1;
+
+             done += function_done;
+           }
+           break;
          }
 
-      /* Write the following constant string.  */
-      outstring (specs[cnt].end_of_fmt,
-                specs[cnt].next_fmt - specs[cnt].end_of_fmt);
-    }
+       /* Write the following constant string.  */
+       outstring (specs[nspecs_done].end_of_fmt,
+                  specs[nspecs_done].next_fmt
+                  - specs[nspecs_done].end_of_fmt);
+      }
+  }
 
   return done;
 }
@@ -636,7 +1250,7 @@ vfprintf (s, format, ap)
 # undef vfprintf
 # ifdef strong_alias
 /* This is for glibc.  */
-strong_alias (_IO_vfprintf, vfprintf)
+strong_alias (_IO_vfprintf, vfprintf);
 # else
 #  if defined __ELF__ || defined __GNU_LIBRARY__
 #   include <gnu-stabs.h>
@@ -646,20 +1260,16 @@ weak_alias (_IO_vfprintf, vfprintf);
 #  endif
 # endif
 #endif
-
-
+\f
 /* Handle an unknown format specifier.  This prints out a canonicalized
    representation of the format spec itself.  */
-
 static int
-printf_unknown (s, info, args)
-  FILE *s;
-  const struct printf_info *info;
-  const void *const *args;
+printf_unknown (FILE *s, const struct printf_info *info,
+               const void *const *args)
+
 {
   int done = 0;
-  char work[BUFSIZ];
-  char *const workend = &work[sizeof(work) - 1];
+  char work_buffer[BUFSIZ];
   register char *w;
 
   outchar ('%');
@@ -679,7 +1289,7 @@ printf_unknown (s, info, args)
 
   if (info->width != 0)
     {
-      w = _itoa (info->width, workend + 1, 10, 0);
+      w = _itoa_word (info->width, workend + 1, 10, 0);
       while (++w <= workend)
        outchar (*w);
     }
@@ -687,7 +1297,7 @@ printf_unknown (s, info, args)
   if (info->prec != -1)
     {
       outchar ('.');
-      w = _itoa (info->prec, workend + 1, 10, 0);
+      w = _itoa_word (info->prec, workend + 1, 10, 0);
       while (++w <= workend)
        outchar (*w);
     }
@@ -700,9 +1310,8 @@ printf_unknown (s, info, args)
 \f
 /* Group the digits according to the grouping rules of the current locale.
    The interpretation of GROUPING is as in `struct lconv' from <locale.h>.  */
-
 static char *
-group_number (char *w, char *workend, const char *grouping,
+group_number (CHAR_T *w, CHAR_T *rear_ptr, const CHAR_T *grouping,
              wchar_t thousands_sep)
 {
   int len;
@@ -717,10 +1326,10 @@ group_number (char *w, char *workend, const char *grouping,
   len = *grouping;
 
   /* Copy existing string so that nothing gets overwritten.  */
-  src = (char *) alloca (workend - w);
-  memcpy (src, w + 1, workend - w);
-  s = &src[workend - w - 1];
-  w = workend;
+  src = (char *) alloca (rear_ptr - w);
+  memcpy (src, w + 1, rear_ptr - w);
+  s = &src[rear_ptr - w - 1];
+  w = rear_ptr;
 
   /* Process all characters in the string.  */
   while (s >= src)
@@ -772,32 +1381,30 @@ _IO_helper_overflow (_IO_FILE *s, int c)
 }
 
 static const struct _IO_jump_t _IO_helper_jumps =
-  {
-    JUMP_INIT_DUMMY,
-    JUMP_INIT (finish, _IO_default_finish),
-    JUMP_INIT (overflow, _IO_helper_overflow),
-    JUMP_INIT (underflow, _IO_default_underflow),
-    JUMP_INIT (uflow, _IO_default_uflow),
-    JUMP_INIT (pbackfail, _IO_default_pbackfail),
-    JUMP_INIT (xsputn, _IO_default_xsputn),
-    JUMP_INIT (xsgetn, _IO_default_xsgetn),
-    JUMP_INIT (seekoff, _IO_default_seekoff),
-    JUMP_INIT (seekpos, _IO_default_seekpos),
-    JUMP_INIT (setbuf, _IO_default_setbuf),
-    JUMP_INIT (sync, _IO_default_sync),
-    JUMP_INIT (doallocate, _IO_default_doallocate),
-    JUMP_INIT (read, _IO_default_read),
-    JUMP_INIT (write, _IO_default_write),
-    JUMP_INIT (seek, _IO_default_seek),
-    JUMP_INIT (close, _IO_default_close),
-    JUMP_INIT (stat, _IO_default_stat)
-  };
+{
+  JUMP_INIT_DUMMY,
+  JUMP_INIT (finish, _IO_default_finish),
+  JUMP_INIT (overflow, _IO_helper_overflow),
+  JUMP_INIT (underflow, _IO_default_underflow),
+  JUMP_INIT (uflow, _IO_default_uflow),
+  JUMP_INIT (pbackfail, _IO_default_pbackfail),
+  JUMP_INIT (xsputn, _IO_default_xsputn),
+  JUMP_INIT (xsgetn, _IO_default_xsgetn),
+  JUMP_INIT (seekoff, _IO_default_seekoff),
+  JUMP_INIT (seekpos, _IO_default_seekpos),
+  JUMP_INIT (setbuf, _IO_default_setbuf),
+  JUMP_INIT (sync, _IO_default_sync),
+  JUMP_INIT (doallocate, _IO_default_doallocate),
+  JUMP_INIT (read, _IO_default_read),
+  JUMP_INIT (write, _IO_default_write),
+  JUMP_INIT (seek, _IO_default_seek),
+  JUMP_INIT (close, _IO_default_close),
+  JUMP_INIT (stat, _IO_default_stat)
+};
 
 static int
-buffered_vfprintf (s, format, args)
-  register _IO_FILE *s;
-  char const *format;
-  _IO_va_list args;
+buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format,
+                  _IO_va_list args)
 {
   char buf[_IO_BUFSIZ];
   struct helper_file helper;
@@ -828,10 +1435,7 @@ buffered_vfprintf (s, format, args)
 #else /* !USE_IN_LIBIO */
 
 static int
-buffered_vfprintf (s, format, args)
-  register FILE *s;
-  char const *format;
-  va_list args;
+buffered_vfprintf (register FILE *s, const CHAR_T *format, va_list args)
 {
   char buf[BUFSIZ];
   int result;
@@ -851,26 +1455,28 @@ buffered_vfprintf (s, format, args)
 
   return result;
 }
-
-
+\f
 /* Pads string with given number of a specified character.
    This code is taken from iopadn.c of the GNU I/O library.  */
 #define PADSIZE 16
-static const char blanks[PADSIZE] =
-{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
-static const char zeroes[PADSIZE] =
-{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+static const CHAR_T blanks[PADSIZE] =
+{ L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '),
+  L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' ') };
+static const CHAR_T zeroes[PADSIZE] =
+{ L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'),
+  L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0') };
 
 ssize_t
-__printf_pad (s, pad, count)
-     FILE *s;
-     char pad;
-     size_t count;
+#ifndef COMPILE_WPRINTF
+__printf_pad (FILE *s, char pad, size_t count)
+#else
+__wprintf_pad (FILE *s, wchar_t pad, size_t count)
+#endif
 {
-  const char *padptr;
+  const CHAR_T *padptr;
   register size_t i;
 
-  padptr = pad == ' ' ? blanks : zeroes;
+  padptr = pad == L_(' ') ? blanks : zeroes;
 
   for (i = count; i >= PADSIZE; i -= PADSIZE)
     if (PUT (s, padptr, PADSIZE) != PADSIZE)
index 3818c81..51dc520 100644 (file)
@@ -481,20 +481,12 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   /* Read the fractional digits.  A special case are the 'american style'
      numbers like `16.' i.e. with decimal but without trailing digits.  */
   if (c == decimal)
-    {
-      if (isdigit (cp[1]))
-       {
-         c = *++cp;
-         do
-           {
-             if (c != '0' && lead_zero == -1)
-               lead_zero = dig_no - int_no;
-             ++dig_no;
-             c = *++cp;
-           }
-         while (isdigit (c));
-       }
-    }
+    while (isdigit (c = *++cp))
+      {
+       if (c != '0' && lead_zero == -1)
+         lead_zero = dig_no - int_no;
+       ++dig_no;
+      }
 
   /* Remember start of exponent (if any).  */
   expp = cp;
index dc2e8b4..7bbd0ac 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -108,7 +108,8 @@ setenv (name, value, replace)
 }
 
 void
-unsetenv (const char *name)
+unsetenv (name)
+     const char *name;
 {
   const size_t len = strlen (name);
   char **ep;
index 6d75c7b..99d9dd5 100644 (file)
 #
 subdir := wcsmbs
 
-headers        := wcstr.h mbstr.h
+headers        := wchar.h
 
-routines := mbsadvance mbscat mbschr mbscmp mbscpy mbsdup mbslen       \
-           mbsncat mbsncmp mbsncpy mbsrchr mbstomb wcscat wcschr wcscmp\
-           wcscpy wcscspn wcsdup wcslen wcsncat wcsncmp wcsncpy wcspbrk\
-           wcsrchr wcsspn wcstok wcswcs
+routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
+           wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
+           wmemcmp wmemcpy wmemmove wmemset \
+           btowc wctob mbsinit \
+           mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs
 
 include ../Rules
diff --git a/wcsmbs/mbsadvance.c b/wcsmbs/mbsadvance.c
deleted file mode 100644 (file)
index b664993..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Advance pointer to multibyte string by one character.  */
-char *
-mbsadvance (mbs)
-    const char *mbs;
-{
-  int clen;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  clen = mblen (mbs, MB_CUR_MAX);
-
-  /* FIXME: when current character is illegal return same character.  */
-  return clen <= 0 ? (char *) mbs : (char *) (mbs + clen);
-}
-
diff --git a/wcsmbs/mbscat.c b/wcsmbs/mbscat.c
deleted file mode 100644 (file)
index 324cad9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Append SRC onto DEST.  */
-char *
-mbscat (dest, src)
-    char *dest;
-    const char *src;
-{
-  const char * const d = dest;
-  size_t len = 0;
-  int clen = 0;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      dest += clen;
-      clen = mblen (dest, MB_CUR_MAX);
-    }
-  while (clen > 0);
-
-  clen = 0;
-  do
-    {
-      len += clen;
-      clen = mblen (&src[len], MB_CUR_MAX);
-    }
-  while (clen > 0);
-
-  (void) memcpy ((void *) dest, (void *) src, len);
-  dest[len] = '\0';        /* '\0' is the multibyte representation of L'\0' */
-
-  return (char *) d;
-}
-
diff --git a/wcsmbs/mbschr.c b/wcsmbs/mbschr.c
deleted file mode 100644 (file)
index f8a7d21..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-#define __need_wchar_t
-#include <stddef.h>
-
-
-/* Find the first occurence of MBC in MBS.  */
-char *
-mbschr (mbs, mbc)
-    const char *mbs;
-    mbchar_t mbc;
-{
-  int clen;
-  wchar_t wc;
-  wchar_t c;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  clen = mbtowc (&wc, (char *) &mbc, MB_CUR_MAX);
-  if (clen < 0)
-    /* FIXME: search character is illegal.  */
-    return NULL;
-  else if (clen == 0)
-    wc = L'\0';
-
-  clen = 0;
-  do
-    {
-      mbs += clen;
-      clen = mbtowc (&c, mbs, MB_CUR_MAX);
-    }
-  while (clen > 0 && c != wc);
-
-  if (clen < 0 || (clen == 0 && wc != L'\0'))
-    /* FIXME: clen < 0 means illegal character in string.  */
-    return NULL;
-
-  return (char *) mbs;
-}
-
diff --git a/wcsmbs/mbscpy.c b/wcsmbs/mbscpy.c
deleted file mode 100644 (file)
index 8f354ce..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Copy SRC to DEST.  */
-char *
-mbscpy (dest, src)
-    char *dest;
-    const char *src;
-{
-  size_t len = 0;
-  int clen = 0;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      len += clen;
-      clen = mblen (&src[len], MB_CUR_MAX);
-    }
-  while (clen > 0);
-
-  (void) memcpy ((void *) dest, (void *) src, len);
-  dest[len] = '\0';        /* '\0' is the multibyte representation of L'\0' */
-
-  return dest;
-}
-
diff --git a/wcsmbs/mbsdup.c b/wcsmbs/mbsdup.c
deleted file mode 100644 (file)
index 2d196dd..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Duplicate MBS, returning an identical malloc'd string.  */
-char *
-mbsdup (mbs)
-    const char *mbs;
-{
-  size_t len = 0;
-  int clen = 0;
-  char *retval;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      len += clen;
-      clen = mblen (&mbs[len], MB_CUR_MAX);
-    }
-  while (clen > 0);
-
-  retval = (char *) malloc (len + 1);
-  if (retval != NULL)
-    {
-      (void) memcpy ((void *) retval, (void *) mbs, len);
-      retval[len] = '\0';   /* '\0' is the multibyte representation of L'\0' */
-    }
-
-  return retval;
-}
-
diff --git a/wcsmbs/mbslen.c b/wcsmbs/mbslen.c
deleted file mode 100644 (file)
index f8077d0..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Return the length of MBS.  */
-size_t
-mbslen (mbs)
-    const char *mbs;
-{
-  size_t len = 0;
-  int clen = 0;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      len += clen;
-      clen = mblen (&mbs[len], MB_CUR_MAX);
-    }
-  while (clen > 0);
-
-  /* FIXME: if string contains an illegal character the length upto this
-     character is returned.  */
-  return len;
-}
-
diff --git a/wcsmbs/mbsncat.c b/wcsmbs/mbsncat.c
deleted file mode 100644 (file)
index 3dd4df1..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Append no more than N multi-byte characters from SRC onto DEST.  */
-char *
-mbsncat (dest, src, n)
-    char *dest;
-    const char *src;
-    size_t n;
-{
-  const char * const d = dest;
-  const char * const s = src;
-  size_t len = 0;
-  int clen = 0;
-
-  if (n == 0)
-    return (char *) d;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      dest += clen;
-      clen = mblen (dest, MB_CUR_MAX);
-    }
-  while (clen > 0);
-
-  clen = 0;
-  do
-    {
-      src += clen;
-      clen = mblen (src, MB_CUR_MAX);
-    }
-  while (clen > 0 && ++len < n);
-
-  (void) memcpy ((void *) dest, (void *) s, src - s);
-  dest[src - s] = '\0';            /* '\0' is the multibyte representation of L'\0' */
-
-  return (char *) d;
-}
-
diff --git a/wcsmbs/mbsncmp.c b/wcsmbs/mbsncmp.c
deleted file mode 100644 (file)
index 43fb527..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-#define __need_wchar_t
-/* FIXME: should be defined in stddef.h.
-!!! #define __need_uwchar_t  */
-typedef unsigned int uwchar_t;
-#include <stddef.h>
-
-
-/* Compare N characters of MBS1 and MBS2.  */
-int
-mbsncmp (mbs1, mbs2, n)
-    const char *mbs1;
-    const char *mbs2;
-    size_t n;
-{
-  size_t len = 0;
-  int clen1 = 0;
-  int clen2 = 0;
-  uwchar_t c1;
-  uwchar_t c2;
-
-  if (n == 0)
-    return 0;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      clen1 = mbtowc ((wchar_t *) &c1, mbs1, MB_CUR_MAX);
-      clen2 = mbtowc ((wchar_t *) &c2, mbs2, MB_CUR_MAX);
-
-      if (clen1 == 0)
-       return clen2 == 0 ? 0 : -1;
-      if (clen2 == 0)
-       return 1;
-      if (clen1 < 0 || clen2 < 0)
-       /* FIXME: an illegal character appears.  What to do?  */
-       return c1 - c2;
-
-      mbs1 += clen1;
-      mbs2 += clen2;
-    }
-  while (c1 == c2 && ++len < n);
-
-  return len < n ? c1 - c2 : 0;
-}
-
diff --git a/wcsmbs/mbsncpy.c b/wcsmbs/mbsncpy.c
deleted file mode 100644 (file)
index 09aecef..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Copy no more than N characters of SRC to DEST.  */
-char *
-mbsncpy (dest, src, n)
-    char *dest;
-    const char *src;
-    size_t n;
-{
-  const char * const s = src;
-  size_t len = 0;
-  int clen = 0;
-
-  if (n == 0)
-    {
-      dest[0] = '\0';      /* '\0' is the multibyte representation of L'\0' */
-      return dest;
-    }
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      src += clen;
-      clen = mblen (src, MB_CUR_MAX);
-    }
-  while (clen > 0 && ++len < n);
-
-  (void) memcpy ((void *) dest, (void *) s, src - s);
-  dest[src - s] = '\0';            /* '\0' is the multibyte representation of L'\0' */
-
-  return dest;
-}
-
diff --git a/wcsmbs/mbsrchr.c b/wcsmbs/mbsrchr.c
deleted file mode 100644 (file)
index 62fa219..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-#define __need_wchar_t
-#include <stddef.h>
-
-
-/* Find the last occurence of MBC in MBS.  */
-char *
-mbsrchr (mbs, mbc)
-    const char *mbs;
-    mbchar_t mbc;
-{
-  const char * retval = NULL;
-  int clen;
-  wchar_t wc;
-  wchar_t c;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  clen = mbtowc (&wc, (char *) &mbc, MB_CUR_MAX);
-  if (clen < 0)
-    /* FIXME: search character MBC is illegal. */
-    return NULL;
-  else if (clen == 0)
-    wc = L'\0';
-
-  clen = 0;
-  do
-    {
-      mbs += clen;
-      clen = mbtowc (&c, mbs, MB_CUR_MAX);
-    }
-  while (clen > 0 && c != wc);
-
-  if (clen < 0)
-    /* FIXME: clen < 0 means illegal character in string.  */
-    return NULL;
-
-  return (char *) (clen > 0 || (clen == 0 && wc == L'\0') ? mbs : retval);
-}
-
diff --git a/wcsmbs/mbstomb.c b/wcsmbs/mbstomb.c
deleted file mode 100644 (file)
index f593ced..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <mbstr.h>
-#include <stdlib.h>
-
-
-/* Advance pointer to multibyte string by one character.  */
-mbchar_t
-mbstomb (mbs)
-    const char *mbs;
-{
-  mbchar_t retval = 0;
-  int clen;
-
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  clen = mblen (mbs, MB_CUR_MAX);
-
-  if (clen > 0)
-    (void) memcpy (&retval, mbs, clen);
-
-  /* FIXME: when current character is illegal return '\0'.  */
-  return retval;
-}
-
diff --git a/wcsmbs/mbstr.h b/wcsmbs/mbstr.h
deleted file mode 100644 (file)
index 7cb94bf..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#ifndef _MBSTRING_H
-
-#define _MBSTRING_H 1
-#include <features.h>
-#include <limits.h>
-
-#define __need_size_t
-#include <stddef.h>
-
-__BEGIN_DECLS
-
-/* This data type should be large enough to contain MB_CUR_MAX bytes.  */
-typedef unsigned int mbchar_t;
-
-
-/* Copy SRC to DEST.  */
-extern char *mbscpy __P ((char *__dest, __const char *__src));
-/* Copy no more than N multi-byte characters of SRC to DEST.  */
-extern char *mbsncpy __P ((char *__dest, __const char *__src, size_t __n));
-
-/* Append SRC onto DEST.  */
-extern char *mbscat __P ((char *__dest, __const char *__src));
-/* Append no more than N characters from SRC onto DEST.  */
-extern char *mbsncat __P ((char *__dest, __const char *__src, size_t __n));
-
-/* Compare S1 and S2.  */
-extern int mbscmp __P ((__const char *__s1, __const char *__s2));
-/* Compare N characters of S1 and S2.  */
-extern int mbsncmp __P ((__const char *__s1, __const char *__s2, size_t __n));
-
-/* Duplicate MBS, returning an identical malloc'd string.  */
-extern char *mbsdup __P ((__const char *__s));
-
-/* Find the first occurence of MBC in MBS.  */
-extern char *mbschr __P ((__const char *__mbs, mbchar_t mbc));
-/* Find the last occurence of MBC in MBS.  */
-extern char *mbsrchr __P ((__const char *__mbs, mbchar_t mbc));
-
-/* Return the length of MBS.  */
-extern size_t mbslen __P ((__const char *__mbs));
-
-
-/* Advance pointer to multibyte string by one character.  */
-extern char *mbsadvance __P ((__const char *__mbs));
-
-/* Return first character in MBS.  */
-extern mbchar_t mbstomb __P ((__const char *__mbs));
-
-__END_DECLS
-
-#endif /* mbstring.h */
index 4ff5c86..e142806 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,14 +17,14 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Append SRC on the end of DEST.  */
 wchar_t *
 wcscat (dest, src)
-    wchar_t *dest;
-    const wchar_t *src;
+     wchar_t *dest;
+     const wchar_t *src;
 {
   register wchar_t *s1 = dest;
   register const wchar_t *s2 = src;
index 85a1801..64af0bf 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -16,14 +16,14 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Find the first ocurrence of WC in WCS.  */
 wchar_t *
 wcschr (wcs, wc)
-    register const wchar_t *wcs;
-    register const wchar_t wc;
+     register const wchar_t *wcs;
+     register const wchar_t wc;
 {
   while (*wcs != L'\0')
     if (*wcs == wc)
index 84ecae8..08da116 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,16 +17,16 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Compare S1 and S2, returning less than, equal to or
-   greater than zero if S1 is lexiographically less than,
+   greater than zero if S1 is lexicographically less than,
    equal to or greater than S2.         */
 int
 wcscmp (s1, s2)
-    const wchar_t *s1;
-    const wchar_t *s2;
+     const wchar_t *s1;
+     const wchar_t *s2;
 {
   uwchar_t c1, c2;
 
index a45747e..3aa897e 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,7 +17,7 @@ License along with the GNU C Library; see the file COPYING.LIB.        If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 #define __need_ptrdiff_t
 #include <stddef.h>
@@ -25,8 +26,8 @@ Cambridge, MA 02139, USA.  */
 /* Copy SRC to DEST.  */
 wchar_t *
 wcscpy (dest, src)
-    wchar_t *dest;
-    const wchar_t *src;
+     wchar_t *dest;
+     const wchar_t *src;
 {
   wchar_t *wcp = (wchar_t *) src;
   wchar_t c;
index 0dc4d9b..7ab8f27 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,15 +17,15 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Return the length of the maximum initial segment
    of WCS which contains only wide-characters not in REJECT.  */
 size_t
 wcscspn (wcs, reject)
-    const wchar_t *wcs;
-    const wchar_t *reject;
+     const wchar_t *wcs;
+     const wchar_t *reject;
 {
   register size_t count = 0;
 
index 62c6462..c24ba96 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,7 +17,7 @@ License along with the GNU C Library; see the file COPYING.LIB.        If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -24,7 +25,7 @@ Cambridge, MA 02139, USA.  */
 /* Duplicate S, returning an identical malloc'd string.         */
 wchar_t *
 wcsdup (s)
-    const wchar_t *s;
+     const wchar_t *s;
 {
   size_t len = (wcslen (s) + 1) * sizeof (wchar_t);
   void *new = malloc (len);
index 2907cb3..1ce365f 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,13 +17,13 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Copy SRC to DEST.  */
 size_t
 wcslen (s)
-    const wchar_t *s;
+     const wchar_t *s;
 {
   size_t len = 0;
 
index 7851d70..48d5460 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,15 +17,15 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Append no more than N wide-character of SRC onto DEST.  */
 wchar_t *
 wcsncat (dest, src, n)
-      wchar_t *dest;
-      const wchar_t *src;
-      size_t n;
+     wchar_t *dest;
+     const wchar_t *src;
+     size_t n;
 {
   wchar_t c;
   wchar_t * const s = dest;
index 9f1829b..3df6bfc 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,7 +17,7 @@ License along with the GNU C Library; see the file COPYING.LIB.        If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Compare no more than N characters of S1 and S2,
@@ -25,9 +26,9 @@ Cambridge, MA 02139, USA.  */
    greater than S2.  */
 int
 wcsncmp (s1, s2, n)
-      const wchar_t *s1;
-      const wchar_t *s2;
-      size_t n;
+     const wchar_t *s1;
+     const wchar_t *s2;
+     size_t n;
 {
   uwchar_t c1 = L'\0';
   uwchar_t c2 = L'\0';
index 740c71e..180da79 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,18 +17,18 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Copy no more than N wide-characters of SRC to DEST. */
 wchar_t *
 wcsncpy (dest, src, n)
-      wchar_t *dest;
-      const wchar_t *src;
-      size_t n;
+     wchar_t *dest;
+     const wchar_t *src;
+     size_t n;
 {
   wchar_t c;
-  wchar_t * const s = dest;
+  wchar_t *const s = dest;
 
   --dest;
 
index 83892ba..91c5573 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,14 +17,14 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Find the first ocurrence in WCS of any wide-character in ACCEPT.  */
 wchar_t *
 wcspbrk (wcs, accept)
-      register const wchar_t *wcs;
-      register const wchar_t *accept;
+     register const wchar_t *wcs;
+     register const wchar_t *accept;
 {
   while (*wcs != L'\0')
     if (wcschr (accept, *wcs) == NULL)
index 87823b3..ae31dc4 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,14 +17,14 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Find the last ocurrence of WC in WCS.  */
 wchar_t *
 wcsrchr (wcs, wc)
-    register const wchar_t *wcs;
-    register const wchar_t wc;
+     register const wchar_t *wcs;
+     register const wchar_t wc;
 {
   const wchar_t *retval = NULL;
 
index 81a557c..158e35e 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,15 +17,15 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 
 
 /* Return the length of the maximum initial segment
    of WCS which contains only wide-characters in ACCEPT.  */
 size_t
 wcsspn (wcs, accept)
-    const wchar_t *wcs;
-    const wchar_t *accept;
+     const wchar_t *wcs;
+     const wchar_t *accept;
 {
   register const wchar_t *p;
   register const wchar_t *a;
index 191bbd5..376fe7b 100644 (file)
@@ -1,5 +1,6 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
+Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
 
 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
@@ -16,52 +17,42 @@ License along with the GNU C Library; see the file COPYING.LIB.      If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <wcstr.h>
+#include <wchar.h>
 #include <errno.h>
 
 
-static wchar_t *olds = NULL;
-
-/* Parse WCS into tokens separated by characters in DELIM.
-   If WCS is NULL, the last string wcstok() was called with is
-   used.  */
+/* Parse WCS into tokens separated by characters in DELIM.  If WCS is
+   NULL, the last string wcstok() was called with is used.  */
 wchar_t *
-wcstok (wcs, delim)
-    register wchar_t *wcs;
-    register const wchar_t *delim;
+wcstok (wcs, delim, ptr)
+     register wchar_t *wcs;
+     register const wchar_t *delim;
+     register wchar_t **ptr;
 {
-  wchar_t *token;
+  wchar_t *result;
 
   if (wcs == NULL)
-    {
-      if (olds == NULL)
-       {
-         errno = EINVAL;
-         return NULL;
-       }
-      else
-       wcs = olds;
-    }
+    wcs = *ptr;
 
   /* Scan leading delimiters.  */
   wcs += wcsspn (wcs, delim);
   if (*wcs == L'\0')
     {
-      olds = NULL;
+      *ptr = NULL;
       return NULL;
     }
 
   /* Find the end of the token.         */
-  token = wcs;
-  wcs = wcspbrk (token, delim);
+  result = wcs;
+  wcs = wcspbrk (result, delim);
   if (wcs == NULL)
     /* This token finishes the string. */
-    olds = NULL;
+    *ptr = NULL;
   else
     {
       /* Terminate the token and make OLDS point past it.  */
       *wcs = L'\0';
-      olds = wcs + 1;
+      *ptr = wcs + 1;
     }
-  return token;
+  return result;
 }
diff --git a/wcsmbs/wcstr.h b/wcsmbs/wcstr.h
deleted file mode 100644 (file)
index e9cc64d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#ifndef _WCSTRING_H
-
-#define _WCSTRING_H 1
-#include <features.h>
-
-__BEGIN_DECLS
-
-/* Get size_t, wchar_t, uwchar_t and NULL from <stddef.h>.  */
-#define __need_size_t
-#define __need_wchar_t
-/* #define __need_uwchar_t */
-#define __need_NULL
-#include <stddef.h>
-
-/* FIXME: Should go with this or another name in stddef.h.  */
-typedef unsigned int uwchar_t;
-
-
-/* Copy SRC to DEST.  */
-extern wchar_t *wcscpy __P ((wchar_t *__dest, __const wchar_t *__src));
-/* Copy no more than N wide-characters of SRC to DEST.  */
-extern wchar_t *wcsncpy __P ((wchar_t *__dest, __const wchar_t *__src,
-                             size_t __n));
-
-/* Append SRC onto DEST.  */
-extern wchar_t *wcscat __P ((wchar_t *__dest, __const wchar_t *__src));
-/* Append no more than N wide-characters of SRC onto DEST.  */
-extern wchar_t *wcsncat __P ((wchar_t *__dest, __const wchar_t *__src,
-                             size_t __n));
-
-/* Compare S1 and S2.  */
-extern int wcscmp __P ((__const wchar_t *__s1, __const wchar_t *__s2));
-/* Compare N wide-characters of S1 and S2.  */
-extern int wcsncmp __P ((__const wchar_t *__s1, __const wchar_t *__s2,
-                        size_t __n));
-
-/* Duplicate S, returning an identical malloc'd string.  */
-extern wchar_t *wcsdup __P ((__const wchar_t *__s));
-
-/* Find the first occurence of WC in WCS.  */
-extern wchar_t *wcschr __P ((__const wchar_t *__wcs, wchar_t __wc));
-/* Find the last occurence of WC in WCS.  */
-extern wchar_t *wcsrchr __P ((__const wchar_t *__wcs, wchar_t __wc));
-
-/* Return the length of the initial segmet of WCS which
-   consists entirely of wide-characters not in REJECT.  */
-extern size_t wcscspn __P ((__const wchar_t *__wcs,
-                           __const wchar_t *__reject));
-/* Return the length of the initial segmet of WCS which
-   consists entirely of wide-characters in  ACCEPT.  */
-extern size_t wcsspn __P ((__const wchar_t *__wcs, __const wchar_t *__accept));
-/* Find the first occurence in WCS of any character in ACCEPT.  */
-extern wchar_t *wcspbrk __P ((__const wchar_t *__wcs,
-                             __const wchar_t *__accept));
-/* Find the first occurence of NEEDLE in HAYSTACK.  */
-extern wchar_t *wcswcs __P ((__const wchar_t *__haystack,
-                            __const wchar_t *__needle));
-/* Divide WCS into tokens separated by characters in DELIM.  */
-extern wchar_t *wcstok __P ((wchar_t *__s, __const wchar_t *__delim));
-
-/* Return the number of wide-characters in S.  */
-extern size_t wcslen __P ((__const wchar_t *__s));
-
-__END_DECLS
-
-#endif /* wcstring.h */
diff --git a/wcsmbs/wcswcs.c b/wcsmbs/wcswcs.c
deleted file mode 100644 (file)
index 4b1f2ac..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-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.
-
-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.
-
-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., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-/*
- * The original strstr() file contains the following comment:
- *
- * My personal strstr() implementation that beats most other algorithms.
- * Until someone tells me otherwise, I assume that this is the
- * fastest implementation of strstr() in C.
- * I deliberately chose not to comment it.  You should have at least
- * as much fun trying to understand it, as I had to write it :-).
- *
- * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
-
-#include <wcstr.h>
-
-wchar_t *
-wcswcs (haystack, needle)
-    const wchar_t *haystack;
-    const wchar_t *needle;
-{
-  register wchar_t b, c;
-
-  if ((b = *needle) != L'\0')
-    {
-      haystack--;                              /* possible ANSI violation */
-      do
-       if ((c = *++haystack) == L'\0')
-         goto ret0;
-      while (c != b);
-
-      if (!(c = *++needle))
-       goto foundneedle;
-      ++needle;
-      goto jin;
-
-      for (;;)
-       { 
-         register wchar_t a;
-         register const wchar_t *rhaystack, *rneedle;
-
-         do
-           {
-             if (!(a = *++haystack))
-               goto ret0;
-             if (a == b)
-               break;
-             if ((a = *++haystack) == L'\0')
-               goto ret0;
-shloop:              ;
-           }
-         while (a != b);
-
-jin:     if (!(a = *++haystack))
-           goto ret0;
-
-         if (a != c)
-           goto shloop;
-
-         if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))
-           do
-             {
-               if (a == L'\0')
-                 goto foundneedle;
-               if (*++rhaystack != (a = *++needle))
-                 break;
-               if (a == L'\0')
-                 goto foundneedle;
-             }
-           while (*++rhaystack == (a = *++needle));
-
-         needle=rneedle;                 /* took the register-poor approach */
-
-         if (a == L'\0')
-           break;
-       }
-    }
-foundneedle:
-  return (wchar_t*)haystack;
-ret0:
-  return NULL;
-}