diff options
Diffstat (limited to 'libc/stdio')
85 files changed, 706 insertions, 1053 deletions
diff --git a/libc/stdio/Makefile.in b/libc/stdio/Makefile.in index 74f6d9aed..7d697bf82 100644 --- a/libc/stdio/Makefile.in +++ b/libc/stdio/Makefile.in @@ -1,107 +1,100 @@ # Makefile for uClibc # # Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> -# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2008 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. # +subdirs += libc/stdio + # SUSv3 functions -CSRC := \ +CSRC-y := \ fclose.c fcloseall.c fdopen.c fgetpos.c fopen.c freopen.c \ fseeko.c fsetpos.c ftello.c getdelim.c getline.c gets.c getw.c \ perror.c puts.c putw.c remove.c rewind.c setbuf.c setbuffer.c \ setlinebuf.c setvbuf.c ungetc.c \ printf.c vprintf.c vsprintf.c fprintf.c snprintf.c dprintf.c \ asprintf.c sprintf.c vasprintf.c vdprintf.c vsnprintf.c \ - tmpfile.c tmpnam.c tmpnam_r.c popen.c tempnam.c ctermid.c - -ifeq ($(UCLIBC_HAS_LFS),y) -CSRC += fgetpos64.c fopen64.c freopen64.c fseeko64.c fsetpos64.c ftello64.c -endif + tmpfile.c popen.c ctermid.c +CSRC-$(UCLIBC_HAS_LFS) += fgetpos64.c fopen64.c freopen64.c \ + fseeko64.c fsetpos64.c ftello64.c +CSRC-$(UCLIBC_SUSV4_LEGACY) += tmpnam.c tmpnam_r.c tempnam.c -# getc -> alias for fgetc -# putc -> alias for fputc -# rename is a syscall - -# Implementation support functions -CSRC += \ +# internal support functions +CSRC-y += \ _READ.c _WRITE.c _adjust_pos.c _fopen.c _fwrite.c \ _rfill.c _stdio.c _trans2r.c _trans2w.c _wcommit.c \ _cs_funcs.c _load_inttype.c _store_inttype.c _uintmaxtostr.c -ifeq ($(UCLIBC_HAS_FLOATS),y) -CSRC += _fpmaxtostr.c -endif +CSRC-$(UCLIBC_HAS_FLOATS) += _fpmaxtostr.c # stdio_ext.h functions -CSRC += \ +CSRC-y += \ __fbufsize.c __flbf.c __fpending.c __fpurge.c __freadable.c \ __freading.c __fsetlocking.c __fwritable.c __fwriting.c _flushlbf.c # Other glibc extensions -ifeq ($(UCLIBC_HAS_GLIBC_CUSTOM_STREAMS),y) -CSRC += fopencookie.c fmemopen.c open_memstream.c -endif +CSRC-$(UCLIBC_HAS_GLIBC_CUSTOM_STREAMS) += fopencookie.c fmemopen.c \ + open_memstream.c # pthread functions -CSRC += flockfile.c ftrylockfile.c funlockfile.c +CSRC-y += flockfile.c ftrylockfile.c funlockfile.c # Functions with unlocked versions -CUSRC := \ +CUSRC-y := \ clearerr.c feof.c ferror.c fflush.c fgetc.c fgets.c fileno.c \ fputc.c fputs.c fread.c fwrite.c getchar.c putchar.c # getc_unlocked -> alias for fgetc_unlocked # putc_unlocked -> alias for fputc_unlocked # vfprintf and support functions -ifneq ($(USE_OLD_VFPRINTF),y) +ifeq ($(USE_OLD_VFPRINTF),y) +VF_CSRC := old_vfprintf.c +else +# multi source _vfprintf.c VF_CSRC := \ vfprintf.c \ _vfprintf_internal.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 -CSRC += old_vfprintf.c endif +CSRC-y += $(VF_CSRC) # vfscanf and support functions plus other *scanf funcs -CSRC += \ +CSRC-y += \ vfscanf.c __scan_cookie.c __psfs_parse_spec.c __psfs_do_numeric.c \ scanf.c sscanf.c fscanf.c vscanf.c vsscanf.c -ifeq ($(UCLIBC_HAS_WCHAR),y) -CSRC += _wfwrite.c fwprintf.c swprintf.c vswprintf.c vwprintf.c wprintf.c \ +CSRC-$(UCLIBC_HAS_WCHAR) += \ + _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 +CUSRC-$(UCLIBC_HAS_WCHAR) += \ + 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) -CSRC += vfwprintf.c _vfwprintf_internal.c -CSRC += wscanf.c swscanf.c fwscanf.c vwscanf.c vswscanf.c vfwscanf.c -endif - -CUSRC_UNLOCKED := $(patsubst %.c,%_unlocked.c,$(CUSRC)) +CSRC-$(UCLIBC_HAS_WCHAR) += vfwprintf.c _vfwprintf_internal.c \ + wscanf.c swscanf.c fwscanf.c vwscanf.c vswscanf.c vfwscanf.c -CSRC += $(CUSRC) $(CUSRC_UNLOCKED) +CUSRC_UNLOCKED := $(patsubst %.c,%_unlocked.c,$(CUSRC-y)) +CSRC-y += $(CUSRC-y) $(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_SRC := $(patsubst %.c,$(STDIO_DIR)/%.c,$(CSRC-y)) +STDIO_OBJ := $(patsubst %.c,$(STDIO_OUT)/%.o,$(CSRC-y)) libc-y += $(STDIO_OBJ) 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 +libc-nomulti-$(UCLIBC_HAS_WCHAR) += $(STDIO_OUT)/vfwprintf.o \ + $(STDIO_OUT)/vfwscanf.o -objclean-y += stdio_objclean +objclean-y += CLEAN_libc/stdio -stdio_objclean: - $(RM) $(STDIO_OUT)/*.{o,os,oS} +CLEAN_libc/stdio: + $(do_rm) $(addprefix $(STDIO_OUT)/*., o os oS) diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c index bafa8dffe..a548dbb3f 100644 --- a/libc/stdio/_READ.c +++ b/libc/stdio/_READ.c @@ -7,8 +7,6 @@ #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 @@ -29,7 +27,7 @@ size_t attribute_hidden __stdio_READ(register FILE *stream, ssize_t rv = 0; __STDIO_STREAM_VALIDATE(stream); - assert(stream->__filedes >= -1); + assert(stream->__filedes >= -2); assert(__STDIO_STREAM_IS_READING(stream)); assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */ assert(!(stream->__modeflags & __FLAG_UNGOT)); diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c index 83714bd4c..712236f8f 100644 --- a/libc/stdio/_WRITE.c +++ b/libc/stdio/_WRITE.c @@ -7,7 +7,6 @@ #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 @@ -37,19 +36,16 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream, ssize_t rv, stodo; __STDIO_STREAM_VALIDATE(stream); - assert(stream->__filedes >= -1); + assert(stream->__filedes >= -2); assert(__STDIO_STREAM_IS_WRITING(stream)); assert(!__STDIO_STREAM_BUFFER_WUSED(stream)); /* Buffer must be empty. */ todo = bufsize; - do { - if (todo == 0) { /* Done? */ - __STDIO_STREAM_VALIDATE(stream); - return bufsize; - } + while (todo != 0) { stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX; - if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) { + rv = __WRITE(stream, (char *) buf, stodo); + if (rv >= 0) { #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Make custom stream write return check optional. #endif @@ -61,26 +57,44 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream, #endif todo -= rv; buf += rv; - } else -#ifdef __UCLIBC_MJN3_ONLY__ -#warning EINTR? -#endif -/* if (errno != EINTR) */ - { + } else { + __STDIO_STREAM_SET_ERROR(stream); + /* We buffer data on "transient" errors, but discard it + * on "hard" ones. Example of a hard error: + * + * close(fileno(stdout)); + * printf("Hi there 1\n"); // EBADF + * dup2(good_fd, fileno(stdout)); + * printf("Hi there 2\n"); // buffers new data + * + * This program should not print "Hi there 1" to good_fd. + * The rationale is that the caller of writing operation + * should check for error and act on it. + * If he didn't, then future users of the stream + * have no idea what to do. + * It's least confusing to at least not burden them with + * some hidden buffered crap in the buffer. + */ + if (errno != EINTR && errno != EAGAIN) { + /* do we have other "soft" errors? */ + break; + } #ifdef __STDIO_BUFFERS - if ((stodo = __STDIO_STREAM_BUFFER_SIZE(stream)) != 0) { + stodo = __STDIO_STREAM_BUFFER_SIZE(stream); + if (stodo != 0) { unsigned char *s; if (stodo > todo) { stodo = todo; } - s = stream->__bufstart; + s = stream->__bufstart; do { - if (((*s = *buf) == '\n') + *s = *buf; + if ((*s == '\n') && __STDIO_STREAM_IS_LBF(stream) ) { break; @@ -95,8 +109,11 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream, } #endif /* __STDIO_BUFFERS */ - __STDIO_STREAM_VALIDATE(stream); - return bufsize - todo; + bufsize -= todo; + break; } - } while (1); + } + + __STDIO_STREAM_VALIDATE(stream); + return bufsize; } diff --git a/libc/stdio/__fpending.c b/libc/stdio/__fpending.c index a7fe05463..e7e33e80a 100644 --- a/libc/stdio/__fpending.c +++ b/libc/stdio/__fpending.c @@ -18,13 +18,6 @@ * convert wide chars to their multibyte encodings and buffer _those_. */ -#ifdef __UCLIBC_HAS_WCHAR__ -#warning Note: Unlike the glibc version, this __fpending returns bytes in buffer for wide streams too! - -link_warning(__fpending, "This version of __fpending returns bytes remaining in buffer for both narrow and wide streams. glibc's version returns wide chars in buffer for the wide stream case.") - -#endif - size_t __fpending(register FILE * __restrict stream) { __STDIO_STREAM_VALIDATE(stream); diff --git a/libc/stdio/__fsetlocking.c b/libc/stdio/__fsetlocking.c index 2e8710076..6d4fc18b8 100644 --- a/libc/stdio/__fsetlocking.c +++ b/libc/stdio/__fsetlocking.c @@ -8,7 +8,6 @@ #include "_stdio.h" #include <stdio_ext.h> -libc_hidden_proto(__fsetlocking) /* Not threadsafe. */ diff --git a/libc/stdio/_cs_funcs.c b/libc/stdio/_cs_funcs.c index 38a8351e5..be416a450 100644 --- a/libc/stdio/_cs_funcs.c +++ b/libc/stdio/_cs_funcs.c @@ -7,55 +7,6 @@ #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); -} - -/**********************************************************************/ - -ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize) -{ - return write(*((int *) cookie), (char *) buf, bufsize); -} - -/**********************************************************************/ - -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); -#else - res = lseek(*((int *) cookie), *pos, whence); -#endif - - return (res >= 0) ? ((*pos = res), 0) : ((int) res); -} - -/**********************************************************************/ - -int attribute_hidden _cs_close(void *cookie) -{ - return close(*((int *) cookie)); -} - -/**********************************************************************/ -#else /**********************************************************************/ int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) @@ -72,5 +23,3 @@ int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t *pos, int wh } /**********************************************************************/ -#endif -/**********************************************************************/ diff --git a/libc/stdio/_flushlbf.c b/libc/stdio/_flushlbf.c index 8a551a746..c322c3e33 100644 --- a/libc/stdio/_flushlbf.c +++ b/libc/stdio/_flushlbf.c @@ -8,7 +8,6 @@ #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 5243e33f7..be05c48a5 100644 --- a/libc/stdio/_fopen.c +++ b/libc/stdio/_fopen.c @@ -7,9 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(isatty) -libc_hidden_proto(open) -libc_hidden_proto(fcntl) /* * Cases: @@ -72,7 +69,8 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode, #warning CONSIDER: Implement glibc mmap option for readonly files? #warning CONSIDER: Implement a text mode using custom read/write funcs? #endif -#if defined(__UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE__) || defined(__UCLIBC_HAS_FOPEN_LARGEFILE_MODE__) +#if defined(__UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE__) || defined(__UCLIBC_HAS_FOPEN_LARGEFILE_MODE__) || \ + defined(__UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE__) while (*++mode) { # ifdef __UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE__ @@ -87,6 +85,12 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode, continue; } # endif +# ifdef __UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE__ + if (*mode == 'e') { /* Close on exec (a glibc extension). */ + open_mode |= O_CLOEXEC; + continue; + } +# endif } #endif @@ -102,7 +106,7 @@ 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; */ - __stdio_init_mutex(&stream->__lock); + STDIO_INIT_MUTEX(stream->__lock); #endif } @@ -121,11 +125,11 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode, i = (open_mode & (O_ACCMODE|O_LARGEFILE)) + 1; /* 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. */ - ) { + if ((i & ((int)fname_or_mode + 1)) != i) /* Basic agreement? */ goto DO_EINVAL; + if ((open_mode & ~(__mode_t)fname_or_mode) & O_APPEND) { + if (fcntl(filedes, F_SETFL, O_APPEND)) /* Need O_APPEND. */ + goto DO_EINVAL; } /* For later... to reflect largefile setting in stream flags. */ __STDIO_WHEN_LFS( open_mode |= (((__mode_t) fname_or_mode) @@ -159,9 +163,15 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode, ((((open_mode & O_ACCMODE) + 1) ^ 0x03) * __FLAG_WRITEONLY); #ifdef __STDIO_BUFFERS - i = errno; /* Preserve errno against isatty call. */ - stream->__modeflags |= (isatty(stream->__filedes) * __FLAG_LBF); - __set_errno(i); + if (stream->__filedes != INT_MAX) { + /* NB: fopencookie uses bogus filedes == INT_MAX, + * avoiding isatty() in that case. + */ + i = errno; /* preserve errno against isatty call. */ + if (isatty(stream->__filedes)) + stream->__modeflags |= __FLAG_LBF; + __set_errno(i); + } if (!stream->__bufstart) { if ((stream->__bufstart = malloc(BUFSIZ)) != NULL) { @@ -182,8 +192,6 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode, __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); #endif - __STDIO_STREAM_RESET_GCS(stream); - #ifdef __UCLIBC_HAS_WCHAR__ stream->__ungot_width[0] = 0; #endif @@ -194,7 +202,7 @@ 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; - /* __stdio_init_mutex(&stream->__lock); */ + /* STDIO_INIT_MUTEX(stream->__lock); */ #endif #ifdef __STDIO_HAS_OPENLIST diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c index b8d93a091..35805844a 100644 --- a/libc/stdio/_fpmaxtostr.c +++ b/libc/stdio/_fpmaxtostr.c @@ -1,6 +1,7 @@ -/* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org> +/* + * Copyright (C) 2000,2001,2003,2004 Manuel Novoa III <mjn3@codepoet.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. */ @@ -9,16 +10,9 @@ #include <printf.h> #include <float.h> #include <locale.h> -#include <bits/uClibc_fpmax.h> +#include "_fpmaxtostr.h" -/* Experimentally off - libc_hidden_proto(memset) */ - -typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, - intptr_t buf); - - -/* Copyright (C) 2000, 2001, 2003 Manuel Novoa III - * +/* * Function: * * ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, @@ -41,7 +35,6 @@ typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, * It should also be fairly portable, as no assumptions are made about the * bit-layout of doubles. Of course, that does make it less efficient than * it could be. - * */ /*****************************************************************************/ @@ -52,11 +45,6 @@ typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, */ #define isnan(x) ((x) != (x)) -/* Without seminumerical functions to examine the sign bit, this is - * about the best we can do to test for '-0'. - */ -#define zeroisnegative(x) ((1./(x)) < 0) - /*****************************************************************************/ /* Don't change anything that follows peroid!!! ;-) */ /*****************************************************************************/ @@ -68,9 +56,6 @@ typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, #define NUM_HEX_DIGITS ((FPMAX_MANT_DIG + 3)/ 4) -/* WARNING: Adjust _fp_out_wide() below if this changes! */ -/* With 32 bit ints, we can get 9 decimal digits per block. */ -#define DIGITS_PER_BLOCK 9 #define HEX_DIGITS_PER_BLOCK 8 /* Maximum number of subcases to output double is... @@ -88,15 +73,9 @@ typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, /*****************************************************************************/ -#define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK) #define NUM_HEX_DIGIT_BLOCKS \ ((NUM_HEX_DIGITS+HEX_DIGITS_PER_BLOCK-1)/HEX_DIGITS_PER_BLOCK) -/* WARNING: Adjust _fp_out_wide() below if this changes! */ - -/* extra space for '-', '.', 'e+###', and nul */ -#define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK ) - /*****************************************************************************/ static const char fmt[] = "inf\0INF\0nan\0NAN\0.\0,"; @@ -201,8 +180,6 @@ static const __fpmax_t exp16_table[] = { #define FPO_STR_PREC 'p' 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__ @@ -220,8 +197,8 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, #ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ int num_groups = 0; int initial_group; /* This does not need to be initialized. */ - int tslen; /* This does not need to be initialized. */ - int nblk2; /* This does not need to be initialized. */ + int tslen; /* This does not need to be initialized. */ + int nblk2; /* This does not need to be initialized. */ const char *ts; /* This does not need to be initialized. */ #endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */ int round, o_exp; @@ -280,7 +257,13 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, if (x == 0) { /* Handle 0 now to avoid false positive. */ #ifdef __UCLIBC_HAVE_SIGNED_ZERO__ - if (zeroisnegative(x)) { /* Handle 'signed' zero. */ + union { + double x; + struct { + unsigned int l1, l2; + } i; + } u = {x}; + if (u.i.l1 ^ u.i.l2) { /* Handle 'signed' zero. */ *sign_str = '-'; } #endif /* __UCLIBC_HAVE_SIGNED_ZERO__ */ @@ -501,8 +484,8 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, const char *p; if (PRINT_INFO_FLAG_VAL(info,group) - && *(p = __UCLIBC_CURLOCALE_DATA.grouping) - ) { + && *(p = __UCLIBC_CURLOCALE->grouping) + ) { int nblk1; nblk2 = nblk1 = *p; @@ -522,8 +505,8 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, tslen = 1; } else { #endif /* __UCLIBC_HAS_WCHAR__ */ - ts = __UCLIBC_CURLOCALE_DATA.thousands_sep; - tslen = __UCLIBC_CURLOCALE_DATA.thousands_sep_len; + ts = __UCLIBC_CURLOCALE->thousands_sep; + tslen = __UCLIBC_CURLOCALE->thousands_sep_len; #ifdef __UCLIBC_HAS_WCHAR__ } #endif /* __UCLIBC_HAS_WCHAR__ */ @@ -576,8 +559,8 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, ppc[2] = (intptr_t)(fmt + DECPT_OFFSET); } else { #endif /* __UCLIBC_HAS_WCHAR__ */ - ppc[1] = __UCLIBC_CURLOCALE_DATA.decimal_point_len; - ppc[2] = (intptr_t)(__UCLIBC_CURLOCALE_DATA.decimal_point); + ppc[1] = __UCLIBC_CURLOCALE->decimal_point_len; + ppc[2] = (intptr_t)(__UCLIBC_CURLOCALE->decimal_point); #ifdef __UCLIBC_HAS_WCHAR__ } #endif /* __UCLIBC_HAS_WCHAR__ */ diff --git a/libc/stdio/_fpmaxtostr.h b/libc/stdio/_fpmaxtostr.h new file mode 100644 index 000000000..7694629ec --- /dev/null +++ b/libc/stdio/_fpmaxtostr.h @@ -0,0 +1,49 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2000,2001,2003,2004 Manuel Novoa III <mjn3@codepoet.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + * + * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. + */ + +#ifndef _FPMAXTOSTR_H +#define _FPMAXTOSTR_H 1 + +#include <features.h> +#define __need_size_t +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <printf.h> +#include <sys/types.h> + +#ifdef __UCLIBC_HAS_FLOATS__ +# include <float.h> +# include <bits/uClibc_fpmax.h> + +/* WARNING: Adjust _fp_out_wide() in _vfprintf.c if this changes! */ +/* With 32 bit ints, we can get 9 decimal digits per block. */ +# define DIGITS_PER_BLOCK 9 + +# define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK) + +/* WARNING: Adjust _fp_out_wide() in _vfprintf.c if this changes! */ +/* extra space for '-', '.', 'e+###', and nul */ +# define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK ) + +/* psm: why do these internals differ? */ +# ifdef __USE_OLD_VFPRINTF__ +typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, intptr_t buf); + +extern size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, + __fp_outfunc_t fp_outfunc) attribute_hidden; +# else +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 + +# endif /* __UCLIBC_HAS_FLOATS__ */ +#endif /* _FPMAXTOSTR_H */ diff --git a/libc/stdio/_fwrite.c b/libc/stdio/_fwrite.c index ba4b02fb1..47860afbf 100644 --- a/libc/stdio/_fwrite.c +++ b/libc/stdio/_fwrite.c @@ -7,9 +7,6 @@ #include "_stdio.h" -/* Experimentally off - libc_hidden_proto(memchr) */ -/* Experimentally off - libc_hidden_proto(memcpy) */ -/* Experimentally off - libc_hidden_proto(memrchr) */ #ifdef __STDIO_BUFFERS diff --git a/libc/stdio/_load_inttype.c b/libc/stdio/_load_inttype.c index 057f5f256..8c0a60abe 100644 --- a/libc/stdio/_load_inttype.c +++ b/libc/stdio/_load_inttype.c @@ -8,7 +8,6 @@ #include "_stdio.h" #include <printf.h> -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 */ @@ -57,7 +56,7 @@ uintmax_t _load_inttype(int desttype, register const void *src, int uflag) { int x; x = *((int *) src); - if (desttype == __PA_FLAG_CHAR) x = (char) x; + if (desttype == __PA_FLAG_CHAR) x = (signed char) x; #if SHRT_MAX != INT_MAX if (desttype == PA_FLAG_SHORT) x = (short int) x; #endif diff --git a/libc/stdio/_rfill.c b/libc/stdio/_rfill.c index d61b1a9f9..e9d2fa698 100644 --- a/libc/stdio/_rfill.c +++ b/libc/stdio/_rfill.c @@ -24,7 +24,7 @@ size_t attribute_hidden __stdio_rfill(register FILE *__restrict stream) size_t rv; __STDIO_STREAM_VALIDATE(stream); - assert(stream->__filedes >= -1); + assert(stream->__filedes >= -2); assert(__STDIO_STREAM_IS_READING(stream)); assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */ assert(__STDIO_STREAM_BUFFER_SIZE(stream)); /* Must have a buffer. */ diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c index 3b004d5f0..80e49567f 100644 --- a/libc/stdio/_scanf.c +++ b/libc/stdio/_scanf.c @@ -11,8 +11,8 @@ * 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. + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. */ /* Aug 1, 2003 @@ -43,7 +43,6 @@ * standards and from an official C standard defect report. */ -#define _ISOC99_SOURCE /* for LLONG_MAX primarily... */ #include <features.h> #include "_stdio.h" #include <stdlib.h> @@ -77,41 +76,6 @@ #include <bits/uClibc_fpmax.h> #endif /* __UCLIBC_HAS_FLOATS__ */ -/* Experimentally off - libc_hidden_proto(memcmp) */ -/* Experimentally off - libc_hidden_proto(memset) */ -/* Experimentally off - libc_hidden_proto(strcpy) */ -/* Experimentally off - libc_hidden_proto(strlen) */ -libc_hidden_proto(ungetc) -libc_hidden_proto(vfscanf) -libc_hidden_proto(vsscanf) -libc_hidden_proto(fclose) -libc_hidden_proto(getc_unlocked) -libc_hidden_proto(__fgetc_unlocked) -#ifdef __UCLIBC_HAS_WCHAR__ -libc_hidden_proto(wcslen) -libc_hidden_proto(vfwscanf) -libc_hidden_proto(vswscanf) -libc_hidden_proto(mbsrtowcs) -libc_hidden_proto(mbrtowc) -libc_hidden_proto(wcrtomb) -libc_hidden_proto(ungetwc) -libc_hidden_proto(iswspace) -libc_hidden_proto(fgetwc_unlocked) -#endif -#ifdef __UCLIBC_HAS_XLOCALE__ -libc_hidden_proto(__ctype_b_loc) -#elif defined __UCLIBC_HAS_CTYPE_TABLES__ -libc_hidden_proto(__ctype_b) -#endif - -#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 @@ -126,8 +90,6 @@ typedef struct { #endif -extern void _store_inttype(void *dest, int desttype, uintmax_t val); - #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) extern unsigned long long @@ -165,7 +127,6 @@ _stdlib_strto_l(register const char * __restrict str, /**********************************************************************/ #ifdef L_fscanf -libc_hidden_proto(fscanf) int fscanf(FILE * __restrict stream, const char * __restrict format, ...) { va_list arg; @@ -201,7 +162,6 @@ int scanf(const char * __restrict format, ...) #ifdef __STDIO_HAS_VSSCANF -libc_hidden_proto(sscanf) int sscanf(const char * __restrict str, const char * __restrict format, ...) { va_list arg; @@ -223,12 +183,10 @@ libc_hidden_def(sscanf) /**********************************************************************/ #ifdef L_vscanf -libc_hidden_proto(vscanf) int vscanf(const char * __restrict format, va_list arg) { return vfscanf(stdin, format, arg); } -libc_hidden_def(vscanf) #endif /**********************************************************************/ @@ -240,19 +198,10 @@ libc_hidden_def(vscanf) #ifdef __STDIO_BUFFERS -int vsscanf(__const char *sp, __const char *fmt, va_list ap) +int 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); @@ -265,7 +214,7 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap) #ifdef __UCLIBC_HAS_THREADS__ f.__user_locking = 1; /* Set user locking. */ - __stdio_init_mutex(&f.__lock); + STDIO_INIT_MUTEX(f.__lock); #endif f.__nextopen = NULL; @@ -284,22 +233,13 @@ libc_hidden_def(vsscanf) #elif !defined(__UCLIBC_HAS_WCHAR__) -int vsscanf(__const char *sp, __const char *fmt, va_list ap) +int 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); @@ -313,7 +253,7 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap) #ifdef __UCLIBC_HAS_THREADS__ f.f.__user_locking = 1; /* Set user locking. */ - __stdio_init_mutex(&f.f.__lock); + STDIO_INIT_MUTEX(f.f.__lock); #endif f.f.__nextopen = NULL; @@ -323,7 +263,7 @@ libc_hidden_def(vsscanf) #elif defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__) -int vsscanf(__const char *sp, __const char *fmt, va_list ap) +int vsscanf(const char *sp, const char *fmt, va_list ap) { FILE *f; int rv = EOF; @@ -419,21 +359,12 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format, FILE f; f.__bufstart = - f.__bufpos = (char *) str; + f.__bufpos = (unsigned char *) str; f.__bufread = - f.__bufend = (char *)(str + wcslen(str)); + f.__bufend = (unsigned 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); @@ -446,7 +377,7 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format, #ifdef __UCLIBC_HAS_THREADS__ f.__user_locking = 1; /* Set user locking. */ - __stdio_init_mutex(&f.__lock); + STDIO_INIT_MUTEX(f.__lock); #endif f.__nextopen = NULL; @@ -464,18 +395,19 @@ libc_hidden_def(vswscanf) /* float layout 0123456789012345678901 repeat n for "l[" */ -#define SPEC_CHARS "npxXoudifFeEgGaACSncs[" -/* npxXoudif eEgG CS cs[ */ +#define SPEC_CHARS "npxXoudifFeEgGaACSnmcs[" +/* npxXoudif eEgG CS cs[ */ +/* NOTE: the 'm' flag must come before any convs that support it */ -/* NOTE: Ordering is important! In particular, CONV_LEFTBRACKET - * must immediately precede CONV_c. */ +/* NOTE: Ordering is important! The CONV_{C,S,LEFTBRACKET} must map + simply to their lowercase equivalents. */ 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_C, CONV_S, CONV_LEFTBRACKET, CONV_m, CONV_c, CONV_s, CONV_leftbracket, CONV_percent, CONV_whitespace /* not in SPEC_* and no flags */ }; @@ -505,7 +437,7 @@ 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[)*/ + FLAG_MALLOC = 0x80, /* only works for c, s, S, and [ (and l[)*/ }; @@ -522,7 +454,7 @@ enum { /* fFeEgGaA */ (0x0c|FLAG_SURPRESS|FLAG_THOUSANDS|FLAG_I18N), \ /* C */ ( 0|FLAG_SURPRESS), \ /* S and l[ */ ( 0|FLAG_SURPRESS|FLAG_MALLOC), \ - /* c */ (0x04|FLAG_SURPRESS), \ + /* c */ (0x04|FLAG_SURPRESS|FLAG_MALLOC), \ /* s and [ */ (0x04|FLAG_SURPRESS|FLAG_MALLOC), \ } @@ -580,21 +512,22 @@ enum { #elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX) #define IMS 8 #else -#error fix QUAL_CHARS ptrdiff_t entry 't'! +#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 */ \ 'h', 'l', 'L', 'j', 'z', 't', 'q', 0, \ - 2, 4, 8, IMS, SS, PDS, 8, 0, /* TODO -- fix!!! */\ - 1, 8 } + 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. +#if WINT_MIN > WEOF +#error Unfortunately, we currently need wint_t to be able to store WEOF. Sorry. #endif #define W_EOF WEOF #define Wint wint_t @@ -717,26 +650,26 @@ void attribute_hidden __init_scan_cookie(register struct scan_cookie *sc, #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; + if (*(sc->grouping = __UCLIBC_CURLOCALE->grouping)) { + sc->thousands_sep = (const unsigned char *) __UCLIBC_CURLOCALE->thousands_sep; + sc->tslen = __UCLIBC_CURLOCALE->thousands_sep_len; #ifdef __UCLIBC_HAS_WCHAR__ - sc->thousands_sep_wc = __UCLIBC_CURLOCALE_DATA.thousands_sep_wc; + sc->thousands_sep_wc = __UCLIBC_CURLOCALE->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; + sc->decpt = (const unsigned char *) __UCLIBC_CURLOCALE->decimal_point; + sc->decpt_len = __UCLIBC_CURLOCALE->decimal_point_len; #else /* __UCLIBC_HAS_LOCALE__ */ sc->fake_decpt = sc->decpt = (unsigned char *) 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; + sc->decpt_wc = __UCLIBC_CURLOCALE->decimal_point_wc; #else sc->decpt_wc = '.'; #endif @@ -933,17 +866,17 @@ int attribute_hidden __psfs_parse_spec(register psfs_t *psfs) 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; + if (*p == 'm' && + (psfs->fmt[1] == '[' || psfs->fmt[1] == 'c' || + /* Assumes ascii for 's' and 'S' test. */ + (psfs->fmt[1] | 0x20) == 's')) + { + if (psfs->store) + psfs->flags |= FLAG_MALLOC; ++psfs->fmt; ++p; - continue; /* The related conversions follow 'a'. */ + continue; /* The related conversions follow 'm'. */ } -#endif /* __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__ */ for (p = spec_ranges; p_m_spec_chars > *p ; ++p) {} if (((psfs->dataargtype >> 8) | psfs->flags) @@ -952,9 +885,12 @@ int attribute_hidden __psfs_parse_spec(register psfs_t *psfs) goto ERROR_EINVAL; } - if ((p_m_spec_chars >= CONV_c) + if (p_m_spec_chars == CONV_p) { + /* a pointer has the same size as 'long int' */ + psfs->dataargtype = PA_FLAG_LONG; + } else if ((p_m_spec_chars >= CONV_c) && (psfs->dataargtype & PA_FLAG_LONG)) { - p_m_spec_chars -= 3; /* lc -> C, ls -> S, l[ -> ?? */ + p_m_spec_chars -= CONV_c - CONV_C; /* lc -> C, ls -> S, l[ -> ?? */ } psfs->conv_num = p_m_spec_chars; @@ -1154,22 +1090,12 @@ static __inline void kill_scan_cookie(register struct scan_cookie *sc) #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 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; @@ -1181,7 +1107,6 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) struct scan_cookie sc; psfs_t psfs; - int i; #ifdef __UCLIBC_MJN3_ONLY__ @@ -1191,7 +1116,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) unsigned char buf[MAX_DIGITS+2]; #ifdef L_vfscanf unsigned char scanset[UCHAR_MAX + 1]; - unsigned char invert; /* Careful! Meaning changes. */ + unsigned char invert = 0; /* Careful! Meaning changes. */ #endif /* L_vfscanf */ unsigned char fail; unsigned char zero_conversions = 1; @@ -1204,7 +1129,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) #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) { + if (__UCLIBC_CURLOCALE->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))) { @@ -1233,13 +1158,13 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) #ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ if (*sc.grouping) { - sc.thousands_sep = fake_thousands_sep_str; + sc.thousands_sep = (const unsigned char *) ","; sc.tslen = 1; } #endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */ #ifdef __UCLIBC_HAS_FLOATS__ - sc.fake_decpt = fake_decpt_str; + sc.fake_decpt = (const unsigned char *) "."; #endif /* __UCLIBC_HAS_FLOATS__ */ #else /* L_vfwscanf */ @@ -1302,12 +1227,6 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) 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; @@ -1405,7 +1324,20 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) (psfs.conv_num >= CONV_c) #endif /* __UCLIBC_HAS_WCHAR__ */ { + /* We might have to handle the allocation ourselves */ + int len; + unsigned char **ptr; + b = (psfs.store ? ((unsigned char *) psfs.cur_ptr) : buf); + /* With 'm', we actually got a pointer to a pointer */ + ptr = (void *)b; + + if (psfs.flags & FLAG_MALLOC) { + len = 0; + b = NULL; + } else + len = -1; + fail = 1; if (psfs.conv_num == CONV_c) { @@ -1413,27 +1345,42 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) sc.width = 1; } + if (psfs.flags & FLAG_MALLOC) + b = malloc(sc.width); + + i = 0; while (__scan_getc(&sc) >= 0) { zero_conversions = 0; - *b = sc.cc; - b += psfs.store; + b[i] = sc.cc; + i += psfs.store; } __scan_ungetc(&sc); if (sc.width > 0) { /* Failed to read all required. */ goto DONE; } + if (psfs.flags & FLAG_MALLOC) + *ptr = b; psfs.cnt += psfs.store; goto NEXT_FMT; } if (psfs.conv_num == CONV_s) { + + i = 0; /* 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; + if (i == len) { + /* Pick a size that won't trigger a lot of + * mallocs early on ... */ + len += 256; + b = realloc(b, len + 1); + } + b[i] = sc.cc; + i += psfs.store; fail = 0; } + } else { #ifdef __UCLIBC_HAS_WCHAR__ assert((psfs.conv_num == CONV_LEFTBRACKET) || \ @@ -1484,13 +1431,20 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) #endif /* __UCLIBC_HAS_WCHAR__ */ + i = 0; while (__scan_getc(&sc) >= 0) { zero_conversions = 0; if (!scanset[sc.cc]) { break; } - *b = sc.cc; - b += psfs.store; + if (i == len) { + /* Pick a size that won't trigger a lot of + * mallocs early on ... */ + len += 256; + b = realloc(b, len + 1); + } + b[i] = sc.cc; + i += psfs.store; fail = 0; } } @@ -1500,6 +1454,9 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) if (fail) { /* nothing stored! */ goto DONE; } + if (psfs.flags & FLAG_MALLOC) + *ptr = b; + b += i; *b = 0; /* Nul-terminate string. */ psfs.cnt += psfs.store; goto NEXT_FMT; @@ -1607,7 +1564,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) *wb = sc.wc; wb += psfs.store; } else { - i = wcrtomb(b, sc.wc, &mbstate); + i = wcrtomb((char*) b, sc.wc, &mbstate); if (i < 0) { /* Conversion failure. */ goto DONE_DO_UNGET; } @@ -1635,7 +1592,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) *wb = sc.wc; wb += psfs.store; } else { - i = wcrtomb(b, sc.wc, &mbstate); + i = wcrtomb((char*) b, sc.wc, &mbstate); if (i < 0) { /* Conversion failure. */ goto DONE_DO_UNGET; } @@ -1709,7 +1666,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) *wb = sc.wc; wb += psfs.store; } else { - i = wcrtomb(b, sc.wc, &mbstate); + i = wcrtomb((char*) b, sc.wc, &mbstate); if (i < 0) { /* Conversion failure. */ goto DONE_DO_UNGET; } @@ -1882,7 +1839,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc) #ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ if ((psfs->flags & FLAG_THOUSANDS) && (base == 10) - && *(p = sc->grouping) + && *(p = (const unsigned char *) sc->grouping) ) { int nblk1, nblk2, nbmax, lastblock, pass, i; @@ -2004,7 +1961,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc) p = sc->fake_decpt + k; do { if (!*++p) { - strcpy(b, sc->decpt); + strcpy((char*) b, (char*) sc->decpt); b += sc->decpt_len; goto GOT_DECPT; } diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c index d8c0ae20d..2a1054618 100644 --- a/libc/stdio/_stdio.c +++ b/libc/stdio/_stdio.c @@ -7,9 +7,6 @@ #include "_stdio.h" -/* Experimentally off - libc_hidden_proto(memcpy) */ -libc_hidden_proto(isatty) - /* This is pretty much straight from uClibc, but with one important * difference. * @@ -54,13 +51,6 @@ libc_hidden_proto(isatty) #define __STDIO_FILE_INIT_BUFFERS(buf,bufsize) #endif -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream) \ - &((stream).__filedes), { _cs_read, _cs_write, _cs_seek, _cs_close }, -#else -#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream) -#endif - #ifdef __STDIO_MBSTATE #define __STDIO_FILE_INIT_MBSTATE \ { 0, 0 }, @@ -76,8 +66,13 @@ libc_hidden_proto(isatty) #endif #ifdef __UCLIBC_HAS_THREADS__ +#ifdef __USE_STDIO_FUTEXES__ +#define __STDIO_FILE_INIT_THREADSAFE \ + 2, _LIBC_LOCK_RECURSIVE_INITIALIZER, +#else #define __STDIO_FILE_INIT_THREADSAFE \ 2, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +#endif #else #define __STDIO_FILE_INIT_THREADSAFE #endif @@ -90,7 +85,6 @@ libc_hidden_proto(isatty) __STDIO_FILE_INIT_BUFGETC((buf)) \ __STDIO_FILE_INIT_BUFPUTC((buf)) \ __STDIO_FILE_INIT_NEXT(next) \ - __STDIO_FILE_INIT_CUSTOM_STREAM(stream) \ __STDIO_FILE_INIT_WUNGOT \ __STDIO_FILE_INIT_MBSTATE \ __STDIO_FILE_INIT_UNUSED \ @@ -154,14 +148,13 @@ FILE *__stdout = _stdio_streams + 1; /* For putchar() macro. */ FILE *_stdio_openlist = _stdio_streams; # ifdef __UCLIBC_HAS_THREADS__ -__UCLIBC_MUTEX_INIT(_stdio_openlist_add_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); -#ifdef __STDIO_BUFFERS -__UCLIBC_MUTEX_INIT(_stdio_openlist_del_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); +__UCLIBC_IO_MUTEX_INIT(_stdio_openlist_add_lock); +# ifdef __STDIO_BUFFERS +__UCLIBC_IO_MUTEX_INIT(_stdio_openlist_del_lock); volatile int _stdio_openlist_use_count = 0; int _stdio_openlist_del_count = 0; -#endif +# endif # endif - #endif /**********************************************************************/ #ifdef __UCLIBC_HAS_THREADS__ @@ -169,6 +162,7 @@ int _stdio_openlist_del_count = 0; /* 2 if threading not initialized and 0 otherwise; */ int _stdio_user_locking = 2; +#ifndef __USE_STDIO_FUTEXES__ void attribute_hidden __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) { const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer, @@ -176,12 +170,13 @@ void attribute_hidden __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer)); } +#endif #endif /**********************************************************************/ /* We assume here that we are the only remaining thread. */ -void attribute_hidden _stdio_term(void) +void _stdio_term(void) { #if defined(__STDIO_BUFFERS) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__) register FILE *ptr; @@ -191,10 +186,9 @@ void attribute_hidden _stdio_term(void) * locked, then I suppose there is a chance that a pointer in the * chain might be corrupt due to a partial store. */ - __stdio_init_mutex(&_stdio_openlist_add_lock); -#warning check + STDIO_INIT_MUTEX(_stdio_openlist_add_lock); #ifdef __STDIO_BUFFERS - __stdio_init_mutex(&_stdio_openlist_del_lock); + STDIO_INIT_MUTEX(_stdio_openlist_del_lock); #endif /* Next we need to worry about the streams themselves. If a stream @@ -216,7 +210,7 @@ void attribute_hidden _stdio_term(void) } ptr->__user_locking = 1; /* Set locking mode to "by caller". */ - __stdio_init_mutex(&ptr->__lock); /* Shouldn't be necessary, but... */ + STDIO_INIT_MUTEX(ptr->__lock); /* Shouldn't be necessary, but... */ } #endif @@ -238,7 +232,7 @@ void attribute_hidden _stdio_term(void) #endif #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ /* Actually close all custom streams to perform any special cleanup. */ - if (ptr->__cookie != &ptr->__filedes) { + if (__STDIO_STREAM_IS_CUSTOM(ptr)) { __CLOSE(ptr); } #endif @@ -248,13 +242,15 @@ void attribute_hidden _stdio_term(void) } #if defined __STDIO_BUFFERS || !defined __UCLIBC__ -void attribute_hidden _stdio_init(void) +void _stdio_init(void) { #ifdef __STDIO_BUFFERS int old_errno = errno; /* stdin and stdout uses line buffering when connected to a tty. */ - _stdio_streams[0].__modeflags ^= (1-isatty(0)) * __FLAG_LBF; - _stdio_streams[1].__modeflags ^= (1-isatty(1)) * __FLAG_LBF; + if (!isatty(0)) + _stdio_streams[0].__modeflags ^= __FLAG_LBF; + if (!isatty(1)) + _stdio_streams[1].__modeflags ^= __FLAG_LBF; __set_errno(old_errno); #endif #ifndef __UCLIBC__ @@ -271,27 +267,18 @@ void attribute_hidden _stdio_init(void) #error Assumption violated about __MASK_READING and __FLAG_UNGOT #endif -#ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h> -#endif - #ifndef NDEBUG -void _stdio_validate_FILE(const FILE *stream) +void attribute_hidden _stdio_validate_FILE(const FILE *stream) { #ifdef __UCLIBC_HAS_THREADS__ assert(((unsigned int)(stream->__user_locking)) <= 2); #endif #warning Define a constant for minimum possible valid __filedes? - assert(stream->__filedes >= -3); + assert(stream->__filedes >= -4); if (stream->__filedes < 0) { -/* assert((stream->__filedes != -1) */ -/* #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ -/* || (stream->__cookie == &stream->__filedes) /\* custom *\/ */ -/* #endif */ -/* ); */ /* assert((stream->__filedes == -1) || __STDIO_STREAM_IS_FBF(stream)); */ assert(!__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream) @@ -308,12 +295,6 @@ void _stdio_validate_FILE(const FILE *stream) #endif } -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ - if (stream->__cookie != &stream->__filedes) { /* custom */ - assert(stream->__filedes == -1); - } -#endif - /* Can not be both narrow and wide oriented at the same time. */ assert(!(__STDIO_STREAM_IS_NARROW(stream) && __STDIO_STREAM_IS_WIDE(stream))); diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h index 27075a8ac..310510d66 100644 --- a/libc/stdio/_stdio.h +++ b/libc/stdio/_stdio.h @@ -4,6 +4,8 @@ * * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. */ +#ifndef __STDIO_H_I +#define __STDIO_H_I 1 #include <features.h> #include <assert.h> @@ -24,21 +26,24 @@ #include <bits/uClibc_mutex.h> #define __STDIO_THREADLOCK_OPENLIST_ADD \ - __UCLIBC_MUTEX_LOCK(_stdio_openlist_add_lock) + __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_add_lock) #define __STDIO_THREADUNLOCK_OPENLIST_ADD \ - __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_add_lock) + __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_add_lock) #ifdef __STDIO_BUFFERS #define __STDIO_THREADLOCK_OPENLIST_DEL \ - __UCLIBC_MUTEX_LOCK(_stdio_openlist_del_lock) + __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_del_lock) #define __STDIO_THREADUNLOCK_OPENLIST_DEL \ - __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_del_lock) + __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_del_lock) #ifdef __UCLIBC_HAS_THREADS__ +extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) attribute_hidden; + +extern volatile int _stdio_openlist_use_count attribute_hidden; /* _stdio_openlist_del_lock */ #define __STDIO_OPENLIST_INC_USE \ do { \ __STDIO_THREADLOCK_OPENLIST_DEL; \ @@ -46,11 +51,12 @@ do { \ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ } while (0) -extern void _stdio_openlist_dec_use(void); +extern void _stdio_openlist_dec_use(void) attribute_hidden; #define __STDIO_OPENLIST_DEC_USE \ _stdio_openlist_dec_use() +extern int _stdio_openlist_del_count attribute_hidden; /* _stdio_openlist_del_lock */ #define __STDIO_OPENLIST_INC_DEL_CNT \ do { \ __STDIO_THREADLOCK_OPENLIST_DEL; \ @@ -92,48 +98,61 @@ do { \ /**********************************************************************/ #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -extern __ssize_t _cs_read(void *cookie, char *buf, size_t bufsize) attribute_hidden; -extern __ssize_t _cs_write(void *cookie, const char *buf, size_t bufsize) attribute_hidden; -extern int _cs_seek(void *cookie, __offmax_t *pos, int whence) attribute_hidden; -extern int _cs_close(void *cookie) attribute_hidden; - -#define __STDIO_STREAM_RESET_GCS(S) \ - (S)->__cookie = &((S)->__filedes); \ - (S)->__gcs.read = _cs_read; \ - (S)->__gcs.write = _cs_write; \ - (S)->__gcs.seek = _cs_seek; \ - (S)->__gcs.close = _cs_close - - -#define __READ(STREAMPTR,BUF,SIZE) \ - ((((STREAMPTR)->__gcs.read) == NULL) ? -1 : \ - (((STREAMPTR)->__gcs.read)((STREAMPTR)->__cookie,(BUF),(SIZE)))) -#define __WRITE(STREAMPTR,BUF,SIZE) \ - ((((STREAMPTR)->__gcs.write) == NULL) ? -1 : \ - (((STREAMPTR)->__gcs.write)((STREAMPTR)->__cookie,(BUF),(SIZE)))) -#define __SEEK(STREAMPTR,PPOS,WHENCE) \ - ((((STREAMPTR)->__gcs.seek) == NULL) ? -1 : \ - (((STREAMPTR)->__gcs.seek)((STREAMPTR)->__cookie,(PPOS),(WHENCE)))) -#define __CLOSE(STREAMPTR) \ - ((((STREAMPTR)->__gcs.close) == NULL) ? 0 : \ - (((STREAMPTR)->__gcs.close)((STREAMPTR)->__cookie))) +#define __STDIO_STREAM_GLIBC_CUSTOM_FILEDES (-2) + +#define __STDIO_STREAM_IS_CUSTOM(S) \ + ((S)->__filedes == __STDIO_STREAM_GLIBC_CUSTOM_FILEDES) + +#define __STDIO_STREAM_CUSTOM_IO_FUNC(S, NAME, RC, ARGS...) \ + if (__STDIO_STREAM_IS_CUSTOM((S))) { \ + _IO_cookie_file_t *cfile = (_IO_cookie_file_t *) (S); \ + return (cfile->__gcs.NAME == NULL) ? (RC) : \ + cfile->__gcs.NAME(cfile->__cookie, ##ARGS); \ + } + +typedef struct { + struct __STDIO_FILE_STRUCT __fp; + void *__cookie; + _IO_cookie_io_functions_t __gcs; +} _IO_cookie_file_t; #else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ +#undef __STDIO_STREAM_GLIBC_CUSTOM_FILEDES +#define __STDIO_STREAM_IS_CUSTOM(S) (0) +#define __STDIO_STREAM_CUSTOM_IO_FUNC(S, NAME, RC, ARGS...) + +#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ + extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attribute_hidden; -#define __STDIO_STREAM_RESET_GCS(S) ((void)0) +static inline ssize_t __READ(FILE *stream, char *buf, size_t bufsize) +{ + __STDIO_STREAM_CUSTOM_IO_FUNC(stream, read, -1, buf, bufsize); -#define __READ(STREAMPTR,BUF,SIZE) \ - (read((STREAMPTR)->__filedes,(BUF),(SIZE))) -#define __WRITE(STREAMPTR,BUF,SIZE) \ - (write((STREAMPTR)->__filedes,(BUF),(SIZE))) -#define __SEEK(STREAMPTR,PPOS,WHENCE) \ - (__stdio_seek((STREAMPTR),(PPOS),(WHENCE))) -#define __CLOSE(STREAMPTR) \ - (close((STREAMPTR)->__filedes)) + return read(stream->__filedes, buf, bufsize); +} -#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ +static inline ssize_t __WRITE(FILE *stream, const char *buf, size_t bufsize) +{ + __STDIO_STREAM_CUSTOM_IO_FUNC(stream, write, -1, buf, bufsize); + + return write(stream->__filedes, buf, bufsize); +} + +static inline int __SEEK(FILE *stream, register __offmax_t *pos, int whence) +{ + __STDIO_STREAM_CUSTOM_IO_FUNC(stream, seek, -1, pos, whence); + + return __stdio_seek(stream, pos, whence); +} + +static inline int __CLOSE(FILE *stream) +{ + __STDIO_STREAM_CUSTOM_IO_FUNC(stream, close, 0); + + return close(stream->__filedes); +} /**********************************************************************/ #ifdef __UCLIBC_HAS_WCHAR__ @@ -250,12 +269,6 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr # define __STDIO_STREAM_CAN_USE_BUFFER_ADD(S) (0) #endif -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -#define __STDIO_STREAM_IS_CUSTOM(S) ((S)->__cookie != &((S)->__filedes)) -#else -#define __STDIO_STREAM_IS_CUSTOM(S) (0) -#endif - /**********************************************************************/ #ifdef __STDIO_BUFFERS @@ -308,6 +321,9 @@ 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 uintmax_t _load_inttype(int desttype, register const void *src, int uflag) attribute_hidden; +extern void _store_inttype(void *dest, int desttype, uintmax_t val) attribute_hidden; + /**********************************************************************/ #ifdef __STDIO_BUFFERS @@ -339,10 +355,10 @@ extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidde (S)->__bufread = (S)->__bufpos = (S)->__bufstart -#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES (-2) -#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-2) -#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES (-3) -#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES (-3) +#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES (-3) +#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-3) +#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES (-4) +#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES (-4) #define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) \ ((S)->__filedes == __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES) @@ -379,6 +395,7 @@ extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidde #define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) (0) #define __STDIO_STREAM_IS_FAKE_VSSCANF(S) (0) #undef __STDIO_STREAM_IS_FAKE_VSWPRINTF +#undef __STDIO_STREAM_IS_FAKE_VSWSCANF # ifdef __USE_OLD_VFPRINTF__ # define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB (-2) @@ -408,7 +425,7 @@ extern int __stdio_adjust_position(FILE *__restrict stream, __offmax_t *pos) att #ifdef NDEBUG #define __STDIO_STREAM_VALIDATE(S) ((void)0) #else -extern void _stdio_validate_FILE(const FILE *stream); +extern void _stdio_validate_FILE(const FILE *stream) attribute_hidden; #define __STDIO_STREAM_VALIDATE(S) _stdio_validate_FILE((S)) #endif @@ -454,3 +471,5 @@ extern int _vfwprintf_internal (FILE * __restrict stream, #if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__) #define __STDIO_HAS_VSNPRINTF 1 #endif + +#endif /* __STDIO_H_I */ diff --git a/libc/stdio/_store_inttype.c b/libc/stdio/_store_inttype.c index fdd4dce05..7ecfe6ed0 100644 --- a/libc/stdio/_store_inttype.c +++ b/libc/stdio/_store_inttype.c @@ -28,7 +28,6 @@ /* We assume int may be short or long, but short and long are different. */ -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 */ diff --git a/libc/stdio/_trans2w.c b/libc/stdio/_trans2w.c index ed1a583fc..c72237939 100644 --- a/libc/stdio/_trans2w.c +++ b/libc/stdio/_trans2w.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fseek) /* Function to handle transition to writing. * Initialize or verify the stream's orientation (even if readonly). diff --git a/libc/stdio/_uintmaxtostr.c b/libc/stdio/_uintmaxtostr.c index 0d25a0a9f..82eb862e1 100644 --- a/libc/stdio/_uintmaxtostr.c +++ b/libc/stdio/_uintmaxtostr.c @@ -5,13 +5,11 @@ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. */ -#define _ISOC99_SOURCE /* for ULLONG primarily... */ #include "_stdio.h" #include <limits.h> #include <locale.h> #include <bits/uClibc_uintmaxtostr.h> -/* Experimentally off - libc_hidden_proto(memcpy) */ /* Avoid using long long / and % operations to cut down dependencies on * libgcc.a. Definitely helps on i386 at least. */ @@ -22,8 +20,8 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval, int base, __UIM_CASE alphacase) { - int negative; - unsigned int digit; + int negative; + unsigned int digit; #ifdef INTERNAL_DIV_MOD unsigned int H, L, high, low, rh; #endif @@ -50,21 +48,21 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_ alphacase ^= outdigit; if (alphacase == __UIM_GROUP) { assert(base == 10); - if (*(g = __UCLIBC_CURLOCALE_DATA.grouping)) { + if (*(g = __UCLIBC_CURLOCALE->grouping)) { grouping = *g; } } #endif /* __LOCALE_C_ONLY */ - *bufend = '\0'; + *bufend = '\0'; #ifndef INTERNAL_DIV_MOD - do { + do { #ifndef __LOCALE_C_ONLY if (!grouping) { /* Finished a group. */ - bufend -= __UCLIBC_CURLOCALE_DATA.thousands_sep_len; - memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep, - __UCLIBC_CURLOCALE_DATA.thousands_sep_len); + bufend -= __UCLIBC_CURLOCALE->thousands_sep_len; + memcpy(bufend, __UCLIBC_CURLOCALE->thousands_sep, + __UCLIBC_CURLOCALE->thousands_sep_len); if (g[1] != 0) { /* g[1] == 0 means repeat last grouping. */ /* Note: g[1] == -1 means no further grouping. But since * we'll never wrap around, we can set grouping to -1 without @@ -80,16 +78,16 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_ #ifndef __LOCALE_C_ONLY if (unlikely(outdigit)) { - bufend -= __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]; + bufend -= __UCLIBC_CURLOCALE->outdigit_length[digit]; memcpy(bufend, - (&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit], - __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]); + (&__UCLIBC_CURLOCALE->outdigit0_mb)[digit], + __UCLIBC_CURLOCALE->outdigit_length[digit]); } else #endif { *--bufend = ( (digit < 10) ? digit + '0' : digit + alphacase ); } - } while (uval); + } while (uval); #else /* ************************************************** */ @@ -102,12 +100,12 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_ low = (unsigned int) uval; high = (unsigned int) (uval >> (sizeof(unsigned int) * CHAR_BIT)); - do { + do { #ifndef __LOCALE_C_ONLY if (!grouping) { /* Finished a group. */ - bufend -= __UCLIBC_CURLOCALE_DATA.thousands_sep_len; - memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep, - __UCLIBC_CURLOCALE_DATA.thousands_sep_len); + bufend -= __UCLIBC_CURLOCALE->thousands_sep_len; + memcpy(bufend, __UCLIBC_CURLOCALE->thousands_sep, + __UCLIBC_CURLOCALE->thousands_sep_len); if (g[1] != 0) { /* g[1] == 0 means repeat last grouping. */ /* Note: g[1] == -1 means no further grouping. But since * we'll never wrap around, we can set grouping to -1 without @@ -132,22 +130,22 @@ char attribute_hidden *_uintmaxtostr(register char * __restrict bufend, uintmax_ #ifndef __LOCALE_C_ONLY if (unlikely(outdigit)) { - bufend -= __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]; + bufend -= __UCLIBC_CURLOCALE->outdigit_length[digit]; memcpy(bufend, - (&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit], - __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]); + (&__UCLIBC_CURLOCALE->outdigit0_mb)[digit], + __UCLIBC_CURLOCALE->outdigit_length[digit]); } else #endif { *--bufend = ( (digit < 10) ? digit + '0' : digit + alphacase ); } - } while (low | high); + } while (low | high); #endif /******************************************************/ - if (negative) { + if (negative) { *--bufend = '-'; - } + } - return bufend; + return bufend; } diff --git a/libc/stdio/_vfprintf.c b/libc/stdio/_vfprintf.c index 61a730d75..a795f4979 100644 --- a/libc/stdio/_vfprintf.c +++ b/libc/stdio/_vfprintf.c @@ -12,8 +12,8 @@ * 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. + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. */ /* This code needs a lot of clean up. Some of that is on hold until uClibc @@ -88,7 +88,6 @@ * treats this as an error. */ -#define _ISOC99_SOURCE /* for ULLONG primarily... */ #include <features.h> #include "_stdio.h" #include <stdlib.h> @@ -101,37 +100,19 @@ #include <stdint.h> #include <errno.h> #include <locale.h> -#include <printf.h> #ifdef __UCLIBC_HAS_THREADS__ -#include <stdio_ext.h> -#include <pthread.h> -#endif /* __UCLIBC_HAS_THREADS__ */ +# include <stdio_ext.h> +# include <pthread.h> +#endif #ifdef __UCLIBC_HAS_WCHAR__ -#include <wchar.h> -#endif /* __UCLIBC_HAS_WCHAR__ */ +# include <wchar.h> +#endif #include <bits/uClibc_uintmaxtostr.h> #include <bits/uClibc_va_copy.h> -/* Experimentally off - libc_hidden_proto(memcpy) */ -/* Experimentally off - libc_hidden_proto(memset) */ -/* Experimentally off - libc_hidden_proto(strlen) */ -/* Experimentally off - 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. @@ -140,82 +121,46 @@ libc_hidden_proto(fputws) #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 */ - +#include "_fpmaxtostr.h" #undef __STDIO_HAS_VSNPRINTF #if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__) -#define __STDIO_HAS_VSNPRINTF 1 +# 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 +# ifdef L_register_printf_function /* emit only once */ -#warning WISHLIST: Make MAX_USER_SPEC configurable? -#warning WISHLIST: Make MAX_ARGS_PER_SPEC configurable? +# warning WISHLIST: Make MAX_USER_SPEC configurable? +# warning WISHLIST: Make MAX_ARGS_PER_SPEC configurable? +# endif #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__ */ +# define MAX_USER_SPEC 10 +# define MAX_ARGS_PER_SPEC 5 +#else +# undef MAX_USER_SPEC +# define MAX_ARGS_PER_SPEC 1 +#endif #if MAX_ARGS_PER_SPEC < 1 -#error MAX_ARGS_PER_SPEC < 1! -#undef MAX_ARGS_PER_SPEC -#define 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! +# error NL_ARGMAX < 9! #endif #if defined(NL_ARGMAX) && (NL_ARGMAX >= (MAX_ARGS_PER_SPEC + 2)) -#define MAX_ARGS NL_ARGMAX +# 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) +# define MAX_ARGS (MAX_ARGS_PER_SPEC + 2) #endif /**********************************************************************/ @@ -227,20 +172,20 @@ libc_hidden_proto(fputws) 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__ */ +#endif /**********************************************************************/ #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 + 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 }; /**********************************************************************/ @@ -260,10 +205,10 @@ enum { }; /* p x X o u d i */ -#define SPEC_BASE { 16, 16, 16, 8, 10, 10, 10 } +#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_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), \ @@ -304,43 +249,43 @@ enum { /* #endif */ #ifdef PDS -#error PDS already defined! +# error PDS already defined! #endif #ifdef SS -#error SS already defined! +# error SS already defined! #endif #ifdef IMS -#error IMS already defined! +# error IMS already defined! #endif #if PTRDIFF_MAX == INT_MAX -#define PDS 0 +# define PDS 0 #elif PTRDIFF_MAX == LONG_MAX -#define PDS 4 +# define PDS 4 #elif defined(LLONG_MAX) && (PTRDIFF_MAX == LLONG_MAX) -#define PDS 8 +# define PDS 8 #else -#error fix QUAL_CHARS ptrdiff_t entry 't'! +# error fix QUAL_CHARS ptrdiff_t entry 't'! #endif #if SIZE_MAX == UINT_MAX -#define SS 0 +# define SS 0 #elif SIZE_MAX == ULONG_MAX -#define SS 4 +# define SS 4 #elif defined(LLONG_MAX) && (SIZE_MAX == ULLONG_MAX) -#define SS 8 +# define SS 8 #else -#error fix QUAL_CHARS size_t entries 'z', 'Z'! +# error fix QUAL_CHARS size_t entries 'z', 'Z'! #endif #if INTMAX_MAX == INT_MAX -#define IMS 0 +# define IMS 0 #elif INTMAX_MAX == LONG_MAX -#define IMS 4 +# define IMS 4 #elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX) -#define IMS 8 +# define IMS 8 #else -#error fix QUAL_CHARS intmax_t entry 'j'! +# error fix QUAL_CHARS intmax_t entry 'j'! #endif #define QUAL_CHARS { \ @@ -348,51 +293,52 @@ enum { /* 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 \ + 1, 8 \ } /**********************************************************************/ #ifdef __STDIO_VA_ARG_PTR -#ifdef __BCC__ -#define __va_arg_ptr(ap,type) (((type *)(ap += sizeof(type))) - 1) -#endif +# ifdef __BCC__ +# define __va_arg_ptr(ap,type) (((type *)(ap += sizeof(type))) - 1) +# endif -#if 1 -#ifdef __GNUC__ +# 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 +# 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)))) +# 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 +# ifdef ULLONG_MAX unsigned long long ull; -#endif -#ifdef __STDIO_PRINTF_FLOAT +# endif +# ifdef __UCLIBC_HAS_FLOATS__ double d; long double ld; -#endif /* __STDIO_PRINTF_FLOAT */ +# endif 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)) +# 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 { @@ -400,7 +346,7 @@ typedef struct { struct printf_info info; #ifdef NL_ARGMAX int maxposarg; /* > 0 if args are positional, 0 if not, -1 if unknown */ -#endif /* NL_ARGMAX */ +#endif int num_data_args; /* TODO: use sentinal??? */ unsigned int conv_num; unsigned char argnumber[4]; /* width | prec | 1st data | unused */ @@ -421,25 +367,16 @@ typedef struct { /* 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 +#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ + /* 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. @@ -456,7 +393,8 @@ size_t parse_printf_format(register const char *template, if (_ppfs_init(&ppfs, template) >= 0) { #ifdef NL_ARGMAX - if (ppfs.maxposarg > 0) { /* Using positional args. */ + if (ppfs.maxposarg > 0) { + /* Using positional args. */ count = ppfs.maxposarg; if (n > count) { n = count; @@ -464,8 +402,10 @@ size_t parse_printf_format(register const char *template, for (i = 0 ; i < n ; i++) { *argtypes++ = ppfs.argtype[i]; } - } else { /* Not using positional args. */ -#endif /* NL_ARGMAX */ + } else +#endif + { + /* Not using positional args. */ while (*template) { if ((*template == '%') && (*++template != '%')) { ppfs.fmtpos = template; @@ -498,15 +438,15 @@ size_t parse_printf_format(register const char *template, ++template; } } -#ifdef NL_ARGMAX } -#endif /* NL_ARGMAX */ } return count; } #endif + +#endif /**********************************************************************/ #ifdef L__ppfs_init @@ -518,14 +458,14 @@ int attribute_hidden _ppfs_init(register ppfs_t *ppfs, const char *fmt0) memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */ #ifdef NL_ARGMAX --ppfs->maxposarg; /* set to -1 */ -#endif /* NL_ARGMAX */ +#endif ppfs->fmtpos = fmt0; #ifdef __UCLIBC_MJN3_ONLY__ -#warning TODO: Make checking of the format string in C locale an option. +# 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) { + if (__UCLIBC_CURLOCALE->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."; @@ -570,7 +510,8 @@ int attribute_hidden _ppfs_init(register ppfs_t *ppfs, const char *fmt0) while (*fmt) { if ((*fmt == '%') && (*++fmt != '%')) { ppfs->fmtpos = fmt; /* back up to the '%' */ - if ((r = _ppfs_parsespec(ppfs)) < 0) { + r = _ppfs_parsespec(ppfs); + if (r < 0) { return -1; } fmt = ppfs->fmtpos; /* update to one past end of spec */ @@ -581,7 +522,7 @@ int attribute_hidden _ppfs_init(register ppfs_t *ppfs, const char *fmt0) ppfs->fmtpos = fmt0; /* rewind */ } -#ifdef NL_MAX_ARG +#ifdef NL_ARGMAX /* If we have positional args, make sure we know all the types. */ { register int *p = ppfs->argtype; @@ -593,7 +534,7 @@ int attribute_hidden _ppfs_init(register ppfs_t *ppfs, const char *fmt0) ++p; } } -#endif /* NL_MAX_ARG */ +#endif /* NL_ARGMAX */ return 0; } @@ -607,13 +548,14 @@ void attribute_hidden _ppfs_prepargs(register ppfs_t *ppfs, va_list arg) va_copy(ppfs->arg, arg); #ifdef NL_ARGMAX - if ((i = ppfs->maxposarg) > 0) { /* init for positional args */ + i = ppfs->maxposarg; /* init for positional args */ + if (i > 0) { ppfs->num_data_args = i; ppfs->info.width = ppfs->info.prec = ppfs->maxposarg = 0; _ppfs_setargs(ppfs); ppfs->maxposarg = i; } -#endif /* NL_ARGMAX */ +#endif } #endif /**********************************************************************/ @@ -630,7 +572,7 @@ void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs) #ifdef NL_ARGMAX if (ppfs->maxposarg == 0) { /* initing for or no pos args */ -#endif /* NL_ARGMAX */ +#endif if (ppfs->info.width == INT_MIN) { ppfs->info.width = #ifdef __va_arg_ptr @@ -669,7 +611,7 @@ void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs) /* we're assuming wchar_t is at least an int */ GET_VA_ARG(p,wc,wchar_t,ppfs->arg); break; -#ifdef __STDIO_PRINTF_FLOAT +#ifdef __UCLIBC_HAS_FLOATS__ /* PA_FLOAT */ case PA_DOUBLE: GET_VA_ARG(p,d,double,ppfs->arg); @@ -677,12 +619,12 @@ void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs) case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE): GET_VA_ARG(p,ld,long double,ppfs->arg); break; -#else /* __STDIO_PRINTF_FLOAT */ +#else /* __UCLIBC_HAS_FLOATS__ */ case PA_DOUBLE: case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE): assert(0); continue; -#endif /* __STDIO_PRINTF_FLOAT */ +#endif /* __UCLIBC_HAS_FLOATS__ */ default: /* TODO -- really need to ensure this can't happen */ assert(ppfs->argtype[i-1] & PA_FLAG_PTR); @@ -728,12 +670,6 @@ void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs) /**********************************************************************/ #ifdef L__ppfs_parsespec -#ifdef __UCLIBC_HAS_XLOCALE__ -libc_hidden_proto(__ctype_b_loc) -#elif defined __UCLIBC_HAS_CTYPE_TABLES__ -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 @@ -765,11 +701,11 @@ static const short int type_codes[] = { PA_INT|PA_FLAG_LONG, PA_INT|PA_FLAG_LONG_LONG, PA_WCHAR, -#ifdef __STDIO_PRINTF_FLOAT +#ifdef __UCLIBC_HAS_FLOATS__ /* PA_FLOAT, */ PA_DOUBLE, PA_DOUBLE|PA_FLAG_LONG_DOUBLE, -#endif /* __STDIO_PRINTF_FLOAT */ +#endif }; static const unsigned char type_sizes[] = { @@ -788,11 +724,11 @@ static const unsigned char type_sizes[] = { PROMOTED_SIZE_OF(long), /* TODO -- is this correct? (above too) */ #endif PROMOTED_SIZE_OF(wchar_t), -#ifdef __STDIO_PRINTF_FLOAT +#ifdef __UCLIBC_HAS_FLOATS__ /* PROMOTED_SIZE_OF(float), */ PROMOTED_SIZE_OF(double), PROMOTED_SIZE_OF(long double), -#endif /* __STDIO_PRINTF_FLOAT */ +#endif }; static int _promoted_size(int argtype) @@ -851,7 +787,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) int dpoint; #ifdef NL_ARGMAX int maxposarg; -#endif /* NL_ARGMAX */ +#endif int p_m_spec_chars; int n; int argtype[MAX_ARGS_PER_SPEC+2]; @@ -864,7 +800,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) static const char qual_chars[] = QUAL_CHARS; #ifdef __UCLIBC_HAS_WCHAR__ char buf[32]; -#endif /* __UCLIBC_HAS_WCHAR__ */ +#endif /* WIDE note: we can test against '%' here since we don't allow */ /* WIDE note: other mappings of '%' in the wide char set. */ @@ -875,7 +811,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) argtype[1] = __PA_NOARG; #ifdef NL_ARGMAX maxposarg = ppfs->maxposarg; -#endif /* NL_ARGMAX */ +#endif #ifdef __UCLIBC_HAS_WCHAR__ /* This is somewhat lame, but saves a lot of code. If we're dealing with @@ -885,15 +821,15 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) * 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) { + flags = ppfs->info._flags & FLAG_WIDESTREAM; + if (flags == 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]) - ) { + buf[i] = (char) (((wchar_t *) ppfs->fmtpos)[i-1]); + if (buf[i] != (((wchar_t *) ppfs->fmtpos)[i-1])) { return -1; } } while (buf[i++] && (i < sizeof(buf))); @@ -902,7 +838,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) #else /* __UCLIBC_HAS_WCHAR__ */ width = flags = dpoint = 0; fmt = ppfs->fmtpos; -#endif /* __UCLIBC_HAS_WCHAR__ */ +#endif assert(fmt[-1] == '%'); assert(fmt[0] != '%'); @@ -916,8 +852,11 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) } i = 0; while (isdigit(*fmt)) { - if (i < MAX_FIELD_WIDTH) { /* Avoid overflow. */ + if (i < INT_MAX / 10 + || (i == INT_MAX / 10 && (*fmt - '0') <= INT_MAX % 10)) { i = (i * 10) + (*fmt - '0'); + } else { + i = INT_MAX; /* best we can do... */ } ++fmt; } @@ -931,22 +870,23 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) if (maxposarg == 0) { return -1; } - if ((argnumber[2] = i) > maxposarg) { + argnumber[2] = i; + if (argnumber[2] > 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 +# 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__ */ +# endif if (*fmt == 'm') { goto PREC_WIDTH; } -#endif /* __UCLIBC_HAS_PRINTF_M_SPEC__ */ +# endif /* __UCLIBC_HAS_PRINTF_M_SPEC__ */ return -1; } maxposarg = 0; /* Possible redundant store, but cuts size. */ @@ -1005,7 +945,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) } argnumber[-dpoint] = i; } else -#endif /* NL_ARGMAX */ +#endif if (++p != fmt) { /* Not using pos args but digits followed *. */ return -1; @@ -1077,33 +1017,30 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) if (*fmt == 'm') { ppfs->conv_num = CONV_m; ppfs->num_data_args = 0; - goto DONE; - } + } else #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! */ + { +#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ + return -1; /* Error */ +#else + /* Handle custom arg -- WARNING -- overwrites p!!! */ + ppfs->conv_num = CONV_custom0; + p = _custom_printf_spec; + while (1) { + if (*p == *fmt) { + printf_arginfo_function *fp = _custom_printf_arginfo[(int)(p - _custom_printf_spec)]; + ppfs->num_data_args = fp(&(ppfs->info), MAX_ARGS_PER_SPEC, argtype + 2); + if (ppfs->num_data_args > MAX_ARGS_PER_SPEC) { + return -1; /* Error -- too many args! */ + } + break; } - goto DONE; + if (++p >= (_custom_printf_spec + MAX_USER_SPEC)) + return -1; /* Error */ } - } 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) { @@ -1114,7 +1051,8 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) ? (ppfs->argnumber[i] = argnumber[i]) : argnumber[2] + (i-2)); if (n > maxposarg) { - if ((maxposarg = n) > NL_ARGMAX) { + maxposarg = n; + if (maxposarg > NL_ARGMAX) { return -1; } } @@ -1124,18 +1062,20 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) ppfs->argtype[n] = argtype[i]; } } while (++i < ppfs->num_data_args + 2); - } else { + } else #endif /* NL_ARGMAX */ + { ppfs->argnumber[2] = 1; memcpy(ppfs->argtype, argtype + 2, ppfs->num_data_args * sizeof(int)); -#ifdef NL_ARGMAX } +#ifdef NL_ARGMAX ppfs->maxposarg = maxposarg; -#endif /* NL_ARGMAX */ +#endif #ifdef __UCLIBC_HAS_WCHAR__ - if ((flags = ppfs->info._flags & FLAG_WIDESTREAM) == 0) { + flags = ppfs->info._flags & FLAG_WIDESTREAM; + if (flags == 0) { ppfs->fmtpos = ++fmt; } else { ppfs->fmtpos = (const char *) (((const wchar_t *)(ppfs->fmtpos)) @@ -1143,7 +1083,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs) } #else /* __UCLIBC_HAS_WCHAR__ */ ppfs->fmtpos = ++fmt; -#endif /* __UCLIBC_HAS_WCHAR__ */ +#endif return ppfs->num_data_args + 2; } @@ -1214,10 +1154,10 @@ static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad); #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 _outnstr(stream, string, len) ((len > 0) ? __stdio_fwrite((const unsigned char *)(string), len, stream) : 0) #define FP_OUT _fp_out_narrow -#ifdef __STDIO_PRINTF_FLOAT +#ifdef __UCLIBC_HAS_FLOATS__ static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) { @@ -1225,17 +1165,19 @@ static size_t _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); - if ((len -= buflen) > 0) { - if ((r = _charpad(fp, (type & 0x7f), len)) != len) { + len -= buflen; + if (len > 0) { + r = _charpad(fp, (type & 0x7f), len); + if (r != len) { return r; } } len = buflen; } - return r + OUTNSTR(fp, (const unsigned char *) buf, len); + return r + OUTNSTR(fp, (const char *) buf, len); } -#endif /* __STDIO_PRINTF_FLOAT */ +#endif /* __UCLIBC_HAS_FLOATS__ */ #else /* L__vfprintf_internal */ @@ -1245,9 +1187,9 @@ static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf #define STRLEN wcslen #define _PPFS_init _ppwfs_init /* Pulls in fseek: */ -#define OUTPUT(F,S) fputws(S,F) +#define OUTPUT(F,S) fputws_unlocked(S,F) /* TODO: #define OUTPUT(F,S) _wstdio_fwrite((S),wcslen(S),(F)) */ -#define _outnwcs(stream, wstring, len) _wstdio_fwrite(wstring, len, stream) +#define _outnwcs(stream, wstring, len) _wstdio_fwrite((const wchar_t *)(wstring), len, stream) #define FP_OUT _fp_out_wide static size_t _outnstr(FILE *stream, const char *s, size_t wclen) @@ -1277,16 +1219,7 @@ static size_t _outnstr(FILE *stream, const char *s, size_t wclen) 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 ) +#ifdef __UCLIBC_HAS_FLOATS__ static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) { @@ -1297,8 +1230,10 @@ static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) if (type & 0x80) { /* Some type of padding needed */ int buflen = strlen(s); - if ((len -= buflen) > 0) { - if ((r = _charpad(fp, (type & 0x7f), len)) != len) { + len -= buflen; + if (len > 0) { + r = _charpad(fp, (type & 0x7f), len); + if (r != len) { return r; } } @@ -1310,15 +1245,15 @@ static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) do { #ifdef __LOCALE_C_ONLY wbuf[i] = s[i]; -#else /* __LOCALE_C_ONLY */ +#else -#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ +# ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ if (s[i] == ',') { - wbuf[i] = __UCLIBC_CURLOCALE_DATA.thousands_sep_wc; + wbuf[i] = __UCLIBC_CURLOCALE->thousands_sep_wc; } else -#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */ +# endif if (s[i] == '.') { - wbuf[i] = __UCLIBC_CURLOCALE_DATA.decimal_point_wc; + wbuf[i] = __UCLIBC_CURLOCALE->decimal_point_wc; } else { wbuf[i] = s[i]; } @@ -1332,7 +1267,7 @@ static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf) return r; } -#endif /* __STDIO_PRINTF_FLOAT */ +#endif /* __UCLIBC_HAS_FLOATS__ */ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0) { @@ -1343,7 +1278,7 @@ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0) memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */ #ifdef NL_ARGMAX --ppfs->maxposarg; /* set to -1 */ -#endif /* NL_ARGMAX */ +#endif ppfs->fmtpos = (const char *) fmt0; ppfs->info._flags = FLAG_WIDESTREAM; @@ -1389,7 +1324,8 @@ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0) while (*fmt) { if ((*fmt == '%') && (*++fmt != '%')) { ppfs->fmtpos = (const char *) fmt; /* back up to the '%' */ - if ((r = _ppfs_parsespec(ppfs)) < 0) { + r = _ppfs_parsespec(ppfs); + if (r < 0) { return -1; } fmt = (const wchar_t *) ppfs->fmtpos; /* update to one past end of spec */ @@ -1428,7 +1364,7 @@ static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad) FMT_TYPE pad[1]; *pad = padchar; - while (todo && (OUTNSTR(stream, (const unsigned char *) pad, 1) == 1)) { + while (todo && (OUTNSTR(stream, (const char *) pad, 1) == 1)) { --todo; } @@ -1442,10 +1378,10 @@ static int _do_one_spec(FILE * __restrict stream, static const char spec_base[] = SPEC_BASE; #ifdef L__vfprintf_internal static const char prefix[] = "+\0-\0 \0000x\0000X"; - /* 0 2 4 6 9 11*/ -#else /* L__vfprintf_internal */ + /* 0 2 4 6 9 11*/ +#else static const wchar_t prefix[] = L"+\0-\0 \0000x\0000X"; -#endif /* L__vfprintf_internal */ +#endif enum { PREFIX_PLUS = 0, PREFIX_MINUS = 2, @@ -1464,7 +1400,7 @@ static int _do_one_spec(FILE * __restrict stream, #ifdef __UCLIBC_HAS_WCHAR__ const wchar_t *ws = NULL; mbstate_t mbstate; -#endif /* __UCLIBC_HAS_WCHAR__ */ +#endif size_t slen; #ifdef L__vfprintf_internal #define SLEN slen @@ -1480,7 +1416,7 @@ static int _do_one_spec(FILE * __restrict stream, char padchar = ' '; #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Determine appropriate buf size. -#endif /* __UCLIBC_MJN3_ONLY__ */ +#endif /* 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 @@ -1500,21 +1436,21 @@ static int _do_one_spec(FILE * __restrict stream, /* Deal with the argptr vs argvalue issue. */ #ifdef __va_arg_ptr argptr = (const void * const *) ppfs->argptr; -#ifdef NL_ARGMAX +# ifdef NL_ARGMAX if (ppfs->maxposarg > 0) { /* Using positional args... */ argptr += ppfs->argnumber[2] - 1; } -#endif /* NL_ARGMAX */ +# endif #else /* Need to build a local copy... */ { register argvalue_t *p = ppfs->argvalue; int i; -#ifdef NL_ARGMAX +# ifdef NL_ARGMAX if (ppfs->maxposarg > 0) { /* Using positional args... */ p += ppfs->argnumber[2] - 1; } -#endif /* NL_ARGMAX */ +# endif for (i = 0 ; i < ppfs->num_data_args ; i++ ) { argptr[i] = (void *) p++; } @@ -1536,8 +1472,9 @@ static int _do_one_spec(FILE * __restrict stream, #ifdef L__vfprintf_internal #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) { +#endif + base = spec_base[(int)(ppfs->conv_num - CONV_p)]; + if (base == 10) { if (PRINT_INFO_FLAG_VAL(&(ppfs->info),group)) { alphacase = __UIM_GROUP; } @@ -1564,7 +1501,7 @@ static int _do_one_spec(FILE * __restrict stream, #ifdef L__vfprintf_internal #warning CONSIDER: If using outdigits and/or grouping, how should we interpret precision? #endif -#endif /* __UCLIBC_MJN3_ONLY__ */ +#endif s = _uintmaxtostr(buf + sizeof(buf) - 1, (uintmax_t) _load_inttype(ppfs->conv_num == CONV_p ? PA_FLAG_LONG : *argtype & __PA_INTMASK, @@ -1620,7 +1557,7 @@ static int _do_one_spec(FILE * __restrict stream, } numfill = ((numfill > SLEN) ? numfill - SLEN : 0); } else if (ppfs->conv_num <= CONV_A) { /* floating point */ -#ifdef __STDIO_PRINTF_FLOAT +#ifdef __UCLIBC_HAS_FLOATS__ ssize_t nf; nf = _fpmaxtostr(stream, (__fpmax_t) @@ -1634,16 +1571,17 @@ static int _do_one_spec(FILE * __restrict stream, *count += nf; return 0; -#else /* __STDIO_PRINTF_FLOAT */ +#else /* __UCLIBC_HAS_FLOATS__ */ return -1; /* TODO -- try to continue? */ -#endif /* __STDIO_PRINTF_FLOAT */ +#endif } else if (ppfs->conv_num <= CONV_S) { /* wide char or string */ #ifdef L__vfprintf_internal #ifdef __UCLIBC_HAS_WCHAR__ mbstate.__mask = 0; /* Initialize the mbstate. */ if (ppfs->conv_num == CONV_S) { /* wide string */ - if (!(ws = *((const wchar_t **) *argptr))) { + ws = *((const wchar_t **) *argptr); + if (!ws) { goto NULL_STRING; } /* We use an awful uClibc-specific hack here, passing @@ -1651,12 +1589,12 @@ static int _do_one_spec(FILE * __restrict stream, * 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) - ) { + slen = wcsrtombs((char *) &ws, &ws, /* Use awful hack! */ + ((ppfs->info.prec >= 0) + ? ppfs->info.prec + : SIZE_MAX), + &mbstate); + if (slen == ((size_t)-1)) { return -1; /* EILSEQ */ } } else { /* wide char */ @@ -1669,7 +1607,7 @@ static int _do_one_spec(FILE * __restrict stream, } #else /* __UCLIBC_HAS_WCHAR__ */ return -1; -#endif /* __UCLIBC_HAS_WCHAR__ */ +#endif } else if (ppfs->conv_num <= CONV_s) { /* char or string */ if (ppfs->conv_num == CONV_s) { /* string */ s = *((char **) (*argptr)); @@ -1685,6 +1623,9 @@ static int _do_one_spec(FILE * __restrict stream, #endif s = "(null)"; slen = 6; + /* Use an empty string rather than truncation if precision is too small. */ + if (ppfs->info.prec >= 0 && ppfs->info.prec < slen) + slen = 0; } } else { /* char */ s = buf; @@ -1715,7 +1656,7 @@ static int _do_one_spec(FILE * __restrict stream, if (ppfs->conv_num == CONV_s) { /* string */ #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Fix %s for _vfwprintf_internal... output upto illegal sequence? -#endif /* __UCLIBC_MJN3_ONLY__ */ +#endif s = *((char **) (*argptr)); if (s) { #ifdef __UCLIBC_HAS_PRINTF_M_SPEC__ @@ -1741,6 +1682,9 @@ static int _do_one_spec(FILE * __restrict stream, NULL_STRING: s = "(null)"; SLEN = slen = 6; + /* Use an empty string rather than truncation if precision is too small. */ + if (ppfs->info.prec >= 0 && ppfs->info.prec < slen) + SLEN = slen = 0; } } else { /* char */ *wbuf = btowc( (unsigned char)(*((const int *) *argptr)) ); @@ -1782,7 +1726,7 @@ static int _do_one_spec(FILE * __restrict stream, #ifdef L__vfprintf_internal #warning CONSIDER: If using outdigits and/or grouping, how should we pad? #endif -#endif /* __UCLIBC_MJN3_ONLY__ */ +#endif { size_t t; @@ -1813,7 +1757,7 @@ static int _do_one_spec(FILE * __restrict stream, #ifdef L__vfprintf_internal -#ifdef __UCLIBC_HAS_WCHAR__ +# ifdef __UCLIBC_HAS_WCHAR__ if (!ws) { assert(s); if (_outnstr(stream, s, slen) != slen) { @@ -1825,18 +1769,18 @@ static int _do_one_spec(FILE * __restrict stream, while (slen) { t = (slen <= sizeof(buf)) ? slen : sizeof(buf); t = wcsrtombs(buf, &ws, t, &mbstate); - assert (t != ((size_t)(-1))); + assert(t != ((size_t)(-1))); if (_outnstr(stream, buf, t) != t) { return -1; } slen -= t; } } -#else /* __UCLIBC_HAS_WCHAR__ */ +# else /* __UCLIBC_HAS_WCHAR__ */ if (_outnstr(stream, (const unsigned char *) s, slen) != slen) { return -1; } -#endif /* __UCLIBC_HAS_WCHAR__ */ +# endif #else /* L__vfprintf_internal */ @@ -1860,7 +1804,6 @@ static int _do_one_spec(FILE * __restrict stream, return 0; } -libc_hidden_proto(fprintf) int VFPRINTF_internal (FILE * __restrict stream, const FMT_TYPE * __restrict format, @@ -1874,7 +1817,7 @@ int VFPRINTF_internal (FILE * __restrict stream, s = format; if (_PPFS_init(&ppfs, format) < 0) { /* Bad format string. */ - OUTNSTR(stream, (const unsigned char *) ppfs.fmtpos, + OUTNSTR(stream, (const char *) ppfs.fmtpos, STRLEN((const FMT_TYPE *)(ppfs.fmtpos))); #if defined(L__vfprintf_internal) && !defined(NDEBUG) fprintf(stderr,"\nIMbS: \"%s\"\n\n", format); @@ -1888,8 +1831,9 @@ int VFPRINTF_internal (FILE * __restrict stream, ++format; } - if (format-s) { /* output any literal text in format string */ - if ( (r = OUTNSTR(stream, (const unsigned char *) s, format-s)) != (format-s)) { + if (format - s) { /* output any literal text in format string */ + r = OUTNSTR(stream, (const char *) s, format - s); + if (r != (format - s)) { count = -1; break; } @@ -1904,7 +1848,8 @@ int VFPRINTF_internal (FILE * __restrict stream, /* 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) { + r = _do_one_spec(stream, &ppfs, &count); + if (r < 0) { count = -1; break; } @@ -1940,13 +1885,13 @@ int VFPRINTF_internal (FILE * __restrict stream, * is using __stdio_fwrite (TODO: do the same for wide functions). */ #ifdef L_vfprintf -#define VFPRINTF vfprintf -#define VFPRINTF_internal _vfprintf_internal -#define FMT_TYPE char +# define VFPRINTF vfprintf +# define VFPRINTF_internal _vfprintf_internal +# define FMT_TYPE char #else -#define VFPRINTF vfwprintf -#define VFPRINTF_internal _vfwprintf_internal -#define FMT_TYPE wchar_t +# define VFPRINTF vfwprintf +# define VFPRINTF_internal _vfwprintf_internal +# define FMT_TYPE wchar_t #endif libc_hidden_proto(VFPRINTF) diff --git a/libc/stdio/_wfwrite.c b/libc/stdio/_wfwrite.c index fb5c6b3ee..517e3a7a3 100644 --- a/libc/stdio/_wfwrite.c +++ b/libc/stdio/_wfwrite.c @@ -16,8 +16,6 @@ #warning TODO: Fix prototype. #endif -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) @@ -38,7 +36,7 @@ size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n, } if (count) { wmemcpy((wchar_t *)(stream->__bufpos), ws, count); - stream->__bufpos = (char *)(((wchar_t *)(stream->__bufpos)) + count); + stream->__bufpos = (unsigned char *)(((wchar_t *)(stream->__bufpos)) + count); } __STDIO_STREAM_VALIDATE(stream); return n; @@ -59,7 +57,7 @@ size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n, ++r; /* 0 is returned when nul is reached. */ pw = ws + count + r; /* pw was set to NULL, so correct. */ } - if (__stdio_fwrite(buf, r, stream) == r) { + if (__stdio_fwrite((const unsigned char *)buf, r, stream) == r) { count = pw - ws; continue; } diff --git a/libc/stdio/asprintf.c b/libc/stdio/asprintf.c index 3f1992559..6334cc72a 100644 --- a/libc/stdio/asprintf.c +++ b/libc/stdio/asprintf.c @@ -11,9 +11,7 @@ #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! diff --git a/libc/stdio/ctermid.c b/libc/stdio/ctermid.c index 26369d6f5..854c526ea 100644 --- a/libc/stdio/ctermid.c +++ b/libc/stdio/ctermid.c @@ -7,7 +7,6 @@ #include "_stdio.h" -/* Experimentally off - libc_hidden_proto(strcpy) */ char *ctermid(register char *s) { diff --git a/libc/stdio/dprintf.c b/libc/stdio/dprintf.c index a8b2704b2..3fab12739 100644 --- a/libc/stdio/dprintf.c +++ b/libc/stdio/dprintf.c @@ -11,7 +11,6 @@ #include "_stdio.h" #include <stdarg.h> -libc_hidden_proto(vdprintf) int dprintf(int filedes, const char * __restrict format, ...) { diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c index 27d3c7e96..7e7bc3b5b 100644 --- a/libc/stdio/fclose.c +++ b/libc/stdio/fclose.c @@ -6,10 +6,7 @@ */ #include "_stdio.h" -libc_hidden_proto(fclose) -libc_hidden_proto(close) -libc_hidden_proto(fflush_unlocked) int fclose(register FILE *stream) { @@ -72,8 +69,6 @@ int fclose(register FILE *stream) stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY); #ifndef NDEBUG - __STDIO_STREAM_RESET_GCS(stream); - /* Reinitialize everything (including putc since fflush could fail). */ __STDIO_STREAM_DISABLE_GETC(stream); __STDIO_STREAM_DISABLE_PUTC(stream); diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c index d3cbb67f8..4d78b37d6 100644 --- a/libc/stdio/fcloseall.c +++ b/libc/stdio/fcloseall.c @@ -10,7 +10,6 @@ #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. diff --git a/libc/stdio/fdopen.c b/libc/stdio/fdopen.c index 635ab803d..76c239f4d 100644 --- a/libc/stdio/fdopen.c +++ b/libc/stdio/fdopen.c @@ -7,15 +7,14 @@ #include "_stdio.h" -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) - ? _stdio_fopen(cur_mode, mode, NULL, filedes) - : NULL; + cur_mode = fcntl(filedes, F_GETFL); + if (cur_mode != -1) + return _stdio_fopen(cur_mode, mode, NULL, filedes); + return NULL; } libc_hidden_def(fdopen) diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c index e1527b3a3..cf0356a38 100644 --- a/libc/stdio/fflush.c +++ b/libc/stdio/fflush.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fflush_unlocked) #ifdef __DO_UNLOCKED @@ -19,15 +18,15 @@ libc_hidden_proto(fflush_unlocked) * when all (lbf) writing streams are flushed. */ #define __MY_STDIO_THREADLOCK(__stream) \ - __UCLIBC_MUTEX_CONDITIONAL_LOCK((__stream)->__lock, \ + __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK((__stream)->__lock, \ (_stdio_user_locking != 2)) #define __MY_STDIO_THREADUNLOCK(__stream) \ - __UCLIBC_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock, \ + __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock, \ (_stdio_user_locking != 2)) #if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -void _stdio_openlist_dec_use(void) +void attribute_hidden _stdio_openlist_dec_use(void) { __STDIO_THREADLOCK_OPENLIST_DEL; if ((_stdio_openlist_use_count == 1) && (_stdio_openlist_del_count > 0)) { @@ -98,8 +97,6 @@ int fflush_unlocked(register FILE *stream) while(stream) { /* We only care about currently writing streams and do not want to * block trying to obtain mutexes on non-writing streams. */ -#warning fix for nonatomic -#warning unnecessary check if no threads if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */ __MY_STDIO_THREADLOCK(stream); /* Need to check again once we have the lock. */ @@ -179,14 +176,12 @@ int fflush_unlocked(register FILE *stream) libc_hidden_def(fflush_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fflush) strong_alias(fflush_unlocked,fflush) libc_hidden_def(fflush) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fflush) int fflush(register FILE *stream) { int retval; diff --git a/libc/stdio/fgetc.c b/libc/stdio/fgetc.c index 7eb2b6ea2..56a284c02 100644 --- a/libc/stdio/fgetc.c +++ b/libc/stdio/fgetc.c @@ -13,11 +13,9 @@ #undef getc #undef getc_unlocked -libc_hidden_proto(__fgetc_unlocked) #ifdef __DO_UNLOCKED -libc_hidden_proto(fflush_unlocked) int __fgetc_unlocked(FILE *stream) { @@ -75,20 +73,13 @@ int __fgetc_unlocked(FILE *stream) } 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) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgetc) strong_alias(__fgetc_unlocked,fgetc) libc_hidden_def(fgetc) @@ -97,7 +88,6 @@ strong_alias(__fgetc_unlocked,getc) #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgetc) int fgetc(register FILE *stream) { if (stream->__user_locking != 0) { diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c index 5acaf91ed..bc710c764 100644 --- a/libc/stdio/fgets.c +++ b/libc/stdio/fgets.c @@ -7,11 +7,9 @@ #include "_stdio.h" -libc_hidden_proto(fgets_unlocked) #ifdef __DO_UNLOCKED -libc_hidden_proto(__fgetc_unlocked) char *fgets_unlocked(char *__restrict s, int n, register FILE * __restrict stream) @@ -64,14 +62,12 @@ char *fgets_unlocked(char *__restrict s, int n, libc_hidden_def(fgets_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgets) strong_alias(fgets_unlocked,fgets) libc_hidden_def(fgets) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgets) char *fgets(char *__restrict s, int n, register FILE * __restrict stream) { diff --git a/libc/stdio/fgetwc.c b/libc/stdio/fgetwc.c index 062d825d6..32d9e0ea3 100644 --- a/libc/stdio/fgetwc.c +++ b/libc/stdio/fgetwc.c @@ -7,9 +7,7 @@ #include "_stdio.h" -libc_hidden_proto(fgetwc_unlocked) -libc_hidden_proto(mbrtowc) #ifdef __DO_UNLOCKED @@ -58,12 +56,12 @@ wint_t fgetwc_unlocked(register FILE *stream) stream->__ungot_width[0] = 0; /* then reset the width. */ } - LOOP: + LOOP: if ((n = __STDIO_STREAM_BUFFER_RAVAIL(stream)) == 0) { goto FILL_BUFFER; } - r = mbrtowc(wc, stream->__bufpos, n, &stream->__state); + r = mbrtowc(wc, (const char*) stream->__bufpos, n, &stream->__state); if (((ssize_t) r) >= 0) { /* Success... */ if (r == 0) { /* Nul wide char... means 0 byte for us so */ ++r; /* increment r and handle below as single. */ @@ -78,7 +76,7 @@ wint_t fgetwc_unlocked(register FILE *stream) /* Potentially valid but incomplete and no more buffered. */ stream->__bufpos += n; /* Update bufpos for stream. */ stream->__ungot_width[0] += n; - FILL_BUFFER: + FILL_BUFFER: if(__STDIO_FILL_READ_BUFFER(stream)) { /* Refill succeeded? */ goto LOOP; } @@ -98,7 +96,7 @@ wint_t fgetwc_unlocked(register FILE *stream) * error indicator is set. */ stream->__modeflags |= __FLAG_ERROR; - DONE: + DONE: if (stream->__bufstart == sbuf) { /* Need to un-munge the stream. */ munge_stream(stream, NULL); } @@ -113,7 +111,6 @@ libc_hidden_def(fgetwc_unlocked) strong_alias(fgetwc_unlocked,getwc_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgetwc) strong_alias(fgetwc_unlocked,fgetwc) libc_hidden_def(fgetwc) @@ -122,7 +119,6 @@ strong_alias(fgetwc_unlocked,getwc) #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgetwc) wint_t fgetwc(register FILE *stream) { wint_t retval; diff --git a/libc/stdio/fgetws.c b/libc/stdio/fgetws.c index c7dcc7d2b..b59d74b15 100644 --- a/libc/stdio/fgetws.c +++ b/libc/stdio/fgetws.c @@ -7,9 +7,7 @@ #include "_stdio.h" -libc_hidden_proto(fgetws_unlocked) -libc_hidden_proto(fgetwc_unlocked) #ifdef __DO_UNLOCKED diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c index 929936bfd..452572bae 100644 --- a/libc/stdio/fileno.c +++ b/libc/stdio/fileno.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fileno_unlocked) #ifdef __DO_UNLOCKED @@ -25,14 +24,12 @@ int fileno_unlocked(register FILE *stream) libc_hidden_def(fileno_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fileno) strong_alias(fileno_unlocked,fileno) libc_hidden_def(fileno) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fileno) int fileno(register FILE *stream) { int retval; diff --git a/libc/stdio/fmemopen.c b/libc/stdio/fmemopen.c index ba194d726..4a67376f5 100644 --- a/libc/stdio/fmemopen.c +++ b/libc/stdio/fmemopen.c @@ -10,8 +10,6 @@ #ifdef __USE_GNU #include "_stdio.h" -/* Experimentally off - libc_hidden_proto(memcpy) */ -libc_hidden_proto(fopencookie) #ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ #error no custom streams! diff --git a/libc/stdio/fopen.c b/libc/stdio/fopen.c index ec14b5956..a2d6617e8 100644 --- a/libc/stdio/fopen.c +++ b/libc/stdio/fopen.c @@ -9,12 +9,11 @@ #ifndef __DO_LARGEFILE # define FILEDES_ARG (-1) -#undef fopen +# undef fopen #else -#undef fopen64 +# undef fopen64 #endif -libc_hidden_proto(fopen) FILE *fopen(const char * __restrict filename, const char * __restrict mode) { return _stdio_fopen(((intptr_t) filename), mode, NULL, FILEDES_ARG); diff --git a/libc/stdio/fopencookie.c b/libc/stdio/fopencookie.c index 0b7ed84b1..216dac39d 100644 --- a/libc/stdio/fopencookie.c +++ b/libc/stdio/fopencookie.c @@ -31,7 +31,6 @@ /* Currently no real reentrancy issues other than a possible double close(). */ #ifndef __BCC__ -libc_hidden_proto(fopencookie) FILE *fopencookie(void * __restrict cookie, const char * __restrict mode, cookie_io_functions_t io_functions) #else @@ -40,21 +39,34 @@ FILE *_fopencookie(void * __restrict cookie, const char * __restrict mode, #endif { FILE *stream; + _IO_cookie_file_t *new_f; + new_f = malloc(sizeof(_IO_cookie_file_t)); + if (new_f == NULL) { + return NULL; + } + new_f->__fp.__modeflags = __FLAG_FREEFILE; +#ifdef __STDIO_BUFFERS + new_f->__fp.__bufstart = NULL; /* We allocate a buffer below. */ +#endif +#ifdef __UCLIBC_HAS_THREADS__ + /* We only initialize the mutex in the non-freopen case. */ + STDIO_INIT_MUTEX(new_f->__fp.__lock); +#endif /* Fake an fdopen guaranteed to pass the _stdio_fopen basic agreement * check without an fcntl call. */ - stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, NULL, INT_MAX); + stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, &new_f->__fp, INT_MAX); if (stream) { - stream->__filedes = -1; + stream->__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES; #ifndef __BCC__ - stream->__gcs = io_functions; + new_f->__gcs = io_functions; #else - stream->__gcs.read = io_functions->read; - stream->__gcs.write = io_functions->write; - stream->__gcs.seek = io_functions->seek; - stream->__gcs.close = io_functions->close; + new_f->__gcs.read = io_functions->read; + new_f->__gcs.write = io_functions->write; + new_f->__gcs.seek = io_functions->seek; + new_f->__gcs.close = io_functions->close; #endif - stream->__cookie = cookie; + new_f->__cookie = cookie; __STDIO_STREAM_VALIDATE(stream); } diff --git a/libc/stdio/fprintf.c b/libc/stdio/fprintf.c index 4f73441e1..fb7549566 100644 --- a/libc/stdio/fprintf.c +++ b/libc/stdio/fprintf.c @@ -8,9 +8,7 @@ #include "_stdio.h" #include <stdarg.h> -libc_hidden_proto(vfprintf) -libc_hidden_proto(fprintf) int fprintf(FILE * __restrict stream, const char * __restrict format, ...) { va_list arg; diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c index ac3b23ec5..7876d77af 100644 --- a/libc/stdio/fputc.c +++ b/libc/stdio/fputc.c @@ -12,7 +12,6 @@ #undef putc #undef putc_unlocked -libc_hidden_proto(__fputc_unlocked) #ifdef __DO_UNLOCKED @@ -72,28 +71,18 @@ int __fputc_unlocked(int c, register FILE *stream) } libc_hidden_def(__fputc_unlocked) -/* exposing these would be fundamentally *wrong*! fix you, instead! */ -/* libc_hidden_proto(fputc_unlocked) */ strong_alias(__fputc_unlocked,fputc_unlocked) -/* exposing these would be fundamentally *wrong*! fix you, instead! */ -/* libc_hidden_def(fputc_unlocked) */ -libc_hidden_proto(putc_unlocked) strong_alias(__fputc_unlocked,putc_unlocked) -libc_hidden_def(putc_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fputc) strong_alias(__fputc_unlocked,fputc) libc_hidden_def(fputc) -libc_hidden_proto(putc) strong_alias(__fputc_unlocked,putc) -libc_hidden_def(putc) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fputc) int fputc(int c, register FILE *stream) { if (stream->__user_locking != 0) { @@ -108,8 +97,6 @@ int fputc(int c, register FILE *stream) } libc_hidden_def(fputc) -libc_hidden_proto(putc) strong_alias(fputc,putc) -libc_hidden_def(putc) #endif diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c index 8a5fd4087..b3ede6871 100644 --- a/libc/stdio/fputs.c +++ b/libc/stdio/fputs.c @@ -7,10 +7,7 @@ #include "_stdio.h" -libc_hidden_proto(fputs_unlocked) -/* Experimentally off - 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 @@ -29,14 +26,12 @@ int fputs_unlocked(register const char * __restrict s, libc_hidden_def(fputs_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fputs) strong_alias(fputs_unlocked,fputs) libc_hidden_def(fputs) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fputs) int fputs(const char * __restrict s, register FILE * __restrict stream) { int retval; diff --git a/libc/stdio/fputwc.c b/libc/stdio/fputwc.c index 240c1e9c4..b699e9d4b 100644 --- a/libc/stdio/fputwc.c +++ b/libc/stdio/fputwc.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fputwc_unlocked) #ifdef __DO_UNLOCKED @@ -20,6 +19,7 @@ libc_hidden_def(fputwc_unlocked) strong_alias(fputwc_unlocked,putwc_unlocked) #ifndef __UCLIBC_HAS_THREADS__ strong_alias(fputwc_unlocked,fputwc) +libc_hidden_def(fputwc) strong_alias(fputwc_unlocked,putwc) #endif @@ -38,6 +38,7 @@ wint_t fputwc(wchar_t wc, register FILE *stream) return retval; } +libc_hidden_def(fputwc) strong_alias(fputwc,putwc) diff --git a/libc/stdio/fputws.c b/libc/stdio/fputws.c index ecbc121dd..7a1892188 100644 --- a/libc/stdio/fputws.c +++ b/libc/stdio/fputws.c @@ -7,9 +7,7 @@ #include "_stdio.h" -libc_hidden_proto(fputws_unlocked) -libc_hidden_proto(wcslen) #ifdef __DO_UNLOCKED @@ -23,14 +21,12 @@ int fputws_unlocked(const wchar_t *__restrict ws, libc_hidden_def(fputws_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fputws) strong_alias(fputws_unlocked,fputws) libc_hidden_def(fputws) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fputws) int fputws(const wchar_t *__restrict ws, register FILE *__restrict stream) { int retval; diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 4f9c98465..5df33b468 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -7,18 +7,15 @@ #include "_stdio.h" -libc_hidden_proto(fread_unlocked) #ifdef __DO_UNLOCKED -/* Experimentally off - 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); - assert(stream->__filedes >= -1); + assert(stream->__filedes >= -2); /* Note: If nmbem * size > SIZE_MAX then there is an application * bug since no array can be larger than SIZE_MAX in size. */ @@ -90,14 +87,12 @@ size_t fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb, libc_hidden_def(fread_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fread) strong_alias(fread_unlocked,fread) libc_hidden_def(fread) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fread) size_t fread(void * __restrict ptr, size_t size, size_t nmemb, register FILE * __restrict stream) { diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c index 942a67991..f48a43b73 100644 --- a/libc/stdio/freopen.c +++ b/libc/stdio/freopen.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fclose) #ifndef __DO_LARGEFILE # define FILEDES_ARG (-1) diff --git a/libc/stdio/fseeko.c b/libc/stdio/fseeko.c index 251040231..16b0c043a 100644 --- a/libc/stdio/fseeko.c +++ b/libc/stdio/fseeko.c @@ -16,11 +16,6 @@ # define OFFSET_TYPE long int #endif -#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) @@ -82,5 +77,5 @@ int FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence) libc_hidden_def(fseeko64) #else libc_hidden_def(fseek) -strong_alias(fseek,fseeko) +strong_alias_untyped(fseek,fseeko) #endif diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c index bae1d877c..219b6996a 100644 --- a/libc/stdio/ftello.c +++ b/libc/stdio/ftello.c @@ -7,11 +7,6 @@ #include "_stdio.h" -#ifdef __UCLIBC_HAS_LFS__ -libc_hidden_proto(ftello64) -#endif -libc_hidden_proto(ftell) - #ifndef __DO_LARGEFILE # define FTELL ftell # define OFFSET_TYPE long int @@ -58,5 +53,5 @@ OFFSET_TYPE FTELL(register FILE *stream) libc_hidden_def(ftello64) #else libc_hidden_def(ftell) -strong_alias(ftell,ftello) +strong_alias_untyped(ftell,ftello) #endif diff --git a/libc/stdio/fwprintf.c b/libc/stdio/fwprintf.c index f2a1afbec..954970867 100644 --- a/libc/stdio/fwprintf.c +++ b/libc/stdio/fwprintf.c @@ -9,7 +9,6 @@ #include <stdarg.h> #include <wchar.h> -libc_hidden_proto(vfwprintf) int fwprintf(FILE * __restrict stream, const wchar_t * __restrict format, ...) { diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c index 7be794ab4..71793ff26 100644 --- a/libc/stdio/fwrite.c +++ b/libc/stdio/fwrite.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fwrite_unlocked) #ifdef __DO_UNLOCKED @@ -38,14 +37,12 @@ size_t fwrite_unlocked(const void * __restrict ptr, size_t size, libc_hidden_def(fwrite_unlocked) #ifndef __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fwrite) strong_alias(fwrite_unlocked,fwrite) libc_hidden_def(fwrite) #endif #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fwrite) size_t fwrite(const void * __restrict ptr, size_t size, size_t nmemb, register FILE * __restrict stream) { diff --git a/libc/stdio/getchar.c b/libc/stdio/getchar.c index e29c426c8..b6c650c9b 100644 --- a/libc/stdio/getchar.c +++ b/libc/stdio/getchar.c @@ -7,14 +7,12 @@ #include "_stdio.h" -libc_hidden_proto(__fgetc_unlocked) #undef getchar #ifdef __DO_UNLOCKED /* the only use of the hidden getchar_unlocked is in gets.c */ #undef getchar_unlocked -libc_hidden_proto(getchar_unlocked) int getchar_unlocked(void) { register FILE *stream = stdin; diff --git a/libc/stdio/getdelim.c b/libc/stdio/getdelim.c index 21c86f400..987e32a19 100644 --- a/libc/stdio/getdelim.c +++ b/libc/stdio/getdelim.c @@ -10,9 +10,7 @@ #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). */ diff --git a/libc/stdio/getline.c b/libc/stdio/getline.c index 22b67b831..98ce8d108 100644 --- a/libc/stdio/getline.c +++ b/libc/stdio/getline.c @@ -10,9 +10,7 @@ #ifdef __USE_GNU #include "_stdio.h" -libc_hidden_proto(getline) -libc_hidden_proto(getdelim) ssize_t getline(char **__restrict lineptr, size_t *__restrict n, FILE *__restrict stream) diff --git a/libc/stdio/gets.c b/libc/stdio/gets.c index 85bb8475a..9f4b751a1 100644 --- a/libc/stdio/gets.c +++ b/libc/stdio/gets.c @@ -7,13 +7,10 @@ #include "_stdio.h" -link_warning(gets, "the 'gets' function is dangerous and should not be used.") - /* UNSAFE FUNCTION -- do not bother optimizing */ /* disable macro, force actual function call */ #undef getchar_unlocked -libc_hidden_proto(getchar_unlocked) char *gets(char *s) { diff --git a/libc/stdio/getw.c b/libc/stdio/getw.c index e3aeda92c..625f17f3e 100644 --- a/libc/stdio/getw.c +++ b/libc/stdio/getw.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fread_unlocked) /* SUSv2 Legacy function -- need not be reentrant. */ diff --git a/libc/stdio/getwchar.c b/libc/stdio/getwchar.c index 9c480b564..75266de3a 100644 --- a/libc/stdio/getwchar.c +++ b/libc/stdio/getwchar.c @@ -9,7 +9,6 @@ #ifdef __DO_UNLOCKED -libc_hidden_proto(fgetwc_unlocked) wint_t getwchar_unlocked(void) { @@ -22,7 +21,6 @@ strong_alias(getwchar_unlocked,getwchar) #elif defined __UCLIBC_HAS_THREADS__ -libc_hidden_proto(fgetwc) wint_t getwchar(void) { diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c index a7ec28d8d..75bf3413e 100644 --- a/libc/stdio/old_vfprintf.c +++ b/libc/stdio/old_vfprintf.c @@ -127,9 +127,7 @@ /**************************************************************************/ -#define _ISOC99_SOURCE /* for ULLONG primarily... */ #include "_stdio.h" -/* #include <stdio.h> */ #include <stdarg.h> #include <limits.h> #include <stdint.h> @@ -137,20 +135,9 @@ #include <errno.h> #include <ctype.h> #include <bits/uClibc_uintmaxtostr.h> -#include <printf.h> -#ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h> -#endif /* __UCLIBC_HAS_THREADS__ */ +#include "_fpmaxtostr.h" -/* Experimentally off - libc_hidden_proto(strlen) */ -/* Experimentally off - libc_hidden_proto(strnlen) */ -/* Experimentally off - 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 */ @@ -214,14 +201,6 @@ static void putc_unlocked_sprintf(int c, __FILE_vsnprintf *f) #endif /* __STDIO_BUFFERS */ #ifdef __UCLIBC_HAS_FLOATS__ -#include <float.h> -#include <bits/uClibc_fpmax.h> - -typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, - intptr_t buf); - -extern size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, - __fp_outfunc_t fp_outfunc) attribute_hidden; static void _charpad(FILE * __restrict stream, int padchar, size_t numpad) { @@ -265,9 +244,6 @@ static const char spec[] = "+-#0 "; /**********************************************************************/ -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; - /* * 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 @@ -343,7 +319,6 @@ 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"; -libc_hidden_proto(vfprintf) int vfprintf(FILE * __restrict op, register const char * __restrict fmt, va_list ap) { diff --git a/libc/stdio/open_memstream.c b/libc/stdio/open_memstream.c index 5861017e4..17ef191cb 100644 --- a/libc/stdio/open_memstream.c +++ b/libc/stdio/open_memstream.c @@ -10,9 +10,6 @@ #ifdef __USE_GNU #include "_stdio.h" -/* Experimentally off - libc_hidden_proto(memcpy) */ -/* Experimentally off - libc_hidden_proto(memset) */ -libc_hidden_proto(fopencookie) #ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ #error no custom streams! @@ -20,6 +17,8 @@ libc_hidden_proto(fopencookie) #define COOKIE ((__oms_cookie *) cookie) +#define MEMSTREAM_BUFSIZ 256 + typedef struct { char *buf; size_t len; @@ -131,14 +130,13 @@ 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). */ -libc_hidden_proto(open_memstream) -FILE *open_memstream(char **__restrict bufloc, size_t *__restrict sizeloc) +FILE *open_memstream(char **bufloc, size_t *sizeloc) { register __oms_cookie *cookie; register FILE *fp; if ((cookie = malloc(sizeof(__oms_cookie))) != NULL) { - if ((cookie->buf = malloc(cookie->len = BUFSIZ)) == NULL) { + if ((cookie->buf = malloc(cookie->len = MEMSTREAM_BUFSIZ)) == NULL) { goto EXIT_cookie; } *cookie->buf = 0; /* Set nul terminator for buffer. */ diff --git a/libc/stdio/perror.c b/libc/stdio/perror.c index 993fcf428..8b943e467 100644 --- a/libc/stdio/perror.c +++ b/libc/stdio/perror.c @@ -7,14 +7,11 @@ #include "_stdio.h" -libc_hidden_proto(fprintf) -libc_hidden_proto(__glibc_strerror_r) #ifdef __UCLIBC_MJN3_ONLY__ #warning CONSIDER: Increase buffer size for error message (non-%m case)? #endif -libc_hidden_proto(perror) void perror(register const char *s) { /* If the program is calling perror, it's a safe bet that printf and diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index 43d07fa0f..1efbd3b7a 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -17,6 +17,7 @@ #include <stdio.h> #include <stdlib.h> +#include <paths.h> #include <errno.h> #include <unistd.h> #include <sys/wait.h> @@ -26,25 +27,6 @@ #warning "hmm... susv3 says Pipe streams are byte-oriented." #endif /* __UCLIBC_MJN3_ONLY__ */ -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 - #ifndef VFORK_LOCK __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); # define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock) @@ -110,7 +92,7 @@ FILE *popen(const char *command, const char *modes) close(po->f->__filedes); } - execl("/bin/sh", "sh", "-c", command, (char *)0); + execl(_PATH_BSHELL, "sh", "-c", command, (char *)0); /* SUSv3 mandates an exit code of 127 for the child if the * command interpreter can not be invoked. */ @@ -143,12 +125,10 @@ FILE *popen(const char *command, const char *modes) return NULL; } -#warning is pclose correct wrt the new mutex semantics? - int pclose(FILE *stream) { struct popen_list_item *p; - int stat; + int status; pid_t pid; /* First, find the list entry corresponding to stream and remove it @@ -183,8 +163,8 @@ int pclose(FILE *stream) /* SUSv3 specificly requires that pclose not return before the child * terminates, in order to disallow pclose from returning on EINTR. */ do { - if (waitpid(pid, &stat, 0) >= 0) { - return stat; + if (waitpid(pid, &status, 0) >= 0) { + return status; } if (errno != EINTR) { break; diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 617561fec..8cd3db9f1 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -8,9 +8,7 @@ #include "_stdio.h" #include <stdarg.h> -libc_hidden_proto(vfprintf) -libc_hidden_proto(printf) int printf(const char * __restrict format, ...) { va_list arg; diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c index b54a7a815..583e90f44 100644 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(__fputc_unlocked) #undef putchar #ifdef __DO_UNLOCKED diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c index 08525b2f6..67775ff7c 100644 --- a/libc/stdio/puts.c +++ b/libc/stdio/puts.c @@ -7,8 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(__fputc_unlocked) -libc_hidden_proto(fputs_unlocked) int puts(register const char * __restrict s) { diff --git a/libc/stdio/putw.c b/libc/stdio/putw.c index 469e44aea..ffdb11478 100644 --- a/libc/stdio/putw.c +++ b/libc/stdio/putw.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(fwrite_unlocked) /* SUSv2 Legacy function -- need not be reentrant. */ diff --git a/libc/stdio/putwchar.c b/libc/stdio/putwchar.c index 7a6501c28..96de6a285 100644 --- a/libc/stdio/putwchar.c +++ b/libc/stdio/putwchar.c @@ -9,8 +9,6 @@ #ifdef __DO_UNLOCKED -libc_hidden_proto(fputwc_unlocked) - wint_t putwchar_unlocked(wchar_t wc) { return fputwc_unlocked(wc, stdout); @@ -22,13 +20,9 @@ strong_alias(putwchar_unlocked,putwchar) #elif defined __UCLIBC_HAS_THREADS__ -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 fputwc(wc, stdout); } #endif diff --git a/libc/stdio/remove.c b/libc/stdio/remove.c index f322411e4..af2850733 100644 --- a/libc/stdio/remove.c +++ b/libc/stdio/remove.c @@ -10,22 +10,19 @@ #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). */ -libc_hidden_proto(remove) int remove(register const char *filename) { int saved_errno = errno; int rv; - if (((rv = rmdir(filename)) < 0) && (errno == ENOTDIR)) { + rv = rmdir(filename); + if ((rv < 0) && (errno == ENOTDIR)) { __set_errno(saved_errno); /* Need to restore errno. */ rv = unlink(filename); } diff --git a/libc/stdio/rewind.c b/libc/stdio/rewind.c index e04d7a086..1b170443a 100644 --- a/libc/stdio/rewind.c +++ b/libc/stdio/rewind.c @@ -7,9 +7,7 @@ #include "_stdio.h" -libc_hidden_proto(fseek) -libc_hidden_proto(rewind) void rewind(register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; diff --git a/libc/stdio/setbuf.c b/libc/stdio/setbuf.c index 6de2c91a1..e6080a522 100644 --- a/libc/stdio/setbuf.c +++ b/libc/stdio/setbuf.c @@ -7,7 +7,6 @@ #include "_stdio.h" -libc_hidden_proto(setvbuf) void setbuf(FILE * __restrict stream, register char * __restrict buf) { diff --git a/libc/stdio/setbuffer.c b/libc/stdio/setbuffer.c index ea2421aa8..b566bfc39 100644 --- a/libc/stdio/setbuffer.c +++ b/libc/stdio/setbuffer.c @@ -9,7 +9,6 @@ #ifdef __USE_BSD -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 diff --git a/libc/stdio/setlinebuf.c b/libc/stdio/setlinebuf.c index 9b4be53eb..932338886 100644 --- a/libc/stdio/setlinebuf.c +++ b/libc/stdio/setlinebuf.c @@ -9,7 +9,6 @@ #ifdef __USE_BSD -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 diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c index 6dbb532db..0b0ea0dde 100644 --- a/libc/stdio/setvbuf.c +++ b/libc/stdio/setvbuf.c @@ -14,7 +14,6 @@ #error Assumption violated for buffering mode flags #endif -libc_hidden_proto(setvbuf) int setvbuf(register FILE * __restrict stream, register char * __restrict buf, int mode, size_t size) { diff --git a/libc/stdio/snprintf.c b/libc/stdio/snprintf.c index ef9c69215..e0902ac70 100644 --- a/libc/stdio/snprintf.c +++ b/libc/stdio/snprintf.c @@ -12,9 +12,7 @@ #warning Skipping snprintf since no vsnprintf! #else -libc_hidden_proto(vsnprintf) -libc_hidden_proto(snprintf) int snprintf(char *__restrict buf, size_t size, const char * __restrict format, ...) { diff --git a/libc/stdio/sprintf.c b/libc/stdio/sprintf.c index 360245366..44304b5da 100644 --- a/libc/stdio/sprintf.c +++ b/libc/stdio/sprintf.c @@ -12,9 +12,7 @@ #warning Skipping sprintf since no vsnprintf! #else -libc_hidden_proto(vsnprintf) -libc_hidden_proto(sprintf) int sprintf(char *__restrict buf, const char * __restrict format, ...) { va_list arg; diff --git a/libc/stdio/swprintf.c b/libc/stdio/swprintf.c index 0c209fe4b..8e037d20d 100644 --- a/libc/stdio/swprintf.c +++ b/libc/stdio/swprintf.c @@ -9,7 +9,6 @@ #include <stdarg.h> #include <wchar.h> -libc_hidden_proto(vswprintf) #ifndef __STDIO_BUFFERS #warning Skipping swprintf since no buffering! diff --git a/libc/stdio/tempnam.c b/libc/stdio/tempnam.c index 3673f4bda..46c921014 100644 --- a/libc/stdio/tempnam.c +++ b/libc/stdio/tempnam.c @@ -13,14 +13,12 @@ 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. */ + see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <string.h> #include "../misc/internals/tempname.h" -/* Experimentally off - 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 @@ -37,9 +35,8 @@ tempnam (const char *dir, const char *pfx) if (__path_search (buf, FILENAME_MAX, dir, pfx, 1)) return NULL; - if (__gen_tempname (buf, __GT_NOCREATE)) + if (__gen_tempname (buf, __GT_NOCREATE, 0, 0, 0)) return NULL; return strdup (buf); } - diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c index f83944539..3654f9e3a 100644 --- a/libc/stdio/tmpfile.c +++ b/libc/stdio/tmpfile.c @@ -13,17 +13,15 @@ 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. */ + see <http://www.gnu.org/licenses/>. */ #include <features.h> #include <stdio.h> +#include <sys/stat.h> #include <unistd.h> #include "../misc/internals/tempname.h" +#include <not-cancel.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). @@ -37,7 +35,7 @@ FILE * tmpfile (void) if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) return NULL; - fd = __gen_tempname (buf, __GT_FILE); + fd = __gen_tempname (buf, __GT_FILE, 0, 0, S_IRUSR | S_IWUSR); if (fd < 0) return NULL; @@ -46,7 +44,7 @@ FILE * tmpfile (void) (void) remove (buf); if ((f = fdopen (fd, "w+b")) == NULL) - close (fd); + close_not_cancel (fd); return f; } diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c index 8df6ff57f..a9f67962e 100644 --- a/libc/stdio/tmpnam.c +++ b/libc/stdio/tmpnam.c @@ -12,15 +12,13 @@ Lesser General Public License for more details. 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. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <string.h> #include "../misc/internals/tempname.h" -/* Experimentally off - libc_hidden_proto(memcpy) */ static char tmpnam_buffer[L_tmpnam]; @@ -42,7 +40,7 @@ tmpnam (char *s) 0)) return NULL; - if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE), 0)) + if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0, 0, 0), 0)) return NULL; if (s == NULL) @@ -50,6 +48,3 @@ tmpnam (char *s) return s; } - -link_warning (tmpnam, - "the use of `tmpnam' is dangerous, better use `mkstemp'") diff --git a/libc/stdio/tmpnam_r.c b/libc/stdio/tmpnam_r.c index eec589e39..2e70c2da6 100644 --- a/libc/stdio/tmpnam_r.c +++ b/libc/stdio/tmpnam_r.c @@ -13,8 +13,7 @@ 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. */ + see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include "../misc/internals/tempname.h" @@ -28,7 +27,7 @@ char * tmpnam_r (char *s) if (__path_search (s, L_tmpnam, NULL, NULL, 0)) return NULL; - if (__gen_tempname (s, __GT_NOCREATE)) + if (__gen_tempname (s, __GT_NOCREATE, 0, 0, 0)) return NULL; return s; diff --git a/libc/stdio/ungetc.c b/libc/stdio/ungetc.c index d900928b2..ea4edd22c 100644 --- a/libc/stdio/ungetc.c +++ b/libc/stdio/ungetc.c @@ -24,7 +24,6 @@ * (See section 7.19.6.2 of the C9X rationale -- WG14/N897.) */ -libc_hidden_proto(ungetc) int ungetc(int c, register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; diff --git a/libc/stdio/ungetwc.c b/libc/stdio/ungetwc.c index 579022240..25b12b887 100644 --- a/libc/stdio/ungetwc.c +++ b/libc/stdio/ungetwc.c @@ -12,7 +12,6 @@ * as reset stream->__ungot_width[1] for use by _stdio_adjpos(). */ -libc_hidden_proto(ungetwc) wint_t ungetwc(wint_t c, register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c index b7e2e0852..fa7926c60 100644 --- a/libc/stdio/vasprintf.c +++ b/libc/stdio/vasprintf.c @@ -22,15 +22,6 @@ #warning Skipping vasprintf since no vsnprintf! #else -#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) { @@ -48,6 +39,8 @@ int vasprintf(char **__restrict buf, const char * __restrict format, if (rv < 0) { free(*buf); *buf = NULL; + } else { + *buf = realloc(*buf, rv + 1); } } diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c index 6e28b14c0..46b8dfe39 100644 --- a/libc/stdio/vdprintf.c +++ b/libc/stdio/vdprintf.c @@ -11,12 +11,7 @@ #include "_stdio.h" #include <stdarg.h> -#ifdef __USE_OLD_VFPRINTF__ -libc_hidden_proto(vfprintf) -#endif -libc_hidden_proto(fflush_unlocked) -libc_hidden_proto(vdprintf) int vdprintf(int filedes, const char * __restrict format, va_list arg) { FILE f; @@ -31,30 +26,21 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg) __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f); #endif -/* __STDIO_STREAM_RESET_GCS(&f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ - f.__cookie = &(f.__filedes); - f.__gcs.read = NULL; - f.__gcs.write = _cs_write; - f.__gcs.seek = NULL; - f.__gcs.close = NULL; -#endif - f.__filedes = filedes; f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); #ifdef __UCLIBC_HAS_WCHAR__ f.__ungot_width[0] = 0; -#endif /* __UCLIBC_HAS_WCHAR__ */ +#endif #ifdef __STDIO_MBSTATE __INIT_MBSTATE(&(f.__state)); -#endif /* __STDIO_MBSTATE */ +#endif /* _vfprintf_internal doesn't do any locking, locking init is here * only because of fflush_unlocked. TODO? */ #if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__) f.__user_locking = 1; /* Set user locking. */ - __stdio_init_mutex(&f.__lock); + STDIO_INIT_MUTEX(f.__lock); #endif f.__nextopen = NULL; diff --git a/libc/stdio/vprintf.c b/libc/stdio/vprintf.c index 7848a078d..853f340cc 100644 --- a/libc/stdio/vprintf.c +++ b/libc/stdio/vprintf.c @@ -8,7 +8,6 @@ #include "_stdio.h" #include <stdarg.h> -libc_hidden_proto(vfprintf) int vprintf(const char * __restrict format, va_list arg) { diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c index e5a14d51a..3a4c60794 100644 --- a/libc/stdio/vsnprintf.c +++ b/libc/stdio/vsnprintf.c @@ -8,11 +8,6 @@ #include "_stdio.h" #include <stdarg.h> -libc_hidden_proto(vsnprintf) - -#ifdef __USE_OLD_VFPRINTF__ -libc_hidden_proto(vfprintf) -#endif #ifdef __UCLIBC_MJN3_ONLY__ #warning WISHLIST: Implement vsnprintf for non-buffered and no custom stream case. @@ -27,15 +22,6 @@ int vsnprintf(char *__restrict buf, size_t size, FILE f; int rv; -/* __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_VSNPRINTF_FILEDES; f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); @@ -46,9 +32,9 @@ int vsnprintf(char *__restrict buf, size_t size, __INIT_MBSTATE(&(f.__state)); #endif /* __STDIO_MBSTATE */ -#if defined(__USE_OLD_VFPRINTF__) && defined(__UCLIBC_HAS_THREADS__) +#if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__) f.__user_locking = 1; /* Set user locking. */ - __stdio_init_mutex(&f.__lock); + STDIO_INIT_MUTEX(f.__lock); #endif f.__nextopen = NULL; @@ -101,15 +87,6 @@ int vsnprintf(char *__restrict buf, size_t size, } f.bufend = buf + size; -/* __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_VSNPRINTF_FILEDES_NB; f.f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); @@ -122,7 +99,7 @@ int vsnprintf(char *__restrict buf, size_t size, #ifdef __UCLIBC_HAS_THREADS__ f.f.__user_locking = 1; /* Set user locking. */ - __stdio_init_mutex(&f.f.__lock); + STDIO_INIT_MUTEX(f.f.__lock); #endif f.f.__nextopen = NULL; @@ -142,7 +119,7 @@ libc_hidden_def(vsnprintf) typedef struct { size_t pos; size_t len; - unsigned char *buf; + char *buf; FILE *fp; } __snpf_cookie; @@ -180,34 +157,34 @@ static ssize_t snpf_write(register void *cookie, const char *buf, int vsnprintf(char *__restrict buf, size_t size, const char * __restrict format, va_list arg) { - FILE f; + _IO_cookie_file_t cf; __snpf_cookie cookie; int rv; cookie.buf = buf; cookie.len = size; cookie.pos = 0; - cookie.fp = &f; + cookie.fp = &cf.__fp; - f.__cookie = &cookie; - f.__gcs.write = snpf_write; - f.__gcs.read = NULL; - f.__gcs.seek = NULL; - f.__gcs.close = NULL; + cf.__cookie = &cookie; + cf.__gcs.write = snpf_write; + cf.__gcs.read = NULL; + cf.__gcs.seek = NULL; + cf.__gcs.close = NULL; - f.__filedes = -1; /* For debugging. */ - f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); + cf.__fp.__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES; + cf.__fp.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); #ifdef __UCLIBC_HAS_WCHAR__ - f.__ungot_width[0] = 0; + cf.__fp.__ungot_width[0] = 0; #endif /* __UCLIBC_HAS_WCHAR__ */ #ifdef __STDIO_MBSTATE - __INIT_MBSTATE(&(f.__state)); + __INIT_MBSTATE(&(cf.__fp.__state)); #endif /* __STDIO_MBSTATE */ - f.__nextopen = NULL; + cf.__fp.__nextopen = NULL; - rv = _vfprintf_internal(&f, format, arg); + rv = _vfprintf_internal(&cf.__fp, format, arg); return rv; } diff --git a/libc/stdio/vsprintf.c b/libc/stdio/vsprintf.c index 8e27c19d9..d87090147 100644 --- a/libc/stdio/vsprintf.c +++ b/libc/stdio/vsprintf.c @@ -12,7 +12,6 @@ #warning Skipping vsprintf since no vsnprintf! #else -libc_hidden_proto(vsnprintf) int vsprintf(char *__restrict buf, const char * __restrict format, va_list arg) diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c index cddf1d5d9..58a06a763 100644 --- a/libc/stdio/vswprintf.c +++ b/libc/stdio/vswprintf.c @@ -9,7 +9,6 @@ #include <stdarg.h> #include <wchar.h> -libc_hidden_proto(vswprintf) /* NB: this file is not used if __USE_OLD_VFPRINTF__ */ @@ -23,15 +22,6 @@ int vswprintf(wchar_t *__restrict buf, size_t size, FILE f; int rv; -/* __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_VSWPRINTF_FILEDES; f.__modeflags = (__FLAG_WIDE|__FLAG_WRITEONLY|__FLAG_WRITING); @@ -40,14 +30,19 @@ int vswprintf(wchar_t *__restrict buf, size_t size, __INIT_MBSTATE(&(f.__state)); #endif /* __STDIO_MBSTATE */ +#ifdef __UCLIBC_HAS_THREADS__ + f.__user_locking = 1; /* Set user locking. */ + STDIO_INIT_MUTEX(f.__lock); +#endif /* __UCLIBC_HAS_THREADS__ */ + f.__nextopen = NULL; if (size > ((SIZE_MAX - (size_t) buf)/sizeof(wchar_t))) { size = ((SIZE_MAX - (size_t) buf)/sizeof(wchar_t)); } - f.__bufstart = (char *) buf; - f.__bufend = (char *)(buf + size); + f.__bufstart = (unsigned char *) buf; + f.__bufend = (unsigned char *) (buf + size); __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f); __STDIO_STREAM_DISABLE_GETC(&f); __STDIO_STREAM_DISABLE_PUTC(&f); @@ -58,7 +53,7 @@ int vswprintf(wchar_t *__restrict buf, size_t size, if (f.__bufpos == f.__bufend) { rv = -1; if (size) { - f.__bufpos = (char *)(((wchar_t *) f.__bufpos) - 1); + f.__bufpos = (unsigned char *) (((wchar_t *) f.__bufpos) - 1); } } if (size) { diff --git a/libc/stdio/vwprintf.c b/libc/stdio/vwprintf.c index 1c32887a4..25dd5b3fa 100644 --- a/libc/stdio/vwprintf.c +++ b/libc/stdio/vwprintf.c @@ -9,7 +9,6 @@ #include <stdarg.h> #include <wchar.h> -libc_hidden_proto(vfwprintf) int vwprintf(const wchar_t * __restrict format, va_list arg) { diff --git a/libc/stdio/wprintf.c b/libc/stdio/wprintf.c index 9dc274aec..b3a6318a5 100644 --- a/libc/stdio/wprintf.c +++ b/libc/stdio/wprintf.c @@ -9,7 +9,6 @@ #include <stdarg.h> #include <wchar.h> -libc_hidden_proto(vfwprintf) int wprintf(const wchar_t * __restrict format, ...) { |
