Move localeconv, duplocale, freelocale, newlocale, uselocale into separate files

Signed-off by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-07-23 21:40:50 +02:00
parent a2ed50381e
commit 956565be70
11 changed files with 425 additions and 334 deletions

View File

@ -8,6 +8,7 @@
#define _LOCALE_H_
#include "_ansi.h"
#include <sys/cdefs.h>
#define __need_NULL
#include <stddef.h>

View File

@ -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

View File

@ -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 \

View 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

View 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);
}

View File

@ -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

View 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

View 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);
}

View File

@ -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__

View File

@ -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 *

View 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