diff options
author | Manuel Novoa III <mjn3@codepoet.org> | 2003-08-01 20:08:59 +0000 |
---|---|---|
committer | Manuel Novoa III <mjn3@codepoet.org> | 2003-08-01 20:08:59 +0000 |
commit | 1217289737588e65b088b3535428b27c7287d699 (patch) | |
tree | 6a292ac767d219702e26a6a2111737f84a96900c /libpthread | |
parent | 32b76c5ec3c257b7287913d0d1a96e0cbb2e9c6a (diff) |
Add a new *scanf implementation, includeing the *wscanf functions.
Should be standards compliant and with several optional features,
including support for hexadecimal float notation, locale awareness,
glibc-like locale-specific digit grouping with the `'' flag, and
positional arg support. I tested it pretty well (finding several
bugs in glibc's scanf in the process), but it is brand new so be
aware.
The *wprintf functions now support floating point output. Also, a
couple of bugs were squashed. Finally, %a/%A conversions are
now implemented.
Implement the glibc xlocale interface for thread-specific locale
support. Also add the various *_l(args, locale_t loc_arg) funcs.
NOTE!!! setlocale() is NOT threadsafe! NOTE!!!
The strto{floating point} conversion functions are now locale aware.
The also now support hexadecimal floating point notation.
Add the wcsto{floating point} conversion functions.
Fix a bug in mktime() related to dst. Note that unlike glibc's mktime,
uClibc's version always normalizes the struct tm before attempting
to determine the correct dst setting if tm_isdst == -1 on entry.
Add a stub version of the libintl functions. (untested)
Fixed a known memory leak in setlocale() related to the collation data.
Add lots of new config options (which Erik agreed to sort out :-),
including finally exposing some of the stripped down stdio configs.
Be careful with those though, as they haven't been tested in a
long time.
(temporary) GOTCHAs...
The ctype functions are currently incorrect for 8-bit locales. They
will be fixed shortly.
The ctype functions are now table-based, resulting in larger staticly
linked binaries. I'll be adding an option to use the old approach
in the stub locale configuration.
Diffstat (limited to 'libpthread')
-rw-r--r-- | libpthread/linuxthreads/Makefile | 5 | ||||
-rw-r--r-- | libpthread/linuxthreads/internals.h | 6 | ||||
-rw-r--r-- | libpthread/linuxthreads/locale.c | 58 | ||||
-rw-r--r-- | libpthread/linuxthreads/manager.c | 9 | ||||
-rw-r--r-- | libpthread/linuxthreads/pthread.c | 14 |
5 files changed, 92 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/Makefile b/libpthread/linuxthreads/Makefile index 748776e71..880fda291 100644 --- a/libpthread/linuxthreads/Makefile +++ b/libpthread/linuxthreads/Makefile @@ -45,6 +45,11 @@ CSRC=attr.c cancel.c condvar.c errno.c events.c join.c lockfile.c manager.c \ mutex.c oldsemaphore.c pt-machine.c ptfork.c pthread.c \ ptlongjmp.c rwlock.c semaphore.c signals.c specific.c spinlock.c \ wrapsyscall.c #weaks.c + +ifeq ($(UCLIBC_HAS_XLOCALE),y) + CSRC += locale.c +endif + COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) diff --git a/libpthread/linuxthreads/internals.h b/libpthread/linuxthreads/internals.h index 528acddc3..bce6b7efe 100644 --- a/libpthread/linuxthreads/internals.h +++ b/libpthread/linuxthreads/internals.h @@ -28,6 +28,9 @@ #include "pt-machine.h" #include "semaphore.h" #include "../linuxthreads_db/thread_dbP.h" +#ifdef __UCLIBC_HAS_XLOCALE__ +#include <bits/uClibc_locale.h> +#endif /* __UCLIBC_HAS_XLOCALE__ */ /* Use a funky version in a probably vein attempt at preventing gdb * from dlopen()'ing glibc's libthread_db library... */ @@ -172,6 +175,9 @@ struct _pthread_descr_struct { pthread_readlock_info *p_readlock_free; /* Free list of structs */ int p_untracked_readlock_count; /* Readlocks not tracked by list */ /* New elements must be added at the end. */ +#ifdef __UCLIBC_HAS_XLOCALE__ + __locale_t locale; /* thread-specific locale from uselocale() only! */ +#endif /* __UCLIBC_HAS_XLOCALE__ */ } __attribute__ ((aligned(32))); /* We need to align the structure so that doubles are aligned properly. This is 8 bytes on MIPS and 16 bytes on MIPS64. diff --git a/libpthread/linuxthreads/locale.c b/libpthread/linuxthreads/locale.c new file mode 100644 index 000000000..c3ebbc285 --- /dev/null +++ b/libpthread/linuxthreads/locale.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2003 Manuel Novoa III + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define _GNU_SOURCE +#include <features.h> +#include "pthread.h" +#include "internals.h" +#include <locale.h> +#include <assert.h> +#include <stdlib.h> + +extern struct _pthread_descr_struct __pthread_initial_thread; + +__locale_t __curlocale(void) +{ + pthread_descr self = thread_self(); + +#ifdef NDEBUG + return THREAD_GETMEM (self, locale); +#else + { + __locale_t r = THREAD_GETMEM (self, locale); + + assert(r); + + return r; + } +#endif +} + +__locale_t __curlocale_set(__locale_t newloc) +{ + __locale_t oldloc; + pthread_descr self = thread_self(); + + oldloc = THREAD_GETMEM (self, locale); + + assert(newloc != LC_GLOBAL_LOCALE); + assert(oldloc); + + THREAD_SETMEM (self, locale, newloc); + + return oldloc; +} diff --git a/libpthread/linuxthreads/manager.c b/libpthread/linuxthreads/manager.c index f1c9b93af..f7301bc52 100644 --- a/libpthread/linuxthreads/manager.c +++ b/libpthread/linuxthreads/manager.c @@ -134,6 +134,11 @@ int __pthread_manager(void *arg) __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno; __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno; +#ifdef __UCLIBC_HAS_XLOCALE__ + /* Initialize thread's locale to the global locale. */ + __pthread_manager_thread.locale = __global_locale; +#endif /* __UCLIBC_HAS_XLOCALE__ */ + /* Block all signals except __pthread_sig_cancel and SIGTRAP */ sigfillset(&manager_mask); sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */ @@ -506,6 +511,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED; new_thread->p_errnop = &new_thread->p_errno; new_thread->p_h_errnop = &new_thread->p_h_errno; +#ifdef __UCLIBC_HAS_XLOCALE__ + /* Initialize thread's locale to the global locale. */ + new_thread->locale = __global_locale; +#endif /* __UCLIBC_HAS_XLOCALE__ */ new_thread->p_guardaddr = guardaddr; new_thread->p_guardsize = guardsize; new_thread->p_self = new_thread; diff --git a/libpthread/linuxthreads/pthread.c b/libpthread/linuxthreads/pthread.c index 22e3f6a9c..1c24cccd8 100644 --- a/libpthread/linuxthreads/pthread.c +++ b/libpthread/linuxthreads/pthread.c @@ -99,6 +99,10 @@ struct _pthread_descr_struct __pthread_initial_thread = { NULL, /* pthread_readlock_info *p_readlock_list; */ NULL, /* pthread_readlock_info *p_readlock_free; */ 0 /* int p_untracked_readlock_count; */ +#ifdef __UCLIBC_HAS_XLOCALE__ + , + NULL, /* __locale_t locale; */ +#endif /* __UCLIBC_HAS_XLOCALE__ */ }; /* Descriptor of the manager thread; none of this is used but the error @@ -151,6 +155,10 @@ struct _pthread_descr_struct __pthread_manager_thread = { NULL, /* pthread_readlock_info *p_readlock_list; */ NULL, /* pthread_readlock_info *p_readlock_free; */ 0 /* int p_untracked_readlock_count; */ +#ifdef __UCLIBC_HAS_XLOCALE__ + , + NULL, /* __locale_t locale; */ +#endif /* __UCLIBC_HAS_XLOCALE__ */ }; /* Pointer to the main thread (the father of the thread manager thread) */ @@ -318,6 +326,12 @@ static void pthread_initialize(void) /* The errno/h_errno variable of the main thread are the global ones. */ __pthread_initial_thread.p_errnop = &_errno; __pthread_initial_thread.p_h_errnop = &_h_errno; + +#ifdef __UCLIBC_HAS_XLOCALE__ + /* The locale of the main thread is the current locale in use. */ + __pthread_initial_thread.locale = __curlocale_var; +#endif /* __UCLIBC_HAS_XLOCALE__ */ + /* Play with the stack size limit to make sure that no stack ever grows beyond STACK_SIZE minus two pages (one page for the thread descriptor immediately beyond, and one page to act as a guard page). */ |