diff options
author | "Steven J. Hill" <sjhill@realitydiluted.com> | 2006-02-25 04:03:33 +0000 |
---|---|---|
committer | "Steven J. Hill" <sjhill@realitydiluted.com> | 2006-02-25 04:03:33 +0000 |
commit | cb6a88484ce0b5ffba2fe98a40e2d51f4af92eb8 (patch) | |
tree | 520f8e8d113184cfa7954ebd274564b8c255fa9a /libc/stdlib | |
parent | e4461be66e2655058aef358b00050bc70ac72861 (diff) | |
download | uClibc-alpine-cb6a88484ce0b5ffba2fe98a40e2d51f4af92eb8.tar.bz2 uClibc-alpine-cb6a88484ce0b5ffba2fe98a40e2d51f4af92eb8.tar.xz |
Merge from trunk. Going pretty good so far. Kind of. Okay, not really.
Diffstat (limited to 'libc/stdlib')
126 files changed, 2286 insertions, 1603 deletions
diff --git a/libc/stdlib/Makefile.in b/libc/stdlib/Makefile.in index 52527e1e5..202e25df2 100644 --- a/libc/stdlib/Makefile.in +++ b/libc/stdlib/Makefile.in @@ -1,7 +1,7 @@ # Makefile for uClibc # # Copyright (C) 2000 by Lineo, inc. -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # @@ -10,133 +10,82 @@ include $(top_srcdir)libc/stdlib/malloc/Makefile.in include $(top_srcdir)libc/stdlib/malloc-simple/Makefile.in include $(top_srcdir)libc/stdlib/malloc-standard/Makefile.in -MSRC1:=stdlib.c -MOBJ1:= abs.o labs.o atoi.o atol.o strtol.o strtoul.o _stdlib_strto_l.o \ - qsort.o bsearch.o \ - llabs.o atoll.o strtoll.o strtoull.o _stdlib_strto_ll.o -# (aliases) strtoq.o strtouq.o -ifeq ($(UCLIBC_HAS_XLOCALE),y) -MOBJ1x:=strtol_l.o strtoul_l.o _stdlib_strto_l_l.o \ - strtoll_l.o strtoull_l.o _stdlib_strto_ll_l.o +CSRC := \ + abort.c getenv.c mkdtemp.c mktemp.c realpath.c mkstemp.c \ + rand.c random.c random_r.c setenv.c system.c div.c ldiv.c lldiv.c \ + getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c drand48-iter.c jrand48.c \ + jrand48_r.c lrand48.c lrand48_r.c mrand48.c mrand48_r.c nrand48.c \ + nrand48_r.c rand_r.c srand48.c srand48_r.c seed48.c seed48_r.c \ + valloc.c posix_memalign.c a64l.c l64a.c +ifeq ($(UCLIBC_HAS_ARC4RANDOM),y) +CSRC += arc4random.c +endif +ifeq ($(UCLIBC_HAS_LFS),y) +CSRC += mkstemp64.c +endif +ifeq ($(UCLIBC_HAS_FLOATS),y) +CSRC += drand48.c drand48_r.c erand48.c erand48_r.c endif -MSRC2:=strtod.c -MOBJ2:= -MOBJ2x:= - +# multi source stdlib.c +CSRC += abs.c labs.c atoi.c atol.c strtol.c strtoul.c _stdlib_strto_l.c \ + qsort.c bsearch.c \ + llabs.c atoll.c strtoll.c strtoull.c _stdlib_strto_ll.c +# (aliases) strtoq.o strtouq.o ifeq ($(UCLIBC_HAS_FLOATS),y) -MOBJ1+=atof.o -MOBJ2+=strtod.o strtof.o strtold.o __strtofpmax.o __fp_range_check.o +CSRC += atof.c +endif ifeq ($(UCLIBC_HAS_XLOCALE),y) -MOBJ2x+=strtod_l.o strtof_l.o strtold_l.o __strtofpmax_l.o +CSRC += strtol_l.c strtoul_l.c _stdlib_strto_l_l.c \ + strtoll_l.c strtoull_l.c _stdlib_strto_ll_l.c endif ifeq ($(UCLIBC_HAS_WCHAR),y) -MOBJ2+=wcstod.o wcstof.o wcstold.o __wcstofpmax.o +CSRC += mblen.c mbtowc.c wctomb.c mbstowcs.c wcstombs.c \ + _stdlib_mb_cur_max.c _stdlib_wcsto_l.c _stdlib_wcsto_ll.c \ + wcstol.c wcstoul.c wcstoll.c wcstoull.c ifeq ($(UCLIBC_HAS_XLOCALE),y) -MOBJ2x+=wcstod_l.o wcstof_l.o wcstold_l.o __wcstofpmax_l.o -endif +CSRC +=_stdlib_wcsto_l_l.c _stdlib_wcsto_ll_l.c \ + wcstol_l.c wcstoul_l.c wcstoll_l.c wcstoull_l.c endif endif +# multi source _strtod.c +ifeq ($(UCLIBC_HAS_FLOATS),y) +CSRC += strtod.c strtof.c strtold.c __strtofpmax.c __fp_range_check.c +ifeq ($(UCLIBC_HAS_XLOCALE),y) +CSRC += strtod_l.c strtof_l.c strtold_l.c __strtofpmax_l.c +endif ifeq ($(UCLIBC_HAS_WCHAR),y) -MOBJ1+= mblen.o mbtowc.o wctomb.o mbstowcs.o wcstombs.o \ - _stdlib_mb_cur_max.o _stdlib_wcsto_l.o _stdlib_wcsto_ll.o \ - wcstol.o wcstoul.o wcstoll.o wcstoull.o +CSRC += wcstod.c wcstof.c wcstold.c __wcstofpmax.c ifeq ($(UCLIBC_HAS_XLOCALE),y) -MOBJ1x+=_stdlib_wcsto_l_l.o _stdlib_wcsto_ll_l.o \ - wcstol_l.o wcstoul_l.o wcstoll_l.o wcstoull_l.o +CSRC += wcstod_l.c wcstof_l.c wcstold_l.c __wcstofpmax_l.c +endif endif endif # (aliases) wcstoq.o wcstouq.o # wcstod wcstof wcstold -MSRC3:=atexit.c -MOBJ3:=on_exit.o __cxa_atexit.o __cxa_finalize.o __exit_handler.o exit.o +# multi source _atexit.c +CSRC += __cxa_atexit.c __cxa_finalize.c __exit_handler.c exit.c on_exit.c ifeq ($(COMPAT_ATEXIT),y) -MOBJ3+=old_atexit.o -endif - -CSRC:= \ - abort.c getenv.c mkdtemp.c mktemp.c realpath.c mkstemp.c mkstemp64.c \ - rand.c random.c random_r.c setenv.c system.c div.c ldiv.c lldiv.c \ - getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c drand48-iter.c jrand48.c \ - jrand48_r.c lrand48.c lrand48_r.c mrand48.c mrand48_r.c nrand48.c \ - nrand48_r.c rand_r.c srand48.c srand48_r.c seed48.c seed48_r.c \ - valloc.c posix_memalign.c a64l.c l64a.c -ifeq ($(UCLIBC_HAS_FLOATS),y) -CSRC+=drand48.c drand48_r.c erand48.c erand48_r.c +CSRC += old_atexit.c endif -STDLIB_MOBJ1_NO_MULTI:=_stdlib_strto_l.o _stdlib_strto_ll.o -STDLIB_MOBJ2_NO_MULTI:=strtod.o strtof.o __strtofpmax.o -STDLIB_MOBJ_NO_MULTI:=$(STDLIB_MOBJ1_NO_MULTI) $(STDLIB_MOBJ2_NO_MULTI) - -STDLIB_DIR:=$(top_srcdir)libc/stdlib -STDLIB_OUT:=$(top_builddir)libc/stdlib - -STDLIB_SRC:=$(patsubst %.c,$(STDLIB_DIR)/%.c,$(CSRC)) -STDLIB_OBJ:=$(patsubst %.c,$(STDLIB_OUT)/%.o,$(CSRC)) - -STDLIB_MSRC1:=$(patsubst %.c,$(STDLIB_DIR)/%.c,$(MSRC1)) -STDLIB_MSRC2:=$(patsubst %.c,$(STDLIB_DIR)/%.c,$(MSRC2)) -STDLIB_MSRC3:=$(patsubst %.c,$(STDLIB_DIR)/%.c,$(MSRC3)) -STDLIB_MOBJ1:=$(patsubst %.o,$(STDLIB_OUT)/%.o,$(MOBJ1)) -STDLIB_MOBJ2:=$(patsubst %.o,$(STDLIB_OUT)/%.o,$(MOBJ2)) -STDLIB_MOBJ3:=$(patsubst %.o,$(STDLIB_OUT)/%.o,$(MOBJ3)) -STDLIB_MOBJ1x:=$(patsubst %.o,$(STDLIB_OUT)/%.o,$(MOBJ1x)) -STDLIB_MOBJ2x:=$(patsubst %.o,$(STDLIB_OUT)/%.o,$(MOBJ2x)) - -STDLIB_MSRC:=$(STDLIB_MSRC1) $(STDLIB_MSRC2) $(STDLIB_MSRC3) -STDLIB_MOBJ:=$(STDLIB_MOBJ1) $(STDLIB_MOBJ2) $(STDLIB_MOBJ3) - -STDLIB_DEF:=$(patsubst %,-DL_%,$(subst .o,,$(filter-out $(STDLIB_MOBJ_NO_MULTI),$(notdir $(STDLIB_MOBJ))))) - -STDLIB_MOBJx:=$(STDLIB_MOBJ1x) $(STDLIB_MOBJ2x) - -STDLIB_OBJS:=$(STDLIB_OBJ) $(STDLIB_MOBJ) $(STDLIB_MOBJx) - -$(STDLIB_MOBJ1): $(STDLIB_MSRC1) - $(compile.m) - -$(STDLIB_MOBJ1:.o=.os): $(STDLIB_MSRC1) - $(compile.m) - -$(STDLIB_MOBJ2): $(STDLIB_MSRC2) - $(compile.m) - -$(STDLIB_MOBJ2:.o=.os): $(STDLIB_MSRC2) - $(compile.m) - -$(STDLIB_MOBJ3): $(STDLIB_MSRC3) - $(compile.m) - -$(STDLIB_MOBJ3:.o=.os) $(STDLIB_OUT)/atexit.os: $(STDLIB_MSRC3) - $(compile.m) - -$(STDLIB_MOBJ1x): $(STDLIB_MSRC1) - $(compile.m) -D__UCLIBC_DO_XLOCALE - -$(STDLIB_MOBJ1x:.o=.os): $(STDLIB_MSRC1) - $(compile.m) -D__UCLIBC_DO_XLOCALE - -$(STDLIB_MOBJ2x): $(STDLIB_MSRC2) - $(compile.m) -D__UCLIBC_DO_XLOCALE +STDLIB_DIR := $(top_srcdir)libc/stdlib +STDLIB_OUT := $(top_builddir)libc/stdlib -$(STDLIB_MOBJ2x:.o=.os): $(STDLIB_MSRC2) - $(compile.m) -D__UCLIBC_DO_XLOCALE +STDLIB_SRC := $(patsubst %.c,$(STDLIB_DIR)/%.c,$(CSRC)) +STDLIB_OBJ := $(patsubst %.c,$(STDLIB_OUT)/%.o,$(CSRC)) -libc-a-y+=$(STDLIB_OBJS) -libc-static-y+=$(STDLIB_OUT)/atexit.o -libc-so-y+=$(STDLIB_OBJS:.o=.os) +libc-y += $(STDLIB_OBJ) +libc-static-y += $(STDLIB_OUT)/atexit.o # this should always be the PIC version, because it could be used in shared libs -libc-nonshared-y+=$(STDLIB_OUT)/atexit.os +libc-nonshared-y += $(STDLIB_OUT)/atexit.os -CFLAGS-multi-y+=$(STDLIB_DEF) -libc-multi-y+=$(STDLIB_SRC) $(STDLIB_MSRC) -libc-nomulti-y+=$(patsubst %.o,$(STDLIB_OUT)/%.o,$(STDLIB_MOBJ_NO_MULTI)) -libc-nomulti-$(UCLIBC_HAS_XLOCALE)+=$(STDLIB_MOBJx) +libc-nomulti-y += $(STDLIB_OUT)/labs.o $(STDLIB_OUT)/atol.o $(STDLIB_OUT)/_stdlib_strto_l.o $(STDLIB_OUT)/_stdlib_strto_ll.o +libc-nomulti-$(UCLIBC_HAS_XLOCALE) += $(STDLIB_OUT)/_stdlib_strto_l_l.o $(STDLIB_OUT)/_stdlib_strto_ll_l.o -objclean-y+=stdlib_objclean +objclean-y += stdlib_objclean stdlib_objclean: - $(RM) $(STDLIB_OUT)/*.{o,os} + $(RM) $(STDLIB_OUT)/*.{o,os,oS} diff --git a/libc/stdlib/__cxa_atexit.c b/libc/stdlib/__cxa_atexit.c new file mode 100644 index 000000000..fbf06e5a7 --- /dev/null +++ b/libc/stdlib/__cxa_atexit.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___cxa_atexit +#include "_atexit.c" diff --git a/libc/stdlib/__cxa_finalize.c b/libc/stdlib/__cxa_finalize.c new file mode 100644 index 000000000..4a91626bd --- /dev/null +++ b/libc/stdlib/__cxa_finalize.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___cxa_finalize +#include "_atexit.c" diff --git a/libc/stdlib/__exit_handler.c b/libc/stdlib/__exit_handler.c new file mode 100644 index 000000000..ae4ff84be --- /dev/null +++ b/libc/stdlib/__exit_handler.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___exit_handler +#include "_atexit.c" diff --git a/libc/stdlib/__fp_range_check.c b/libc/stdlib/__fp_range_check.c new file mode 100644 index 000000000..9c60972ad --- /dev/null +++ b/libc/stdlib/__fp_range_check.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___fp_range_check +#include "_strtod.c" diff --git a/libc/stdlib/__strtofpmax.c b/libc/stdlib/__strtofpmax.c new file mode 100644 index 000000000..6b01aca0f --- /dev/null +++ b/libc/stdlib/__strtofpmax.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___strtofpmax +#include "_strtod.c" diff --git a/libc/stdlib/__strtofpmax_l.c b/libc/stdlib/__strtofpmax_l.c new file mode 100644 index 000000000..a6141323e --- /dev/null +++ b/libc/stdlib/__strtofpmax_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___strtofpmax_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/__wcstofpmax.c b/libc/stdlib/__wcstofpmax.c new file mode 100644 index 000000000..3c3fdccee --- /dev/null +++ b/libc/stdlib/__wcstofpmax.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___wcstofpmax +#include "_strtod.c" diff --git a/libc/stdlib/__wcstofpmax_l.c b/libc/stdlib/__wcstofpmax_l.c new file mode 100644 index 000000000..909b7204d --- /dev/null +++ b/libc/stdlib/__wcstofpmax_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___wcstofpmax_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/_atexit.c b/libc/stdlib/_atexit.c new file mode 100644 index 000000000..bf35ab2d6 --- /dev/null +++ b/libc/stdlib/_atexit.c @@ -0,0 +1,348 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * Dec 2000 Manuel Novoa III + * + * Made atexit handling conform to standards... i.e. no args. + * Removed on_exit since it did not match gnu libc definition. + * Combined atexit and __do_exit into one object file. + * + * Feb 2001 Manuel Novoa III + * + * Reworked file after addition of __uClibc_main. + * Changed name of __do_exit to atexit_handler. + * Changed name of __cleanup to __uClibc_cleanup. + * Moved declaration of __uClibc_cleanup to __uClibc_main + * where it is initialized with (possibly weak alias) + * _stdio_term. + * + * Jul 2001 Steve Thayer + * + * Added an on_exit implementation (that now matches gnu libc definition.) + * Pulled atexit_handler out of the atexit object since it is now required by + * on_exit as well. Renamed it to __exit_handler. + * Fixed a problem where exit functions stop getting called if one of + * them calls exit(). + * As a side effect of these changes, abort() no longer calls the exit + * functions (it now matches the gnu libc definition). + * + * August 2002 Erik Andersen + * Added locking so atexit and friends can be thread safe + * + * August 2005 Stephen Warren + * Added __cxa_atexit and __cxa_finalize support + * + */ + +#include <features.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <atomic.h> + +libc_hidden_proto(exit) +libc_hidden_proto(_exit) + +#ifdef __UCLIBC_HAS_THREADS__ +# include <pthread.h> +extern pthread_mutex_t mylock; +libc_hidden_proto(mylock) +#endif +#define LOCK __pthread_mutex_lock(&mylock) +#define UNLOCK __pthread_mutex_unlock(&mylock) + + +typedef void (*aefuncp) (void); /* atexit function pointer */ +typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ +typedef void (*cxaefuncp) (void *); /* __cxa_atexit function pointer */ +typedef enum { + ef_free, + ef_in_use, + ef_on_exit, + ef_cxa_atexit +} ef_type; /* exit function types */ + +/* this is in the L_exit object */ +extern void (*__exit_cleanup) (int) attribute_hidden; + +/* these are in the L___do_exit object */ +extern int __exit_slots attribute_hidden; +extern int __exit_count attribute_hidden; +extern void __exit_handler(int) attribute_hidden; +struct exit_function { + /* + * 'type' should be of type of the 'enum ef_type' above but since we + * need this element in an atomic operation we have to use 'long int'. + */ + long int type; /* enum ef_type */ + union { + struct { + oefuncp func; + void *arg; + } on_exit; + struct { + cxaefuncp func; + void *arg; + void* dso_handle; + } cxa_atexit; + } funcs; +}; +#ifdef __UCLIBC_DYNAMIC_ATEXIT__ +extern struct exit_function *__exit_function_table attribute_hidden; +#else +extern struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT] attribute_hidden; +#endif +extern struct exit_function *__new_exitfn (void) attribute_hidden; + +/* this is in the L___cxa_atexit object */ +extern int __cxa_atexit (cxaefuncp, void *arg, void *dso_handle); + + +/* remove old_atexit after 0.9.29 */ +#if defined(L_atexit) || defined(L_old_atexit) +extern void *__dso_handle __attribute__ ((__weak__)); + +/* + * register a function to be called at normal program termination + * (the registered function takes no arguments) + */ +#ifdef L_atexit +int attribute_hidden atexit(aefuncp func) +#else +int old_atexit(aefuncp func) +#endif +{ + /* + * glibc casts aefuncp to cxaefuncp. + * This seems dodgy, but I guess callling a function with more + * parameters than it needs will work everywhere? + */ + return __cxa_atexit((cxaefuncp)func, NULL, + &__dso_handle == NULL ? NULL : __dso_handle); +} +#ifndef L_atexit +weak_alias(old_atexit,atexit) +#endif +#endif + +#ifdef L_on_exit +/* + * register a function to be called at normal program termination + * the registered function takes two arguments: + * status - the exit status that was passed to the exit() function + * arg - generic argument + */ +int on_exit(oefuncp func, void *arg) +{ + struct exit_function *efp; + + if (func == NULL) { + return 0; + } + + efp = __new_exitfn(); + if (efp == NULL) { + return -1; + } + + efp->funcs.on_exit.func = func; + efp->funcs.on_exit.arg = arg; + /* assign last for thread safety, since we're now unlocked */ + efp->type = ef_on_exit; + + return 0; +} +#endif + +#ifdef L___cxa_atexit +libc_hidden_proto(__cxa_atexit) +int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle) +{ + struct exit_function *efp; + + if (func == NULL) { + return 0; + } + + efp = __new_exitfn(); + if (efp == NULL) { + return -1; + } + + efp->funcs.cxa_atexit.func = func; + efp->funcs.cxa_atexit.arg = arg; + efp->funcs.cxa_atexit.dso_handle = dso_handle; + /* assign last for thread safety, since we're now unlocked */ + efp->type = ef_cxa_atexit; + + return 0; +} +libc_hidden_def(__cxa_atexit) +#endif + +#ifdef L___cxa_finalize +/* + * If D is non-NULL, call all functions registered with `__cxa_atexit' + * with the same dso handle. Otherwise, if D is NULL, call all of the + * registered handlers. + */ +void __cxa_finalize (void *dso_handle); +void __cxa_finalize (void *dso_handle) +{ + struct exit_function *efp; + int exit_count_snapshot = __exit_count; + + /* In reverse order */ + while (exit_count_snapshot) { + efp = &__exit_function_table[--exit_count_snapshot]; + + /* + * We check dso_handle match before we verify the type of the union entry. + * However, the atomic_exchange will validate that we were really "allowed" + * to read dso_handle... + */ + if ((dso_handle == NULL || dso_handle == efp->funcs.cxa_atexit.dso_handle) + /* We don't want to run this cleanup more than once. */ + && !atomic_compare_and_exchange_bool_acq(&efp->type, ef_free, ef_cxa_atexit) + ) { + /* glibc passes status (0) too, but that's not in the prototype */ + (*efp->funcs.cxa_atexit.func)(efp->funcs.cxa_atexit.arg); + } + } + +#if 0 /* haven't looked into this yet... */ + /* + * Remove the registered fork handlers. We do not have to + * unregister anything if the program is going to terminate anyway. + */ +#ifdef UNREGISTER_ATFORK + if (d != NULL) { + UNREGISTER_ATFORK (d); + } +#endif +#endif +} +#endif + +#ifdef L___exit_handler +int __exit_count = 0; /* Number of registered exit functions */ +#ifdef __UCLIBC_DYNAMIC_ATEXIT__ +struct exit_function *__exit_function_table = NULL; +int __exit_slots = 0; /* Size of __exit_function_table */ +#else +struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT]; +#endif + +/* + * Find and return a new exit_function pointer, for atexit, + * onexit and __cxa_atexit to initialize + */ +struct exit_function attribute_hidden *__new_exitfn(void) +{ + struct exit_function *efp; + + LOCK; + +#ifdef __UCLIBC_DYNAMIC_ATEXIT__ + /* If we are out of function table slots, make some more */ + if (__exit_slots < __exit_count+1) { + efp=realloc(__exit_function_table, + (__exit_slots+20)*sizeof(struct exit_function)); + if (efp == NULL) { + UNLOCK; + __set_errno(ENOMEM); + return 0; + } + __exit_function_table = efp; + __exit_slots += 20; + } +#else + if (__exit_count >= __UCLIBC_MAX_ATEXIT) { + UNLOCK; + __set_errno(ENOMEM); + return 0; + } +#endif + + __exit_cleanup = __exit_handler; /* enable cleanup */ + efp = &__exit_function_table[__exit_count++]; + efp->type = ef_in_use; + + UNLOCK; + + return efp; +} + +/* + * Handle the work of executing the registered exit functions + * This is called while we are locked, so no additional locking + * is needed... + */ +void __exit_handler(int status) +{ + struct exit_function *efp; + + /* In reverse order */ + while ( __exit_count ) { + efp = &__exit_function_table[--__exit_count]; + switch (efp->type) { + case ef_on_exit: + if (efp->funcs.on_exit.func) { + (efp->funcs.on_exit.func) (status, efp->funcs.on_exit.arg); + } + break; + case ef_cxa_atexit: + if (efp->funcs.cxa_atexit.func) { + /* glibc passes status too, but that's not in the prototype */ + (efp->funcs.cxa_atexit.func) (efp->funcs.cxa_atexit.arg); + } + break; + } + } +#ifdef __UCLIBC_DYNAMIC_ATEXIT__ + /* Free up memory used by the __exit_function_table structure */ + if (__exit_function_table) + free(__exit_function_table); +#endif +} +#endif + +#ifdef L_exit +extern void weak_function _stdio_term(void) attribute_hidden; +attribute_hidden void (*__exit_cleanup) (int) = 0; +#ifdef __UCLIBC_HAS_THREADS__ +pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +libc_hidden_data_def(mylock) +#endif + +extern void __uClibc_fini(void); +libc_hidden_proto(__uClibc_fini) + +/* + * Normal program termination + */ +void exit(int rv) +{ + /* Perform exit-specific cleanup (atexit and on_exit) */ + LOCK; + if (__exit_cleanup) { + __exit_cleanup(rv); + } + UNLOCK; + + __uClibc_fini(); + + /* If we are using stdio, try to shut it down. At the very least, + * this will attempt to commit all buffered writes. It may also + * unbuffer all writable files, or close them outright. + * Check the stdio routines for details. */ + if (_stdio_term) + _stdio_term(); + + _exit(rv); +} +libc_hidden_def(exit) +#endif diff --git a/libc/stdlib/_stdlib_mb_cur_max.c b/libc/stdlib/_stdlib_mb_cur_max.c new file mode 100644 index 000000000..b87f6094b --- /dev/null +++ b/libc/stdlib/_stdlib_mb_cur_max.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_mb_cur_max +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_strto_l.c b/libc/stdlib/_stdlib_strto_l.c new file mode 100644 index 000000000..4dfa03785 --- /dev/null +++ b/libc/stdlib/_stdlib_strto_l.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_strto_l +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_strto_l_l.c b/libc/stdlib/_stdlib_strto_l_l.c new file mode 100644 index 000000000..1692f0cf2 --- /dev/null +++ b/libc/stdlib/_stdlib_strto_l_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_strto_l_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_strto_ll.c b/libc/stdlib/_stdlib_strto_ll.c new file mode 100644 index 000000000..ce79598b4 --- /dev/null +++ b/libc/stdlib/_stdlib_strto_ll.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_strto_ll +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_strto_ll_l.c b/libc/stdlib/_stdlib_strto_ll_l.c new file mode 100644 index 000000000..b5fb11171 --- /dev/null +++ b/libc/stdlib/_stdlib_strto_ll_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_strto_ll_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_wcsto_l.c b/libc/stdlib/_stdlib_wcsto_l.c new file mode 100644 index 000000000..d05a20786 --- /dev/null +++ b/libc/stdlib/_stdlib_wcsto_l.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_wcsto_l +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_wcsto_l_l.c b/libc/stdlib/_stdlib_wcsto_l_l.c new file mode 100644 index 000000000..26ea5a704 --- /dev/null +++ b/libc/stdlib/_stdlib_wcsto_l_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_wcsto_l_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_wcsto_ll.c b/libc/stdlib/_stdlib_wcsto_ll.c new file mode 100644 index 000000000..e67a57739 --- /dev/null +++ b/libc/stdlib/_stdlib_wcsto_ll.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_wcsto_ll +#include "stdlib.c" diff --git a/libc/stdlib/_stdlib_wcsto_ll_l.c b/libc/stdlib/_stdlib_wcsto_ll_l.c new file mode 100644 index 000000000..9d6471282 --- /dev/null +++ b/libc/stdlib/_stdlib_wcsto_ll_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L__stdlib_wcsto_ll_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/_strtod.c b/libc/stdlib/_strtod.c new file mode 100644 index 000000000..c4447d9ea --- /dev/null +++ b/libc/stdlib/_strtod.c @@ -0,0 +1,623 @@ +/* + * Copyright (C) 2000-2005 Manuel Novoa III + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* Notes: + * + * The primary objective of this implementation was minimal size and + * portablility, while providing robustness and resonable accuracy. + * + * This implementation depends on IEEE floating point behavior and expects + * to be able to generate +/- infinity as a result. + * + * There are a number of compile-time options below. + */ + +/* July 27, 2003 + * + * General cleanup and some minor size optimizations. + * Change implementation to support __strtofpmax() rather than strtod(). + * Now all the strto{floating pt}() funcs are implemented in terms of + * of the internal __strtofpmax() function. + * Support "nan", "inf", and "infinity" strings (case-insensitive). + * Support hexadecimal floating point notation. + * Support wchar variants. + * Support xlocale variants. + * + * TODO: + * + * Consider accumulating blocks of digits in longs to save floating pt mults. + * This would likely be much better on anything that only supported floats + * where DECIMAL_DIG == 9. Actually, if floats have FLT_MAX_10_EXP == 38, + * we could calculate almost all the exponent multipliers (p_base) in + * long arithmetic as well. + */ + +/**********************************************************************/ +/* OPTIONS */ +/**********************************************************************/ + +/* Defined if we want to recognize "nan", "inf", and "infinity". (C99) */ +#define _STRTOD_NAN_INF_STRINGS 1 + +/* Defined if we want support hexadecimal floating point notation. (C99) */ +/* Note! Now controlled by uClibc configuration. See below. */ +#define _STRTOD_HEXADECIMAL_FLOATS 1 + +/* Defined if we want to scale with a O(log2(exp)) multiplications. + * This is generally a good thing to do unless you are really tight + * on space and do not expect to convert values of large magnitude. */ + +#define _STRTOD_LOG_SCALING 1 + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * + * Clearing any of the options below this point is not advised (or tested). + * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! */ + +/* Defined if we want strtod to set errno appropriately. */ +/* NOTE: Implies all options below. */ +#define _STRTOD_ERRNO 1 + +/* Defined if we want support for the endptr arg. */ +/* Implied by _STRTOD_ERRNO. */ +#define _STRTOD_ENDPTR 1 + +/* Defined if we want to prevent overflow in accumulating the exponent. */ +/* Implied by _STRTOD_ERRNO. */ +#define _STRTOD_RESTRICT_EXP 1 + +/* Defined if we want to process mantissa digits more intelligently. */ +/* Implied by _STRTOD_ERRNO. */ +#define _STRTOD_RESTRICT_DIGITS 1 + +/* Defined if we want to skip scaling 0 for the exponent. */ +/* Implied by _STRTOD_ERRNO. */ +#define _STRTOD_ZERO_CHECK 1 + +/**********************************************************************/ +/* Don't change anything that follows. */ +/**********************************************************************/ + +#ifdef _STRTOD_ERRNO +#undef _STRTOD_ENDPTR +#undef _STRTOD_RESTRICT_EXP +#undef _STRTOD_RESTRICT_DIGITS +#undef _STRTOD_ZERO_CHECK +#define _STRTOD_ENDPTR 1 +#define _STRTOD_RESTRICT_EXP 1 +#define _STRTOD_RESTRICT_DIGITS 1 +#define _STRTOD_ZERO_CHECK 1 +#endif + +/**********************************************************************/ + +#define _ISOC99_SOURCE 1 +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <float.h> +#include <bits/uClibc_fpmax.h> + +#include <locale.h> + +#ifdef __UCLIBC_HAS_WCHAR__ + +#include <wchar.h> +#include <wctype.h> +#include <bits/uClibc_uwchar.h> +libc_hidden_proto(iswspace) +#endif + +#ifdef __UCLIBC_HAS_XLOCALE__ +#include <xlocale.h> +libc_hidden_proto(iswspace_l) +#endif /* __UCLIBC_HAS_XLOCALE__ */ + +/* Handle _STRTOD_HEXADECIMAL_FLOATS via uClibc config now. */ +#undef _STRTOD_HEXADECIMAL_FLOATS +#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ +#define _STRTOD_HEXADECIMAL_FLOATS 1 +#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ + +/**********************************************************************/ + +#undef _STRTOD_FPMAX + +#if FPMAX_TYPE == 3 + +#define NEED_STRTOLD_WRAPPER +#define NEED_STRTOD_WRAPPER +#define NEED_STRTOF_WRAPPER + +#elif FPMAX_TYPE == 2 + +#define NEED_STRTOD_WRAPPER +#define NEED_STRTOF_WRAPPER + +#elif FPMAX_TYPE == 1 + +#define NEED_STRTOF_WRAPPER + +#else + +#error unknown FPMAX_TYPE! + +#endif + +extern void __fp_range_check(__fpmax_t y, __fpmax_t x) attribute_hidden; + +/**********************************************************************/ + +#ifdef _STRTOD_RESTRICT_DIGITS +#define EXP_DENORM_ADJUST DECIMAL_DIG +#define MAX_ALLOWED_EXP (DECIMAL_DIG + EXP_DENORM_ADJUST - FPMAX_MIN_10_EXP) + +#if MAX_ALLOWED_EXP > INT_MAX +#error size assumption violated for MAX_ALLOWED_EXP +#endif +#else +/* We want some excess if we're not restricting mantissa digits. */ +#define MAX_ALLOWED_EXP ((20 - FPMAX_MIN_10_EXP) * 2) +#endif + + +#if defined(_STRTOD_RESTRICT_DIGITS) || defined(_STRTOD_ENDPTR) || defined(_STRTOD_HEXADECIMAL_FLOATS) +#undef _STRTOD_NEED_NUM_DIGITS +#define _STRTOD_NEED_NUM_DIGITS 1 +#endif + +/**********************************************************************/ +#if defined(L___strtofpmax) || defined(L___strtofpmax_l) || defined(L___wcstofpmax) || defined(L___wcstofpmax_l) + +#ifdef __UCLIBC_HAS_XLOCALE__ +libc_hidden_proto(__ctype_b_loc) +#else +#ifdef __UCLIBC_HAS_LOCALE__ +libc_hidden_proto(__global_locale) +#endif +libc_hidden_proto(__ctype_b) +libc_hidden_proto(__ctype_tolower) +#endif + +#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) + +#define __strtofpmax __wcstofpmax +#define __strtofpmax_l __wcstofpmax_l + +#define Wchar wchar_t +#ifdef __UCLIBC_DO_XLOCALE +#define ISSPACE(C) iswspace_l((C), locale_arg) +#else +#define ISSPACE(C) iswspace((C)) +#endif + +#else /* defined(L___wcstofpmax) || defined(L___wcstofpmax_l) */ + +#define Wchar char +#ifdef __UCLIBC_DO_XLOCALE +#define ISSPACE(C) isspace_l((C), locale_arg) +#else +#define ISSPACE(C) isspace((C)) +#endif + +#endif /* defined(L___wcstofpmax) || defined(L___wcstofpmax_l) */ + + +#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) + +__fpmax_t attribute_hidden __strtofpmax(const Wchar *str, Wchar **endptr, int exponent_power) +{ + return __strtofpmax_l(str, endptr, exponent_power, __UCLIBC_CURLOCALE); +} + +#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ + +libc_hidden_proto(memcmp) + +__fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endptr, int exponent_power + __LOCALE_PARAM ) +{ + __fpmax_t number; + __fpmax_t p_base = 10; /* Adjusted to 16 in the hex case. */ + Wchar *pos0; +#ifdef _STRTOD_ENDPTR + Wchar *pos1; +#endif + Wchar *pos = (Wchar *) str; + int exponent_temp; + int negative; /* A flag for the number, a multiplier for the exponent. */ +#ifdef _STRTOD_NEED_NUM_DIGITS + int num_digits; +#endif +#ifdef __UCLIBC_HAS_LOCALE__ +#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) + wchar_t decpt_wc = __LOCALE_PTR->decimal_point; +#else + const char *decpt = __LOCALE_PTR->decimal_point; + int decpt_len = __LOCALE_PTR->decimal_point_len; +#endif +#endif + +#ifdef _STRTOD_HEXADECIMAL_FLOATS + Wchar expchar = 'e'; + Wchar *poshex = NULL; + __uint16_t is_mask = _ISdigit; +#define EXPCHAR expchar +#define IS_X_DIGIT(C) __isctype((C), is_mask) +#else /* _STRTOD_HEXADECIMAL_FLOATS */ +#define EXPCHAR 'e' +#define IS_X_DIGIT(C) isdigit((C)) +#endif /* _STRTOD_HEXADECIMAL_FLOATS */ + + while (ISSPACE(*pos)) { /* Skip leading whitespace. */ + ++pos; + } + + negative = 0; + switch(*pos) { /* Handle optional sign. */ + case '-': negative = 1; /* Fall through to increment position. */ + case '+': ++pos; + } + +#ifdef _STRTOD_HEXADECIMAL_FLOATS + if ((*pos == '0') && (((pos[1])|0x20) == 'x')) { + poshex = ++pos; /* Save position of 'x' in case no digits */ + ++pos; /* and advance past it. */ + is_mask = _ISxdigit; /* Used by IS_X_DIGIT. */ + expchar = 'p'; /* Adjust exponent char. */ + p_base = 16; /* Adjust base multiplier. */ + } +#endif + + number = 0.; +#ifdef _STRTOD_NEED_NUM_DIGITS + num_digits = -1; +#endif +/* exponent_power = 0; */ + pos0 = NULL; + + LOOP: + while (IS_X_DIGIT(*pos)) { /* Process string of (hex) digits. */ +#ifdef _STRTOD_RESTRICT_DIGITS + if (num_digits < 0) { /* First time through? */ + ++num_digits; /* We've now seen a digit. */ + } + if (num_digits || (*pos != '0')) { /* Had/have nonzero. */ + ++num_digits; + if (num_digits <= DECIMAL_DIG) { /* Is digit significant? */ +#ifdef _STRTOD_HEXADECIMAL_FLOATS + number = number * p_base + + (isdigit(*pos) + ? (*pos - '0') + : (((*pos)|0x20) - ('a' - 10))); +#else /* _STRTOD_HEXADECIMAL_FLOATS */ + number = number * p_base + (*pos - '0'); +#endif /* _STRTOD_HEXADECIMAL_FLOATS */ + } + } +#else /* _STRTOD_RESTRICT_DIGITS */ +#ifdef _STRTOD_NEED_NUM_DIGITS + ++num_digits; +#endif +#ifdef _STRTOD_HEXADECIMAL_FLOATS + number = number * p_base + + (isdigit(*pos) + ? (*pos - '0') + : (((*pos)|0x20) - ('a' - 10))); +#else /* _STRTOD_HEXADECIMAL_FLOATS */ + number = number * p_base + (*pos - '0'); +#endif /* _STRTOD_HEXADECIMAL_FLOATS */ +#endif /* _STRTOD_RESTRICT_DIGITS */ + ++pos; + } + +#ifdef __UCLIBC_HAS_LOCALE__ +#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) + if (!pos0 && (*pos == decpt_wc)) { /* First decimal point? */ + pos0 = ++pos; + goto LOOP; + } +#else + if (!pos0 && !memcmp(pos, decpt, decpt_len)) { /* First decimal point? */ + pos0 = (pos += decpt_len); + goto LOOP; + } +#endif +#else /* __UCLIBC_HAS_LOCALE__ */ + if ((*pos == '.') && !pos0) { /* First decimal point? */ + pos0 = ++pos; /* Save position of decimal point */ + goto LOOP; /* and process rest of digits. */ + } +#endif /* __UCLIBC_HAS_LOCALE__ */ + +#ifdef _STRTOD_NEED_NUM_DIGITS + if (num_digits<0) { /* Must have at least one digit. */ +#ifdef _STRTOD_HEXADECIMAL_FLOATS + if (poshex) { /* Back up to '0' in '0x' prefix. */ + pos = poshex; + goto DONE; + } +#endif /* _STRTOD_HEXADECIMAL_FLOATS */ + +#ifdef _STRTOD_NAN_INF_STRINGS + if (!pos0) { /* No decimal point, so check for inf/nan. */ + /* Note: nan is the first string so 'number = i/0.;' works. */ + static const char nan_inf_str[] = "\05nan\0\012infinity\0\05inf\0"; + int i = 0; + +#ifdef __UCLIBC_HAS_LOCALE__ + /* Avoid tolower problems for INFINITY in the tr_TR locale. (yuk)*/ +#undef _tolower +#define _tolower(C) ((C)|0x20) +#endif /* __UCLIBC_HAS_LOCALE__ */ + + do { + /* Unfortunately, we have no memcasecmp(). */ + int j = 0; + while (_tolower(pos[j]) == nan_inf_str[i+1+j]) { + ++j; + if (!nan_inf_str[i+1+j]) { + number = i / 0.; + if (negative) { /* Correct for sign. */ + number = -number; + } + pos += nan_inf_str[i] - 2; + goto DONE; + } + } + i += nan_inf_str[i]; + } while (nan_inf_str[i]); + } + +#endif /* STRTOD_NAN_INF_STRINGS */ +#ifdef _STRTOD_ENDPTR + pos = (Wchar *) str; +#endif + goto DONE; + } +#endif /* _STRTOD_NEED_NUM_DIGITS */ + +#ifdef _STRTOD_RESTRICT_DIGITS + if (num_digits > DECIMAL_DIG) { /* Adjust exponent for skipped digits. */ + exponent_power += num_digits - DECIMAL_DIG; + } +#endif + + if (pos0) { + exponent_power += pos0 - pos; /* Adjust exponent for decimal point. */ + } + +#ifdef _STRTOD_HEXADECIMAL_FLOATS + if (poshex) { + exponent_power *= 4; /* Above is 2**4, but below is 2. */ + p_base = 2; + } +#endif /* _STRTOD_HEXADECIMAL_FLOATS */ + + if (negative) { /* Correct for sign. */ + number = -number; + } + + /* process an exponent string */ + if (((*pos)|0x20) == EXPCHAR) { +#ifdef _STRTOD_ENDPTR + pos1 = pos; +#endif + negative = 1; + switch(*++pos) { /* Handle optional sign. */ + case '-': negative = -1; /* Fall through to increment pos. */ + case '+': ++pos; + } + + pos0 = pos; + exponent_temp = 0; + while (isdigit(*pos)) { /* Process string of digits. */ +#ifdef _STRTOD_RESTRICT_EXP + if (exponent_temp < MAX_ALLOWED_EXP) { /* Avoid overflow. */ + exponent_temp = exponent_temp * 10 + (*pos - '0'); + } +#else + exponent_temp = exponent_temp * 10 + (*pos - '0'); +#endif + ++pos; + } + +#ifdef _STRTOD_ENDPTR + if (pos == pos0) { /* No digits? */ + pos = pos1; /* Back up to {e|E}/{p|P}. */ + } /* else */ +#endif + + exponent_power += negative * exponent_temp; + } + +#ifdef _STRTOD_ZERO_CHECK + if (number == 0.) { + goto DONE; + } +#endif + + /* scale the result */ +#ifdef _STRTOD_LOG_SCALING + exponent_temp = exponent_power; + + if (exponent_temp < 0) { + exponent_temp = -exponent_temp; + } + + while (exponent_temp) { + if (exponent_temp & 1) { + if (exponent_power < 0) { + /* Warning... caluclating a factor for the exponent and + * then dividing could easily be faster. But doing so + * might cause problems when dealing with denormals. */ + number /= p_base; + } else { + number *= p_base; + } + } + exponent_temp >>= 1; + p_base *= p_base; + } + +#else /* _STRTOD_LOG_SCALING */ + while (exponent_power) { + if (exponent_power < 0) { + number /= p_base; + exponent_power++; + } else { + number *= p_base; + exponent_power--; + } + } +#endif /* _STRTOD_LOG_SCALING */ + +#ifdef _STRTOD_ERRNO + if (__FPMAX_ZERO_OR_INF_CHECK(number)) { + __set_errno(ERANGE); + } +#endif + + DONE: +#ifdef _STRTOD_ENDPTR + if (endptr) { + *endptr = pos; + } +#endif + + return number; +} + +#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ + +#endif +/**********************************************************************/ +#ifdef L___fp_range_check +#if defined(NEED_STRTOF_WRAPPER) || defined(NEED_STRTOD_WRAPPER) + +void attribute_hidden __fp_range_check(__fpmax_t y, __fpmax_t x) +{ + if (__FPMAX_ZERO_OR_INF_CHECK(y) /* y is 0 or +/- infinity */ + && (y != 0) /* y is not 0 (could have x>0, y==0 if underflow) */ + && !__FPMAX_ZERO_OR_INF_CHECK(x) /* x is not 0 or +/- infinity */ + ) { + __set_errno(ERANGE); /* Then x is not in y's range. */ + } +} + +#endif +#endif +/**********************************************************************/ +#if defined(L_strtof) || defined(L_strtof_l) || defined(L_wcstof) || defined(L_wcstof_l) +#if defined(NEED_STRTOF_WRAPPER) + +#if defined(L_wcstof) || defined(L_wcstof_l) +#define strtof wcstof +#define strtof_l wcstof_l +#define __strtofpmax __wcstofpmax +#define __strtofpmax_l __wcstofpmax_l +#define Wchar wchar_t +#else +#define Wchar char +#endif + + +libc_hidden_proto(__XL_NPP(strtof)) +float __XL_NPP(strtof)(const Wchar *str, Wchar **endptr __LOCALE_PARAM ) +{ +#if FPMAX_TYPE == 1 + return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); +#else + __fpmax_t x; + float y; + + x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); + y = (float) x; + + __fp_range_check(y, x); + + return y; +#endif +} +libc_hidden_def(__XL_NPP(strtof)) + +#endif +#endif +/**********************************************************************/ +#if defined(L_strtod) || defined(L_strtod_l) || defined(L_wcstod) || defined(L_wcstod_l) +#if defined(NEED_STRTOD_WRAPPER) + +#if defined(L_wcstod) || defined(L_wcstod_l) +#define strtod wcstod +#define strtod_l wcstod_l +#define __strtofpmax __wcstofpmax +#define __strtofpmax_l __wcstofpmax_l +#define Wchar wchar_t +#else +#define Wchar char +#endif + +libc_hidden_proto(__XL_NPP(strtod)) +double __XL_NPP(strtod)(const Wchar *__restrict str, + Wchar **__restrict endptr __LOCALE_PARAM ) +{ +#if FPMAX_TYPE == 2 + return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); +#else + __fpmax_t x; + double y; + + x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); + y = (double) x; + + __fp_range_check(y, x); + + return y; +#endif +} +libc_hidden_def(__XL_NPP(strtod)) + +#endif +#endif +/**********************************************************************/ +#if defined(L_strtold) || defined(L_strtold_l) || defined(L_wcstold) || defined(L_wcstold_l) +#if defined(NEED_STRTOLD_WRAPPER) + +#if defined(L_wcstold) || defined(L_wcstold_l) +#define strtold wcstold +#define strtold_l wcstold_l +#define __strtofpmax __wcstofpmax +#define __strtofpmax_l __wcstofpmax_l +#define Wchar wchar_t +#else +#define Wchar char +#endif + +libc_hidden_proto(__XL_NPP(strtold)) +long double __XL_NPP(strtold) (const Wchar *str, Wchar **endptr __LOCALE_PARAM ) +{ +#if FPMAX_TYPE == 3 + return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); +#else + __fpmax_t x; + long double y; + + x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); + y = (long double) x; + + __fp_range_check(y, x); + + return y; +#endif +} +libc_hidden_def(__XL_NPP(strtold)) + +#endif +#endif +/**********************************************************************/ diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index 47252d1f7..a940768c0 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -18,9 +18,6 @@ Cambridge, MA 02139, USA. */ /* Hacked up for uClibc by Erik Andersen */ -#define sigaction __sigaction - -#define _GNU_SOURCE #include <features.h> #include <signal.h> #include <stdio.h> @@ -30,41 +27,20 @@ Cambridge, MA 02139, USA. */ #include <signal.h> #include <errno.h> +libc_hidden_proto(abort) + +libc_hidden_proto(memset) +libc_hidden_proto(sigaction) +libc_hidden_proto(sigprocmask) +libc_hidden_proto(raise) +libc_hidden_proto(_exit) /* Our last ditch effort to commit suicide */ -#if defined(__alpha__) -#define ABORT_INSTRUCTION asm ("call_pal 0") -#elif defined(__arm__) -#define ABORT_INSTRUCTION asm ("bl abort") -#elif defined(__hppa__) -#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)") -#elif defined(__i386__) -#define ABORT_INSTRUCTION asm ("hlt") -#elif defined(__ia64__) -#define ABORT_INSTRUCTION asm ("break 0") -#elif defined(__m68k__) -#define ABORT_INSTRUCTION asm ("illegal") -#elif defined(__mc68000__) -#define ABORT_INSTRUCTION asm (".long 0xffffffff") -#elif defined(__mips__) -#define ABORT_INSTRUCTION asm ("break 255") -#elif defined(__powerpc__) -#define ABORT_INSTRUCTION asm (".long 0") -#elif defined(__s390__) -#define ABORT_INSTRUCTION asm (".word 0") -#elif defined(__sparc__) -#define ABORT_INSTRUCTION asm ("unimp 0xf00") -#elif defined(__SH5__) -#define ABORT_INSTRUCTION asm ("movi 0x10, r9; shori 0xff, r9; trapa r9") -#elif defined(__sh2__) -#define ABORT_INSTRUCTION asm ("trapa #32") -#elif defined(__sh__) -#define ABORT_INSTRUCTION asm ("trapa #0xff") -#elif defined(__x86_64__) -#define ABORT_INSTRUCTION asm ("hlt") +#ifdef __UCLIBC_ABORT_INSTRUCTION__ +# define ABORT_INSTRUCTION __asm__(__UCLIBC_ABORT_INSTRUCTION__) #else -#define ABORT_INSTRUCTION -#warning no abort instruction defined for your arch +# define ABORT_INSTRUCTION +# warning "no abort instruction defined for your arch" #endif #ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ @@ -80,21 +56,17 @@ static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; #define LOCK __pthread_mutex_lock(&mylock) #define UNLOCK __pthread_mutex_unlock(&mylock) -extern int __raise (int __sig) __THROW attribute_hidden; - /* Cause an abnormal program termination with core-dump */ -#undef __abort -#undef abort -void attribute_hidden __abort(void) +void abort(void) { - sigset_t sigset; + sigset_t sigs; /* Make sure we acquire the lock before proceeding */ LOCK; /* Unmask SIGABRT to be sure we can get it */ - if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { - __sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL); + if (__sigemptyset(&sigs) == 0 && __sigaddset(&sigs, SIGABRT) == 0) { + sigprocmask(SIG_UNBLOCK, &sigs, (sigset_t *) NULL); } while (1) { @@ -104,8 +76,8 @@ void attribute_hidden __abort(void) #ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ /* If we are using stdio, try to shut it down. At the very least, - * this will attemt to commit all buffered writes. It may also - * unboffer all writable files, or close them outright. + * this will attempt to commit all buffered writes. It may also + * unbuffer all writable files, or close them outright. * Check the stdio routines for details. */ if (_stdio_term) { _stdio_term(); @@ -114,7 +86,7 @@ void attribute_hidden __abort(void) abort_it: UNLOCK; - __raise(SIGABRT); + raise(SIGABRT); LOCK; } @@ -123,7 +95,7 @@ abort_it: struct sigaction act; been_there_done_that++; - __memset(&act, '\0', sizeof(struct sigaction)); + memset(&act, '\0', sizeof(struct sigaction)); act.sa_handler = SIG_DFL; __sigfillset(&act.sa_mask); act.sa_flags = 0; @@ -141,7 +113,7 @@ abort_it: /* Still here? Try to at least exit */ if (been_there_done_that == 3) { been_there_done_that++; - _exit_internal(127); + _exit(127); } /* Still here? We're screwed. Sleepy time. Good night. */ @@ -150,4 +122,4 @@ abort_it: ABORT_INSTRUCTION; } } -strong_alias(__abort,abort) +libc_hidden_def(abort) diff --git a/libc/stdlib/abs.c b/libc/stdlib/abs.c new file mode 100644 index 000000000..540c020ec --- /dev/null +++ b/libc/stdlib/abs.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_abs +#include "stdlib.c" diff --git a/libc/stdlib/arc4random.c b/libc/stdlib/arc4random.c index ebdd7d561..836b79f6c 100644 --- a/libc/stdlib/arc4random.c +++ b/libc/stdlib/arc4random.c @@ -27,8 +27,6 @@ */ #include <features.h> -#ifdef __UCLIBC_HAS_ARC4RANDOM__ - #include <fcntl.h> #include <stdlib.h> #include <unistd.h> @@ -37,12 +35,18 @@ #include <sys/time.h> #ifdef __ARC4RANDOM_USE_ERANDOM__ #include <sys/sysctl.h> +//libc_hidden_proto(sysctl) #endif +libc_hidden_proto(open) +libc_hidden_proto(read) +libc_hidden_proto(close) +libc_hidden_proto(gettimeofday) + struct arc4_stream { - u_int8_t i; - u_int8_t j; - u_int8_t s[256]; + uint8_t i; + uint8_t j; + uint8_t s[256]; }; static int rs_initialized; @@ -51,8 +55,8 @@ static struct arc4_stream rs; static inline void arc4_init(struct arc4_stream *); static inline void arc4_addrandom(struct arc4_stream *, u_char *, int); static void arc4_stir(struct arc4_stream *); -static inline u_int8_t arc4_getbyte(struct arc4_stream *); -static inline u_int32_t arc4_getword(struct arc4_stream *); +static inline uint8_t arc4_getbyte(struct arc4_stream *); +static inline uint32_t arc4_getword(struct arc4_stream *); static inline void arc4_init(as) @@ -73,7 +77,7 @@ arc4_addrandom(as, dat, datlen) int datlen; { int n; - u_int8_t si; + uint8_t si; as->i--; for (n = 0; n < 256; n++) { @@ -93,20 +97,20 @@ arc4_stir(as) int fd; struct { struct timeval tv; - u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; + uint rnd[(128 - sizeof(struct timeval)) / sizeof(uint)]; } rdat; int n; gettimeofday(&rdat.tv, NULL); - fd = __open("/dev/urandom", O_RDONLY); + fd = open("/dev/urandom", O_RDONLY); if (fd != -1) { - __read(fd, rdat.rnd, sizeof(rdat.rnd)); - __close(fd); + read(fd, rdat.rnd, sizeof(rdat.rnd)); + close(fd); } #ifdef __ARC4RANDOM_USE_ERANDOM__ else { int mib[3]; - u_int i; + uint i; size_t len; /* Device could not be opened, we might be chrooted, take @@ -116,8 +120,8 @@ arc4_stir(as) mib[1] = KERN_RANDOM; mib[2] = RANDOM_ERANDOM; - for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i++) { - len = sizeof(u_int); + for (i = 0; i < sizeof(rdat.rnd) / sizeof(uint); i++) { + len = sizeof(uint); if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) break; } @@ -137,11 +141,11 @@ arc4_stir(as) arc4_getbyte(as); } -static inline u_int8_t +static inline uint8_t arc4_getbyte(as) struct arc4_stream *as; { - u_int8_t si, sj; + uint8_t si, sj; as->i = (as->i + 1); si = as->s[as->i]; @@ -152,11 +156,11 @@ arc4_getbyte(as) return (as->s[(si + sj) & 0xff]); } -static inline u_int32_t +static inline uint32_t arc4_getword(as) struct arc4_stream *as; { - u_int32_t val; + uint32_t val; val = arc4_getbyte(as) << 24; val |= arc4_getbyte(as) << 16; val |= arc4_getbyte(as) << 8; @@ -164,8 +168,9 @@ arc4_getword(as) return val; } +libc_hidden_proto(arc4random_stir) void -arc4random_stir() +arc4random_stir(void) { if (!rs_initialized) { arc4_init(&rs); @@ -173,19 +178,18 @@ arc4random_stir() } arc4_stir(&rs); } +libc_hidden_def(arc4random_stir) void -arc4random_addrandom(dat, datlen) - u_char *dat; - int datlen; +arc4random_addrandom(u_char *dat, int datlen) { if (!rs_initialized) arc4random_stir(); arc4_addrandom(&rs, dat, datlen); } -u_int32_t -arc4random() +uint32_t +arc4random(void) { if (!rs_initialized) arc4random_stir(); @@ -204,5 +208,3 @@ int main(void) { return 0; } #endif - -#endif /* __UCLIBC_HAS_ARC4RANDOM__ */ diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index f6944edc5..158869e77 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -1,351 +1,8 @@ -/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ - /* - * Dec 2000 Manuel Novoa III - * - * Made atexit handling conform to standards... i.e. no args. - * Removed on_exit since it did not match gnu libc definition. - * Combined atexit and __do_exit into one object file. - * - * Feb 2001 Manuel Novoa III - * - * Reworked file after addition of __uClibc_main. - * Changed name of __do_exit to atexit_handler. - * Changed name of __cleanup to __uClibc_cleanup. - * Moved declaration of __uClibc_cleanup to __uClibc_main - * where it is initialized with (possibly weak alias) - * _stdio_term. - * - * Jul 2001 Steve Thayer - * - * Added an on_exit implementation (that now matches gnu libc definition.) - * Pulled atexit_handler out of the atexit object since it is now required by - * on_exit as well. Renamed it to __exit_handler. - * Fixed a problem where exit functions stop getting called if one of - * them calls exit(). - * As a side effect of these changes, abort() no longer calls the exit - * functions (it now matches the gnu libc definition). - * - * August 2002 Erik Andersen - * Added locking so atexit and friends can be thread safe - * - * August 2005 Stephen Warren - * Added __cxa_atexit and __cxa_finalize support + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define _GNU_SOURCE -#include <features.h> -#include <unistd.h> -#include <stdlib.h> -#include <errno.h> -#include <atomic.h> - -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -extern pthread_mutex_t mylock; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) - - -typedef void (*aefuncp) (void); /* atexit function pointer */ -typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ -typedef void (*cxaefuncp) (void *); /* __cxa_atexit function pointer */ -typedef enum { - ef_free, - ef_in_use, - ef_on_exit, - ef_cxa_atexit -} ef_type; /* exit function types */ - -/* this is in the L_exit object */ -extern void (*__exit_cleanup) (int); - -/* these are in the L___do_exit object */ -extern int __exit_slots; -extern int __exit_count; -extern void __exit_handler(int); -struct exit_function { - /* - * 'type' should be of type of the 'enum ef_type' above but since we - * need this element in an atomic operation we have to use 'long int'. - */ - long int type; /* enum ef_type */ - union { - struct { - oefuncp func; - void *arg; - } on_exit; - struct { - cxaefuncp func; - void *arg; - void* dso_handle; - } cxa_atexit; - } funcs; -}; -#ifdef __UCLIBC_DYNAMIC_ATEXIT__ -extern struct exit_function *__exit_function_table; -#else -extern struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT]; -#endif -extern struct exit_function *__new_exitfn (void) attribute_hidden; - -/* this is in the L___cxa_atexit object */ -extern int __cxa_atexit (cxaefuncp, void *arg, void *dso_handle); - - -/* remove old_atexit after 0.9.29 */ -#if defined(L_atexit) || defined(L_old_atexit) -extern void *__dso_handle __attribute__ ((__weak__)); - -/* - * register a function to be called at normal program termination - * (the registered function takes no arguments) - */ -#ifdef L_atexit -int attribute_hidden atexit(aefuncp func) -#else -int old_atexit(aefuncp func) -#endif -{ - /* - * glibc casts aefuncp to cxaefuncp. - * This seems dodgy, but I guess callling a function with more - * parameters than it needs will work everywhere? - */ - return __cxa_atexit((cxaefuncp)func, NULL, - &__dso_handle == NULL ? NULL : __dso_handle); -} -#ifndef L_atexit -weak_alias(old_atexit,atexit) -#endif -#endif - -#ifdef L_on_exit -/* - * register a function to be called at normal program termination - * the registered function takes two arguments: - * status - the exit status that was passed to the exit() function - * arg - generic argument - */ -int on_exit(oefuncp func, void *arg) -{ - struct exit_function *efp; - - if (func == NULL) { - return 0; - } - - efp = __new_exitfn(); - if (efp == NULL) { - return -1; - } - - efp->funcs.on_exit.func = func; - efp->funcs.on_exit.arg = arg; - /* assign last for thread safety, since we're now unlocked */ - efp->type = ef_on_exit; - - return 0; -} -#endif - -#ifdef L___cxa_atexit -extern int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle) -{ - struct exit_function *efp; - - if (func == NULL) { - return 0; - } - - efp = __new_exitfn(); - if (efp == NULL) { - return -1; - } - - efp->funcs.cxa_atexit.func = func; - efp->funcs.cxa_atexit.arg = arg; - efp->funcs.cxa_atexit.dso_handle = dso_handle; - /* assign last for thread safety, since we're now unlocked */ - efp->type = ef_cxa_atexit; - - return 0; -} -#endif - -#ifdef L___cxa_finalize -/* - * If D is non-NULL, call all functions registered with `__cxa_atexit' - * with the same dso handle. Otherwise, if D is NULL, call all of the - * registered handlers. - */ -void __cxa_finalize (void *dso_handle) -{ - struct exit_function *efp; - int exit_count_snapshot = __exit_count; - - /* In reverse order */ - while (exit_count_snapshot) { - efp = &__exit_function_table[--exit_count_snapshot]; - - /* - * We check dso_handle match before we verify the type of the union entry. - * However, the atomic_exchange will validate that we were really "allowed" - * to read dso_handle... - */ - if ((dso_handle == NULL || dso_handle == efp->funcs.cxa_atexit.dso_handle) - /* We don't want to run this cleanup more than once. */ - && !atomic_compare_and_exchange_bool_acq(&efp->type, ef_free, ef_cxa_atexit) - ) { - /* glibc passes status (0) too, but that's not in the prototype */ - (*efp->funcs.cxa_atexit.func)(efp->funcs.cxa_atexit.arg); - } - } - -#if 0 /* haven't looked into this yet... */ - /* - * Remove the registered fork handlers. We do not have to - * unregister anything if the program is going to terminate anyway. - */ -#ifdef UNREGISTER_ATFORK - if (d != NULL) { - UNREGISTER_ATFORK (d); - } -#endif -#endif -} -#endif - -#ifdef L___exit_handler -int __exit_count = 0; /* Number of registered exit functions */ -#ifdef __UCLIBC_DYNAMIC_ATEXIT__ -struct exit_function *__exit_function_table = NULL; -int __exit_slots = 0; /* Size of __exit_function_table */ -#else -struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT]; -#endif - -/* - * Find and return a new exit_function pointer, for atexit, - * onexit and __cxa_atexit to initialize - */ -struct exit_function attribute_hidden *__new_exitfn(void) -{ - struct exit_function *efp; - - LOCK; - -#ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* If we are out of function table slots, make some more */ - if (__exit_slots < __exit_count+1) { - efp=realloc(__exit_function_table, - (__exit_slots+20)*sizeof(struct exit_function)); - if (efp == NULL) { - UNLOCK; - __set_errno(ENOMEM); - return 0; - } - __exit_function_table = efp; - __exit_slots += 20; - } -#else - if (__exit_count >= __UCLIBC_MAX_ATEXIT) { - UNLOCK; - __set_errno(ENOMEM); - return 0; - } -#endif - - __exit_cleanup = __exit_handler; /* enable cleanup */ - efp = &__exit_function_table[__exit_count++]; - efp->type = ef_in_use; - - UNLOCK; - - return efp; -} - -/* - * Handle the work of executing the registered exit functions - * This is called while we are locked, so no additional locking - * is needed... - */ -void __exit_handler(int status) -{ - struct exit_function *efp; - - /* In reverse order */ - while ( __exit_count ) { - efp = &__exit_function_table[--__exit_count]; - switch (efp->type) { - case ef_on_exit: - if (efp->funcs.on_exit.func) { - (efp->funcs.on_exit.func) (status, efp->funcs.on_exit.arg); - } - break; - case ef_cxa_atexit: - if (efp->funcs.cxa_atexit.func) { - /* glibc passes status too, but that's not in the prototype */ - (efp->funcs.cxa_atexit.func) (efp->funcs.cxa_atexit.arg); - } - break; - } - } -#ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* Free up memory used by the __exit_function_table structure */ - if (__exit_function_table) - free(__exit_function_table); -#endif -} -#endif - -#ifdef L_exit -extern void weak_function _stdio_term(void) attribute_hidden; -void (*__exit_cleanup) (int) = 0; -#ifdef __UCLIBC_HAS_THREADS__ -pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif - -#ifdef __UCLIBC_CTOR_DTOR__ -extern void (*__app_fini)(void); -#endif - -extern void (*__rtld_fini)(void); - -/* - * Normal program termination - */ -#undef exit -#undef __exit -void attribute_hidden __exit(int rv) -{ - /* Perform exit-specific cleanup (atexit and on_exit) */ - LOCK; - if (__exit_cleanup) { - __exit_cleanup(rv); - } - UNLOCK; - -#ifdef __UCLIBC_CTOR_DTOR__ - if (__app_fini != NULL) - (__app_fini)(); -#endif - if (__rtld_fini != NULL) - (__rtld_fini)(); - - /* If we are using stdio, try to shut it down. At the very least, - * this will attempt to commit all buffered writes. It may also - * unbuffer all writable files, or close them outright. - * Check the stdio routines for details. */ - if (_stdio_term) - _stdio_term(); - - _exit_internal(rv); -} -strong_alias(__exit,exit) -#endif +#define L_atexit +#include "_atexit.c" diff --git a/libc/stdlib/atof.c b/libc/stdlib/atof.c new file mode 100644 index 000000000..2fdd75cda --- /dev/null +++ b/libc/stdlib/atof.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_atof +#include "stdlib.c" diff --git a/libc/stdlib/atoi.c b/libc/stdlib/atoi.c new file mode 100644 index 000000000..61562bbb2 --- /dev/null +++ b/libc/stdlib/atoi.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_atoi +#include "stdlib.c" diff --git a/libc/stdlib/atol.c b/libc/stdlib/atol.c new file mode 100644 index 000000000..3e5772085 --- /dev/null +++ b/libc/stdlib/atol.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_atol +#include "stdlib.c" diff --git a/libc/stdlib/atoll.c b/libc/stdlib/atoll.c new file mode 100644 index 000000000..f6b04a66c --- /dev/null +++ b/libc/stdlib/atoll.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_atoll +#include "stdlib.c" diff --git a/libc/stdlib/bsd_getpt.c b/libc/stdlib/bsd_getpt.c index aec0ca4bc..9b885c4e5 100644 --- a/libc/stdlib/bsd_getpt.c +++ b/libc/stdlib/bsd_getpt.c @@ -22,6 +22,8 @@ #include <string.h> #include <unistd.h> +libc_hidden_proto(open) +libc_hidden_proto(mempcpy) /* Prefix for master pseudo terminal nodes. */ #define _PATH_PTY "/dev/pty" @@ -48,7 +50,7 @@ __getpt (void) const char *p, *q; char *s; - s = __mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1); + s = mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1); /* s[0] and s[1] will be filled in the loop. */ s[2] = '\0'; @@ -62,7 +64,7 @@ __getpt (void) s[1] = *q; - fd = __open (buf, O_RDWR); + fd = open (buf, O_RDWR); if (fd != -1) return fd; diff --git a/libc/stdlib/bsearch.c b/libc/stdlib/bsearch.c new file mode 100644 index 000000000..4feceefd3 --- /dev/null +++ b/libc/stdlib/bsearch.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_bsearch +#include "stdlib.c" diff --git a/libc/stdlib/drand48-iter.c b/libc/stdlib/drand48-iter.c index bc2c15cb6..0e674a3ce 100644 --- a/libc/stdlib/drand48-iter.c +++ b/libc/stdlib/drand48-iter.c @@ -1,6 +1,6 @@ /* Copyright (C) 1995, 1996, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -24,11 +24,14 @@ #include <sys/types.h> /* Global state for non-reentrant functions. */ -struct drand48_data __libc_drand48_data; +struct drand48_data __libc_drand48_data attribute_hidden; -int attribute_hidden -__drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) +int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) attribute_hidden; +int +__drand48_iterate (xsubi, buffer) + unsigned short int xsubi[3]; + struct drand48_data *buffer; { uint64_t X; uint64_t result; @@ -55,4 +58,3 @@ __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) return 0; } - diff --git a/libc/stdlib/drand48.c b/libc/stdlib/drand48.c index fc66816c1..ab6239d75 100644 --- a/libc/stdlib/drand48.c +++ b/libc/stdlib/drand48.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2001,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -17,18 +17,19 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define erand48_r __erand48_r - #include <stdlib.h> +libc_hidden_proto(erand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; -double drand48 (void) +double +drand48 () { - double result; + double result; - erand48_r (__libc_drand48_data.__x, &__libc_drand48_data, &result); + (void) erand48_r (__libc_drand48_data.__x, &__libc_drand48_data, &result); - return result; + return result; } diff --git a/libc/stdlib/drand48_r.c b/libc/stdlib/drand48_r.c index 14235e6e0..1000a3acb 100644 --- a/libc/stdlib/drand48_r.c +++ b/libc/stdlib/drand48_r.c @@ -1,6 +1,6 @@ /* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -17,13 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define erand48_r __erand48_r - #include <errno.h> #include <math.h> #include <stdlib.h> +libc_hidden_proto(erand48_r) + int drand48_r (struct drand48_data *buffer, double *result) { - return erand48_r (buffer->__x, buffer, result); + return erand48_r (buffer->__x, buffer, result); } diff --git a/libc/stdlib/erand48.c b/libc/stdlib/erand48.c index 96a8ad115..853c2c35a 100644 --- a/libc/stdlib/erand48.c +++ b/libc/stdlib/erand48.c @@ -17,11 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define erand48_r __erand48_r #include <stdlib.h> +libc_hidden_proto(erand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; double erand48 (unsigned short int xsubi[3]) { diff --git a/libc/stdlib/erand48_r.c b/libc/stdlib/erand48_r.c index 0a69266a7..3dd0dfdf0 100644 --- a/libc/stdlib/erand48_r.c +++ b/libc/stdlib/erand48_r.c @@ -24,7 +24,8 @@ extern int __drand48_iterate(unsigned short xsubi[3], struct drand48_data *buffer) attribute_hidden; -int attribute_hidden __erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, double *result) +libc_hidden_proto(erand48_r) +int erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, double *result) { union ieee754_double temp; @@ -45,4 +46,4 @@ int attribute_hidden __erand48_r (unsigned short int xsubi[3], struct drand48_da return 0; } -strong_alias(__erand48_r,erand48_r) +libc_hidden_def(erand48_r) diff --git a/libc/stdlib/exit.c b/libc/stdlib/exit.c new file mode 100644 index 000000000..a2255d2b4 --- /dev/null +++ b/libc/stdlib/exit.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_exit +#include "_atexit.c" diff --git a/libc/stdlib/gcvt.c b/libc/stdlib/gcvt.c index 75e3bbe70..f1c1f4270 100644 --- a/libc/stdlib/gcvt.c +++ b/libc/stdlib/gcvt.c @@ -1,11 +1,13 @@ #include <stdio.h> #include <stdlib.h> +libc_hidden_proto(sprintf) + #ifdef __UCLIBC_HAS_FLOATS__ #define MAX_NDIGIT 17 char *gcvt (double number, int ndigit, char *buf) { - __sprintf(buf, "%.*g", (ndigit > MAX_NDIGIT)? MAX_NDIGIT : ndigit, number); + sprintf(buf, "%.*g", (ndigit > MAX_NDIGIT)? MAX_NDIGIT : ndigit, number); return buf; } #endif diff --git a/libc/stdlib/getenv.c b/libc/stdlib/getenv.c index 6cbdc3e65..4f4c4f1f8 100644 --- a/libc/stdlib/getenv.c +++ b/libc/stdlib/getenv.c @@ -1,42 +1,34 @@ /* getenv.c for uClibc - Erik Andersen <andersen@codepoet.org> - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - 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. - */ + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <string.h> #include <unistd.h> +#include <stdlib.h> + +libc_hidden_proto(getenv) +libc_hidden_proto(memcmp) +libc_hidden_proto(strlen) +libc_hidden_proto(__environ) /* IEEE Std 1003.1-2001 says getenv need not be thread safe, so * don't bother locking access to __environ */ -char attribute_hidden *__getenv(const char *var) +char *getenv(const char *var) { int len; char **ep; if (!(ep=__environ)) return NULL; - len = __strlen(var); + len = strlen(var); while(*ep) { - if (__memcmp(var, *ep, len) == 0 && (*ep)[len] == '=') { + if (memcmp(var, *ep, len) == 0 && (*ep)[len] == '=') { return *ep + len + 1; } ep++; } return NULL; } - -strong_alias(__getenv,getenv) +libc_hidden_def(getenv) diff --git a/libc/stdlib/getpt.c b/libc/stdlib/getpt.c index 4bd082823..cab96bb06 100644 --- a/libc/stdlib/getpt.c +++ b/libc/stdlib/getpt.c @@ -23,6 +23,9 @@ #include <unistd.h> #include <paths.h> +libc_hidden_proto(open) +libc_hidden_proto(close) + #if !defined __ASSUME_DEVPTS__ # include <sys/statfs.h> @@ -55,7 +58,7 @@ getpt (void) if (!have_no_dev_ptmx) #endif { - fd = __open (_PATH_DEVPTMX, O_RDWR); + fd = open (_PATH_DEVPTMX, O_RDWR); if (fd != -1) { #if defined __ASSUME_DEVPTS__ @@ -79,7 +82,7 @@ getpt (void) /* If /dev/pts is not mounted then the UNIX98 pseudo terminals are not usable. */ - __close (fd); + close (fd); #if !defined __UNIX98PTY_ONLY__ have_no_dev_ptmx = 1; #endif diff --git a/libc/stdlib/jrand48.c b/libc/stdlib/jrand48.c index 44b32487f..6f812068b 100644 --- a/libc/stdlib/jrand48.c +++ b/libc/stdlib/jrand48.c @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define jrand48_r __jrand48_r - #include <stdlib.h> +libc_hidden_proto(jrand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; long int jrand48 (unsigned short int xsubi[3]) { diff --git a/libc/stdlib/jrand48_r.c b/libc/stdlib/jrand48_r.c index a21bda080..912f70c4f 100644 --- a/libc/stdlib/jrand48_r.c +++ b/libc/stdlib/jrand48_r.c @@ -22,7 +22,8 @@ extern int __drand48_iterate(unsigned short xsubi[3], struct drand48_data *buffer) attribute_hidden; -int attribute_hidden __jrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result) +libc_hidden_proto(jrand48_r) +int jrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result) { /* Compute next state. */ if (__drand48_iterate (xsubi, buffer) < 0) @@ -33,4 +34,4 @@ int attribute_hidden __jrand48_r (unsigned short int xsubi[3], struct drand48_da return 0; } -strong_alias(__jrand48_r,jrand48_r) +libc_hidden_def(jrand48_r) diff --git a/libc/stdlib/labs.c b/libc/stdlib/labs.c new file mode 100644 index 000000000..95196af99 --- /dev/null +++ b/libc/stdlib/labs.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_labs +#include "stdlib.c" diff --git a/libc/stdlib/ldiv.c b/libc/stdlib/ldiv.c index f8e789a92..88a877116 100644 --- a/libc/stdlib/ldiv.c +++ b/libc/stdlib/ldiv.c @@ -57,5 +57,5 @@ ldiv (long int numer, long int denom) #if __WORDSIZE == 64 #undef imaxdiv -weak_alias (ldiv, imaxdiv) +strong_alias(ldiv,imaxdiv) #endif diff --git a/libc/stdlib/llabs.c b/libc/stdlib/llabs.c new file mode 100644 index 000000000..17ec30a64 --- /dev/null +++ b/libc/stdlib/llabs.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_llabs +#include "stdlib.c" diff --git a/libc/stdlib/lldiv.c b/libc/stdlib/lldiv.c index 56ccb2612..ff670174c 100644 --- a/libc/stdlib/lldiv.c +++ b/libc/stdlib/lldiv.c @@ -17,7 +17,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define _GNU_SOURCE #include <features.h> #include <stdlib.h> @@ -58,5 +57,5 @@ lldiv (long long int numer, long long int denom) #if __WORDSIZE != 64 #undef imaxdiv -weak_alias (lldiv, imaxdiv) +strong_alias(lldiv,imaxdiv) #endif diff --git a/libc/stdlib/lrand48.c b/libc/stdlib/lrand48.c index 88301d70f..863951f07 100644 --- a/libc/stdlib/lrand48.c +++ b/libc/stdlib/lrand48.c @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define nrand48_r __nrand48_r - #include <stdlib.h> +libc_hidden_proto(nrand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; long int lrand48 (void) { diff --git a/libc/stdlib/lrand48_r.c b/libc/stdlib/lrand48_r.c index 0ff1ef25e..277fb9ae3 100644 --- a/libc/stdlib/lrand48_r.c +++ b/libc/stdlib/lrand48_r.c @@ -17,11 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define nrand48_r __nrand48_r - #include <stdlib.h> -int attribute_hidden __lrand48_r (struct drand48_data *buffer, long int *result) +libc_hidden_proto(nrand48_r) + +libc_hidden_proto(lrand48_r) +int lrand48_r (struct drand48_data *buffer, long int *result) { /* Be generous for the arguments, detect some errors. */ if (buffer == NULL) @@ -29,4 +30,4 @@ int attribute_hidden __lrand48_r (struct drand48_data *buffer, long int *result) return nrand48_r (buffer->__x, buffer, result); } -strong_alias(__lrand48_r,lrand48_r) +libc_hidden_def(lrand48_r) diff --git a/libc/stdlib/malloc-simple/Makefile.in b/libc/stdlib/malloc-simple/Makefile.in index 7add9deaa..51488ff58 100644 --- a/libc/stdlib/malloc-simple/Makefile.in +++ b/libc/stdlib/malloc-simple/Makefile.in @@ -1,33 +1,22 @@ # Makefile for uClibc # -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -MSRC:=alloc.c -MOBJ:=malloc.o realloc.o free.o calloc.o memalign.o +STDLIB_MALLOC_SIMPLE_DIR := $(top_srcdir)libc/stdlib/malloc-simple +STDLIB_MALLOC_SIMPLE_OUT := $(top_builddir)libc/stdlib/malloc-simple -STDLIB_MALLOC_SIMPLE_DIR:=$(top_srcdir)libc/stdlib/malloc-simple -STDLIB_MALLOC_SIMPLE_OUT:=$(top_builddir)libc/stdlib/malloc-simple +CSRC := $(notdir $(wildcard $(STDLIB_MALLOC_SIMPLE_DIR)/*.c)) +CSRC := $(filter-out alloc.c,$(CSRC)) -STDLIB_MALLOC_SIMPLE_MSRC:=$(STDLIB_MALLOC_SIMPLE_DIR)/$(MSRC) -STDLIB_MALLOC_SIMPLE_MOBJ:=$(patsubst %.o,$(STDLIB_MALLOC_SIMPLE_OUT)/%.o,$(MOBJ)) -STDLIB_MALLOC_SIMPLE_DEF:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(STDLIB_MALLOC_SIMPLE_MOBJ)))) +STDLIB_MALLOC_SIMPLE_SRC := $(patsubst %.c,$(STDLIB_MALLOC_SIMPLE_DIR)/%.c,$(CSRC)) +STDLIB_MALLOC_SIMPLE_OBJ := $(patsubst %.c,$(STDLIB_MALLOC_SIMPLE_OUT)/%.o,$(CSRC)) -libc-a-$(MALLOC_SIMPLE)+=$(STDLIB_MALLOC_SIMPLE_MOBJ) -libc-so-$(MALLOC_SIMPLE)+=$(STDLIB_MALLOC_SIMPLE_MOBJ:.o=.os) +libc-$(MALLOC_SIMPLE) += $(STDLIB_MALLOC_SIMPLE_OBJ) -CFLAGS-multi-$(MALLOC_SIMPLE)+=$(STDLIB_MALLOC_SIMPLE_DEF) -libc-multi-$(MALLOC_SIMPLE)+=$(STDLIB_MALLOC_SIMPLE_MSRC) - -$(STDLIB_MALLOC_SIMPLE_MOBJ): $(STDLIB_MALLOC_SIMPLE_MSRC) - $(compile.m) - -$(STDLIB_MALLOC_SIMPLE_MOBJ:.o=.os): $(STDLIB_MALLOC_SIMPLE_MSRC) - $(compile.m) - -objclean-y+=stdlib_malloc_simple_objclean +objclean-y += stdlib_malloc_simple_objclean stdlib_malloc_simple_objclean: $(RM) $(STDLIB_MALLOC_SIMPLE_OUT)/*.{o,os} diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c index 5a208bf28..e382cee55 100644 --- a/libc/stdlib/malloc-simple/alloc.c +++ b/libc/stdlib/malloc-simple/alloc.c @@ -1,15 +1,13 @@ /* alloc.c * - * Written by Erik Andersen <andersee@codepoet.org> - * LGPLv2 + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ +/* * Parts of the memalign code were stolen from malloc-930716. */ -#define mmap __mmap -#define munmap __munmap - -#define _GNU_SOURCE #include <features.h> #include <unistd.h> #include <stdio.h> @@ -19,6 +17,10 @@ #include <errno.h> #include <sys/mman.h> +libc_hidden_proto(memcpy) +/*libc_hidden_proto(memset)*/ +libc_hidden_proto(mmap) +libc_hidden_proto(munmap) #ifdef L_malloc void *malloc(size_t size) @@ -34,7 +36,7 @@ void *malloc(size_t size) #endif } -#ifdef __ARCH_HAS_MMU__ +#ifdef __ARCH_USE_MMU__ # define MMAP_FLAGS MAP_PRIVATE | MAP_ANONYMOUS #else # define MMAP_FLAGS MAP_SHARED | MAP_ANONYMOUS @@ -67,7 +69,7 @@ void * calloc(size_t nmemb, size_t lsize) * doesn't need to actually zero anything.... */ if (result != NULL) { - __memset(result, 0, size); + memset(result, 0, size); } #endif return result; @@ -88,7 +90,7 @@ void *realloc(void *ptr, size_t size) newptr = malloc(size); if (newptr) { - __memcpy(newptr, ptr, *((size_t *) (ptr - sizeof(size_t)))); + memcpy(newptr, ptr, *((size_t *) (ptr - sizeof(size_t)))); free(ptr); } return newptr; diff --git a/libc/stdlib/malloc-simple/calloc.c b/libc/stdlib/malloc-simple/calloc.c new file mode 100644 index 000000000..75edff86d --- /dev/null +++ b/libc/stdlib/malloc-simple/calloc.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_calloc +#include "alloc.c" diff --git a/libc/stdlib/malloc-simple/free.c b/libc/stdlib/malloc-simple/free.c new file mode 100644 index 000000000..553a6bfc8 --- /dev/null +++ b/libc/stdlib/malloc-simple/free.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_free +#include "alloc.c" diff --git a/libc/stdlib/malloc-simple/malloc.c b/libc/stdlib/malloc-simple/malloc.c new file mode 100644 index 000000000..61f33d871 --- /dev/null +++ b/libc/stdlib/malloc-simple/malloc.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_malloc +#include "alloc.c" diff --git a/libc/stdlib/malloc-simple/memalign.c b/libc/stdlib/malloc-simple/memalign.c new file mode 100644 index 000000000..24b7ab9c5 --- /dev/null +++ b/libc/stdlib/malloc-simple/memalign.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_memalign +#include "alloc.c" diff --git a/libc/stdlib/malloc-simple/realloc.c b/libc/stdlib/malloc-simple/realloc.c new file mode 100644 index 000000000..de9675d59 --- /dev/null +++ b/libc/stdlib/malloc-simple/realloc.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_realloc +#include "alloc.c" diff --git a/libc/stdlib/malloc-standard/Makefile.in b/libc/stdlib/malloc-standard/Makefile.in index e566dad8c..1d29703c4 100644 --- a/libc/stdlib/malloc-standard/Makefile.in +++ b/libc/stdlib/malloc-standard/Makefile.in @@ -1,32 +1,29 @@ # Makefile for uClibc # # Copyright (C) 2000 by Lineo, inc. -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # # Turn on malloc debugging if requested ifeq ($(UCLIBC_MALLOC_DEBUGGING),y) -CFLAGS+=-D__MALLOC_DEBUGGING +CFLAGS += -D__MALLOC_DEBUGGING endif # calloc.c can be found at uClibc/libc/stdlib/calloc.c # valloc.c can be found at uClibc/libc/stdlib/valloc.c -CSRC:=malloc.c calloc.c realloc.c free.c memalign.c mallopt.c mallinfo.c +CSRC := malloc.c calloc.c realloc.c free.c memalign.c mallopt.c mallinfo.c -STDLIB_MALLOC_STANDARD_DIR:=$(top_srcdir)libc/stdlib/malloc-standard -STDLIB_MALLOC_STANDARD_OUT:=$(top_builddir)libc/stdlib/malloc-standard +STDLIB_MALLOC_STANDARD_DIR := $(top_srcdir)libc/stdlib/malloc-standard +STDLIB_MALLOC_STANDARD_OUT := $(top_builddir)libc/stdlib/malloc-standard -STDLIB_MALLOC_STANDARD_SRC:=$(patsubst %.c,$(STDLIB_MALLOC_STANDARD_DIR)/%.c,$(CSRC)) -STDLIB_MALLOC_STANDARD_OBJ:=$(patsubst %.c,$(STDLIB_MALLOC_STANDARD_OUT)/%.o,$(CSRC)) +STDLIB_MALLOC_STANDARD_SRC := $(patsubst %.c,$(STDLIB_MALLOC_STANDARD_DIR)/%.c,$(CSRC)) +STDLIB_MALLOC_STANDARD_OBJ := $(patsubst %.c,$(STDLIB_MALLOC_STANDARD_OUT)/%.o,$(CSRC)) -libc-a-$(MALLOC_STANDARD)+=$(STDLIB_MALLOC_STANDARD_OBJ) -libc-so-$(MALLOC_STANDARD)+=$(STDLIB_MALLOC_STANDARD_OBJ:.o=.os) +libc-$(MALLOC_STANDARD) += $(STDLIB_MALLOC_STANDARD_OBJ) -libc-multi-$(MALLOC_STANDARD)+=$(STDLIB_MALLOC_STANDARD_SRC) - -objclean-y+=stdlib_malloc_standard_objclean +objclean-y += stdlib_malloc_standard_objclean stdlib_malloc_standard_objclean: $(RM) $(STDLIB_MALLOC_STANDARD_OUT)/*.{o,os} diff --git a/libc/stdlib/malloc-standard/calloc.c b/libc/stdlib/malloc-standard/calloc.c index b8c43d9dc..99e8884ad 100644 --- a/libc/stdlib/malloc-standard/calloc.c +++ b/libc/stdlib/malloc-standard/calloc.c @@ -16,6 +16,7 @@ #include "malloc.h" +libc_hidden_proto(memset) /* ------------------------------ calloc ------------------------------ */ void* calloc(size_t n_elements, size_t elem_size) @@ -54,7 +55,7 @@ void* calloc(size_t n_elements, size_t elem_size) assert(nclears >= 3); if (nclears > 9) - __memset(d, 0, clearsize); + memset(d, 0, clearsize); else { *(d+0) = 0; @@ -83,7 +84,7 @@ void* calloc(size_t n_elements, size_t elem_size) d = (size_t*)mem; /* Note the additional (sizeof(size_t)) */ clearsize = chunksize(p) - 2*(sizeof(size_t)); - __memset(d, 0, clearsize); + memset(d, 0, clearsize); } #endif } diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c index 1b294d706..e0c6ef061 100644 --- a/libc/stdlib/malloc-standard/free.c +++ b/libc/stdlib/malloc-standard/free.c @@ -14,10 +14,9 @@ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> */ -#define munmap __munmap - #include "malloc.h" +libc_hidden_proto(munmap) /* ------------------------- __malloc_trim ------------------------- __malloc_trim is an inverse of sorts to __malloc_alloc. It gives memory @@ -402,13 +401,10 @@ void free(void* mem) */ else { - int ret; size_t offset = p->prev_size; av->n_mmaps--; av->mmapped_mem -= (size + offset); - ret = munmap((char*)p - offset, size + offset); - /* munmap returns non-zero on failure */ - assert(ret == 0); + munmap((char*)p - offset, size + offset); } UNLOCK; } diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c index 029ceda1f..89c9a6e7e 100644 --- a/libc/stdlib/malloc-standard/mallinfo.c +++ b/libc/stdlib/malloc-standard/mallinfo.c @@ -16,9 +16,12 @@ #include "malloc.h" +libc_hidden_proto(fprintf) +libc_hidden_proto(stderr) /* ------------------------------ mallinfo ------------------------------ */ -struct mallinfo attribute_hidden __mallinfo(void) +libc_hidden_proto(mallinfo) +struct mallinfo mallinfo(void) { mstate av; struct mallinfo mi; @@ -78,7 +81,7 @@ struct mallinfo attribute_hidden __mallinfo(void) UNLOCK; return mi; } -strong_alias(__mallinfo,mallinfo) +libc_hidden_def(mallinfo) void malloc_stats(FILE *file) { @@ -88,7 +91,7 @@ void malloc_stats(FILE *file) file = stderr; } - mi = __mallinfo(); + mi = mallinfo(); fprintf(file, "total bytes allocated = %10u\n", (unsigned int)(mi.arena + mi.hblkhd)); fprintf(file, "total bytes in use bytes = %10u\n", (unsigned int)(mi.uordblks + mi.hblkhd)); fprintf(file, "total non-mmapped bytes allocated = %10d\n", mi.arena); diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index 7025e8335..10d421330 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -14,12 +14,12 @@ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> */ -#define _GNU_SOURCE #include "malloc.h" #ifdef __UCLIBC_HAS_THREADS__ pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +libc_hidden_data_def(__malloc_lock) #endif /* diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h index 68d38cb3d..a3fabb0c4 100644 --- a/libc/stdlib/malloc-standard/malloc.h +++ b/libc/stdlib/malloc-standard/malloc.h @@ -14,10 +14,6 @@ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> */ -#define mmap __mmap -#define sysconf __sysconf -#define sbrk __sbrk - #include <features.h> #include <stddef.h> #include <unistd.h> @@ -25,11 +21,17 @@ #include <string.h> #include <malloc.h> #include <stdlib.h> +#include <sys/mman.h> +libc_hidden_proto(mmap) +libc_hidden_proto(sysconf) +libc_hidden_proto(sbrk) +libc_hidden_proto(abort) #ifdef __UCLIBC_HAS_THREADS__ # include <pthread.h> extern pthread_mutex_t __malloc_lock; +libc_hidden_proto(__malloc_lock) #endif #define LOCK __pthread_mutex_lock(&__malloc_lock) #define UNLOCK __pthread_mutex_unlock(&__malloc_lock) @@ -352,7 +354,7 @@ extern pthread_mutex_t __malloc_lock; #define MAP_ANONYMOUS MAP_ANON #endif -#ifdef __ARCH_HAS_MMU__ +#ifdef __ARCH_USE_MMU__ #define MMAP(addr, size, prot) \ (mmap((addr), (size), (prot), MAP_PRIVATE|MAP_ANONYMOUS, 0, 0)) diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c index bd9536272..27502893d 100644 --- a/libc/stdlib/malloc-standard/memalign.c +++ b/libc/stdlib/malloc-standard/memalign.c @@ -28,7 +28,7 @@ void* memalign(size_t alignment, size_t bytes) size_t nb; /* padded request size */ char* m; /* memory returned by malloc call */ mchunkptr p; /* corresponding chunk */ - char* brk; /* alignment point within p */ + char* _brk; /* alignment point within p */ mchunkptr newp; /* chunk to return */ size_t newsize; /* its size */ size_t leadsize; /* leading space before alignment point */ @@ -79,13 +79,13 @@ void* memalign(size_t alignment, size_t bytes) total room so that this is always possible. */ - brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) & + _brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) & -((signed long) alignment))); - if ((unsigned long)(brk - (char*)(p)) < MINSIZE) - brk += alignment; + if ((unsigned long)(_brk - (char*)(p)) < MINSIZE) + _brk += alignment; - newp = (mchunkptr)brk; - leadsize = brk - (char*)(p); + newp = (mchunkptr)_brk; + leadsize = _brk - (char*)(p); newsize = chunksize(p) - leadsize; /* For mmapped chunks, just adjust offset */ diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c index 36bfe4d99..ae2d33bee 100644 --- a/libc/stdlib/malloc-standard/realloc.c +++ b/libc/stdlib/malloc-standard/realloc.c @@ -14,11 +14,10 @@ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> */ -#define mremap __mremap - #include "malloc.h" - +libc_hidden_proto(mremap) +libc_hidden_proto(memcpy) /* ------------------------------ realloc ------------------------------ */ void* realloc(void* oldmem, size_t bytes) @@ -128,7 +127,7 @@ void* realloc(void* oldmem, size_t bytes) assert(ncopies >= 3); if (ncopies > 9) - __memcpy(d, s, copysize); + memcpy(d, s, copysize); else { *(d+0) = *(s+0); @@ -228,7 +227,7 @@ void* realloc(void* oldmem, size_t bytes) /* Must alloc, copy, free. */ newmem = malloc(nb - MALLOC_ALIGN_MASK); if (newmem != 0) { - __memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t))); + memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t))); free(oldmem); } } diff --git a/libc/stdlib/malloc/Makefile.in b/libc/stdlib/malloc/Makefile.in index 55831c379..73e0d6419 100644 --- a/libc/stdlib/malloc/Makefile.in +++ b/libc/stdlib/malloc/Makefile.in @@ -2,35 +2,32 @@ # # Copyright (C) 2002-2003 NEC Electronics Corporation # Copyright (C) 2002-2003 Miles Bader <miles@gnu.org> -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC:= malloc.c calloc.c free.c realloc.c memalign.c \ +CSRC := malloc.c calloc.c free.c realloc.c memalign.c \ heap_alloc.c heap_alloc_at.c heap_free.c # Turn on malloc debugging if requested ifeq ($(UCLIBC_MALLOC_DEBUGGING),y) -CSRC+=malloc_debug.c heap_debug.c -CFLAGS+=-DMALLOC_DEBUGGING -DHEAP_DEBUGGING +CSRC += malloc_debug.c heap_debug.c +CFLAGS += -DMALLOC_DEBUGGING -DHEAP_DEBUGGING ifeq ($(UCLIBC_UCLINUX_BROKEN_MUNMAP),y) -CFLAGS+=-DMALLOC_MMB_DEBUGGING +CFLAGS += -DMALLOC_MMB_DEBUGGING endif endif -STDLIB_MALLOC_DIR:=$(top_srcdir)libc/stdlib/malloc -STDLIB_MALLOC_OUT:=$(top_builddir)libc/stdlib/malloc +STDLIB_MALLOC_DIR := $(top_srcdir)libc/stdlib/malloc +STDLIB_MALLOC_OUT := $(top_builddir)libc/stdlib/malloc -STDLIB_MALLOC_SRC:=$(patsubst %.c,$(STDLIB_MALLOC_DIR)/%.c,$(CSRC)) -STDLIB_MALLOC_OBJ:=$(patsubst %.c,$(STDLIB_MALLOC_OUT)/%.o,$(CSRC)) +STDLIB_MALLOC_SRC := $(patsubst %.c,$(STDLIB_MALLOC_DIR)/%.c,$(CSRC)) +STDLIB_MALLOC_OBJ := $(patsubst %.c,$(STDLIB_MALLOC_OUT)/%.o,$(CSRC)) -libc-a-$(MALLOC)+=$(STDLIB_MALLOC_OBJ) -libc-so-$(MALLOC)+=$(STDLIB_MALLOC_OBJ:.o=.os) +libc-$(MALLOC) += $(STDLIB_MALLOC_OBJ) -libc-multi-$(MALLOC)+=$(STDLIB_MALLOC_SRC) - -objclean-y+=stdlib_malloc_objclean +objclean-y += stdlib_malloc_objclean stdlib_malloc_objclean: $(RM) $(STDLIB_MALLOC_OUT)/*.{o,os} diff --git a/libc/stdlib/malloc/calloc.c b/libc/stdlib/malloc/calloc.c index 94031ce29..5925a9e0a 100644 --- a/libc/stdlib/malloc/calloc.c +++ b/libc/stdlib/malloc/calloc.c @@ -22,6 +22,8 @@ #include <string.h> #include <errno.h> +libc_hidden_proto(memset) + void * calloc(size_t nmemb, size_t lsize) { void *result; @@ -34,7 +36,7 @@ void * calloc(size_t nmemb, size_t lsize) return NULL; } if ((result=malloc(size)) != NULL) { - __memset(result, 0, size); + memset(result, 0, size); } return result; } diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c index 81ec38cd9..81c718376 100644 --- a/libc/stdlib/malloc/free.c +++ b/libc/stdlib/malloc/free.c @@ -11,17 +11,16 @@ * Written by Miles Bader <miles@gnu.org> */ -#define munmap __munmap -#define sbrk __sbrk - #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> +libc_hidden_proto(munmap) +libc_hidden_proto(sbrk) + #include "malloc.h" #include "heap.h" - static void free_to_heap (void *mem, struct heap *heap) { diff --git a/libc/stdlib/malloc/heap_debug.c b/libc/stdlib/malloc/heap_debug.c index 7dab95627..9e5b61c43 100644 --- a/libc/stdlib/malloc/heap_debug.c +++ b/libc/stdlib/malloc/heap_debug.c @@ -11,13 +11,14 @@ * Written by Miles Bader <miles@gnu.org> */ -#define vfprintf __vfprintf - #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <string.h> +libc_hidden_proto(vfprintf) +libc_hidden_proto(fprintf) + #include "malloc.h" #include "heap.h" diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c index 6bc8d8773..2ec8b07da 100644 --- a/libc/stdlib/malloc/malloc.c +++ b/libc/stdlib/malloc/malloc.c @@ -11,14 +11,14 @@ * Written by Miles Bader <miles@gnu.org> */ -#define mmap __mmap -#define sbrk __sbrk - #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/mman.h> +libc_hidden_proto(mmap) +libc_hidden_proto(sbrk) + #include "malloc.h" #include "heap.h" @@ -106,7 +106,7 @@ malloc_from_heap (size_t size, struct heap *heap) #else /* !MALLOC_USE_SBRK */ /* Otherwise, use mmap. */ -#ifdef __ARCH_HAS_MMU__ +#ifdef __ARCH_USE_MMU__ block = mmap ((void *)0, block_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); #else diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h index 707cad13d..753205443 100644 --- a/libc/stdlib/malloc/malloc.h +++ b/libc/stdlib/malloc/malloc.h @@ -16,6 +16,7 @@ /* The system pagesize... */ extern size_t __pagesize; +libc_hidden_proto(__pagesize) #define MALLOC_PAGE_SIZE __pagesize /* The minimum size of block we request from the the system to extend the @@ -43,7 +44,7 @@ extern size_t __pagesize; heap, instead of mmap/munmap. This is a tradeoff -- sbrk is faster than mmap/munmap, and guarantees contiguous allocation, but is also less flexible, and causes the heap to only be shrinkable from the end. */ -#ifdef __ARCH_HAS_MMU__ +#ifdef __ARCH_USE_MMU__ # define MALLOC_USE_SBRK #endif diff --git a/libc/stdlib/malloc/malloc_debug.c b/libc/stdlib/malloc/malloc_debug.c index abe5546ca..6c74d78bb 100644 --- a/libc/stdlib/malloc/malloc_debug.c +++ b/libc/stdlib/malloc/malloc_debug.c @@ -11,14 +11,16 @@ * Written by Miles Bader <miles@gnu.org> */ -#define atoi __atoi -#define vfprintf __vfprintf - #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <stdarg.h> +libc_hidden_proto(atoi) +libc_hidden_proto(vfprintf) +libc_hidden_proto(putc) +libc_hidden_proto(getenv) + #include "malloc.h" #include "heap.h" @@ -42,7 +44,7 @@ __malloc_debug_printf (int indent, const char *fmt, ...) while (spaces > 0) { - __putc (' ', stderr); + putc (' ', stderr); spaces--; } @@ -50,7 +52,7 @@ __malloc_debug_printf (int indent, const char *fmt, ...) vfprintf (stderr, fmt, val); va_end (val); - __putc ('\n', stderr); + putc ('\n', stderr); __malloc_debug_indent (indent); } @@ -58,7 +60,7 @@ __malloc_debug_printf (int indent, const char *fmt, ...) void __malloc_debug_init (void) { - char *ev = __getenv ("MALLOC_DEBUG"); + char *ev = getenv ("MALLOC_DEBUG"); if (ev) { int val = atoi (ev); diff --git a/libc/stdlib/malloc/memalign.c b/libc/stdlib/malloc/memalign.c index ce13eb99d..5b248f3e2 100644 --- a/libc/stdlib/malloc/memalign.c +++ b/libc/stdlib/malloc/memalign.c @@ -30,6 +30,7 @@ \____ INIT ____/ \______ RETURNED _______/ \____ END ___/ */ +void *memalign (size_t alignment, size_t size); void * memalign (size_t alignment, size_t size) { diff --git a/libc/stdlib/malloc/realloc.c b/libc/stdlib/malloc/realloc.c index 8dcc35360..4d56565aa 100644 --- a/libc/stdlib/malloc/realloc.c +++ b/libc/stdlib/malloc/realloc.c @@ -15,6 +15,8 @@ #include <string.h> #include <errno.h> +libc_hidden_proto(memcpy) + #include "malloc.h" #include "heap.h" @@ -26,13 +28,13 @@ realloc (void *mem, size_t new_size) char *base_mem; /* Check for special cases. */ - if (! mem) - return malloc (new_size); if (! new_size) { free (mem); return malloc (new_size); } + if (! mem) + return malloc (new_size); /* Normal realloc. */ @@ -66,7 +68,7 @@ realloc (void *mem, size_t new_size) void *new_mem = malloc (new_size - MALLOC_HEADER_SIZE); if (new_mem) { - __memcpy (new_mem, mem, size - MALLOC_HEADER_SIZE); + memcpy (new_mem, mem, size - MALLOC_HEADER_SIZE); free (mem); } mem = new_mem; diff --git a/libc/stdlib/mblen.c b/libc/stdlib/mblen.c new file mode 100644 index 000000000..c7a0ccb6e --- /dev/null +++ b/libc/stdlib/mblen.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_mblen +#include "stdlib.c" diff --git a/libc/stdlib/mbstowcs.c b/libc/stdlib/mbstowcs.c new file mode 100644 index 000000000..f61800373 --- /dev/null +++ b/libc/stdlib/mbstowcs.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_mbstowcs +#include "stdlib.c" diff --git a/libc/stdlib/mbtowc.c b/libc/stdlib/mbtowc.c new file mode 100644 index 000000000..5d888d163 --- /dev/null +++ b/libc/stdlib/mbtowc.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_mbtowc +#include "stdlib.c" diff --git a/libc/stdlib/mrand48.c b/libc/stdlib/mrand48.c index e9d5353ad..6905545bd 100644 --- a/libc/stdlib/mrand48.c +++ b/libc/stdlib/mrand48.c @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define jrand48_r __jrand48_r - #include <stdlib.h> +libc_hidden_proto(jrand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; long int mrand48 (void) { diff --git a/libc/stdlib/mrand48_r.c b/libc/stdlib/mrand48_r.c index f79e5f887..ca2bd7bbb 100644 --- a/libc/stdlib/mrand48_r.c +++ b/libc/stdlib/mrand48_r.c @@ -17,10 +17,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define jrand48_r __jrand48_r - #include <stdlib.h> +libc_hidden_proto(jrand48_r) + int mrand48_r (struct drand48_data *buffer, long int *result) { /* Be generous for the arguments, detect some errors. */ diff --git a/libc/stdlib/nrand48.c b/libc/stdlib/nrand48.c index 6cdf4ebad..0199a30a5 100644 --- a/libc/stdlib/nrand48.c +++ b/libc/stdlib/nrand48.c @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define nrand48_r __nrand48_r - #include <stdlib.h> +libc_hidden_proto(nrand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; long int nrand48 (unsigned short int xsubi[3]) { diff --git a/libc/stdlib/nrand48_r.c b/libc/stdlib/nrand48_r.c index f72c07030..f45cb1132 100644 --- a/libc/stdlib/nrand48_r.c +++ b/libc/stdlib/nrand48_r.c @@ -22,7 +22,8 @@ extern int __drand48_iterate(unsigned short xsubi[3], struct drand48_data *buffer) attribute_hidden; -int attribute_hidden __nrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result) +libc_hidden_proto(nrand48_r) +int nrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result) { /* Compute next state. */ if (__drand48_iterate (xsubi, buffer) < 0) @@ -36,4 +37,4 @@ int attribute_hidden __nrand48_r (unsigned short int xsubi[3], struct drand48_da return 0; } -strong_alias(__nrand48_r,nrand48_r) +libc_hidden_def(nrand48_r) diff --git a/libc/stdlib/old_atexit.c b/libc/stdlib/old_atexit.c new file mode 100644 index 000000000..b15fd0aa2 --- /dev/null +++ b/libc/stdlib/old_atexit.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_old_atexit +#include "_atexit.c" diff --git a/libc/stdlib/on_exit.c b/libc/stdlib/on_exit.c new file mode 100644 index 000000000..cb943aca1 --- /dev/null +++ b/libc/stdlib/on_exit.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_on_exit +#include "_atexit.c" diff --git a/libc/stdlib/ptsname.c b/libc/stdlib/ptsname.c index 8e18e3989..b41f6a118 100644 --- a/libc/stdlib/ptsname.c +++ b/libc/stdlib/ptsname.c @@ -17,8 +17,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define isatty __isatty - #define _ISOC99_SOURCE #include <stdio.h> #include <errno.h> @@ -32,6 +30,13 @@ #include <unistd.h> #include <bits/uClibc_uintmaxtostr.h> +libc_hidden_proto(strcat) +libc_hidden_proto(strcpy) +libc_hidden_proto(strlen) +libc_hidden_proto(isatty) +libc_hidden_proto(ioctl) +libc_hidden_proto(fstat) +libc_hidden_proto(stat) #if !defined __UNIX98PTY_ONLY__ @@ -64,7 +69,8 @@ extern const char __libc_ptyname2[] attribute_hidden; /* Store at most BUFLEN characters of the pathname of the slave pseudo terminal associated with the master FD is open on in BUF. Return 0 on success, otherwise an error number. */ -int attribute_hidden __ptsname_r (int fd, char *buf, size_t buflen) +libc_hidden_proto(ptsname_r) +int ptsname_r (int fd, char *buf, size_t buflen) { int save_errno = errno; #if !defined __UNIX98PTY_ONLY__ @@ -88,7 +94,7 @@ int attribute_hidden __ptsname_r (int fd, char *buf, size_t buflen) # error "__UNIX98PTY_ONLY__ enabled but TIOCGPTN ioctl not supported by your kernel." #endif #ifdef TIOCGPTN - if (__ioctl (fd, TIOCGPTN, &ptyno) == 0) + if (ioctl (fd, TIOCGPTN, &ptyno) == 0) { /* Buffer we use to print the number in. */ char numbuf[__BUFLEN_INT10TOSTR]; @@ -103,8 +109,8 @@ int attribute_hidden __ptsname_r (int fd, char *buf, size_t buflen) return ERANGE; } - __strcpy (buf, devpts); - __strcat (buf, p); + strcpy (buf, devpts); + strcat (buf, p); /* Note: Don't bother with stat on the slave name and checking the driver's major device number - the ioctl above succeeded so we know the fd was a Unix'98 master and the /dev/pts/ prefix @@ -130,13 +136,13 @@ int attribute_hidden __ptsname_r (int fd, char *buf, size_t buflen) { char *p; - if (buflen < __strlen (_PATH_TTY) + 3) + if (buflen < strlen (_PATH_TTY) + 3) { errno = ERANGE; return ERANGE; } - if (__fstat (fd, &st) < 0) + if (fstat (fd, &st) < 0) return errno; /* Check if FD really is a master pseudo terminal. */ @@ -152,20 +158,20 @@ int attribute_hidden __ptsname_r (int fd, char *buf, size_t buflen) if (major (st.st_rdev) == 4) ptyno -= 128; - if (ptyno / 16 >= __strlen (__libc_ptyname1)) + if (ptyno / 16 >= strlen (__libc_ptyname1)) { errno = ENOTTY; return ENOTTY; } - __strcpy (buf, _PATH_TTY); - p = buf + __strlen (buf); + strcpy (buf, _PATH_TTY); + p = buf + strlen (buf); p[0] = __libc_ptyname1[ptyno / 16]; p[1] = __libc_ptyname2[ptyno % 16]; p[2] = '\0'; } - if (__stat(buf, &st) < 0) + if (stat(buf, &st) < 0) return errno; /* Check if the name we're about to return really corresponds to a @@ -181,7 +187,7 @@ int attribute_hidden __ptsname_r (int fd, char *buf, size_t buflen) errno = save_errno; return 0; } -strong_alias(__ptsname_r,ptsname_r) +libc_hidden_def(ptsname_r) /* Return the pathname of the pseudo terminal slave assoicated with the master FD is open on, or NULL on errors. @@ -191,5 +197,5 @@ ptsname (int fd) { static char buffer[sizeof (_PATH_DEVPTS) + 20]; - return __ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer; + return ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer; } diff --git a/libc/stdlib/qsort.c b/libc/stdlib/qsort.c new file mode 100644 index 000000000..31fc2eaf8 --- /dev/null +++ b/libc/stdlib/qsort.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_qsort +#include "stdlib.c" diff --git a/libc/stdlib/rand.c b/libc/stdlib/rand.c index a4c739c18..cdf58ecc7 100644 --- a/libc/stdlib/rand.c +++ b/libc/stdlib/rand.c @@ -17,10 +17,10 @@ * write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ -#define random __random - #include <stdlib.h> +libc_hidden_proto(random) + int rand (void) { return((int)random()); diff --git a/libc/stdlib/random.c b/libc/stdlib/random.c index eb146098a..9f1977ee3 100644 --- a/libc/stdlib/random.c +++ b/libc/stdlib/random.c @@ -22,17 +22,16 @@ * Rewritten to use reentrant functions by Ulrich Drepper, 1995. */ -#define random_r __random_r -#define srandom_r __srandom_r -#define setstate_r __setstate_r -#define initstate_r __initstate_r - -#define _GNU_SOURCE #include <features.h> #include <limits.h> #include <stddef.h> #include <stdlib.h> +libc_hidden_proto(random_r) +libc_hidden_proto(srandom_r) +libc_hidden_proto(setstate_r) +libc_hidden_proto(initstate_r) + #ifdef __UCLIBC_HAS_THREADS__ # include <pthread.h> /* POSIX.1c requires that there is mutual exclusion for the `rand' and @@ -191,7 +190,7 @@ void srandom (unsigned int x) srandom_r (x, &unsafe_state); __pthread_mutex_unlock(&lock); } -weak_alias (srandom, srand) +strong_alias(srandom,srand) /* Initialize the state information in the given array of N bytes for future random number generation. Based on the number of bytes we @@ -246,7 +245,8 @@ char * setstate (char *arg_state) rear pointers can't wrap on the same call by not testing the rear pointer if the front one has wrapped. Returns a 31-bit random number. */ -long int attribute_hidden __random (void) +libc_hidden_proto(random) +long int random (void) { int32_t retval; @@ -255,4 +255,4 @@ long int attribute_hidden __random (void) __pthread_mutex_unlock(&lock); return retval; } -strong_alias(__random,random) +libc_hidden_def(random) diff --git a/libc/stdlib/random_r.c b/libc/stdlib/random_r.c index b10f29519..e95653545 100644 --- a/libc/stdlib/random_r.c +++ b/libc/stdlib/random_r.c @@ -22,7 +22,6 @@ * Rewritten to be reentrant by Ulrich Drepper, 1995 */ -#define _GNU_SOURCE #include <features.h> #include <errno.h> #include <limits.h> @@ -134,7 +133,8 @@ static const struct random_poly_info random_poly_info = rear pointers can't wrap on the same call by not testing the rear pointer if the front one has wrapped. Returns a 31-bit random number. */ -int attribute_hidden __random_r(struct random_data *buf, int32_t *result) +libc_hidden_proto(random_r) +int random_r(struct random_data *buf, int32_t *result) { int32_t *state; @@ -181,7 +181,7 @@ fail: __set_errno (EINVAL); return -1; } -strong_alias(__random_r,random_r) +libc_hidden_def(random_r) /* Initialize the random number generator based on the given seed. If the type is the trivial no-state-information type, just remember the seed. @@ -191,7 +191,8 @@ strong_alias(__random_r,random_r) information a given number of times to get rid of any initial dependencies introduced by the L.C.R.N.G. Note that the initialization of randtbl[] for default usage relies on values produced by this routine. */ -int attribute_hidden __srandom_r (unsigned int seed, struct random_data *buf) +libc_hidden_proto(srandom_r) +int srandom_r (unsigned int seed, struct random_data *buf) { int type; int32_t *state; @@ -236,7 +237,7 @@ int attribute_hidden __srandom_r (unsigned int seed, struct random_data *buf) while (--kc >= 0) { int32_t discard; - (void) __random_r (buf, &discard); + (void) random_r (buf, &discard); } done: @@ -245,7 +246,7 @@ done: fail: return -1; } -strong_alias(__srandom_r,srandom_r) +libc_hidden_def(srandom_r) /* Initialize the state information in the given array of N bytes for future random number generation. Based on the number of bytes we @@ -258,7 +259,8 @@ strong_alias(__srandom_r,srandom_r) Note: The first thing we do is save the current state, if any, just like setstate so that it doesn't matter when initstate is called. Returns a pointer to the old state. */ -int attribute_hidden __initstate_r (unsigned int seed, char *arg_state, size_t n, struct random_data *buf) +libc_hidden_proto(initstate_r) +int initstate_r (unsigned int seed, char *arg_state, size_t n, struct random_data *buf) { int type; int degree; @@ -294,7 +296,7 @@ int attribute_hidden __initstate_r (unsigned int seed, char *arg_state, size_t n buf->state = state; - __srandom_r (seed, buf); + srandom_r (seed, buf); state[-1] = TYPE_0; if (type != TYPE_0) @@ -306,7 +308,7 @@ fail: __set_errno (EINVAL); return -1; } -strong_alias(__initstate_r,initstate_r) +libc_hidden_def(initstate_r) /* Restore the state from the given state array. Note: It is important that we also remember the locations of the pointers @@ -316,7 +318,8 @@ strong_alias(__initstate_r,initstate_r) to the order in which things are done, it is OK to call setstate with the same state as the current state Returns a pointer to the old state information. */ -int attribute_hidden __setstate_r (char *arg_state, struct random_data *buf) +libc_hidden_proto(setstate_r) +int setstate_r (char *arg_state, struct random_data *buf) { int32_t *new_state = 1 + (int32_t *) arg_state; int type; @@ -359,4 +362,4 @@ fail: __set_errno (EINVAL); return -1; } -strong_alias(__setstate_r,setstate_r) +libc_hidden_def(setstate_r) diff --git a/libc/stdlib/realpath.c b/libc/stdlib/realpath.c index 88677f7a7..c3cc517de 100644 --- a/libc/stdlib/realpath.c +++ b/libc/stdlib/realpath.c @@ -1,21 +1,11 @@ /* * realpath.c -- canonicalize pathname by removing symlinks * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library Public License for more details. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define readlink __readlink -#define getcwd __getcwd - #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -28,9 +18,16 @@ #include <limits.h> /* for PATH_MAX */ #include <sys/param.h> /* for MAXPATHLEN */ #include <errno.h> +#include <stdlib.h> #include <sys/stat.h> /* for S_IFLNK */ +libc_hidden_proto(strcat) +libc_hidden_proto(strcpy) +libc_hidden_proto(strlen) +libc_hidden_proto(readlink) +libc_hidden_proto(getcwd) + #ifndef PATH_MAX #ifdef _POSIX_VERSION #define PATH_MAX _POSIX_PATH_MAX @@ -62,11 +59,11 @@ char resolved_path[]; int n; /* Make a copy of the source path since we may need to modify it. */ - if (__strlen(path) >= PATH_MAX - 2) { + if (strlen(path) >= PATH_MAX - 2) { __set_errno(ENAMETOOLONG); return NULL; } - __strcpy(copy_path, path); + strcpy(copy_path, path); path = copy_path; max_path = copy_path + PATH_MAX - 2; /* If it's a relative pathname use getwd for starters. */ @@ -78,7 +75,7 @@ char resolved_path[]; #else getwd(new_path); #endif - new_path += __strlen(new_path); + new_path += strlen(new_path); if (new_path[-1] != '/') *new_path++ = '/'; } else { @@ -132,7 +129,7 @@ char resolved_path[]; if (errno != EINVAL) { /* Make sure it's null terminated. */ *new_path = '\0'; - __strcpy(resolved_path, got_path); + strcpy(resolved_path, got_path); return NULL; } } else { @@ -145,13 +142,13 @@ char resolved_path[]; /* Otherwise back up over this component. */ while (*(--new_path) != '/'); /* Safe sex check. */ - if (__strlen(path) + n >= PATH_MAX - 2) { + if (strlen(path) + n >= PATH_MAX - 2) { __set_errno(ENAMETOOLONG); return NULL; } /* Insert symlink contents into path. */ - __strcat(link_path, path); - __strcpy(copy_path, link_path); + strcat(link_path, path); + strcpy(copy_path, link_path); path = copy_path; } #endif /* S_IFLNK */ @@ -162,6 +159,6 @@ char resolved_path[]; new_path--; /* Make sure it's null terminated. */ *new_path = '\0'; - __strcpy(resolved_path, got_path); + strcpy(resolved_path, got_path); return resolved_path; } diff --git a/libc/stdlib/seed48.c b/libc/stdlib/seed48.c index 3de07aa31..f068b980d 100644 --- a/libc/stdlib/seed48.c +++ b/libc/stdlib/seed48.c @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define seed48_r __seed48_r - #include <stdlib.h> +libc_hidden_proto(seed48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; unsigned short int * seed48 (unsigned short int seed16v[3]) diff --git a/libc/stdlib/seed48_r.c b/libc/stdlib/seed48_r.c index d1c74f24c..c88d0f23e 100644 --- a/libc/stdlib/seed48_r.c +++ b/libc/stdlib/seed48_r.c @@ -21,10 +21,13 @@ #include <string.h> #include <limits.h> -int attribute_hidden __seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer) +libc_hidden_proto(memcpy) + +libc_hidden_proto(seed48_r) +int seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer) { /* Save old value at a private place to be used as return value. */ - __memcpy (buffer->__old_x, buffer->__x, sizeof (buffer->__x)); + memcpy (buffer->__old_x, buffer->__x, sizeof (buffer->__x)); /* Install new state. */ buffer->__x[2] = seed16v[2]; @@ -36,4 +39,4 @@ int attribute_hidden __seed48_r (unsigned short int seed16v[3], struct drand48_d return 0; } -strong_alias(__seed48_r,seed48_r) +libc_hidden_def(seed48_r) diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c index 413ebed9e..e7dc26053 100644 --- a/libc/stdlib/setenv.c +++ b/libc/stdlib/setenv.c @@ -19,15 +19,20 @@ modified for uClibc by Erik Andersen <andersen@codepoet.org> */ -#define strndup __strndup - -#define _GNU_SOURCE #include <features.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +libc_hidden_proto(memcpy) +libc_hidden_proto(strchr) +libc_hidden_proto(strlen) +libc_hidden_proto(strncmp) +libc_hidden_proto(strndup) +libc_hidden_proto(unsetenv) +libc_hidden_proto(__environ) + #ifdef __UCLIBC_HAS_THREADS__ # include <pthread.h> static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; @@ -35,7 +40,6 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; #define LOCK __pthread_mutex_lock(&mylock) #define UNLOCK __pthread_mutex_unlock(&mylock) -extern int __unsetenv (__const char *__name) attribute_hidden; /* If this variable is not a null pointer we allocated the current environment. */ @@ -48,13 +52,15 @@ static char **last_environ; must be used directly. This is all complicated by the fact that we try to reuse values once generated for a `setenv' call since we can never free the strings. */ -int attribute_hidden __add_to_environ (const char *name, const char *value, +int __add_to_environ (const char *name, const char *value, + const char *combined, int replace) attribute_hidden; +int __add_to_environ (const char *name, const char *value, const char *combined, int replace) { register char **ep; register size_t size; - const size_t namelen = __strlen (name); - const size_t vallen = value != NULL ? __strlen (value) + 1 : 0; + const size_t namelen = strlen (name); + const size_t vallen = value != NULL ? strlen (value) + 1 : 0; LOCK; @@ -65,7 +71,7 @@ int attribute_hidden __add_to_environ (const char *name, const char *value, size = 0; if (ep != NULL) { for (; *ep != NULL; ++ep) { - if (!__strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') break; else ++size; @@ -97,13 +103,13 @@ int attribute_hidden __add_to_environ (const char *name, const char *value, return -1; } - __memcpy (new_environ[size], name, namelen); + memcpy (new_environ[size], name, namelen); new_environ[size][namelen] = '='; - __memcpy (&new_environ[size][namelen + 1], value, vallen); + memcpy (&new_environ[size][namelen + 1], value, vallen); } if (__environ != last_environ) { - __memcpy ((char *) new_environ, (char *) __environ, + memcpy ((char *) new_environ, (char *) __environ, size * sizeof (char *)); } @@ -121,9 +127,9 @@ int attribute_hidden __add_to_environ (const char *name, const char *value, UNLOCK; return -1; } - __memcpy (np, name, namelen); + memcpy (np, name, namelen); np[namelen] = '='; - __memcpy (&np[namelen + 1], value, vallen); + memcpy (&np[namelen + 1], value, vallen); } *ep = np; } @@ -132,27 +138,29 @@ int attribute_hidden __add_to_environ (const char *name, const char *value, return 0; } -int attribute_hidden __setenv (const char *name, const char *value, int replace) +libc_hidden_proto(setenv) +int setenv (const char *name, const char *value, int replace) { return __add_to_environ (name, value, NULL, replace); } -strong_alias(__setenv,setenv) +libc_hidden_def(setenv) -int attribute_hidden __unsetenv (const char *name) +libc_hidden_proto(unsetenv) +int unsetenv (const char *name) { size_t len; char **ep; - if (name == NULL || *name == '\0' || __strchr (name, '=') != NULL) { + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { __set_errno (EINVAL); return -1; } - len = __strlen (name); + len = strlen (name); LOCK; ep = __environ; while (*ep != NULL) { - if (!__strncmp (*ep, name, len) && (*ep)[len] == '=') { + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { /* Found it. Remove this pointer by moving later ones back. */ char **dp = ep; do { @@ -166,7 +174,7 @@ int attribute_hidden __unsetenv (const char *name) UNLOCK; return 0; } -strong_alias(__unsetenv,unsetenv) +libc_hidden_def(unsetenv) /* The `clearenv' was planned to be added to POSIX.1 but probably never made it. Nevertheless the POSIX.9 standard (POSIX bindings @@ -189,7 +197,7 @@ int clearenv (void) int putenv (char *string) { int result; - const char *const name_end = __strchr (string, '='); + const char *const name_end = strchr (string, '='); if (name_end != NULL) { char *name = strndup(string, name_end - string); @@ -197,7 +205,7 @@ int putenv (char *string) free(name); return(result); } - __unsetenv (string); + unsetenv (string); return 0; } diff --git a/libc/stdlib/srand48.c b/libc/stdlib/srand48.c index 1dcdc14a7..42e90c9f9 100644 --- a/libc/stdlib/srand48.c +++ b/libc/stdlib/srand48.c @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define srand48_r __srand48_r - #include <stdlib.h> +libc_hidden_proto(srand48_r) + /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ -extern struct drand48_data __libc_drand48_data; +extern struct drand48_data __libc_drand48_data attribute_hidden; void srand48 (long seedval) { diff --git a/libc/stdlib/srand48_r.c b/libc/stdlib/srand48_r.c index d2f959c79..45bb75f11 100644 --- a/libc/stdlib/srand48_r.c +++ b/libc/stdlib/srand48_r.c @@ -20,7 +20,8 @@ #include <stdlib.h> #include <limits.h> -int attribute_hidden __srand48_r (long int seedval, struct drand48_data *buffer) +libc_hidden_proto(srand48_r) +int srand48_r (long int seedval, struct drand48_data *buffer) { /* The standards say we only have 32 bits. */ if (sizeof (long int) > 4) @@ -36,4 +37,4 @@ int attribute_hidden __srand48_r (long int seedval, struct drand48_data *buffer) return 0; } -strong_alias(__srand48_r,srand48_r) +libc_hidden_def(srand48_r) diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c index 8203881a4..f9ec75555 100644 --- a/libc/stdlib/stdlib.c +++ b/libc/stdlib/stdlib.c @@ -32,55 +32,67 @@ * Add wscto{inttype} functions. */ -#define wcsrtombs __wcsrtombs -#define mbsrtowcs __mbsrtowcs -#define mbrtowc __mbrtowc -#define mbrlen __mbrlen -#define iswspace __iswspace -#define iswspace_l __iswspace_l -#define wcrtomb __wcrtomb - #define _ISOC99_SOURCE /* for ULLONG primarily... */ -#define _GNU_SOURCE #include <limits.h> -#include <stdint.h> -#include <inttypes.h> -#include <ctype.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> - /* Work around gcc's refusal to create aliases. * TODO: Add in a define to disable the aliases? */ #if UINT_MAX == ULONG_MAX -#define atoi __ignore_atoi +#ifdef L_labs #define abs __ignore_abs #endif +#ifdef L_atol +#define atoi __ignore_atoi +#endif +#endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) +#ifdef L_labs #define llabs __ignore_llabs +#endif +#ifdef L_atol #define atoll __ignore_atoll +#endif +#ifdef L_strtol #define strtoll __ignore_strtoll +#endif +#ifdef L_strtoul #define strtoull __ignore_strtoull +#endif +#ifdef L_wcstol #define wcstoll __ignore_wcstoll +#endif +#ifdef L_wcstoul #define wcstoull __ignore_wcstoull +#endif +#ifdef strtol_l #define strtoll_l __ignore_strtoll_l +#endif +#ifdef L_strtoul_l #define strtoull_l __ignore_strtoull_l +#endif +#ifdef L_wcstol_l #define wcstoll_l __ignore_wcstoll_l +#endif +#ifdef L_wcstoul_l #define wcstoull_l __ignore_wcstoull_l #endif +#endif +#if defined(ULLONG_MAX) && (ULLONG_MAX == UINTMAX_MAX) +#if defined L_labs || defined L_llabs +#define imaxabs __ignore_imaxabs +#endif +#endif + +#include <stdint.h> +#include <inttypes.h> +#include <ctype.h> +#include <errno.h> +#include <assert.h> +#include <unistd.h> #include <stdlib.h> #include <locale.h> -extern long int __strtol (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur attribute_hidden; -__extension__ -extern long long int __strtoll (__const char *__restrict __nptr, - char **__restrict __endptr, int __base) - __THROW __nonnull ((1)) __wur attribute_hidden; - #ifdef __UCLIBC_HAS_WCHAR__ #include <wchar.h> @@ -90,6 +102,9 @@ extern long long int __strtoll (__const char *__restrict __nptr, #ifdef __UCLIBC_HAS_XLOCALE__ #include <xlocale.h> #endif /* __UCLIBC_HAS_XLOCALE__ */ +#ifdef __UCLIBC_HAS_LOCALE__ +libc_hidden_proto(__global_locale) +#endif /* TODO: clean up the following... */ @@ -127,49 +142,32 @@ extern long long int __strtoll (__const char *__restrict __nptr, #endif /* __UCLIBC_HAS_LOCALE__ */ -#if UINT_MAX == ULONG_MAX -#undef atoi -#undef abs -#endif -#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) -#undef llabs -#undef atoll -#undef strtoll -#undef strtoull -#undef wcstoll -#undef wcstoull -#undef strtoll_l -#undef strtoull_l -#undef wcstoll_l -#undef wcstoull_l -#endif /* __UCLIBC_HAS_WCHAR__ */ - /**********************************************************************/ #ifdef __UCLIBC_HAS_XLOCALE__ extern unsigned long _stdlib_strto_l_l(register const char * __restrict str, char ** __restrict endptr, int base, int sflag, - __locale_t locale_arg); + __locale_t locale_arg) attribute_hidden; #if defined(ULLONG_MAX) extern unsigned long long _stdlib_strto_ll_l(register const char * __restrict str, char ** __restrict endptr, int base, int sflag, - __locale_t locale_arg); + __locale_t locale_arg) attribute_hidden; #endif #ifdef __UCLIBC_HAS_WCHAR__ extern unsigned long _stdlib_wcsto_l_l(register const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base, int sflag, - __locale_t locale_arg); + __locale_t locale_arg) attribute_hidden; #if defined(ULLONG_MAX) extern unsigned long long _stdlib_wcsto_ll_l(register const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base, int sflag, - __locale_t locale_arg); + __locale_t locale_arg) attribute_hidden; #endif #endif /* __UCLIBC_HAS_WCHAR__ */ @@ -179,35 +177,33 @@ _stdlib_wcsto_ll_l(register const wchar_t * __restrict str, extern unsigned long _stdlib_strto_l(register const char * __restrict str, - char ** __restrict endptr, int base, int sflag); + char ** __restrict endptr, int base, int sflag) attribute_hidden; #if defined(ULLONG_MAX) extern unsigned long long _stdlib_strto_ll(register const char * __restrict str, - char ** __restrict endptr, int base, int sflag); + char ** __restrict endptr, int base, int sflag) attribute_hidden; #endif #ifdef __UCLIBC_HAS_WCHAR__ extern unsigned long _stdlib_wcsto_l(register const wchar_t * __restrict str, - wchar_t ** __restrict endptr, int base, int sflag); + wchar_t ** __restrict endptr, int base, int sflag) attribute_hidden; #if defined(ULLONG_MAX) extern unsigned long long _stdlib_wcsto_ll(register const wchar_t * __restrict str, - wchar_t ** __restrict endptr, int base, int sflag); + wchar_t ** __restrict endptr, int base, int sflag) attribute_hidden; #endif #endif /* __UCLIBC_HAS_WCHAR__ */ /**********************************************************************/ #ifdef L_atof -extern double __strtod (__const char *__restrict __nptr, - char **__restrict __endptr) - __THROW __nonnull ((1)) __wur attribute_hidden; +libc_hidden_proto(strtod) double atof(const char *nptr) { - return __strtod(nptr, (char **) NULL); + return strtod(nptr, (char **) NULL); } #endif @@ -233,14 +229,20 @@ long int labs(long int j) } #if UINT_MAX == ULONG_MAX +#undef abs +extern __typeof(labs) abs; strong_alias(labs,abs) #endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) +#undef llabs +extern __typeof(labs) llabs; strong_alias(labs,llabs) #endif #if ULONG_MAX == UINTMAX_MAX +#undef imaxabs +extern __typeof(labs) imaxabs; strong_alias(labs,imaxabs) #endif @@ -256,6 +258,8 @@ long long int llabs(long long int j) } #if (ULLONG_MAX == UINTMAX_MAX) +#undef imaxabs +extern __typeof(llabs) imaxabs; strong_alias(llabs,imaxabs) #endif @@ -267,11 +271,14 @@ strong_alias(llabs,imaxabs) #if INT_MAX < LONG_MAX -int attribute_hidden __atoi(const char *nptr) +libc_hidden_proto(strtol) + +libc_hidden_proto(atoi) +int atoi(const char *nptr) { - return (int) __strtol(nptr, (char **) NULL, 10); + return (int) strtol(nptr, (char **) NULL, 10); } -strong_alias(__atoi,atoi) +libc_hidden_def(atoi) #endif /* INT_MAX < LONG_MAX */ @@ -279,19 +286,27 @@ strong_alias(__atoi,atoi) /**********************************************************************/ #ifdef L_atol -long attribute_hidden __atol(const char *nptr) +libc_hidden_proto(strtol) + +libc_hidden_proto(atol) +long atol(const char *nptr) { - return __strtol(nptr, (char **) NULL, 10); + return strtol(nptr, (char **) NULL, 10); } -strong_alias(__atol,atol) +libc_hidden_def(atol) #if UINT_MAX == ULONG_MAX -hidden_strong_alias(__atol,__atoi) -strong_alias(__atol,atoi) +#undef atoi +extern __typeof(atol) atoi; +libc_hidden_proto(atoi) +strong_alias(atol,atoi) +libc_hidden_def(atoi) #endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) -strong_alias(__atol,atoll) +#undef atoll +extern __typeof(atol) atoll; +strong_alias(atol,atoll) #endif #endif @@ -300,9 +315,11 @@ strong_alias(__atol,atoll) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) +libc_hidden_proto(strtoll) + long long atoll(const char *nptr) { - return __strtoll(nptr, (char **) NULL, 10); + return strtoll(nptr, (char **) NULL, 10); } #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */ @@ -311,20 +328,28 @@ long long atoll(const char *nptr) /**********************************************************************/ #if defined(L_strtol) || defined(L_strtol_l) -long attribute_hidden __UCXL(strtol)(const char * __restrict str, char ** __restrict endptr, +libc_hidden_proto(__XL_NPP(strtol)) +long __XL_NPP(strtol)(const char * __restrict str, char ** __restrict endptr, int base __LOCALE_PARAM ) { return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG ); } - -__UCXL_ALIAS(strtol) +libc_hidden_def(__XL_NPP(strtol)) #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtol_l) strong_alias(strtol,strtoimax) #endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) -strong_alias(__XL(strtol),__XL(strtoll)) +#ifdef L_strtol_l +#undef strtoll_l +#else +#undef strtoll +#endif +extern __typeof(strtol) __XL_NPP(strtoll); +libc_hidden_proto(__XL_NPP(strtoll)) +strong_alias(__XL_NPP(strtol),__XL_NPP(strtoll)) +libc_hidden_def(__XL_NPP(strtoll)) #endif #endif @@ -333,15 +358,15 @@ strong_alias(__XL(strtol),__XL(strtoll)) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -long long attribute_hidden __UCXL(strtoll)(const char * __restrict str, +libc_hidden_proto(__XL_NPP(strtoll)) +long long __XL_NPP(strtoll)(const char * __restrict str, char ** __restrict endptr, int base __LOCALE_PARAM ) { return (long long) __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 1 __LOCALE_ARG ); } - -__UCXL_ALIAS(strtoll) +libc_hidden_def(__XL_NPP(strtoll)) #if !defined(L_strtoll_l) #if (ULLONG_MAX == UINTMAX_MAX) @@ -356,21 +381,29 @@ strong_alias(strtoll,strtoq) /**********************************************************************/ #if defined(L_strtoul) || defined(L_strtoul_l) -unsigned long attribute_hidden __UCXL(strtoul)(const char * __restrict str, +libc_hidden_proto(__XL_NPP(strtoul)) +unsigned long __XL_NPP(strtoul)(const char * __restrict str, char ** __restrict endptr, int base __LOCALE_PARAM ) { return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0 __LOCALE_ARG ); } - -__UCXL_ALIAS(strtoul) +libc_hidden_def(__XL_NPP(strtoul)) #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtoul_l) strong_alias(strtoul,strtoumax) #endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) -strong_alias(__XL(strtoul),__XL(strtoull)) +#ifdef L_strtoul_l +#undef strtoull_l +#else +#undef strtoull +#endif +extern __typeof(strtoul) __XL_NPP(strtoull); +libc_hidden_proto(__XL_NPP(strtoull)) +strong_alias(__XL_NPP(strtoul),__XL_NPP(strtoull)) +libc_hidden_def(__XL_NPP(strtoull)) #endif @@ -380,14 +413,14 @@ strong_alias(__XL(strtoul),__XL(strtoull)) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -unsigned long long attribute_hidden __UCXL(strtoull)(const char * __restrict str, +libc_hidden_proto(__XL_NPP(strtoull)) +unsigned long long __XL_NPP(strtoull)(const char * __restrict str, char ** __restrict endptr, int base __LOCALE_PARAM ) { return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0 __LOCALE_ARG ); } - -__UCXL_ALIAS(strtoull) +libc_hidden_def(__XL_NPP(strtoull)) #if !defined(L_strtoull_l) #if (ULLONG_MAX == UINTMAX_MAX) @@ -435,8 +468,10 @@ strong_alias(strtoull,strtouq) #define Wuchar __uwchar_t #ifdef __UCLIBC_DO_XLOCALE #define ISSPACE(C) iswspace_l((C), locale_arg) +libc_hidden_proto(iswspace_l) #else #define ISSPACE(C) iswspace((C)) +libc_hidden_proto(iswspace) #endif #else /* defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l) */ @@ -445,8 +480,10 @@ strong_alias(strtoull,strtouq) #define Wuchar unsigned char #ifdef __UCLIBC_DO_XLOCALE #define ISSPACE(C) isspace_l((C), locale_arg) +libc_hidden_proto(isspace_l) #else #define ISSPACE(C) isspace((C)) +libc_hidden_proto(isspace) #endif #endif /* defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l) */ @@ -466,6 +503,12 @@ unsigned long attribute_hidden _stdlib_strto_l(register const Wchar * __restrict /* This is the main work fuction which handles both strtol (sflag = 1) and * strtoul (sflag = 0). */ +#ifdef __UCLIBC_HAS_XLOCALE__ +libc_hidden_proto(__ctype_b_loc) +#else +libc_hidden_proto(__ctype_b) +#endif + unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * __restrict str, Wchar ** __restrict endptr, int base, int sflag __LOCALE_PARAM ) @@ -580,8 +623,10 @@ unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * #define Wuchar __uwchar_t #ifdef __UCLIBC_DO_XLOCALE #define ISSPACE(C) iswspace_l((C), locale_arg) +libc_hidden_proto(iswspace_l) #else #define ISSPACE(C) iswspace((C)) +libc_hidden_proto(iswspace) #endif #else /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */ @@ -590,8 +635,10 @@ unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * #define Wuchar unsigned char #ifdef __UCLIBC_DO_XLOCALE #define ISSPACE(C) isspace_l((C), locale_arg) +libc_hidden_proto(isspace_l) #else #define ISSPACE(C) isspace((C)) +libc_hidden_proto(isspace) #endif #endif /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */ @@ -608,6 +655,9 @@ unsigned long long attribute_hidden _stdlib_strto_ll(register const Wchar * __re #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ +#ifndef __UCLIBC_HAS_XLOCALE__ +libc_hidden_proto(__ctype_b) +#endif /* This is the main work fuction which handles both strtoll (sflag = 1) and * strtoull (sflag = 0). */ @@ -721,10 +771,10 @@ unsigned long long attribute_hidden __XL_NPP(_stdlib_strto_ll)(register const Wc /**********************************************************************/ /* Made _Exit() an alias for _exit(), as per C99. */ /* #ifdef L__Exit */ - +/* libc_hidden_proto(_exit) */ /* void _Exit(int status) */ /* { */ -/* _exit_internal(status); */ +/* _exit(status); */ /* } */ /* #endif */ @@ -769,7 +819,8 @@ void *bsearch(const void *key, const void *base, size_t /* nmemb */ high, * calculation, as well as to reduce the generated code size with * bcc and gcc. */ -void attribute_hidden __qsort (void *base, +libc_hidden_proto(qsort) +void qsort (void *base, size_t nel, size_t width, int (*comp)(const void *, const void *)) @@ -814,7 +865,7 @@ void attribute_hidden __qsort (void *base, } while (wgap); } } -strong_alias(__qsort,qsort) +libc_hidden_def(qsort) /* ---------- original snippets version below ---------- */ @@ -868,7 +919,8 @@ void ssort (void *base, /**********************************************************************/ #ifdef L__stdlib_mb_cur_max -size_t attribute_hidden _stdlib_mb_cur_max_internal(void) +libc_hidden_proto(_stdlib_mb_cur_max) +size_t _stdlib_mb_cur_max(void) { #ifdef __CTYPE_HAS_UTF_8_LOCALES return __UCLIBC_CURLOCALE_DATA.mb_cur_max; @@ -881,12 +933,14 @@ size_t attribute_hidden _stdlib_mb_cur_max_internal(void) return 1; #endif } -strong_alias(_stdlib_mb_cur_max_internal,_stdlib_mb_cur_max) +libc_hidden_def(_stdlib_mb_cur_max) #endif /**********************************************************************/ #ifdef L_mblen +libc_hidden_proto(mbrlen) + int mblen(register const char *s, size_t n) { static mbstate_t state; @@ -904,7 +958,7 @@ int mblen(register const char *s, size_t n) if ((r = mbrlen(s, n, &state)) == (size_t) -2) { /* TODO: Should we set an error state? */ state.__wc = 0xffffU; /* Make sure we're in an error state. */ - return (size_t) -1; /* TODO: Change error code above? */ + return -1; /* TODO: Change error code above? */ } return r; } @@ -913,6 +967,8 @@ int mblen(register const char *s, size_t n) /**********************************************************************/ #ifdef L_mbtowc +libc_hidden_proto(mbrtowc) + int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n) { static mbstate_t state; @@ -930,7 +986,7 @@ int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n) if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) { /* TODO: Should we set an error state? */ state.__wc = 0xffffU; /* Make sure we're in an error state. */ - return (size_t) -1; /* TODO: Change error code above? */ + return -1; /* TODO: Change error code above? */ } return r; } @@ -941,6 +997,8 @@ int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n) /* Note: We completely ignore state in all currently supported conversions. */ +libc_hidden_proto(wcrtomb) + int wctomb(register char *__restrict s, wchar_t swc) { return (!s) @@ -957,6 +1015,8 @@ int wctomb(register char *__restrict s, wchar_t swc) /**********************************************************************/ #ifdef L_mbstowcs +libc_hidden_proto(mbsrtowcs) + size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) { mbstate_t state; @@ -972,6 +1032,8 @@ size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) /* Note: We completely ignore state in all currently supported conversions. */ +libc_hidden_proto(wcsrtombs) + size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) { const wchar_t *e = pwcs; /* Needed because of restrict. */ @@ -983,20 +1045,28 @@ size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) /**********************************************************************/ #if defined(L_wcstol) || defined(L_wcstol_l) -long __UCXL(wcstol)(const wchar_t * __restrict str, +libc_hidden_proto(__XL_NPP(wcstol)) +long __XL_NPP(wcstol)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) { return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG ); } - -__UCXL_ALIAS(wcstol) +libc_hidden_def(__XL_NPP(wcstol)) #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstol_l) strong_alias(wcstol,wcstoimax) #endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) -strong_alias(__XL(wcstol),__XL(wcstoll)) +#ifdef L_wcstol_l +#undef wcstoll_l +#else +#undef wcstoll +#endif +extern __typeof(wcstol) __XL_NPP(wcstoll); +libc_hidden_proto(__XL_NPP(wcstoll)) +strong_alias(__XL_NPP(wcstol),__XL_NPP(wcstoll)) +libc_hidden_def(__XL_NPP(wcstoll)) #endif #endif @@ -1005,15 +1075,15 @@ strong_alias(__XL(wcstol),__XL(wcstoll)) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -long long attribute_hidden __UCXL(wcstoll)(const wchar_t * __restrict str, +libc_hidden_proto(__XL_NPP(wcstoll)) +long long __XL_NPP(wcstoll)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) { return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1 __LOCALE_ARG ); } - -__UCXL_ALIAS(wcstoll) +libc_hidden_def(__XL_NPP(wcstoll)) #if !defined(L_wcstoll_l) #if (ULLONG_MAX == UINTMAX_MAX) @@ -1028,21 +1098,29 @@ strong_alias(wcstoll,wcstoq) /**********************************************************************/ #if defined(L_wcstoul) || defined(L_wcstoul_l) -unsigned long attribute_hidden __UCXL(wcstoul)(const wchar_t * __restrict str, +libc_hidden_proto(__XL_NPP(wcstoul)) +unsigned long __XL_NPP(wcstoul)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) { return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG ); } - -__UCXL_ALIAS(wcstoul) +libc_hidden_def(__XL_NPP(wcstoul)) #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstoul_l) strong_alias(wcstoul,wcstoumax) #endif #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) -strong_alias(__XL(wcstoul),__XL(wcstoull)) +#ifdef L_wcstoul_l +#undef wcstoull_l +#else +#undef wcstoull +#endif +extern __typeof(wcstoul) __XL_NPP(wcstoull); +libc_hidden_proto(__XL_NPP(wcstoull)) +strong_alias(__XL_NPP(wcstoul),__XL_NPP(wcstoull)) +libc_hidden_def(__XL_NPP(wcstoull)) #endif #endif @@ -1051,14 +1129,14 @@ strong_alias(__XL(wcstoul),__XL(wcstoull)) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -unsigned long long attribute_hidden __UCXL(wcstoull)(const wchar_t * __restrict str, +libc_hidden_proto(__XL_NPP(wcstoull)) +unsigned long long __XL_NPP(wcstoull)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) { return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0 __LOCALE_ARG ); } - -__UCXL_ALIAS(wcstoull) +libc_hidden_def(__XL_NPP(wcstoull)) #if !defined(L_wcstoull_l) #if (ULLONG_MAX == UINTMAX_MAX) diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c index 3a5adcd4e..7f59aef49 100644 --- a/libc/stdlib/strtod.c +++ b/libc/stdlib/strtod.c @@ -1,622 +1,8 @@ /* - * Copyright (C) 2000-2005 Manuel Novoa III + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -/* Notes: - * - * The primary objective of this implementation was minimal size and - * portablility, while providing robustness and resonable accuracy. - * - * This implementation depends on IEEE floating point behavior and expects - * to be able to generate +/- infinity as a result. - * - * There are a number of compile-time options below. - */ - -/* July 27, 2003 - * - * General cleanup and some minor size optimizations. - * Change implementation to support __strtofpmax() rather than strtod(). - * Now all the strto{floating pt}() funcs are implemented in terms of - * of the internal __strtofpmax() function. - * Support "nan", "inf", and "infinity" strings (case-insensitive). - * Support hexadecimal floating point notation. - * Support wchar variants. - * Support xlocale variants. - * - * TODO: - * - * Consider accumulating blocks of digits in longs to save floating pt mults. - * This would likely be much better on anything that only supported floats - * where DECIMAL_DIG == 9. Actually, if floats have FLT_MAX_10_EXP == 38, - * we could calculate almost all the exponent multipliers (p_base) in - * long arithmetic as well. - */ - -/**********************************************************************/ -/* OPTIONS */ -/**********************************************************************/ - -/* Defined if we want to recognize "nan", "inf", and "infinity". (C99) */ -#define _STRTOD_NAN_INF_STRINGS 1 - -/* Defined if we want support hexadecimal floating point notation. (C99) */ -/* Note! Now controlled by uClibc configuration. See below. */ -#define _STRTOD_HEXADECIMAL_FLOATS 1 - -/* Defined if we want to scale with a O(log2(exp)) multiplications. - * This is generally a good thing to do unless you are really tight - * on space and do not expect to convert values of large magnitude. */ - -#define _STRTOD_LOG_SCALING 1 - -/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! - * - * Clearing any of the options below this point is not advised (or tested). - * - * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! */ - -/* Defined if we want strtod to set errno appropriately. */ -/* NOTE: Implies all options below. */ -#define _STRTOD_ERRNO 1 - -/* Defined if we want support for the endptr arg. */ -/* Implied by _STRTOD_ERRNO. */ -#define _STRTOD_ENDPTR 1 - -/* Defined if we want to prevent overflow in accumulating the exponent. */ -/* Implied by _STRTOD_ERRNO. */ -#define _STRTOD_RESTRICT_EXP 1 - -/* Defined if we want to process mantissa digits more intelligently. */ -/* Implied by _STRTOD_ERRNO. */ -#define _STRTOD_RESTRICT_DIGITS 1 - -/* Defined if we want to skip scaling 0 for the exponent. */ -/* Implied by _STRTOD_ERRNO. */ -#define _STRTOD_ZERO_CHECK 1 - -/**********************************************************************/ -/* Don't change anything that follows. */ -/**********************************************************************/ - -#ifdef _STRTOD_ERRNO -#undef _STRTOD_ENDPTR -#undef _STRTOD_RESTRICT_EXP -#undef _STRTOD_RESTRICT_DIGITS -#undef _STRTOD_ZERO_CHECK -#define _STRTOD_ENDPTR 1 -#define _STRTOD_RESTRICT_EXP 1 -#define _STRTOD_RESTRICT_DIGITS 1 -#define _STRTOD_ZERO_CHECK 1 -#endif - -/**********************************************************************/ - -#define iswspace __iswspace -#define iswspace_l __iswspace_l - -#define _ISOC99_SOURCE 1 -#define _GNU_SOURCE -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <float.h> -#include <bits/uClibc_fpmax.h> - -#include <locale.h> - -#ifdef __UCLIBC_HAS_WCHAR__ - -#include <wchar.h> -#include <wctype.h> -#include <bits/uClibc_uwchar.h> - -#endif - -#ifdef __UCLIBC_HAS_XLOCALE__ -#include <xlocale.h> -#endif /* __UCLIBC_HAS_XLOCALE__ */ - - - -/* Handle _STRTOD_HEXADECIMAL_FLOATS via uClibc config now. */ -#undef _STRTOD_HEXADECIMAL_FLOATS -#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__ -#define _STRTOD_HEXADECIMAL_FLOATS 1 -#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ - -/**********************************************************************/ - -#undef _STRTOD_FPMAX - -#if FPMAX_TYPE == 3 - -#define NEED_STRTOLD_WRAPPER -#define NEED_STRTOD_WRAPPER -#define NEED_STRTOF_WRAPPER - -#elif FPMAX_TYPE == 2 - -#define NEED_STRTOD_WRAPPER -#define NEED_STRTOF_WRAPPER - -#elif FPMAX_TYPE == 1 - -#define NEED_STRTOF_WRAPPER - -#else - -#error unknown FPMAX_TYPE! - -#endif - -extern void __fp_range_check(__fpmax_t y, __fpmax_t x) attribute_hidden; - -/**********************************************************************/ - -#ifdef _STRTOD_RESTRICT_DIGITS -#define EXP_DENORM_ADJUST DECIMAL_DIG -#define MAX_ALLOWED_EXP (DECIMAL_DIG + EXP_DENORM_ADJUST - FPMAX_MIN_10_EXP) - -#if MAX_ALLOWED_EXP > INT_MAX -#error size assumption violated for MAX_ALLOWED_EXP -#endif -#else -/* We want some excess if we're not restricting mantissa digits. */ -#define MAX_ALLOWED_EXP ((20 - FPMAX_MIN_10_EXP) * 2) -#endif - - -#if defined(_STRTOD_RESTRICT_DIGITS) || defined(_STRTOD_ENDPTR) || defined(_STRTOD_HEXADECIMAL_FLOATS) -#undef _STRTOD_NEED_NUM_DIGITS -#define _STRTOD_NEED_NUM_DIGITS 1 -#endif - -/**********************************************************************/ -#if defined(L___strtofpmax) || defined(L___strtofpmax_l) || defined(L___wcstofpmax) || defined(L___wcstofpmax_l) - -#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) - -#define __strtofpmax __wcstofpmax -#define __strtofpmax_l __wcstofpmax_l - -#define Wchar wchar_t -#ifdef __UCLIBC_DO_XLOCALE -#define ISSPACE(C) iswspace_l((C), locale_arg) -#else -#define ISSPACE(C) iswspace((C)) -#endif - -#else /* defined(L___wcstofpmax) || defined(L___wcstofpmax_l) */ - -#define Wchar char -#ifdef __UCLIBC_DO_XLOCALE -#define ISSPACE(C) isspace_l((C), locale_arg) -#else -#define ISSPACE(C) isspace((C)) -#endif - -#endif /* defined(L___wcstofpmax) || defined(L___wcstofpmax_l) */ - - -#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) - -__fpmax_t attribute_hidden __strtofpmax(const Wchar *str, Wchar **endptr, int exponent_power) -{ - return __strtofpmax_l(str, endptr, exponent_power, __UCLIBC_CURLOCALE); -} - -#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ - -__fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endptr, int exponent_power - __LOCALE_PARAM ) -{ - __fpmax_t number; - __fpmax_t p_base = 10; /* Adjusted to 16 in the hex case. */ - Wchar *pos0; -#ifdef _STRTOD_ENDPTR - Wchar *pos1; -#endif - Wchar *pos = (Wchar *) str; - int exponent_temp; - int negative; /* A flag for the number, a multiplier for the exponent. */ -#ifdef _STRTOD_NEED_NUM_DIGITS - int num_digits; -#endif -#ifdef __UCLIBC_HAS_LOCALE__ -#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) - wchar_t decpt_wc = __LOCALE_PTR->decimal_point; -#else - const char *decpt = __LOCALE_PTR->decimal_point; - int decpt_len = __LOCALE_PTR->decimal_point_len; -#endif -#endif - -#ifdef _STRTOD_HEXADECIMAL_FLOATS - Wchar expchar = 'e'; - Wchar *poshex = NULL; - __uint16_t is_mask = _ISdigit; -#define EXPCHAR expchar -#define IS_X_DIGIT(C) __isctype((C), is_mask) -#else /* _STRTOD_HEXADECIMAL_FLOATS */ -#define EXPCHAR 'e' -#define IS_X_DIGIT(C) isdigit((C)) -#endif /* _STRTOD_HEXADECIMAL_FLOATS */ - - while (ISSPACE(*pos)) { /* Skip leading whitespace. */ - ++pos; - } - - negative = 0; - switch(*pos) { /* Handle optional sign. */ - case '-': negative = 1; /* Fall through to increment position. */ - case '+': ++pos; - } - -#ifdef _STRTOD_HEXADECIMAL_FLOATS - if ((*pos == '0') && (((pos[1])|0x20) == 'x')) { - poshex = ++pos; /* Save position of 'x' in case no digits */ - ++pos; /* and advance past it. */ - is_mask = _ISxdigit; /* Used by IS_X_DIGIT. */ - expchar = 'p'; /* Adjust exponent char. */ - p_base = 16; /* Adjust base multiplier. */ - } -#endif - - number = 0.; -#ifdef _STRTOD_NEED_NUM_DIGITS - num_digits = -1; -#endif -/* exponent_power = 0; */ - pos0 = NULL; - - LOOP: - while (IS_X_DIGIT(*pos)) { /* Process string of (hex) digits. */ -#ifdef _STRTOD_RESTRICT_DIGITS - if (num_digits < 0) { /* First time through? */ - ++num_digits; /* We've now seen a digit. */ - } - if (num_digits || (*pos != '0')) { /* Had/have nonzero. */ - ++num_digits; - if (num_digits <= DECIMAL_DIG) { /* Is digit significant? */ -#ifdef _STRTOD_HEXADECIMAL_FLOATS - number = number * p_base - + (isdigit(*pos) - ? (*pos - '0') - : (((*pos)|0x20) - ('a' - 10))); -#else /* _STRTOD_HEXADECIMAL_FLOATS */ - number = number * p_base + (*pos - '0'); -#endif /* _STRTOD_HEXADECIMAL_FLOATS */ - } - } -#else /* _STRTOD_RESTRICT_DIGITS */ -#ifdef _STRTOD_NEED_NUM_DIGITS - ++num_digits; -#endif -#ifdef _STRTOD_HEXADECIMAL_FLOATS - number = number * p_base - + (isdigit(*pos) - ? (*pos - '0') - : (((*pos)|0x20) - ('a' - 10))); -#else /* _STRTOD_HEXADECIMAL_FLOATS */ - number = number * p_base + (*pos - '0'); -#endif /* _STRTOD_HEXADECIMAL_FLOATS */ -#endif /* _STRTOD_RESTRICT_DIGITS */ - ++pos; - } - -#ifdef __UCLIBC_HAS_LOCALE__ -#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) - if (!pos0 && (*pos == decpt_wc)) { /* First decimal point? */ - pos0 = ++pos; - goto LOOP; - } -#else - if (!pos0 && !__memcmp(pos, decpt, decpt_len)) { /* First decimal point? */ - pos0 = (pos += decpt_len); - goto LOOP; - } -#endif -#else /* __UCLIBC_HAS_LOCALE__ */ - if ((*pos == '.') && !pos0) { /* First decimal point? */ - pos0 = ++pos; /* Save position of decimal point */ - goto LOOP; /* and process rest of digits. */ - } -#endif /* __UCLIBC_HAS_LOCALE__ */ - -#ifdef _STRTOD_NEED_NUM_DIGITS - if (num_digits<0) { /* Must have at least one digit. */ -#ifdef _STRTOD_HEXADECIMAL_FLOATS - if (poshex) { /* Back up to '0' in '0x' prefix. */ - pos = poshex; - goto DONE; - } -#endif /* _STRTOD_HEXADECIMAL_FLOATS */ - -#ifdef _STRTOD_NAN_INF_STRINGS - if (!pos0) { /* No decimal point, so check for inf/nan. */ - /* Note: nan is the first string so 'number = i/0.;' works. */ - static const char nan_inf_str[] = "\05nan\0\012infinity\0\05inf\0"; - int i = 0; - -#ifdef __UCLIBC_HAS_LOCALE__ - /* Avoid tolower problems for INFINITY in the tr_TR locale. (yuk)*/ -#undef _tolower -#define _tolower(C) ((C)|0x20) -#endif /* __UCLIBC_HAS_LOCALE__ */ - - do { - /* Unfortunately, we have no memcasecmp(). */ - int j = 0; - while (_tolower(pos[j]) == nan_inf_str[i+1+j]) { - ++j; - if (!nan_inf_str[i+1+j]) { - number = i / 0.; - if (negative) { /* Correct for sign. */ - number = -number; - } - pos += nan_inf_str[i] - 2; - goto DONE; - } - } - i += nan_inf_str[i]; - } while (nan_inf_str[i]); - } - -#endif /* STRTOD_NAN_INF_STRINGS */ -#ifdef _STRTOD_ENDPTR - pos = (Wchar *) str; -#endif - goto DONE; - } -#endif /* _STRTOD_NEED_NUM_DIGITS */ - -#ifdef _STRTOD_RESTRICT_DIGITS - if (num_digits > DECIMAL_DIG) { /* Adjust exponent for skipped digits. */ - exponent_power += num_digits - DECIMAL_DIG; - } -#endif - - if (pos0) { - exponent_power += pos0 - pos; /* Adjust exponent for decimal point. */ - } - -#ifdef _STRTOD_HEXADECIMAL_FLOATS - if (poshex) { - exponent_power *= 4; /* Above is 2**4, but below is 2. */ - p_base = 2; - } -#endif /* _STRTOD_HEXADECIMAL_FLOATS */ - - if (negative) { /* Correct for sign. */ - number = -number; - } - - /* process an exponent string */ - if (((*pos)|0x20) == EXPCHAR) { -#ifdef _STRTOD_ENDPTR - pos1 = pos; -#endif - negative = 1; - switch(*++pos) { /* Handle optional sign. */ - case '-': negative = -1; /* Fall through to increment pos. */ - case '+': ++pos; - } - - pos0 = pos; - exponent_temp = 0; - while (isdigit(*pos)) { /* Process string of digits. */ -#ifdef _STRTOD_RESTRICT_EXP - if (exponent_temp < MAX_ALLOWED_EXP) { /* Avoid overflow. */ - exponent_temp = exponent_temp * 10 + (*pos - '0'); - } -#else - exponent_temp = exponent_temp * 10 + (*pos - '0'); -#endif - ++pos; - } - -#ifdef _STRTOD_ENDPTR - if (pos == pos0) { /* No digits? */ - pos = pos1; /* Back up to {e|E}/{p|P}. */ - } /* else */ -#endif - - exponent_power += negative * exponent_temp; - } - -#ifdef _STRTOD_ZERO_CHECK - if (number == 0.) { - goto DONE; - } -#endif - - /* scale the result */ -#ifdef _STRTOD_LOG_SCALING - exponent_temp = exponent_power; - - if (exponent_temp < 0) { - exponent_temp = -exponent_temp; - } - - while (exponent_temp) { - if (exponent_temp & 1) { - if (exponent_power < 0) { - /* Warning... caluclating a factor for the exponent and - * then dividing could easily be faster. But doing so - * might cause problems when dealing with denormals. */ - number /= p_base; - } else { - number *= p_base; - } - } - exponent_temp >>= 1; - p_base *= p_base; - } - -#else /* _STRTOD_LOG_SCALING */ - while (exponent_power) { - if (exponent_power < 0) { - number /= p_base; - exponent_power++; - } else { - number *= p_base; - exponent_power--; - } - } -#endif /* _STRTOD_LOG_SCALING */ - -#ifdef _STRTOD_ERRNO - if (__FPMAX_ZERO_OR_INF_CHECK(number)) { - __set_errno(ERANGE); - } -#endif - - DONE: -#ifdef _STRTOD_ENDPTR - if (endptr) { - *endptr = pos; - } -#endif - - return number; -} - -#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ - -#endif -/**********************************************************************/ -#ifdef L___fp_range_check -#if defined(NEED_STRTOF_WRAPPER) || defined(NEED_STRTOD_WRAPPER) - -void attribute_hidden __fp_range_check(__fpmax_t y, __fpmax_t x) -{ - if (__FPMAX_ZERO_OR_INF_CHECK(y) /* y is 0 or +/- infinity */ - && (y != 0) /* y is not 0 (could have x>0, y==0 if underflow) */ - && !__FPMAX_ZERO_OR_INF_CHECK(x) /* x is not 0 or +/- infinity */ - ) { - __set_errno(ERANGE); /* Then x is not in y's range. */ - } -} - -#endif -#endif -/**********************************************************************/ -#if defined(L_strtof) || defined(L_strtof_l) || defined(L_wcstof) || defined(L_wcstof_l) -#if defined(NEED_STRTOF_WRAPPER) - -#if defined(L_wcstof) || defined(L_wcstof_l) -#define strtof wcstof -#define strtof_l wcstof_l -#define __strtof __wcstof -#define __strtof_l __wcstof_l -#define __strtofpmax __wcstofpmax -#define __strtofpmax_l __wcstofpmax_l -#define Wchar wchar_t -#else -#define Wchar char -#endif - - -float attribute_hidden __UCXL(strtof)(const Wchar *str, Wchar **endptr __LOCALE_PARAM ) -{ -#if FPMAX_TYPE == 1 - return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); -#else - __fpmax_t x; - float y; - - x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); - y = (float) x; - - __fp_range_check(y, x); - - return y; -#endif -} - -__UCXL_ALIAS(strtof) - -#endif -#endif -/**********************************************************************/ -#if defined(L_strtod) || defined(L_strtod_l) || defined(L_wcstod) || defined(L_wcstod_l) -#if defined(NEED_STRTOD_WRAPPER) - -#if defined(L_wcstod) || defined(L_wcstod_l) -#define strtod wcstod -#define strtod_l wcstod_l -#define __strtod __wcstod -#define __strtod_l __wcstod_l -#define __strtofpmax __wcstofpmax -#define __strtofpmax_l __wcstofpmax_l -#define Wchar wchar_t -#else -#define Wchar char -#endif - -double attribute_hidden __UCXL(strtod)(const Wchar *__restrict str, - Wchar **__restrict endptr __LOCALE_PARAM ) -{ -#if FPMAX_TYPE == 2 - return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); -#else - __fpmax_t x; - double y; - - x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); - y = (double) x; - - __fp_range_check(y, x); - - return y; -#endif -} - -__UCXL_ALIAS(strtod) - -#endif -#endif -/**********************************************************************/ -#if defined(L_strtold) || defined(L_strtold_l) || defined(L_wcstold) || defined(L_wcstold_l) -#if defined(NEED_STRTOLD_WRAPPER) - -#if defined(L_wcstold) || defined(L_wcstold_l) -#define strtold wcstold -#define strtold_l wcstold_l -#define __strtold __wcstold -#define __strtold_l __wcstold_l -#define __strtofpmax __wcstofpmax -#define __strtofpmax_l __wcstofpmax_l -#define Wchar wchar_t -#else -#define Wchar char -#endif - -long double attribute_hidden __UCXL(strtold)(const Wchar *str, Wchar **endptr __LOCALE_PARAM ) -{ -#if FPMAX_TYPE == 3 - return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); -#else - __fpmax_t x; - long double y; - - x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); - y = (long double) x; - - __fp_range_check(y, x); - - return y; -#endif -} - -__UCXL_ALIAS(strtold) - -#endif -#endif -/**********************************************************************/ +#define L_strtod +#include "_strtod.c" diff --git a/libc/stdlib/strtod_l.c b/libc/stdlib/strtod_l.c new file mode 100644 index 000000000..413124230 --- /dev/null +++ b/libc/stdlib/strtod_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtod_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/strtof.c b/libc/stdlib/strtof.c index d25a67d05..35e89771a 100644 --- a/libc/stdlib/strtof.c +++ b/libc/stdlib/strtof.c @@ -1,34 +1,8 @@ -/* vi: set sw=4 ts=4: */ -/* strtof for uClibc - * - * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License - * for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -/* This implementation is a bit lame, since we are actually making the compiler - * to an internal conversion from a double to a float, thereby wasting a bunch - * of precision. But this is small, and works for now... */ - -#define strtod __strtod - -#include <stdlib.h> - -float strtof (const char *str, char **endptr) -{ - return(strtod(str,endptr)); -} - +#define L_strtof +#include "_strtod.c" diff --git a/libc/stdlib/strtof_l.c b/libc/stdlib/strtof_l.c new file mode 100644 index 000000000..7b44d1b05 --- /dev/null +++ b/libc/stdlib/strtof_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtof_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/strtol.c b/libc/stdlib/strtol.c new file mode 100644 index 000000000..cee4e1347 --- /dev/null +++ b/libc/stdlib/strtol.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtol +#include "stdlib.c" diff --git a/libc/stdlib/strtol_l.c b/libc/stdlib/strtol_l.c new file mode 100644 index 000000000..d59c1e50c --- /dev/null +++ b/libc/stdlib/strtol_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtol_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/strtold.c b/libc/stdlib/strtold.c index 3ef1fc491..91a3ba79d 100644 --- a/libc/stdlib/strtold.c +++ b/libc/stdlib/strtold.c @@ -1,34 +1,8 @@ -/* vi: set sw=4 ts=4: */ -/* strtold for uClibc - * - * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License - * for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -/* This implementation is a bit lame, since we are actually making the compiler - * to an internal conversion from a double to a long double, thereby losing - * tons of precision. But this is small, and works for now... */ - -#define strtod __strtod - -#include <stdlib.h> - -long double strtold (const char *str, char **endptr) -{ - return(strtod(str,endptr)); -} - +#define L_strtold +#include "_strtod.c" diff --git a/libc/stdlib/strtold_l.c b/libc/stdlib/strtold_l.c new file mode 100644 index 000000000..7eccd00bb --- /dev/null +++ b/libc/stdlib/strtold_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtold_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/strtoll.c b/libc/stdlib/strtoll.c new file mode 100644 index 000000000..a9c7c83ee --- /dev/null +++ b/libc/stdlib/strtoll.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtoll +#include "stdlib.c" diff --git a/libc/stdlib/strtoll_l.c b/libc/stdlib/strtoll_l.c new file mode 100644 index 000000000..9fa46bdd4 --- /dev/null +++ b/libc/stdlib/strtoll_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtoll_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/strtoul.c b/libc/stdlib/strtoul.c new file mode 100644 index 000000000..e92d2464b --- /dev/null +++ b/libc/stdlib/strtoul.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtoul +#include "stdlib.c" diff --git a/libc/stdlib/strtoul_l.c b/libc/stdlib/strtoul_l.c new file mode 100644 index 000000000..2aef138a5 --- /dev/null +++ b/libc/stdlib/strtoul_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtoul_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/strtoull.c b/libc/stdlib/strtoull.c new file mode 100644 index 000000000..60b626fe0 --- /dev/null +++ b/libc/stdlib/strtoull.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtoull +#include "stdlib.c" diff --git a/libc/stdlib/strtoull_l.c b/libc/stdlib/strtoull_l.c new file mode 100644 index 000000000..81e045a4d --- /dev/null +++ b/libc/stdlib/strtoull_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_strtoull_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c index a537156fd..5c16dbee2 100644 --- a/libc/stdlib/system.c +++ b/libc/stdlib/system.c @@ -1,22 +1,40 @@ -#define wait4 __wait4 -#define execl __execl -#define signal __signal -#define vfork __vfork -#define fork __fork +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ +#define SHELL_PATH "/bin/sh" /* Path of the shell. */ +#define SHELL_NAME "sh" /* Name to give it. */ #include <stdio.h> #include <stddef.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> +#include <stdlib.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sched.h> +#include <errno.h> +#include <bits/libc-lock.h> +#include <sysdep-cancel.h> +#endif + +libc_hidden_proto(_exit) +libc_hidden_proto(wait4) +libc_hidden_proto(execl) +libc_hidden_proto(signal) +libc_hidden_proto(vfork) +#if !defined __UCLIBC_HAS_THREADS_NATIVE__ /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */ #include <sys/syscall.h> -#if ! defined __NR_vfork -#define vfork fork +#ifndef __NR_vfork +# define vfork fork +libc_hidden_proto(fork) #endif -int __libc_system(char *command) +extern __typeof(system) __libc_system; +int __libc_system(const char *command) { int wait_val, pid; __sighandler_t save_quit, save_int, save_chld; @@ -39,8 +57,8 @@ int __libc_system(char *command) signal(SIGINT, SIG_DFL); signal(SIGCHLD, SIG_DFL); - execl("/bin/sh", "sh", "-c", command, (char *) 0); - _exit_internal(127); + execl(SHELL_PATH, SHELL_NAME, "-c", command, (char *) 0); + _exit(127); } /* Signals are not absolutly guarenteed with vfork */ signal(SIGQUIT, SIG_IGN); @@ -58,4 +76,192 @@ int __libc_system(char *command) signal(SIGCHLD, save_chld); return wait_val; } -weak_alias(__libc_system, system) +#else +/* We have to and actually can handle cancelable system(). The big + problem: we have to kill the child process if necessary. To do + this a cleanup handler has to be registered and is has to be able + to find the PID of the child. The main problem is to reliable have + the PID when needed. It is not necessary for the parent thread to + return. It might still be in the kernel when the cancellation + request comes. Therefore we have to use the clone() calls ability + to have the kernel write the PID into the user-level variable. */ +#if defined __ia64__ +# define FORK() \ + INLINE_SYSCALL (clone2, 6, CLONE_PARENT_SETTID | SIGCHLD, NULL, 0, \ + &pid, NULL, NULL) +#elif defined __sparc__ +# define FORK() \ + INLINE_CLONE_SYSCALL (CLONE_PARENT_SETTID | SIGCHLD, 0, &pid, NULL, NULL) +#elif defined __s390__ +# define FORK() \ + INLINE_SYSCALL (clone, 3, 0, CLONE_PARENT_SETTID | SIGCHLD, &pid) +#else +# define FORK() \ + INLINE_SYSCALL (clone, 3, CLONE_PARENT_SETTID | SIGCHLD, 0, &pid) +#endif + +static void cancel_handler (void *arg); + +# define CLEANUP_HANDLER \ + __libc_cleanup_region_start (1, cancel_handler, &pid) + +# define CLEANUP_RESET \ + __libc_cleanup_region_end (0) + +static struct sigaction intr, quit; +static int sa_refcntr; +__libc_lock_define_initialized (static, lock); + +# define DO_LOCK() __libc_lock_lock (lock) +# define DO_UNLOCK() __libc_lock_unlock (lock) +# define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; }) +# define ADD_REF() sa_refcntr++ +# define SUB_REF() --sa_refcntr + +/* Execute LINE as a shell command, returning its status. */ +static int +do_system (const char *line) +{ + int status, save; + pid_t pid; + struct sigaction sa; + sigset_t omask; + + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + __sigemptyset (&sa.sa_mask); + + DO_LOCK (); + if (ADD_REF () == 0) + { + if (__sigaction (SIGINT, &sa, &intr) < 0) + { + SUB_REF (); + goto out; + } + if (__sigaction (SIGQUIT, &sa, &quit) < 0) + { + save = errno; + SUB_REF (); + goto out_restore_sigint; + } + } + DO_UNLOCK (); + + /* We reuse the bitmap in the 'sa' structure. */ + __sigaddset (&sa.sa_mask, SIGCHLD); + save = errno; + if (sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0) + { + { + DO_LOCK (); + if (SUB_REF () == 0) + { + save = errno; + (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + out_restore_sigint: + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + __set_errno (save); + } + out: + DO_UNLOCK (); + return -1; + } + } + + CLEANUP_HANDLER; + + pid = FORK (); + if (pid == (pid_t) 0) + { + /* Child side. */ + const char *new_argv[4]; + new_argv[0] = SHELL_NAME; + new_argv[1] = "-c"; + new_argv[2] = line; + new_argv[3] = NULL; + + /* Restore the signals. */ + (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); + (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + (void) sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL); + INIT_LOCK (); + + /* Exec the shell. */ + (void) execve (SHELL_PATH, (char *const *) new_argv, __environ); + _exit (127); + } + else if (pid < (pid_t) 0) + /* The fork failed. */ + status = -1; + else + /* Parent side. */ + { + /* Note the system() is a cancellation point. But since we call + waitpid() which itself is a cancellation point we do not + have to do anything here. */ + if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid) + status = -1; + } + + CLEANUP_RESET; + + save = errno; + DO_LOCK (); + if ((SUB_REF () == 0 + && (sigaction (SIGINT, &intr, (struct sigaction *) NULL) + | sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0) + || sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0) + { + status = -1; + } + DO_UNLOCK (); + + return status; +} + + +int +__libc_system (const char *line) +{ + if (line == NULL) + /* Check that we have a command processor available. It might + not be available after a chroot(), for example. */ + return do_system ("exit 0") == 0; + + if (SINGLE_THREAD_P) + return do_system (line); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = do_system (line); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + + +/* The cancellation handler. */ +static void +cancel_handler (void *arg) +{ + pid_t child = *(pid_t *) arg; + + INTERNAL_SYSCALL_DECL (err); + INTERNAL_SYSCALL (kill, err, 2, child, SIGKILL); + + TEMP_FAILURE_RETRY (__waitpid (child, NULL, 0)); + + DO_LOCK (); + + if (SUB_REF () == 0) + { + (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); + } + + DO_UNLOCK (); +} +#endif +weak_alias(__libc_system,system) diff --git a/libc/stdlib/unix_grantpt.c b/libc/stdlib/unix_grantpt.c index 0e7d50a99..f88a54bc0 100644 --- a/libc/stdlib/unix_grantpt.c +++ b/libc/stdlib/unix_grantpt.c @@ -17,16 +17,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define memchr __memchr -#define getgid __getgid -#define getuid __getuid -#define setrlimit __setrlimit -#define waitpid __waitpid -#define dup2 __dup2 -#define chmod __chmod -#define vfork __vfork -#define fork __fork - #include <assert.h> #include <errno.h> #include <grp.h> @@ -40,6 +30,20 @@ #include <unistd.h> #include "pty-private.h" +libc_hidden_proto(memchr) +libc_hidden_proto(getgid) +libc_hidden_proto(getuid) +libc_hidden_proto(setrlimit) +libc_hidden_proto(waitpid) +libc_hidden_proto(dup2) +libc_hidden_proto(chmod) +libc_hidden_proto(chown) +libc_hidden_proto(vfork) +libc_hidden_proto(fork) +libc_hidden_proto(stat) +libc_hidden_proto(ptsname_r) +libc_hidden_proto(execle) +libc_hidden_proto(_exit) /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */ #include <sys/syscall.h> @@ -47,8 +51,6 @@ #define vfork fork #endif -extern int __ptsname_r (int fd, char *buf, size_t buflen) attribute_hidden; - /* Return the result of ptsname_r in the buffer pointed to by PTS, which should be of length BUF_LEN. If it is too long to fit in this buffer, a sufficiently long buffer is allocated using malloc, @@ -65,7 +67,7 @@ pts_name (int fd, char **pts, size_t buf_len) if (buf_len) { - rv = __ptsname_r (fd, buf, buf_len); + rv = ptsname_r (fd, buf, buf_len); if (rv != 0 || memchr (buf, '\0', buf_len)) /* We either got an error, or we succeeded and the @@ -122,7 +124,7 @@ grantpt (int fd) if (pts_name (fd, &buf, sizeof (_buf))) return -1; - if (__stat(buf, &st) < 0) + if (stat(buf, &st) < 0) goto cleanup; /* Make sure that we own the device. */ @@ -168,10 +170,10 @@ grantpt (int fd) /* We pase the master pseudo terminal as file descriptor PTY_FILENO. */ if (fd != PTY_FILENO) if (dup2 (fd, PTY_FILENO) < 0) - _exit_internal (FAIL_EBADF); + _exit (FAIL_EBADF); execle (_PATH_PT_CHOWN, _PATH_PT_CHOWN, NULL, NULL); - _exit_internal (FAIL_EXEC); + _exit (FAIL_EXEC); } else { diff --git a/libc/stdlib/unlockpt.c b/libc/stdlib/unlockpt.c index 3f99c1c0b..8c426553c 100644 --- a/libc/stdlib/unlockpt.c +++ b/libc/stdlib/unlockpt.c @@ -22,6 +22,7 @@ #include <sys/ioctl.h> #include <termios.h> +libc_hidden_proto(ioctl) /* Unlock the slave pseudo terminal associated with the master pseudo terminal specified by FD. */ @@ -32,7 +33,7 @@ unlockpt (int fd) int save_errno = errno; int unlock = 0; - if (__ioctl (fd, TIOCSPTLCK, &unlock)) + if (ioctl (fd, TIOCSPTLCK, &unlock)) { if (errno == EINVAL) { diff --git a/libc/stdlib/valloc.c b/libc/stdlib/valloc.c index d4f21d121..13dbe0f67 100644 --- a/libc/stdlib/valloc.c +++ b/libc/stdlib/valloc.c @@ -20,12 +20,12 @@ Cambridge, MA 02139, USA. The author may be reached (Email) at the address mike@@ai.mit.edu, or (US mail) as Mike Haertel c/o Free Software Foundation. */ -#define getpagesize __getpagesize_internal - #include <stdlib.h> #include <unistd.h> #include <malloc.h> +libc_hidden_proto(getpagesize) + static size_t pagesize; __ptr_t valloc (size_t size) diff --git a/libc/stdlib/wcstod.c b/libc/stdlib/wcstod.c new file mode 100644 index 000000000..08f802112 --- /dev/null +++ b/libc/stdlib/wcstod.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstod +#include "_strtod.c" diff --git a/libc/stdlib/wcstod_l.c b/libc/stdlib/wcstod_l.c new file mode 100644 index 000000000..be0e58e51 --- /dev/null +++ b/libc/stdlib/wcstod_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstod_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/wcstof.c b/libc/stdlib/wcstof.c new file mode 100644 index 000000000..27ad22f61 --- /dev/null +++ b/libc/stdlib/wcstof.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstof +#include "_strtod.c" diff --git a/libc/stdlib/wcstof_l.c b/libc/stdlib/wcstof_l.c new file mode 100644 index 000000000..953ebe040 --- /dev/null +++ b/libc/stdlib/wcstof_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstof_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/wcstol.c b/libc/stdlib/wcstol.c new file mode 100644 index 000000000..74462e1a8 --- /dev/null +++ b/libc/stdlib/wcstol.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstol +#include "stdlib.c" diff --git a/libc/stdlib/wcstol_l.c b/libc/stdlib/wcstol_l.c new file mode 100644 index 000000000..4282987dc --- /dev/null +++ b/libc/stdlib/wcstol_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstol_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/wcstold.c b/libc/stdlib/wcstold.c new file mode 100644 index 000000000..cd879c110 --- /dev/null +++ b/libc/stdlib/wcstold.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstold +#include "_strtod.c" diff --git a/libc/stdlib/wcstold_l.c b/libc/stdlib/wcstold_l.c new file mode 100644 index 000000000..2ea23b0d5 --- /dev/null +++ b/libc/stdlib/wcstold_l.c @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstold_l +#define __UCLIBC_DO_XLOCALE +#include "_strtod.c" diff --git a/libc/stdlib/wcstoll.c b/libc/stdlib/wcstoll.c new file mode 100644 index 000000000..4cc9b05fb --- /dev/null +++ b/libc/stdlib/wcstoll.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstoll +#include "stdlib.c" diff --git a/libc/stdlib/wcstoll_l.c b/libc/stdlib/wcstoll_l.c new file mode 100644 index 000000000..66c23c290 --- /dev/null +++ b/libc/stdlib/wcstoll_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstoll_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/wcstombs.c b/libc/stdlib/wcstombs.c new file mode 100644 index 000000000..c3d08d8d5 --- /dev/null +++ b/libc/stdlib/wcstombs.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstombs +#include "stdlib.c" diff --git a/libc/stdlib/wcstoul.c b/libc/stdlib/wcstoul.c new file mode 100644 index 000000000..55427447c --- /dev/null +++ b/libc/stdlib/wcstoul.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstoul +#include "stdlib.c" diff --git a/libc/stdlib/wcstoul_l.c b/libc/stdlib/wcstoul_l.c new file mode 100644 index 000000000..529e8e40b --- /dev/null +++ b/libc/stdlib/wcstoul_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstoul_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/wcstoull.c b/libc/stdlib/wcstoull.c new file mode 100644 index 000000000..ea884ef08 --- /dev/null +++ b/libc/stdlib/wcstoull.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstoull +#include "stdlib.c" diff --git a/libc/stdlib/wcstoull_l.c b/libc/stdlib/wcstoull_l.c new file mode 100644 index 000000000..976d103ee --- /dev/null +++ b/libc/stdlib/wcstoull_l.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wcstoull_l +#define __UCLIBC_DO_XLOCALE +#include "stdlib.c" diff --git a/libc/stdlib/wctomb.c b/libc/stdlib/wctomb.c new file mode 100644 index 000000000..3f612be27 --- /dev/null +++ b/libc/stdlib/wctomb.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_wctomb +#include "stdlib.c" |