mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-18 12:29:32 +08:00
Move localeconv, duplocale, freelocale, newlocale, uselocale into separate files
Signed-off by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
a2ed50381e
commit
956565be70
@ -8,6 +8,7 @@
|
||||
#define _LOCALE_H_
|
||||
|
||||
#include "_ansi.h"
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
|
@ -4,19 +4,23 @@ AUTOMAKE_OPTIONS = cygnus
|
||||
|
||||
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
||||
|
||||
GENERAL_SOURCES = setlocale.h
|
||||
GENERAL_SOURCES = setlocale.h locale.c localeconv.c
|
||||
|
||||
## The following interfaces are EL/IX level 2
|
||||
if ELIX_LEVEL_1
|
||||
ELIX_SOURCES =
|
||||
else
|
||||
ELIX_SOURCES = \
|
||||
duplocale.c \
|
||||
freelocale.c \
|
||||
lctype.c \
|
||||
lmessages.c \
|
||||
lnumeric.c \
|
||||
lmonetary.c \
|
||||
newlocale.c \
|
||||
nl_langinfo.c \
|
||||
timelocal.c \
|
||||
lctype.c
|
||||
uselocale.c
|
||||
endif
|
||||
|
||||
liblocale_la_LDFLAGS = -Xcompiler -nostdlib
|
||||
|
@ -1,9 +1,8 @@
|
||||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.12.2 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright (C) 1994-2012 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
@ -54,15 +53,11 @@ POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
|
||||
$(srcdir)/Makefile.am
|
||||
$(srcdir)/Makefile.am $(top_srcdir)/../../mkinstalldirs
|
||||
subdir = locale
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/../../libtool.m4 \
|
||||
$(top_srcdir)/../../ltoptions.m4 \
|
||||
$(top_srcdir)/../../ltsugar.m4 \
|
||||
$(top_srcdir)/../../ltversion.m4 \
|
||||
$(top_srcdir)/../../lt~obsolete.m4 \
|
||||
$(top_srcdir)/../acinclude.m4 $(top_srcdir)/configure.in
|
||||
am__aclocal_m4_deps = $(top_srcdir)/../acinclude.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
|
||||
@ -72,21 +67,27 @@ LIBRARIES = $(noinst_LIBRARIES)
|
||||
ARFLAGS = cru
|
||||
lib_a_AR = $(AR) $(ARFLAGS)
|
||||
lib_a_LIBADD =
|
||||
am__objects_1 = lib_a-locale.$(OBJEXT)
|
||||
@ELIX_LEVEL_1_FALSE@am__objects_2 = lib_a-lmessages.$(OBJEXT) \
|
||||
am__objects_1 = lib_a-locale.$(OBJEXT) lib_a-localeconv.$(OBJEXT)
|
||||
@ELIX_LEVEL_1_FALSE@am__objects_2 = lib_a-duplocale.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-freelocale.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-lctype.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-lmessages.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-lnumeric.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-lmonetary.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-newlocale.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-nl_langinfo.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-timelocal.$(OBJEXT) \
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-lctype.$(OBJEXT)
|
||||
@ELIX_LEVEL_1_FALSE@ lib_a-uselocale.$(OBJEXT)
|
||||
@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) \
|
||||
@USE_LIBTOOL_FALSE@ $(am__objects_2)
|
||||
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
liblocale_la_LIBADD =
|
||||
am__objects_3 = locale.lo
|
||||
@ELIX_LEVEL_1_FALSE@am__objects_4 = lmessages.lo lnumeric.lo lmonetary.lo \
|
||||
@ELIX_LEVEL_1_FALSE@ nl_langinfo.lo timelocal.lo lctype.lo
|
||||
am__objects_3 = locale.lo localeconv.lo
|
||||
@ELIX_LEVEL_1_FALSE@am__objects_4 = duplocale.lo freelocale.lo \
|
||||
@ELIX_LEVEL_1_FALSE@ lctype.lo lmessages.lo lnumeric.lo \
|
||||
@ELIX_LEVEL_1_FALSE@ lmonetary.lo newlocale.lo nl_langinfo.lo \
|
||||
@ELIX_LEVEL_1_FALSE@ timelocal.lo uselocale.lo
|
||||
@USE_LIBTOOL_TRUE@am_liblocale_la_OBJECTS = $(am__objects_3) \
|
||||
@USE_LIBTOOL_TRUE@ $(am__objects_4)
|
||||
liblocale_la_OBJECTS = $(am_liblocale_la_OBJECTS)
|
||||
@ -173,8 +174,10 @@ LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NEWLIB_CFLAGS = @NEWLIB_CFLAGS@
|
||||
NM = @NM@
|
||||
@ -203,6 +206,7 @@ abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
aext = @aext@
|
||||
@ -261,14 +265,18 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = cygnus
|
||||
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
||||
GENERAL_SOURCES = setlocale.h
|
||||
GENERAL_SOURCES = setlocale.h locale.c localeconv.c
|
||||
@ELIX_LEVEL_1_FALSE@ELIX_SOURCES = \
|
||||
@ELIX_LEVEL_1_FALSE@ duplocale.c \
|
||||
@ELIX_LEVEL_1_FALSE@ freelocale.c \
|
||||
@ELIX_LEVEL_1_FALSE@ lctype.c \
|
||||
@ELIX_LEVEL_1_FALSE@ lmessages.c \
|
||||
@ELIX_LEVEL_1_FALSE@ lnumeric.c \
|
||||
@ELIX_LEVEL_1_FALSE@ lmonetary.c \
|
||||
@ELIX_LEVEL_1_FALSE@ newlocale.c \
|
||||
@ELIX_LEVEL_1_FALSE@ nl_langinfo.c \
|
||||
@ELIX_LEVEL_1_FALSE@ timelocal.c \
|
||||
@ELIX_LEVEL_1_FALSE@ lctype.c
|
||||
@ELIX_LEVEL_1_FALSE@ uselocale.c
|
||||
|
||||
@ELIX_LEVEL_1_TRUE@ELIX_SOURCES =
|
||||
liblocale_la_LDFLAGS = -Xcompiler -nostdlib
|
||||
@ -336,12 +344,14 @@ lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) $(EXTRA_lib_a_DEPENDENCIES)
|
||||
|
||||
clean-noinstLTLIBRARIES:
|
||||
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
@list='$(noinst_LTLIBRARIES)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
liblocale.la: $(liblocale_la_OBJECTS) $(liblocale_la_DEPENDENCIES) $(EXTRA_liblocale_la_DEPENDENCIES)
|
||||
$(liblocale_la_LINK) $(am_liblocale_la_rpath) $(liblocale_la_OBJECTS) $(liblocale_la_LIBADD) $(LIBS)
|
||||
|
||||
@ -366,6 +376,30 @@ lib_a-locale.o: locale.c
|
||||
lib_a-locale.obj: locale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-locale.obj `if test -f 'locale.c'; then $(CYGPATH_W) 'locale.c'; else $(CYGPATH_W) '$(srcdir)/locale.c'; fi`
|
||||
|
||||
lib_a-localeconv.o: localeconv.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-localeconv.o `test -f 'localeconv.c' || echo '$(srcdir)/'`localeconv.c
|
||||
|
||||
lib_a-localeconv.obj: localeconv.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-localeconv.obj `if test -f 'localeconv.c'; then $(CYGPATH_W) 'localeconv.c'; else $(CYGPATH_W) '$(srcdir)/localeconv.c'; fi`
|
||||
|
||||
lib_a-duplocale.o: duplocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-duplocale.o `test -f 'duplocale.c' || echo '$(srcdir)/'`duplocale.c
|
||||
|
||||
lib_a-duplocale.obj: duplocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-duplocale.obj `if test -f 'duplocale.c'; then $(CYGPATH_W) 'duplocale.c'; else $(CYGPATH_W) '$(srcdir)/duplocale.c'; fi`
|
||||
|
||||
lib_a-freelocale.o: freelocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-freelocale.o `test -f 'freelocale.c' || echo '$(srcdir)/'`freelocale.c
|
||||
|
||||
lib_a-freelocale.obj: freelocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-freelocale.obj `if test -f 'freelocale.c'; then $(CYGPATH_W) 'freelocale.c'; else $(CYGPATH_W) '$(srcdir)/freelocale.c'; fi`
|
||||
|
||||
lib_a-lctype.o: lctype.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lctype.o `test -f 'lctype.c' || echo '$(srcdir)/'`lctype.c
|
||||
|
||||
lib_a-lctype.obj: lctype.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lctype.obj `if test -f 'lctype.c'; then $(CYGPATH_W) 'lctype.c'; else $(CYGPATH_W) '$(srcdir)/lctype.c'; fi`
|
||||
|
||||
lib_a-lmessages.o: lmessages.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lmessages.o `test -f 'lmessages.c' || echo '$(srcdir)/'`lmessages.c
|
||||
|
||||
@ -384,6 +418,12 @@ lib_a-lmonetary.o: lmonetary.c
|
||||
lib_a-lmonetary.obj: lmonetary.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lmonetary.obj `if test -f 'lmonetary.c'; then $(CYGPATH_W) 'lmonetary.c'; else $(CYGPATH_W) '$(srcdir)/lmonetary.c'; fi`
|
||||
|
||||
lib_a-newlocale.o: newlocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-newlocale.o `test -f 'newlocale.c' || echo '$(srcdir)/'`newlocale.c
|
||||
|
||||
lib_a-newlocale.obj: newlocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-newlocale.obj `if test -f 'newlocale.c'; then $(CYGPATH_W) 'newlocale.c'; else $(CYGPATH_W) '$(srcdir)/newlocale.c'; fi`
|
||||
|
||||
lib_a-nl_langinfo.o: nl_langinfo.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-nl_langinfo.o `test -f 'nl_langinfo.c' || echo '$(srcdir)/'`nl_langinfo.c
|
||||
|
||||
@ -396,11 +436,11 @@ lib_a-timelocal.o: timelocal.c
|
||||
lib_a-timelocal.obj: timelocal.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-timelocal.obj `if test -f 'timelocal.c'; then $(CYGPATH_W) 'timelocal.c'; else $(CYGPATH_W) '$(srcdir)/timelocal.c'; fi`
|
||||
|
||||
lib_a-lctype.o: lctype.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lctype.o `test -f 'lctype.c' || echo '$(srcdir)/'`lctype.c
|
||||
lib_a-uselocale.o: uselocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-uselocale.o `test -f 'uselocale.c' || echo '$(srcdir)/'`uselocale.c
|
||||
|
||||
lib_a-lctype.obj: lctype.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lctype.obj `if test -f 'lctype.c'; then $(CYGPATH_W) 'lctype.c'; else $(CYGPATH_W) '$(srcdir)/lctype.c'; fi`
|
||||
lib_a-uselocale.obj: uselocale.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-uselocale.obj `if test -f 'uselocale.c'; then $(CYGPATH_W) 'uselocale.c'; else $(CYGPATH_W) '$(srcdir)/uselocale.c'; fi`
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
@ -457,6 +497,20 @@ GTAGS:
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
cscopelist: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
check-am:
|
||||
@ -567,7 +621,7 @@ uninstall-am:
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-noinstLIBRARIES clean-noinstLTLIBRARIES \
|
||||
ctags distclean distclean-compile distclean-generic \
|
||||
cscopelist ctags distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags dvi dvi-am html html-am info \
|
||||
info-am install install-am install-data install-data-am \
|
||||
install-dvi install-dvi-am install-exec install-exec-am \
|
||||
|
61
newlib/libc/locale/duplocale.c
Normal file
61
newlib/libc/locale/duplocale.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <newlib.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
#include "setlocale.h"
|
||||
|
||||
struct __locale_t *
|
||||
_duplocale_r (struct _reent *p, struct __locale_t *locobj)
|
||||
{
|
||||
struct __locale_t tmp_locale, *new_locale;
|
||||
int i;
|
||||
|
||||
/* LC_GLOBAL_LOCALE denotes the global locale. */
|
||||
if (locobj == LC_GLOBAL_LOCALE)
|
||||
locobj = __get_global_locale ();
|
||||
/* The "C" locale is used statically, never copied. */
|
||||
else if (locobj == &__C_locale)
|
||||
return (struct __locale_t *) &__C_locale;
|
||||
/* Copy locale content. */
|
||||
tmp_locale = *locobj;
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (locobj->lc_cat[i].buf)
|
||||
{
|
||||
/* If the object is not a "C" locale category, copy it. Just call
|
||||
__loadlocale. It knows what to do to replicate the category. */
|
||||
tmp_locale.lc_cat[i].ptr = NULL;
|
||||
tmp_locale.lc_cat[i].buf = NULL;
|
||||
if (!__loadlocale (&tmp_locale, i, tmp_locale.categories[i]))
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
/* Allocate new locale_t. */
|
||||
new_locale = (struct __locale_t *) _calloc_r (p, 1, sizeof *new_locale);
|
||||
if (!new_locale)
|
||||
goto error;
|
||||
|
||||
*new_locale = tmp_locale;
|
||||
return new_locale;
|
||||
|
||||
error:
|
||||
/* An error occured while we had already (potentially) allocated memory.
|
||||
Free memory and return NULL. errno is supposed to be set already. */
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
while (--i > 0)
|
||||
if (tmp_locale.lc_cat[i].buf)
|
||||
{
|
||||
_free_r (p, (void *) tmp_locale.lc_cat[i].ptr);
|
||||
_free_r (p, tmp_locale.lc_cat[i].buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
struct __locale_t *
|
||||
duplocale (struct __locale_t *locobj)
|
||||
{
|
||||
return _duplocale_r (_REENT, locobj);
|
||||
}
|
||||
#endif
|
27
newlib/libc/locale/freelocale.c
Normal file
27
newlib/libc/locale/freelocale.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <newlib.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
#include "setlocale.h"
|
||||
|
||||
void
|
||||
_freelocale_r (struct _reent *p, struct __locale_t *locobj)
|
||||
{
|
||||
/* Sanity check. The "C" locale is static, don't try to free it. */
|
||||
if (!locobj || locobj == &__C_locale || locobj == LC_GLOBAL_LOCALE)
|
||||
return;
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
for (int i = 1; i < _LC_LAST; ++i)
|
||||
if (locobj->lc_cat[i].buf)
|
||||
{
|
||||
_free_r (p, (void *) locobj->lc_cat[i].ptr);
|
||||
_free_r (p, locobj->lc_cat[i].buf);
|
||||
}
|
||||
#endif
|
||||
_free_r (p, locobj);
|
||||
}
|
||||
|
||||
void
|
||||
freelocale (struct __locale_t *locobj)
|
||||
{
|
||||
_freelocale_r (_REENT, locobj);
|
||||
}
|
@ -190,16 +190,6 @@ int __EXPORT __mb_cur_max = 6;
|
||||
|
||||
char *_PathLocale = NULL;
|
||||
|
||||
static
|
||||
struct lconv lconv =
|
||||
{
|
||||
".", "", "", "", "", "", "", "", "", "",
|
||||
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
||||
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
||||
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
||||
CHAR_MAX, CHAR_MAX
|
||||
};
|
||||
|
||||
#ifdef _MB_CAPABLE
|
||||
/*
|
||||
* Category names for getenv()
|
||||
@ -292,8 +282,6 @@ struct __locale_t __global_locale =
|
||||
functionality for uselocale. */
|
||||
static char global_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)];
|
||||
static char *currentlocale (void);
|
||||
static char *loadlocale (struct __locale_t *, int, const char *);
|
||||
static const char *__get_locale_env(struct _reent *, int);
|
||||
|
||||
#endif /* _MB_CAPABLE */
|
||||
|
||||
@ -419,23 +407,23 @@ _DEFUN(_setlocale_r, (p, category, locale),
|
||||
}
|
||||
|
||||
if (category != LC_ALL)
|
||||
return loadlocale (__get_global_locale (), category,
|
||||
new_categories[category]);
|
||||
return __loadlocale (__get_global_locale (), category,
|
||||
new_categories[category]);
|
||||
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
{
|
||||
strcpy (saved_categories[i], __get_global_locale ()->categories[i]);
|
||||
if (loadlocale (__get_global_locale (), i, new_categories[i]) == NULL)
|
||||
if (__loadlocale (__get_global_locale (), i, new_categories[i]) == NULL)
|
||||
{
|
||||
saverr = p->_errno;
|
||||
for (j = 1; j < i; j++)
|
||||
{
|
||||
strcpy (new_categories[j], saved_categories[j]);
|
||||
if (loadlocale (__get_global_locale (), j, new_categories[j])
|
||||
if (__loadlocale (__get_global_locale (), j, new_categories[j])
|
||||
== NULL)
|
||||
{
|
||||
strcpy (new_categories[j], "C");
|
||||
loadlocale (__get_global_locale (), j, new_categories[j]);
|
||||
__loadlocale (__get_global_locale (), j, new_categories[j]);
|
||||
}
|
||||
}
|
||||
p->_errno = saverr;
|
||||
@ -471,8 +459,8 @@ currentlocale ()
|
||||
|
||||
extern void __set_ctype (struct __locale_t *, const char *charset);
|
||||
|
||||
static char *
|
||||
loadlocale (struct __locale_t *loc, int category, const char *new_locale)
|
||||
char *
|
||||
__loadlocale (struct __locale_t *loc, int category, const char *new_locale)
|
||||
{
|
||||
/* At this point a full-featured system would just load the locale
|
||||
specific data from the locale files.
|
||||
@ -945,7 +933,7 @@ restart:
|
||||
return strcpy(loc->categories[category], new_locale);
|
||||
}
|
||||
|
||||
static const char *
|
||||
const char *
|
||||
__get_locale_env (struct _reent *p, int category)
|
||||
{
|
||||
const char *env;
|
||||
@ -991,257 +979,10 @@ _DEFUN_VOID (__locale_ctype_ptr)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct lconv *
|
||||
_DEFUN (_localeconv_r, (data),
|
||||
struct _reent *data)
|
||||
char *
|
||||
__locale_ctype_ptr_l (struct __locale_t *locale)
|
||||
{
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
const struct lc_numeric_T *n = __get_current_numeric_locale ();
|
||||
const struct lc_monetary_T *m = __get_current_monetary_locale ();
|
||||
|
||||
lconv.decimal_point = (char *) n->decimal_point;
|
||||
lconv.thousands_sep = (char *) n->thousands_sep;
|
||||
lconv.grouping = (char *) n->grouping;
|
||||
lconv.int_curr_symbol = (char *) m->int_curr_symbol;
|
||||
lconv.currency_symbol = (char *) m->currency_symbol;
|
||||
lconv.mon_decimal_point = (char *) m->mon_decimal_point;
|
||||
lconv.mon_thousands_sep = (char *) m->mon_thousands_sep;
|
||||
lconv.mon_grouping = (char *) m->mon_grouping;
|
||||
lconv.positive_sign = (char *) m->positive_sign;
|
||||
lconv.negative_sign = (char *) m->negative_sign;
|
||||
lconv.int_frac_digits = m->int_frac_digits[0];
|
||||
lconv.frac_digits = m->frac_digits[0];
|
||||
lconv.p_cs_precedes = m->p_cs_precedes[0];
|
||||
lconv.p_sep_by_space = m->p_sep_by_space[0];
|
||||
lconv.n_cs_precedes = m->n_cs_precedes[0];
|
||||
lconv.n_sep_by_space = m->n_sep_by_space[0];
|
||||
lconv.p_sign_posn = m->p_sign_posn[0];
|
||||
lconv.n_sign_posn = m->n_sign_posn[0];
|
||||
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
|
||||
lconv.int_p_cs_precedes = m->int_p_cs_precedes[0];
|
||||
lconv.int_p_sep_by_space = m->int_p_sep_by_space[0];
|
||||
lconv.int_n_cs_precedes = m->int_n_cs_precedes[0];
|
||||
lconv.int_n_sep_by_space = m->int_n_sep_by_space[0];
|
||||
lconv.int_n_sign_posn = m->int_n_sign_posn[0];
|
||||
lconv.int_p_sign_posn = m->int_p_sign_posn[0];
|
||||
#else /* !__HAVE_LOCALE_INFO_EXTENDED__ */
|
||||
lconv.int_p_cs_precedes = m->p_cs_precedes[0];
|
||||
lconv.int_p_sep_by_space = m->p_sep_by_space[0];
|
||||
lconv.int_n_cs_precedes = m->n_cs_precedes[0];
|
||||
lconv.int_n_sep_by_space = m->n_sep_by_space[0];
|
||||
lconv.int_n_sign_posn = m->n_sign_posn[0];
|
||||
lconv.int_p_sign_posn = m->p_sign_posn[0];
|
||||
#endif /* !__HAVE_LOCALE_INFO_EXTENDED__ */
|
||||
#endif /* __HAVE_LOCALE_INFO__ */
|
||||
return (struct lconv *) &lconv;
|
||||
}
|
||||
|
||||
#define LC_VALID_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MONETARY_MASK \
|
||||
| LC_NUMERIC_MASK | LC_TIME_MASK | LC_MESSAGES_MASK)
|
||||
|
||||
struct __locale_t *
|
||||
_newlocale_r (struct _reent *p, int category_mask, const char *locale,
|
||||
struct __locale_t *base)
|
||||
{
|
||||
struct __locale_t tmp_locale, *new_locale;
|
||||
int i;
|
||||
|
||||
/* Convert LC_ALL_MASK to a mask containing all valid MASK values.
|
||||
This simplifies the code below. */
|
||||
if (category_mask & LC_ALL_MASK)
|
||||
{
|
||||
category_mask &= ~LC_ALL_MASK;
|
||||
category_mask |= LC_VALID_MASK;
|
||||
}
|
||||
/* Check for invalid mask values and valid locale ptr. */
|
||||
if (category_mask & ~LC_VALID_MASK || !locale)
|
||||
{
|
||||
p->_errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
/* If the new locale is supposed to be all default locale, just return
|
||||
a pointer to the default locale. */
|
||||
if ((!base && category_mask == 0)
|
||||
|| (category_mask == LC_VALID_MASK
|
||||
&& (!strcmp (locale, "C") || !strcmp (locale, "POSIX"))))
|
||||
return (struct __locale_t *) &__C_locale;
|
||||
/* Start with setting all values to the default locale values. */
|
||||
tmp_locale = __C_locale;
|
||||
/* Fill out category strings. */
|
||||
if (!*locale)
|
||||
{
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (((1 << i) & category_mask) != 0)
|
||||
{
|
||||
const char *env = __get_locale_env (p, i);
|
||||
if (strlen (env) > ENCODING_LEN)
|
||||
{
|
||||
p->_errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
strcpy (tmp_locale.categories[i], env);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (((1 << i) & category_mask) != 0)
|
||||
strcpy (tmp_locale.categories[i], locale);
|
||||
}
|
||||
/* Now go over all categories and set them. */
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
{
|
||||
if (((1 << i) & category_mask) != 0)
|
||||
{
|
||||
/* Nothing to do for "C"/"POSIX" locale. */
|
||||
if (!strcmp (tmp_locale.categories[i], "C")
|
||||
|| !strcmp (tmp_locale.categories[i], "POSIX"))
|
||||
continue;
|
||||
/* If the new locale is the old locale, just copy it over. */
|
||||
if (base && !strcmp (base->categories[i], tmp_locale.categories[i]))
|
||||
{
|
||||
if (i == LC_CTYPE)
|
||||
{
|
||||
tmp_locale.wctomb = base->wctomb;
|
||||
tmp_locale.mbtowc = base->mbtowc;
|
||||
tmp_locale.cjk_lang = base->cjk_lang;
|
||||
tmp_locale.ctype_ptr - base->ctype_ptr;
|
||||
}
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
tmp_locale.lc_cat[i].ptr = base->lc_cat[i].ptr;
|
||||
/* Mark the value as "has still to be copied". We do this in
|
||||
two steps to simplify freeing new locale types in case of a
|
||||
subsequent error. */
|
||||
tmp_locale.lc_cat[i].buf = (void *) -1;
|
||||
#else
|
||||
if (i == LC_CTYPE)
|
||||
strcpy (tmp_locale.ctype_codeset, base->ctype_codeset);
|
||||
else if (i == LC_MESSAGES)
|
||||
strcpy (tmp_locale.message_codeset, base->message_codeset);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
/* Otherwise load locale data. */
|
||||
if (!loadlocale (&tmp_locale, i, tmp_locale.categories[i]))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* Allocate new locale_t. */
|
||||
new_locale = (struct __locale_t *) _calloc_r (p, 1, sizeof *new_locale);
|
||||
if (!new_locale)
|
||||
goto error;
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
/* Second step of copying over. At this point we can safely copy. Make
|
||||
sure to invalidate the copied buffer pointers in base, so a subsequent
|
||||
freelocale (base) doesn't free the buffers now used in the new locale. */
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (tmp_locale.lc_cat[i].buf == (const void *) -1)
|
||||
{
|
||||
tmp_locale.lc_cat[i].buf = base->lc_cat[i].buf;
|
||||
base->lc_cat[i].buf = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
*new_locale = tmp_locale;
|
||||
return new_locale;
|
||||
|
||||
error:
|
||||
/* An error occured while we had already (potentially) allocated memory.
|
||||
Free memory and return NULL. errno is supposed to be set already. */
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (tmp_locale.lc_cat[i].buf
|
||||
&& tmp_locale.lc_cat[i].buf != (const void *) -1)
|
||||
{
|
||||
_free_r (p, tmp_locale.lc_cat[i].ptr);
|
||||
_free_r (p, tmp_locale.lc_cat[i].buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_freelocale_r (struct _reent *p, struct __locale_t *locobj)
|
||||
{
|
||||
/* Sanity check. The "C" locale is static, don't try to free it. */
|
||||
if (!locobj || locobj == &__C_locale || locobj == LC_GLOBAL_LOCALE)
|
||||
return;
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
for (int i = 1; i < _LC_LAST; ++i)
|
||||
if (locobj->lc_cat[i].buf)
|
||||
{
|
||||
_free_r (p, locobj->lc_cat[i].ptr);
|
||||
_free_r (p, locobj->lc_cat[i].buf);
|
||||
}
|
||||
#endif
|
||||
_free_r (p, locobj);
|
||||
}
|
||||
|
||||
struct __locale_t *
|
||||
_duplocale_r (struct _reent *p, struct __locale_t *locobj)
|
||||
{
|
||||
struct __locale_t tmp_locale, *new_locale;
|
||||
int i;
|
||||
|
||||
/* LC_GLOBAL_LOCALE denotes the global locale. */
|
||||
if (locobj == LC_GLOBAL_LOCALE)
|
||||
locobj = __get_global_locale ();
|
||||
/* The "C" locale is used statically, never copied. */
|
||||
else if (locobj == &__C_locale)
|
||||
return (struct __locale_t *) &__C_locale;
|
||||
/* Copy locale content. */
|
||||
tmp_locale = *locobj;
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (locobj->lc_cat[i].buf)
|
||||
{
|
||||
/* If the object is not a "C" locale category, copy it. Just call
|
||||
loadlocale. It knows what to do to replicate the category. */
|
||||
tmp_locale.lc_cat[i].ptr = NULL;
|
||||
tmp_locale.lc_cat[i].buf = NULL;
|
||||
if (!loadlocale (&tmp_locale, i, tmp_locale.categories[i]))
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
/* Allocate new locale_t. */
|
||||
new_locale = (struct __locale_t *) _calloc_r (p, 1, sizeof *new_locale);
|
||||
if (!new_locale)
|
||||
goto error;
|
||||
|
||||
*new_locale = tmp_locale;
|
||||
return new_locale;
|
||||
|
||||
error:
|
||||
/* An error occured while we had already (potentially) allocated memory.
|
||||
Free memory and return NULL. errno is supposed to be set already. */
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
while (--i > 0)
|
||||
if (tmp_locale.lc_cat[i].buf)
|
||||
{
|
||||
_free_r (p, tmp_locale.lc_cat[i].ptr);
|
||||
_free_r (p, tmp_locale.lc_cat[i].buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct __locale_t *
|
||||
_uselocale_r (struct _reent *p, struct __locale_t *newloc)
|
||||
{
|
||||
struct __locale_t *current_locale;
|
||||
|
||||
current_locale = __get_locale_r (p);
|
||||
if (!current_locale)
|
||||
current_locale = LC_GLOBAL_LOCALE;
|
||||
|
||||
if (newloc == LC_GLOBAL_LOCALE)
|
||||
p->_locale = NULL;
|
||||
else if (newloc)
|
||||
p->_locale = newloc;
|
||||
|
||||
return current_locale;
|
||||
return locale->ctype_ptr;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
@ -1254,33 +995,4 @@ _DEFUN (setlocale, (category, locale),
|
||||
return _setlocale_r (_REENT, category, locale);
|
||||
}
|
||||
|
||||
struct lconv *
|
||||
_DEFUN_VOID (localeconv)
|
||||
{
|
||||
return _localeconv_r (_REENT);
|
||||
}
|
||||
|
||||
struct __locale_t *
|
||||
newlocale (int category_mask, const char *locale, struct __locale_t *base)
|
||||
{
|
||||
return _newlocale_r (_REENT, category_mask, locale, base);
|
||||
}
|
||||
|
||||
void
|
||||
freelocale (struct __locale_t *locobj)
|
||||
{
|
||||
_freelocale_r (_REENT, locobj);
|
||||
}
|
||||
|
||||
struct __locale_t *
|
||||
duplocale (struct __locale_t *locobj)
|
||||
{
|
||||
return _duplocale_r (_REENT, locobj);
|
||||
}
|
||||
|
||||
struct __locale_t *
|
||||
uselocale (struct __locale_t *newloc)
|
||||
{
|
||||
return _uselocale_r (_REENT, newloc);
|
||||
}
|
||||
#endif
|
||||
|
66
newlib/libc/locale/localeconv.c
Normal file
66
newlib/libc/locale/localeconv.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include "newlib.h"
|
||||
#include <reent.h>
|
||||
#include "setlocale.h"
|
||||
|
||||
static
|
||||
struct lconv lconv =
|
||||
{
|
||||
".", "", "", "", "", "", "", "", "", "",
|
||||
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
||||
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
||||
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
||||
CHAR_MAX, CHAR_MAX
|
||||
};
|
||||
|
||||
struct lconv *
|
||||
_DEFUN (_localeconv_r, (data),
|
||||
struct _reent *data)
|
||||
{
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
const struct lc_numeric_T *n = __get_current_numeric_locale ();
|
||||
const struct lc_monetary_T *m = __get_current_monetary_locale ();
|
||||
|
||||
lconv.decimal_point = (char *) n->decimal_point;
|
||||
lconv.thousands_sep = (char *) n->thousands_sep;
|
||||
lconv.grouping = (char *) n->grouping;
|
||||
lconv.int_curr_symbol = (char *) m->int_curr_symbol;
|
||||
lconv.currency_symbol = (char *) m->currency_symbol;
|
||||
lconv.mon_decimal_point = (char *) m->mon_decimal_point;
|
||||
lconv.mon_thousands_sep = (char *) m->mon_thousands_sep;
|
||||
lconv.mon_grouping = (char *) m->mon_grouping;
|
||||
lconv.positive_sign = (char *) m->positive_sign;
|
||||
lconv.negative_sign = (char *) m->negative_sign;
|
||||
lconv.int_frac_digits = m->int_frac_digits[0];
|
||||
lconv.frac_digits = m->frac_digits[0];
|
||||
lconv.p_cs_precedes = m->p_cs_precedes[0];
|
||||
lconv.p_sep_by_space = m->p_sep_by_space[0];
|
||||
lconv.n_cs_precedes = m->n_cs_precedes[0];
|
||||
lconv.n_sep_by_space = m->n_sep_by_space[0];
|
||||
lconv.p_sign_posn = m->p_sign_posn[0];
|
||||
lconv.n_sign_posn = m->n_sign_posn[0];
|
||||
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
|
||||
lconv.int_p_cs_precedes = m->int_p_cs_precedes[0];
|
||||
lconv.int_p_sep_by_space = m->int_p_sep_by_space[0];
|
||||
lconv.int_n_cs_precedes = m->int_n_cs_precedes[0];
|
||||
lconv.int_n_sep_by_space = m->int_n_sep_by_space[0];
|
||||
lconv.int_n_sign_posn = m->int_n_sign_posn[0];
|
||||
lconv.int_p_sign_posn = m->int_p_sign_posn[0];
|
||||
#else /* !__HAVE_LOCALE_INFO_EXTENDED__ */
|
||||
lconv.int_p_cs_precedes = m->p_cs_precedes[0];
|
||||
lconv.int_p_sep_by_space = m->p_sep_by_space[0];
|
||||
lconv.int_n_cs_precedes = m->n_cs_precedes[0];
|
||||
lconv.int_n_sep_by_space = m->n_sep_by_space[0];
|
||||
lconv.int_n_sign_posn = m->n_sign_posn[0];
|
||||
lconv.int_p_sign_posn = m->p_sign_posn[0];
|
||||
#endif /* !__HAVE_LOCALE_INFO_EXTENDED__ */
|
||||
#endif /* __HAVE_LOCALE_INFO__ */
|
||||
return (struct lconv *) &lconv;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
struct lconv *
|
||||
_DEFUN_VOID (localeconv)
|
||||
{
|
||||
return _localeconv_r (_REENT);
|
||||
}
|
||||
#endif
|
135
newlib/libc/locale/newlocale.c
Normal file
135
newlib/libc/locale/newlocale.c
Normal file
@ -0,0 +1,135 @@
|
||||
#include <newlib.h>
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
#include "setlocale.h"
|
||||
|
||||
#define LC_VALID_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MONETARY_MASK \
|
||||
| LC_NUMERIC_MASK | LC_TIME_MASK | LC_MESSAGES_MASK)
|
||||
|
||||
struct __locale_t *
|
||||
_newlocale_r (struct _reent *p, int category_mask, const char *locale,
|
||||
struct __locale_t *base)
|
||||
{
|
||||
struct __locale_t tmp_locale, *new_locale;
|
||||
int i;
|
||||
|
||||
/* Convert LC_ALL_MASK to a mask containing all valid MASK values.
|
||||
This simplifies the code below. */
|
||||
if (category_mask & LC_ALL_MASK)
|
||||
{
|
||||
category_mask &= ~LC_ALL_MASK;
|
||||
category_mask |= LC_VALID_MASK;
|
||||
}
|
||||
/* Check for invalid mask values and valid locale ptr. */
|
||||
if (category_mask & ~LC_VALID_MASK || !locale)
|
||||
{
|
||||
p->_errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
/* If the new locale is supposed to be all default locale, just return
|
||||
a pointer to the default locale. */
|
||||
if ((!base && category_mask == 0)
|
||||
|| (category_mask == LC_VALID_MASK
|
||||
&& (!strcmp (locale, "C") || !strcmp (locale, "POSIX"))))
|
||||
return (struct __locale_t *) &__C_locale;
|
||||
/* Start with setting all values to the default locale values. */
|
||||
tmp_locale = __C_locale;
|
||||
/* Fill out category strings. */
|
||||
if (!*locale)
|
||||
{
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (((1 << i) & category_mask) != 0)
|
||||
{
|
||||
const char *env = __get_locale_env (p, i);
|
||||
if (strlen (env) > ENCODING_LEN)
|
||||
{
|
||||
p->_errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
strcpy (tmp_locale.categories[i], env);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (((1 << i) & category_mask) != 0)
|
||||
strcpy (tmp_locale.categories[i], locale);
|
||||
}
|
||||
/* Now go over all categories and set them. */
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
{
|
||||
if (((1 << i) & category_mask) != 0)
|
||||
{
|
||||
/* Nothing to do for "C"/"POSIX" locale. */
|
||||
if (!strcmp (tmp_locale.categories[i], "C")
|
||||
|| !strcmp (tmp_locale.categories[i], "POSIX"))
|
||||
continue;
|
||||
/* If the new locale is the old locale, just copy it over. */
|
||||
if (base && !strcmp (base->categories[i], tmp_locale.categories[i]))
|
||||
{
|
||||
if (i == LC_CTYPE)
|
||||
{
|
||||
tmp_locale.wctomb = base->wctomb;
|
||||
tmp_locale.mbtowc = base->mbtowc;
|
||||
tmp_locale.cjk_lang = base->cjk_lang;
|
||||
tmp_locale.ctype_ptr - base->ctype_ptr;
|
||||
}
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
tmp_locale.lc_cat[i].ptr = base->lc_cat[i].ptr;
|
||||
/* Mark the value as "has still to be copied". We do this in
|
||||
two steps to simplify freeing new locale types in case of a
|
||||
subsequent error. */
|
||||
tmp_locale.lc_cat[i].buf = (void *) -1;
|
||||
#else
|
||||
if (i == LC_CTYPE)
|
||||
strcpy (tmp_locale.ctype_codeset, base->ctype_codeset);
|
||||
else if (i == LC_MESSAGES)
|
||||
strcpy (tmp_locale.message_codeset, base->message_codeset);
|
||||
#endif
|
||||
}
|
||||
/* Otherwise load locale data. */
|
||||
else if (!__loadlocale (&tmp_locale, i, tmp_locale.categories[i]))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* Allocate new locale_t. */
|
||||
new_locale = (struct __locale_t *) _calloc_r (p, 1, sizeof *new_locale);
|
||||
if (!new_locale)
|
||||
goto error;
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
/* Second step of copying over. At this point we can safely copy. Make
|
||||
sure to invalidate the copied buffer pointers in base, so a subsequent
|
||||
freelocale (base) doesn't free the buffers now used in the new locale. */
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (tmp_locale.lc_cat[i].buf == (const void *) -1)
|
||||
{
|
||||
tmp_locale.lc_cat[i].buf = base->lc_cat[i].buf;
|
||||
base->lc_cat[i].buf = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
*new_locale = tmp_locale;
|
||||
return new_locale;
|
||||
|
||||
error:
|
||||
/* An error occured while we had already (potentially) allocated memory.
|
||||
Free memory and return NULL. errno is supposed to be set already. */
|
||||
#ifdef __HAVE_LOCALE_INFO__
|
||||
for (i = 1; i < _LC_LAST; ++i)
|
||||
if (tmp_locale.lc_cat[i].buf
|
||||
&& tmp_locale.lc_cat[i].buf != (const void *) -1)
|
||||
{
|
||||
_free_r (p, (void *) tmp_locale.lc_cat[i].ptr);
|
||||
_free_r (p, tmp_locale.lc_cat[i].buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct __locale_t *
|
||||
newlocale (int category_mask, const char *locale, struct __locale_t *base)
|
||||
{
|
||||
return _newlocale_r (_REENT, category_mask, locale, base);
|
||||
}
|
@ -174,8 +174,8 @@ static struct _nl_item_t
|
||||
|
||||
char *
|
||||
_DEFUN(nl_langinfo, (item),
|
||||
nl_item item) {
|
||||
|
||||
nl_item item)
|
||||
{
|
||||
char *ret, *cs;
|
||||
#ifndef __CYGWIN__
|
||||
char *s;
|
||||
@ -212,7 +212,7 @@ _DEFUN(nl_langinfo, (item),
|
||||
#endif /* __HAVE_LOCALE_INFO__ */
|
||||
case CODESET:
|
||||
#ifdef __CYGWIN__
|
||||
ret = __locale_charset ();
|
||||
ret = (char *) __locale_charset ();
|
||||
#endif
|
||||
do_codeset:
|
||||
#ifdef __CYGWIN__
|
||||
|
@ -189,8 +189,12 @@ struct __locale_t
|
||||
#endif
|
||||
};
|
||||
|
||||
extern const struct __locale_t __C_locale;
|
||||
extern struct __locale_t __global_locale;
|
||||
|
||||
extern char *__loadlocale (struct __locale_t *, int, const char *);
|
||||
extern const char *__get_locale_env(struct _reent *, int);
|
||||
|
||||
/* In POSIX terms the global locale is the process-wide locale. Use this
|
||||
function to always refer to the global locale. */
|
||||
_ELIDABLE_INLINE struct __locale_t *
|
||||
|
27
newlib/libc/locale/uselocale.c
Normal file
27
newlib/libc/locale/uselocale.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <newlib.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
#include "setlocale.h"
|
||||
|
||||
struct __locale_t *
|
||||
_uselocale_r (struct _reent *p, struct __locale_t *newloc)
|
||||
{
|
||||
struct __locale_t *current_locale;
|
||||
|
||||
current_locale = __get_locale_r (p);
|
||||
if (!current_locale)
|
||||
current_locale = LC_GLOBAL_LOCALE;
|
||||
if (newloc == LC_GLOBAL_LOCALE)
|
||||
p->_locale = NULL;
|
||||
else if (newloc)
|
||||
p->_locale = newloc;
|
||||
return current_locale;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
struct __locale_t *
|
||||
uselocale (struct __locale_t *newloc)
|
||||
{
|
||||
return _uselocale_r (_REENT, newloc);
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user