From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 786713858009; Thu, 1 Feb 2024 11:38:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 786713858009 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1706787536; bh=khSsgPOHEMcR3ZbkyPXvOZWYS52scguGqdovbQcyl/U=; h=From:To:Subject:Date:From; b=PySWU/QPQ/w8WVfFdL4JTzwp8H9oCuzOLyj651OAC2cyms5cZuGXz5wvbMNxgQStN Wo6EB2WQimMR2BaYL+H3pEeHAtlthB1ngxsaCcyd+FNg4Vep7S8rq8p4B83r/uvu9H l7BkI/v/goghTqH9Cvc/oNH7Lt5XJ3e08+Lak2zk= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: newlib-cvs@sourceware.org Subject: [newlib-cygwin/main] getlocalename_l: implement per SUS Base Specifications Issue 8 draft X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/main X-Git-Oldrev: cb54031e01a8485743cb6eb68e59f7e19548ae1a X-Git-Newrev: 71511d4ac8686c2220093cc01525311d9c88bc4e Message-Id: <20240201113856.786713858009@sourceware.org> Date: Thu, 1 Feb 2024 11:38:56 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D71511d4ac86= 86c2220093cc01525311d9c88bc4e commit 71511d4ac8686c2220093cc01525311d9c88bc4e Author: Corinna Vinschen AuthorDate: Sun Jan 21 13:23:09 2024 +0100 Commit: Corinna Vinschen CommitDate: Wed Jan 31 20:11:57 2024 +0100 getlocalename_l: implement per SUS Base Specifications Issue 8 draft =20 #include const char *getlocalename_l(int category, locale_t locobj); =20 Most notably, we need a per-thread space to store the string returned if locobj is LC_GLOBAL_LOCALE. No errors are defined for getlocalename_l. So we can't use buffer allocation which might lead to an ENOMEM error. We have to use a "static" buffer in the per-thread state. =20 Note that the feature test macro in locale.h is not quite correct. This needs to be fixed as soon as the =20 Signed-off-by: Corinna Vinschen Diff: --- newlib/Makefile.in | 21 ++++++++++ newlib/libc/include/locale.h | 5 +++ newlib/libc/include/sys/reent.h | 12 ++++++ newlib/libc/locale/Makefile.inc | 1 + newlib/libc/locale/getlocalename_l.c | 77 ++++++++++++++++++++++++++++++++= ++++ 5 files changed, 116 insertions(+) diff --git a/newlib/Makefile.in b/newlib/Makefile.in index 9a32646abe96..61a89ff65c93 100644 --- a/newlib/Makefile.in +++ b/newlib/Makefile.in @@ -353,6 +353,7 @@ check_PROGRAMS =3D @ELIX_LEVEL_1_FALSE@am__append_19 =3D \ @ELIX_LEVEL_1_FALSE@ libc/locale/duplocale.c \ @ELIX_LEVEL_1_FALSE@ libc/locale/freelocale.c \ +@ELIX_LEVEL_1_FALSE@ libc/locale/getlocalename_l.c \ @ELIX_LEVEL_1_FALSE@ libc/locale/lctype.c \ @ELIX_LEVEL_1_FALSE@ libc/locale/lmessages.c \ @ELIX_LEVEL_1_FALSE@ libc/locale/lnumeric.c \ @@ -1383,6 +1384,7 @@ am__objects_21 =3D $(am__objects_20) @ELIX_LEVEL_1_FALSE@am__objects_23 =3D \ @ELIX_LEVEL_1_FALSE@ libc/locale/libc_a-duplocale.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@ libc/locale/libc_a-freelocale.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@ libc/locale/libc_a-getlocalename_l.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@ libc/locale/libc_a-lctype.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@ libc/locale/libc_a-lmessages.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@ libc/locale/libc_a-lnumeric.$(OBJEXT) \ @@ -3937,6 +3939,7 @@ pdfdir =3D @pdfdir@ prefix =3D @prefix@ program_transform_name =3D @program_transform_name@ psdir =3D @psdir@ +runstatedir =3D @runstatedir@ sbindir =3D @sbindir@ shared_machine_dir =3D @shared_machine_dir@ sharedstatedir =3D @sharedstatedir@ @@ -6602,6 +6605,9 @@ libc/locale/libc_a-duplocale.$(OBJEXT): libc/locale/$= (am__dirstamp) \ libc/locale/$(DEPDIR)/$(am__dirstamp) libc/locale/libc_a-freelocale.$(OBJEXT): libc/locale/$(am__dirstamp) \ libc/locale/$(DEPDIR)/$(am__dirstamp) +libc/locale/libc_a-getlocalename_l.$(OBJEXT): \ + libc/locale/$(am__dirstamp) \ + libc/locale/$(DEPDIR)/$(am__dirstamp) libc/locale/libc_a-lctype.$(OBJEXT): libc/locale/$(am__dirstamp) \ libc/locale/$(DEPDIR)/$(am__dirstamp) libc/locale/libc_a-lmessages.$(OBJEXT): libc/locale/$(am__dirstamp) \ @@ -12774,6 +12780,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@libc/iconv/lib/$(DEPDIR)/libc_a-ucsco= nv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/locale/$(DEPDIR)/libc_a-duplocal= e.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/locale/$(DEPDIR)/libc_a-freeloca= le.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libc/locale/$(DEPDIR)/libc_a-getlocal= ename_l.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/locale/$(DEPDIR)/libc_a-lctype.P= o@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/locale/$(DEPDIR)/libc_a-lmessage= s.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/locale/$(DEPDIR)/libc_a-lmonetar= y.Po@am__quote@ @@ -28041,6 +28048,20 @@ libc/locale/libc_a-freelocale.obj: libc/locale/fre= elocale.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDE= S) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c= -o libc/locale/libc_a-freelocale.obj `if test -f 'libc/locale/freelocale.c= '; then $(CYGPATH_W) 'libc/locale/freelocale.c'; else $(CYGPATH_W) '$(srcdi= r)/libc/locale/freelocale.c'; fi` =20 +libc/locale/libc_a-getlocalename_l.o: libc/locale/getlocalename_l.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDE= S) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/local= e/libc_a-getlocalename_l.o -MD -MP -MF libc/locale/$(DEPDIR)/libc_a-getloca= lename_l.Tpo -c -o libc/locale/libc_a-getlocalename_l.o `test -f 'libc/loca= le/getlocalename_l.c' || echo '$(srcdir)/'`libc/locale/getlocalename_l.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/locale/$(DEPDIR)/libc_a-getl= ocalename_l.Tpo libc/locale/$(DEPDIR)/libc_a-getlocalename_l.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'libc/locale/getlocal= ename_l.c' object=3D'libc/locale/libc_a-getlocalename_l.o' libtool=3Dno @AM= DEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDE= S) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c= -o libc/locale/libc_a-getlocalename_l.o `test -f 'libc/locale/getlocalenam= e_l.c' || echo '$(srcdir)/'`libc/locale/getlocalename_l.c + +libc/locale/libc_a-getlocalename_l.obj: libc/locale/getlocalename_l.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDE= S) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/local= e/libc_a-getlocalename_l.obj -MD -MP -MF libc/locale/$(DEPDIR)/libc_a-getlo= calename_l.Tpo -c -o libc/locale/libc_a-getlocalename_l.obj `if test -f 'li= bc/locale/getlocalename_l.c'; then $(CYGPATH_W) 'libc/locale/getlocalename_= l.c'; else $(CYGPATH_W) '$(srcdir)/libc/locale/getlocalename_l.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/locale/$(DEPDIR)/libc_a-getl= ocalename_l.Tpo libc/locale/$(DEPDIR)/libc_a-getlocalename_l.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'libc/locale/getlocal= ename_l.c' object=3D'libc/locale/libc_a-getlocalename_l.obj' libtool=3Dno @= AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDE= S) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c= -o libc/locale/libc_a-getlocalename_l.obj `if test -f 'libc/locale/getloca= lename_l.c'; then $(CYGPATH_W) 'libc/locale/getlocalename_l.c'; else $(CYGP= ATH_W) '$(srcdir)/libc/locale/getlocalename_l.c'; fi` + libc/locale/libc_a-lctype.o: libc/locale/lctype.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDE= S) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/local= e/libc_a-lctype.o -MD -MP -MF libc/locale/$(DEPDIR)/libc_a-lctype.Tpo -c -o= libc/locale/libc_a-lctype.o `test -f 'libc/locale/lctype.c' || echo '$(src= dir)/'`libc/locale/lctype.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/locale/$(DEPDIR)/libc_a-lcty= pe.Tpo libc/locale/$(DEPDIR)/libc_a-lctype.Po diff --git a/newlib/libc/include/locale.h b/newlib/libc/include/locale.h index ec7f86119c4e..e3a702a5eaef 100644 --- a/newlib/libc/include/locale.h +++ b/newlib/libc/include/locale.h @@ -76,6 +76,7 @@ struct __locale_t *_newlocale_r (struct _reent *, int, co= nst char *, void _freelocale_r (struct _reent *, struct __locale_t *); struct __locale_t *_duplocale_r (struct _reent *, struct __locale_t *); struct __locale_t *_uselocale_r (struct _reent *, struct __locale_t *); +const char *_getlocalename_l_r (struct _reent *, int, struct __locale_t *); =20 #ifndef _REENT_ONLY =20 @@ -89,6 +90,10 @@ locale_t duplocale (locale_t); locale_t uselocale (locale_t); #endif /* __POSIX_VISIBLE >=3D 200809 */ =20 +#if __POSIX_VISIBLE >=3D 200809 /* FIXME? Starting with issue 8 */ +const char *getlocalename_l (int, struct __locale_t *); +#endif + #endif /* _REENT_ONLY */ =20 _END_STD_C diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reen= t.h index a02e7c2bd994..4e60c3096ae2 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -369,6 +369,9 @@ struct _misc_reent _mbstate_t _mbsrtowcs_state; _mbstate_t _wcrtomb_state; _mbstate_t _wcsrtombs_state; +#ifdef _MB_CAPABLE + char _getlocalename_l_buf[32 /*ENCODING + 1*/]; +#endif }; =20 /* This version of _reent is laid out with "int"s in pairs, to help @@ -530,6 +533,7 @@ struct _reent _r->_misc->_wcrtomb_state.__value.__wch =3D 0; \ _r->_misc->_wcsrtombs_state.__count =3D 0; \ _r->_misc->_wcsrtombs_state.__value.__wch =3D 0; \ + _r->_misc->_getlocale_l_buf[0] =3D '\0'; \ _r->_misc->_l64a_buf[0] =3D '\0'; \ _r->_misc->_getdate_err =3D 0; \ } while (0) @@ -561,6 +565,7 @@ struct _reent #define _REENT_WCSRTOMBS_STATE(ptr) ((ptr)->_misc->_wcsrtombs_state) #define _REENT_L64A_BUF(ptr) ((ptr)->_misc->_l64a_buf) #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_misc->_getdate_err)) +#define _REENT_GETLOCALENAME_L_BUF(ptr) ((ptr)->_misc->_getlocalename_l_bu= f) #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_signal_buf) =20 #else /* !_REENT_SMALL */ @@ -631,6 +636,10 @@ struct _reent _mbstate_t _mbrtoc16_state; _mbstate_t _mbrtoc32_state; #endif + /* No errors are defined for getlocalename_l. So we can't use + buffer allocation which might lead to an ENOMEM error. We + have to use a "static" buffer here instead. */ + char _getlocalename_l_buf[32 /* ENCODING_LEN + 1 */]; } _reent; #ifdef _REENT_BACKWARD_BINARY_COMPAT struct @@ -750,6 +759,7 @@ struct _reent #define _REENT_L64A_BUF(ptr) ((ptr)->_new._reent._l64a_buf) #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_new._reent._signal_buf) #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_new._reent._getdate_err)) +#define _REENT_GETLOCALENAME_L_BUF(ptr)((ptr)->_new._reent._getlocalename_= l_buf) =20 #endif /* !_REENT_SMALL */ =20 @@ -842,6 +852,8 @@ extern _Thread_local char _tls_l64a_buf[8]; extern _Thread_local struct __locale_t *_tls_locale; #define _REENT_LOCALE(_ptr) (_tls_locale) extern _Thread_local _mbstate_t _tls_mblen_state; +#define _REENT_GETLOCALENAME_L_BUF(ptr) (_tls_getlocalename_l_buf) +extern _Thread_local char _tls_getlocalename_l_buf[32 /*ENCODING + 1*/]; #define _REENT_MBLEN_STATE(_ptr) (_tls_mblen_state) extern _Thread_local _mbstate_t _tls_mbrlen_state; #define _REENT_MBRLEN_STATE(_ptr) (_tls_mbrlen_state) diff --git a/newlib/libc/locale/Makefile.inc b/newlib/libc/locale/Makefile.= inc index cef4131d08ec..0189643c2a94 100644 --- a/newlib/libc/locale/Makefile.inc +++ b/newlib/libc/locale/Makefile.inc @@ -8,6 +8,7 @@ if !ELIX_LEVEL_1 libc_a_SOURCES +=3D \ %D%/duplocale.c \ %D%/freelocale.c \ + %D%/getlocalename_l.c \ %D%/lctype.c \ %D%/lmessages.c \ %D%/lnumeric.c \ diff --git a/newlib/libc/locale/getlocalename_l.c b/newlib/libc/locale/getl= ocalename_l.c new file mode 100644 index 000000000000..7060c8df5952 --- /dev/null +++ b/newlib/libc/locale/getlocalename_l.c @@ -0,0 +1,77 @@ +/* +FUNCTION + <>---create or modify a locale object + +INDEX + getlocalename_l + +INDEX + _getlocalename_l_r + +SYNOPSIS + #include + locale_t getlocalename_l(int <[category]>, locale_t <[locobj]>); + + locale_t _getlocalename_l_r(void *<[reent]>, int <[category]>, + locale_t <[locobj]>); + +DESCRIPTION +The <> function shall return the locale name for the +given locale category of the locale object locobj, or of the global +locale if locobj is the special locale object LC_GLOBAL_LOCALE. + +The category argument specifies the locale category to be queried. If +the value is LC_ALL or is not a supported locale category value (see +<>), <> shall fail. + +The behavior is undefined if the locobj argument is neither the special +locale object LC_GLOBAL_LOCALE nor a valid locale object handle. + +RETURNS +Upon successful completion, <> shall return a pointer +to a string containing the locale name; otherwise, a null pointer shall +be returned. + +If locobj is LC_GLOBAL_LOCALE, the returned string pointer might be +invalidated or the string content might be overwritten by a subsequent +call in the same thread to <> with LC_GLOBAL_LOCALE; +the returned string pointer might also be invalidated if the calling +thread is terminated. Otherwise, the returned string pointer and content +shall remain valid until the locale object locobj is used in a call to +<> or as the base argument in a successful call to +<>. + +No errors are defined. + +PORTABILITY +<> is POSIX-1.2008 since Base Specification Issue 8 +*/ + +#include +#include "setlocale.h" + +const char * +_getlocalename_l_r (struct _reent *ptr, int category, struct __locale_t *l= ocobj) +{ + if (category <=3D LC_ALL || category > LC_MESSAGES) + return NULL; +#ifndef _MB_CAPABLE + return "C"; +#else + if (locobj =3D=3D LC_GLOBAL_LOCALE) + { + /* getlocalename_l is supposed to return the value in a + thread-safe manner. This requires to copy over the + category string into thread-local storage. */ + strcpy (_REENT_GETLOCALENAME_L_BUF (ptr), + __get_global_locale ()->categories[category]); + } + return locobj->categories[category]; +#endif +} + +const char * +getlocalename_l (int category, struct __locale_t *locobj) +{ + return _getlocalename_l_r (_REENT, category, locobj); +}