aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--MakeTAGS4
-rw-r--r--Makerules4
-rw-r--r--locale/Makefile5
-rw-r--r--locale/programs/config.h3
-rw-r--r--locale/programs/ctypedump.c163
-rw-r--r--locale/programs/locale.c188
-rw-r--r--po/header.pot14
-rw-r--r--posix/fnmatch.c17
-rw-r--r--posix/glob.c2
-rw-r--r--setjmp/setjmp.h2
-rw-r--r--stdio-common/_itoa.c6
-rw-r--r--stdio-common/_itoa.h29
-rw-r--r--stdio-common/printf-parse.h135
-rw-r--r--stdio-common/printf-prs.c52
-rw-r--r--stdio-common/printf.h9
-rw-r--r--stdio-common/tst-printf.c17
-rw-r--r--stdio-common/vfprintf.c1710
-rw-r--r--stdlib/strtod.c20
-rw-r--r--sysdeps/generic/setenv.c5
-rw-r--r--wcsmbs/Makefile11
-rw-r--r--wcsmbs/mbsadvance.c38
-rw-r--r--wcsmbs/mbscat.c56
-rw-r--r--wcsmbs/mbschr.c60
-rw-r--r--wcsmbs/mbscpy.c47
-rw-r--r--wcsmbs/mbsdup.c51
-rw-r--r--wcsmbs/mbslen.c45
-rw-r--r--wcsmbs/mbsncat.c61
-rw-r--r--wcsmbs/mbsncmp.c68
-rw-r--r--wcsmbs/mbsncpy.c55
-rw-r--r--wcsmbs/mbsrchr.c61
-rw-r--r--wcsmbs/mbstomb.c42
-rw-r--r--wcsmbs/mbstr.h69
-rw-r--r--wcsmbs/wcscat.c9
-rw-r--r--wcsmbs/wcschr.c8
-rw-r--r--wcsmbs/wcscmp.c11
-rw-r--r--wcsmbs/wcscpy.c9
-rw-r--r--wcsmbs/wcscspn.c9
-rw-r--r--wcsmbs/wcsdup.c7
-rw-r--r--wcsmbs/wcslen.c7
-rw-r--r--wcsmbs/wcsncat.c11
-rw-r--r--wcsmbs/wcsncmp.c11
-rw-r--r--wcsmbs/wcsncpy.c13
-rw-r--r--wcsmbs/wcspbrk.c9
-rw-r--r--wcsmbs/wcsrchr.c9
-rw-r--r--wcsmbs/wcsspn.c9
-rw-r--r--wcsmbs/wcstok.c43
-rw-r--r--wcsmbs/wcstr.h84
-rw-r--r--wcsmbs/wcswcs.c97
49 files changed, 1507 insertions, 1895 deletions
diff --git a/ChangeLog b/ChangeLog
index f8c952fa76..ac276db283 100644
--- 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.
diff --git a/MakeTAGS b/MakeTAGS
index a9baba65e8..7aaf0ac7da 100644
--- 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' $@
diff --git a/Makerules b/Makerules
index 296e811432..d7e82d9082 100644
--- 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
diff --git a/locale/Makefile b/locale/Makefile
index 675052aa03..0a30cd27d3 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -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
diff --git a/locale/programs/config.h b/locale/programs/config.h
index 64054657cb..4aa406d755 100644
--- a/locale/programs/config.h
+++ b/locale/programs/config.h
@@ -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
index 2a6753495e..0000000000
--- a/locale/programs/ctypedump.c
+++ /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:
- */
diff --git a/locale/programs/locale.c b/locale/programs/locale.c
index 4e4ff83a37..8254289598 100644
--- a/locale/programs/locale.c
+++ b/locale/programs/locale.c
@@ -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
index 0000000000..c8d0c8a9d2
--- /dev/null
+++ b/po/header.pot
@@ -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"
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index 1ddea80961..08c1c9448e 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -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;
diff --git a/posix/glob.c b/posix/glob.c
index eea126d800..1a00af6f3f 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -699,7 +699,7 @@ glob_pattern_p (pattern, quote)
return 1;
case '\\':
- if (quote)
+ if (quote && p[1] != '\0')
++p;
break;
diff --git a/setjmp/setjmp.h b/setjmp/setjmp.h
index 12b05f1033..1cd5bbd36d 100644
--- a/setjmp/setjmp.h
+++ b/setjmp/setjmp.h
@@ -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'.
diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c
index caa8179624..38d5367ba2 100644
--- a/stdio-common/_itoa.c
+++ b/stdio-common/_itoa.c
@@ -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";
diff --git a/stdio-common/_itoa.h b/stdio-common/_itoa.h
index ab3d1d1d3a..75f5f85892 100644
--- a/stdio-common/_itoa.h
+++ b/stdio-common/_itoa.h
@@ -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 */
diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h
index 9abbdba187..a7960e6003 100644
--- a/stdio-common/printf-parse.h
+++ b/stdio-common/printf-parse.h
@@ -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;
diff --git a/stdio-common/printf-prs.c b/stdio-common/printf-prs.c
index 811a9cb7eb..d0756de7d4 100644
--- a/stdio-common/printf-prs.c
+++ b/stdio-common/printf-prs.c
@@ -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)
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index df7747ec38..6e90154cde 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -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. */
diff --git a/stdio-common/tst-printf.c b/stdio-common/tst-printf.c
index c177da18b2..12212b87b2 100644
--- a/stdio-common/tst-printf.c
+++ b/stdio-common/tst-printf.c
@@ -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;
+ }
}
rfg1 ()
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index d6b9f9a092..26b31a6ed2 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -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
-
-
+
/* 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)
/* 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;
}
-
-
+
/* 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)
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index 3818c81ecb..51dc520c01 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -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;
diff --git a/sysdeps/generic/setenv.c b/sysdeps/generic/setenv.c
index dc2e8b43f3..7bbd0acbab 100644
--- a/sysdeps/generic/setenv.c
+++ b/sysdeps/generic/setenv.c
@@ -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;
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 6d75c7b01f..99d9dd5010 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -21,11 +21,12 @@
#
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
index b6649935d7..0000000000
--- a/wcsmbs/mbsadvance.c
+++ /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
index 324cad9cc8..0000000000
--- a/wcsmbs/mbscat.c
+++ /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
index f8a7d21857..0000000000
--- a/wcsmbs/mbschr.c
+++ /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
index 8f354ceede..0000000000
--- a/wcsmbs/mbscpy.c
+++ /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
index 2d196dd06d..0000000000
--- a/wcsmbs/mbsdup.c
+++ /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
index f8077d0fb9..0000000000
--- a/wcsmbs/mbslen.c
+++ /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
index 3dd4df1c70..0000000000
--- a/wcsmbs/mbsncat.c
+++ /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
index 43fb527afb..0000000000
--- a/wcsmbs/mbsncmp.c
+++ /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
index 09aecefd03..0000000000
--- a/wcsmbs/mbsncpy.c
+++ /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
index 62fa219dd2..0000000000
--- a/wcsmbs/mbsrchr.c
+++ /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
index f593ced3cb..0000000000
--- a/wcsmbs/mbstomb.c
+++ /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
index 7cb94bf85b..0000000000
--- a/wcsmbs/mbstr.h
+++ /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 */
diff --git a/wcsmbs/wcscat.c b/wcsmbs/wcscat.c
index 4ff5c861e4..e142806fae 100644
--- a/wcsmbs/wcscat.c
+++ b/wcsmbs/wcscat.c
@@ -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;
diff --git a/wcsmbs/wcschr.c b/wcsmbs/wcschr.c
index 85a1801839..64af0bf456 100644
--- a/wcsmbs/wcschr.c
+++ b/wcsmbs/wcschr.c
@@ -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)
diff --git a/wcsmbs/wcscmp.c b/wcsmbs/wcscmp.c
index 84ecae8553..08da116787 100644
--- a/wcsmbs/wcscmp.c
+++ b/wcsmbs/wcscmp.c
@@ -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;
diff --git a/wcsmbs/wcscpy.c b/wcsmbs/wcscpy.c
index a45747edf1..3aa897ec7f 100644
--- a/wcsmbs/wcscpy.c
+++ b/wcsmbs/wcscpy.c
@@ -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;
diff --git a/wcsmbs/wcscspn.c b/wcsmbs/wcscspn.c
index 0dc4d9bc9e..7ab8f278fd 100644
--- a/wcsmbs/wcscspn.c
+++ b/wcsmbs/wcscspn.c
@@ -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;
diff --git a/wcsmbs/wcsdup.c b/wcsmbs/wcsdup.c
index 62c64621de..c24ba96f88 100644
--- a/wcsmbs/wcsdup.c
+++ b/wcsmbs/wcsdup.c
@@ -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);
diff --git a/wcsmbs/wcslen.c b/wcsmbs/wcslen.c
index 2907cb3cc4..1ce365f8c4 100644
--- a/wcsmbs/wcslen.c
+++ b/wcsmbs/wcslen.c
@@ -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;
diff --git a/wcsmbs/wcsncat.c b/wcsmbs/wcsncat.c
index 7851d7048d..48d54603d6 100644
--- a/wcsmbs/wcsncat.c
+++ b/wcsmbs/wcsncat.c
@@ -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;
diff --git a/wcsmbs/wcsncmp.c b/wcsmbs/wcsncmp.c
index 9f1829bc5d..3df6bfc151 100644
--- a/wcsmbs/wcsncmp.c
+++ b/wcsmbs/wcsncmp.c
@@ -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';
diff --git a/wcsmbs/wcsncpy.c b/wcsmbs/wcsncpy.c
index 740c71ecf8..180da794d7 100644
--- a/wcsmbs/wcsncpy.c
+++ b/wcsmbs/wcsncpy.c
@@ -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;
diff --git a/wcsmbs/wcspbrk.c b/wcsmbs/wcspbrk.c
index 83892bacb0..91c5573722 100644
--- a/wcsmbs/wcspbrk.c
+++ b/wcsmbs/wcspbrk.c
@@ -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)
diff --git a/wcsmbs/wcsrchr.c b/wcsmbs/wcsrchr.c
index 87823b3709..ae31dc4104 100644
--- a/wcsmbs/wcsrchr.c
+++ b/wcsmbs/wcsrchr.c
@@ -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;
diff --git a/wcsmbs/wcsspn.c b/wcsmbs/wcsspn.c
index 81a557c7b7..158e35ee97 100644
--- a/wcsmbs/wcsspn.c
+++ b/wcsmbs/wcsspn.c
@@ -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;
diff --git a/wcsmbs/wcstok.c b/wcsmbs/wcstok.c
index 191bbd5960..376fe7bfcb 100644
--- a/wcsmbs/wcstok.c
+++ b/wcsmbs/wcstok.c
@@ -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
index e9cc64ddc1..0000000000
--- a/wcsmbs/wcstr.h
+++ /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
index 4b1f2ace54..0000000000
--- a/wcsmbs/wcswcs.c
+++ /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;
-}