diff --git a/newlib/libc/include/locale.h b/newlib/libc/include/locale.h index 95e27e761..a195c195e 100644 --- a/newlib/libc/include/locale.h +++ b/newlib/libc/include/locale.h @@ -8,6 +8,7 @@ #define _LOCALE_H_ #include "_ansi.h" +#include #define __need_NULL #include diff --git a/newlib/libc/locale/Makefile.am b/newlib/libc/locale/Makefile.am index 86a95cc8c..666ca5f39 100644 --- a/newlib/libc/locale/Makefile.am +++ b/newlib/libc/locale/Makefile.am @@ -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 diff --git a/newlib/libc/locale/Makefile.in b/newlib/libc/locale/Makefile.in index 2897d6b88..43b7f8840 100644 --- a/newlib/libc/locale/Makefile.in +++ b/newlib/libc/locale/Makefile.in @@ -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 \ diff --git a/newlib/libc/locale/duplocale.c b/newlib/libc/locale/duplocale.c new file mode 100644 index 000000000..6c4c79313 --- /dev/null +++ b/newlib/libc/locale/duplocale.c @@ -0,0 +1,61 @@ +#include +#include +#include +#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 diff --git a/newlib/libc/locale/freelocale.c b/newlib/libc/locale/freelocale.c new file mode 100644 index 000000000..d7eb5bf8f --- /dev/null +++ b/newlib/libc/locale/freelocale.c @@ -0,0 +1,27 @@ +#include +#include +#include +#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); +} diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index f6e9a9718..583e3e2cb 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -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 diff --git a/newlib/libc/locale/localeconv.c b/newlib/libc/locale/localeconv.c new file mode 100644 index 000000000..14151733c --- /dev/null +++ b/newlib/libc/locale/localeconv.c @@ -0,0 +1,66 @@ +#include "newlib.h" +#include +#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 diff --git a/newlib/libc/locale/newlocale.c b/newlib/libc/locale/newlocale.c new file mode 100644 index 000000000..91937174b --- /dev/null +++ b/newlib/libc/locale/newlocale.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#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); +} diff --git a/newlib/libc/locale/nl_langinfo.c b/newlib/libc/locale/nl_langinfo.c index 46e8b0e92..c7e27cfb7 100644 --- a/newlib/libc/locale/nl_langinfo.c +++ b/newlib/libc/locale/nl_langinfo.c @@ -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__ diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h index f1b19783c..4f52e7428 100644 --- a/newlib/libc/locale/setlocale.h +++ b/newlib/libc/locale/setlocale.h @@ -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 * diff --git a/newlib/libc/locale/uselocale.c b/newlib/libc/locale/uselocale.c new file mode 100644 index 000000000..dbf0d3393 --- /dev/null +++ b/newlib/libc/locale/uselocale.c @@ -0,0 +1,27 @@ +#include +#include +#include +#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