summaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/stdio/Makefile.in97
-rw-r--r--libc/stdio/_READ.c5
-rw-r--r--libc/stdio/_WRITE.c4
-rw-r--r--libc/stdio/__fsetlocking.c10
-rw-r--r--libc/stdio/__psfs_do_numeric.c9
-rw-r--r--libc/stdio/__psfs_parse_spec.c9
-rw-r--r--libc/stdio/__scan_cookie.c9
-rw-r--r--libc/stdio/_cs_funcs.c23
-rw-r--r--libc/stdio/_flushlbf.c2
-rw-r--r--libc/stdio/_fopen.c22
-rw-r--r--libc/stdio/_fpmaxtostr.c15
-rw-r--r--libc/stdio/_fwrite.c11
-rw-r--r--libc/stdio/_load_inttype.c3
-rw-r--r--libc/stdio/_ppfs_init.c9
-rw-r--r--libc/stdio/_ppfs_parsespec.c9
-rw-r--r--libc/stdio/_ppfs_prepargs.c9
-rw-r--r--libc/stdio/_ppfs_setargs.c9
-rw-r--r--libc/stdio/_stdio.c22
-rw-r--r--libc/stdio/_stdio.h97
-rw-r--r--libc/stdio/_store_inttype.c3
-rw-r--r--libc/stdio/_trans2w.c4
-rw-r--r--libc/stdio/_uintmaxtostr.c13
-rw-r--r--libc/stdio/_vfprintf.c1951
-rw-r--r--libc/stdio/_wfwrite.c10
-rw-r--r--libc/stdio/asprintf.c13
-rw-r--r--libc/stdio/clearerr.c7
-rw-r--r--libc/stdio/clearerr_unlocked.c9
-rw-r--r--libc/stdio/ctermid.c4
-rw-r--r--libc/stdio/dprintf.c6
-rw-r--r--libc/stdio/fclose.c13
-rw-r--r--libc/stdio/fcloseall.c6
-rw-r--r--libc/stdio/fdopen.c9
-rw-r--r--libc/stdio/feof.c7
-rw-r--r--libc/stdio/feof_unlocked.c9
-rw-r--r--libc/stdio/ferror.c7
-rw-r--r--libc/stdio/ferror_unlocked.c9
-rw-r--r--libc/stdio/fflush.c21
-rw-r--r--libc/stdio/fflush_unlocked.c9
-rw-r--r--libc/stdio/fgetc.c42
-rw-r--r--libc/stdio/fgetc_unlocked.c9
-rw-r--r--libc/stdio/fgetpos.c4
-rw-r--r--libc/stdio/fgetpos64.c2
-rw-r--r--libc/stdio/fgets.c23
-rw-r--r--libc/stdio/fgets_unlocked.c14
-rw-r--r--libc/stdio/fgetwc.c29
-rw-r--r--libc/stdio/fgetwc_unlocked.c9
-rw-r--r--libc/stdio/fgetws.c15
-rw-r--r--libc/stdio/fgetws_unlocked.c9
-rw-r--r--libc/stdio/fileno.c19
-rw-r--r--libc/stdio/fileno_unlocked.c9
-rw-r--r--libc/stdio/fmemopen.c11
-rw-r--r--libc/stdio/fopen.c7
-rw-r--r--libc/stdio/fopen64.c1
-rw-r--r--libc/stdio/fopencookie.c9
-rw-r--r--libc/stdio/fprintf.c10
-rw-r--r--libc/stdio/fputc.c33
-rw-r--r--libc/stdio/fputc_unlocked.c9
-rw-r--r--libc/stdio/fputs.c25
-rw-r--r--libc/stdio/fputs_unlocked.c14
-rw-r--r--libc/stdio/fputwc.c16
-rw-r--r--libc/stdio/fputwc_unlocked.c9
-rw-r--r--libc/stdio/fputws.c25
-rw-r--r--libc/stdio/fputws_unlocked.c9
-rw-r--r--libc/stdio/fread.c23
-rw-r--r--libc/stdio/fread_unlocked.c9
-rw-r--r--libc/stdio/freopen.c2
-rw-r--r--libc/stdio/fscanf.c9
-rw-r--r--libc/stdio/fseeko.c17
-rw-r--r--libc/stdio/fseeko64.c2
-rw-r--r--libc/stdio/fsetpos.c4
-rw-r--r--libc/stdio/fsetpos64.c2
-rw-r--r--libc/stdio/ftello.c17
-rw-r--r--libc/stdio/ftello64.c2
-rw-r--r--libc/stdio/fwprintf.c4
-rw-r--r--libc/stdio/fwrite.c18
-rw-r--r--libc/stdio/fwrite_unlocked.c9
-rw-r--r--libc/stdio/fwscanf.c9
-rw-r--r--libc/stdio/getchar.c10
-rw-r--r--libc/stdio/getchar_unlocked.c9
-rw-r--r--libc/stdio/getdelim.c13
-rw-r--r--libc/stdio/getline.c12
-rw-r--r--libc/stdio/gets.c10
-rw-r--r--libc/stdio/getw.c4
-rw-r--r--libc/stdio/getwchar.c13
-rw-r--r--libc/stdio/getwchar_unlocked.c9
-rw-r--r--libc/stdio/old_vfprintf.c25
-rw-r--r--libc/stdio/open_memstream.c19
-rw-r--r--libc/stdio/parse_printf_format.c9
-rw-r--r--libc/stdio/perror.c11
-rw-r--r--libc/stdio/popen.c36
-rw-r--r--libc/stdio/printf.c9
-rw-r--r--libc/stdio/putchar.c10
-rw-r--r--libc/stdio/putchar_unlocked.c9
-rw-r--r--libc/stdio/puts.c7
-rw-r--r--libc/stdio/putw.c6
-rw-r--r--libc/stdio/putwchar.c15
-rw-r--r--libc/stdio/putwchar_unlocked.c9
-rw-r--r--libc/stdio/register_printf_function.c9
-rw-r--r--libc/stdio/remove.c11
-rw-r--r--libc/stdio/rewind.c9
-rw-r--r--libc/stdio/scanf.c2261
-rw-r--r--libc/stdio/setbuf.c4
-rw-r--r--libc/stdio/setbuffer.c4
-rw-r--r--libc/stdio/setlinebuf.c4
-rw-r--r--libc/stdio/setvbuf.c5
-rw-r--r--libc/stdio/snprintf.c9
-rw-r--r--libc/stdio/sprintf.c9
-rw-r--r--libc/stdio/sscanf.c9
-rw-r--r--libc/stdio/swprintf.c4
-rw-r--r--libc/stdio/swscanf.c9
-rw-r--r--libc/stdio/tempnam.c4
-rw-r--r--libc/stdio/tmpfile.c11
-rw-r--r--libc/stdio/tmpnam.c57
-rw-r--r--libc/stdio/ungetc.c5
-rw-r--r--libc/stdio/ungetwc.c5
-rw-r--r--libc/stdio/vasprintf.c24
-rw-r--r--libc/stdio/vdprintf.c16
-rw-r--r--libc/stdio/vfprintf.c1932
-rw-r--r--libc/stdio/vfscanf.c9
-rw-r--r--libc/stdio/vfwprintf.c9
-rw-r--r--libc/stdio/vfwscanf.c9
-rw-r--r--libc/stdio/vprintf.c4
-rw-r--r--libc/stdio/vscanf.c9
-rw-r--r--libc/stdio/vsnprintf.c22
-rw-r--r--libc/stdio/vsprintf.c4
-rw-r--r--libc/stdio/vsscanf.c9
-rw-r--r--libc/stdio/vswprintf.c10
-rw-r--r--libc/stdio/vswscanf.c9
-rw-r--r--libc/stdio/vwprintf.c4
-rw-r--r--libc/stdio/vwscanf.c9
-rw-r--r--libc/stdio/wprintf.c4
-rw-r--r--libc/stdio/wscanf.c9
132 files changed, 3024 insertions, 4715 deletions
diff --git a/libc/stdio/Makefile.in b/libc/stdio/Makefile.in
index 3a6f739b4..5d4d74ed2 100644
--- a/libc/stdio/Makefile.in
+++ b/libc/stdio/Makefile.in
@@ -1,10 +1,12 @@
# Makefile for uClibc
#
# Copyright (C) 2000 by Lineo, inc.
-# Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
-# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
#
-# Licensed under LGPL v2.1, see the file COPYING.LIB in this tarball for details.
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+# Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
#
# SUSv3 functions
@@ -55,96 +57,51 @@ CUSRC := \
# putc_unlocked -> alias for fputc_unlocked
# vfprintf and support functions
-MSRC1 := vfprintf.c
ifneq ($(USE_OLD_VFPRINTF),y)
-MOBJ1 := \
- vfprintf.o \
- _ppfs_init.o _ppfs_prepargs.o _ppfs_setargs.o _ppfs_parsespec.o \
- register_printf_function.o parse_printf_format.o
+VF_CSRC := \
+ vfprintf.c \
+ _ppfs_init.c _ppfs_prepargs.c _ppfs_setargs.c _ppfs_parsespec.c \
+ register_printf_function.c parse_printf_format.c
+CSRC += $(VF_CSRC)
else
-MOBJ1 :=
CSRC += old_vfprintf.c
endif
# vfscanf and support functions plus other *scanf funcs
-MSRC2 := scanf.c
-MOBJ2 := \
- vfscanf.o __scan_cookie.o __psfs_parse_spec.o __psfs_do_numeric.o \
- scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o
+CSRC += \
+ vfscanf.c __scan_cookie.c __psfs_parse_spec.c __psfs_do_numeric.c \
+ scanf.c sscanf.c fscanf.c vscanf.c vsscanf.c
-CWSRC :=
ifeq ($(UCLIBC_HAS_WCHAR),y)
-CWSRC += _wfwrite.c fwprintf.c swprintf.c vswprintf.c vwprintf.c wprintf.c \
+CSRC += _wfwrite.c fwprintf.c swprintf.c vswprintf.c vwprintf.c wprintf.c \
fwide.c ungetwc.c
CUSRC += fgetwc.c getwchar.c fgetws.c fputwc.c putwchar.c fputws.c
# getwc (fgetwc alias) getwc_unlocked (fgetwc_unlocked alias)
# putwc (fputwc alias) putwc_unlocked (fputwc_unlocked alias)
-MOBJ1 += vfwprintf.o
-MOBJ2 += wscanf.o swscanf.o fwscanf.o vwscanf.o vswscanf.o vfwscanf.o
+CSRC += vfwprintf.c
+CSRC += wscanf.c swscanf.c fwscanf.c vwscanf.c vswscanf.c vfwscanf.c
endif
-CSRC += $(CUSRC) $(CWSRC)
+CUSRC_UNLOCKED := $(patsubst %.c,%_unlocked.c,$(CUSRC))
-ifneq ($(DOMULTI),n)
-STDIO_CSRC_NO_MULTI := fwrite.c fputc.c fputs.c fprintf.c _fpmaxtostr.c
-CSRC := $(filter-out $(STDIO_CSRC_NO_MULTI),$(CSRC))
-endif
-STDIO_MOBJ1_NO_MULTI := vfprintf.o vfwprintf.o register_printf_function.o
-STDIO_MOBJ2_NO_MULTI := vfscanf.o vfwscanf.o fscanf.o
-STDIO_MOBJ_NO_MULTI := $(STDIO_MOBJ1_NO_MULTI) $(STDIO_MOBJ2_NO_MULTI)
+CSRC += $(CUSRC) $(CUSRC_UNLOCKED)
STDIO_DIR := $(top_srcdir)libc/stdio
STDIO_OUT := $(top_builddir)libc/stdio
STDIO_SRC := $(patsubst %.c,$(STDIO_DIR)/%.c,$(CSRC))
STDIO_OBJ := $(patsubst %.c,$(STDIO_OUT)/%.o,$(CSRC))
-STDIO_CUSRC := $(patsubst %.c,$(STDIO_DIR)/%.c,$(CUSRC))
-STDIO_CUOBJ := $(patsubst %.c,$(STDIO_OUT)/%_unlocked.o,$(CUSRC))
-
-STDIO_MSRC1 := $(patsubst %.c,$(STDIO_DIR)/%.c,$(MSRC1))
-STDIO_MSRC2 := $(patsubst %.c,$(STDIO_DIR)/%.c,$(MSRC2))
-STDIO_MOBJ1 := $(patsubst %.o,$(STDIO_OUT)/%.o,$(MOBJ1))
-STDIO_MOBJ2 := $(patsubst %.o,$(STDIO_OUT)/%.o,$(MOBJ2))
-
-STDIO_MSRC := $(STDIO_MSRC1) $(STDIO_MSRC2)
-STDIO_MOBJ := $(STDIO_MOBJ1) $(STDIO_MOBJ2)
-
-STDIO_DEF := $(patsubst %,-DL_%,$(subst .o,,$(filter-out $(STDIO_MOBJ_NO_MULTI),$(notdir $(STDIO_MOBJ)))))
-
-STDIO_OBJS := $(STDIO_OBJ) $(STDIO_MOBJ) $(STDIO_CUOBJ)
-
-STDIO_NO_MULTI := $(STDIO_CUOBJ)
-
-# these need special handling or rewrite to support multi-build
-# CUOBJ
-%_unlocked.o: %.c
- $(compile.c) -D__DO_UNLOCKED
-%_unlocked.os: %.c
- $(compile.c) -D__DO_UNLOCKED
+libc-y += $(STDIO_OBJ)
-$(STDIO_MOBJ1): $(STDIO_MSRC1)
- $(compile.m)
-
-$(STDIO_MOBJ1:.o=.os): $(STDIO_MSRC1)
- $(compile.m)
-
-$(STDIO_MOBJ2): $(STDIO_MSRC2)
- $(compile.m)
-
-$(STDIO_MOBJ2:.o=.os): $(STDIO_MSRC2)
- $(compile.m)
-
-libc-a-y+=$(STDIO_OBJS)
-libc-so-y+=$(STDIO_OBJS:.o=.os)
-
-CFLAGS-multi-y+=$(STDIO_DEF)
-libc-multi-y+=$(STDIO_SRC) $(STDIO_MSRC)
-libc-nomulti-y+=$(STDIO_NO_MULTI)
-libc-nomulti-y+=$(patsubst %.c,$(STDIO_OUT)/%.o,$(STDIO_CSRC_NO_MULTI))
-libc-nomulti-y+=$(patsubst %.o,$(STDIO_OUT)/%.o,$(STDIO_MOBJ_NO_MULTI))
+ifneq ($(USE_OLD_VFPRINTF),y)
+libc-nomulti-y += $(patsubst %.c,$(STDIO_OUT)/%.o,$(VF_CSRC))
+endif
+ifeq ($(UCLIBC_HAS_WCHAR),y)
+libc-nomulti-y += $(STDIO_OUT)/vfwprintf.o $(STDIO_OUT)/vfwscanf.o
+endif
-objclean-y+=stdio_objclean
+objclean-y += stdio_objclean
stdio_objclean:
- $(RM) $(STDIO_OUT)/*.{o,os}
+ $(RM) $(STDIO_OUT)/*.{o,os,oS}
diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c
index e27309c11..0c7febb3c 100644
--- a/libc/stdio/_READ.c
+++ b/libc/stdio/_READ.c
@@ -5,10 +5,11 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define read __read
-
#include "_stdio.h"
+libc_hidden_proto(read)
+libc_hidden_proto(abort)
+
/* Given a reading stream without its end-of-file indicator set and
* with no buffered input or ungots, read at most 'bufsize' bytes
* into 'buf' (which may be the stream's __bufstart).
diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c
index c2b0e7b5d..2bd0977fd 100644
--- a/libc/stdio/_WRITE.c
+++ b/libc/stdio/_WRITE.c
@@ -5,10 +5,10 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define write __write
-
#include "_stdio.h"
+libc_hidden_proto(write)
+
/* Given a writing stream with no buffered output, write the
* data in 'buf' (which may be the stream's bufstart) of size
* 'bufsize' to the stream. If a write error occurs, set the
diff --git a/libc/stdio/__fsetlocking.c b/libc/stdio/__fsetlocking.c
index 5b6070cc3..746a098f9 100644
--- a/libc/stdio/__fsetlocking.c
+++ b/libc/stdio/__fsetlocking.c
@@ -8,6 +8,11 @@
#include "_stdio.h"
#include <stdio_ext.h>
+libc_hidden_proto(__fsetlocking)
+#ifdef __UCLIBC_HAS_THREADS__
+libc_hidden_proto(_stdio_user_locking)
+#endif
+
/* Not threadsafe. */
/* Notes:
@@ -15,7 +20,7 @@
* glibc treats invalid locking_mode args as FSETLOCKING_INTERNAL.
*/
-int attribute_hidden __fsetlocking_internal(FILE *stream, int locking_mode)
+int __fsetlocking(FILE *stream, int locking_mode)
{
#ifdef __UCLIBC_HAS_THREADS__
int current = 1 + (stream->__user_locking & 1);
@@ -43,5 +48,4 @@ int attribute_hidden __fsetlocking_internal(FILE *stream, int locking_mode)
return FSETLOCKING_INTERNAL;
#endif
}
-
-strong_alias(__fsetlocking_internal,__fsetlocking)
+libc_hidden_def(__fsetlocking)
diff --git a/libc/stdio/__psfs_do_numeric.c b/libc/stdio/__psfs_do_numeric.c
new file mode 100644
index 000000000..e3714776c
--- /dev/null
+++ b/libc/stdio/__psfs_do_numeric.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L___psfs_do_numeric
+#include "_scanf.c"
diff --git a/libc/stdio/__psfs_parse_spec.c b/libc/stdio/__psfs_parse_spec.c
new file mode 100644
index 000000000..cac9cda46
--- /dev/null
+++ b/libc/stdio/__psfs_parse_spec.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L___psfs_parse_spec
+#include "_scanf.c"
diff --git a/libc/stdio/__scan_cookie.c b/libc/stdio/__scan_cookie.c
new file mode 100644
index 000000000..d5d53c4c5
--- /dev/null
+++ b/libc/stdio/__scan_cookie.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L___scan_cookie
+#include "_scanf.c"
diff --git a/libc/stdio/_cs_funcs.c b/libc/stdio/_cs_funcs.c
index ef92048c0..38a8351e5 100644
--- a/libc/stdio/_cs_funcs.c
+++ b/libc/stdio/_cs_funcs.c
@@ -7,20 +7,29 @@
#include "_stdio.h"
+libc_hidden_proto(read)
+libc_hidden_proto(write)
+libc_hidden_proto(close)
+#ifdef __UCLIBC_HAS_LFS__
+libc_hidden_proto(lseek64)
+#else
+libc_hidden_proto(lseek)
+#endif
+
/**********************************************************************/
#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
/**********************************************************************/
ssize_t attribute_hidden _cs_read(void *cookie, char *buf, size_t bufsize)
{
- return __read(*((int *) cookie), buf, bufsize);
+ return read(*((int *) cookie), buf, bufsize);
}
/**********************************************************************/
ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize)
{
- return __write(*((int *) cookie), (char *) buf, bufsize);
+ return write(*((int *) cookie), (char *) buf, bufsize);
}
/**********************************************************************/
@@ -30,9 +39,9 @@ int attribute_hidden _cs_seek(void *cookie, register __offmax_t *pos, int whence
__offmax_t res;
#ifdef __UCLIBC_HAS_LFS__
- res = __lseek64(*((int *) cookie), *pos, whence);
+ res = lseek64(*((int *) cookie), *pos, whence);
#else
- res = __lseek(*((int *) cookie), *pos, whence);
+ res = lseek(*((int *) cookie), *pos, whence);
#endif
return (res >= 0) ? ((*pos = res), 0) : ((int) res);
@@ -42,7 +51,7 @@ int attribute_hidden _cs_seek(void *cookie, register __offmax_t *pos, int whence
int attribute_hidden _cs_close(void *cookie)
{
- return __close(*((int *) cookie));
+ return close(*((int *) cookie));
}
/**********************************************************************/
@@ -54,9 +63,9 @@ int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t *pos, int wh
__offmax_t res;
#ifdef __UCLIBC_HAS_LFS__
- res = __lseek64(stream->__filedes, *pos, whence);
+ res = lseek64(stream->__filedes, *pos, whence);
#else
- res = __lseek(stream->__filedes, *pos, whence);
+ res = lseek(stream->__filedes, *pos, whence);
#endif
return (res >= 0) ? ((*pos = res), 0) : ((int) res);
diff --git a/libc/stdio/_flushlbf.c b/libc/stdio/_flushlbf.c
index 31ed2fc55..8a551a746 100644
--- a/libc/stdio/_flushlbf.c
+++ b/libc/stdio/_flushlbf.c
@@ -8,6 +8,8 @@
#include "_stdio.h"
#include <stdio_ext.h>
+libc_hidden_proto(fflush_unlocked)
+
/* Solaris function --
* Flush all line buffered (writing) streams.
*/
diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
index 33b7b89ad..4ca028275 100644
--- a/libc/stdio/_fopen.c
+++ b/libc/stdio/_fopen.c
@@ -5,10 +5,16 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define isatty __isatty
-
#include "_stdio.h"
+libc_hidden_proto(isatty)
+libc_hidden_proto(open)
+libc_hidden_proto(fcntl)
+
+#ifdef __UCLIBC_HAS_THREADS__
+libc_hidden_proto(_stdio_user_locking)
+#endif
+
/*
* Cases:
* fopen64 : filename != NULL, stream == NULL, filedes == -2
@@ -100,12 +106,8 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_THREADS__
/* We only initialize the mutex in the non-freopen case. */
/* stream->__user_locking = _stdio_user_locking; */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (stream->_lock);
-#else
__stdio_init_mutex(&stream->__lock);
#endif
-#endif
}
#ifdef __UCLIBC_MJN3_ONLY__
@@ -125,7 +127,7 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
/* NOTE: fopencookie needs changing if the basic check changes! */
if (((i & (((int) fname_or_mode) + 1)) != i) /* Basic agreement? */
|| (((open_mode & ~((__mode_t) fname_or_mode)) & O_APPEND)
- && __fcntl(filedes, F_SETFL, O_APPEND)) /* Need O_APPEND. */
+ && fcntl(filedes, F_SETFL, O_APPEND)) /* Need O_APPEND. */
) {
goto DO_EINVAL;
}
@@ -134,7 +136,7 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
& O_LARGEFILE) );
} else {
__STDIO_WHEN_LFS( if (filedes < -1) open_mode |= O_LARGEFILE );
- if ((stream->__filedes = __open(((const char *) fname_or_mode),
+ if ((stream->__filedes = open(((const char *) fname_or_mode),
open_mode, 0666)) < 0) {
goto FREE_STREAM;
}
@@ -196,12 +198,8 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_THREADS__
/* Even in the freopen case, we reset the user locking flag. */
stream->__user_locking = _stdio_user_locking;
-#ifdef __USE_STDIO_FUTEXES__
- /* _IO_lock_init (stream->_lock); */
-#else
/* __stdio_init_mutex(&stream->__lock); */
#endif
-#endif
#ifdef __STDIO_HAS_OPENLIST
__STDIO_THREADLOCK_OPENLIST;
diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c
index 99fc9a9dd..9b87f64cf 100644
--- a/libc/stdio/_fpmaxtostr.c
+++ b/libc/stdio/_fpmaxtostr.c
@@ -11,6 +11,11 @@
#include <locale.h>
#include <bits/uClibc_fpmax.h>
+libc_hidden_proto(memset)
+#ifdef __UCLIBC_HAS_LOCALE__
+libc_hidden_proto(__global_locale)
+#endif
+
typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
intptr_t buf);
@@ -198,7 +203,9 @@ static const __fpmax_t exp16_table[] = {
#define FPO_STR_WIDTH (0x80 | ' ');
#define FPO_STR_PREC 'p'
-ssize_t attribute_hidden _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
+ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
+ __fp_outfunc_t fp_outfunc) attribute_hidden;
+ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
__fp_outfunc_t fp_outfunc)
{
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
@@ -275,11 +282,11 @@ ssize_t attribute_hidden _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info
}
if (x == 0) { /* Handle 0 now to avoid false positive. */
-#if 1
+#ifdef __UCLIBC_HAVE_SIGNED_ZERO__
if (zeroisnegative(x)) { /* Handle 'signed' zero. */
*sign_str = '-';
}
-#endif
+#endif /* __UCLIBC_HAVE_SIGNED_ZERO__ */
exp = -1;
goto GENERATE_DIGITS;
}
@@ -417,7 +424,7 @@ ssize_t attribute_hidden _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info
if (mode == 'f') {
round += exp;
if (round < -1) {
- __memset(buf, '0', DECIMAL_DIG); /* OK, since 'f' -> decimal case. */
+ memset(buf, '0', DECIMAL_DIG); /* OK, since 'f' -> decimal case. */
exp = -1;
round = -1;
}
diff --git a/libc/stdio/_fwrite.c b/libc/stdio/_fwrite.c
index 600b15e6d..1e0f7ceee 100644
--- a/libc/stdio/_fwrite.c
+++ b/libc/stdio/_fwrite.c
@@ -5,11 +5,12 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define memrchr __memrchr
-#define memchr __memchr
-
#include "_stdio.h"
+libc_hidden_proto(memchr)
+libc_hidden_proto(memcpy)
+libc_hidden_proto(memrchr)
+
#ifdef __STDIO_BUFFERS
/* Either buffer data or (commit buffer if necessary and) write. */
@@ -35,7 +36,7 @@ size_t attribute_hidden __stdio_fwrite(const unsigned char * __restrict buffer,
if (pending > bytes) {
pending = bytes;
}
- __memcpy(stream->__bufpos, buffer, pending);
+ memcpy(stream->__bufpos, buffer, pending);
stream->__bufpos += pending;
__STDIO_STREAM_VALIDATE(stream);
return bytes;
@@ -43,7 +44,7 @@ size_t attribute_hidden __stdio_fwrite(const unsigned char * __restrict buffer,
/* RETRY: */
if (bytes <= __STDIO_STREAM_BUFFER_WAVAIL(stream)) {
- __memcpy(stream->__bufpos, buffer, bytes);
+ memcpy(stream->__bufpos, buffer, bytes);
stream->__bufpos += bytes;
if (__STDIO_STREAM_IS_LBF(stream)
&& memrchr(buffer, '\n', bytes) /* Search backwards. */
diff --git a/libc/stdio/_load_inttype.c b/libc/stdio/_load_inttype.c
index e4dc61e9c..057f5f256 100644
--- a/libc/stdio/_load_inttype.c
+++ b/libc/stdio/_load_inttype.c
@@ -8,7 +8,8 @@
#include "_stdio.h"
#include <printf.h>
-uintmax_t attribute_hidden _load_inttype(int desttype, register const void *src, int uflag)
+uintmax_t _load_inttype(int desttype, register const void *src, int uflag) attribute_hidden;
+uintmax_t _load_inttype(int desttype, register const void *src, int uflag)
{
if (uflag >= 0) { /* unsigned */
#if LONG_MAX != INT_MAX
diff --git a/libc/stdio/_ppfs_init.c b/libc/stdio/_ppfs_init.c
new file mode 100644
index 000000000..80d8aeb96
--- /dev/null
+++ b/libc/stdio/_ppfs_init.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L__ppfs_init
+#include "_vfprintf.c"
diff --git a/libc/stdio/_ppfs_parsespec.c b/libc/stdio/_ppfs_parsespec.c
new file mode 100644
index 000000000..a3e298801
--- /dev/null
+++ b/libc/stdio/_ppfs_parsespec.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L__ppfs_parsespec
+#include "_vfprintf.c"
diff --git a/libc/stdio/_ppfs_prepargs.c b/libc/stdio/_ppfs_prepargs.c
new file mode 100644
index 000000000..a6efbf466
--- /dev/null
+++ b/libc/stdio/_ppfs_prepargs.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L__ppfs_prepargs
+#include "_vfprintf.c"
diff --git a/libc/stdio/_ppfs_setargs.c b/libc/stdio/_ppfs_setargs.c
new file mode 100644
index 000000000..41214d993
--- /dev/null
+++ b/libc/stdio/_ppfs_setargs.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L__ppfs_setargs
+#include "_vfprintf.c"
diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
index e8d90a800..a967bd0de 100644
--- a/libc/stdio/_stdio.c
+++ b/libc/stdio/_stdio.c
@@ -5,10 +5,11 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define isatty __isatty
-
#include "_stdio.h"
+libc_hidden_proto(memcpy)
+libc_hidden_proto(isatty)
+
/* This is pretty much straight from uClibc, but with one important
* difference.
*
@@ -129,12 +130,19 @@ static FILE _stdio_streams[] = {
0 )
};
+/* psm: moved to _stdio.h: libc_hidden_proto(stdin/stdout) */
FILE *stdin = _stdio_streams;
+libc_hidden_data_def(stdin)
FILE *stdout = _stdio_streams + 1;
+libc_hidden_data_def(stdout)
+libc_hidden_proto(stderr)
FILE *stderr = _stdio_streams + 2;
+libc_hidden_data_def(stderr)
#ifdef __STDIO_GETC_MACRO
+libc_hidden_proto(__stdin)
FILE *__stdin = _stdio_streams; /* For getchar() macro. */
+libc_hidden_data_def(__stdin)
#endif
#ifdef __STDIO_PUTC_MACRO
FILE *__stdout = _stdio_streams + 1; /* For putchar() macro. */
@@ -156,6 +164,7 @@ FILE *__stdout = _stdio_streams + 1; /* For putchar() macro. */
*/
FILE *_stdio_openlist = _stdio_streams;
+libc_hidden_data_def(_stdio_openlist)
# ifdef __UCLIBC_HAS_THREADS__
# ifdef __USE_STDIO_FUTEXES__
@@ -164,6 +173,7 @@ _IO_lock_t _stdio_openlist_lock = _IO_lock_initializer;
# else
pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
# endif
+libc_hidden_data_def(_stdio_openlist_lock)
int _stdio_openlist_delflag = 0;
# endif
@@ -172,7 +182,9 @@ int _stdio_openlist_delflag = 0;
#ifdef __UCLIBC_HAS_THREADS__
/* 2 if threading not initialized and 0 otherwise; */
+libc_hidden_proto(_stdio_user_locking)
int _stdio_user_locking = 2;
+libc_hidden_data_def(_stdio_user_locking)
#ifndef __USE_STDIO_FUTEXES__
void attribute_hidden __stdio_init_mutex(pthread_mutex_t *m)
@@ -180,7 +192,7 @@ void attribute_hidden __stdio_init_mutex(pthread_mutex_t *m)
static const pthread_mutex_t __stdio_mutex_initializer
= PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
- __memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
+ memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
}
#endif
@@ -258,6 +270,7 @@ void attribute_hidden _stdio_term(void)
#endif
}
+#if defined __STDIO_BUFFERS || !defined __UCLIBC__
void attribute_hidden _stdio_init(void)
{
#ifdef __STDIO_BUFFERS
@@ -271,8 +284,9 @@ void attribute_hidden _stdio_init(void)
/* _stdio_term is done automatically when exiting if stdio is used.
* See misc/internals/__uClibc_main.c and and stdlib/atexit.c. */
atexit(_stdio_term);
-#endif /* __UCLIBC__ */
+#endif
}
+#endif
/**********************************************************************/
diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
index 50229ffb0..83d43352b 100644
--- a/libc/stdio/_stdio.h
+++ b/libc/stdio/_stdio.h
@@ -5,8 +5,6 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define _GNU_SOURCE
-
#include <features.h>
#include <assert.h>
#include <errno.h>
@@ -18,51 +16,19 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-
-extern int __vfprintf (FILE *__restrict __s, __const char *__restrict __format,
- __gnuc_va_list __arg) attribute_hidden;
-
-extern int __vsnprintf (char *__restrict __s, size_t __maxlen,
- __const char *__restrict __format, __gnuc_va_list __arg)
- __THROW __attribute__ ((__format__ (__printf__, 3, 0))) attribute_hidden;
-
-extern int __vfscanf (FILE *__restrict __s, __const char *__restrict __format,
- __gnuc_va_list __arg)
- __attribute__ ((__format__ (__scanf__, 2, 0))) attribute_hidden;
-
-extern int __vsscanf (__const char *__restrict __s,
- __const char *__restrict __format, __gnuc_va_list __arg)
- __THROW __attribute__ ((__format__ (__scanf__, 2, 0))) attribute_hidden;
-
#ifdef __UCLIBC_HAS_WCHAR__
#include <wchar.h>
+#endif
-extern int __vfwprintf (__FILE *__restrict __s,
- __const wchar_t *__restrict __format,
- __gnuc_va_list __arg) attribute_hidden;
-
-extern int __vfwscanf (__FILE *__restrict __s,
- __const wchar_t *__restrict __format,
- __gnuc_va_list __arg) attribute_hidden;
+libc_hidden_proto(stdin)
+libc_hidden_proto(stdout)
-extern int __vswscanf (__const wchar_t *__restrict __s,
- __const wchar_t *__restrict __format,
- __gnuc_va_list __arg) __THROW attribute_hidden;
-#endif
+libc_hidden_proto(_stdio_openlist)
#ifdef __UCLIBC_HAS_THREADS__
#include <pthread.h>
+libc_hidden_proto(_stdio_openlist_lock)
-#ifdef __USE_STDIO_FUTEXES___
-#define __STDIO_THREADLOCK_OPENLIST \
- _IO_lock_lock(_stdio_openlist_lock)
-
-#define __STDIO_THREADUNLOCK_OPENLIST \
- _IO_lock_unlock(_stdio_openlist_lock)
-
-#define __STDIO_THREADTRYLOCK_OPENLIST \
- _IO_lock_trylock(_stdio_openlist_lock)
-#else
#define __STDIO_THREADLOCK_OPENLIST \
__pthread_mutex_lock(&_stdio_openlist_lock)
@@ -71,9 +37,6 @@ extern int __vswscanf (__const wchar_t *__restrict __s,
#define __STDIO_THREADTRYLOCK_OPENLIST \
__pthread_mutex_trylock(&_stdio_openlist_lock)
-#endif
-
-
#else
@@ -300,8 +263,6 @@ extern int __stdio_trans2w(FILE *__restrict stream) attribute_hidden;
extern int __stdio_trans2r_o(FILE *__restrict stream, int oflag) attribute_hidden;
extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidden;
-extern int __setvbuf (FILE *__restrict __stream, char *__restrict __buf,
- int __modes, size_t __n) __THROW attribute_hidden;
/**********************************************************************/
#ifdef __STDIO_BUFFERS
@@ -389,46 +350,11 @@ extern int __setvbuf (FILE *__restrict __stream, char *__restrict __buf,
#endif /* __STDIO_BUFFERS */
/**********************************************************************/
-extern int __fputs_unlocked(const char *__restrict s, FILE *__restrict stream) attribute_hidden;
-
-extern int __putchar_unlocked(int c);
-
-
-extern size_t __fwrite_unlocked(const void *__restrict ptr, size_t size,
- size_t nmemb, FILE *__restrict stream) attribute_hidden;
-
-extern size_t __fread_unlocked(void *__restrict ptr, size_t size,
- size_t nmemb, FILE *__restrict stream) attribute_hidden;
-
-extern int __fputc_unlocked_internal(int c, FILE *stream) attribute_hidden;
-
-extern int __fflush_unlocked(FILE *stream) attribute_hidden;
-
extern int __stdio_adjust_position(FILE *__restrict stream, __offmax_t *pos) attribute_hidden;
-extern void __clearerr_unlocked(FILE *stream);
-extern int __feof_unlocked(FILE *stream);
-extern int __ferror_unlocked(FILE *stream);
-
-extern int __fgetc_unlocked_internal(FILE *stream) attribute_hidden;
-extern int __getc_unlocked(FILE *stream) attribute_hidden;
-extern char *__fgets_unlocked(char *__restrict s, int n,
- FILE * __restrict stream) attribute_hidden;
-
-extern int __fileno_unlocked(FILE *stream) attribute_hidden;
-
-extern int __getchar_unlocked(void) attribute_hidden;
-
-extern int __fseek(FILE *stream, long int offset, int whence) attribute_hidden;
-extern long int __ftell(FILE *stream) attribute_hidden;
-#ifdef __UCLIBC_HAS_LFS__
-extern int __fseeko64(FILE *stream, __off64_t offset, int whence) attribute_hidden;
-extern __off64_t __ftello64(FILE *stream) attribute_hidden;
-#endif
-
#ifdef __STDIO_HAS_OPENLIST
/* Uses an implementation hack!!! */
-#define __STDIO_FLUSH_LBF_STREAMS __fflush_unlocked((FILE *) &_stdio_openlist)
+#define __STDIO_FLUSH_LBF_STREAMS fflush_unlocked((FILE *) &_stdio_openlist)
#else
#define __STDIO_FLUSH_LBF_STREAMS ((void)0)
#endif
@@ -451,14 +377,6 @@ extern void _stdio_validate_FILE(const FILE *stream);
/**********************************************************************/
-extern int _stdio_adjpos(FILE *__restrict stream, __offmax_t * pos);
-extern int _stdio_lseek(FILE *stream, __offmax_t *pos, int whence);
-
-extern size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
- FILE *stream);
-extern size_t _stdio_fread(unsigned char *buffer, size_t bytes,
- FILE *stream);
-
extern FILE *_stdio_fopen(intptr_t fname_or_mode,
const char *__restrict mode,
FILE *__restrict stream, int filedes) attribute_hidden;
@@ -466,9 +384,6 @@ extern FILE *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_WCHAR__
extern size_t _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
FILE *__restrict stream) attribute_hidden;
-
-extern wint_t __fgetwc_unlocked(register FILE *stream) attribute_hidden;
-extern wint_t __fputwc_unlocked(wchar_t wc, FILE *stream) attribute_hidden;
#endif
/**********************************************************************/
diff --git a/libc/stdio/_store_inttype.c b/libc/stdio/_store_inttype.c
index 82fb894c6..6eb74fe86 100644
--- a/libc/stdio/_store_inttype.c
+++ b/libc/stdio/_store_inttype.c
@@ -28,7 +28,8 @@
/* We assume int may be short or long, but short and long are different. */
-void attribute_hidden _store_inttype(register void *dest, int desttype, uintmax_t val)
+void _store_inttype(register void *dest, int desttype, uintmax_t val) attribute_hidden;
+void _store_inttype(register void *dest, int desttype, uintmax_t val)
{
if (desttype == __PA_FLAG_CHAR) { /* assume char not int */
*((unsigned char *) dest) = val;
diff --git a/libc/stdio/_trans2w.c b/libc/stdio/_trans2w.c
index 650a5e1a0..ed1a583fc 100644
--- a/libc/stdio/_trans2w.c
+++ b/libc/stdio/_trans2w.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(fseek)
+
/* Function to handle transition to writing.
* Initialize or verify the stream's orientation (even if readonly).
* Check that the stream is writable.
@@ -64,7 +66,7 @@ int attribute_hidden __stdio_trans2w(FILE * __restrict stream)
* the end even if not reading.*/
if (((__STDIO_STREAM_BUFFER_RAVAIL(stream))
|| (stream->__modeflags & __FLAG_UNGOT))
- && __fseek(stream, 0L,
+ && fseek(stream, 0L,
((stream->__modeflags & __FLAG_APPEND)
? SEEK_END : SEEK_CUR))
) {
diff --git a/libc/stdio/_uintmaxtostr.c b/libc/stdio/_uintmaxtostr.c
index bf92506d5..f9c83506e 100644
--- a/libc/stdio/_uintmaxtostr.c
+++ b/libc/stdio/_uintmaxtostr.c
@@ -11,6 +11,11 @@
#include <locale.h>
#include <bits/uClibc_uintmaxtostr.h>
+libc_hidden_proto(memcpy)
+#ifdef __UCLIBC_HAS_LOCALE__
+libc_hidden_proto(__global_locale)
+#endif
+
/* Avoid using long long / and % operations to cut down dependencies on
* libgcc.a. Definitely helps on i386 at least. */
#if (INTMAX_MAX > INT_MAX) && (((INTMAX_MAX/INT_MAX)/2) - 2 <= INT_MAX)
@@ -61,7 +66,7 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_
#ifndef __LOCALE_C_ONLY
if (!grouping) { /* Finished a group. */
bufend -= __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
- __memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
+ memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
__UCLIBC_CURLOCALE_DATA.thousands_sep_len);
if (g[1] != 0) { /* g[1] == 0 means repeat last grouping. */
/* Note: g[1] == -1 means no further grouping. But since
@@ -79,7 +84,7 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_
#ifndef __LOCALE_C_ONLY
if (unlikely(outdigit)) {
bufend -= __UCLIBC_CURLOCALE_DATA.outdigit_length[digit];
- __memcpy(bufend,
+ memcpy(bufend,
(&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit],
__UCLIBC_CURLOCALE_DATA.outdigit_length[digit]);
} else
@@ -104,7 +109,7 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_
#ifndef __LOCALE_C_ONLY
if (!grouping) { /* Finished a group. */
bufend -= __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
- __memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
+ memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
__UCLIBC_CURLOCALE_DATA.thousands_sep_len);
if (g[1] != 0) { /* g[1] == 0 means repeat last grouping. */
/* Note: g[1] == -1 means no further grouping. But since
@@ -131,7 +136,7 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_
#ifndef __LOCALE_C_ONLY
if (unlikely(outdigit)) {
bufend -= __UCLIBC_CURLOCALE_DATA.outdigit_length[digit];
- __memcpy(bufend,
+ memcpy(bufend,
(&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit],
__UCLIBC_CURLOCALE_DATA.outdigit_length[digit]);
} else
diff --git a/libc/stdio/_vfprintf.c b/libc/stdio/_vfprintf.c
new file mode 100644
index 000000000..a32960f2e
--- /dev/null
+++ b/libc/stdio/_vfprintf.c
@@ -0,0 +1,1951 @@
+/* Copyright (C) 2002-2004 Manuel Novoa III
+ * My stdio library for linux and (soon) elks.
+ *
+ * This 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.
+ *
+ * This 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 this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This code needs a lot of clean up. Some of that is on hold until uClibc
+ * gets a better configuration system (on Erik's todo list).
+ * The other cleanup will take place during the implementation/integration of
+ * the wide char (un)formatted i/o functions which I'm currently working on.
+ */
+
+/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+ *
+ * This code is currently under development. Also, I plan to port
+ * it to elks which is a 16-bit environment with a fairly limited
+ * compiler. Therefore, please refrain from modifying this code
+ * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel
+ *
+ * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
+
+
+/* April 1, 2002
+ * Initialize thread locks for fake files in vsnprintf and vdprintf.
+ * reported by Erik Andersen (andersen@codepoet.com)
+ * Fix an arg promotion handling bug in _do_one_spec for %c.
+ * reported by Ilguiz Latypov <ilatypov@superbt.com>
+ *
+ * May 10, 2002
+ * Remove __isdigit and use new ctype.h version.
+ * Add conditional setting of QUAL_CHARS for size_t and ptrdiff_t.
+ *
+ * Aug 16, 2002
+ * Fix two problems that showed up with the python 2.2.1 tests; one
+ * involving %o and one involving %f.
+ *
+ * Oct 28, 2002
+ * Fix a problem in vasprintf (reported by vodz a while back) when built
+ * without custom stream support. In that case, it is necessary to do
+ * a va_copy.
+ * Make sure each va_copy has a matching va_end, as required by C99.
+ *
+ * Nov 4, 2002
+ * Add locale-specific grouping support for integer decimal conversion.
+ * Add locale-specific decimal point support for floating point conversion.
+ * Note: grouping will have to wait for _dtostr() rewrite.
+ * Add printf wchar support for %lc (%C) and %ls (%S).
+ * Require printf format strings to be valid multibyte strings beginning and
+ * ending in their initial shift state, as per the stds.
+ *
+ * Nov 21, 2002
+ * Add *wprintf functions. Currently they don't support floating point
+ * conversions. That will wait until the rewrite of _dtostr.
+ *
+ * Aug 1, 2003
+ * Optional hexadecimal float notation support for %a/%A.
+ * Floating point output now works for *wprintf.
+ * Support for glibc locale-specific digit grouping for floats.
+ * Misc bug fixes.
+ *
+ * Aug 31, 2003
+ * Fix precision bug for %g conversion specifier when using %f style.
+ *
+ * Sep 5, 2003
+ * Implement *s*scanf for the non-buffered stdio case with old_vfprintf.
+ *
+ * Sep 23, 2003
+ * vfprintf was not always checking for narrow stream orientation.
+ */
+
+/* TODO:
+ *
+ * Should we validate that *printf format strings are valid multibyte
+ * strings in the current locale? ANSI/ISO C99 seems to imply this
+ * and Plauger's printf implementation in his Standard C Library book
+ * treats this as an error.
+ */
+
+#define _ISOC99_SOURCE /* for ULLONG primarily... */
+#include <features.h>
+#include "_stdio.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <stdint.h>
+#include <errno.h>
+#include <locale.h>
+
+#define __PRINTF_INFO_NO_BITFIELD
+#include <printf.h>
+
+#ifdef __UCLIBC_HAS_THREADS__
+#include <stdio_ext.h>
+#include <pthread.h>
+#endif /* __UCLIBC_HAS_THREADS__ */
+
+#ifdef __UCLIBC_HAS_WCHAR__
+#include <wchar.h>
+#endif /* __UCLIBC_HAS_WCHAR__ */
+
+#include <bits/uClibc_uintmaxtostr.h>
+#include <bits/uClibc_va_copy.h>
+
+libc_hidden_proto(memcpy)
+libc_hidden_proto(memset)
+libc_hidden_proto(strlen)
+libc_hidden_proto(strnlen)
+libc_hidden_proto(__glibc_strerror_r)
+libc_hidden_proto(fputs_unlocked)
+libc_hidden_proto(abort)
+#ifdef __UCLIBC_HAS_WCHAR__
+libc_hidden_proto(wcslen)
+libc_hidden_proto(wcsnlen)
+libc_hidden_proto(mbsrtowcs)
+libc_hidden_proto(wcsrtombs)
+libc_hidden_proto(btowc)
+libc_hidden_proto(wcrtomb)
+libc_hidden_proto(fputws)
+#endif
+
+/* Some older or broken gcc toolchains define LONG_LONG_MAX but not
+ * LLONG_MAX. Since LLONG_MAX is part of the standard, that's what
+ * we use. So complain if we do not have it but should.
+ */
+#if !defined(LLONG_MAX) && defined(LONG_LONG_MAX)
+#error Apparently, LONG_LONG_MAX is defined but LLONG_MAX is not. You need to fix your toolchain headers to support the standard macros for (unsigned) long long.
+#endif
+
+/**********************************************************************/
+/* These provide some control over printf's feature set */
+
+/* This is undefined below depeding on uClibc's configuration. */
+#define __STDIO_PRINTF_FLOAT 1
+
+/* Now controlled by uClibc_stdio.h. */
+/* #define __UCLIBC_HAS_PRINTF_M_SPEC__ */
+
+
+/**********************************************************************/
+
+#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_FLOATS__)
+#undef __STDIO_PRINTF_FLOAT
+#endif
+
+#ifdef __BCC__
+#undef __STDIO_PRINTF_FLOAT
+#endif
+
+#ifdef __STDIO_PRINTF_FLOAT
+#include <float.h>
+#include <bits/uClibc_fpmax.h>
+#else /* __STDIO_PRINTF_FLOAT */
+#undef L__fpmaxtostr
+#endif /* __STDIO_PRINTF_FLOAT */
+
+
+#undef __STDIO_HAS_VSNPRINTF
+#if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
+#define __STDIO_HAS_VSNPRINTF 1
+#endif
+
+/**********************************************************************/
+
+/* Now controlled by uClibc_stdio.h. */
+/* #define __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+
+/* TODO -- move these to a configuration section? */
+#define MAX_FIELD_WIDTH 4095
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#ifdef L_register_printf_function
+/* emit only once */
+#warning WISHLIST: Make MAX_USER_SPEC configurable?
+#warning WISHLIST: Make MAX_ARGS_PER_SPEC configurable?
+#endif
+#endif /* __UCLIBC_MJN3_ONLY__ */
+
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
+
+#define MAX_USER_SPEC 10
+#define MAX_ARGS_PER_SPEC 5
+
+#else /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+
+#undef MAX_USER_SPEC
+#define MAX_ARGS_PER_SPEC 1
+
+#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+
+#if MAX_ARGS_PER_SPEC < 1
+#error MAX_ARGS_PER_SPEC < 1!
+#undef MAX_ARGS_PER_SPEC
+#define MAX_ARGS_PER_SPEC 1
+#endif
+
+#if defined(NL_ARGMAX) && (NL_ARGMAX < 9)
+#error NL_ARGMAX < 9!
+#endif
+
+#if defined(NL_ARGMAX) && (NL_ARGMAX >= (MAX_ARGS_PER_SPEC + 2))
+#define MAX_ARGS NL_ARGMAX
+#else
+/* N for spec itself, plus 1 each for width and precision */
+#define MAX_ARGS (MAX_ARGS_PER_SPEC + 2)
+#endif
+
+/**********************************************************************/
+
+#define __PA_FLAG_INTMASK \
+ (__PA_FLAG_CHAR|PA_FLAG_SHORT|__PA_FLAG_INT|PA_FLAG_LONG|PA_FLAG_LONG_LONG)
+
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
+extern printf_function _custom_printf_handler[MAX_USER_SPEC] attribute_hidden;
+extern printf_arginfo_function *_custom_printf_arginfo[MAX_USER_SPEC] attribute_hidden;
+extern char *_custom_printf_spec attribute_hidden;
+#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+
+/**********************************************************************/
+
+#define SPEC_FLAGS " +0-#'I"
+enum {
+ FLAG_SPACE = 0x01,
+ FLAG_PLUS = 0x02, /* must be 2 * FLAG_SPACE */
+ FLAG_ZERO = 0x04,
+ FLAG_MINUS = 0x08, /* must be 2 * FLAG_ZERO */
+ FLAG_HASH = 0x10,
+ FLAG_THOUSANDS = 0x20,
+ FLAG_I18N = 0x40, /* only works for d, i, u */
+ FLAG_WIDESTREAM = 0x80
+};
+
+/**********************************************************************/
+
+/* float layout 01234567890123456789 TODO: B?*/
+#define SPEC_CHARS "npxXoudifFeEgGaACScs"
+enum {
+ CONV_n = 0,
+ CONV_p,
+ CONV_x, CONV_X, CONV_o, CONV_u, CONV_d, CONV_i,
+ CONV_f, CONV_F, CONV_e, CONV_E, CONV_g, CONV_G, CONV_a, CONV_A,
+ CONV_C, CONV_S, CONV_c, CONV_s,
+#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
+ CONV_m,
+#endif
+ CONV_custom0 /* must be last */
+};
+
+/* p x X o u d i */
+#define SPEC_BASE { 16, 16, 16, 8, 10, 10, 10 }
+
+#define SPEC_RANGES { CONV_n, CONV_p, CONV_i, CONV_A, \
+ CONV_C, CONV_S, CONV_c, CONV_s, CONV_custom0 }
+
+#define SPEC_OR_MASK { \
+ /* n */ (PA_FLAG_PTR|PA_INT), \
+ /* p */ PA_POINTER, \
+ /* oxXudi */ PA_INT, \
+ /* fFeEgGaA */ PA_DOUBLE, \
+ /* C */ PA_WCHAR, \
+ /* S */ PA_WSTRING, \
+ /* c */ PA_CHAR, \
+ /* s */ PA_STRING, \
+}
+
+#define SPEC_AND_MASK { \
+ /* n */ (PA_FLAG_PTR|__PA_INTMASK), \
+ /* p */ PA_POINTER, \
+ /* oxXudi */ (__PA_INTMASK), \
+ /* fFeEgGaA */ (PA_FLAG_LONG_DOUBLE|PA_DOUBLE), \
+ /* C */ (PA_WCHAR), \
+ /* S */ (PA_WSTRING), \
+ /* c */ (PA_CHAR), \
+ /* s */ (PA_STRING), \
+}
+
+/**********************************************************************/
+/*
+ * In order to ease translation to what arginfo and _print_info._flags expect,
+ * we map: 0:int 1:char 2:longlong 4:long 8:short
+ * and then _flags |= (((q << 7) + q) & 0x701) and argtype |= (_flags & 0x701)
+ */
+
+/* TODO -- Fix the table below to take into account stdint.h. */
+/* #ifndef LLONG_MAX */
+/* #error fix QUAL_CHARS for no long long! Affects 'L', 'j', 'q', 'll'. */
+/* #else */
+/* #if LLONG_MAX != INTMAX_MAX */
+/* #error fix QUAL_CHARS intmax_t entry 'j'! */
+/* #endif */
+/* #endif */
+
+#ifdef PDS
+#error PDS already defined!
+#endif
+#ifdef SS
+#error SS already defined!
+#endif
+#ifdef IMS
+#error IMS already defined!
+#endif
+
+#if PTRDIFF_MAX == INT_MAX
+#define PDS 0
+#elif PTRDIFF_MAX == LONG_MAX
+#define PDS 4
+#elif defined(LLONG_MAX) && (PTRDIFF_MAX == LLONG_MAX)
+#define PDS 8
+#else
+#error fix QUAL_CHARS ptrdiff_t entry 't'!
+#endif
+
+#if SIZE_MAX == UINT_MAX
+#define SS 0
+#elif SIZE_MAX == ULONG_MAX
+#define SS 4
+#elif defined(LLONG_MAX) && (SIZE_MAX == ULLONG_MAX)
+#define SS 8
+#else
+#error fix QUAL_CHARS size_t entries 'z', 'Z'!
+#endif
+
+#if INTMAX_MAX == INT_MAX
+#define IMS 0
+#elif INTMAX_MAX == LONG_MAX
+#define IMS 4
+#elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX)
+#define IMS 8
+#else
+#error fix QUAL_CHARS intmax_t entry 'j'!
+#endif
+
+#define QUAL_CHARS { \
+ /* j:(u)intmax_t z:(s)size_t t:ptrdiff_t \0:int */ \
+ /* q:long_long Z:(s)size_t */ \
+ 'h', 'l', 'L', 'j', 'z', 't', 'q', 'Z', 0, \
+ 2, 4, 8, IMS, SS, PDS, 8, SS, 0, /* TODO -- fix!!! */\
+ 1, 8 \
+}
+
+/**********************************************************************/
+
+#ifdef __STDIO_VA_ARG_PTR
+#ifdef __BCC__
+#define __va_arg_ptr(ap,type) (((type *)(ap += sizeof(type))) - 1)
+#endif
+
+#if 1
+#ifdef __GNUC__
+/* TODO -- need other than for 386 as well! */
+
+#ifndef __va_rounded_size
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+#endif
+#define __va_arg_ptr(AP, TYPE) \
+ (AP = (va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ ((void *) ((char *) (AP) - __va_rounded_size (TYPE))))
+#endif
+#endif
+#endif /* __STDIO_VA_ARG_PTR */
+
+#ifdef __va_arg_ptr
+#define GET_VA_ARG(AP,F,TYPE,ARGS) (*(AP) = __va_arg_ptr(ARGS,TYPE))
+#define GET_ARG_VALUE(AP,F,TYPE) (*((TYPE *)(*(AP))))
+#else
+typedef union {
+ wchar_t wc;
+ unsigned int u;
+ unsigned long ul;
+#ifdef ULLONG_MAX
+ unsigned long long ull;
+#endif
+#ifdef __STDIO_PRINTF_FLOAT
+ double d;
+ long double ld;
+#endif /* __STDIO_PRINTF_FLOAT */
+ void *p;
+} argvalue_t;
+
+#define GET_VA_ARG(AU,F,TYPE,ARGS) (AU->F = va_arg(ARGS,TYPE))
+#define GET_ARG_VALUE(AU,F,TYPE) ((TYPE)((AU)->F))
+#endif
+
+typedef struct {
+ const char *fmtpos; /* TODO: move below struct?? */
+ struct printf_info info;
+#ifdef NL_ARGMAX
+ int maxposarg; /* > 0 if args are positional, 0 if not, -1 if unknown */
+#endif /* NL_ARGMAX */
+ int num_data_args; /* TODO: use sentinal??? */
+ unsigned int conv_num;
+ unsigned char argnumber[4]; /* width | prec | 1st data | unused */
+ int argtype[MAX_ARGS];
+ va_list arg;
+#ifdef __va_arg_ptr
+ void *argptr[MAX_ARGS];
+#else
+/* if defined(NL_ARGMAX) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__) */
+ /* While this is wasteful of space in the case where pos args aren't
+ * enabled, it is also needed to support custom printf handlers. */
+ argvalue_t argvalue[MAX_ARGS];
+#endif
+} ppfs_t; /* parse printf format state */
+
+/**********************************************************************/
+
+/* TODO: fix printf to return 0 and set errno if format error. Standard says
+ only returns -1 if sets error indicator for the stream. */
+
+#ifdef __STDIO_PRINTF_FLOAT
+typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
+ intptr_t buf);
+
+extern ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
+ __fp_outfunc_t fp_outfunc) attribute_hidden;
+#endif
+
+extern int _ppfs_init(ppfs_t *ppfs, const char *fmt0) attribute_hidden; /* validates */
+extern void _ppfs_prepargs(ppfs_t *ppfs, va_list arg) attribute_hidden; /* sets posargptrs */
+extern void _ppfs_setargs(ppfs_t *ppfs) attribute_hidden; /* sets argptrs for current spec */
+extern int _ppfs_parsespec(ppfs_t *ppfs) attribute_hidden; /* parses specifier */
+
+extern void _store_inttype(void *dest, int desttype, uintmax_t val) attribute_hidden;
+extern uintmax_t _load_inttype(int desttype, const void *src, int uflag) attribute_hidden;
+
+/**********************************************************************/
+#ifdef L_parse_printf_format
+
+/* NOTE: This function differs from the glibc version in that parsing stops
+ * upon encountering an invalid conversion specifier. Since this is the way
+ * my printf functions work, I think it makes sense to do it that way here.
+ * Unfortunately, since glibc sets the return type as size_t, we have no way
+ * of returning that the template is illegal, other than returning 0.
+ */
+
+size_t parse_printf_format(register const char *template,
+ size_t n, register int *argtypes)
+{
+ ppfs_t ppfs;
+ size_t i;
+ size_t count = 0;
+
+ if (_ppfs_init(&ppfs, template) >= 0) {
+#ifdef NL_ARGMAX
+ if (ppfs.maxposarg > 0) { /* Using positional args. */
+ count = ppfs.maxposarg;
+ if (n > count) {
+ n = count;
+ }
+ for (i = 0 ; i < n ; i++) {
+ *argtypes++ = ppfs.argtype[i];
+ }
+ } else { /* Not using positional args. */
+#endif /* NL_ARGMAX */
+ while (*template) {
+ if ((*template == '%') && (*++template != '%')) {
+ ppfs.fmtpos = template;
+ _ppfs_parsespec(&ppfs); /* Can't fail. */
+ template = ppfs.fmtpos; /* Update to one past spec end. */
+ if (ppfs.info.width == INT_MIN) {
+ ++count;
+ if (n > 0) {
+ *argtypes++ = PA_INT;
+ --n;
+ }
+ }
+ if (ppfs.info.prec == INT_MIN) {
+ ++count;
+ if (n > 0) {
+ *argtypes++ = PA_INT;
+ --n;
+ }
+ }
+ for (i = 0 ; i < ppfs.num_data_args ; i++) {
+ if ((ppfs.argtype[i]) != __PA_NOARG) {
+ ++count;
+ if (n > 0) {
+ *argtypes++ = ppfs.argtype[i];
+ --n;
+ }
+ }
+ }
+ } else {
+ ++template;
+ }
+ }
+#ifdef NL_ARGMAX
+ }
+#endif /* NL_ARGMAX */
+ }
+
+ return count;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L__ppfs_init
+
+#ifdef __UCLIBC_HAS_LOCALE__
+libc_hidden_proto(__global_locale)
+#endif
+
+int attribute_hidden _ppfs_init(register ppfs_t *ppfs, const char *fmt0)
+{
+ int r;
+
+ /* First, zero out everything... argnumber[], argtype[], argptr[] */
+ memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */
+#ifdef NL_ARGMAX
+ --ppfs->maxposarg; /* set to -1 */
+#endif /* NL_ARGMAX */
+ ppfs->fmtpos = fmt0;
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO: Make checking of the format string in C locale an option.
+#endif
+#ifdef __UCLIBC_HAS_LOCALE__
+ /* To support old programs, don't check mb validity if in C locale. */
+ if (((__UCLIBC_CURLOCALE_DATA).encoding) != __ctype_encoding_7_bit) {
+ /* ANSI/ISO C99 requires format string to be a valid multibyte string
+ * beginning and ending in its initial shift state. */
+ static const char invalid_mbs[] = "Invalid multibyte format string.";
+ mbstate_t mbstate;
+ const char *p;
+ mbstate.__mask = 0; /* Initialize the mbstate. */
+ p = fmt0;
+ if (mbsrtowcs(NULL, &p, SIZE_MAX, &mbstate) == ((size_t)(-1))) {
+ ppfs->fmtpos = invalid_mbs;
+ return -1;
+ }
+ }
+#endif /* __UCLIBC_HAS_LOCALE__ */
+ /* now set all argtypes to no-arg */
+ {
+#if 1
+ /* TODO - use memset here since already "paid for"? */
+ register int *p = ppfs->argtype;
+
+ r = MAX_ARGS;
+ do {
+ *p++ = __PA_NOARG;
+ } while (--r);
+#else
+ /* TODO -- get rid of this?? */
+ register char *p = (char *) ((MAX_ARGS-1) * sizeof(int));
+
+ do {
+ *((int *)(((char *)ppfs) + ((int)p) + offsetof(ppfs_t,argtype))) = __PA_NOARG;
+ p -= sizeof(int);
+ } while (p);
+#endif
+ }
+
+ /*
+ * Run through the entire format string to validate it and initialize
+ * the positional arg numbers (if any).
+ */
+ {
+ register const char *fmt = fmt0;
+
+ while (*fmt) {
+ if ((*fmt == '%') && (*++fmt != '%')) {
+ ppfs->fmtpos = fmt; /* back up to the '%' */
+ if ((r = _ppfs_parsespec(ppfs)) < 0) {
+ return -1;
+ }
+ fmt = ppfs->fmtpos; /* update to one past end of spec */
+ } else {
+ ++fmt;
+ }
+ }
+ ppfs->fmtpos = fmt0; /* rewind */
+ }
+
+#ifdef NL_MAX_ARG
+ /* If we have positional args, make sure we know all the types. */
+ {
+ register int *p = ppfs->argtype;
+ r = ppfs->maxposarg;
+ while (--r >= 0) {
+ if ( *p == __PA_NOARG ) { /* missing arg type!!! */
+ return -1;
+ }
+ ++p;
+ }
+ }
+#endif /* NL_MAX_ARG */
+
+ return 0;
+}
+#endif
+/**********************************************************************/
+#ifdef L__ppfs_prepargs
+void attribute_hidden _ppfs_prepargs(register ppfs_t *ppfs, va_list arg)
+{
+ int i;
+
+ va_copy(ppfs->arg, arg);
+
+#ifdef NL_ARGMAX
+ if ((i = ppfs->maxposarg) > 0) { /* init for positional args */
+ ppfs->num_data_args = i;
+ ppfs->info.width = ppfs->info.prec = ppfs->maxposarg = 0;
+ _ppfs_setargs(ppfs);
+ ppfs->maxposarg = i;
+ }
+#endif /* NL_ARGMAX */
+}
+#endif
+/**********************************************************************/
+#ifdef L__ppfs_setargs
+
+void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs)
+{
+#ifdef __va_arg_ptr
+ register void **p = ppfs->argptr;
+#else
+ register argvalue_t *p = ppfs->argvalue;
+#endif
+ int i;
+
+#ifdef NL_ARGMAX
+ if (ppfs->maxposarg == 0) { /* initing for or no pos args */
+#endif /* NL_ARGMAX */
+ if (ppfs->info.width == INT_MIN) {
+ ppfs->info.width =
+#ifdef __va_arg_ptr
+ *(int *)
+#endif
+ GET_VA_ARG(p,u,unsigned int,ppfs->arg);
+ }
+ if (ppfs->info.prec == INT_MIN) {
+ ppfs->info.prec =
+#ifdef __va_arg_ptr
+ *(int *)
+#endif
+ GET_VA_ARG(p,u,unsigned int,ppfs->arg);
+ }
+ i = 0;
+ while (i < ppfs->num_data_args) {
+ switch(ppfs->argtype[i++]) {
+ case (PA_INT|PA_FLAG_LONG_LONG):
+#ifdef ULLONG_MAX
+ GET_VA_ARG(p,ull,unsigned long long,ppfs->arg);
+ break;
+#endif
+ case (PA_INT|PA_FLAG_LONG):
+#if ULONG_MAX != UINT_MAX
+ GET_VA_ARG(p,ul,unsigned long,ppfs->arg);
+ break;
+#endif
+ case PA_CHAR: /* TODO - be careful */
+ /* ... users could use above and really want below!! */
+ case (PA_INT|__PA_FLAG_CHAR):/* TODO -- translate this!!! */
+ case (PA_INT|PA_FLAG_SHORT):
+ case PA_INT:
+ GET_VA_ARG(p,u,unsigned int,ppfs->arg);
+ break;
+ case PA_WCHAR: /* TODO -- assume int? */
+ /* we're assuming wchar_t is at least an int */
+ GET_VA_ARG(p,wc,wchar_t,ppfs->arg);
+ break;
+#ifdef __STDIO_PRINTF_FLOAT
+ /* PA_FLOAT */
+ case PA_DOUBLE:
+ GET_VA_ARG(p,d,double,ppfs->arg);
+ break;
+ case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE):
+ GET_VA_ARG(p,ld,long double,ppfs->arg);
+ break;
+#else /* __STDIO_PRINTF_FLOAT */
+ case PA_DOUBLE:
+ case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE):
+ assert(0);
+ continue;
+#endif /* __STDIO_PRINTF_FLOAT */
+ default:
+ /* TODO -- really need to ensure this can't happen */
+ assert(ppfs->argtype[i-1] & PA_FLAG_PTR);
+ case PA_POINTER:
+ case PA_STRING:
+ case PA_WSTRING:
+ GET_VA_ARG(p,p,void *,ppfs->arg);
+ break;
+ case __PA_NOARG:
+ continue;
+ }
+ ++p;
+ }
+#ifdef NL_ARGMAX
+ } else {
+ if (ppfs->info.width == INT_MIN) {
+ ppfs->info.width
+ = (int) GET_ARG_VALUE(p + ppfs->argnumber[0] - 1,u,unsigned int);
+ }
+ if (ppfs->info.prec == INT_MIN) {
+ ppfs->info.prec
+ = (int) GET_ARG_VALUE(p + ppfs->argnumber[1] - 1,u,unsigned int);
+ }
+ }
+#endif /* NL_ARGMAX */
+
+ /* Now we know the width and precision. */
+ if (ppfs->info.width < 0) {
+ ppfs->info.width = -ppfs->info.width;
+ PRINT_INFO_SET_FLAG(&(ppfs->info),left);
+ PRINT_INFO_CLR_FLAG(&(ppfs->info),space);
+ ppfs->info.pad = ' ';
+ }
+#if 0
+ /* NOTE -- keep neg for now so float knows! */
+ if (ppfs->info.prec < 0) { /* spec says treat as omitted. */
+ /* so use default prec... 1 for everything but floats and strings. */
+ ppfs->info.prec = 1;
+ }
+#endif
+}
+#endif
+/**********************************************************************/
+#ifdef L__ppfs_parsespec
+
+#ifdef __UCLIBC_HAS_XLOCALE__
+libc_hidden_proto(__ctype_b_loc)
+#else
+libc_hidden_proto(__ctype_b)
+#endif
+
+/* Notes: argtype differs from glibc for the following:
+ * mine glibc
+ * lc PA_WCHAR PA_CHAR the standard says %lc means %C
+ * ls PA_WSTRING PA_STRING the standard says %ls means %S
+ * {*}n {*}|PA_FLAG_PTR PA_FLAG_PTR size of n can be qualified
+ */
+
+/* TODO: store positions of positional args */
+
+/* TODO -- WARNING -- assumes aligned on integer boundaries!!! */
+
+/* TODO -- disable if not using positional args!!! */
+#define _OVERLAPPING_DIFFERENT_ARGS
+
+/* TODO -- rethink this -- perhaps we should set to largest type??? */
+
+#ifdef _OVERLAPPING_DIFFERENT_ARGS
+
+#define PROMOTED_SIZE_OF(X) ((sizeof(X) + sizeof(int) - 1) / sizeof(X))
+
+static const short int type_codes[] = {
+ __PA_NOARG, /* must be first entry */
+ PA_POINTER,
+ PA_STRING,
+ PA_WSTRING,
+ PA_CHAR,
+ PA_INT|PA_FLAG_SHORT,
+ PA_INT,
+ PA_INT|PA_FLAG_LONG,
+ PA_INT|PA_FLAG_LONG_LONG,
+ PA_WCHAR,
+#ifdef __STDIO_PRINTF_FLOAT
+ /* PA_FLOAT, */
+ PA_DOUBLE,
+ PA_DOUBLE|PA_FLAG_LONG_DOUBLE,
+#endif /* __STDIO_PRINTF_FLOAT */
+};
+
+static const unsigned char type_sizes[] = {
+ /* unknown type consumes no arg */
+ 0, /* must be first entry */
+ PROMOTED_SIZE_OF(void *),
+ PROMOTED_SIZE_OF(char *),
+ PROMOTED_SIZE_OF(wchar_t *),
+ PROMOTED_SIZE_OF(char),
+ PROMOTED_SIZE_OF(short),
+ PROMOTED_SIZE_OF(int),
+ PROMOTED_SIZE_OF(long),
+#ifdef ULLONG_MAX
+ PROMOTED_SIZE_OF(long long),
+#else
+ PROMOTED_SIZE_OF(long), /* TODO -- is this correct? (above too) */
+#endif
+ PROMOTED_SIZE_OF(wchar_t),
+#ifdef __STDIO_PRINTF_FLOAT
+ /* PROMOTED_SIZE_OF(float), */
+ PROMOTED_SIZE_OF(double),
+ PROMOTED_SIZE_OF(long double),
+#endif /* __STDIO_PRINTF_FLOAT */
+};
+
+static int _promoted_size(int argtype)
+{
+ register const short int *p;
+
+ /* note -- since any unrecognized type is treated as a pointer */
+ p = type_codes + sizeof(type_codes)/sizeof(type_codes[0]);
+ do {
+ if (*--p == argtype) {
+ break;
+ }
+ } while (p > type_codes);
+
+ return type_sizes[(int)(p - type_codes)];
+}
+
+static int _is_equal_or_bigger_arg(int curtype, int newtype)
+{
+ /* Quick test */
+ if (newtype == __PA_NOARG) {
+ return 0;
+ }
+ if ((curtype == __PA_NOARG) || (curtype == newtype)) {
+ return 1;
+ }
+ /* Ok... slot is already filled and types are different in name. */
+ /* So, compare promoted sizes of curtype and newtype args. */
+ return _promoted_size(curtype) <= _promoted_size(newtype);
+}
+
+#else
+
+#define _is_equal_or_bigger_arg(C,N) (((C) == __PA_NOARG) || ((C) == (N)))
+
+#endif
+
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
+/* TODO - do this differently? */
+static char _bss_custom_printf_spec[MAX_USER_SPEC]; /* 0-init'd for us. */
+
+attribute_hidden char *_custom_printf_spec = _bss_custom_printf_spec;
+attribute_hidden printf_arginfo_function *_custom_printf_arginfo[MAX_USER_SPEC];
+attribute_hidden printf_function _custom_printf_handler[MAX_USER_SPEC];
+#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+
+int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs)
+{
+ register const char *fmt;
+ register const char *p;
+ int preci;
+ int width;
+ int flags;
+ int dataargtype;
+ int i;
+ int dpoint;
+#ifdef NL_ARGMAX
+ int maxposarg;
+#endif /* NL_ARGMAX */
+ int p_m_spec_chars;
+ int n;
+ int argtype[MAX_ARGS_PER_SPEC+2];
+ int argnumber[3]; /* width, precision, 1st data arg */
+ static const char spec_flags[] = SPEC_FLAGS;
+ static const char spec_chars[] = SPEC_CHARS;/* TODO: b? */
+ static const char spec_ranges[] = SPEC_RANGES;
+ static const short spec_or_mask[] = SPEC_OR_MASK;
+ static const short spec_and_mask[] = SPEC_AND_MASK;
+ static const char qual_chars[] = QUAL_CHARS;
+#ifdef __UCLIBC_HAS_WCHAR__
+ char buf[32];
+#endif /* __UCLIBC_HAS_WCHAR__ */
+
+ /* WIDE note: we can test against '%' here since we don't allow */
+ /* WIDE note: other mappings of '%' in the wide char set. */
+ preci = -1;
+ argnumber[0] = 0;
+ argnumber[1] = 0;
+ argtype[0] = __PA_NOARG;
+ argtype[1] = __PA_NOARG;
+#ifdef NL_ARGMAX
+ maxposarg = ppfs->maxposarg;
+#endif /* NL_ARGMAX */
+
+#ifdef __UCLIBC_HAS_WCHAR__
+ /* This is somewhat lame, but saves a lot of code. If we're dealing with
+ * a wide stream, that means the format is a wchar string. So, copy it
+ * char-by-char into a normal char buffer for processing. Make the buffer
+ * (buf) big enough so that any reasonable format specifier will fit.
+ * While there a legal specifiers that won't, the all involve duplicate
+ * flags or outrageous field widths/precisions. */
+ width = dpoint = 0;
+ if ((flags = ppfs->info._flags & FLAG_WIDESTREAM) == 0) {
+ fmt = ppfs->fmtpos;
+ } else {
+ fmt = buf + 1;
+ i = 0;
+ do {
+ if ((buf[i] = (char) (((wchar_t *) ppfs->fmtpos)[i-1]))
+ != (((wchar_t *) ppfs->fmtpos)[i-1])
+ ) {
+ return -1;
+ }
+ } while (buf[i++]);
+ buf[sizeof(buf)-1] = 0;
+ }
+#else /* __UCLIBC_HAS_WCHAR__ */
+ width = flags = dpoint = 0;
+ fmt = ppfs->fmtpos;
+#endif /* __UCLIBC_HAS_WCHAR__ */
+
+ assert(fmt[-1] == '%');
+ assert(fmt[0] != '%');
+
+ /* Process arg pos and/or flags and/or width and/or precision. */
+ width_precision:
+ p = fmt;
+ if (*fmt == '*') {
+ argtype[-dpoint] = PA_INT;
+ ++fmt;
+ }
+ i = 0;
+ while (isdigit(*fmt)) {
+ if (i < MAX_FIELD_WIDTH) { /* Avoid overflow. */
+ i = (i * 10) + (*fmt - '0');
+ }
+ ++fmt;
+ }
+ if (p[-1] == '%') { /* Check for a position. */
+
+ /* TODO: if val not in range, then error */
+
+#ifdef NL_ARGMAX
+ if ((*fmt == '$') && (i > 0)) {/* Positional spec. */
+ ++fmt;
+ if (maxposarg == 0) {
+ return -1;
+ }
+ if ((argnumber[2] = i) > maxposarg) {
+ maxposarg = i;
+ }
+ /* Now fall through to check flags. */
+ } else {
+ if (maxposarg > 0) {
+#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO: Support prec and width for %m when positional args used
+ /* Actually, positional arg processing will fail in general
+ * for specifiers that don't require an arg. */
+#endif /* __UCLIBC_MJN3_ONLY__ */
+ if (*fmt == 'm') {
+ goto PREC_WIDTH;
+ }
+#endif /* __UCLIBC_HAS_PRINTF_M_SPEC__ */
+ return -1;
+ }
+ maxposarg = 0; /* Possible redundant store, but cuts size. */
+
+ if ((fmt > p) && (*p != '0')) {
+ goto PREC_WIDTH;
+ }
+
+ fmt = p; /* Back up for possible '0's flag. */
+ /* Now fall through to check flags. */
+ }
+#else /* NL_ARGMAX */
+ if (*fmt == '$') { /* Positional spec. */
+ return -1;
+ }
+
+ if ((fmt > p) && (*p != '0')) {
+ goto PREC_WIDTH;
+ }
+
+ fmt = p; /* Back up for possible '0's flag. */
+ /* Now fall through to check flags. */
+#endif /* NL_ARGMAX */
+
+ restart_flags: /* Process flags. */
+ i = 1;
+ p = spec_flags;
+
+ do {
+ if (*fmt == *p++) {
+ ++fmt;
+ flags |= i;
+ goto restart_flags;
+ }
+ i += i; /* Better than i <<= 1 for bcc */
+ } while (*p);
+ i = 0;
+
+ /* If '+' then ignore ' ', and if '-' then ignore '0'. */
+ /* Note: Need to ignore '0' when prec is an arg with val < 0, */
+ /* but that test needs to wait until the arg is retrieved. */
+ flags &= ~((flags & (FLAG_PLUS|FLAG_MINUS)) >> 1);
+ /* Note: Ignore '0' when prec is specified < 0 too (in printf). */
+
+ if (fmt[-1] != '%') { /* If we've done anything, loop for width. */
+ goto width_precision;
+ }
+ }
+ PREC_WIDTH:
+ if (*p == '*') { /* Prec or width takes an arg. */
+#ifdef NL_ARGMAX
+ if (maxposarg) {
+ if ((*fmt++ != '$') || (i <= 0)) {
+ /* Using pos args and no $ or invalid arg number. */
+ return -1;
+ }
+ argnumber[-dpoint] = i;
+ } else
+#endif /* NL_ARGMAX */
+ if (++p != fmt) {
+ /* Not using pos args but digits followed *. */
+ return -1;
+ }
+ i = INT_MIN;
+ }
+
+ if (!dpoint) {
+ width = i;
+ if (*fmt == '.') {
+ ++fmt;
+ dpoint = -1; /* To use as default precison. */
+ goto width_precision;
+ }
+ } else {
+ preci = i;
+ }
+
+ /* Process qualifier. */
+ p = qual_chars;
+ do {
+ if (*fmt == *p) {
+ ++fmt;
+ break;
+ }
+ } while (*++p);
+ if ((p - qual_chars < 2) && (*fmt == *p)) {
+ p += ((sizeof(qual_chars)-2) / 2);
+ ++fmt;
+ }
+ dataargtype = ((int)(p[(sizeof(qual_chars)-2) / 2])) << 8;
+
+ /* Process conversion specifier. */
+ if (!*fmt) {
+ return -1;
+ }
+
+ p = spec_chars;
+
+ do {
+ if (*fmt == *p) {
+ p_m_spec_chars = p - spec_chars;
+
+ if ((p_m_spec_chars >= CONV_c)
+ && (dataargtype & PA_FLAG_LONG)) {
+ p_m_spec_chars -= 2; /* lc -> C and ls -> S */
+ }
+
+ ppfs->conv_num = p_m_spec_chars;
+ p = spec_ranges-1;
+ while (p_m_spec_chars > *++p) {}
+
+ i = p - spec_ranges;
+ argtype[2] = (dataargtype | spec_or_mask[i]) & spec_and_mask[i];
+ p = spec_chars;
+ break;
+ }
+ } while(*++p);
+
+ ppfs->info.spec = *fmt;
+ ppfs->info.prec = preci;
+ ppfs->info.width = width;
+ ppfs->info.pad = ((flags & FLAG_ZERO) ? '0' : ' ');
+ ppfs->info._flags = (flags & ~FLAG_ZERO) | (dataargtype & __PA_INTMASK);
+ ppfs->num_data_args = 1;
+
+ if (!*p) {
+#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
+ if (*fmt == 'm') {
+ ppfs->conv_num = CONV_m;
+ ppfs->num_data_args = 0;
+ goto DONE;
+ }
+#endif
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
+
+ /* Handle custom arg -- WARNING -- overwrites p!!! */
+ ppfs->conv_num = CONV_custom0;
+ p = _custom_printf_spec;
+ do {
+ if (*p == *fmt) {
+ if ((ppfs->num_data_args
+ = ((*_custom_printf_arginfo[(int)(p-_custom_printf_spec)])
+ (&(ppfs->info), MAX_ARGS_PER_SPEC, argtype+2)))
+ > MAX_ARGS_PER_SPEC) {
+ break; /* Error -- too many args! */
+ }
+ goto DONE;
+ }
+ } while (++p < (_custom_printf_spec + MAX_USER_SPEC));
+#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+ /* Otherwise error. */
+ return -1;
+ }
+
+#if defined(__UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__) || defined(__UCLIBC_HAS_PRINTF_M_SPEC__)
+ DONE:
+#endif
+
+#ifdef NL_ARGMAX
+ if (maxposarg > 0) {
+ i = 0;
+ do {
+ /* Update maxposarg and check that NL_ARGMAX is not exceeded. */
+ n = ((i <= 2)
+ ? (ppfs->argnumber[i] = argnumber[i])
+ : argnumber[2] + (i-2));
+ if (n > maxposarg) {
+ if ((maxposarg = n) > NL_ARGMAX) {
+ return -1;
+ }
+ }
+ --n;
+ /* Record argtype with largest size (current, new). */
+ if (_is_equal_or_bigger_arg(ppfs->argtype[n], argtype[i])) {
+ ppfs->argtype[n] = argtype[i];
+ }
+ } while (++i < ppfs->num_data_args + 2);
+ } else {
+#endif /* NL_ARGMAX */
+ ppfs->argnumber[2] = 1;
+ memcpy(ppfs->argtype, argtype + 2, ppfs->num_data_args * sizeof(int));
+#ifdef NL_ARGMAX
+ }
+
+ ppfs->maxposarg = maxposarg;
+#endif /* NL_ARGMAX */
+
+#ifdef __UCLIBC_HAS_WCHAR__
+ if ((flags = ppfs->info._flags & FLAG_WIDESTREAM) == 0) {
+ ppfs->fmtpos = ++fmt;
+ } else {
+ ppfs->fmtpos = (const char *) (((const wchar_t *)(ppfs->fmtpos))
+ + (fmt - buf) );
+ }
+#else /* __UCLIBC_HAS_WCHAR__ */
+ ppfs->fmtpos = ++fmt;
+#endif /* __UCLIBC_HAS_WCHAR__ */
+
+ return ppfs->num_data_args + 2;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_register_printf_function
+
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
+
+int register_printf_function(int spec, printf_function handler,
+ printf_arginfo_function arginfo)
+{
+ register char *r;
+ register char *p;
+
+ if (spec && (arginfo != NULL)) { /* TODO -- check if spec is valid char */
+ r = NULL;
+ p = _custom_printf_spec + MAX_USER_SPEC;
+ do {
+ --p;
+ if (!*p) {
+ r = p;
+ }
+#ifdef __BCC__
+ else /* bcc generates less code with fall-through */
+#endif
+ if (*p == spec) {
+ r = p;
+ p = _custom_printf_spec;
+ }
+ } while (p > _custom_printf_spec);
+
+ if (r) {
+ if (handler) {
+ *r = spec;
+ _custom_printf_handler[(int)(r - p)] = handler;
+ _custom_printf_arginfo[(int)(r - p)] = arginfo;
+ } else {
+ *r = 0;
+ }
+ return 0;
+ }
+ /* TODO -- if asked to unregister a non-existent spec, return what? */
+ }
+ return -1;
+}
+
+#endif
+
+#endif
+/**********************************************************************/
+#if defined(L_vfprintf) || defined(L_vfwprintf)
+
+/* We only support ascii digits (or their USC equivalent codes) in
+ * precision and width settings in *printf (wide) format strings.
+ * In other words, we don't currently support glibc's 'I' flag.
+ * We do accept it, but it is currently ignored. */
+
+static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad);
+
+#ifdef L_vfprintf
+
+#define VFPRINTF vfprintf
+#define FMT_TYPE char
+#define OUTNSTR _outnstr
+#define STRLEN strlen
+#define _PPFS_init _ppfs_init
+#define OUTPUT(F,S) fputs_unlocked(S,F)
+/* #define _outnstr(stream, string, len) __stdio_fwrite(string, len, stream) */
+#define _outnstr(stream, string, len) ((len > 0) ? __stdio_fwrite(string, len, stream) : 0)
+#define FP_OUT _fp_out_narrow
+
+#ifdef __STDIO_PRINTF_FLOAT
+
+static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
+{
+ size_t r = 0;
+
+ if (type & 0x80) { /* Some type of padding needed. */
+ int buflen = strlen((const char *) buf);
+ if ((len -= buflen) > 0) {
+ if ((r = _charpad(fp, (type & 0x7f), len)) != len) {
+ return r;
+ }
+ }
+ len = buflen;
+ }
+ return r + OUTNSTR(fp, (const char *) buf, len);
+}
+
+#endif /* __STDIO_PRINTF_FLOAT */
+
+#else /* L_vfprintf */
+
+#define VFPRINTF vfwprintf
+#define FMT_TYPE wchar_t
+#define OUTNSTR _outnwcs
+#define STRLEN wcslen
+#define _PPFS_init _ppwfs_init
+#define OUTPUT(F,S) fputws(S,F)
+#define _outnwcs(stream, wstring, len) _wstdio_fwrite(wstring, len, stream)
+#define FP_OUT _fp_out_wide
+
+#ifdef __UCLIBC_HAS_LOCALE__
+libc_hidden_proto(__global_locale)
+#endif
+
+static size_t _outnstr(FILE *stream, const char *s, size_t wclen)
+{
+ /* NOTE!!! len here is the number of wchars we want to generate!!! */
+ wchar_t wbuf[64];
+ mbstate_t mbstate;
+ size_t todo, r, n;
+
+ mbstate.__mask = 0;
+ todo = wclen;
+
+ while (todo) {
+ r = mbsrtowcs(wbuf, &s,
+ ((todo <= sizeof(wbuf)/sizeof(wbuf[0]))
+ ? todo
+ : sizeof(wbuf)/sizeof(wbuf[0])),
+ &mbstate);
+ assert(((ssize_t)r) > 0);
+ n = _outnwcs(stream, wbuf, r);
+ todo -= n;
+ if (n != r) {
+ break;
+ }
+ }
+
+ return wclen - todo;
+}
+
+#ifdef __STDIO_PRINTF_FLOAT
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO: Move defines from _fpmaxtostr. Put them in a common header.
+#endif
+
+/* The following defines are from _fpmaxtostr.*/
+#define DIGITS_PER_BLOCK 9
+#define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK)
+#define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK )
+
+static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
+{
+ wchar_t wbuf[BUF_SIZE];
+ const char *s = (const char *) buf;
+ size_t r = 0;
+ int i;
+
+ if (type & 0x80) { /* Some type of padding needed */
+ int buflen = strlen(s);
+ if ((len -= buflen) > 0) {
+ if ((r = _charpad(fp, (type & 0x7f), len)) != len) {
+ return r;
+ }
+ }
+ len = buflen;
+ }
+
+ if (len > 0) {
+ i = 0;
+ do {
+#ifdef __LOCALE_C_ONLY
+ wbuf[i] = s[i];
+#else /* __LOCALE_C_ONLY */
+
+#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
+ if (s[i] == ',') {
+ wbuf[i] = __UCLIBC_CURLOCALE_DATA.thousands_sep_wc;
+ } else
+#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
+ if (s[i] == '.') {
+ wbuf[i] = __UCLIBC_CURLOCALE_DATA.decimal_point_wc;
+ } else {
+ wbuf[i] = s[i];
+ }
+#endif /* __LOCALE_C_ONLY */
+
+ } while (++i < len);
+
+ r += OUTNSTR(fp, wbuf, len);
+ }
+
+ return r;
+}
+
+#endif /* __STDIO_PRINTF_FLOAT */
+
+static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0)
+{
+ static const wchar_t invalid_wcs[] = L"Invalid wide format string.";
+ int r;
+
+ /* First, zero out everything... argnumber[], argtype[], argptr[] */
+ memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */
+#ifdef NL_ARGMAX
+ --ppfs->maxposarg; /* set to -1 */
+#endif /* NL_ARGMAX */
+ ppfs->fmtpos = (const char *) fmt0;
+ ppfs->info._flags = FLAG_WIDESTREAM;
+
+ {
+ mbstate_t mbstate;
+ const wchar_t *p;
+ mbstate.__mask = 0; /* Initialize the mbstate. */
+ p = fmt0;
+ if (wcsrtombs(NULL, &p, SIZE_MAX, &mbstate) == ((size_t)(-1))) {
+ ppfs->fmtpos = (const char *) invalid_wcs;
+ return -1;
+ }
+ }
+
+ /* now set all argtypes to no-arg */
+ {
+#if 1
+ /* TODO - use memset here since already "paid for"? */
+ register int *p = ppfs->argtype;
+
+ r = MAX_ARGS;
+ do {
+ *p++ = __PA_NOARG;
+ } while (--r);
+#else
+ /* TODO -- get rid of this?? */
+ register char *p = (char *) ((MAX_ARGS-1) * sizeof(int));
+
+ do {
+ *((int *)(((char *)ppfs) + ((int)p) + offsetof(ppfs_t,argtype))) = __PA_NOARG;
+ p -= sizeof(int);
+ } while (p);
+#endif
+ }
+
+ /*
+ * Run through the entire format string to validate it and initialize
+ * the positional arg numbers (if any).
+ */
+ {
+ register const wchar_t *fmt = fmt0;
+
+ while (*fmt) {
+ if ((*fmt == '%') && (*++fmt != '%')) {
+ ppfs->fmtpos = (const char *) fmt; /* back up to the '%' */
+ if ((r = _ppfs_parsespec(ppfs)) < 0) {
+ return -1;
+ }
+ fmt = (const wchar_t *) ppfs->fmtpos; /* update to one past end of spec */
+ } else {
+ ++fmt;
+ }
+ }
+ ppfs->fmtpos = (const char *) fmt0; /* rewind */
+ }
+
+#ifdef NL_ARGMAX
+ /* If we have positional args, make sure we know all the types. */
+ {
+ register int *p = ppfs->argtype;
+ r = ppfs->maxposarg;
+ while (--r >= 0) {
+ if ( *p == __PA_NOARG ) { /* missing arg type!!! */
+ return -1;
+ }
+ ++p;
+ }
+ }
+#endif /* NL_ARGMAX */
+
+ return 0;
+}
+
+#endif /* L_vfprintf */
+
+static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)
+{
+ size_t todo = numpad;
+
+ /* TODO -- Use a buffer to cut down on function calls... */
+ FMT_TYPE pad[1];
+
+ *pad = padchar;
+ while (todo && (OUTNSTR(stream, pad, 1) == 1)) {
+ --todo;
+ }
+
+ return numpad - todo;
+}
+
+/* TODO -- Dynamically allocate work space to accomodate stack-poor archs? */
+static int _do_one_spec(FILE * __restrict stream,
+ register ppfs_t *ppfs, int *count)
+{
+ static const char spec_base[] = SPEC_BASE;
+#ifdef L_vfprintf
+ static const char prefix[] = "+\0-\0 \0000x\0000X";
+ /* 0 2 4 6 9 11*/
+#else /* L_vfprintf */
+ static const wchar_t prefix[] = L"+\0-\0 \0000x\0000X";
+#endif /* L_vfprintf */
+ enum {
+ PREFIX_PLUS = 0,
+ PREFIX_MINUS = 2,
+ PREFIX_SPACE = 4,
+ PREFIX_LWR_X = 6,
+ PREFIX_UPR_X = 9,
+ PREFIX_NONE = 11
+ };
+
+#ifdef __va_arg_ptr
+ const void * const *argptr;
+#else
+ const void * argptr[MAX_ARGS_PER_SPEC];
+#endif
+ int *argtype;
+#ifdef __UCLIBC_HAS_WCHAR__
+ const wchar_t *ws = NULL;
+ mbstate_t mbstate;
+#endif /* __UCLIBC_HAS_WCHAR__ */
+ size_t slen;
+#ifdef L_vfprintf
+#define SLEN slen
+#else
+ size_t SLEN;
+ wchar_t wbuf[2];
+#endif
+ int base;
+ int numpad;
+ int alphacase;
+ int numfill = 0; /* TODO: fix */
+ int prefix_num = PREFIX_NONE;
+ char padchar = ' ';
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO: Determine appropriate buf size.
+#endif /* __UCLIBC_MJN3_ONLY__ */
+ /* TODO: buf needs to be big enough for any possible error return strings
+ * and also for any locale-grouped long long integer strings generated.
+ * This should be large enough for any of the current archs/locales, but
+ * eventually this should be handled robustly. */
+ char buf[128];
+
+#ifdef NDEBUG
+ _ppfs_parsespec(ppfs);
+#else
+ if (_ppfs_parsespec(ppfs) < 0) { /* TODO: just for debugging */
+ abort();
+ }
+#endif
+ _ppfs_setargs(ppfs);
+
+ argtype = ppfs->argtype + ppfs->argnumber[2] - 1;
+ /* Deal with the argptr vs argvalue issue. */
+#ifdef __va_arg_ptr
+ argptr = (const void * const *) ppfs->argptr;
+#ifdef NL_ARGMAX
+ if (ppfs->maxposarg > 0) { /* Using positional args... */
+ argptr += ppfs->argnumber[2] - 1;
+ }
+#endif /* NL_ARGMAX */
+#else
+ /* Need to build a local copy... */
+ {
+ register argvalue_t *p = ppfs->argvalue;
+ int i;
+#ifdef NL_ARGMAX
+ if (ppfs->maxposarg > 0) { /* Using positional args... */
+ p += ppfs->argnumber[2] - 1;
+ }
+#endif /* NL_ARGMAX */
+ for (i = 0 ; i < ppfs->num_data_args ; i++ ) {
+ argptr[i] = (void *) p++;
+ }
+ }
+#endif
+ {
+ register char *s = NULL; /* TODO: Should s be unsigned char * ? */
+
+ if (ppfs->conv_num == CONV_n) {
+ _store_inttype(*(void **)*argptr,
+ ppfs->info._flags & __PA_INTMASK,
+ (intmax_t) (*count));
+ return 0;
+ }
+ if (ppfs->conv_num <= CONV_i) { /* pointer or (un)signed int */
+ alphacase = __UIM_LOWER;
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#ifdef L_vfprintf
+#warning CONSIDER: Should we ignore these flags if stub locale? What about custom specs?
+#endif
+#endif /* __UCLIBC_MJN3_ONLY__ */
+ if ((base = spec_base[(int)(ppfs->conv_num - CONV_p)]) == 10) {
+ if (PRINT_INFO_FLAG_VAL(&(ppfs->info),group)) {
+ alphacase = __UIM_GROUP;
+ }
+ if (PRINT_INFO_FLAG_VAL(&(ppfs->info),i18n)) {
+ alphacase |= 0x80;
+ }
+ }
+
+ if (ppfs->conv_num <= CONV_u) { /* pointer or unsigned int */
+ if (ppfs->conv_num == CONV_X) {
+ alphacase = __UIM_UPPER;
+ }
+ if (ppfs->conv_num == CONV_p) { /* pointer */
+ prefix_num = PREFIX_LWR_X;
+ } else { /* unsigned int */
+ }
+ } else { /* signed int */
+ base = -base;
+ }
+ if (ppfs->info.prec < 0) { /* Ignore '0' flag if prec specified. */
+ padchar = ppfs->info.pad;
+ }
+#ifdef __UCLIBC_MJN3_ONLY__
+#ifdef L_vfprintf
+#warning CONSIDER: If using outdigits and/or grouping, how should we interpret precision?
+#endif
+#endif /* __UCLIBC_MJN3_ONLY__ */
+ s = _uintmaxtostr(buf + sizeof(buf) - 1,
+ (uintmax_t)
+ _load_inttype(*argtype & __PA_INTMASK,
+ *argptr, base), base, alphacase);
+ if (ppfs->conv_num > CONV_u) { /* signed int */
+ if (*s == '-') {
+ PRINT_INFO_SET_FLAG(&(ppfs->info),showsign);
+ ++s; /* handle '-' in the prefix string */
+ prefix_num = PREFIX_MINUS;
+ } else if (PRINT_INFO_FLAG_VAL(&(ppfs->info),showsign)) {
+ prefix_num = PREFIX_PLUS;
+ } else if (PRINT_INFO_FLAG_VAL(&(ppfs->info),space)) {
+ prefix_num = PREFIX_SPACE;
+ }
+ }
+ slen = (char *)(buf + sizeof(buf) - 1) - s;
+#ifdef L_vfwprintf
+ {
+ const char *q = s;
+ mbstate.__mask = 0; /* Initialize the mbstate. */
+ SLEN = mbsrtowcs(NULL, &q, 0, &mbstate);
+ }
+#endif
+ numfill = ((ppfs->info.prec < 0) ? 1 : ppfs->info.prec);
+ if (PRINT_INFO_FLAG_VAL(&(ppfs->info),alt)) {
+ if (ppfs->conv_num <= CONV_x) { /* x or p */
+ prefix_num = PREFIX_LWR_X;
+ }
+ if (ppfs->conv_num == CONV_X) {
+ prefix_num = PREFIX_UPR_X;
+ }
+ if ((ppfs->conv_num == CONV_o) && (numfill <= SLEN)) {
+ numfill = ((*s == '0') ? 1 : SLEN + 1);
+ }
+ }
+ if (*s == '0') {
+ if (prefix_num >= PREFIX_LWR_X) {
+ prefix_num = PREFIX_NONE;
+ }
+ if (ppfs->conv_num == CONV_p) {/* null pointer */
+ s = "(nil)";
+#ifdef L_vfwprintf
+ SLEN =
+#endif
+ slen = 5;
+ numfill = 0;
+ } else if (numfill == 0) { /* if precision 0, no output */
+#ifdef L_vfwprintf
+ SLEN =
+#endif
+ slen = 0;
+ }
+ }
+ numfill = ((numfill > SLEN) ? numfill - SLEN : 0);
+ } else if (ppfs->conv_num <= CONV_A) { /* floating point */
+#ifdef __STDIO_PRINTF_FLOAT
+ ssize_t nf;
+ nf = _fpmaxtostr(stream,
+ (__fpmax_t)
+ (PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double)
+ ? *(long double *) *argptr
+ : (long double) (* (double *) *argptr)),
+ &ppfs->info, FP_OUT );
+ if (nf < 0) {
+ return -1;
+ }
+ *count += nf;
+
+ return 0;
+#else /* __STDIO_PRINTF_FLOAT */
+ return -1; /* TODO -- try to continue? */
+#endif /* __STDIO_PRINTF_FLOAT */
+ } else if (ppfs->conv_num <= CONV_S) { /* wide char or string */
+#ifdef L_vfprintf
+
+#ifdef __UCLIBC_HAS_WCHAR__
+ mbstate.__mask = 0; /* Initialize the mbstate. */
+ if (ppfs->conv_num == CONV_S) { /* wide string */
+ if (!(ws = *((const wchar_t **) *argptr))) {
+ goto NULL_STRING;
+ }
+ /* We use an awful uClibc-specific hack here, passing
+ * (char*) &ws as the conversion destination. This signals
+ * uClibc's wcsrtombs that we want a "restricted" length
+ * such that the mbs fits in a buffer of the specified
+ * size with no partial conversions. */
+ if ((slen = wcsrtombs((char *) &ws, &ws, /* Use awful hack! */
+ ((ppfs->info.prec >= 0)
+ ? ppfs->info.prec
+ : SIZE_MAX), &mbstate))
+ == ((size_t)-1)
+ ) {
+ return -1; /* EILSEQ */
+ }
+ } else { /* wide char */
+ s = buf;
+ slen = wcrtomb(s, (*((const wchar_t *) *argptr)), &mbstate);
+ if (slen == ((size_t)-1)) {
+ return -1; /* EILSEQ */
+ }
+ s[slen] = 0; /* TODO - Is this necessary? */
+ }
+#else /* __UCLIBC_HAS_WCHAR__ */
+ return -1;
+#endif /* __UCLIBC_HAS_WCHAR__ */
+ } else if (ppfs->conv_num <= CONV_s) { /* char or string */
+ if (ppfs->conv_num == CONV_s) { /* string */
+ s = *((char **) (*argptr));
+ if (s) {
+#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
+ SET_STRING_LEN:
+#endif
+ slen = strnlen(s, ((ppfs->info.prec >= 0)
+ ? ppfs->info.prec : SIZE_MAX));
+ } else {
+#ifdef __UCLIBC_HAS_WCHAR__
+ NULL_STRING:
+#endif
+ s = "(null)";
+ slen = 6;
+ }
+ } else { /* char */
+ s = buf;
+ *s = (unsigned char)(*((const int *) *argptr));
+ s[1] = 0;
+ slen = 1;
+ }
+
+#else /* L_vfprintf */
+
+ if (ppfs->conv_num == CONV_S) { /* wide string */
+ ws = *((wchar_t **) (*argptr));
+ if (!ws) {
+ goto NULL_STRING;
+ }
+ SLEN = wcsnlen(ws, ((ppfs->info.prec >= 0)
+ ? ppfs->info.prec : SIZE_MAX));
+ } else { /* wide char */
+ *wbuf = (wchar_t)(*((const wint_t *) *argptr));
+ CHAR_CASE:
+ ws = wbuf;
+ wbuf[1] = 0;
+ SLEN = 1;
+ }
+
+ } else if (ppfs->conv_num <= CONV_s) { /* char or string */
+
+ if (ppfs->conv_num == CONV_s) { /* string */
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO: Fix %s for vfwprintf... output upto illegal sequence?
+#endif /* __UCLIBC_MJN3_ONLY__ */
+ s = *((char **) (*argptr));
+ if (s) {
+#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
+ SET_STRING_LEN:
+#endif
+ /* We use an awful uClibc-specific hack here, passing
+ * (wchar_t*) &mbstate as the conversion destination.
+ * This signals uClibc's mbsrtowcs that we want a
+ * "restricted" length such that the mbs fits in a buffer
+ * of the specified size with no partial conversions. */
+ {
+ const char *q = s;
+ mbstate.__mask = 0; /* Initialize the mbstate. */
+ SLEN = mbsrtowcs((wchar_t *) &mbstate, &q,
+ ((ppfs->info.prec >= 0)
+ ? ppfs->info.prec : SIZE_MAX),
+ &mbstate);
+ }
+ if (SLEN == ((size_t)(-1))) {
+ return -1; /* EILSEQ */
+ }
+ } else {
+ NULL_STRING:
+ s = "(null)";
+ SLEN = slen = 6;
+ }
+ } else { /* char */
+ *wbuf = btowc( (unsigned char)(*((const int *) *argptr)) );
+ goto CHAR_CASE;
+ }
+
+#endif /* L_vfprintf */
+
+#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
+ } else if (ppfs->conv_num == CONV_m) {
+ s = __glibc_strerror_r(errno, buf, sizeof(buf));
+ goto SET_STRING_LEN;
+#endif
+ } else {
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
+ assert(ppfs->conv_num == CONV_custom0);
+
+ s = _custom_printf_spec;
+ do {
+ if (*s == ppfs->info.spec) {
+ int rv;
+ /* TODO -- check return value for sanity? */
+ rv = (*_custom_printf_handler
+ [(int)(s-_custom_printf_spec)])
+ (stream, &ppfs->info, argptr);
+ if (rv < 0) {
+ return -1;
+ }
+ *count += rv;
+ return 0;
+ }
+ } while (++s < (_custom_printf_spec + MAX_USER_SPEC));
+#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
+ assert(0);
+ return -1;
+ }
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#ifdef L_vfprintf
+#warning CONSIDER: If using outdigits and/or grouping, how should we pad?
+#endif
+#endif /* __UCLIBC_MJN3_ONLY__ */
+ {
+ size_t t;
+
+ t = SLEN + numfill;
+ if (prefix_num != PREFIX_NONE) {
+ t += ((prefix_num < PREFIX_LWR_X) ? 1 : 2);
+ }
+ numpad = ((ppfs->info.width > t) ? (ppfs->info.width - t) : 0);
+ *count += t + numpad;
+ }
+ if (padchar == '0') { /* TODO: check this */
+ numfill += numpad;
+ numpad = 0;
+ }
+
+ /* Now handle the output itself. */
+ if (!PRINT_INFO_FLAG_VAL(&(ppfs->info),left)) {
+ if (_charpad(stream, ' ', numpad) != numpad) {
+ return -1;
+ }
+ numpad = 0;
+ }
+ OUTPUT(stream, prefix + prefix_num);
+ if (_charpad(stream, '0', numfill) != numfill) {
+ return -1;
+ }
+
+#ifdef L_vfprintf
+
+#ifdef __UCLIBC_HAS_WCHAR__
+ if (!ws) {
+ assert(s);
+ if (_outnstr(stream, s, slen) != slen) {
+ return -1;
+ }
+ } else { /* wide string */
+ size_t t;
+ mbstate.__mask = 0; /* Initialize the mbstate. */
+ while (slen) {
+ t = (slen <= sizeof(buf)) ? slen : sizeof(buf);
+ t = wcsrtombs(buf, &ws, t, &mbstate);
+ assert (t != ((size_t)(-1)));
+ if (_outnstr(stream, buf, t) != t) {
+ return -1;
+ }
+ slen -= t;
+ }
+ }
+#else /* __UCLIBC_HAS_WCHAR__ */
+ if (_outnstr(stream, s, slen) != slen) {
+ return -1;
+ }
+#endif /* __UCLIBC_HAS_WCHAR__ */
+
+#else /* L_vfprintf */
+
+ if (!ws) {
+ assert(s);
+ if (_outnstr(stream, s, SLEN) != SLEN) {
+ return -1;
+ }
+ } else {
+ if (_outnwcs(stream, ws, SLEN) != SLEN) {
+ return -1;
+ }
+ }
+
+#endif /* L_vfprintf */
+ if (_charpad(stream, ' ', numpad) != numpad) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+libc_hidden_proto(fprintf)
+
+libc_hidden_proto(VFPRINTF)
+int VFPRINTF (FILE * __restrict stream,
+ register const FMT_TYPE * __restrict format,
+ va_list arg)
+{
+ ppfs_t ppfs;
+ int count, r;
+ register const FMT_TYPE *s;
+ __STDIO_AUTO_THREADLOCK_VAR;
+
+ __STDIO_AUTO_THREADLOCK(stream);
+
+ count = 0;
+ s = format;
+
+ if
+#ifdef L_vfprintf
+ (!__STDIO_STREAM_IS_NARROW_WRITING(stream)
+ && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
+#else
+ (!__STDIO_STREAM_IS_WIDE_WRITING(stream)
+ && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
+#endif
+ {
+ count = -1;
+ } else if (_PPFS_init(&ppfs, format) < 0) { /* Bad format string. */
+ OUTNSTR(stream, (const FMT_TYPE *) ppfs.fmtpos,
+ STRLEN((const FMT_TYPE *)(ppfs.fmtpos)));
+#if defined(L_vfprintf) && !defined(NDEBUG)
+ fprintf(stderr,"\nIMbS: \"%s\"\n\n", format);
+#endif
+ count = -1;
+ } else {
+ _ppfs_prepargs(&ppfs, arg); /* This did a va_copy!!! */
+
+ do {
+ while (*format && (*format != '%')) {
+ ++format;
+ }
+
+ if (format-s) { /* output any literal text in format string */
+ if ( (r = OUTNSTR(stream, s, format-s)) != (format-s)) {
+ count = -1;
+ break;
+ }
+ count += r;
+ }
+
+ if (!*format) { /* we're done */
+ break;
+ }
+
+ if (format[1] != '%') { /* if we get here, *format == '%' */
+ /* TODO: _do_one_spec needs to know what the output funcs are!!! */
+ ppfs.fmtpos = (const char *)(++format);
+ /* TODO: check -- should only fail on stream error */
+ if ( (r = _do_one_spec(stream, &ppfs, &count)) < 0) {
+ count = -1;
+ break;
+ }
+ s = format = (const FMT_TYPE *) ppfs.fmtpos;
+ } else { /* %% means literal %, so start new string */
+ s = ++format;
+ ++format;
+ }
+ } while (1);
+
+ va_end(ppfs.arg); /* Need to clean up after va_copy! */
+ }
+
+/* #if defined(L_vfprintf) && defined(__UCLIBC_HAS_WCHAR__) */
+/* DONE: */
+/* #endif */
+
+ __STDIO_AUTO_THREADUNLOCK(stream);
+
+ return count;
+}
+libc_hidden_def(VFPRINTF)
+#endif
+/**********************************************************************/
diff --git a/libc/stdio/_wfwrite.c b/libc/stdio/_wfwrite.c
index 792cff604..fb5c6b3ee 100644
--- a/libc/stdio/_wfwrite.c
+++ b/libc/stdio/_wfwrite.c
@@ -5,8 +5,6 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define wmemcpy __wmemcpy
-
#include "_stdio.h"
#include <wchar.h>
@@ -17,9 +15,9 @@
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Fix prototype.
#endif
-extern size_t __wcsnrtombs(char *__restrict dst,
- const wchar_t **__restrict src,
- size_t NWC, size_t len, mbstate_t *__restrict ps) attribute_hidden;
+
+libc_hidden_proto(wmemcpy)
+libc_hidden_proto(wcsnrtombs)
size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
register FILE *__restrict stream)
@@ -55,7 +53,7 @@ size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
pw = ws;
while (n > count) {
- r = __wcsnrtombs(buf, &pw, n-count, sizeof(buf), &stream->__state);
+ r = wcsnrtombs(buf, &pw, n-count, sizeof(buf), &stream->__state);
if (r != ((size_t) -1)) { /* No encoding errors */
if (!r) {
++r; /* 0 is returned when nul is reached. */
diff --git a/libc/stdio/asprintf.c b/libc/stdio/asprintf.c
index 207b35a3c..3f1992559 100644
--- a/libc/stdio/asprintf.c
+++ b/libc/stdio/asprintf.c
@@ -5,16 +5,21 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define vasprintf __vasprintf
+#include <features.h>
+#ifdef __USE_GNU
#include "_stdio.h"
#include <stdarg.h>
+libc_hidden_proto(asprintf)
+
+libc_hidden_proto(vasprintf)
+
#ifndef __STDIO_HAS_VSNPRINTF
#warning Skipping asprintf and __asprintf since no vsnprintf!
#else
-int attribute_hidden __asprintf(char **__restrict buf, const char * __restrict format, ...)
+int asprintf(char **__restrict buf, const char * __restrict format, ...)
{
va_list arg;
int rv;
@@ -25,7 +30,7 @@ int attribute_hidden __asprintf(char **__restrict buf, const char * __restrict f
return rv;
}
+libc_hidden_def(asprintf)
-strong_alias(__asprintf,asprintf)
-
+#endif
#endif
diff --git a/libc/stdio/clearerr.c b/libc/stdio/clearerr.c
index cf1e623c7..a96ecaa89 100644
--- a/libc/stdio/clearerr.c
+++ b/libc/stdio/clearerr.c
@@ -7,18 +7,19 @@
#include "_stdio.h"
+#undef clearerr
#ifdef __DO_UNLOCKED
-void __clearerr_unlocked(register FILE *stream)
+#undef clearerr_unlocked
+void clearerr_unlocked(register FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
__CLEARERR_UNLOCKED(stream);
}
-weak_alias(__clearerr_unlocked,clearerr_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__clearerr_unlocked,clearerr)
+strong_alias(clearerr_unlocked,clearerr)
#endif
#elif defined __UCLIBC_HAS_THREADS__
diff --git a/libc/stdio/clearerr_unlocked.c b/libc/stdio/clearerr_unlocked.c
new file mode 100644
index 000000000..1728d0378
--- /dev/null
+++ b/libc/stdio/clearerr_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "clearerr.c"
diff --git a/libc/stdio/ctermid.c b/libc/stdio/ctermid.c
index 11e43f336..1cb8a0845 100644
--- a/libc/stdio/ctermid.c
+++ b/libc/stdio/ctermid.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(strcpy)
+
char *ctermid(register char *s)
{
static char sbuf[L_ctermid];
@@ -21,6 +23,6 @@ char *ctermid(register char *s)
return s;
#else
/* glibc always returns /dev/tty for linux. */
- return __strcpy((s ? s : sbuf), "/dev/tty");
+ return strcpy((s ? s : sbuf), "/dev/tty");
#endif
}
diff --git a/libc/stdio/dprintf.c b/libc/stdio/dprintf.c
index 1fc46c722..a8b2704b2 100644
--- a/libc/stdio/dprintf.c
+++ b/libc/stdio/dprintf.c
@@ -5,11 +5,14 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define vdprintf __vdprintf
+#include <features.h>
+#ifdef __USE_GNU
#include "_stdio.h"
#include <stdarg.h>
+libc_hidden_proto(vdprintf)
+
int dprintf(int filedes, const char * __restrict format, ...)
{
va_list arg;
@@ -21,3 +24,4 @@ int dprintf(int filedes, const char * __restrict format, ...)
return rv;
}
+#endif
diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c
index e019ad53e..843599c0f 100644
--- a/libc/stdio/fclose.c
+++ b/libc/stdio/fclose.c
@@ -5,12 +5,13 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define close __close
-
#include "_stdio.h"
+libc_hidden_proto(fclose)
+
+libc_hidden_proto(close)
+libc_hidden_proto(fflush_unlocked)
-#undef fclose
-int attribute_hidden __fclose(register FILE *stream)
+int fclose(register FILE *stream)
{
int rv = 0;
__STDIO_AUTO_THREADLOCK_VAR;
@@ -47,7 +48,7 @@ int attribute_hidden __fclose(register FILE *stream)
#ifdef __STDIO_BUFFERS
/* Write any pending buffered chars. */
if (__STDIO_STREAM_IS_WRITING(stream)) {
- rv = __fflush_unlocked(stream);
+ rv = fflush_unlocked(stream);
}
#endif
@@ -87,4 +88,4 @@ int attribute_hidden __fclose(register FILE *stream)
return rv;
}
-strong_alias(__fclose,fclose)
+libc_hidden_def(fclose)
diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c
index dbb600067..7d2422562 100644
--- a/libc/stdio/fcloseall.c
+++ b/libc/stdio/fcloseall.c
@@ -5,8 +5,13 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
+#include <features.h>
+
+#ifdef __USE_GNU
#include "_stdio.h"
+libc_hidden_proto(fclose)
+
/* NOTE: GLIBC difference!!! -- fcloseall
* According to the info pages, glibc actually fclose()s all open files.
* Apparently, glibc's new version only fflush()s and unbuffers all
@@ -38,3 +43,4 @@ int fcloseall (void)
#endif
}
+#endif
diff --git a/libc/stdio/fdopen.c b/libc/stdio/fdopen.c
index bca7f23fb..acf6231b2 100644
--- a/libc/stdio/fdopen.c
+++ b/libc/stdio/fdopen.c
@@ -7,12 +7,15 @@
#include "_stdio.h"
-FILE attribute_hidden *__fdopen(int filedes, const char *mode)
+libc_hidden_proto(fdopen)
+libc_hidden_proto(fcntl)
+
+FILE *fdopen(int filedes, const char *mode)
{
intptr_t cur_mode;
- return (((cur_mode = __fcntl(filedes, F_GETFL))) != -1)
+ return (((cur_mode = fcntl(filedes, F_GETFL))) != -1)
? _stdio_fopen(cur_mode, mode, NULL, filedes)
: NULL;
}
-strong_alias(__fdopen,fdopen)
+libc_hidden_def(fdopen)
diff --git a/libc/stdio/feof.c b/libc/stdio/feof.c
index b0528d5ae..e5f03b720 100644
--- a/libc/stdio/feof.c
+++ b/libc/stdio/feof.c
@@ -7,18 +7,19 @@
#include "_stdio.h"
+#undef feof
#ifdef __DO_UNLOCKED
-int __feof_unlocked(register FILE *stream)
+#undef feof_unlocked
+int feof_unlocked(register FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
return __FEOF_UNLOCKED(stream);
}
-weak_alias(__feof_unlocked,feof_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__feof_unlocked,feof)
+strong_alias(feof_unlocked,feof)
#endif
#elif defined __UCLIBC_HAS_THREADS__
diff --git a/libc/stdio/feof_unlocked.c b/libc/stdio/feof_unlocked.c
new file mode 100644
index 000000000..4553f306b
--- /dev/null
+++ b/libc/stdio/feof_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "feof.c"
diff --git a/libc/stdio/ferror.c b/libc/stdio/ferror.c
index e8d19bfa4..947b89ed1 100644
--- a/libc/stdio/ferror.c
+++ b/libc/stdio/ferror.c
@@ -7,18 +7,19 @@
#include "_stdio.h"
+#undef ferror
#ifdef __DO_UNLOCKED
-int __ferror_unlocked(register FILE *stream)
+#undef ferror_unlocked
+int ferror_unlocked(register FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
return __FERROR_UNLOCKED(stream);
}
-weak_alias(__ferror_unlocked,ferror_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__ferror_unlocked,ferror)
+strong_alias(ferror_unlocked,ferror)
#endif
#elif defined __UCLIBC_HAS_THREADS__
diff --git a/libc/stdio/ferror_unlocked.c b/libc/stdio/ferror_unlocked.c
new file mode 100644
index 000000000..19722b8bb
--- /dev/null
+++ b/libc/stdio/ferror_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "ferror.c"
diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c
index 0a74afe3f..a2e1cf916 100644
--- a/libc/stdio/fflush.c
+++ b/libc/stdio/fflush.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(fflush_unlocked)
+
#ifdef __DO_UNLOCKED
#ifdef __UCLIBC_MJN3_ONLY__
@@ -14,6 +16,7 @@
#endif /* __UCLIBC_MJN3_ONLY__ */
#ifdef __UCLIBC_HAS_THREADS__
+libc_hidden_proto(_stdio_user_locking)
/* Even if the stream is set to user-locking, we still need to lock
* when all (lbf) writing streams are flushed. */
#define MY_STDIO_THREADLOCK(STREAM) \
@@ -31,7 +34,7 @@
#endif
-int attribute_hidden __fflush_unlocked(register FILE *stream)
+int fflush_unlocked(register FILE *stream)
{
#ifdef __STDIO_BUFFERS
@@ -125,16 +128,18 @@ int attribute_hidden __fflush_unlocked(register FILE *stream)
return 0;
#endif /* __STDIO_BUFFERS */
}
+libc_hidden_def(fflush_unlocked)
-weak_alias(__fflush_unlocked,fflush_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fflush_unlocked,__fflush)
-weak_alias(__fflush_unlocked,fflush)
+libc_hidden_proto(fflush)
+strong_alias(fflush_unlocked,fflush)
+libc_hidden_def(fflush)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-int attribute_hidden __fflush(register FILE *stream)
+libc_hidden_proto(fflush)
+int fflush(register FILE *stream)
{
int retval;
__STDIO_AUTO_THREADLOCK_VAR;
@@ -147,15 +152,15 @@ int attribute_hidden __fflush(register FILE *stream)
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fflush_unlocked(stream);
+ retval = fflush_unlocked(stream);
__STDIO_AUTO_THREADUNLOCK(stream);
} else {
- retval = __fflush_unlocked(stream);
+ retval = fflush_unlocked(stream);
}
return retval;
}
-strong_alias(__fflush,fflush)
+libc_hidden_def(fflush)
#endif
diff --git a/libc/stdio/fflush_unlocked.c b/libc/stdio/fflush_unlocked.c
new file mode 100644
index 000000000..a6adb59c2
--- /dev/null
+++ b/libc/stdio/fflush_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fflush.c"
diff --git a/libc/stdio/fgetc.c b/libc/stdio/fgetc.c
index d83b6c92a..7eb2b6ea2 100644
--- a/libc/stdio/fgetc.c
+++ b/libc/stdio/fgetc.c
@@ -1,6 +1,7 @@
/* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
- * GNU Library General Public License (LGPL) version 2 or later.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
@@ -12,9 +13,13 @@
#undef getc
#undef getc_unlocked
+libc_hidden_proto(__fgetc_unlocked)
+
#ifdef __DO_UNLOCKED
-int attribute_hidden __fgetc_unlocked_internal(FILE *stream)
+libc_hidden_proto(fflush_unlocked)
+
+int __fgetc_unlocked(FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
@@ -68,20 +73,32 @@ int attribute_hidden __fgetc_unlocked_internal(FILE *stream)
return EOF;
}
+libc_hidden_def(__fgetc_unlocked)
+
+libc_hidden_proto(fgetc_unlocked)
+strong_alias(__fgetc_unlocked,fgetc_unlocked)
+libc_hidden_def(fgetc_unlocked)
+
+//libc_hidden_proto(__getc_unlocked)
+//strong_alias(__fgetc_unlocked,__getc_unlocked)
+//libc_hidden_def(__getc_unlocked)
+
+libc_hidden_proto(getc_unlocked)
+strong_alias(__fgetc_unlocked,getc_unlocked)
+libc_hidden_def(getc_unlocked)
-strong_alias(__fgetc_unlocked_internal,__fgetc_unlocked)
-weak_alias(__fgetc_unlocked_internal,fgetc_unlocked)
-hidden_strong_alias(__fgetc_unlocked_internal,__getc_unlocked)
-weak_alias(__fgetc_unlocked_internal,getc_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fgetc_unlocked_internal,__fgetc)
-weak_alias(__fgetc_unlocked_internal,fgetc)
-weak_alias(__fgetc_unlocked_internal,getc)
+libc_hidden_proto(fgetc)
+strong_alias(__fgetc_unlocked,fgetc)
+libc_hidden_def(fgetc)
+
+strong_alias(__fgetc_unlocked,getc)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-int attribute_hidden __fgetc(register FILE *stream)
+libc_hidden_proto(fgetc)
+int fgetc(register FILE *stream)
{
if (stream->__user_locking != 0) {
return __GETC_UNLOCKED_MACRO(stream);
@@ -93,7 +110,8 @@ int attribute_hidden __fgetc(register FILE *stream)
return retval;
}
}
-strong_alias(__fgetc,fgetc)
-weak_alias(__fgetc,getc)
+libc_hidden_def(fgetc)
+
+strong_alias(fgetc,getc)
#endif
diff --git a/libc/stdio/fgetc_unlocked.c b/libc/stdio/fgetc_unlocked.c
new file mode 100644
index 000000000..a20c7eef2
--- /dev/null
+++ b/libc/stdio/fgetc_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fgetc.c"
diff --git a/libc/stdio/fgetpos.c b/libc/stdio/fgetpos.c
index 03c18ab93..610737d36 100644
--- a/libc/stdio/fgetpos.c
+++ b/libc/stdio/fgetpos.c
@@ -8,9 +8,11 @@
#include "_stdio.h"
#ifndef __DO_LARGEFILE
-#define FTELL __ftell
+#define FTELL ftell
#endif
+libc_hidden_proto(FTELL)
+
int fgetpos(FILE * __restrict stream, register fpos_t * __restrict pos)
{
#ifdef __STDIO_MBSTATE
diff --git a/libc/stdio/fgetpos64.c b/libc/stdio/fgetpos64.c
index 6f46746b1..32b7120aa 100644
--- a/libc/stdio/fgetpos64.c
+++ b/libc/stdio/fgetpos64.c
@@ -10,5 +10,5 @@
#define __DO_LARGEFILE
#define fgetpos fgetpos64
#define fpos_t fpos64_t
-#define FTELL __ftello64
+#define FTELL ftello64
#include "fgetpos.c"
diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c
index 5baf63a58..5acaf91ed 100644
--- a/libc/stdio/fgets.c
+++ b/libc/stdio/fgets.c
@@ -7,9 +7,13 @@
#include "_stdio.h"
+libc_hidden_proto(fgets_unlocked)
+
#ifdef __DO_UNLOCKED
-char attribute_hidden *__fgets_unlocked(char *__restrict s, int n,
+libc_hidden_proto(__fgetc_unlocked)
+
+char *fgets_unlocked(char *__restrict s, int n,
register FILE * __restrict stream)
{
register char *p;
@@ -34,7 +38,7 @@ char attribute_hidden *__fgets_unlocked(char *__restrict s, int n,
break;
}
} else {
- if ((c = __fgetc_unlocked_internal(stream)) == EOF) {
+ if ((c = __fgetc_unlocked(stream)) == EOF) {
if (__FERROR_UNLOCKED(stream)) {
goto ERROR;
}
@@ -57,17 +61,18 @@ char attribute_hidden *__fgets_unlocked(char *__restrict s, int n,
ERROR:
return NULL;
}
-
-weak_alias(__fgets_unlocked,fgets_unlocked)
+libc_hidden_def(fgets_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fgets_unlocked,__fgets)
-weak_alias(__fgets_unlocked,fgets)
+libc_hidden_proto(fgets)
+strong_alias(fgets_unlocked,fgets)
+libc_hidden_def(fgets)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-char attribute_hidden *__fgets(char *__restrict s, int n,
+libc_hidden_proto(fgets)
+char *fgets(char *__restrict s, int n,
register FILE * __restrict stream)
{
char *retval;
@@ -75,12 +80,12 @@ char attribute_hidden *__fgets(char *__restrict s, int n,
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fgets_unlocked(s, n, stream);
+ retval = fgets_unlocked(s, n, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fgets,fgets)
+libc_hidden_def(fgets)
#endif
diff --git a/libc/stdio/fgets_unlocked.c b/libc/stdio/fgets_unlocked.c
new file mode 100644
index 000000000..db0191305
--- /dev/null
+++ b/libc/stdio/fgets_unlocked.c
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+
+#include <features.h>
+
+#ifdef __USE_GNU
+# define __DO_UNLOCKED
+# include "fgets.c"
+#endif
diff --git a/libc/stdio/fgetwc.c b/libc/stdio/fgetwc.c
index 45ff86b80..062d825d6 100644
--- a/libc/stdio/fgetwc.c
+++ b/libc/stdio/fgetwc.c
@@ -5,10 +5,12 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define mbrtowc __mbrtowc
-
#include "_stdio.h"
+libc_hidden_proto(fgetwc_unlocked)
+
+libc_hidden_proto(mbrtowc)
+
#ifdef __DO_UNLOCKED
static void munge_stream(register FILE *stream, unsigned char *buf)
@@ -19,7 +21,7 @@ static void munge_stream(register FILE *stream, unsigned char *buf)
__STDIO_STREAM_DISABLE_PUTC(stream);
}
-wint_t attribute_hidden __fgetwc_unlocked(register FILE *stream)
+wint_t fgetwc_unlocked(register FILE *stream)
{
wint_t wi;
wchar_t wc[1];
@@ -107,31 +109,34 @@ wint_t attribute_hidden __fgetwc_unlocked(register FILE *stream)
return wi;
}
+libc_hidden_def(fgetwc_unlocked)
-weak_alias(__fgetwc_unlocked,fgetwc_unlocked)
-weak_alias(__fgetwc_unlocked,getwc_unlocked)
+strong_alias(fgetwc_unlocked,getwc_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fgetwc_unlocked,__fgetwc)
-weak_alias(__fgetwc_unlocked,fgetwc)
-weak_alias(__fgetwc_unlocked,getwc)
+libc_hidden_proto(fgetwc)
+strong_alias(fgetwc_unlocked,fgetwc)
+libc_hidden_def(fgetwc)
+
+strong_alias(fgetwc_unlocked,getwc)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-wint_t attribute_hidden __fgetwc(register FILE *stream)
+libc_hidden_proto(fgetwc)
+wint_t fgetwc(register FILE *stream)
{
wint_t retval;
__STDIO_AUTO_THREADLOCK_VAR;
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fgetwc_unlocked(stream);
+ retval = fgetwc_unlocked(stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fgetwc,fgetwc)
-weak_alias(__fgetwc,getwc)
+libc_hidden_def(fgetwc)
+strong_alias(fgetwc,getwc)
#endif
diff --git a/libc/stdio/fgetwc_unlocked.c b/libc/stdio/fgetwc_unlocked.c
new file mode 100644
index 000000000..8eab84393
--- /dev/null
+++ b/libc/stdio/fgetwc_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fgetwc.c"
diff --git a/libc/stdio/fgetws.c b/libc/stdio/fgetws.c
index fe8da002d..c7dcc7d2b 100644
--- a/libc/stdio/fgetws.c
+++ b/libc/stdio/fgetws.c
@@ -7,12 +7,13 @@
#include "_stdio.h"
-extern wchar_t *__fgetws_unlocked(wchar_t *__restrict ws, int n,
- FILE *__restrict stream) attribute_hidden;
+libc_hidden_proto(fgetws_unlocked)
+
+libc_hidden_proto(fgetwc_unlocked)
#ifdef __DO_UNLOCKED
-wchar_t attribute_hidden *__fgetws_unlocked(wchar_t *__restrict ws, int n,
+wchar_t *fgetws_unlocked(wchar_t *__restrict ws, int n,
FILE *__restrict stream)
{
register wchar_t *p = ws;
@@ -21,7 +22,7 @@ wchar_t attribute_hidden *__fgetws_unlocked(wchar_t *__restrict ws, int n,
__STDIO_STREAM_VALIDATE(stream);
while ((n > 1)
- && ((wi = __fgetwc_unlocked(stream)) != WEOF)
+ && ((wi = fgetwc_unlocked(stream)) != WEOF)
&& ((*p++ = wi) != '\n')
) {
--n;
@@ -36,10 +37,10 @@ wchar_t attribute_hidden *__fgetws_unlocked(wchar_t *__restrict ws, int n,
*p = 0;
return ws;
}
+libc_hidden_def(fgetws_unlocked)
-weak_alias(__fgetws_unlocked,fgetws_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__fgetws_unlocked,fgetws)
+strong_alias(fgetws_unlocked,fgetws)
#endif
#elif defined __UCLIBC_HAS_THREADS__
@@ -51,7 +52,7 @@ wchar_t *fgetws(wchar_t *__restrict ws, int n, FILE *__restrict stream)
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fgetws_unlocked(ws, n, stream);
+ retval = fgetws_unlocked(ws, n, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
diff --git a/libc/stdio/fgetws_unlocked.c b/libc/stdio/fgetws_unlocked.c
new file mode 100644
index 000000000..6dd58f20a
--- /dev/null
+++ b/libc/stdio/fgetws_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fgetws.c"
diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c
index bc1ade952..929936bfd 100644
--- a/libc/stdio/fileno.c
+++ b/libc/stdio/fileno.c
@@ -7,9 +7,11 @@
#include "_stdio.h"
+libc_hidden_proto(fileno_unlocked)
+
#ifdef __DO_UNLOCKED
-int attribute_hidden __fileno_unlocked(register FILE *stream)
+int fileno_unlocked(register FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
@@ -20,27 +22,30 @@ int attribute_hidden __fileno_unlocked(register FILE *stream)
__set_errno(EBADF);
return -1;
}
+libc_hidden_def(fileno_unlocked)
-weak_alias(__fileno_unlocked,fileno_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_weak_alias(__fileno_unlocked,__fileno)
-weak_alias(__fileno_unlocked,fileno)
+libc_hidden_proto(fileno)
+strong_alias(fileno_unlocked,fileno)
+libc_hidden_def(fileno)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-int attribute_hidden __fileno(register FILE *stream)
+libc_hidden_proto(fileno)
+int fileno(register FILE *stream)
{
int retval;
__STDIO_AUTO_THREADLOCK_VAR;
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fileno_unlocked(stream);
+ retval = fileno_unlocked(stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fileno,fileno)
+libc_hidden_def(fileno)
+
#endif
diff --git a/libc/stdio/fileno_unlocked.c b/libc/stdio/fileno_unlocked.c
new file mode 100644
index 000000000..e50059296
--- /dev/null
+++ b/libc/stdio/fileno_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fileno.c"
diff --git a/libc/stdio/fmemopen.c b/libc/stdio/fmemopen.c
index fc7870258..a78d56efc 100644
--- a/libc/stdio/fmemopen.c
+++ b/libc/stdio/fmemopen.c
@@ -5,10 +5,14 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define fopencookie __fopencookie
+#include <features.h>
+#ifdef __USE_GNU
#include "_stdio.h"
+libc_hidden_proto(memcpy)
+libc_hidden_proto(fopencookie)
+
#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
#error no custom streams!
#endif
@@ -37,7 +41,7 @@ static ssize_t fmo_read(register void *cookie, char *buf, size_t bufsize)
bufsize = count;
}
- __memcpy(buf, COOKIE->buf + COOKIE->pos, bufsize);
+ memcpy(buf, COOKIE->buf + COOKIE->pos, bufsize);
COOKIE->pos += bufsize;
return bufsize;
@@ -64,7 +68,7 @@ static ssize_t fmo_write(register void *cookie, const char *buf, size_t bufsize)
}
}
- __memcpy(COOKIE->buf + COOKIE->pos, buf, bufsize);
+ memcpy(COOKIE->buf + COOKIE->pos, buf, bufsize);
COOKIE->pos += bufsize;
if (COOKIE->pos > COOKIE->eof) {
@@ -176,3 +180,4 @@ FILE *fmemopen(void *s, size_t len, const char *modes)
return NULL;
}
+#endif
diff --git a/libc/stdio/fopen.c b/libc/stdio/fopen.c
index ad5d1aa92..ec14b5956 100644
--- a/libc/stdio/fopen.c
+++ b/libc/stdio/fopen.c
@@ -9,15 +9,14 @@
#ifndef __DO_LARGEFILE
# define FILEDES_ARG (-1)
-#undef __fopen
#undef fopen
#else
-#undef __fopen64
#undef fopen64
#endif
-FILE attribute_hidden *__fopen(const char * __restrict filename, const char * __restrict mode)
+libc_hidden_proto(fopen)
+FILE *fopen(const char * __restrict filename, const char * __restrict mode)
{
return _stdio_fopen(((intptr_t) filename), mode, NULL, FILEDES_ARG);
}
-strong_alias(__fopen,fopen)
+libc_hidden_def(fopen)
diff --git a/libc/stdio/fopen64.c b/libc/stdio/fopen64.c
index c65e9a4e9..cbdb03d68 100644
--- a/libc/stdio/fopen64.c
+++ b/libc/stdio/fopen64.c
@@ -8,7 +8,6 @@
#include "_stdio.h"
#define __DO_LARGEFILE
-#define __fopen __fopen64
#undef fopen
#define fopen fopen64
#define FILEDES_ARG (-2)
diff --git a/libc/stdio/fopencookie.c b/libc/stdio/fopencookie.c
index a70e17b80..0b7ed84b1 100644
--- a/libc/stdio/fopencookie.c
+++ b/libc/stdio/fopencookie.c
@@ -5,6 +5,9 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
+#include <features.h>
+
+#ifdef __USE_GNU
#include "_stdio.h"
#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
@@ -28,7 +31,8 @@
/* Currently no real reentrancy issues other than a possible double close(). */
#ifndef __BCC__
-FILE attribute_hidden *__fopencookie(void * __restrict cookie, const char * __restrict mode,
+libc_hidden_proto(fopencookie)
+FILE *fopencookie(void * __restrict cookie, const char * __restrict mode,
cookie_io_functions_t io_functions)
#else
FILE *_fopencookie(void * __restrict cookie, const char * __restrict mode,
@@ -58,5 +62,6 @@ FILE *_fopencookie(void * __restrict cookie, const char * __restrict mode,
return stream;
}
#ifndef __BCC__
-strong_alias(__fopencookie,fopencookie)
+libc_hidden_def(fopencookie)
+#endif
#endif
diff --git a/libc/stdio/fprintf.c b/libc/stdio/fprintf.c
index ee19c85a5..4f73441e1 100644
--- a/libc/stdio/fprintf.c
+++ b/libc/stdio/fprintf.c
@@ -8,16 +8,18 @@
#include "_stdio.h"
#include <stdarg.h>
-#undef fprintf
-int attribute_hidden __fprintf(FILE * __restrict stream, const char * __restrict format, ...)
+libc_hidden_proto(vfprintf)
+
+libc_hidden_proto(fprintf)
+int fprintf(FILE * __restrict stream, const char * __restrict format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
- rv = __vfprintf(stream, format, arg);
+ rv = vfprintf(stream, format, arg);
va_end(arg);
return rv;
}
-strong_alias(__fprintf,fprintf)
+libc_hidden_def(fprintf)
diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c
index 4cc396e08..8c80bff27 100644
--- a/libc/stdio/fputc.c
+++ b/libc/stdio/fputc.c
@@ -12,9 +12,11 @@
#undef putc
#undef putc_unlocked
+libc_hidden_proto(__fputc_unlocked)
+
#ifdef __DO_UNLOCKED
-int attribute_hidden __fputc_unlocked_internal(int c, register FILE *stream)
+int __fputc_unlocked(int c, register FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
@@ -68,20 +70,25 @@ int attribute_hidden __fputc_unlocked_internal(int c, register FILE *stream)
BAD:
return EOF;
}
+libc_hidden_def(__fputc_unlocked)
+
+strong_alias(__fputc_unlocked,fputc_unlocked)
-strong_alias(__fputc_unlocked_internal,__fputc_unlocked)
-weak_alias(__fputc_unlocked_internal,fputc_unlocked)
-weak_alias(__fputc_unlocked_internal,putc_unlocked)
+libc_hidden_proto(putc_unlocked)
+strong_alias(__fputc_unlocked,putc_unlocked)
+libc_hidden_def(putc_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fputc_unlocked_internal,__fputc)
-weak_alias(__fputc_unlocked_internal,fputc)
-hidden_strong_alias(__fputc_unlocked_internal,__putc)
-weak_alias(__fputc_unlocked_internal,putc)
+strong_alias(__fputc_unlocked,fputc)
+
+libc_hidden_proto(putc)
+strong_alias(__fputc_unlocked,putc)
+libc_hidden_def(putc)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-int attribute_hidden __fputc(int c, register FILE *stream)
+libc_hidden_proto(fputc)
+int fputc(int c, register FILE *stream)
{
if (stream->__user_locking != 0) {
return __PUTC_UNLOCKED_MACRO(c, stream);
@@ -93,8 +100,10 @@ int attribute_hidden __fputc(int c, register FILE *stream)
return retval;
}
}
-strong_alias(__fputc,fputc)
-hidden_strong_alias(__fputc,__putc)
-weak_alias(__fputc,putc)
+libc_hidden_def(fputc)
+
+libc_hidden_proto(putc)
+strong_alias(fputc,putc)
+libc_hidden_def(putc)
#endif
diff --git a/libc/stdio/fputc_unlocked.c b/libc/stdio/fputc_unlocked.c
new file mode 100644
index 000000000..dc4c77a51
--- /dev/null
+++ b/libc/stdio/fputc_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fputc.c"
diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c
index 64e7fd57f..4111491d6 100644
--- a/libc/stdio/fputs.c
+++ b/libc/stdio/fputs.c
@@ -7,6 +7,11 @@
#include "_stdio.h"
+libc_hidden_proto(fputs_unlocked)
+
+libc_hidden_proto(strlen)
+libc_hidden_proto(fwrite_unlocked)
+
/* Note: The standard says fputs returns a nonnegative number on
* success. In this implementation, we return the length of the
* string written on success.
@@ -14,35 +19,37 @@
#ifdef __DO_UNLOCKED
-int attribute_hidden __fputs_unlocked(register const char * __restrict s,
+int fputs_unlocked(register const char * __restrict s,
FILE * __restrict stream)
{
- size_t n = __strlen(s);
+ size_t n = strlen(s);
- return ((__fwrite_unlocked(s, 1, n, stream) == n) ? n : EOF);
+ return ((fwrite_unlocked(s, 1, n, stream) == n) ? n : EOF);
}
+libc_hidden_def(fputs_unlocked)
-weak_alias(__fputs_unlocked,fputs_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fputs_unlocked,__fputs)
-weak_alias(__fputs_unlocked,fputs)
+libc_hidden_proto(fputs)
+strong_alias(fputs_unlocked,fputs)
+libc_hidden_def(fputs)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-int attribute_hidden __fputs(const char * __restrict s, register FILE * __restrict stream)
+libc_hidden_proto(fputs)
+int fputs(const char * __restrict s, register FILE * __restrict stream)
{
int retval;
__STDIO_AUTO_THREADLOCK_VAR;
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fputs_unlocked(s, stream);
+ retval = fputs_unlocked(s, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fputs,fputs)
+libc_hidden_def(fputs)
#endif
diff --git a/libc/stdio/fputs_unlocked.c b/libc/stdio/fputs_unlocked.c
new file mode 100644
index 000000000..c7ff3f59b
--- /dev/null
+++ b/libc/stdio/fputs_unlocked.c
@@ -0,0 +1,14 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+
+#include <features.h>
+
+#ifdef __USE_GNU
+# define __DO_UNLOCKED
+# include "fputs.c"
+#endif
diff --git a/libc/stdio/fputwc.c b/libc/stdio/fputwc.c
index 8f1178710..240c1e9c4 100644
--- a/libc/stdio/fputwc.c
+++ b/libc/stdio/fputwc.c
@@ -7,18 +7,20 @@
#include "_stdio.h"
+libc_hidden_proto(fputwc_unlocked)
+
#ifdef __DO_UNLOCKED
-wint_t attribute_hidden __fputwc_unlocked(wchar_t wc, FILE *stream)
+wint_t fputwc_unlocked(wchar_t wc, FILE *stream)
{
return _wstdio_fwrite(&wc, 1, stream) ? wc : WEOF;
}
+libc_hidden_def(fputwc_unlocked)
-weak_alias(__fputwc_unlocked,fputwc_unlocked)
-weak_alias(__fputwc_unlocked,putwc_unlocked)
+strong_alias(fputwc_unlocked,putwc_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__fputwc_unlocked,fputwc)
-weak_alias(__fputwc_unlocked,putwc)
+strong_alias(fputwc_unlocked,fputwc)
+strong_alias(fputwc_unlocked,putwc)
#endif
#elif defined __UCLIBC_HAS_THREADS__
@@ -30,13 +32,13 @@ wint_t fputwc(wchar_t wc, register FILE *stream)
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fputwc_unlocked(wc, stream);
+ retval = fputwc_unlocked(wc, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-weak_alias(fputwc,putwc)
+strong_alias(fputwc,putwc)
#endif
diff --git a/libc/stdio/fputwc_unlocked.c b/libc/stdio/fputwc_unlocked.c
new file mode 100644
index 000000000..757cbd0d2
--- /dev/null
+++ b/libc/stdio/fputwc_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fputwc.c"
diff --git a/libc/stdio/fputws.c b/libc/stdio/fputws.c
index 74919d6ea..ecbc121dd 100644
--- a/libc/stdio/fputws.c
+++ b/libc/stdio/fputws.c
@@ -5,44 +5,45 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define wcslen __wcslen
-
#include "_stdio.h"
+libc_hidden_proto(fputws_unlocked)
+
+libc_hidden_proto(wcslen)
+
#ifdef __DO_UNLOCKED
-int attribute_hidden __fputws_unlocked(const wchar_t *__restrict ws,
+int fputws_unlocked(const wchar_t *__restrict ws,
register FILE *__restrict stream)
{
size_t n = wcslen(ws);
return (_wstdio_fwrite(ws, n, stream) == n) ? 0 : -1;
}
+libc_hidden_def(fputws_unlocked)
-weak_alias(__fputws_unlocked,fputws_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fputws_unlocked,__fputws)
-weak_alias(__fputws_unlocked,fputws)
+libc_hidden_proto(fputws)
+strong_alias(fputws_unlocked,fputws)
+libc_hidden_def(fputws)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-extern int __fputws_unlocked(const wchar_t *__restrict ws,
- FILE *__restrict stream) attribute_hidden;
-
-int attribute_hidden __fputws(const wchar_t *__restrict ws, register FILE *__restrict stream)
+libc_hidden_proto(fputws)
+int fputws(const wchar_t *__restrict ws, register FILE *__restrict stream)
{
int retval;
__STDIO_AUTO_THREADLOCK_VAR;
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fputws_unlocked(ws, stream);
+ retval = fputws_unlocked(ws, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fputws,fputws)
+libc_hidden_def(fputws)
#endif
diff --git a/libc/stdio/fputws_unlocked.c b/libc/stdio/fputws_unlocked.c
new file mode 100644
index 000000000..b3a037771
--- /dev/null
+++ b/libc/stdio/fputws_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fputws.c"
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c
index 0defb36a0..c603a9d2e 100644
--- a/libc/stdio/fread.c
+++ b/libc/stdio/fread.c
@@ -7,9 +7,14 @@
#include "_stdio.h"
+libc_hidden_proto(fread_unlocked)
+
#ifdef __DO_UNLOCKED
-size_t attribute_hidden __fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb,
+libc_hidden_proto(memcpy)
+libc_hidden_proto(fflush_unlocked)
+
+size_t fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb,
FILE * __restrict stream)
{
__STDIO_STREAM_VALIDATE(stream);
@@ -44,7 +49,7 @@ size_t attribute_hidden __fread_unlocked(void * __restrict ptr, size_t size, siz
if (avail > todo) {
avail = todo;
}
- __memcpy(buffer, stream->__bufpos, avail);
+ memcpy(buffer, stream->__bufpos, avail);
buffer += avail;
stream->__bufpos += avail;
if (!(todo -= avail)) {
@@ -82,16 +87,18 @@ size_t attribute_hidden __fread_unlocked(void * __restrict ptr, size_t size, siz
__STDIO_STREAM_VALIDATE(stream);
return 0;
}
+libc_hidden_def(fread_unlocked)
-weak_alias(__fread_unlocked,fread_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fread_unlocked,__fread)
-weak_alias(__fread_unlocked,fread)
+libc_hidden_proto(fread)
+strong_alias(fread_unlocked,fread)
+libc_hidden_def(fread)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-size_t attribute_hidden __fread(void * __restrict ptr, size_t size, size_t nmemb,
+libc_hidden_proto(fread)
+size_t fread(void * __restrict ptr, size_t size, size_t nmemb,
register FILE * __restrict stream)
{
size_t retval;
@@ -99,12 +106,12 @@ size_t attribute_hidden __fread(void * __restrict ptr, size_t size, size_t nmemb
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fread_unlocked(ptr, size, nmemb, stream);
+ retval = fread_unlocked(ptr, size, nmemb, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fread,fread)
+libc_hidden_def(fread)
#endif
diff --git a/libc/stdio/fread_unlocked.c b/libc/stdio/fread_unlocked.c
new file mode 100644
index 000000000..441edbb64
--- /dev/null
+++ b/libc/stdio/fread_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fread.c"
diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c
index 7df035d48..7314807d3 100644
--- a/libc/stdio/freopen.c
+++ b/libc/stdio/freopen.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(fclose)
+
#ifndef __DO_LARGEFILE
# define FILEDES_ARG (-1)
#endif
diff --git a/libc/stdio/fscanf.c b/libc/stdio/fscanf.c
new file mode 100644
index 000000000..102cb8d59
--- /dev/null
+++ b/libc/stdio/fscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_fscanf
+#include "_scanf.c"
diff --git a/libc/stdio/fseeko.c b/libc/stdio/fseeko.c
index 190485775..f63ebad4e 100644
--- a/libc/stdio/fseeko.c
+++ b/libc/stdio/fseeko.c
@@ -12,15 +12,20 @@
#endif
#ifndef __DO_LARGEFILE
-# define FSEEK __fseek
+# define FSEEK fseek
# define OFFSET_TYPE long int
#endif
-int attribute_hidden FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence)
+#ifdef __UCLIBC_HAS_LFS__
+libc_hidden_proto(fseeko64)
+#endif
+libc_hidden_proto(fseek)
+
+int FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence)
{
#if defined(__UCLIBC_HAS_LFS__) && !defined(__DO_LARGEFILE)
- return __fseeko64(stream, offset, whence);
+ return fseeko64(stream, offset, whence);
#else
@@ -74,8 +79,8 @@ int attribute_hidden FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence
}
#ifdef __DO_LARGEFILE
-strong_alias(__fseeko64,fseeko64)
+libc_hidden_def(fseeko64)
#else
-strong_alias(__fseek,fseek)
-weak_alias(__fseek,fseeko)
+libc_hidden_def(fseek)
+strong_alias(fseek,fseeko)
#endif
diff --git a/libc/stdio/fseeko64.c b/libc/stdio/fseeko64.c
index 5bc4ae34e..78cab1b5c 100644
--- a/libc/stdio/fseeko64.c
+++ b/libc/stdio/fseeko64.c
@@ -8,6 +8,6 @@
#include "_stdio.h"
#define __DO_LARGEFILE
-#define FSEEK __fseeko64
+#define FSEEK fseeko64
#define OFFSET_TYPE __off64_t
#include "fseeko.c"
diff --git a/libc/stdio/fsetpos.c b/libc/stdio/fsetpos.c
index f33043f3b..d63adc024 100644
--- a/libc/stdio/fsetpos.c
+++ b/libc/stdio/fsetpos.c
@@ -8,9 +8,11 @@
#include "_stdio.h"
#ifndef __DO_LARGEFILE
-#define FSEEK __fseek
+#define FSEEK fseek
#endif
+libc_hidden_proto(FSEEK)
+
int fsetpos(FILE *stream, register const fpos_t *pos)
{
#ifdef __STDIO_MBSTATE
diff --git a/libc/stdio/fsetpos64.c b/libc/stdio/fsetpos64.c
index bf7d574cb..82819a4fe 100644
--- a/libc/stdio/fsetpos64.c
+++ b/libc/stdio/fsetpos64.c
@@ -10,5 +10,5 @@
#define __DO_LARGEFILE
#define fsetpos fsetpos64
#define fpos_t fpos64_t
-#define FSEEK __fseeko64
+#define FSEEK fseeko64
#include "fsetpos.c"
diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c
index 7f5c53126..4445471a4 100644
--- a/libc/stdio/ftello.c
+++ b/libc/stdio/ftello.c
@@ -7,16 +7,21 @@
#include "_stdio.h"
+#ifdef __UCLIBC_HAS_LFS__
+libc_hidden_proto(ftello64)
+#endif
+libc_hidden_proto(ftell)
+
#ifndef __DO_LARGEFILE
-# define FTELL __ftell
+# define FTELL ftell
# define OFFSET_TYPE long int
#endif
-OFFSET_TYPE attribute_hidden FTELL(register FILE *stream)
+OFFSET_TYPE FTELL(register FILE *stream)
{
#if defined(__UCLIBC_HAS_LFS__) && !defined(__DO_LARGEFILE)
- __offmax_t pos = __ftello64(stream);
+ __offmax_t pos = ftello64(stream);
if ((sizeof(long) >= sizeof(__offmax_t)) || (((long) pos) == pos)) {
return ((long) pos);
@@ -47,8 +52,8 @@ OFFSET_TYPE attribute_hidden FTELL(register FILE *stream)
}
#ifdef __DO_LARGEFILE
-weak_alias(__ftello64,ftello64)
+libc_hidden_def(ftello64)
#else
-weak_alias(__ftell,ftell)
-weak_alias(ftell,ftello)
+libc_hidden_def(ftell)
+strong_alias(ftell,ftello)
#endif
diff --git a/libc/stdio/ftello64.c b/libc/stdio/ftello64.c
index 32a37d368..905834f39 100644
--- a/libc/stdio/ftello64.c
+++ b/libc/stdio/ftello64.c
@@ -8,6 +8,6 @@
#include "_stdio.h"
#define __DO_LARGEFILE
-#define FTELL __ftello64
+#define FTELL ftello64
#define OFFSET_TYPE __off64_t
#include "ftello.c"
diff --git a/libc/stdio/fwprintf.c b/libc/stdio/fwprintf.c
index c81d40482..f2a1afbec 100644
--- a/libc/stdio/fwprintf.c
+++ b/libc/stdio/fwprintf.c
@@ -9,13 +9,15 @@
#include <stdarg.h>
#include <wchar.h>
+libc_hidden_proto(vfwprintf)
+
int fwprintf(FILE * __restrict stream, const wchar_t * __restrict format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
- rv = __vfwprintf(stream, format, arg);
+ rv = vfwprintf(stream, format, arg);
va_end(arg);
return rv;
diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c
index abe24fbb7..7be794ab4 100644
--- a/libc/stdio/fwrite.c
+++ b/libc/stdio/fwrite.c
@@ -7,9 +7,11 @@
#include "_stdio.h"
+libc_hidden_proto(fwrite_unlocked)
+
#ifdef __DO_UNLOCKED
-size_t attribute_hidden __fwrite_unlocked(const void * __restrict ptr, size_t size,
+size_t fwrite_unlocked(const void * __restrict ptr, size_t size,
size_t nmemb, register FILE * __restrict stream)
{
__STDIO_STREAM_VALIDATE(stream);
@@ -33,16 +35,18 @@ size_t attribute_hidden __fwrite_unlocked(const void * __restrict ptr, size_t si
return 0;
}
+libc_hidden_def(fwrite_unlocked)
-weak_alias(__fwrite_unlocked,fwrite_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-hidden_strong_alias(__fwrite_unlocked,__fwrite)
-weak_alias(__fwrite_unlocked,fwrite)
+libc_hidden_proto(fwrite)
+strong_alias(fwrite_unlocked,fwrite)
+libc_hidden_def(fwrite)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-size_t attribute_hidden __fwrite(const void * __restrict ptr, size_t size,
+libc_hidden_proto(fwrite)
+size_t fwrite(const void * __restrict ptr, size_t size,
size_t nmemb, register FILE * __restrict stream)
{
size_t retval;
@@ -50,12 +54,12 @@ size_t attribute_hidden __fwrite(const void * __restrict ptr, size_t size,
__STDIO_AUTO_THREADLOCK(stream);
- retval = __fwrite_unlocked(ptr, size, nmemb, stream);
+ retval = fwrite_unlocked(ptr, size, nmemb, stream);
__STDIO_AUTO_THREADUNLOCK(stream);
return retval;
}
-strong_alias(__fwrite,fwrite)
+libc_hidden_def(fwrite)
#endif
diff --git a/libc/stdio/fwrite_unlocked.c b/libc/stdio/fwrite_unlocked.c
new file mode 100644
index 000000000..0f9e026c0
--- /dev/null
+++ b/libc/stdio/fwrite_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "fwrite.c"
diff --git a/libc/stdio/fwscanf.c b/libc/stdio/fwscanf.c
new file mode 100644
index 000000000..3409d00a0
--- /dev/null
+++ b/libc/stdio/fwscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_fwscanf
+#include "_scanf.c"
diff --git a/libc/stdio/getchar.c b/libc/stdio/getchar.c
index d17704056..6da8307b6 100644
--- a/libc/stdio/getchar.c
+++ b/libc/stdio/getchar.c
@@ -7,21 +7,21 @@
#include "_stdio.h"
-#undef getchar_unlocked
-#undef getchar
+libc_hidden_proto(__fgetc_unlocked)
+#undef getchar
#ifdef __DO_UNLOCKED
-int attribute_hidden __getchar_unlocked(void)
+#undef getchar_unlocked
+int getchar_unlocked(void)
{
register FILE *stream = stdin;
return __GETC_UNLOCKED_MACRO(stream);
}
-weak_alias(__getchar_unlocked,getchar_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__getchar_unlocked,getchar)
+strong_alias(getchar_unlocked,getchar)
#endif
#elif defined __UCLIBC_HAS_THREADS__
diff --git a/libc/stdio/getchar_unlocked.c b/libc/stdio/getchar_unlocked.c
new file mode 100644
index 000000000..60ea25129
--- /dev/null
+++ b/libc/stdio/getchar_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "getchar.c"
diff --git a/libc/stdio/getdelim.c b/libc/stdio/getdelim.c
index e1b808340..21c86f400 100644
--- a/libc/stdio/getdelim.c
+++ b/libc/stdio/getdelim.c
@@ -5,8 +5,15 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
+#include <features.h>
+
+#ifdef __USE_GNU
#include "_stdio.h"
+libc_hidden_proto(getdelim)
+
+libc_hidden_proto(__fgetc_unlocked)
+
/* Note: There is a defect in this function. (size_t vs ssize_t). */
/* glibc function --
@@ -20,7 +27,7 @@
#define GETDELIM_GROWBY 64
-ssize_t attribute_hidden __getdelim(char **__restrict lineptr, size_t *__restrict n,
+ssize_t getdelim(char **__restrict lineptr, size_t *__restrict n,
int delimiter, register FILE *__restrict stream)
{
register char *buf;
@@ -73,5 +80,5 @@ ssize_t attribute_hidden __getdelim(char **__restrict lineptr, size_t *__restric
return pos;
}
-
-strong_alias(__getdelim,getdelim)
+libc_hidden_def(getdelim)
+#endif
diff --git a/libc/stdio/getline.c b/libc/stdio/getline.c
index 943526abe..22b67b831 100644
--- a/libc/stdio/getline.c
+++ b/libc/stdio/getline.c
@@ -5,13 +5,19 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define getdelim __getdelim
+#include <features.h>
+#ifdef __USE_GNU
#include "_stdio.h"
-ssize_t attribute_hidden __getline(char **__restrict lineptr, size_t *__restrict n,
+libc_hidden_proto(getline)
+
+libc_hidden_proto(getdelim)
+
+ssize_t getline(char **__restrict lineptr, size_t *__restrict n,
FILE *__restrict stream)
{
return getdelim(lineptr, n, '\n', stream);
}
-strong_alias(__getline,getline)
+libc_hidden_def(getline)
+#endif
diff --git a/libc/stdio/gets.c b/libc/stdio/gets.c
index 1badd8152..5ff7869dc 100644
--- a/libc/stdio/gets.c
+++ b/libc/stdio/gets.c
@@ -11,6 +11,14 @@ link_warning(gets, "the 'gets' function is dangerous and should not be used.")
/* UNSAFE FUNCTION -- do not bother optimizing */
+libc_hidden_proto(getchar_unlocked)
+libc_hidden_proto(__fgetc_unlocked)
+#ifdef __STDIO_GETC_MACRO
+libc_hidden_proto(__stdin)
+#else
+#define __stdin stdin
+#endif
+
char *gets(char *s)
{
register char *p = s;
@@ -21,7 +29,7 @@ char *gets(char *s)
/* Note: don't worry about performance here... this shouldn't be used!
* Therefore, force actual function call. */
- while (((c = __getchar_unlocked()) != EOF) && ((*p = c) != '\n')) {
+ while (((c = getchar_unlocked()) != EOF) && ((*p = c) != '\n')) {
++p;
}
if ((c == EOF) || (s == p)) {
diff --git a/libc/stdio/getw.c b/libc/stdio/getw.c
index 6b3b9e5e7..e3aeda92c 100644
--- a/libc/stdio/getw.c
+++ b/libc/stdio/getw.c
@@ -7,12 +7,14 @@
#include "_stdio.h"
+libc_hidden_proto(fread_unlocked)
+
/* SUSv2 Legacy function -- need not be reentrant. */
int getw(FILE *stream)
{
int aw;
- return (__fread_unlocked((void *) &aw, sizeof(int), 1, stream) != 0)
+ return (fread_unlocked((void *) &aw, sizeof(int), 1, stream) != 0)
? aw : EOF;
}
diff --git a/libc/stdio/getwchar.c b/libc/stdio/getwchar.c
index 90e5a032e..9c480b564 100644
--- a/libc/stdio/getwchar.c
+++ b/libc/stdio/getwchar.c
@@ -9,23 +9,24 @@
#ifdef __DO_UNLOCKED
-wint_t __getwchar_unlocked(void)
+libc_hidden_proto(fgetwc_unlocked)
+
+wint_t getwchar_unlocked(void)
{
- return __fgetwc_unlocked(stdin);
+ return fgetwc_unlocked(stdin);
}
-weak_alias(__getwchar_unlocked,getwchar_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__getwchar_unlocked,getwchar)
+strong_alias(getwchar_unlocked,getwchar)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-extern wint_t __fgetwc (__FILE *__stream) attribute_hidden;
+libc_hidden_proto(fgetwc)
wint_t getwchar(void)
{
- return __fgetwc(stdin);
+ return fgetwc(stdin);
}
#endif
diff --git a/libc/stdio/getwchar_unlocked.c b/libc/stdio/getwchar_unlocked.c
new file mode 100644
index 000000000..af4a9e888
--- /dev/null
+++ b/libc/stdio/getwchar_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "getwchar.c"
diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c
index ce6bde1a4..f81ef8688 100644
--- a/libc/stdio/old_vfprintf.c
+++ b/libc/stdio/old_vfprintf.c
@@ -127,10 +127,7 @@
/**************************************************************************/
-#define strnlen __strnlen
-
#define _ISOC99_SOURCE /* for ULLONG primarily... */
-#define _GNU_SOURCE /* for strnlen */
#include "_stdio.h"
/* #include <stdio.h> */
#include <stdarg.h>
@@ -148,6 +145,13 @@
#include <pthread.h>
#endif /* __UCLIBC_HAS_THREADS__ */
+libc_hidden_proto(strlen)
+libc_hidden_proto(strnlen)
+libc_hidden_proto(memcpy)
+libc_hidden_proto(putc_unlocked)
+libc_hidden_proto(__fputc_unlocked)
+libc_hidden_proto(__glibc_strerror_r)
+
/* #undef __UCLIBC_HAS_FLOATS__ */
/* #undef WANT_FLOAT_ERROR */
/* #define WANT_FLOAT_ERROR 1 */
@@ -166,7 +170,7 @@
#ifdef __STDIO_BUFFERS
-#define PUTC(C,F) __putc_unlocked((C),(F))
+#define PUTC(C,F) putc_unlocked((C),(F))
#define OUTNSTR _outnstr
#define _outnstr(stream, string, len) __stdio_fwrite(string, len, stream)
@@ -190,7 +194,7 @@ static void _outnstr(FILE *stream, const unsigned char *s, size_t n)
if (r > n) {
r = n;
}
- __memcpy(f->bufpos, s, r);
+ memcpy(f->bufpos, s, r);
f->bufpos += r;
}
}
@@ -199,7 +203,7 @@ static void _outnstr(FILE *stream, const unsigned char *s, size_t n)
static void putc_unlocked_sprintf(int c, __FILE_vsnprintf *f)
{
if (!__STDIO_STREAM_IS_FAKE_VSNPRINTF_NB(&f->f)) {
- __putc_unlocked(c, &f->f);
+ putc_unlocked(c, &f->f);
} else if (f->bufpos < f->bufend) {
*f->bufpos++ = c;
}
@@ -236,7 +240,7 @@ static void _charpad(FILE * __restrict stream, int padchar, size_t numpad)
static void _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
{
if (type & 0x80) { /* Some type of padding needed. */
- int buflen = __strlen((const char *) buf);
+ int buflen = strlen((const char *) buf);
if ((len -= buflen) > 0) {
_charpad(fp, (type & 0x7f), len);
}
@@ -341,7 +345,8 @@ static const char u_spec[] = "%nbopxXudics";
/* u_radix[i] <-> u_spec[i+2] for unsigned entries only */
static const char u_radix[] = "\x02\x08\x10\x10\x10\x0a";
-int attribute_hidden __vfprintf(FILE * __restrict op, register const char * __restrict fmt,
+libc_hidden_proto(vfprintf)
+int vfprintf(FILE * __restrict op, register const char * __restrict fmt,
va_list ap)
{
union {
@@ -450,7 +455,7 @@ int attribute_hidden __vfprintf(FILE * __restrict op, register const char * __re
if (*fmt == 'm') {
flag[FLAG_PLUS] = '\0';
flag[FLAG_0_PAD] = ' ';
- p = __glibc_strerror_r_internal(errno, tmp, sizeof(tmp));
+ p = __glibc_strerror_r(errno, tmp, sizeof(tmp));
goto print;
}
#endif
@@ -711,4 +716,4 @@ int attribute_hidden __vfprintf(FILE * __restrict op, register const char * __re
return i;
}
-strong_alias(__vfprintf,vfprintf)
+libc_hidden_def(vfprintf)
diff --git a/libc/stdio/open_memstream.c b/libc/stdio/open_memstream.c
index f750cd11c..25c2f9f61 100644
--- a/libc/stdio/open_memstream.c
+++ b/libc/stdio/open_memstream.c
@@ -5,10 +5,15 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define fopencookie __fopencookie
+#include <features.h>
+#ifdef __USE_GNU
#include "_stdio.h"
+libc_hidden_proto(memcpy)
+libc_hidden_proto(memset)
+libc_hidden_proto(fopencookie)
+
#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
#error no custom streams!
#endif
@@ -53,7 +58,7 @@ static ssize_t oms_write(register void *cookie, const char *buf, size_t bufsize)
}
}
- __memcpy(COOKIE->buf + COOKIE->pos, buf, bufsize);
+ memcpy(COOKIE->buf + COOKIE->pos, buf, bufsize);
COOKIE->pos += bufsize;
if (COOKIE->pos > COOKIE->eof) {
@@ -92,7 +97,7 @@ static int oms_seek(register void *cookie, __offmax_t *pos, int whence)
if (buf) {
*COOKIE->bufloc = COOKIE->buf = buf;
COOKIE->len = leastlen;
- __memset(buf + COOKIE->eof, leastlen - COOKIE->eof, 0); /* 0-fill */
+ memset(buf + COOKIE->eof, leastlen - COOKIE->eof, 0); /* 0-fill */
} else {
/* TODO: check glibc errno setting... */
return -1;
@@ -102,7 +107,7 @@ static int oms_seek(register void *cookie, __offmax_t *pos, int whence)
*pos = COOKIE->pos = --leastlen;
if (leastlen > COOKIE->eof) {
- __memset(COOKIE->buf + COOKIE->eof, leastlen - COOKIE->eof, 0);
+ memset(COOKIE->buf + COOKIE->eof, leastlen - COOKIE->eof, 0);
*COOKIE->sizeloc = COOKIE->eof;
}
@@ -126,7 +131,8 @@ static const cookie_io_functions_t _oms_io_funcs = {
* (ie replace the FILE buffer with the cookie buffer and update FILE bufstart,
* etc. whenever we seek). */
-FILE attribute_hidden *__open_memstream(char **__restrict bufloc, size_t *__restrict sizeloc)
+libc_hidden_proto(open_memstream)
+FILE *open_memstream(char **__restrict bufloc, size_t *__restrict sizeloc)
{
register __oms_cookie *cookie;
register FILE *fp;
@@ -162,4 +168,5 @@ FILE attribute_hidden *__open_memstream(char **__restrict bufloc, size_t *__rest
return NULL;
}
-strong_alias(__open_memstream,open_memstream)
+libc_hidden_def(open_memstream)
+#endif
diff --git a/libc/stdio/parse_printf_format.c b/libc/stdio/parse_printf_format.c
new file mode 100644
index 000000000..38266b3de
--- /dev/null
+++ b/libc/stdio/parse_printf_format.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_parse_printf_format
+#include "_vfprintf.c"
diff --git a/libc/stdio/perror.c b/libc/stdio/perror.c
index 9edcf4efb..2c3cbbdb5 100644
--- a/libc/stdio/perror.c
+++ b/libc/stdio/perror.c
@@ -7,11 +7,16 @@
#include "_stdio.h"
+libc_hidden_proto(fprintf)
+libc_hidden_proto(__glibc_strerror_r)
+libc_hidden_proto(stderr)
+
#ifdef __UCLIBC_MJN3_ONLY__
#warning CONSIDER: Increase buffer size for error message (non-%m case)?
#endif
-void attribute_hidden __perror(register const char *s)
+libc_hidden_proto(perror)
+void perror(register const char *s)
{
/* If the program is calling perror, it's a safe bet that printf and
* friends are used as well. It is also possible that the calling
@@ -30,8 +35,8 @@ void attribute_hidden __perror(register const char *s)
{
char buf[64];
fprintf(stderr, "%s%s%s\n", s, sep,
- __glibc_strerror_r_internal(errno, buf, sizeof(buf)));
+ __glibc_strerror_r(errno, buf, sizeof(buf)));
}
#endif
}
-strong_alias(__perror,perror)
+libc_hidden_def(perror)
diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c
index f84a27a3c..2163d7f8c 100644
--- a/libc/stdio/popen.c
+++ b/libc/stdio/popen.c
@@ -1,6 +1,7 @@
/* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
- * GNU Library General Public License (LGPL) version 2 or later.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
@@ -14,26 +15,29 @@
* Fix failure exit code for failed execve().
*/
-#define waitpid __waitpid
-#define execl __execl
-#define dup2 __dup2
-#define fdopen __fdopen
-#define pipe __pipe
-#define vfork __vfork
-#define fork __fork
-
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
+libc_hidden_proto(close)
+libc_hidden_proto(_exit)
+libc_hidden_proto(waitpid)
+libc_hidden_proto(execl)
+libc_hidden_proto(dup2)
+libc_hidden_proto(fdopen)
+libc_hidden_proto(pipe)
+libc_hidden_proto(vfork)
+libc_hidden_proto(fclose)
+
/* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
#include <sys/syscall.h>
#if ! defined __NR_vfork
# define vfork fork
# define VFORK_LOCK ((void) 0)
# define VFORK_UNLOCK ((void) 0)
+libc_hidden_proto(fork)
#endif
#ifdef __UCLIBC_HAS_THREADS__
@@ -88,36 +92,36 @@ FILE *popen(const char *command, const char *modes)
parent_fd = pipe_fd[1-child_writing];
if (!(fp = fdopen(parent_fd, modes))) {
- __close(parent_fd);
- __close(child_fd);
+ close(parent_fd);
+ close(child_fd);
goto FREE_PI;
}
VFORK_LOCK;
if ((pid = vfork()) == 0) { /* Child of vfork... */
- __close(parent_fd);
+ close(parent_fd);
if (child_fd != child_writing) {
dup2(child_fd, child_writing);
- __close(child_fd);
+ close(child_fd);
}
/* SUSv3 requires that any previously popen()'d streams in the
* parent shall be closed in the child. */
for (po = popen_list ; po ; po = po->next) {
- __close(po->f->__filedes);
+ close(po->f->__filedes);
}
execl("/bin/sh", "sh", "-c", command, (char *)0);
/* SUSv3 mandates an exit code of 127 for the child if the
* command interpreter can not be invoked. */
- _exit_internal(127);
+ _exit(127);
}
VFORK_UNLOCK;
/* We need to close the child filedes whether vfork failed or
* it succeeded and we're in the parent. */
- __close(child_fd);
+ close(child_fd);
if (pid > 0) { /* Parent of vfork... */
pi->pid = pid;
diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c
index 82326a9c3..617561fec 100644
--- a/libc/stdio/printf.c
+++ b/libc/stdio/printf.c
@@ -8,15 +8,18 @@
#include "_stdio.h"
#include <stdarg.h>
-int attribute_hidden __printf(const char * __restrict format, ...)
+libc_hidden_proto(vfprintf)
+
+libc_hidden_proto(printf)
+int printf(const char * __restrict format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
- rv = __vfprintf(stdout, format, arg);
+ rv = vfprintf(stdout, format, arg);
va_end(arg);
return rv;
}
-strong_alias(__printf,printf)
+libc_hidden_def(printf)
diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c
index e503b9484..b54a7a815 100644
--- a/libc/stdio/putchar.c
+++ b/libc/stdio/putchar.c
@@ -7,21 +7,21 @@
#include "_stdio.h"
-#undef putchar_unlocked
-#undef putchar
+libc_hidden_proto(__fputc_unlocked)
+#undef putchar
#ifdef __DO_UNLOCKED
-int __putchar_unlocked(int c)
+#undef putchar_unlocked
+int putchar_unlocked(int c)
{
register FILE *stream = stdout;
return __PUTC_UNLOCKED_MACRO(c, stream);
}
-weak_alias(__putchar_unlocked,putchar_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__putchar_unlocked,putchar)
+strong_alias(putchar_unlocked,putchar)
#endif
#elif defined __UCLIBC_HAS_THREADS__
diff --git a/libc/stdio/putchar_unlocked.c b/libc/stdio/putchar_unlocked.c
new file mode 100644
index 000000000..6d6ec471a
--- /dev/null
+++ b/libc/stdio/putchar_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "putchar.c"
diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c
index 3a510325b..08525b2f6 100644
--- a/libc/stdio/puts.c
+++ b/libc/stdio/puts.c
@@ -7,6 +7,9 @@
#include "_stdio.h"
+libc_hidden_proto(__fputc_unlocked)
+libc_hidden_proto(fputs_unlocked)
+
int puts(register const char * __restrict s)
{
register FILE *stream = stdout; /* This helps bcc optimize. */
@@ -20,9 +23,9 @@ int puts(register const char * __restrict s)
* then we could have a newline in the buffer of an LBF stream. */
/* Note: Nonportable as fputs need only return nonnegative on success. */
- if ((n = __fputs_unlocked(s, stream)) != EOF) {
+ if ((n = fputs_unlocked(s, stream)) != EOF) {
++n;
- if (__fputc_unlocked_internal('\n', stream) == EOF) {
+ if (__fputc_unlocked('\n', stream) == EOF) {
n = EOF;
}
}
diff --git a/libc/stdio/putw.c b/libc/stdio/putw.c
index 5dfa06890..469e44aea 100644
--- a/libc/stdio/putw.c
+++ b/libc/stdio/putw.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(fwrite_unlocked)
+
/* SUSv2 Legacy function -- need not be reentrant. */
int putw(int w, FILE *stream)
@@ -20,9 +22,9 @@ int putw(int w, FILE *stream)
#endif
#if EOF == -1
- return __fwrite_unlocked((void *) PW, sizeof(int), 1, stream) - 1;
+ return fwrite_unlocked((void *) PW, sizeof(int), 1, stream) - 1;
#else
- return (__fwrite_unlocked((void *) PW, sizeof(int), 1, stream) != 0)
+ return (fwrite_unlocked((void *) PW, sizeof(int), 1, stream) != 0)
? 0 : EOF;
#endif
}
diff --git a/libc/stdio/putwchar.c b/libc/stdio/putwchar.c
index d093656e6..7a6501c28 100644
--- a/libc/stdio/putwchar.c
+++ b/libc/stdio/putwchar.c
@@ -9,23 +9,26 @@
#ifdef __DO_UNLOCKED
-wint_t __putwchar_unlocked(wchar_t wc)
+libc_hidden_proto(fputwc_unlocked)
+
+wint_t putwchar_unlocked(wchar_t wc)
{
- return __fputwc_unlocked(wc, stdout);
+ return fputwc_unlocked(wc, stdout);
}
-weak_alias(__putwchar_unlocked,putwchar_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
-weak_alias(__putwchar_unlocked,putwchar)
+strong_alias(putwchar_unlocked,putwchar)
#endif
#elif defined __UCLIBC_HAS_THREADS__
-extern int __fputc (int __c, FILE *__stream) attribute_hidden;
+libc_hidden_proto(__fputc_unlocked)
+/* psm: should this be fputwc? */
+libc_hidden_proto(fputc)
wint_t putwchar(wchar_t wc)
{
- return __fputc(wc, stdout);
+ return fputc(wc, stdout);
}
#endif
diff --git a/libc/stdio/putwchar_unlocked.c b/libc/stdio/putwchar_unlocked.c
new file mode 100644
index 000000000..5b0c60006
--- /dev/null
+++ b/libc/stdio/putwchar_unlocked.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define __DO_UNLOCKED
+#include "putwchar.c"
diff --git a/libc/stdio/register_printf_function.c b/libc/stdio/register_printf_function.c
new file mode 100644
index 000000000..c6b3240a7
--- /dev/null
+++ b/libc/stdio/register_printf_function.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_register_printf_function
+#include "_vfprintf.c"
diff --git a/libc/stdio/remove.c b/libc/stdio/remove.c
index 2d4fedcc1..04ab12edb 100644
--- a/libc/stdio/remove.c
+++ b/libc/stdio/remove.c
@@ -5,21 +5,22 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define rmdir __rmdir
-#define unlink __unlink
-
#include "_stdio.h"
#include <unistd.h>
#include <errno.h>
+libc_hidden_proto(rmdir)
+libc_hidden_proto(unlink)
+
/* SUSv3 states:
* If path does not name a directory, remove(path) shall be equivalent
* to unlink(path). If path names a directory, remove(path) shall be
* equivalent to rmdir(path).
*/
-int attribute_hidden __remove(register const char *filename)
+libc_hidden_proto(remove)
+int remove(register const char *filename)
{
int saved_errno = errno;
int rv;
@@ -30,4 +31,4 @@ int attribute_hidden __remove(register const char *filename)
}
return rv;
}
-strong_alias(__remove,remove)
+libc_hidden_def(remove)
diff --git a/libc/stdio/rewind.c b/libc/stdio/rewind.c
index 8e0acc2d0..e04d7a086 100644
--- a/libc/stdio/rewind.c
+++ b/libc/stdio/rewind.c
@@ -7,15 +7,18 @@
#include "_stdio.h"
-void attribute_hidden __rewind(register FILE *stream)
+libc_hidden_proto(fseek)
+
+libc_hidden_proto(rewind)
+void rewind(register FILE *stream)
{
__STDIO_AUTO_THREADLOCK_VAR;
__STDIO_AUTO_THREADLOCK(stream);
__STDIO_STREAM_CLEAR_ERROR(stream); /* Clear the error indicator */
- __fseek(stream, 0L, SEEK_SET); /* first since fseek could set it. */
+ fseek(stream, 0L, SEEK_SET); /* first since fseek could set it. */
__STDIO_AUTO_THREADUNLOCK(stream);
}
-strong_alias(__rewind,rewind)
+libc_hidden_def(rewind)
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
index ddc2bd75f..4943c88df 100644
--- a/libc/stdio/scanf.c
+++ b/libc/stdio/scanf.c
@@ -1,2258 +1,9 @@
-/* Copyright (C) 2002-2004 Manuel Novoa III
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
- * This 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.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*
- * This 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 this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Aug 1, 2003
- * New *scanf implementation with lots of bug fixes and *wscanf support.
- * Also now optionally supports hexadecimal float notation, positional
- * args, and glibc locale-specific digit grouping. Should now be
- * standards compliant.
- *
- * Aug 18, 2003
- * Bug fix: scanf %lc,%ls,%l[ would always set mb_fail on eof or error,
- * even when just starting a new mb char.
- * Bug fix: wscanf would incorrectly unget in certain situations.
- *
- * Sep 5, 2003
- * Bug fix: store flag wasn't respected if no positional args.
- * Implement vs{n}scanf for the non-buffered stdio no-wchar case.
- *
- * Sep 13, 2003
- * Bug fix: Fix a problem reported by Atsushi Nemoto <anemo@mba.ocn.ne.jp>
- * for environments where long and long long are the same.
- *
- * Sep 21, 2003
- * Ugh... EOF handling by scanf was completely broken. :-( Regretably,
- * I got my mind fixed in one mode and didn't comply with the standards.
- * Things should be fixed now, but comparision testing is difficult when
- * glibc's scanf is broken and they stubbornly refuse to even acknowledge
- * that it is... even when confronted by specific examples from the C99
- * standards and from an official C standard defect report.
- */
-
-#define wcslen __wcslen
-#define mbsrtowcs __mbsrtowcs
-#define mbrtowc __mbrtowc
-#define ungetc __ungetc
-#define ungetwc __ungetwc
-#define iswspace __iswspace
-#define wcrtomb __wcrtomb
-
-#define _ISOC99_SOURCE /* for LLONG_MAX primarily... */
-#define _GNU_SOURCE
-#include <features.h>
-#include "_stdio.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <errno.h>
-#include <printf.h>
-
-#ifdef __UCLIBC_HAS_WCHAR__
-#include <bits/uClibc_uwchar.h>
-#include <wchar.h>
-#include <wctype.h>
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-#include <langinfo.h>
-#include <locale.h>
-
-#include <assert.h>
-#include <limits.h>
-
-#ifdef __UCLIBC_HAS_THREADS__
-#include <stdio_ext.h>
-#include <pthread.h>
-#endif /* __UCLIBC_HAS_THREADS__ */
-
-#ifdef __UCLIBC_HAS_FLOATS__
-#include <float.h>
-#include <bits/uClibc_fpmax.h>
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-#ifdef __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__
-#ifdef L_vfscanf
-/* only emit this once */
-#warning Forcing undef of __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__ until implemented!
-#endif
-#undef __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__
-#endif
-
-#undef __STDIO_HAS_VSSCANF
-#if defined(__STDIO_BUFFERS) || !defined(__UCLIBC_HAS_WCHAR__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
-#define __STDIO_HAS_VSSCANF 1
-
-#if !defined(__STDIO_BUFFERS) && !defined(__UCLIBC_HAS_WCHAR__)
-typedef struct {
- FILE f;
- unsigned char *bufread; /* pointer to 1 past end of buffer */
- unsigned char *bufpos;
-} __FILE_vsscanf;
-#endif
-
-#endif
-
-extern void _store_inttype(void *dest, int desttype, uintmax_t val);
-
-#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
-
-extern unsigned long long
-_stdlib_strto_ll(register const char * __restrict str,
- char ** __restrict endptr, int base, int sflag);
-#if (ULLONG_MAX == UINTMAX_MAX)
-#define STRTOUIM(s,e,b,sf) _stdlib_strto_ll(s,e,b,sf)
-#endif
-
-#else /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
-
-extern unsigned long
-_stdlib_strto_l(register const char * __restrict str,
- char ** __restrict endptr, int base, int sflag);
-
-#if (ULONG_MAX == UINTMAX_MAX)
-#define STRTOUIM(s,e,b,sf) _stdlib_strto_l(s,e,b,sf)
-#endif
-
-#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
-
-#ifndef STRTOUIM
-#error STRTOUIM conversion function is undefined!
-#endif
-
-/**********************************************************************/
-
-/* The standards require EOF < 0. */
-#if EOF >= CHAR_MIN
-#define __isdigit_char_or_EOF(C) __isdigit_char((C))
-#else
-#define __isdigit_char_or_EOF(C) __isdigit_int((C))
-#endif
-
-/**********************************************************************/
-#ifdef L_fscanf
-
-int attribute_hidden __fscanf(FILE * __restrict stream, const char * __restrict format, ...)
-{
- va_list arg;
- int rv;
-
- va_start(arg, format);
- rv = __vfscanf(stream, format, arg);
- va_end(arg);
-
- return rv;
-}
-strong_alias(__fscanf,fscanf)
-
-#endif
-/**********************************************************************/
-#ifdef L_scanf
-
-int scanf(const char * __restrict format, ...)
-{
- va_list arg;
- int rv;
-
- va_start(arg, format);
- rv = __vfscanf(stdin, format, arg);
- va_end(arg);
-
- return rv;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_sscanf
-
-#ifdef __STDIO_HAS_VSSCANF
-
-int attribute_hidden __sscanf(const char * __restrict str, const char * __restrict format, ...)
-{
- va_list arg;
- int rv;
-
- va_start(arg, format);
- rv = __vsscanf(str, format, arg);
- va_end(arg);
-
- return rv;
-}
-strong_alias(__sscanf,sscanf)
-
-#else /* __STDIO_HAS_VSSCANF */
-#warning Skipping sscanf since no vsscanf!
-#endif /* __STDIO_HAS_VSSCANF */
-
-#endif
-/**********************************************************************/
-#ifdef L_vscanf
-
-int attribute_hidden __vscanf(const char * __restrict format, va_list arg)
-{
- return __vfscanf(stdin, format, arg);
-}
-strong_alias(__vscanf,vscanf)
-
-#endif
-/**********************************************************************/
-#ifdef L_vsscanf
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning WISHLIST: Implement vsscanf for non-buf and no custom stream case.
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
-#ifdef __STDIO_BUFFERS
-
-int attribute_hidden __vsscanf(__const char *sp, __const char *fmt, va_list ap)
-{
- FILE f;
-
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
- f.__filedes = __STDIO_STREAM_FAKE_VSSCANF_FILEDES;
- f.__modeflags = (__FLAG_NARROW|__FLAG_READONLY|__FLAG_READING);
-
-#ifdef __UCLIBC_HAS_WCHAR__
- f.__ungot_width[0] = 0;
-#endif
-#ifdef __STDIO_MBSTATE
- __INIT_MBSTATE(&(f.__state));
-#endif
-
-#ifdef __UCLIBC_HAS_THREADS__
- f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
-#endif
- f.__nextopen = NULL;
-
- /* Set these last since __bufgetc initialization depends on
- * __user_locking and only gets set if user locking is on. */
- f.__bufstart =
- f.__bufpos = (unsigned char *) ((void *) sp);
- f.__bufread =
- f.__bufend = f.__bufstart + __strlen(sp);
- __STDIO_STREAM_ENABLE_GETC(&f);
- __STDIO_STREAM_DISABLE_PUTC(&f);
-
- return __vfscanf(&f, fmt, ap);
-}
-strong_alias(__vsscanf,vsscanf)
-
-#elif !defined(__UCLIBC_HAS_WCHAR__)
-
-int attribute_hidden __vsscanf(__const char *sp, __const char *fmt, va_list ap)
-{
- __FILE_vsscanf f;
-
- f.bufpos = (unsigned char *) ((void *) sp);
- f.bufread = f.bufpos + __strlen(sp);
-
-/* __STDIO_STREAM_RESET_GCS(&f.f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.f.__cookie = &(f.f.__filedes);
- f.f.__gcs.read = NULL;
- f.f.__gcs.write = NULL;
- f.f.__gcs.seek = NULL;
- f.f.__gcs.close = NULL;
-#endif
-
- f.f.__filedes = __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB;
- f.f.__modeflags = (__FLAG_NARROW|__FLAG_READONLY|__FLAG_READING);
-
-/* #ifdef __UCLIBC_HAS_WCHAR__ */
-/* f.f.__ungot_width[0] = 0; */
-/* #endif */
-#ifdef __STDIO_MBSTATE
-#error __STDIO_MBSTATE is defined!
-/* __INIT_MBSTATE(&(f.f.__state)); */
-#endif
-
-#ifdef __UCLIBC_HAS_THREADS__
- f.f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f.f._lock);
-#else
- __stdio_init_mutex(&f.f.__lock);
-#endif
-#endif
- f.f.__nextopen = NULL;
-
- return __vfscanf(&f.f, fmt, ap);
-}
-strong_alias(__vsscanf,vsscanf)
-
-#elif defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
-
-int attribute_hidden __vsscanf(__const char *sp, __const char *fmt, va_list ap)
-{
- FILE *f;
- int rv = EOF;
-
- if ((f = fmemopen((char *)sp, __strlen(sp), "r")) != NULL) {
- rv = __vfscanf(f, fmt, ap);
- fclose(f);
- }
-
- return rv;
-}
-strong_alias(__vsscanf,vsscanf)
-
-#else
-#warning Skipping vsscanf since no buffering, no custom streams, and wchar enabled!
-#ifdef __STDIO_HAS_VSSCANF
-#error WHOA! __STDIO_HAS_VSSCANF is defined!
-#endif
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_fwscanf
-
-int fwscanf(FILE * __restrict stream, const wchar_t * __restrict format, ...)
-{
- va_list arg;
- int rv;
-
- va_start(arg, format);
- rv = __vfwscanf(stream, format, arg);
- va_end(arg);
-
- return rv;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_wscanf
-
-int wscanf(const wchar_t * __restrict format, ...)
-{
- va_list arg;
- int rv;
-
- va_start(arg, format);
- rv = __vfwscanf(stdin, format, arg);
- va_end(arg);
-
- return rv;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_swscanf
-
-#ifdef __STDIO_BUFFERS
-
-int swscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,
- ...)
-{
- va_list arg;
- int rv;
-
- va_start(arg, format);
- rv = __vswscanf(str, format, arg);
- va_end(arg);
-
- return rv;
-}
-#else /* __STDIO_BUFFERS */
-#warning Skipping swscanf since no buffering!
-#endif /* __STDIO_BUFFERS */
-
-#endif
-/**********************************************************************/
-#ifdef L_vwscanf
-
-int vwscanf(const wchar_t * __restrict format, va_list arg)
-{
- return __vfwscanf(stdin, format, arg);
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_vswscanf
-
-#ifdef __STDIO_BUFFERS
-
-int attribute_hidden __vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,
- va_list arg)
-{
- FILE f;
-
- f.__bufstart =
- f.__bufpos = (char *) str;
- f.__bufread =
- f.__bufend = (char *)(str + wcslen(str));
- __STDIO_STREAM_DISABLE_GETC(&f);
- __STDIO_STREAM_DISABLE_PUTC(&f);
-
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
- f.__filedes = __STDIO_STREAM_FAKE_VSWSCANF_FILEDES;
- f.__modeflags = (__FLAG_WIDE|__FLAG_READONLY|__FLAG_READING);
-
-#ifdef __UCLIBC_HAS_WCHAR__
- f.__ungot_width[0] = 0;
-#endif /* __UCLIBC_HAS_WCHAR__ */
-#ifdef __STDIO_MBSTATE
- __INIT_MBSTATE(&(f.__state));
-#endif /* __STDIO_MBSTATE */
-
-#ifdef __UCLIBC_HAS_THREADS__
- f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
-#endif
- f.__nextopen = NULL;
-
- return __vfwscanf(&f, format, arg);
-}
-strong_alias(__vswscanf,vswscanf)
-#else /* __STDIO_BUFFERS */
-#warning Skipping vswscanf since no buffering!
-#endif /* __STDIO_BUFFERS */
-
-#endif
-/**********************************************************************/
-/**********************************************************************/
-
-
-
-/* float layout 0123456789012345678901 repeat n for "l[" */
-#define SPEC_CHARS "npxXoudifFeEgGaACSncs["
-/* npxXoudif eEgG CS cs[ */
-
-/* NOTE: Ordering is important! In particular, CONV_LEFTBRACKET
- * must immediately precede CONV_c. */
-
-enum {
- CONV_n = 0,
- CONV_p,
- CONV_x, CONV_X, CONV_o, CONV_u, CONV_d, CONV_i,
- CONV_f, CONV_F, CONV_e, CONV_E, CONV_g, CONV_G, CONV_a, CONV_A,
- CONV_C, CONV_S, CONV_LEFTBRACKET, CONV_c, CONV_s, CONV_leftbracket,
- CONV_percent, CONV_whitespace /* not in SPEC_* and no flags */
-};
-
-#ifdef __UCLIBC_HAS_FLOATS__
-#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
-/* p x X o u d i f F e E g G a A */
-#define SPEC_BASE { 16, 16, 16, 8, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-#else
-/* p x X o u d i f F e E g G a A */
-#define SPEC_BASE { 16, 16, 16, 8, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10 }
-#endif
-#else /* __UCLIBC_HAS_FLOATS__ */
-/* p x X o u d i f F e E g G a A */
-#define SPEC_BASE { 16, 16, 16, 8, 10, 10, 0 }
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfscanf
-/* emit once */
-#warning CONSIDER: Add a '0' flag to eat 0 padding when grouping?
-#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
-#define SPEC_FLAGS "*'I"
-
-enum {
- FLAG_SURPRESS = 0x10, /* MUST BE 1ST!! See DO_FLAGS. */
- FLAG_THOUSANDS = 0x20,
- FLAG_I18N = 0x40, /* only works for d, i, u */
- FLAG_MALLOC = 0x80, /* only works for s, S, and [ (and l[)*/
-};
-
-
-#define SPEC_RANGES { CONV_n, CONV_p, CONV_i, CONV_A, \
- CONV_C, CONV_LEFTBRACKET, \
- CONV_c, CONV_leftbracket }
-
-/* Note: We treat L and ll as synonymous... for ints and floats. */
-
-#define SPEC_ALLOWED_FLAGS { \
- /* n */ (0x0f|FLAG_SURPRESS), \
- /* p */ ( 0|FLAG_SURPRESS), \
- /* oxXudi */ (0x0f|FLAG_SURPRESS|FLAG_THOUSANDS|FLAG_I18N), \
- /* fFeEgGaA */ (0x0c|FLAG_SURPRESS|FLAG_THOUSANDS|FLAG_I18N), \
- /* C */ ( 0|FLAG_SURPRESS), \
- /* S and l[ */ ( 0|FLAG_SURPRESS|FLAG_MALLOC), \
- /* c */ (0x04|FLAG_SURPRESS), \
- /* s and [ */ (0x04|FLAG_SURPRESS|FLAG_MALLOC), \
-}
-
-
-/**********************************************************************/
-/*
- * In order to ease translation to what arginfo and _print_info._flags expect,
- * we map: 0:int 1:char 2:longlong 4:long 8:short
- * and then _flags |= (((q << 7) + q) & 0x701) and argtype |= (_flags & 0x701)
- */
-
-/* TODO -- Fix the table below to take into account stdint.h. */
-/* #ifndef LLONG_MAX */
-/* #error fix QUAL_CHARS for no long long! Affects 'L', 'j', 'q', 'll'. */
-/* #else */
-/* #if LLONG_MAX != INTMAX_MAX */
-/* #error fix QUAL_CHARS intmax_t entry 'j'! */
-/* #endif */
-/* #endif */
-
-#ifdef PDS
-#error PDS already defined!
-#endif
-#ifdef SS
-#error SS already defined!
-#endif
-#ifdef IMS
-#error IMS already defined!
-#endif
-
-#if PTRDIFF_MAX == INT_MAX
-#define PDS 0
-#elif PTRDIFF_MAX == LONG_MAX
-#define PDS 4
-#elif defined(LLONG_MAX) && (PTRDIFF_MAX == LLONG_MAX)
-#define PDS 8
-#else
-#error fix QUAL_CHARS ptrdiff_t entry 't'!
-#endif
-
-#if SIZE_MAX == UINT_MAX
-#define SS 0
-#elif SIZE_MAX == ULONG_MAX
-#define SS 4
-#elif defined(LLONG_MAX) && (SIZE_MAX == ULLONG_MAX)
-#define SS 8
-#else
-#error fix QUAL_CHARS size_t entries 'z', 'Z'!
-#endif
-
-#if INTMAX_MAX == INT_MAX
-#define IMS 0
-#elif INTMAX_MAX == LONG_MAX
-#define IMS 4
-#elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX)
-#define IMS 8
-#else
-#error fix QUAL_CHARS ptrdiff_t entry 't'!
-#endif
-
-#define QUAL_CHARS { \
- /* j:(u)intmax_t z:(s)size_t t:ptrdiff_t \0:int q:long_long */ \
- 'h', 'l', 'L', 'j', 'z', 't', 'q', 0, \
- 2, 4, 8, IMS, SS, PDS, 8, 0, /* TODO -- fix!!! */\
- 1, 8 }
-
-
-/**********************************************************************/
-
-#ifdef L_vfwscanf
-#if WINT_MIN > EOF
-#error Unfortunately, we currently need wint_t to be able to store EOF. Sorry.
-#endif
-#define W_EOF WEOF
-#define Wint wint_t
-#define Wchar wchar_t
-#define Wuchar __uwchar_t
-#define ISSPACE(C) iswspace((C))
-#define HIDDEN_VFSCANF __vfwscanf
-#define VFSCANF vfwscanf
-#define GETC(SC) (SC)->sc_getc((SC))
-#else
-typedef unsigned char __uchar_t;
-#define W_EOF EOF
-#define Wint int
-#define Wchar char
-#define Wuchar __uchar_t
-#define ISSPACE(C) isspace((C))
-#define HIDDEN_VFSCANF __vfscanf
-#define VFSCANF vfscanf
-#ifdef __UCLIBC_HAS_WCHAR__
-#define GETC(SC) (SC)->sc_getc((SC))
-#else /* __UCLIBC_HAS_WCHAR__ */
-#define GETC(SC) __getc_unlocked((SC)->fp)
-#endif /* __UCLIBC_HAS_WCHAR__ */
-#endif
-
-struct scan_cookie {
- Wint cc;
- Wint ungot_char;
- FILE *fp;
- int nread;
- int width;
-
-#ifdef __UCLIBC_HAS_WCHAR__
- wchar_t app_ungot; /* Match FILE struct member type. */
- unsigned char ungot_wchar_width;
-#else /* __UCLIBC_HAS_WCHAR__ */
- unsigned char app_ungot; /* Match FILE struct member type. */
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- char ungot_flag;
-
-#ifdef __UCLIBC_HAS_WCHAR__
- char ungot_wflag; /* vfwscanf */
- char mb_fail; /* vfscanf */
- mbstate_t mbstate; /* vfscanf */
- wint_t wc;
- wint_t ungot_wchar; /* to support __scan_getc */
- int (*sc_getc)(struct scan_cookie *);
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- const char *grouping;
- const unsigned char *thousands_sep;
- int tslen;
-#ifdef __UCLIBC_HAS_WCHAR__
- wchar_t thousands_sep_wc;
-#endif /* __UCLIBC_HAS_WCHAR__ */
-#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
-
-#ifdef __UCLIBC_HAS_FLOATS__
- const unsigned char *decpt;
- int decpt_len;
-#ifdef __UCLIBC_HAS_WCHAR__
- wchar_t decpt_wc;
-#endif /* __UCLIBC_HAS_WCHAR__ */
- const unsigned char *fake_decpt;
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-};
-
-typedef struct {
-#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)
-#if NL_ARGMAX > 10
-#warning NL_ARGMAX > 10, and space is allocated on the stack for positional args.
-#endif
- void *pos_args[NL_ARGMAX];
- int num_pos_args; /* Must start at -1. */
- int cur_pos_arg;
-#endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
- void *cur_ptr;
- const unsigned char *fmt;
- int cnt, dataargtype, conv_num, max_width;
- unsigned char store, flags;
-} psfs_t; /* parse scanf format state */
-
-
-/**********************************************************************/
-/**********************************************************************/
-
-extern void __init_scan_cookie(register struct scan_cookie *sc,
- register FILE *fp) attribute_hidden;
-extern int __scan_getc(register struct scan_cookie *sc) attribute_hidden;
-extern void __scan_ungetc(register struct scan_cookie *sc) attribute_hidden;
-
-#ifdef __UCLIBC_HAS_FLOATS__
-extern int __scan_strtold(long double *ld, struct scan_cookie *sc);
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-extern int __psfs_parse_spec(psfs_t *psfs) attribute_hidden;
-extern int __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc) attribute_hidden;
-
-/**********************************************************************/
-#ifdef L___scan_cookie
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Remove dependence on decpt_str and fake_decpt in stub locale mode.
-#endif
-#ifndef __UCLIBC_HAS_LOCALE__
-static const char decpt_str[] = ".";
-#endif
-
-void attribute_hidden __init_scan_cookie(register struct scan_cookie *sc,
- register FILE *fp)
-{
- sc->fp = fp;
- sc->nread = 0;
- sc->ungot_flag = 0;
- sc->app_ungot = ((fp->__modeflags & __FLAG_UNGOT) ? fp->__ungot[1] : 0);
-#ifdef __UCLIBC_HAS_WCHAR__
- sc->ungot_wflag = 0; /* vfwscanf */
- sc->mb_fail = 0;
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- if (*(sc->grouping = __UCLIBC_CURLOCALE_DATA.grouping)) {
- sc->thousands_sep = __UCLIBC_CURLOCALE_DATA.thousands_sep;
- sc->tslen = __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
-#ifdef __UCLIBC_HAS_WCHAR__
- sc->thousands_sep_wc = __UCLIBC_CURLOCALE_DATA.thousands_sep_wc;
-#endif /* __UCLIBC_HAS_WCHAR__ */
- }
-#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
-
-#ifdef __UCLIBC_HAS_FLOATS__
-#ifdef __UCLIBC_HAS_LOCALE__
- sc->decpt = __UCLIBC_CURLOCALE_DATA.decimal_point;
- sc->decpt_len = __UCLIBC_CURLOCALE_DATA.decimal_point_len;
-#else /* __UCLIBC_HAS_LOCALE__ */
- sc->fake_decpt = sc->decpt = decpt_str;
- sc->decpt_len = 1;
-#endif /* __UCLIBC_HAS_LOCALE__ */
-#ifdef __UCLIBC_HAS_WCHAR__
-#ifdef __UCLIBC_HAS_LOCALE__
- sc->decpt_wc = __UCLIBC_CURLOCALE_DATA.decimal_point_wc;
-#else
- sc->decpt_wc = '.';
-#endif
-#endif /* __UCLIBC_HAS_WCHAR__ */
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-}
-
-int attribute_hidden __scan_getc(register struct scan_cookie *sc)
-{
- int c;
-
-#ifdef __UCLIBC_HAS_WCHAR__
- assert(!sc->mb_fail);
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- sc->cc = EOF;
-
- if (--sc->width < 0) {
- sc->ungot_flag |= 2;
- return -1;
- }
-
- if (sc->ungot_flag == 0) {
-#if !defined(__STDIO_BUFFERS) && !defined(__UCLIBC_HAS_WCHAR__)
- if (!__STDIO_STREAM_IS_FAKE_VSSCANF_NB(sc->fp)) {
- c = GETC(sc);
- } else {
- __FILE_vsscanf *fv = (__FILE_vsscanf *)(sc->fp);
- if (fv->bufpos < fv->bufread) {
- c = *fv->bufpos++;
- } else {
- c = EOF;
- sc->fp->__modeflags |= __FLAG_EOF;
- }
- }
- if (c == EOF) {
- sc->ungot_flag |= 2;
- return -1;
- }
-#else
- if ((c = GETC(sc)) == EOF) {
- sc->ungot_flag |= 2;
- return -1;
- }
-#endif
- sc->ungot_char = c;
- } else {
- assert(sc->ungot_flag == 1);
- sc->ungot_flag = 0;
- }
-
- ++sc->nread;
- return sc->cc = sc->ungot_char;
-}
-
-void attribute_hidden __scan_ungetc(register struct scan_cookie *sc)
-{
- ++sc->width;
- if (sc->ungot_flag == 2) { /* last was EOF */
- sc->ungot_flag = 0;
- sc->cc = sc->ungot_char;
- } else if (sc->ungot_flag == 0) {
- sc->ungot_flag = 1;
- --sc->nread;
- } else {
- assert(0);
- }
-}
-
-#endif
-/**********************************************************************/
-#ifdef L___psfs_parse_spec
-
-#ifdef SPEC_FLAGS
-static const unsigned char spec_flags[] = SPEC_FLAGS;
-#endif /* SPEC_FLAGS */
-static const unsigned char spec_chars[] = SPEC_CHARS;
-static const unsigned char qual_chars[] = QUAL_CHARS;
-static const unsigned char spec_ranges[] = SPEC_RANGES;
-static const unsigned short spec_allowed[] = SPEC_ALLOWED_FLAGS;
-
-int attribute_hidden __psfs_parse_spec(register psfs_t *psfs)
-{
- const unsigned char *p;
- const unsigned char *fmt0 = psfs->fmt;
- int i;
-#ifdef SPEC_FLAGS
- int j;
-#endif
-#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)
- unsigned char fail = 0;
-
- i = 0; /* Do this here to avoid a warning. */
-
- if (!__isdigit_char(*psfs->fmt)) { /* Not a positional arg. */
- fail = 1;
- goto DO_FLAGS;
- }
-
- /* parse the positional arg (or width) value */
- do {
- if (i <= ((INT_MAX - 9)/10)) {
- i = (i * 10) + (*psfs->fmt++ - '0');
- }
- } while (__isdigit_char(*psfs->fmt));
-
- if (*psfs->fmt != '$') { /* This is a max field width. */
- if (psfs->num_pos_args >= 0) { /* Already saw a pos arg! */
- goto ERROR_EINVAL;
- }
- psfs->max_width = i;
- psfs->num_pos_args = -2;
- goto DO_QUALIFIER;
- }
- ++psfs->fmt; /* Advance past '$'. */
-#endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
-
-#if defined(SPEC_FLAGS) || (defined(NL_ARGMAX) && (NL_ARGMAX > 0))
- DO_FLAGS:
-#endif /* defined(SPEC_FLAGS) || (defined(NL_ARGMAX) && (NL_ARGMAX > 0)) */
-#ifdef SPEC_FLAGS
- p = spec_flags;
- j = FLAG_SURPRESS;
- do {
- if (*p == *psfs->fmt) {
- ++psfs->fmt;
- psfs->flags |= j;
- goto DO_FLAGS;
- }
- j += j;
- } while (*++p);
-
- if (psfs->flags & FLAG_SURPRESS) { /* Suppress assignment. */
- psfs->store = 0;
- goto DO_WIDTH;
- }
-#else /* SPEC_FLAGS */
- if (*psfs->fmt == '*') { /* Suppress assignment. */
- ++psfs->fmt;
- psfs->store = 0;
- goto DO_WIDTH;
- }
-#endif /* SPEC_FLAGS */
-
-
-#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)
- if (fail) {
- /* Must be a non-positional arg */
- if (psfs->num_pos_args >= 0) { /* Already saw a pos arg! */
- goto ERROR_EINVAL;
- }
- psfs->num_pos_args = -2;
- } else {
- if ((psfs->num_pos_args == -2) || (((unsigned int)(--i)) >= NL_ARGMAX)) {
- /* Already saw a non-pos arg or (0-based) num too large. */
- goto ERROR_EINVAL;
- }
- psfs->cur_pos_arg = i;
- }
-#endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
-
- DO_WIDTH:
- for (i = 0 ; __isdigit_char(*psfs->fmt) ; ) {
- if (i <= ((INT_MAX - 9)/10)) {
- i = (i * 10) + (*psfs->fmt++ - '0');
- psfs->max_width = i;
- }
- }
-
-#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)
- DO_QUALIFIER:
-#endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
- p = qual_chars;
- do {
- if (*psfs->fmt == *p) {
- ++psfs->fmt;
- break;
- }
- } while (*++p);
- if ((p - qual_chars < 2) && (*psfs->fmt == *p)) {
- p += ((sizeof(qual_chars)-2) / 2);
- ++psfs->fmt;
- }
- psfs->dataargtype = ((int)(p[(sizeof(qual_chars)-2) / 2])) << 8;
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning CONSIDER: Should we validate that psfs->max_width > 0 in __psfs_parse_spec()? It would avoid whitespace consumption...
-#warning CONSIDER: Should INT_MAX be a valid width (%c/%C)? See __psfs_parse_spec().
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
- p = spec_chars;
- do {
- if (*psfs->fmt == *p) {
- int p_m_spec_chars = p - spec_chars;
-
-#ifdef __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__
-#error implement gnu a flag
- if ((*p == 'a')
- && ((psfs->fmt[1] == '[') || ((psfs->fmt[1]|0x20) == 's'))
- ) { /* Assumes ascii for 's' and 'S' test. */
- psfs->flags |= FLAG_MALLOC;
- ++psfs->fmt;
- ++p;
- continue; /* The related conversions follow 'a'. */
- }
-#endif /* __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__ */
-
- for (p = spec_ranges; p_m_spec_chars > *p ; ++p) {}
- if (((psfs->dataargtype >> 8) | psfs->flags)
- & ~spec_allowed[(int)(p - spec_ranges)]
- ) {
- goto ERROR_EINVAL;
- }
-
- if ((p_m_spec_chars >= CONV_c)
- && (psfs->dataargtype & PA_FLAG_LONG)) {
- p_m_spec_chars -= 3; /* lc -> C, ls -> S, l[ -> ?? */
- }
-
- psfs->conv_num = p_m_spec_chars;
- return psfs->fmt - fmt0;
- }
- if (!*++p) {
- ERROR_EINVAL:
- __set_errno(EINVAL);
- return -1;
- }
- } while(1);
-
- assert(0);
-}
-
-#endif
-/**********************************************************************/
-#if defined(L_vfscanf) || defined(L_vfwscanf)
-
-#ifdef __UCLIBC_HAS_WCHAR__
-#ifdef L_vfscanf
-static int sc_getc(register struct scan_cookie *sc)
-{
- return (__getc_unlocked)(sc->fp); /* Disable the macro. */
-}
-
-static int scan_getwc(register struct scan_cookie *sc)
-{
- size_t r;
- int width;
- wchar_t wc[1];
- char b[1];
-
- if (--sc->width < 0) {
- sc->ungot_flag |= 2;
- return -1;
- }
-
- width = sc->width; /* Preserve width. */
- sc->width = INT_MAX; /* MB_CUR_MAX can invoke a function. */
-
- assert(!sc->mb_fail);
-
- r = (size_t)(-3);
- while (__scan_getc(sc) >= 0) {
- *b = sc->cc;
-
- r = mbrtowc(wc, b, 1, &sc->mbstate);
- if (((ssize_t) r) >= 0) { /* Successful completion of a wc. */
- sc->wc = *wc;
- goto SUCCESS;
- } else if (r == ((size_t) -2)) {
- /* Potentially valid but incomplete. */
- continue;
- }
- break;
- }
-
- if (r == ((size_t)(-3))) { /* EOF or ERROR on first read */
- sc->wc = WEOF;
- r = (size_t)(-1);
- } else {
- /* If we reach here, either r == ((size_t)-1) and
- * mbrtowc set errno to EILSEQ, or r == ((size_t)-2)
- * and stream is in an error state or at EOF with a
- * partially complete wchar. */
- __set_errno(EILSEQ); /* In case of incomplete conversion. */
- sc->mb_fail = 1;
- }
-
- SUCCESS:
- sc->width = width; /* Restore width. */
-
- return (int)((ssize_t) r);
-}
-
-#endif /* L_vfscanf */
-
-#ifdef L_vfwscanf
-
-/* This gets called by __scan_getc. __scan_getc is called by vfwscanf
- * when the next wide char is expected to be valid ascii (digits).
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-static int sc_getc(register struct scan_cookie *sc)
-{
- wint_t wc;
-
- if (__STDIO_STREAM_IS_FAKE_VSWSCANF(sc->fp)) {
- if (sc->fp->__bufpos < sc->fp->__bufend) {
- wc = *((wchar_t *)(sc->fp->__bufpos));
- sc->fp->__bufpos += sizeof(wchar_t);
- } else {
- sc->fp->__modeflags |= __FLAG_EOF;
- return EOF;
- }
- } else if ((wc = __fgetwc_unlocked(sc->fp)) == WEOF) {
- return EOF;
- }
-
- sc->ungot_wflag = 1;
- sc->ungot_wchar = wc;
- sc->ungot_wchar_width = sc->fp->__ungot_width[0];
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- if (wc == sc->thousands_sep_wc) {
- wc = ',';
- } else
-#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
-#ifdef __UCLIBC_HAS_FLOATS__
- if (wc == sc->decpt_wc) {
- wc = '.';
- } else
-#endif /* __UCLIBC_HAS_FLOATS__ */
- if (!__isascii(wc)) {
- wc = '?';
- }
- sc->wc = sc->ungot_char = wc;
-
- return (int) wc;
-}
-
-static int scan_getwc(register struct scan_cookie *sc)
-{
- wint_t wc;
-
- sc->wc = WEOF;
-
- if (--sc->width < 0) {
- sc->ungot_flag |= 2;
- return -1;
- }
-
- if (sc->ungot_flag == 0) {
- if (__STDIO_STREAM_IS_FAKE_VSWSCANF(sc->fp)) {
- if (sc->fp->__bufpos < sc->fp->__bufend) {
- wc = *((wchar_t *)(sc->fp->__bufpos));
- sc->fp->__bufpos += sizeof(wchar_t);
- } else {
- sc->ungot_flag |= 2;
- return -1;
- }
- } else if ((wc = __fgetwc_unlocked(sc->fp)) == WEOF) {
- sc->ungot_flag |= 2;
- return -1;
- }
- sc->ungot_wflag = 1;
- sc->ungot_char = wc;
- sc->ungot_wchar_width = sc->fp->__ungot_width[0];
- } else {
- assert(sc->ungot_flag == 1);
- sc->ungot_flag = 0;
- }
-
- ++sc->nread;
- sc->wc = sc->ungot_char;
-
- return 0;
-}
-
-
-#endif /* L_vfwscanf */
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-static __inline void kill_scan_cookie(register struct scan_cookie *sc)
-{
-#ifdef L_vfscanf
-
- if (sc->ungot_flag & 1) {
-#if !defined(__STDIO_BUFFERS) && !defined(__UCLIBC_HAS_WCHAR__)
- if (!__STDIO_STREAM_IS_FAKE_VSSCANF_NB(sc->fp)) {
- ungetc(sc->ungot_char, sc->fp);
- }
-#else
- ungetc(sc->ungot_char, sc->fp);
-#endif
- /* Deal with distiction between user and scanf ungots. */
- if (sc->nread == 0) { /* Only one char was read... app ungot? */
- sc->fp->__ungot[1] = sc->app_ungot; /* restore ungot state. */
- } else {
- sc->fp->__ungot[1] = 0;
- }
- }
-
-#else
-
- if ((sc->ungot_flag & 1) && (sc->ungot_wflag & 1)
- && !__STDIO_STREAM_IS_FAKE_VSWSCANF(sc->fp)
- && (sc->fp->__state.__mask == 0)
- ) {
- ungetwc(sc->ungot_char, sc->fp);
- /* Deal with distiction between user and scanf ungots. */
- if (sc->nread == 0) { /* Only one char was read... app ungot? */
- sc->fp->__ungot[1] = sc->app_ungot; /* restore ungot state. */
- } else {
- sc->fp->__ungot[1] = 0;
- }
- sc->fp->__ungot_width[1] = sc->ungot_wchar_width;
- }
-
-#endif
-}
-
-#ifdef L_vfwscanf
-#ifdef __UCLIBC_HAS_FLOATS__
-static const char fake_decpt_str[] = ".";
-#endif
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
-static const char fake_thousands_sep_str[] = ",";
-#endif
-#endif /* L_vfwscanf */
-
-
-int attribute_hidden HIDDEN_VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)
-{
- const Wuchar *fmt;
- unsigned char *b;
-
-
-#ifdef L_vfwscanf
- wchar_t wbuf[1];
- wchar_t *wb;
-#endif /* L_vfwscanf */
-
-#ifdef __UCLIBC_HAS_WCHAR__
- mbstate_t mbstate;
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- struct scan_cookie sc;
- psfs_t psfs;
-
- int i;
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Fix MAX_DIGITS. We do not do binary, so...!
-#endif
-#define MAX_DIGITS 65 /* Allow one leading 0. */
- unsigned char buf[MAX_DIGITS+2];
-#ifdef L_vfscanf
- unsigned char scanset[UCHAR_MAX + 1];
- unsigned char invert; /* Careful! Meaning changes. */
-#endif /* L_vfscanf */
- unsigned char fail;
- unsigned char zero_conversions = 1;
- __STDIO_AUTO_THREADLOCK_VAR;
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Make checking of the format string in C locale an option.
-#endif
- /* To support old programs, don't check mb validity if in C locale. */
-#if defined(__UCLIBC_HAS_LOCALE__) && !defined(L_vfwscanf)
- /* ANSI/ISO C99 requires format string to be a valid multibyte string
- * beginning and ending in its initial shift state. */
- if (((__UCLIBC_CURLOCALE_DATA).encoding) != __ctype_encoding_7_bit) {
- const char *p = format;
- mbstate.__mask = 0; /* Initialize the mbstate. */
- if (mbsrtowcs(NULL, &p, SIZE_MAX, &mbstate) == ((size_t)(-1))) {
- __set_errno(EINVAL); /* Format string is invalid. */
- return 0;
- }
- }
-#endif /* defined(__UCLIBC_HAS_LOCALE__) && !defined(L_vfwscanf) */
-
-#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)
- psfs.num_pos_args = -1; /* Must start at -1. */
- /* Initialize positional arg ptrs to NULL. */
- __memset(psfs.pos_args, 0, sizeof(psfs.pos_args));
-#endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
-
- __STDIO_AUTO_THREADLOCK(fp);
-
- __STDIO_STREAM_VALIDATE(fp);
-
- __init_scan_cookie(&sc,fp);
-#ifdef __UCLIBC_HAS_WCHAR__
- sc.sc_getc = sc_getc;
- sc.ungot_wchar_width = sc.fp->__ungot_width[1];
-
-#ifdef L_vfwscanf
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- if (*sc.grouping) {
- sc.thousands_sep = fake_thousands_sep_str;
- sc.tslen = 1;
- }
-#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
-
-#ifdef __UCLIBC_HAS_FLOATS__
- sc.fake_decpt = fake_decpt_str;
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-#else /* L_vfwscanf */
-
-#ifdef __UCLIBC_HAS_FLOATS__
- sc.fake_decpt = sc.decpt;
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
-#endif /* L_vfwscanf */
-
-#endif /* __UCLIBC_HAS_WCHAR__ */
- psfs.cnt = 0;
-
- /* Note: If we ever wanted to support non-nice codesets, we
- * would really need to do a mb->wc conversion here in the
- * vfscanf case. Related changes would have to be made in
- * the code that follows... basicly wherever fmt appears. */
- for (fmt = (const Wuchar *) format ; *fmt ; /* ++fmt */) {
-
- psfs.store = 1;
- psfs.flags = 0;
-#ifndef NDEBUG
- psfs.cur_ptr = NULL; /* Debugging aid. */
-#endif /* NDEBUG */
-
-
- sc.ungot_flag &= 1; /* Clear (possible fake) EOF. */
- sc.width = psfs.max_width = INT_MAX;
-
- /* Note: According to the standards, vfscanf does use isspace
- * here. So, if we did a mb->wc conversion, we would have to do
- * something like
- * ((((__uwchar_t)wc) < UCHAR_MAX) && isspace(wc))
- * because wc might not be in the allowed domain. */
- if (ISSPACE(*fmt)) {
- do {
- ++fmt;
- } while (ISSPACE(*fmt));
- --fmt;
- psfs.conv_num = CONV_whitespace;
- goto DO_WHITESPACE;
- }
-
- if (*fmt == '%') { /* Conversion specification. */
- if (*++fmt == '%') { /* Remember, '%' eats whitespace too. */
- /* Note: The standard says no conversion occurs.
- * So do not reset zero_conversions flag. */
- psfs.conv_num = CONV_percent;
- goto DO_CONVERSION;
- }
-
-
-#ifdef L_vfscanf
- psfs.fmt = fmt;
-#else /* L_vfscanf */
- {
- const __uwchar_t *wf = fmt;
- psfs.fmt = b = buf;
-
- while (*wf && __isascii(*wf) && (b < buf + sizeof(buf) - 1)) {
- *b++ = *wf++;
- }
-#ifdef __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__
-#error this is wrong... we need to ched in __psfs_parse_spec instead since this checks last char in buffer and conversion my have stopped before it.
- if ((*b == 'a') && ((*wf == '[') || ((*wf|0x20) == 's'))) {
- goto DONE; /* Spec was excessively long. */
- }
-#endif /* __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__ */
- *b = 0;
- if (b == buf) { /* Bad conversion specifier! */
- goto DONE;
- }
- }
-#endif /* L_vfscanf */
- if ((i = __psfs_parse_spec(&psfs)) < 0) { /* Bad conversion specifier! */
- goto DONE;
- }
- fmt += i;
-
- if (psfs.store) {
-#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)
- if (psfs.num_pos_args == -2) {
- psfs.cur_ptr = va_arg(arg, void *);
- } else {
- while (psfs.cur_pos_arg > psfs.num_pos_args) {
- psfs.pos_args[++psfs.num_pos_args] = va_arg(arg, void *);
- }
- psfs.cur_ptr = psfs.pos_args[psfs.cur_pos_arg];
- }
-#else /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
- psfs.cur_ptr = va_arg(arg, void *);
-#endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */
- }
-
- DO_CONVERSION:
- /* First, consume white-space if not n, c, [, C, or l[. */
- if ((((1L << CONV_n)|(1L << CONV_C)|(1L << CONV_c)
- |(1L << CONV_LEFTBRACKET)|(1L << CONV_leftbracket))
- & (1L << psfs.conv_num)) == 0
- ) {
- DO_WHITESPACE:
- while ((__scan_getc(&sc) >= 0)
-#ifdef L_vfscanf
- && isspace(sc.cc)
-#else /* L_vfscanf */
- && iswspace(sc.wc)
-#endif /* L_vfscanf */
- ) {}
- __scan_ungetc(&sc);
- if (psfs.conv_num == CONV_whitespace) {
- goto NEXT_FMT;
- }
- }
-
- sc.width = psfs.max_width; /* Now limit the max width. */
-
- if (sc.width == 0) { /* 0 width is forbidden. */
- goto DONE;
- }
-
-
- if (psfs.conv_num == CONV_percent) {
- goto MATCH_CHAR;
- }
-
- if (psfs.conv_num == CONV_n) {
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning CONSIDER: Should %n count as a conversion as far as EOF return value?
-#endif
-/* zero_conversions = 0; */
- if (psfs.store) {
- _store_inttype(psfs.cur_ptr, psfs.dataargtype,
- (uintmax_t) sc.nread);
- }
- goto NEXT_FMT;
- }
-
- if (psfs.conv_num <= CONV_A) { /* pointer, integer, or float spec */
- int r = __psfs_do_numeric(&psfs, &sc);
-#ifndef L_vfscanf
- if (sc.ungot_wflag == 1) { /* fix up '?', '.', and ',' hacks */
- sc.cc = sc.ungot_char = sc.ungot_wchar;
- }
-#endif
- if (r != -1) { /* Either success or a matching failure. */
- zero_conversions = 0;
- }
- if (r < 0) {
- goto DONE;
- }
- goto NEXT_FMT;
- }
-
- /* Do string conversions here since they are not common code. */
-
-
-#ifdef L_vfscanf
-
- if
-#ifdef __UCLIBC_HAS_WCHAR__
- (psfs.conv_num >= CONV_LEFTBRACKET)
-#else /* __UCLIBC_HAS_WCHAR__ */
- (psfs.conv_num >= CONV_c)
-#endif /* __UCLIBC_HAS_WCHAR__ */
- {
- b = (psfs.store ? ((unsigned char *) psfs.cur_ptr) : buf);
- fail = 1;
-
-
- if (psfs.conv_num == CONV_c) {
- if (sc.width == INT_MAX) {
- sc.width = 1;
- }
-
- while (__scan_getc(&sc) >= 0) {
- zero_conversions = 0;
- *b = sc.cc;
- b += psfs.store;
- }
- __scan_ungetc(&sc);
- if (sc.width > 0) { /* Failed to read all required. */
- goto DONE;
- }
- psfs.cnt += psfs.store;
- goto NEXT_FMT;
- }
-
- if (psfs.conv_num == CONV_s) {
- /* Yes, believe it or not, a %s conversion can store nuls. */
- while ((__scan_getc(&sc) >= 0) && !isspace(sc.cc)) {
- zero_conversions = 0;
- *b = sc.cc;
- b += psfs.store;
- fail = 0;
- }
- } else {
-#ifdef __UCLIBC_HAS_WCHAR__
- assert((psfs.conv_num == CONV_LEFTBRACKET) || \
- (psfs.conv_num == CONV_leftbracket));
-#else /* __UCLIBC_HAS_WCHAR__ */
- assert((psfs.conv_num == CONV_leftbracket));
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- invert = 0;
-
- if (*++fmt == '^') {
- ++fmt;
- invert = 1;
- }
- __memset(scanset, invert, sizeof(scanset));
- invert = 1-invert;
-
- if (*fmt == ']') {
- scanset[(int)(']')] = invert;
- ++fmt;
- }
-
- while (*fmt != ']') {
- if (!*fmt) { /* No closing ']'. */
- goto DONE;
- }
- if ((*fmt == '-') && (fmt[1] != ']')
- && (fmt[-1] < fmt[1]) /* sorted? */
- ) { /* range */
- ++fmt;
- i = fmt[-2];
- /* Note: scanset[i] should already have been done
- * in the previous iteration. */
- do {
- scanset[++i] = invert;
- } while (i < *fmt);
- /* Safe to fall through, and a bit smaller. */
- }
- /* literal char */
- scanset[(int) *fmt] = invert;
- ++fmt;
- }
-
-#ifdef __UCLIBC_HAS_WCHAR__
- if (psfs.conv_num == CONV_LEFTBRACKET) {
- goto DO_LEFTBRACKET;
- }
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-
- while (__scan_getc(&sc) >= 0) {
- zero_conversions = 0;
- if (!scanset[sc.cc]) {
- break;
- }
- *b = sc.cc;
- b += psfs.store;
- fail = 0;
- }
- }
- /* Common tail for processing of %s and %[. */
-
- __scan_ungetc(&sc);
- if (fail) { /* nothing stored! */
- goto DONE;
- }
- *b = 0; /* Nul-terminate string. */
- psfs.cnt += psfs.store;
- goto NEXT_FMT;
- }
-
-#ifdef __UCLIBC_HAS_WCHAR__
- DO_LEFTBRACKET: /* Need to do common wide init. */
- if (psfs.conv_num >= CONV_C) {
- wchar_t wbuf[1];
- wchar_t *wb;
-
- sc.mbstate.__mask = 0;
-
- wb = (psfs.store ? ((wchar_t *) psfs.cur_ptr) : wbuf);
- fail = 1;
-
- if (psfs.conv_num == CONV_C) {
- if (sc.width == INT_MAX) {
- sc.width = 1;
- }
-
- while (scan_getwc(&sc) >= 0) {
- zero_conversions = 0;
- assert(sc.width >= 0);
- *wb = sc.wc;
- wb += psfs.store;
- }
-
- __scan_ungetc(&sc);
- if (sc.width > 0) { /* Failed to read all required. */
- goto DONE;
- }
- psfs.cnt += psfs.store;
- goto NEXT_FMT;
- }
-
-
- if (psfs.conv_num == CONV_S) {
- /* Yes, believe it or not, a %s conversion can store nuls. */
- while (scan_getwc(&sc) >= 0) {
- zero_conversions = 0;
- if ((((__uwchar_t)(sc.wc)) <= UCHAR_MAX) && isspace(sc.wc)) {
- break;
- }
- *wb = sc.wc;
- wb += psfs.store;
- fail = 0;
- }
- } else {
- assert(psfs.conv_num == CONV_LEFTBRACKET);
-
- while (scan_getwc(&sc) >= 0) {
- zero_conversions = 0;
- if (((__uwchar_t) sc.wc) <= UCHAR_MAX) {
- if (!scanset[sc.wc]) {
- break;
- }
- } else if (invert) {
- break;
- }
- *wb = sc.wc;
- wb += psfs.store;
- fail = 0;
- }
- }
- /* Common tail for processing of %ls and %l[. */
-
- __scan_ungetc(&sc);
- if (fail || sc.mb_fail) { /* Nothing stored or mb error. */
- goto DONE;
- }
- *wb = 0; /* Nul-terminate string. */
- psfs.cnt += psfs.store;
- goto NEXT_FMT;
-
- }
-
-#endif /* __UCLIBC_HAS_WCHAR__ */
-#else /* L_vfscanf */
-
- if (psfs.conv_num >= CONV_C) {
- b = buf;
- wb = wbuf;
- if (psfs.conv_num >= CONV_c) {
- mbstate.__mask = 0; /* Initialize the mbstate. */
- if (psfs.store) {
- b = (unsigned char *) psfs.cur_ptr;
- }
- } else {
- if (psfs.store) {
- wb = (wchar_t *) psfs.cur_ptr;
- }
- }
- fail = 1;
-
-
- if ((psfs.conv_num == CONV_C) || (psfs.conv_num == CONV_c)) {
- if (sc.width == INT_MAX) {
- sc.width = 1;
- }
-
- while (scan_getwc(&sc) >= 0) {
- zero_conversions = 0;
- if (psfs.conv_num == CONV_C) {
- *wb = sc.wc;
- wb += psfs.store;
- } else {
- i = wcrtomb(b, sc.wc, &mbstate);
- if (i < 0) { /* Conversion failure. */
- goto DONE_DO_UNGET;
- }
- if (psfs.store) {
- b += i;
- }
- }
- }
- __scan_ungetc(&sc);
- if (sc.width > 0) { /* Failed to read all required. */
- goto DONE;
- }
- psfs.cnt += psfs.store;
- goto NEXT_FMT;
- }
-
- if ((psfs.conv_num == CONV_S) || (psfs.conv_num == CONV_s)) {
- /* Yes, believe it or not, a %s conversion can store nuls. */
- while (scan_getwc(&sc) >= 0) {
- zero_conversions = 0;
- if (iswspace(sc.wc)) {
- break;
- }
- if (psfs.conv_num == CONV_S) {
- *wb = sc.wc;
- wb += psfs.store;
- } else {
- i = wcrtomb(b, sc.wc, &mbstate);
- if (i < 0) { /* Conversion failure. */
- goto DONE_DO_UNGET;
- }
- if (psfs.store) {
- b += i;
- }
- }
- fail = 0;
- }
- } else {
- const wchar_t *sss;
- const wchar_t *ssp;
- unsigned char invert = 0;
-
- assert((psfs.conv_num == CONV_LEFTBRACKET)
- || (psfs.conv_num == CONV_leftbracket));
-
- if (*++fmt == '^') {
- ++fmt;
- invert = 1;
- }
- sss = (const wchar_t *) fmt;
- if (*fmt == ']') {
- ++fmt;
- }
- while (*fmt != ']') {
- if (!*fmt) { /* No closing ']'. */
- goto DONE;
- }
- if ((*fmt == '-') && (fmt[1] != ']')
- && (fmt[-1] < fmt[1]) /* sorted? */
- ) { /* range */
- ++fmt;
- }
- ++fmt;
- }
- /* Ok... a valid scanset spec. */
-
- while (scan_getwc(&sc) >= 0) {
- zero_conversions = 0;
- ssp = sss;
- do { /* We know sss < fmt. */
- if (*ssp == '-') { /* possible range... */
- /* Note: We accept a-c-e (ordered) as
- * equivalent to a-e. */
- if (ssp > sss) {
- if ((++ssp < (const wchar_t *) fmt)
- && (ssp[-2] < *ssp) /* sorted? */
- ) { /* yes */
- if ((sc.wc >= ssp[-2])
- && (sc.wc <= *ssp)) {
- break;
- }
- continue; /* not in range */
- }
- --ssp; /* oops... '-' at end, so back up */
- }
- /* false alarm... a literal '-' */
- }
- if (sc.wc == *ssp) { /* Matched literal char. */
- break;
- }
- } while (++ssp < (const wchar_t *) fmt);
-
- if ((ssp == (const wchar_t *) fmt) ^ invert) {
- /* no match and not inverting
- * or match and inverting */
- break;
- }
- if (psfs.conv_num == CONV_LEFTBRACKET) {
- *wb = sc.wc;
- wb += psfs.store;
- } else {
- i = wcrtomb(b, sc.wc, &mbstate);
- if (i < 0) { /* Conversion failure. */
- goto DONE_DO_UNGET;
- }
- if (psfs.store) {
- b += i;
- }
- }
- fail = 0;
- }
- }
- /* Common tail for processing of %s and %[. */
-
- __scan_ungetc(&sc);
- if (fail) { /* nothing stored! */
- goto DONE;
- }
- *wb = 0; /* Nul-terminate string. */
- *b = 0;
- psfs.cnt += psfs.store;
- goto NEXT_FMT;
- }
-
-#endif /* L_vfscanf */
-
- assert(0);
- goto DONE;
- } /* conversion specification */
-
- MATCH_CHAR:
- if (__scan_getc(&sc) != *fmt) {
-#ifdef L_vfwscanf
- DONE_DO_UNGET:
-#endif /* L_vfwscanf */
- __scan_ungetc(&sc);
- goto DONE;
- }
-
- NEXT_FMT:
- ++fmt;
- if (__FERROR_UNLOCKED(fp)) {
- break;
- }
- }
-
- DONE:
- if (__FERROR_UNLOCKED(fp) || (*fmt && zero_conversions && __FEOF_UNLOCKED(fp))) {
- psfs.cnt = EOF; /* Yes, vfwscanf also returns EOF. */
- }
-
- kill_scan_cookie(&sc);
-
- __STDIO_STREAM_VALIDATE(fp);
-
- __STDIO_AUTO_THREADUNLOCK(fp);
-
- return psfs.cnt;
-}
-strong_alias(HIDDEN_VFSCANF,VFSCANF)
-#endif
-/**********************************************************************/
-#ifdef L___psfs_do_numeric
-
-static const unsigned char spec_base[] = SPEC_BASE;
-static const unsigned char nil_string[] = "(nil)";
-
-int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
-{
- unsigned char *b;
- const unsigned char *p;
-
-#ifdef __UCLIBC_HAS_FLOATS__
- int exp_adjust = 0;
-#endif
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Fix MAX_DIGITS. We do not do binary, so...!
-#warning TODO: Fix buf!
-#endif
-#define MAX_DIGITS 65 /* Allow one leading 0. */
- unsigned char buf[MAX_DIGITS+2+ 100];
- unsigned char usflag, base;
- unsigned char nonzero = 0;
- unsigned char seendigit = 0;
-
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning CONSIDER: What should be returned for an invalid conversion specifier?
-#endif
-#ifndef __UCLIBC_HAS_FLOATS__
- if (psfs->conv_num > CONV_i) { /* floating point */
- goto DONE;
- }
-#endif
-
- base = spec_base[psfs->conv_num - CONV_p];
- usflag = (psfs->conv_num <= CONV_u); /* (1)0 if (un)signed */
- b = buf;
-
-
- if (psfs->conv_num == CONV_p) { /* Pointer */
- p = nil_string;
- do {
- if ((__scan_getc(sc) < 0) || (*p != sc->cc)) {
- __scan_ungetc(sc);
- if (p > nil_string) {
- /* We matched at least the '(' so even if we
- * are at eof, we can not match a pointer. */
- return -2; /* Matching failure */
- }
- break;
- }
- if (!*++p) { /* Matched (nil), so no unget necessary. */
- if (psfs->store) {
- ++psfs->cnt;
- _store_inttype(psfs->cur_ptr, psfs->dataargtype,
- (uintmax_t) NULL);
- }
- return 0;
- }
- } while (1);
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning CONSIDER: Should we require a 0x prefix and disallow +/- for pointer %p?
-#endif /* __UCLIBC_MJN3_ONLY__ */
- }
-
- __scan_getc(sc);
- if (sc->cc < 0) {
- return -1; /* Input failure (nothing read yet). */
- }
-
- if ((sc->cc == '+') || (sc->cc == '-')) { /* Handle leading sign.*/
- *b++ = sc->cc;
- __scan_getc(sc);
- }
-
- if ((base & 0xef) == 0) { /* 0xef is ~16, so 16 or 0. */
- if (sc->cc == '0') { /* Possibly set base and handle prefix. */
- __scan_getc(sc);
- if ((sc->cc|0x20) == 'x') { /* Assumes ascii.. x or X. */
- if (__scan_getc(sc) < 0) {
- /* Either EOF or error (including wc outside char range).
- * If EOF or error, this is a matching failure (we read 0x).
- * If wc outside char range, this is also a matching failure.
- * Hence, we do an unget (although not really necessary here
- * and fail. */
- goto DONE_DO_UNGET; /* matching failure */
- }
- base = 16; /* Base 16 for sure now. */
-#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
- /* The prefix is required for hexadecimal floats. */
- *b++ = '0';
- *b++ = 'x';
-#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
- } else { /* oops... back up */
- __scan_ungetc(sc);
- sc->cc = '0'; /* NASTY HACK! */
-
- base = (base >> 1) + 8; /* 0->8, 16->16. no 'if' */
-#ifdef __UCLIBC_HAS_FLOATS__
- if (psfs->conv_num > CONV_i) { /* floating point */
- base = 10;
- }
-#endif
- }
- } else if (!base) {
- base = 10;
- }
- }
-
- /***************** digit grouping **********************/
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
-
- if ((psfs->flags & FLAG_THOUSANDS) && (base == 10)
- && *(p = sc->grouping)
- ) {
-
- int nblk1, nblk2, nbmax, lastblock, pass, i;
-
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning CONSIDER: Should we initalize the grouping blocks in __init_scan_cookie()?
-#endif /* __UCLIBC_MJN3_ONLY__ */
- nbmax = nblk2 = nblk1 = *p;
- if (*++p) {
- nblk2 = *p;
- if (nbmax < nblk2) {
- nbmax = nblk2;
- }
- assert(!p[1]);
- }
-
- /* Note: for printf, if 0 and \' flags appear then
- * grouping is done before 0-padding. Should we
- * strip leading 0's first? Or add a 0 flag? */
-
- /* For vfwscanf, sc_getc translates, so the value of sc->cc is
- * either EOF or a char. */
-
- if (!__isdigit_char_or_EOF(sc->cc)) { /* No starting digit! */
-#ifdef __UCLIBC_HAS_FLOATS__
- if (psfs->conv_num > CONV_i) { /* floating point */
- goto NO_STARTING_DIGIT;
- }
-#endif
- goto DONE_DO_UNGET;
- }
-
- if (sc->cc == '0') {
- seendigit = 1;
- *b++ = '0'; /* Store the first 0. */
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning CONSIDER: Should leading 0s be skipped before digit grouping? (printf 0 pad)
-#endif /* __UCLIBC_MJN3_ONLY__ */
-#if 0
- do { /* But ignore all subsequent 0s. */
- __scan_getc(sc);
- } while (sc->cc == '0');
-#endif
- }
- pass = 0;
- lastblock = 0;
- do {
- i = 0;
- while (__isdigit_char_or_EOF(sc->cc)) {
- seendigit = 1;
- if (i == nbmax) { /* too many digits for a block */
-#ifdef __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__
- if (!pass) { /* treat as nongrouped */
- if (nonzero) {
- goto DO_NO_GROUP;
- }
- goto DO_TRIM_LEADING_ZEROS;
- }
-#endif
- if (nbmax > nblk1) {
- goto DONE_DO_UNGET; /* matching failure */
- }
- goto DONE_GROUPING_DO_UNGET; /* nbmax == nblk1 */
- }
- ++i;
-
- if (nonzero || (sc->cc != '0')) {
- if (b < buf + MAX_DIGITS) {
- *b++ = sc->cc;
- nonzero = 1;
-#ifdef __UCLIBC_HAS_FLOATS__
- } else {
- ++exp_adjust;
-#endif
- }
- }
-
- __scan_getc(sc);
- }
-
- if (i) { /* we saw digits digits */
- if ((i == nblk2) || ((i < nblk2) && !pass)) {
- /* (possible) outer grp */
- p = sc->thousands_sep;
- if (*p == sc->cc) { /* first byte matches... */
- /* so check if grouping mb char */
- /* Since 1st matched, either match or fail now
- * unless EOF (yuk) */
- __scan_getc(sc);
- MBG_LOOP:
- if (!*++p) { /* is a grouping mb char */
- lastblock = i;
- ++pass;
- continue;
- }
- if (*p == sc->cc) {
- __scan_getc(sc);
- goto MBG_LOOP;
- }
- /* bad grouping mb char! */
- __scan_ungetc(sc);
- if ((sc->cc >= 0) || (p > sc->thousands_sep + 1)) {
-#ifdef __UCLIBC_HAS_FLOATS__
- /* We failed to match a thousep mb char, and
- * we've read too much to recover. But if
- * this is a floating point conversion and
- * the initial portion of the decpt mb char
- * matches, then we may still be able to
- * recover. */
- int k = p - sc->thousands_sep - 1;
-
- if ((psfs->conv_num > CONV_i) /* float conversion */
- && (!pass || (i == nblk1)) /* possible last */
- && !__memcmp(sc->thousands_sep, sc->fake_decpt, k)
- /* and prefix matched, so could be decpt */
- ) {
- __scan_getc(sc);
- p = sc->fake_decpt + k;
- do {
- if (!*++p) {
- __strcpy(b, sc->decpt);
- b += sc->decpt_len;
- goto GOT_DECPT;
- }
- if (*p != sc->cc) {
- __scan_ungetc(sc);
- break; /* failed */
- }
- __scan_getc(sc);
- } while (1);
- }
-#endif /* __UCLIBC_HAS_FLOATS__ */
- goto DONE;
- }
- /* was EOF and 1st, so recoverable. */
- }
- }
- if ((i == nblk1) || ((i < nblk1) && !pass)) {
- /* got an inner group */
- goto DONE_GROUPING_DO_UNGET;
- }
- goto DONE_DO_UNGET; /* Matching failure. */
- } /* i != 0 */
-
- assert(pass);
-
- goto DONE_DO_UNGET;
- } while (1);
-
- assert(0); /* Should never get here. */
- }
-
-#endif /***************** digit grouping **********************/
-
- /* Not grouping so first trim all but one leading 0. */
-#ifdef __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__
- DO_TRIM_LEADING_ZEROS:
-#endif /* __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__ */
- if (sc->cc == '0') {
- seendigit = 1;
- *b++ = '0'; /* Store the first 0. */
- do { /* But ignore all subsequent 0s. */
- __scan_getc(sc);
- } while (sc->cc == '0');
- }
-
-#ifdef __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__
- DO_NO_GROUP:
-#endif /* __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__ */
- /* At this point, we're ready to start reading digits. */
-
-#define valid_digit(cc,base) (isxdigit(cc) && ((base == 16) || (cc - '0' < base)))
-
- while (valid_digit(sc->cc,base)) { /* Now for significant digits.*/
- if (b - buf < MAX_DIGITS) {
- nonzero = seendigit = 1; /* Set nonzero too 0s trimmed above. */
- *b++ = sc->cc;
-#ifdef __UCLIBC_HAS_FLOATS__
- } else {
- ++exp_adjust;
-#endif
- }
- __scan_getc(sc);
- }
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- DONE_GROUPING_DO_UNGET:
-#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
- if (psfs->conv_num <= CONV_i) { /* integer conversion */
- __scan_ungetc(sc);
- *b = 0; /* null-terminate */
- if (!seendigit) {
- goto DONE; /* No digits! */
- }
- if (psfs->store) {
- if (*buf == '-') {
- usflag = 0;
- }
- ++psfs->cnt;
- _store_inttype(psfs->cur_ptr, psfs->dataargtype,
- (uintmax_t) STRTOUIM(buf, NULL, base, 1-usflag));
- }
- return 0;
- }
-
-#ifdef __UCLIBC_HAS_FLOATS__
-
- /* At this point, we have everything left of the decimal point or exponent. */
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- NO_STARTING_DIGIT:
-#endif
- p = sc->fake_decpt;
- do {
- if (!*p) {
- __strcpy(b, sc->decpt);
- b += sc->decpt_len;
- break;
- }
- if (*p != sc->cc) {
- if (p > sc->fake_decpt) {
- goto DONE_DO_UNGET; /* matching failure (read some of decpt) */
- }
- goto DO_DIGIT_CHECK;
- }
- ++p;
- __scan_getc(sc);
- } while (1);
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- GOT_DECPT:
-#endif
- if (!nonzero) {
- if (sc->cc == '0') {
- assert(exp_adjust == 0);
- *b++ = '0';
- ++exp_adjust;
- seendigit = 1;
- do {
- --exp_adjust;
- __scan_getc(sc);
- } while (sc->cc == '0');
- }
- }
-
- while (valid_digit(sc->cc,base)) { /* Process fractional digits.*/
- if (b - buf < MAX_DIGITS) {
- seendigit = 1;
- *b++ = sc->cc;
- }
- __scan_getc(sc);
- }
-
- DO_DIGIT_CHECK:
- /* Hmm... no decimal point. */
- if (!seendigit) {
- static const unsigned char nan_inf_str[] = "an\0nfinity";
-
- if (base == 16) { /* We had a prefix, but no digits! */
- goto DONE_DO_UNGET; /* matching failure */
- }
-
- /* Avoid tolower problems for INFINITY in the tr_TR locale. (yuk)*/
-#undef TOLOWER
-#define TOLOWER(C) ((C)|0x20)
-
- switch (TOLOWER(sc->cc)) {
- case 'i':
- p = nan_inf_str + 3;
- break;
- case 'n':
- p = nan_inf_str;
- break;
- default:
- /* No digits and not inf or nan. */
- goto DONE_DO_UNGET;
- }
-
- *b++ = sc->cc;
-
- do {
- __scan_getc(sc);
- if (TOLOWER(sc->cc) == *p) {
- *b++ = sc->cc;
- ++p;
- continue;
- }
- if (!*p || (p == nan_inf_str + 5)) { /* match nan/infinity or inf */
- goto GOT_FLOAT;
- }
- /* Unrecoverable. Even if on 1st char, we had no digits. */
- goto DONE_DO_UNGET;
- } while (1);
- }
-
- /* If we get here, we had some digits. */
-
- if (
-#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
- ((base == 16) && (((sc->cc)|0x20) == 'p')) ||
-#endif
- (((sc->cc)|0x20) == 'e')
- ) { /* Process an exponent. */
- *b++ = sc->cc;
-
- __scan_getc(sc);
- if (sc->cc < 0) {
- goto DONE_DO_UNGET; /* matching failure.. no exponent digits */
- }
-
- if ((sc->cc == '+') || (sc->cc == '-')) { /* Signed exponent? */
- *b++ = sc->cc;
- __scan_getc(sc);
- }
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Fix MAX_EXP_DIGITS!
-#endif
-#define MAX_EXP_DIGITS 20
- assert(seendigit);
- seendigit = 0;
- nonzero = 0;
-
- if (sc->cc == '0') {
- seendigit = 1;
- *b++ = '0';
- do {
- __scan_getc(sc);
- } while (sc->cc == '0');
- }
-
- while (__isdigit_char_or_EOF(sc->cc)) { /* Exponent digits (base 10).*/
- if (seendigit < MAX_EXP_DIGITS) {
- ++seendigit;
- *b++ = sc->cc;
- }
- __scan_getc(sc);
- }
-
- if (!seendigit) { /* No digits. Unrecoverable. */
- goto DONE_DO_UNGET;
- }
- }
-
-
- GOT_FLOAT:
- *b = 0;
- {
- __fpmax_t x;
- char *e;
- x = __strtofpmax(buf, &e, exp_adjust);
- assert(!*e);
- if (psfs->store) {
- if (psfs->dataargtype & PA_FLAG_LONG_LONG) {
- *((long double *)psfs->cur_ptr) = (long double) x;
- } else if (psfs->dataargtype & PA_FLAG_LONG) {
- *((double *)psfs->cur_ptr) = (double) x;
- } else {
- *((float *)psfs->cur_ptr) = (float) x;
- }
- ++psfs->cnt;
- }
- __scan_ungetc(sc);
- return 0;
- }
-#endif /* __UCLIBC_HAS_FLOATS__ */
-
- DONE_DO_UNGET:
- __scan_ungetc(sc);
- DONE:
- return -2; /* Matching failure. */
-
-}
-#endif
-/**********************************************************************/
+#define L_scanf
+#include "_scanf.c"
diff --git a/libc/stdio/setbuf.c b/libc/stdio/setbuf.c
index 02a4736ac..6de2c91a1 100644
--- a/libc/stdio/setbuf.c
+++ b/libc/stdio/setbuf.c
@@ -7,9 +7,11 @@
#include "_stdio.h"
+libc_hidden_proto(setvbuf)
+
void setbuf(FILE * __restrict stream, register char * __restrict buf)
{
#ifdef __STDIO_BUFFERS
- __setvbuf(stream, buf, ((buf != NULL) ? _IOFBF : _IONBF), BUFSIZ);
+ setvbuf(stream, buf, ((buf != NULL) ? _IOFBF : _IONBF), BUFSIZ);
#endif
}
diff --git a/libc/stdio/setbuffer.c b/libc/stdio/setbuffer.c
index d1f12a1af..3ca4fb7f8 100644
--- a/libc/stdio/setbuffer.c
+++ b/libc/stdio/setbuffer.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(setvbuf)
+
/* A BSD function. The implementation matches the linux man page,
* except that we do not bother calling setvbuf if not configured
* for stream buffering.
@@ -16,6 +18,6 @@ void setbuffer(FILE * __restrict stream, register char * __restrict buf,
size_t size)
{
#ifdef __STDIO_BUFFERS
- __setvbuf(stream, buf, (buf ? _IOFBF : _IONBF), size);
+ setvbuf(stream, buf, (buf ? _IOFBF : _IONBF), size);
#endif
}
diff --git a/libc/stdio/setlinebuf.c b/libc/stdio/setlinebuf.c
index 56e89e11b..29b2bdeac 100644
--- a/libc/stdio/setlinebuf.c
+++ b/libc/stdio/setlinebuf.c
@@ -7,6 +7,8 @@
#include "_stdio.h"
+libc_hidden_proto(setvbuf)
+
/* A BSD function. The implementation matches the linux man page,
* except that we do not bother calling setvbuf if not configured
* for stream buffering.
@@ -15,6 +17,6 @@
void setlinebuf(FILE * __restrict stream)
{
#ifdef __STDIO_BUFFERS
- __setvbuf(stream, NULL, _IOLBF, (size_t) 0);
+ setvbuf(stream, NULL, _IOLBF, (size_t) 0);
#endif
}
diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c
index d12d1576a..c1566504a 100644
--- a/libc/stdio/setvbuf.c
+++ b/libc/stdio/setvbuf.c
@@ -14,7 +14,8 @@
#error Assumption violated for buffering mode flags
#endif
-int attribute_hidden __setvbuf(register FILE * __restrict stream, register char * __restrict buf,
+libc_hidden_proto(setvbuf)
+int setvbuf(register FILE * __restrict stream, register char * __restrict buf,
int mode, size_t size)
{
#ifdef __STDIO_BUFFERS
@@ -104,4 +105,4 @@ int attribute_hidden __setvbuf(register FILE * __restrict stream, register char
#endif
}
-strong_alias(__setvbuf,setvbuf)
+libc_hidden_def(setvbuf)
diff --git a/libc/stdio/snprintf.c b/libc/stdio/snprintf.c
index a1ea79fc0..ef9c69215 100644
--- a/libc/stdio/snprintf.c
+++ b/libc/stdio/snprintf.c
@@ -12,17 +12,20 @@
#warning Skipping snprintf since no vsnprintf!
#else
-int attribute_hidden __snprintf(char *__restrict buf, size_t size,
+libc_hidden_proto(vsnprintf)
+
+libc_hidden_proto(snprintf)
+int snprintf(char *__restrict buf, size_t size,
const char * __restrict format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
- rv = __vsnprintf(buf, size, format, arg);
+ rv = vsnprintf(buf, size, format, arg);
va_end(arg);
return rv;
}
-strong_alias(__snprintf,snprintf)
+libc_hidden_def(snprintf)
#endif
diff --git a/libc/stdio/sprintf.c b/libc/stdio/sprintf.c
index 5778c011d..360245366 100644
--- a/libc/stdio/sprintf.c
+++ b/libc/stdio/sprintf.c
@@ -12,17 +12,20 @@
#warning Skipping sprintf since no vsnprintf!
#else
-int attribute_hidden __sprintf(char *__restrict buf, const char * __restrict format, ...)
+libc_hidden_proto(vsnprintf)
+
+libc_hidden_proto(sprintf)
+int sprintf(char *__restrict buf, const char * __restrict format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
- rv = __vsnprintf(buf, SIZE_MAX, format, arg);
+ rv = vsnprintf(buf, SIZE_MAX, format, arg);
va_end(arg);
return rv;
}
-strong_alias(__sprintf,sprintf)
+libc_hidden_def(sprintf)
#endif
diff --git a/libc/stdio/sscanf.c b/libc/stdio/sscanf.c
new file mode 100644
index 000000000..f53c06545
--- /dev/null
+++ b/libc/stdio/sscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_sscanf
+#include "_scanf.c"
diff --git a/libc/stdio/swprintf.c b/libc/stdio/swprintf.c
index b373df8bd..0c209fe4b 100644
--- a/libc/stdio/swprintf.c
+++ b/libc/stdio/swprintf.c
@@ -5,12 +5,12 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define vswprintf __vswprintf
-
#include "_stdio.h"
#include <stdarg.h>
#include <wchar.h>
+libc_hidden_proto(vswprintf)
+
#ifndef __STDIO_BUFFERS
#warning Skipping swprintf since no buffering!
#else /* __STDIO_BUFFERS */
diff --git a/libc/stdio/swscanf.c b/libc/stdio/swscanf.c
new file mode 100644
index 000000000..06f8cb75f
--- /dev/null
+++ b/libc/stdio/swscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_swscanf
+#include "_scanf.c"
diff --git a/libc/stdio/tempnam.c b/libc/stdio/tempnam.c
index d626dc0f8..43cbf781b 100644
--- a/libc/stdio/tempnam.c
+++ b/libc/stdio/tempnam.c
@@ -20,6 +20,8 @@
#include <string.h>
#include "../misc/internals/tempname.h"
+libc_hidden_proto(strdup)
+
/* Generate a unique temporary filename using up to five characters of PFX
if it is not NULL. The directory to put this file in is searched for
as follows: First the environment variable "TMPDIR" is checked.
@@ -38,6 +40,6 @@ tempnam (const char *dir, const char *pfx)
if (__gen_tempname (buf, __GT_NOCREATE))
return NULL;
- return __strdup (buf);
+ return strdup (buf);
}
diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c
index 606fcc436..f83944539 100644
--- a/libc/stdio/tmpfile.c
+++ b/libc/stdio/tmpfile.c
@@ -16,14 +16,15 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define fdopen __fdopen
-#define remove __remove
-
#include <features.h>
#include <stdio.h>
#include <unistd.h>
#include "../misc/internals/tempname.h"
+libc_hidden_proto(fdopen)
+libc_hidden_proto(remove)
+libc_hidden_proto(close)
+
/* This returns a new stream opened on a temporary file (generated
by tmpnam). The file is opened with mode "w+b" (binary read/write).
If we couldn't generate a unique filename or the file couldn't
@@ -45,10 +46,10 @@ FILE * tmpfile (void)
(void) remove (buf);
if ((f = fdopen (fd, "w+b")) == NULL)
- __close (fd);
+ close (fd);
return f;
}
#ifdef __UCLIBC_HAS_LFS__
-weak_alias(tmpfile,tmpfile64)
+strong_alias(tmpfile,tmpfile64)
#endif
diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c
index df2399e66..bc4ffeb6a 100644
--- a/libc/stdio/tmpnam.c
+++ b/libc/stdio/tmpnam.c
@@ -1,48 +1,55 @@
-/* Copyright (C) 1991, 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-1999,2000 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.
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
#include <stdio.h>
#include <string.h>
#include "../misc/internals/tempname.h"
+libc_hidden_proto(memcpy)
+
static char tmpnam_buffer[L_tmpnam];
/* Generate a unique filename in P_tmpdir.
- This function is *not* thread safe when S == NULL!
-*/
-char * tmpnam (char *s)
+
+ This function is *not* thread safe! */
+char *
+tmpnam (char *s)
{
- /* By using two buffers we manage to be thread safe in the case
- where S != NULL. */
- char tmpbuf[L_tmpnam];
+ /* By using two buffers we manage to be thread safe in the case
+ where S != NULL. */
+ char tmpbufmem[L_tmpnam];
+ char *tmpbuf = s ?: tmpbufmem;
- /* In the following call we use the buffer pointed to by S if
- non-NULL although we don't know the size. But we limit the size
- to L_tmpnam characters in any case. */
- if (__path_search (s ? : tmpbuf, L_tmpnam, NULL, NULL, 0))
- return NULL;
+ /* In the following call we use the buffer pointed to by S if
+ non-NULL although we don't know the size. But we limit the size
+ to L_tmpnam characters in any case. */
+ if (__builtin_expect (__path_search (tmpbuf, L_tmpnam, NULL, NULL, 0),
+ 0))
+ return NULL;
- if (__gen_tempname (s ? : tmpbuf, __GT_NOCREATE))
- return NULL;
+ if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE), 0))
+ return NULL;
- if (s == NULL)
- return (char *) __memcpy (tmpnam_buffer, tmpbuf, L_tmpnam);
+ if (s == NULL)
+ return (char *) memcpy (tmpnam_buffer, tmpbuf, L_tmpnam);
- return s;
+ return s;
}
+link_warning (tmpnam,
+ "the use of `tmpnam' is dangerous, better use `mkstemp'")
diff --git a/libc/stdio/ungetc.c b/libc/stdio/ungetc.c
index de3f1d16b..d900928b2 100644
--- a/libc/stdio/ungetc.c
+++ b/libc/stdio/ungetc.c
@@ -24,7 +24,8 @@
* (See section 7.19.6.2 of the C9X rationale -- WG14/N897.)
*/
-int attribute_hidden __ungetc(int c, register FILE *stream)
+libc_hidden_proto(ungetc)
+int ungetc(int c, register FILE *stream)
{
__STDIO_AUTO_THREADLOCK_VAR;
@@ -75,4 +76,4 @@ int attribute_hidden __ungetc(int c, register FILE *stream)
return c;
}
-strong_alias(__ungetc,ungetc)
+libc_hidden_def(ungetc)
diff --git a/libc/stdio/ungetwc.c b/libc/stdio/ungetwc.c
index c6a99dd9d..579022240 100644
--- a/libc/stdio/ungetwc.c
+++ b/libc/stdio/ungetwc.c
@@ -12,7 +12,8 @@
* as reset stream->__ungot_width[1] for use by _stdio_adjpos().
*/
-wint_t attribute_hidden __ungetwc(wint_t c, register FILE *stream)
+libc_hidden_proto(ungetwc)
+wint_t ungetwc(wint_t c, register FILE *stream)
{
__STDIO_AUTO_THREADLOCK_VAR;
@@ -46,4 +47,4 @@ wint_t attribute_hidden __ungetwc(wint_t c, register FILE *stream)
return c;
}
-strong_alias(__ungetwc,ungetwc)
+libc_hidden_def(ungetwc)
diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c
index ca110cbd1..7a34f6870 100644
--- a/libc/stdio/vasprintf.c
+++ b/libc/stdio/vasprintf.c
@@ -5,12 +5,14 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-#define open_memstream __open_memstream
+#include <features.h>
+#ifdef __USE_GNU
#include "_stdio.h"
#include <stdarg.h>
#include <bits/uClibc_va_copy.h>
+
#ifdef __UCLIBC_MJN3_ONLY__
/* Do the memstream stuff inline to avoid fclose and the openlist? */
#warning CONSIDER: avoid open_memstream call?
@@ -20,7 +22,16 @@
#warning Skipping vasprintf since no vsnprintf!
#else
-int attribute_hidden __vasprintf(char **__restrict buf, const char * __restrict format,
+#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
+libc_hidden_proto(open_memstream)
+libc_hidden_proto(fclose)
+libc_hidden_proto(vfprintf)
+#else
+libc_hidden_proto(vsnprintf)
+#endif
+
+libc_hidden_proto(vasprintf)
+int vasprintf(char **__restrict buf, const char * __restrict format,
va_list arg)
{
#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
@@ -32,7 +43,7 @@ int attribute_hidden __vasprintf(char **__restrict buf, const char * __restrict
*buf = NULL;
if ((f = open_memstream(buf, &size)) != NULL) {
- rv = __vfprintf(f, format, arg);
+ rv = vfprintf(f, format, arg);
fclose(f);
if (rv < 0) {
free(*buf);
@@ -54,14 +65,14 @@ int attribute_hidden __vasprintf(char **__restrict buf, const char * __restrict
int rv;
va_copy(arg2, arg);
- rv = __vsnprintf(NULL, 0, format, arg2);
+ rv = vsnprintf(NULL, 0, format, arg2);
va_end(arg2);
*buf = NULL;
if (rv >= 0) {
if ((*buf = malloc(++rv)) != NULL) {
- if ((rv = __vsnprintf(*buf, rv, format, arg)) < 0) {
+ if ((rv = vsnprintf(*buf, rv, format, arg)) < 0) {
free(*buf);
*buf = NULL;
}
@@ -74,6 +85,7 @@ int attribute_hidden __vasprintf(char **__restrict buf, const char * __restrict
#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
}
-strong_alias(__vasprintf,vasprintf)
+libc_hidden_def(vasprintf)
#endif
+#endif
diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
index 4e066f169..67adf47be 100644
--- a/libc/stdio/vdprintf.c
+++ b/libc/stdio/vdprintf.c
@@ -5,10 +5,17 @@
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
+#include <features.h>
+
+#ifdef __USE_GNU
#include "_stdio.h"
#include <stdarg.h>
-int attribute_hidden __vdprintf(int filedes, const char * __restrict format, va_list arg)
+libc_hidden_proto(vfprintf)
+libc_hidden_proto(fflush_unlocked)
+
+libc_hidden_proto(vdprintf)
+int vdprintf(int filedes, const char * __restrict format, va_list arg)
{
FILE f;
int rv;
@@ -51,11 +58,11 @@ int attribute_hidden __vdprintf(int filedes, const char * __restrict format, va_
#endif
f.__nextopen = NULL;
- rv = __vfprintf(&f, format, arg);
+ rv = vfprintf(&f, format, arg);
#ifdef __STDIO_BUFFERS
/* If not buffering, then fflush is unnecessary. */
- if ((rv > 0) && __fflush_unlocked(&f)) {
+ if ((rv > 0) && fflush_unlocked(&f)) {
rv = -1;
}
#endif
@@ -64,4 +71,5 @@ int attribute_hidden __vdprintf(int filedes, const char * __restrict format, va_
return rv;
}
-strong_alias(__vdprintf,vdprintf)
+libc_hidden_def(vdprintf)
+#endif
diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c
index bdbf0c788..78b725fd9 100644
--- a/libc/stdio/vfprintf.c
+++ b/libc/stdio/vfprintf.c
@@ -1,1929 +1,9 @@
-/* Copyright (C) 2002-2004 Manuel Novoa III
- * My stdio library for linux and (soon) elks.
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
- * This 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.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*
- * This 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 this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* This code needs a lot of clean up. Some of that is on hold until uClibc
- * gets a better configuration system (on Erik's todo list).
- * The other cleanup will take place during the implementation/integration of
- * the wide char (un)formatted i/o functions which I'm currently working on.
- */
-
-/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
- *
- * This code is currently under development. Also, I plan to port
- * it to elks which is a 16-bit environment with a fairly limited
- * compiler. Therefore, please refrain from modifying this code
- * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel
- *
- * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
-
-
-/* April 1, 2002
- * Initialize thread locks for fake files in vsnprintf and vdprintf.
- * reported by Erik Andersen (andersen@codepoet.com)
- * Fix an arg promotion handling bug in _do_one_spec for %c.
- * reported by Ilguiz Latypov <ilatypov@superbt.com>
- *
- * May 10, 2002
- * Remove __isdigit and use new ctype.h version.
- * Add conditional setting of QUAL_CHARS for size_t and ptrdiff_t.
- *
- * Aug 16, 2002
- * Fix two problems that showed up with the python 2.2.1 tests; one
- * involving %o and one involving %f.
- *
- * Oct 28, 2002
- * Fix a problem in vasprintf (reported by vodz a while back) when built
- * without custom stream support. In that case, it is necessary to do
- * a va_copy.
- * Make sure each va_copy has a matching va_end, as required by C99.
- *
- * Nov 4, 2002
- * Add locale-specific grouping support for integer decimal conversion.
- * Add locale-specific decimal point support for floating point conversion.
- * Note: grouping will have to wait for _dtostr() rewrite.
- * Add printf wchar support for %lc (%C) and %ls (%S).
- * Require printf format strings to be valid multibyte strings beginning and
- * ending in their initial shift state, as per the stds.
- *
- * Nov 21, 2002
- * Add *wprintf functions. Currently they don't support floating point
- * conversions. That will wait until the rewrite of _dtostr.
- *
- * Aug 1, 2003
- * Optional hexadecimal float notation support for %a/%A.
- * Floating point output now works for *wprintf.
- * Support for glibc locale-specific digit grouping for floats.
- * Misc bug fixes.
- *
- * Aug 31, 2003
- * Fix precision bug for %g conversion specifier when using %f style.
- *
- * Sep 5, 2003
- * Implement *s*scanf for the non-buffered stdio case with old_vfprintf.
- *
- * Sep 23, 2003
- * vfprintf was not always checking for narrow stream orientation.
- */
-
-/* TODO:
- *
- * Should we validate that *printf format strings are valid multibyte
- * strings in the current locale? ANSI/ISO C99 seems to imply this
- * and Plauger's printf implementation in his Standard C Library book
- * treats this as an error.
- */
-
-#define strnlen __strnlen
-#define wcslen __wcslen
-#define wcsnlen __wcsnlen
-#define wcsrtombs __wcsrtombs
-#define mbsrtowcs __mbsrtowcs
-#define btowc __btowc
-#define wcrtomb __wcrtomb
-#define fputws __fputws
-
-#define _ISOC99_SOURCE /* for ULLONG primarily... */
-#define _GNU_SOURCE
-#include <features.h>
-#include "_stdio.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <stdint.h>
-#include <errno.h>
-#include <locale.h>
-
-#define __PRINTF_INFO_NO_BITFIELD
-#include <printf.h>
-
-#ifdef __UCLIBC_HAS_THREADS__
-#include <stdio_ext.h>
-#include <pthread.h>
-#endif /* __UCLIBC_HAS_THREADS__ */
-
-#ifdef __UCLIBC_HAS_WCHAR__
-#include <wchar.h>
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-#include <bits/uClibc_uintmaxtostr.h>
-#include <bits/uClibc_va_copy.h>
-
-/* Some older or broken gcc toolchains define LONG_LONG_MAX but not
- * LLONG_MAX. Since LLONG_MAX is part of the standard, that's what
- * we use. So complain if we do not have it but should.
- */
-#if !defined(LLONG_MAX) && defined(LONG_LONG_MAX)
-#error Apparently, LONG_LONG_MAX is defined but LLONG_MAX is not. You need to fix your toolchain headers to support the standard macros for (unsigned) long long.
-#endif
-
-/**********************************************************************/
-/* These provide some control over printf's feature set */
-
-/* This is undefined below depeding on uClibc's configuration. */
-#define __STDIO_PRINTF_FLOAT 1
-
-/* Now controlled by uClibc_stdio.h. */
-/* #define __UCLIBC_HAS_PRINTF_M_SPEC__ */
-
-
-/**********************************************************************/
-
-#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_FLOATS__)
-#undef __STDIO_PRINTF_FLOAT
-#endif
-
-#ifdef __BCC__
-#undef __STDIO_PRINTF_FLOAT
-#endif
-
-#ifdef __STDIO_PRINTF_FLOAT
-#include <float.h>
-#include <bits/uClibc_fpmax.h>
-#else /* __STDIO_PRINTF_FLOAT */
-#undef L__fpmaxtostr
-#endif /* __STDIO_PRINTF_FLOAT */
-
-
-#undef __STDIO_HAS_VSNPRINTF
-#if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
-#define __STDIO_HAS_VSNPRINTF 1
-#endif
-
-/**********************************************************************/
-
-/* Now controlled by uClibc_stdio.h. */
-/* #define __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
-
-/* TODO -- move these to a configuration section? */
-#define MAX_FIELD_WIDTH 4095
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_register_printf_function
-/* emit only once */
-#warning WISHLIST: Make MAX_USER_SPEC configurable?
-#warning WISHLIST: Make MAX_ARGS_PER_SPEC configurable?
-#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
-
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
-
-#define MAX_USER_SPEC 10
-#define MAX_ARGS_PER_SPEC 5
-
-#else /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
-
-#undef MAX_USER_SPEC
-#define MAX_ARGS_PER_SPEC 1
-
-#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
-
-#if MAX_ARGS_PER_SPEC < 1
-#error MAX_ARGS_PER_SPEC < 1!
-#undef MAX_ARGS_PER_SPEC
-#define MAX_ARGS_PER_SPEC 1
-#endif
-
-#if defined(NL_ARGMAX) && (NL_ARGMAX < 9)
-#error NL_ARGMAX < 9!
-#endif
-
-#if defined(NL_ARGMAX) && (NL_ARGMAX >= (MAX_ARGS_PER_SPEC + 2))
-#define MAX_ARGS NL_ARGMAX
-#else
-/* N for spec itself, plus 1 each for width and precision */
-#define MAX_ARGS (MAX_ARGS_PER_SPEC + 2)
-#endif
-
-/**********************************************************************/
-
-#define __PA_FLAG_INTMASK \
- (__PA_FLAG_CHAR|PA_FLAG_SHORT|__PA_FLAG_INT|PA_FLAG_LONG|PA_FLAG_LONG_LONG)
-
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
-extern printf_function _custom_printf_handler[MAX_USER_SPEC];
-extern printf_arginfo_function *_custom_printf_arginfo[MAX_USER_SPEC];
-extern char *_custom_printf_spec;
-#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
-
-/**********************************************************************/
-
-#define SPEC_FLAGS " +0-#'I"
-enum {
- FLAG_SPACE = 0x01,
- FLAG_PLUS = 0x02, /* must be 2 * FLAG_SPACE */
- FLAG_ZERO = 0x04,
- FLAG_MINUS = 0x08, /* must be 2 * FLAG_ZERO */
- FLAG_HASH = 0x10,
- FLAG_THOUSANDS = 0x20,
- FLAG_I18N = 0x40, /* only works for d, i, u */
- FLAG_WIDESTREAM = 0x80
-};
-
-/**********************************************************************/
-
-/* float layout 01234567890123456789 TODO: B?*/
-#define SPEC_CHARS "npxXoudifFeEgGaACScs"
-enum {
- CONV_n = 0,
- CONV_p,
- CONV_x, CONV_X, CONV_o, CONV_u, CONV_d, CONV_i,
- CONV_f, CONV_F, CONV_e, CONV_E, CONV_g, CONV_G, CONV_a, CONV_A,
- CONV_C, CONV_S, CONV_c, CONV_s,
-#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
- CONV_m,
-#endif
- CONV_custom0 /* must be last */
-};
-
-/* p x X o u d i */
-#define SPEC_BASE { 16, 16, 16, 8, 10, 10, 10 }
-
-#define SPEC_RANGES { CONV_n, CONV_p, CONV_i, CONV_A, \
- CONV_C, CONV_S, CONV_c, CONV_s, CONV_custom0 }
-
-#define SPEC_OR_MASK { \
- /* n */ (PA_FLAG_PTR|PA_INT), \
- /* p */ PA_POINTER, \
- /* oxXudi */ PA_INT, \
- /* fFeEgGaA */ PA_DOUBLE, \
- /* C */ PA_WCHAR, \
- /* S */ PA_WSTRING, \
- /* c */ PA_CHAR, \
- /* s */ PA_STRING, \
-}
-
-#define SPEC_AND_MASK { \
- /* n */ (PA_FLAG_PTR|__PA_INTMASK), \
- /* p */ PA_POINTER, \
- /* oxXudi */ (__PA_INTMASK), \
- /* fFeEgGaA */ (PA_FLAG_LONG_DOUBLE|PA_DOUBLE), \
- /* C */ (PA_WCHAR), \
- /* S */ (PA_WSTRING), \
- /* c */ (PA_CHAR), \
- /* s */ (PA_STRING), \
-}
-
-/**********************************************************************/
-/*
- * In order to ease translation to what arginfo and _print_info._flags expect,
- * we map: 0:int 1:char 2:longlong 4:long 8:short
- * and then _flags |= (((q << 7) + q) & 0x701) and argtype |= (_flags & 0x701)
- */
-
-/* TODO -- Fix the table below to take into account stdint.h. */
-/* #ifndef LLONG_MAX */
-/* #error fix QUAL_CHARS for no long long! Affects 'L', 'j', 'q', 'll'. */
-/* #else */
-/* #if LLONG_MAX != INTMAX_MAX */
-/* #error fix QUAL_CHARS intmax_t entry 'j'! */
-/* #endif */
-/* #endif */
-
-#ifdef PDS
-#error PDS already defined!
-#endif
-#ifdef SS
-#error SS already defined!
-#endif
-#ifdef IMS
-#error IMS already defined!
-#endif
-
-#if PTRDIFF_MAX == INT_MAX
-#define PDS 0
-#elif PTRDIFF_MAX == LONG_MAX
-#define PDS 4
-#elif defined(LLONG_MAX) && (PTRDIFF_MAX == LLONG_MAX)
-#define PDS 8
-#else
-#error fix QUAL_CHARS ptrdiff_t entry 't'!
-#endif
-
-#if SIZE_MAX == UINT_MAX
-#define SS 0
-#elif SIZE_MAX == ULONG_MAX
-#define SS 4
-#elif defined(LLONG_MAX) && (SIZE_MAX == ULLONG_MAX)
-#define SS 8
-#else
-#error fix QUAL_CHARS size_t entries 'z', 'Z'!
-#endif
-
-#if INTMAX_MAX == INT_MAX
-#define IMS 0
-#elif INTMAX_MAX == LONG_MAX
-#define IMS 4
-#elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX)
-#define IMS 8
-#else
-#error fix QUAL_CHARS intmax_t entry 'j'!
-#endif
-
-#define QUAL_CHARS { \
- /* j:(u)intmax_t z:(s)size_t t:ptrdiff_t \0:int */ \
- /* q:long_long Z:(s)size_t */ \
- 'h', 'l', 'L', 'j', 'z', 't', 'q', 'Z', 0, \
- 2, 4, 8, IMS, SS, PDS, 8, SS, 0, /* TODO -- fix!!! */\
- 1, 8 \
-}
-
-/**********************************************************************/
-
-#ifdef __STDIO_VA_ARG_PTR
-#ifdef __BCC__
-#define __va_arg_ptr(ap,type) (((type *)(ap += sizeof(type))) - 1)
-#endif
-
-#if 1
-#ifdef __GNUC__
-/* TODO -- need other than for 386 as well! */
-
-#ifndef __va_rounded_size
-#define __va_rounded_size(TYPE) \
- (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
-#endif
-#define __va_arg_ptr(AP, TYPE) \
- (AP = (va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
- ((void *) ((char *) (AP) - __va_rounded_size (TYPE))))
-#endif
-#endif
-#endif /* __STDIO_VA_ARG_PTR */
-
-#ifdef __va_arg_ptr
-#define GET_VA_ARG(AP,F,TYPE,ARGS) (*(AP) = __va_arg_ptr(ARGS,TYPE))
-#define GET_ARG_VALUE(AP,F,TYPE) (*((TYPE *)(*(AP))))
-#else
-typedef union {
- wchar_t wc;
- unsigned int u;
- unsigned long ul;
-#ifdef ULLONG_MAX
- unsigned long long ull;
-#endif
-#ifdef __STDIO_PRINTF_FLOAT
- double d;
- long double ld;
-#endif /* __STDIO_PRINTF_FLOAT */
- void *p;
-} argvalue_t;
-
-#define GET_VA_ARG(AU,F,TYPE,ARGS) (AU->F = va_arg(ARGS,TYPE))
-#define GET_ARG_VALUE(AU,F,TYPE) ((TYPE)((AU)->F))
-#endif
-
-typedef struct {
- const char *fmtpos; /* TODO: move below struct?? */
- struct printf_info info;
-#ifdef NL_ARGMAX
- int maxposarg; /* > 0 if args are positional, 0 if not, -1 if unknown */
-#endif /* NL_ARGMAX */
- int num_data_args; /* TODO: use sentinal??? */
- unsigned int conv_num;
- unsigned char argnumber[4]; /* width | prec | 1st data | unused */
- int argtype[MAX_ARGS];
- va_list arg;
-#ifdef __va_arg_ptr
- void *argptr[MAX_ARGS];
-#else
-/* if defined(NL_ARGMAX) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__) */
- /* While this is wasteful of space in the case where pos args aren't
- * enabled, it is also needed to support custom printf handlers. */
- argvalue_t argvalue[MAX_ARGS];
-#endif
-} ppfs_t; /* parse printf format state */
-
-/**********************************************************************/
-
-/* TODO: fix printf to return 0 and set errno if format error. Standard says
- only returns -1 if sets error indicator for the stream. */
-
-#ifdef __STDIO_PRINTF_FLOAT
-typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
- intptr_t buf);
-
-extern ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
- __fp_outfunc_t fp_outfunc) attribute_hidden;
-#endif
-
-extern int _ppfs_init(ppfs_t *ppfs, const char *fmt0) attribute_hidden; /* validates */
-extern void _ppfs_prepargs(ppfs_t *ppfs, va_list arg) attribute_hidden; /* sets posargptrs */
-extern void _ppfs_setargs(ppfs_t *ppfs) attribute_hidden; /* sets argptrs for current spec */
-extern int _ppfs_parsespec(ppfs_t *ppfs) attribute_hidden; /* parses specifier */
-
-extern void _store_inttype(void *dest, int desttype, uintmax_t val) attribute_hidden;
-extern uintmax_t _load_inttype(int desttype, const void *src, int uflag) attribute_hidden;
-
-/**********************************************************************/
-#ifdef L_parse_printf_format
-
-/* NOTE: This function differs from the glibc version in that parsing stops
- * upon encountering an invalid conversion specifier. Since this is the way
- * my printf functions work, I think it makes sense to do it that way here.
- * Unfortunately, since glibc sets the return type as size_t, we have no way
- * of returning that the template is illegal, other than returning 0.
- */
-
-size_t parse_printf_format(register const char *template,
- size_t n, register int *argtypes)
-{
- ppfs_t ppfs;
- size_t i;
- size_t count = 0;
-
- if (_ppfs_init(&ppfs, template) >= 0) {
-#ifdef NL_ARGMAX
- if (ppfs.maxposarg > 0) { /* Using positional args. */
- count = ppfs.maxposarg;
- if (n > count) {
- n = count;
- }
- for (i = 0 ; i < n ; i++) {
- *argtypes++ = ppfs.argtype[i];
- }
- } else { /* Not using positional args. */
-#endif /* NL_ARGMAX */
- while (*template) {
- if ((*template == '%') && (*++template != '%')) {
- ppfs.fmtpos = template;
- _ppfs_parsespec(&ppfs); /* Can't fail. */
- template = ppfs.fmtpos; /* Update to one past spec end. */
- if (ppfs.info.width == INT_MIN) {
- ++count;
- if (n > 0) {
- *argtypes++ = PA_INT;
- --n;
- }
- }
- if (ppfs.info.prec == INT_MIN) {
- ++count;
- if (n > 0) {
- *argtypes++ = PA_INT;
- --n;
- }
- }
- for (i = 0 ; i < ppfs.num_data_args ; i++) {
- if ((ppfs.argtype[i]) != __PA_NOARG) {
- ++count;
- if (n > 0) {
- *argtypes++ = ppfs.argtype[i];
- --n;
- }
- }
- }
- } else {
- ++template;
- }
- }
-#ifdef NL_ARGMAX
- }
-#endif /* NL_ARGMAX */
- }
-
- return count;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L__ppfs_init
-
-int attribute_hidden _ppfs_init(register ppfs_t *ppfs, const char *fmt0)
-{
- int r;
-
- /* First, zero out everything... argnumber[], argtype[], argptr[] */
- __memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */
-#ifdef NL_ARGMAX
- --ppfs->maxposarg; /* set to -1 */
-#endif /* NL_ARGMAX */
- ppfs->fmtpos = fmt0;
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Make checking of the format string in C locale an option.
-#endif
-#ifdef __UCLIBC_HAS_LOCALE__
- /* To support old programs, don't check mb validity if in C locale. */
- if (((__UCLIBC_CURLOCALE_DATA).encoding) != __ctype_encoding_7_bit) {
- /* ANSI/ISO C99 requires format string to be a valid multibyte string
- * beginning and ending in its initial shift state. */
- static const char invalid_mbs[] = "Invalid multibyte format string.";
- mbstate_t mbstate;
- const char *p;
- mbstate.__mask = 0; /* Initialize the mbstate. */
- p = fmt0;
- if (mbsrtowcs(NULL, &p, SIZE_MAX, &mbstate) == ((size_t)(-1))) {
- ppfs->fmtpos = invalid_mbs;
- return -1;
- }
- }
-#endif /* __UCLIBC_HAS_LOCALE__ */
- /* now set all argtypes to no-arg */
- {
-#if 1
- /* TODO - use memset here since already "paid for"? */
- register int *p = ppfs->argtype;
-
- r = MAX_ARGS;
- do {
- *p++ = __PA_NOARG;
- } while (--r);
-#else
- /* TODO -- get rid of this?? */
- register char *p = (char *) ((MAX_ARGS-1) * sizeof(int));
-
- do {
- *((int *)(((char *)ppfs) + ((int)p) + offsetof(ppfs_t,argtype))) = __PA_NOARG;
- p -= sizeof(int);
- } while (p);
-#endif
- }
-
- /*
- * Run through the entire format string to validate it and initialize
- * the positional arg numbers (if any).
- */
- {
- register const char *fmt = fmt0;
-
- while (*fmt) {
- if ((*fmt == '%') && (*++fmt != '%')) {
- ppfs->fmtpos = fmt; /* back up to the '%' */
- if ((r = _ppfs_parsespec(ppfs)) < 0) {
- return -1;
- }
- fmt = ppfs->fmtpos; /* update to one past end of spec */
- } else {
- ++fmt;
- }
- }
- ppfs->fmtpos = fmt0; /* rewind */
- }
-
-#ifdef NL_MAX_ARG
- /* If we have positional args, make sure we know all the types. */
- {
- register int *p = ppfs->argtype;
- r = ppfs->maxposarg;
- while (--r >= 0) {
- if ( *p == __PA_NOARG ) { /* missing arg type!!! */
- return -1;
- }
- ++p;
- }
- }
-#endif /* NL_MAX_ARG */
-
- return 0;
-}
-#endif
-/**********************************************************************/
-#ifdef L__ppfs_prepargs
-void attribute_hidden _ppfs_prepargs(register ppfs_t *ppfs, va_list arg)
-{
- int i;
-
- va_copy(ppfs->arg, arg);
-
-#ifdef NL_ARGMAX
- if ((i = ppfs->maxposarg) > 0) { /* init for positional args */
- ppfs->num_data_args = i;
- ppfs->info.width = ppfs->info.prec = ppfs->maxposarg = 0;
- _ppfs_setargs(ppfs);
- ppfs->maxposarg = i;
- }
-#endif /* NL_ARGMAX */
-}
-#endif
-/**********************************************************************/
-#ifdef L__ppfs_setargs
-
-void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs)
-{
-#ifdef __va_arg_ptr
- register void **p = ppfs->argptr;
-#else
- register argvalue_t *p = ppfs->argvalue;
-#endif
- int i;
-
-#ifdef NL_ARGMAX
- if (ppfs->maxposarg == 0) { /* initing for or no pos args */
-#endif /* NL_ARGMAX */
- if (ppfs->info.width == INT_MIN) {
- ppfs->info.width =
-#ifdef __va_arg_ptr
- *(int *)
-#endif
- GET_VA_ARG(p,u,unsigned int,ppfs->arg);
- }
- if (ppfs->info.prec == INT_MIN) {
- ppfs->info.prec =
-#ifdef __va_arg_ptr
- *(int *)
-#endif
- GET_VA_ARG(p,u,unsigned int,ppfs->arg);
- }
- i = 0;
- while (i < ppfs->num_data_args) {
- switch(ppfs->argtype[i++]) {
- case (PA_INT|PA_FLAG_LONG_LONG):
-#ifdef ULLONG_MAX
- GET_VA_ARG(p,ull,unsigned long long,ppfs->arg);
- break;
-#endif
- case (PA_INT|PA_FLAG_LONG):
-#if ULONG_MAX != UINT_MAX
- GET_VA_ARG(p,ul,unsigned long,ppfs->arg);
- break;
-#endif
- case PA_CHAR: /* TODO - be careful */
- /* ... users could use above and really want below!! */
- case (PA_INT|__PA_FLAG_CHAR):/* TODO -- translate this!!! */
- case (PA_INT|PA_FLAG_SHORT):
- case PA_INT:
- GET_VA_ARG(p,u,unsigned int,ppfs->arg);
- break;
- case PA_WCHAR: /* TODO -- assume int? */
- /* we're assuming wchar_t is at least an int */
- GET_VA_ARG(p,wc,wchar_t,ppfs->arg);
- break;
-#ifdef __STDIO_PRINTF_FLOAT
- /* PA_FLOAT */
- case PA_DOUBLE:
- GET_VA_ARG(p,d,double,ppfs->arg);
- break;
- case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE):
- GET_VA_ARG(p,ld,long double,ppfs->arg);
- break;
-#else /* __STDIO_PRINTF_FLOAT */
- case PA_DOUBLE:
- case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE):
- assert(0);
- continue;
-#endif /* __STDIO_PRINTF_FLOAT */
- default:
- /* TODO -- really need to ensure this can't happen */
- assert(ppfs->argtype[i-1] & PA_FLAG_PTR);
- case PA_POINTER:
- case PA_STRING:
- case PA_WSTRING:
- GET_VA_ARG(p,p,void *,ppfs->arg);
- break;
- case __PA_NOARG:
- continue;
- }
- ++p;
- }
-#ifdef NL_ARGMAX
- } else {
- if (ppfs->info.width == INT_MIN) {
- ppfs->info.width
- = (int) GET_ARG_VALUE(p + ppfs->argnumber[0] - 1,u,unsigned int);
- }
- if (ppfs->info.prec == INT_MIN) {
- ppfs->info.prec
- = (int) GET_ARG_VALUE(p + ppfs->argnumber[1] - 1,u,unsigned int);
- }
- }
-#endif /* NL_ARGMAX */
-
- /* Now we know the width and precision. */
- if (ppfs->info.width < 0) {
- ppfs->info.width = -ppfs->info.width;
- PRINT_INFO_SET_FLAG(&(ppfs->info),left);
- PRINT_INFO_CLR_FLAG(&(ppfs->info),space);
- ppfs->info.pad = ' ';
- }
-#if 0
- /* NOTE -- keep neg for now so float knows! */
- if (ppfs->info.prec < 0) { /* spec says treat as omitted. */
- /* so use default prec... 1 for everything but floats and strings. */
- ppfs->info.prec = 1;
- }
-#endif
-}
-#endif
-/**********************************************************************/
-#ifdef L__ppfs_parsespec
-
-/* Notes: argtype differs from glibc for the following:
- * mine glibc
- * lc PA_WCHAR PA_CHAR the standard says %lc means %C
- * ls PA_WSTRING PA_STRING the standard says %ls means %S
- * {*}n {*}|PA_FLAG_PTR PA_FLAG_PTR size of n can be qualified
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
-
-/* TODO: store positions of positional args */
-
-/* TODO -- WARNING -- assumes aligned on integer boundaries!!! */
-
-/* TODO -- disable if not using positional args!!! */
-#define _OVERLAPPING_DIFFERENT_ARGS
-
-/* TODO -- rethink this -- perhaps we should set to largest type??? */
-
-#ifdef _OVERLAPPING_DIFFERENT_ARGS
-
-#define PROMOTED_SIZE_OF(X) ((sizeof(X) + sizeof(int) - 1) / sizeof(X))
-
-static const short int type_codes[] = {
- __PA_NOARG, /* must be first entry */
- PA_POINTER,
- PA_STRING,
- PA_WSTRING,
- PA_CHAR,
- PA_INT|PA_FLAG_SHORT,
- PA_INT,
- PA_INT|PA_FLAG_LONG,
- PA_INT|PA_FLAG_LONG_LONG,
- PA_WCHAR,
-#ifdef __STDIO_PRINTF_FLOAT
- /* PA_FLOAT, */
- PA_DOUBLE,
- PA_DOUBLE|PA_FLAG_LONG_DOUBLE,
-#endif /* __STDIO_PRINTF_FLOAT */
-};
-
-static const unsigned char type_sizes[] = {
- /* unknown type consumes no arg */
- 0, /* must be first entry */
- PROMOTED_SIZE_OF(void *),
- PROMOTED_SIZE_OF(char *),
- PROMOTED_SIZE_OF(wchar_t *),
- PROMOTED_SIZE_OF(char),
- PROMOTED_SIZE_OF(short),
- PROMOTED_SIZE_OF(int),
- PROMOTED_SIZE_OF(long),
-#ifdef ULLONG_MAX
- PROMOTED_SIZE_OF(long long),
-#else
- PROMOTED_SIZE_OF(long), /* TODO -- is this correct? (above too) */
-#endif
- PROMOTED_SIZE_OF(wchar_t),
-#ifdef __STDIO_PRINTF_FLOAT
- /* PROMOTED_SIZE_OF(float), */
- PROMOTED_SIZE_OF(double),
- PROMOTED_SIZE_OF(long double),
-#endif /* __STDIO_PRINTF_FLOAT */
-};
-
-static int _promoted_size(int argtype)
-{
- register const short int *p;
-
- /* note -- since any unrecognized type is treated as a pointer */
- p = type_codes + sizeof(type_codes)/sizeof(type_codes[0]);
- do {
- if (*--p == argtype) {
- break;
- }
- } while (p > type_codes);
-
- return type_sizes[(int)(p - type_codes)];
-}
-
-static int _is_equal_or_bigger_arg(int curtype, int newtype)
-{
- /* Quick test */
- if (newtype == __PA_NOARG) {
- return 0;
- }
- if ((curtype == __PA_NOARG) || (curtype == newtype)) {
- return 1;
- }
- /* Ok... slot is already filled and types are different in name. */
- /* So, compare promoted sizes of curtype and newtype args. */
- return _promoted_size(curtype) <= _promoted_size(newtype);
-}
-
-#else
-
-#define _is_equal_or_bigger_arg(C,N) (((C) == __PA_NOARG) || ((C) == (N)))
-
-#endif
-
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
-/* TODO - do this differently? */
-static char _bss_custom_printf_spec[MAX_USER_SPEC]; /* 0-init'd for us. */
-
-char *_custom_printf_spec = _bss_custom_printf_spec;
-printf_arginfo_function *_custom_printf_arginfo[MAX_USER_SPEC];
-printf_function _custom_printf_handler[MAX_USER_SPEC];
-#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
-
-int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs)
-{
- register const char *fmt;
- register const char *p;
- int preci;
- int width;
- int flags;
- int dataargtype;
- int i;
- int dpoint;
-#ifdef NL_ARGMAX
- int maxposarg;
-#endif /* NL_ARGMAX */
- int p_m_spec_chars;
- int n;
- int argtype[MAX_ARGS_PER_SPEC+2];
- int argnumber[3]; /* width, precision, 1st data arg */
- static const char spec_flags[] = SPEC_FLAGS;
- static const char spec_chars[] = SPEC_CHARS;/* TODO: b? */
- static const char spec_ranges[] = SPEC_RANGES;
- static const short spec_or_mask[] = SPEC_OR_MASK;
- static const short spec_and_mask[] = SPEC_AND_MASK;
- static const char qual_chars[] = QUAL_CHARS;
-#ifdef __UCLIBC_HAS_WCHAR__
- char buf[32];
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- /* WIDE note: we can test against '%' here since we don't allow */
- /* WIDE note: other mappings of '%' in the wide char set. */
- preci = -1;
- argnumber[0] = 0;
- argnumber[1] = 0;
- argtype[0] = __PA_NOARG;
- argtype[1] = __PA_NOARG;
-#ifdef NL_ARGMAX
- maxposarg = ppfs->maxposarg;
-#endif /* NL_ARGMAX */
-
-#ifdef __UCLIBC_HAS_WCHAR__
- /* This is somewhat lame, but saves a lot of code. If we're dealing with
- * a wide stream, that means the format is a wchar string. So, copy it
- * char-by-char into a normal char buffer for processing. Make the buffer
- * (buf) big enough so that any reasonable format specifier will fit.
- * While there a legal specifiers that won't, the all involve duplicate
- * flags or outrageous field widths/precisions. */
- width = dpoint = 0;
- if ((flags = ppfs->info._flags & FLAG_WIDESTREAM) == 0) {
- fmt = ppfs->fmtpos;
- } else {
- fmt = buf + 1;
- i = 0;
- do {
- if ((buf[i] = (char) (((wchar_t *) ppfs->fmtpos)[i-1]))
- != (((wchar_t *) ppfs->fmtpos)[i-1])
- ) {
- return -1;
- }
- } while (buf[i++]);
- buf[sizeof(buf)-1] = 0;
- }
-#else /* __UCLIBC_HAS_WCHAR__ */
- width = flags = dpoint = 0;
- fmt = ppfs->fmtpos;
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- assert(fmt[-1] == '%');
- assert(fmt[0] != '%');
-
- /* Process arg pos and/or flags and/or width and/or precision. */
- width_precision:
- p = fmt;
- if (*fmt == '*') {
- argtype[-dpoint] = PA_INT;
- ++fmt;
- }
- i = 0;
- while (isdigit(*fmt)) {
- if (i < MAX_FIELD_WIDTH) { /* Avoid overflow. */
- i = (i * 10) + (*fmt - '0');
- }
- ++fmt;
- }
- if (p[-1] == '%') { /* Check for a position. */
-
- /* TODO: if val not in range, then error */
-
-#ifdef NL_ARGMAX
- if ((*fmt == '$') && (i > 0)) {/* Positional spec. */
- ++fmt;
- if (maxposarg == 0) {
- return -1;
- }
- if ((argnumber[2] = i) > maxposarg) {
- maxposarg = i;
- }
- /* Now fall through to check flags. */
- } else {
- if (maxposarg > 0) {
-#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Support prec and width for %m when positional args used
- /* Actually, positional arg processing will fail in general
- * for specifiers that don't require an arg. */
-#endif /* __UCLIBC_MJN3_ONLY__ */
- if (*fmt == 'm') {
- goto PREC_WIDTH;
- }
-#endif /* __UCLIBC_HAS_PRINTF_M_SPEC__ */
- return -1;
- }
- maxposarg = 0; /* Possible redundant store, but cuts size. */
-
- if ((fmt > p) && (*p != '0')) {
- goto PREC_WIDTH;
- }
-
- fmt = p; /* Back up for possible '0's flag. */
- /* Now fall through to check flags. */
- }
-#else /* NL_ARGMAX */
- if (*fmt == '$') { /* Positional spec. */
- return -1;
- }
-
- if ((fmt > p) && (*p != '0')) {
- goto PREC_WIDTH;
- }
-
- fmt = p; /* Back up for possible '0's flag. */
- /* Now fall through to check flags. */
-#endif /* NL_ARGMAX */
-
- restart_flags: /* Process flags. */
- i = 1;
- p = spec_flags;
-
- do {
- if (*fmt == *p++) {
- ++fmt;
- flags |= i;
- goto restart_flags;
- }
- i += i; /* Better than i <<= 1 for bcc */
- } while (*p);
- i = 0;
-
- /* If '+' then ignore ' ', and if '-' then ignore '0'. */
- /* Note: Need to ignore '0' when prec is an arg with val < 0, */
- /* but that test needs to wait until the arg is retrieved. */
- flags &= ~((flags & (FLAG_PLUS|FLAG_MINUS)) >> 1);
- /* Note: Ignore '0' when prec is specified < 0 too (in printf). */
-
- if (fmt[-1] != '%') { /* If we've done anything, loop for width. */
- goto width_precision;
- }
- }
- PREC_WIDTH:
- if (*p == '*') { /* Prec or width takes an arg. */
-#ifdef NL_ARGMAX
- if (maxposarg) {
- if ((*fmt++ != '$') || (i <= 0)) {
- /* Using pos args and no $ or invalid arg number. */
- return -1;
- }
- argnumber[-dpoint] = i;
- } else
-#endif /* NL_ARGMAX */
- if (++p != fmt) {
- /* Not using pos args but digits followed *. */
- return -1;
- }
- i = INT_MIN;
- }
-
- if (!dpoint) {
- width = i;
- if (*fmt == '.') {
- ++fmt;
- dpoint = -1; /* To use as default precison. */
- goto width_precision;
- }
- } else {
- preci = i;
- }
-
- /* Process qualifier. */
- p = qual_chars;
- do {
- if (*fmt == *p) {
- ++fmt;
- break;
- }
- } while (*++p);
- if ((p - qual_chars < 2) && (*fmt == *p)) {
- p += ((sizeof(qual_chars)-2) / 2);
- ++fmt;
- }
- dataargtype = ((int)(p[(sizeof(qual_chars)-2) / 2])) << 8;
-
- /* Process conversion specifier. */
- if (!*fmt) {
- return -1;
- }
-
- p = spec_chars;
-
- do {
- if (*fmt == *p) {
- p_m_spec_chars = p - spec_chars;
-
- if ((p_m_spec_chars >= CONV_c)
- && (dataargtype & PA_FLAG_LONG)) {
- p_m_spec_chars -= 2; /* lc -> C and ls -> S */
- }
-
- ppfs->conv_num = p_m_spec_chars;
- p = spec_ranges-1;
- while (p_m_spec_chars > *++p) {}
-
- i = p - spec_ranges;
- argtype[2] = (dataargtype | spec_or_mask[i]) & spec_and_mask[i];
- p = spec_chars;
- break;
- }
- } while(*++p);
-
- ppfs->info.spec = *fmt;
- ppfs->info.prec = preci;
- ppfs->info.width = width;
- ppfs->info.pad = ((flags & FLAG_ZERO) ? '0' : ' ');
- ppfs->info._flags = (flags & ~FLAG_ZERO) | (dataargtype & __PA_INTMASK);
- ppfs->num_data_args = 1;
-
- if (!*p) {
-#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
- if (*fmt == 'm') {
- ppfs->conv_num = CONV_m;
- ppfs->num_data_args = 0;
- goto DONE;
- }
-#endif
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
-
- /* Handle custom arg -- WARNING -- overwrites p!!! */
- ppfs->conv_num = CONV_custom0;
- p = _custom_printf_spec;
- do {
- if (*p == *fmt) {
- if ((ppfs->num_data_args
- = ((*_custom_printf_arginfo[(int)(p-_custom_printf_spec)])
- (&(ppfs->info), MAX_ARGS_PER_SPEC, argtype+2)))
- > MAX_ARGS_PER_SPEC) {
- break; /* Error -- too many args! */
- }
- goto DONE;
- }
- } while (++p < (_custom_printf_spec + MAX_USER_SPEC));
-#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
- /* Otherwise error. */
- return -1;
- }
-
-#if defined(__UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__) || defined(__UCLIBC_HAS_PRINTF_M_SPEC__)
- DONE:
-#endif
-
-#ifdef NL_ARGMAX
- if (maxposarg > 0) {
- i = 0;
- do {
- /* Update maxposarg and check that NL_ARGMAX is not exceeded. */
- n = ((i <= 2)
- ? (ppfs->argnumber[i] = argnumber[i])
- : argnumber[2] + (i-2));
- if (n > maxposarg) {
- if ((maxposarg = n) > NL_ARGMAX) {
- return -1;
- }
- }
- --n;
- /* Record argtype with largest size (current, new). */
- if (_is_equal_or_bigger_arg(ppfs->argtype[n], argtype[i])) {
- ppfs->argtype[n] = argtype[i];
- }
- } while (++i < ppfs->num_data_args + 2);
- } else {
-#endif /* NL_ARGMAX */
- ppfs->argnumber[2] = 1;
- __memcpy(ppfs->argtype, argtype + 2, ppfs->num_data_args * sizeof(int));
-#ifdef NL_ARGMAX
- }
-
- ppfs->maxposarg = maxposarg;
-#endif /* NL_ARGMAX */
-
-#ifdef __UCLIBC_HAS_WCHAR__
- if ((flags = ppfs->info._flags & FLAG_WIDESTREAM) == 0) {
- ppfs->fmtpos = ++fmt;
- } else {
- ppfs->fmtpos = (const char *) (((const wchar_t *)(ppfs->fmtpos))
- + (fmt - buf) );
- }
-#else /* __UCLIBC_HAS_WCHAR__ */
- ppfs->fmtpos = ++fmt;
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
- return ppfs->num_data_args + 2;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_register_printf_function
-
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
-
-int register_printf_function(int spec, printf_function handler,
- printf_arginfo_function arginfo)
-{
- register char *r;
- register char *p;
-
- if (spec && (arginfo != NULL)) { /* TODO -- check if spec is valid char */
- r = NULL;
- p = _custom_printf_spec + MAX_USER_SPEC;
- do {
- --p;
- if (!*p) {
- r = p;
- }
-#ifdef __BCC__
- else /* bcc generates less code with fall-through */
-#endif
- if (*p == spec) {
- r = p;
- p = _custom_printf_spec;
- }
- } while (p > _custom_printf_spec);
-
- if (r) {
- if (handler) {
- *r = spec;
- _custom_printf_handler[(int)(r - p)] = handler;
- _custom_printf_arginfo[(int)(r - p)] = arginfo;
- } else {
- *r = 0;
- }
- return 0;
- }
- /* TODO -- if asked to unregister a non-existent spec, return what? */
- }
- return -1;
-}
-
-#endif
-
-#endif
-/**********************************************************************/
-#if defined(L_vfprintf) || defined(L_vfwprintf)
-
-/* We only support ascii digits (or their USC equivalent codes) in
- * precision and width settings in *printf (wide) format strings.
- * In other words, we don't currently support glibc's 'I' flag.
- * We do accept it, but it is currently ignored. */
-
-static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad);
-
-#ifdef L_vfprintf
-
-#define HIDDEN_VFPRINTF __vfprintf
-#define VFPRINTF vfprintf
-#define FMT_TYPE char
-#define OUTNSTR _outnstr
-#define STRLEN __strlen
-#define _PPFS_init _ppfs_init
-#define OUTPUT(F,S) __fputs_unlocked(S,F)
-/* #define _outnstr(stream, string, len) __stdio_fwrite(string, len, stream) */
-#define _outnstr(stream, string, len) ((len > 0) ? __stdio_fwrite(string, len, stream) : 0)
-#define FP_OUT _fp_out_narrow
-
-#ifdef __STDIO_PRINTF_FLOAT
-
-static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
-{
- size_t r = 0;
-
- if (type & 0x80) { /* Some type of padding needed. */
- int buflen = __strlen((const char *) buf);
- if ((len -= buflen) > 0) {
- if ((r = _charpad(fp, (type & 0x7f), len)) != len) {
- return r;
- }
- }
- len = buflen;
- }
- return r + OUTNSTR(fp, (const char *) buf, len);
-}
-
-#endif /* __STDIO_PRINTF_FLOAT */
-
-#else /* L_vfprintf */
-
-#define HIDDEN_VFPRINTF __vfwprintf
-#define VFPRINTF vfwprintf
-#define FMT_TYPE wchar_t
-#define OUTNSTR _outnwcs
-#define STRLEN wcslen
-#define _PPFS_init _ppwfs_init
-#define OUTPUT(F,S) fputws(S,F)
-#define _outnwcs(stream, wstring, len) _wstdio_fwrite(wstring, len, stream)
-#define FP_OUT _fp_out_wide
-
-static size_t _outnstr(FILE *stream, const char *s, size_t wclen)
-{
- /* NOTE!!! len here is the number of wchars we want to generate!!! */
- wchar_t wbuf[64];
- mbstate_t mbstate;
- size_t todo, r, n;
-
- mbstate.__mask = 0;
- todo = wclen;
-
- while (todo) {
- r = mbsrtowcs(wbuf, &s,
- ((todo <= sizeof(wbuf)/sizeof(wbuf[0]))
- ? todo
- : sizeof(wbuf)/sizeof(wbuf[0])),
- &mbstate);
- assert(((ssize_t)r) > 0);
- n = _outnwcs(stream, wbuf, r);
- todo -= n;
- if (n != r) {
- break;
- }
- }
-
- return wclen - todo;
-}
-
-#ifdef __STDIO_PRINTF_FLOAT
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Move defines from _fpmaxtostr. Put them in a common header.
-#endif
-
-/* The following defines are from _fpmaxtostr.*/
-#define DIGITS_PER_BLOCK 9
-#define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK)
-#define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK )
-
-static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
-{
- wchar_t wbuf[BUF_SIZE];
- const char *s = (const char *) buf;
- size_t r = 0;
- int i;
-
- if (type & 0x80) { /* Some type of padding needed */
- int buflen = __strlen(s);
- if ((len -= buflen) > 0) {
- if ((r = _charpad(fp, (type & 0x7f), len)) != len) {
- return r;
- }
- }
- len = buflen;
- }
-
- if (len > 0) {
- i = 0;
- do {
-#ifdef __LOCALE_C_ONLY
- wbuf[i] = s[i];
-#else /* __LOCALE_C_ONLY */
-
-#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- if (s[i] == ',') {
- wbuf[i] = __UCLIBC_CURLOCALE_DATA.thousands_sep_wc;
- } else
-#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
- if (s[i] == '.') {
- wbuf[i] = __UCLIBC_CURLOCALE_DATA.decimal_point_wc;
- } else {
- wbuf[i] = s[i];
- }
-#endif /* __LOCALE_C_ONLY */
-
- } while (++i < len);
-
- r += OUTNSTR(fp, wbuf, len);
- }
-
- return r;
-}
-
-#endif /* __STDIO_PRINTF_FLOAT */
-
-static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0)
-{
- static const wchar_t invalid_wcs[] = L"Invalid wide format string.";
- int r;
-
- /* First, zero out everything... argnumber[], argtype[], argptr[] */
- __memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */
-#ifdef NL_ARGMAX
- --ppfs->maxposarg; /* set to -1 */
-#endif /* NL_ARGMAX */
- ppfs->fmtpos = (const char *) fmt0;
- ppfs->info._flags = FLAG_WIDESTREAM;
-
- {
- mbstate_t mbstate;
- const wchar_t *p;
- mbstate.__mask = 0; /* Initialize the mbstate. */
- p = fmt0;
- if (wcsrtombs(NULL, &p, SIZE_MAX, &mbstate) == ((size_t)(-1))) {
- ppfs->fmtpos = (const char *) invalid_wcs;
- return -1;
- }
- }
-
- /* now set all argtypes to no-arg */
- {
-#if 1
- /* TODO - use memset here since already "paid for"? */
- register int *p = ppfs->argtype;
-
- r = MAX_ARGS;
- do {
- *p++ = __PA_NOARG;
- } while (--r);
-#else
- /* TODO -- get rid of this?? */
- register char *p = (char *) ((MAX_ARGS-1) * sizeof(int));
-
- do {
- *((int *)(((char *)ppfs) + ((int)p) + offsetof(ppfs_t,argtype))) = __PA_NOARG;
- p -= sizeof(int);
- } while (p);
-#endif
- }
-
- /*
- * Run through the entire format string to validate it and initialize
- * the positional arg numbers (if any).
- */
- {
- register const wchar_t *fmt = fmt0;
-
- while (*fmt) {
- if ((*fmt == '%') && (*++fmt != '%')) {
- ppfs->fmtpos = (const char *) fmt; /* back up to the '%' */
- if ((r = _ppfs_parsespec(ppfs)) < 0) {
- return -1;
- }
- fmt = (const wchar_t *) ppfs->fmtpos; /* update to one past end of spec */
- } else {
- ++fmt;
- }
- }
- ppfs->fmtpos = (const char *) fmt0; /* rewind */
- }
-
-#ifdef NL_ARGMAX
- /* If we have positional args, make sure we know all the types. */
- {
- register int *p = ppfs->argtype;
- r = ppfs->maxposarg;
- while (--r >= 0) {
- if ( *p == __PA_NOARG ) { /* missing arg type!!! */
- return -1;
- }
- ++p;
- }
- }
-#endif /* NL_ARGMAX */
-
- return 0;
-}
-
-#endif /* L_vfprintf */
-
-static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)
-{
- size_t todo = numpad;
-
- /* TODO -- Use a buffer to cut down on function calls... */
- FMT_TYPE pad[1];
-
- *pad = padchar;
- while (todo && (OUTNSTR(stream, pad, 1) == 1)) {
- --todo;
- }
-
- return numpad - todo;
-}
-
-/* TODO -- Dynamically allocate work space to accomodate stack-poor archs? */
-static int _do_one_spec(FILE * __restrict stream,
- register ppfs_t *ppfs, int *count)
-{
- static const char spec_base[] = SPEC_BASE;
-#ifdef L_vfprintf
- static const char prefix[] = "+\0-\0 \0000x\0000X";
- /* 0 2 4 6 9 11*/
-#else /* L_vfprintf */
- static const wchar_t prefix[] = L"+\0-\0 \0000x\0000X";
-#endif /* L_vfprintf */
- enum {
- PREFIX_PLUS = 0,
- PREFIX_MINUS = 2,
- PREFIX_SPACE = 4,
- PREFIX_LWR_X = 6,
- PREFIX_UPR_X = 9,
- PREFIX_NONE = 11
- };
-
-#ifdef __va_arg_ptr
- const void * const *argptr;
-#else
- const void * argptr[MAX_ARGS_PER_SPEC];
-#endif
- int *argtype;
-#ifdef __UCLIBC_HAS_WCHAR__
- const wchar_t *ws = NULL;
- mbstate_t mbstate;
-#endif /* __UCLIBC_HAS_WCHAR__ */
- size_t slen;
-#ifdef L_vfprintf
-#define SLEN slen
-#else
- size_t SLEN;
- wchar_t wbuf[2];
-#endif
- int base;
- int numpad;
- int alphacase;
- int numfill = 0; /* TODO: fix */
- int prefix_num = PREFIX_NONE;
- char padchar = ' ';
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Determine appropriate buf size.
-#endif /* __UCLIBC_MJN3_ONLY__ */
- /* TODO: buf needs to be big enough for any possible error return strings
- * and also for any locale-grouped long long integer strings generated.
- * This should be large enough for any of the current archs/locales, but
- * eventually this should be handled robustly. */
- char buf[128];
-
-#ifdef NDEBUG
- _ppfs_parsespec(ppfs);
-#else
- if (_ppfs_parsespec(ppfs) < 0) { /* TODO: just for debugging */
- abort();
- }
-#endif
- _ppfs_setargs(ppfs);
-
- argtype = ppfs->argtype + ppfs->argnumber[2] - 1;
- /* Deal with the argptr vs argvalue issue. */
-#ifdef __va_arg_ptr
- argptr = (const void * const *) ppfs->argptr;
-#ifdef NL_ARGMAX
- if (ppfs->maxposarg > 0) { /* Using positional args... */
- argptr += ppfs->argnumber[2] - 1;
- }
-#endif /* NL_ARGMAX */
-#else
- /* Need to build a local copy... */
- {
- register argvalue_t *p = ppfs->argvalue;
- int i;
-#ifdef NL_ARGMAX
- if (ppfs->maxposarg > 0) { /* Using positional args... */
- p += ppfs->argnumber[2] - 1;
- }
-#endif /* NL_ARGMAX */
- for (i = 0 ; i < ppfs->num_data_args ; i++ ) {
- argptr[i] = (void *) p++;
- }
- }
-#endif
- {
- register char *s = NULL; /* TODO: Should s be unsigned char * ? */
-
- if (ppfs->conv_num == CONV_n) {
- _store_inttype(*(void **)*argptr,
- ppfs->info._flags & __PA_INTMASK,
- (intmax_t) (*count));
- return 0;
- }
- if (ppfs->conv_num <= CONV_i) { /* pointer or (un)signed int */
- alphacase = __UIM_LOWER;
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
-#warning CONSIDER: Should we ignore these flags if stub locale? What about custom specs?
-#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
- if ((base = spec_base[(int)(ppfs->conv_num - CONV_p)]) == 10) {
- if (PRINT_INFO_FLAG_VAL(&(ppfs->info),group)) {
- alphacase = __UIM_GROUP;
- }
- if (PRINT_INFO_FLAG_VAL(&(ppfs->info),i18n)) {
- alphacase |= 0x80;
- }
- }
-
- if (ppfs->conv_num <= CONV_u) { /* pointer or unsigned int */
- if (ppfs->conv_num == CONV_X) {
- alphacase = __UIM_UPPER;
- }
- if (ppfs->conv_num == CONV_p) { /* pointer */
- prefix_num = PREFIX_LWR_X;
- } else { /* unsigned int */
- }
- } else { /* signed int */
- base = -base;
- }
- if (ppfs->info.prec < 0) { /* Ignore '0' flag if prec specified. */
- padchar = ppfs->info.pad;
- }
-#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
-#warning CONSIDER: If using outdigits and/or grouping, how should we interpret precision?
-#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
- s = _uintmaxtostr(buf + sizeof(buf) - 1,
- (uintmax_t)
- _load_inttype(*argtype & __PA_INTMASK,
- *argptr, base), base, alphacase);
- if (ppfs->conv_num > CONV_u) { /* signed int */
- if (*s == '-') {
- PRINT_INFO_SET_FLAG(&(ppfs->info),showsign);
- ++s; /* handle '-' in the prefix string */
- prefix_num = PREFIX_MINUS;
- } else if (PRINT_INFO_FLAG_VAL(&(ppfs->info),showsign)) {
- prefix_num = PREFIX_PLUS;
- } else if (PRINT_INFO_FLAG_VAL(&(ppfs->info),space)) {
- prefix_num = PREFIX_SPACE;
- }
- }
- slen = (char *)(buf + sizeof(buf) - 1) - s;
-#ifdef L_vfwprintf
- {
- const char *q = s;
- mbstate.__mask = 0; /* Initialize the mbstate. */
- SLEN = mbsrtowcs(NULL, &q, 0, &mbstate);
- }
-#endif
- numfill = ((ppfs->info.prec < 0) ? 1 : ppfs->info.prec);
- if (PRINT_INFO_FLAG_VAL(&(ppfs->info),alt)) {
- if (ppfs->conv_num <= CONV_x) { /* x or p */
- prefix_num = PREFIX_LWR_X;
- }
- if (ppfs->conv_num == CONV_X) {
- prefix_num = PREFIX_UPR_X;
- }
- if ((ppfs->conv_num == CONV_o) && (numfill <= SLEN)) {
- numfill = ((*s == '0') ? 1 : SLEN + 1);
- }
- }
- if (*s == '0') {
- if (prefix_num >= PREFIX_LWR_X) {
- prefix_num = PREFIX_NONE;
- }
- if (ppfs->conv_num == CONV_p) {/* null pointer */
- s = "(nil)";
-#ifdef L_vfwprintf
- SLEN =
-#endif
- slen = 5;
- numfill = 0;
- } else if (numfill == 0) { /* if precision 0, no output */
-#ifdef L_vfwprintf
- SLEN =
-#endif
- slen = 0;
- }
- }
- numfill = ((numfill > SLEN) ? numfill - SLEN : 0);
- } else if (ppfs->conv_num <= CONV_A) { /* floating point */
-#ifdef __STDIO_PRINTF_FLOAT
- ssize_t nf;
- nf = _fpmaxtostr(stream,
- (__fpmax_t)
- (PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double)
- ? *(long double *) *argptr
- : (long double) (* (double *) *argptr)),
- &ppfs->info, FP_OUT );
- if (nf < 0) {
- return -1;
- }
- *count += nf;
-
- return 0;
-#else /* __STDIO_PRINTF_FLOAT */
- return -1; /* TODO -- try to continue? */
-#endif /* __STDIO_PRINTF_FLOAT */
- } else if (ppfs->conv_num <= CONV_S) { /* wide char or string */
-#ifdef L_vfprintf
-
-#ifdef __UCLIBC_HAS_WCHAR__
- mbstate.__mask = 0; /* Initialize the mbstate. */
- if (ppfs->conv_num == CONV_S) { /* wide string */
- if (!(ws = *((const wchar_t **) *argptr))) {
- goto NULL_STRING;
- }
- /* We use an awful uClibc-specific hack here, passing
- * (char*) &ws as the conversion destination. This signals
- * uClibc's wcsrtombs that we want a "restricted" length
- * such that the mbs fits in a buffer of the specified
- * size with no partial conversions. */
- if ((slen = wcsrtombs((char *) &ws, &ws, /* Use awful hack! */
- ((ppfs->info.prec >= 0)
- ? ppfs->info.prec
- : SIZE_MAX), &mbstate))
- == ((size_t)-1)
- ) {
- return -1; /* EILSEQ */
- }
- } else { /* wide char */
- s = buf;
- slen = wcrtomb(s, (*((const wchar_t *) *argptr)), &mbstate);
- if (slen == ((size_t)-1)) {
- return -1; /* EILSEQ */
- }
- s[slen] = 0; /* TODO - Is this necessary? */
- }
-#else /* __UCLIBC_HAS_WCHAR__ */
- return -1;
-#endif /* __UCLIBC_HAS_WCHAR__ */
- } else if (ppfs->conv_num <= CONV_s) { /* char or string */
- if (ppfs->conv_num == CONV_s) { /* string */
- s = *((char **) (*argptr));
- if (s) {
-#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
- SET_STRING_LEN:
-#endif
- slen = strnlen(s, ((ppfs->info.prec >= 0)
- ? ppfs->info.prec : SIZE_MAX));
- } else {
-#ifdef __UCLIBC_HAS_WCHAR__
- NULL_STRING:
-#endif
- s = "(null)";
- slen = 6;
- }
- } else { /* char */
- s = buf;
- *s = (unsigned char)(*((const int *) *argptr));
- s[1] = 0;
- slen = 1;
- }
-
-#else /* L_vfprintf */
-
- if (ppfs->conv_num == CONV_S) { /* wide string */
- ws = *((wchar_t **) (*argptr));
- if (!ws) {
- goto NULL_STRING;
- }
- SLEN = wcsnlen(ws, ((ppfs->info.prec >= 0)
- ? ppfs->info.prec : SIZE_MAX));
- } else { /* wide char */
- *wbuf = (wchar_t)(*((const wint_t *) *argptr));
- CHAR_CASE:
- ws = wbuf;
- wbuf[1] = 0;
- SLEN = 1;
- }
-
- } else if (ppfs->conv_num <= CONV_s) { /* char or string */
-
- if (ppfs->conv_num == CONV_s) { /* string */
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Fix %s for vfwprintf... output upto illegal sequence?
-#endif /* __UCLIBC_MJN3_ONLY__ */
- s = *((char **) (*argptr));
- if (s) {
-#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
- SET_STRING_LEN:
-#endif
- /* We use an awful uClibc-specific hack here, passing
- * (wchar_t*) &mbstate as the conversion destination.
- * This signals uClibc's mbsrtowcs that we want a
- * "restricted" length such that the mbs fits in a buffer
- * of the specified size with no partial conversions. */
- {
- const char *q = s;
- mbstate.__mask = 0; /* Initialize the mbstate. */
- SLEN = mbsrtowcs((wchar_t *) &mbstate, &q,
- ((ppfs->info.prec >= 0)
- ? ppfs->info.prec : SIZE_MAX),
- &mbstate);
- }
- if (SLEN == ((size_t)(-1))) {
- return -1; /* EILSEQ */
- }
- } else {
- NULL_STRING:
- s = "(null)";
- SLEN = slen = 6;
- }
- } else { /* char */
- *wbuf = btowc( (unsigned char)(*((const int *) *argptr)) );
- goto CHAR_CASE;
- }
-
-#endif /* L_vfprintf */
-
-#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
- } else if (ppfs->conv_num == CONV_m) {
- s = __glibc_strerror_r_internal(errno, buf, sizeof(buf));
- goto SET_STRING_LEN;
-#endif
- } else {
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__
- assert(ppfs->conv_num == CONV_custom0);
-
- s = _custom_printf_spec;
- do {
- if (*s == ppfs->info.spec) {
- int rv;
- /* TODO -- check return value for sanity? */
- rv = (*_custom_printf_handler
- [(int)(s-_custom_printf_spec)])
- (stream, &ppfs->info, argptr);
- if (rv < 0) {
- return -1;
- }
- *count += rv;
- return 0;
- }
- } while (++s < (_custom_printf_spec + MAX_USER_SPEC));
-#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
- assert(0);
- return -1;
- }
-
-#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
-#warning CONSIDER: If using outdigits and/or grouping, how should we pad?
-#endif
-#endif /* __UCLIBC_MJN3_ONLY__ */
- {
- size_t t;
-
- t = SLEN + numfill;
- if (prefix_num != PREFIX_NONE) {
- t += ((prefix_num < PREFIX_LWR_X) ? 1 : 2);
- }
- numpad = ((ppfs->info.width > t) ? (ppfs->info.width - t) : 0);
- *count += t + numpad;
- }
- if (padchar == '0') { /* TODO: check this */
- numfill += numpad;
- numpad = 0;
- }
-
- /* Now handle the output itself. */
- if (!PRINT_INFO_FLAG_VAL(&(ppfs->info),left)) {
- if (_charpad(stream, ' ', numpad) != numpad) {
- return -1;
- }
- numpad = 0;
- }
- OUTPUT(stream, prefix + prefix_num);
- if (_charpad(stream, '0', numfill) != numfill) {
- return -1;
- }
-
-#ifdef L_vfprintf
-
-#ifdef __UCLIBC_HAS_WCHAR__
- if (!ws) {
- assert(s);
- if (_outnstr(stream, s, slen) != slen) {
- return -1;
- }
- } else { /* wide string */
- size_t t;
- mbstate.__mask = 0; /* Initialize the mbstate. */
- while (slen) {
- t = (slen <= sizeof(buf)) ? slen : sizeof(buf);
- t = wcsrtombs(buf, &ws, t, &mbstate);
- assert (t != ((size_t)(-1)));
- if (_outnstr(stream, buf, t) != t) {
- return -1;
- }
- slen -= t;
- }
- }
-#else /* __UCLIBC_HAS_WCHAR__ */
- if (_outnstr(stream, s, slen) != slen) {
- return -1;
- }
-#endif /* __UCLIBC_HAS_WCHAR__ */
-
-#else /* L_vfprintf */
-
- if (!ws) {
- assert(s);
- if (_outnstr(stream, s, SLEN) != SLEN) {
- return -1;
- }
- } else {
- if (_outnwcs(stream, ws, SLEN) != SLEN) {
- return -1;
- }
- }
-
-#endif /* L_vfprintf */
- if (_charpad(stream, ' ', numpad) != numpad) {
- return -1;
- }
- }
-
- return 0;
-}
-
-int attribute_hidden HIDDEN_VFPRINTF (FILE * __restrict stream,
- register const FMT_TYPE * __restrict format,
- va_list arg)
-{
- ppfs_t ppfs;
- int count, r;
- register const FMT_TYPE *s;
- __STDIO_AUTO_THREADLOCK_VAR;
-
- __STDIO_AUTO_THREADLOCK(stream);
-
- count = 0;
- s = format;
-
- if
-#ifdef L_vfprintf
- (!__STDIO_STREAM_IS_NARROW_WRITING(stream)
- && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
-#else
- (!__STDIO_STREAM_IS_WIDE_WRITING(stream)
- && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
-#endif
- {
- count = -1;
- } else if (_PPFS_init(&ppfs, format) < 0) { /* Bad format string. */
- OUTNSTR(stream, (const FMT_TYPE *) ppfs.fmtpos,
- STRLEN((const FMT_TYPE *)(ppfs.fmtpos)));
-#if defined(L_vfprintf) && !defined(NDEBUG)
- fprintf(stderr,"\nIMbS: \"%s\"\n\n", format);
-#endif
- count = -1;
- } else {
- _ppfs_prepargs(&ppfs, arg); /* This did a va_copy!!! */
-
- do {
- while (*format && (*format != '%')) {
- ++format;
- }
-
- if (format-s) { /* output any literal text in format string */
- if ( (r = OUTNSTR(stream, s, format-s)) != (format-s)) {
- count = -1;
- break;
- }
- count += r;
- }
-
- if (!*format) { /* we're done */
- break;
- }
-
- if (format[1] != '%') { /* if we get here, *format == '%' */
- /* TODO: _do_one_spec needs to know what the output funcs are!!! */
- ppfs.fmtpos = (const char *)(++format);
- /* TODO: check -- should only fail on stream error */
- if ( (r = _do_one_spec(stream, &ppfs, &count)) < 0) {
- count = -1;
- break;
- }
- s = format = (const FMT_TYPE *) ppfs.fmtpos;
- } else { /* %% means literal %, so start new string */
- s = ++format;
- ++format;
- }
- } while (1);
-
- va_end(ppfs.arg); /* Need to clean up after va_copy! */
- }
-
-/* #if defined(L_vfprintf) && defined(__UCLIBC_HAS_WCHAR__) */
-/* DONE: */
-/* #endif */
-
- __STDIO_AUTO_THREADUNLOCK(stream);
-
- return count;
-}
-strong_alias(HIDDEN_VFPRINTF,VFPRINTF)
-#endif
-/**********************************************************************/
+#define L_vfprintf
+#include "_vfprintf.c"
diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.c
new file mode 100644
index 000000000..b13ff8db8
--- /dev/null
+++ b/libc/stdio/vfscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vfscanf
+#include "_scanf.c"
diff --git a/libc/stdio/vfwprintf.c b/libc/stdio/vfwprintf.c
new file mode 100644
index 000000000..323b90015
--- /dev/null
+++ b/libc/stdio/vfwprintf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vfwprintf
+#include "_vfprintf.c"
diff --git a/libc/stdio/vfwscanf.c b/libc/stdio/vfwscanf.c
new file mode 100644
index 000000000..ac982b4f1
--- /dev/null
+++ b/libc/stdio/vfwscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vfwscanf
+#include "_scanf.c"
diff --git a/libc/stdio/vprintf.c b/libc/stdio/vprintf.c
index 9c0e07514..7848a078d 100644
--- a/libc/stdio/vprintf.c
+++ b/libc/stdio/vprintf.c
@@ -8,7 +8,9 @@
#include "_stdio.h"
#include <stdarg.h>
+libc_hidden_proto(vfprintf)
+
int vprintf(const char * __restrict format, va_list arg)
{
- return __vfprintf(stdout, format, arg);
+ return vfprintf(stdout, format, arg);
}
diff --git a/libc/stdio/vscanf.c b/libc/stdio/vscanf.c
new file mode 100644
index 000000000..834fe92ee
--- /dev/null
+++ b/libc/stdio/vscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vscanf
+#include "_scanf.c"
diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c
index c926b2ad7..ab6154848 100644
--- a/libc/stdio/vsnprintf.c
+++ b/libc/stdio/vsnprintf.c
@@ -8,13 +8,17 @@
#include "_stdio.h"
#include <stdarg.h>
+libc_hidden_proto(vsnprintf)
+
+libc_hidden_proto(vfprintf)
+
#ifdef __UCLIBC_MJN3_ONLY__
#warning WISHLIST: Implement vsnprintf for non-buffered and no custom stream case.
#endif /* __UCLIBC_MJN3_ONLY__ */
#ifdef __STDIO_BUFFERS
-int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
+int vsnprintf(char *__restrict buf, size_t size,
const char * __restrict format, va_list arg)
{
FILE f;
@@ -61,7 +65,7 @@ int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
__STDIO_STREAM_DISABLE_GETC(&f);
__STDIO_STREAM_ENABLE_PUTC(&f);
- rv = __vfprintf(&f, format, arg);
+ rv = vfprintf(&f, format, arg);
if (size) {
if (f.__bufpos == f.__bufend) {
--f.__bufpos;
@@ -70,7 +74,7 @@ int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
}
return rv;
}
-strong_alias(__vsnprintf,vsnprintf)
+libc_hidden_def(vsnprintf)
#elif defined(__USE_OLD_VFPRINTF__)
@@ -80,7 +84,7 @@ typedef struct {
unsigned char *bufpos;
} __FILE_vsnprintf;
-int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
+int vsnprintf(char *__restrict buf, size_t size,
const char * __restrict format, va_list arg)
{
__FILE_vsnprintf f;
@@ -122,7 +126,7 @@ int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
#endif
f.f.__nextopen = NULL;
- rv = __vfprintf((FILE *) &f, format, arg);
+ rv = vfprintf((FILE *) &f, format, arg);
if (size) {
if (f.bufpos == f.bufend) {
--f.bufpos;
@@ -131,7 +135,7 @@ int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
}
return rv;
}
-strong_alias(__vsnprintf,vsnprintf)
+libc_hidden_def(vsnprintf)
#elif defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
@@ -173,7 +177,7 @@ static ssize_t snpf_write(register void *cookie, const char *buf,
#undef COOKIE
-int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
+int vsnprintf(char *__restrict buf, size_t size,
const char * __restrict format, va_list arg)
{
FILE f;
@@ -211,11 +215,11 @@ int attribute_hidden __vsnprintf(char *__restrict buf, size_t size,
#endif
f.__nextopen = NULL;
- rv = __vfprintf(&f, format, arg);
+ rv = vfprintf(&f, format, arg);
return rv;
}
-strong_alias(__vsnprintf,vsnprintf)
+libc_hidden_def(vsnprintf)
#else
#warning Skipping vsnprintf since no buffering, no custom streams, and not old vfprintf!
diff --git a/libc/stdio/vsprintf.c b/libc/stdio/vsprintf.c
index a7d5e08f5..8e27c19d9 100644
--- a/libc/stdio/vsprintf.c
+++ b/libc/stdio/vsprintf.c
@@ -12,10 +12,12 @@
#warning Skipping vsprintf since no vsnprintf!
#else
+libc_hidden_proto(vsnprintf)
+
int vsprintf(char *__restrict buf, const char * __restrict format,
va_list arg)
{
- return __vsnprintf(buf, SIZE_MAX, format, arg);
+ return vsnprintf(buf, SIZE_MAX, format, arg);
}
#endif
diff --git a/libc/stdio/vsscanf.c b/libc/stdio/vsscanf.c
new file mode 100644
index 000000000..882c2713e
--- /dev/null
+++ b/libc/stdio/vsscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vsscanf
+#include "_scanf.c"
diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c
index c9e73cf87..d95de51a2 100644
--- a/libc/stdio/vswprintf.c
+++ b/libc/stdio/vswprintf.c
@@ -9,11 +9,15 @@
#include <stdarg.h>
#include <wchar.h>
+libc_hidden_proto(vswprintf)
+
+libc_hidden_proto(vfwprintf)
+
#ifndef __STDIO_BUFFERS
#warning Skipping vswprintf since no buffering!
#else /* __STDIO_BUFFERS */
-int attribute_hidden __vswprintf(wchar_t *__restrict buf, size_t size,
+int vswprintf(wchar_t *__restrict buf, size_t size,
const wchar_t * __restrict format, va_list arg)
{
FILE f;
@@ -56,7 +60,7 @@ int attribute_hidden __vswprintf(wchar_t *__restrict buf, size_t size,
__STDIO_STREAM_DISABLE_GETC(&f);
__STDIO_STREAM_DISABLE_PUTC(&f);
- rv = __vfwprintf(&f, format, arg);
+ rv = vfwprintf(&f, format, arg);
/* NOTE: Return behaviour differs from snprintf... */
if (f.__bufpos == f.__bufend) {
@@ -70,6 +74,6 @@ int attribute_hidden __vswprintf(wchar_t *__restrict buf, size_t size,
}
return rv;
}
-strong_alias(__vswprintf,vswprintf)
+libc_hidden_def(vswprintf)
#endif /* __STDIO_BUFFERS */
diff --git a/libc/stdio/vswscanf.c b/libc/stdio/vswscanf.c
new file mode 100644
index 000000000..fddb60209
--- /dev/null
+++ b/libc/stdio/vswscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vswscanf
+#include "_scanf.c"
diff --git a/libc/stdio/vwprintf.c b/libc/stdio/vwprintf.c
index 8c3401846..1c32887a4 100644
--- a/libc/stdio/vwprintf.c
+++ b/libc/stdio/vwprintf.c
@@ -9,7 +9,9 @@
#include <stdarg.h>
#include <wchar.h>
+libc_hidden_proto(vfwprintf)
+
int vwprintf(const wchar_t * __restrict format, va_list arg)
{
- return __vfwprintf(stdout, format, arg);
+ return vfwprintf(stdout, format, arg);
}
diff --git a/libc/stdio/vwscanf.c b/libc/stdio/vwscanf.c
new file mode 100644
index 000000000..9e21a271e
--- /dev/null
+++ b/libc/stdio/vwscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_vwscanf
+#include "_scanf.c"
diff --git a/libc/stdio/wprintf.c b/libc/stdio/wprintf.c
index 00f5ef514..9dc274aec 100644
--- a/libc/stdio/wprintf.c
+++ b/libc/stdio/wprintf.c
@@ -9,13 +9,15 @@
#include <stdarg.h>
#include <wchar.h>
+libc_hidden_proto(vfwprintf)
+
int wprintf(const wchar_t * __restrict format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
- rv = __vfwprintf(stdout, format, arg);
+ rv = vfwprintf(stdout, format, arg);
va_end(arg);
return rv;
diff --git a/libc/stdio/wscanf.c b/libc/stdio/wscanf.c
new file mode 100644
index 000000000..d354d527f
--- /dev/null
+++ b/libc/stdio/wscanf.c
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L_wscanf
+#include "_scanf.c"