Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2016-07-24 21:00:34 +0300
committerCorinna Vinschen <corinna@vinschen.de>2016-08-15 11:56:58 +0300
commitc1b7d9d93dc8e88693162c0d984a114371919fdd (patch)
tree25842a96b7ae037393ebc3d96803a376e7beff45
parent8493c1631643fada62384768408852bc0fa6ff44 (diff)
Implement per-locale string functions
strcasecmp_l, strcoll_l, strncasecmp_l, strxfrm_l, wcscasecmp_l, wcscoll_l, wcstrncasecmp_l, wcstrxfrm_l, strftime_l. Add missing CHEWOUT_FILES from previous patch. TODO: strfmon_l. Signed-off by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--newlib/libc/ctype/Makefile.am35
-rw-r--r--newlib/libc/ctype/Makefile.in35
-rw-r--r--newlib/libc/include/string.h13
-rw-r--r--newlib/libc/include/wchar.h13
-rw-r--r--newlib/libc/locale/setlocale.h36
-rw-r--r--newlib/libc/string/Makefile.am14
-rw-r--r--newlib/libc/string/Makefile.in132
-rw-r--r--newlib/libc/string/strcasecmp.c6
-rw-r--r--newlib/libc/string/strcasecmp_l.c54
-rw-r--r--newlib/libc/string/strcoll.c3
-rw-r--r--newlib/libc/string/strcoll_l.c46
-rw-r--r--newlib/libc/string/strncasecmp.c6
-rw-r--r--newlib/libc/string/strncasecmp_l.c56
-rw-r--r--newlib/libc/string/strxfrm.c3
-rw-r--r--newlib/libc/string/strxfrm_l.c71
-rw-r--r--newlib/libc/string/wcscasecmp.c12
-rw-r--r--newlib/libc/string/wcscasecmp_l.c54
-rw-r--r--newlib/libc/string/wcscoll.c4
-rw-r--r--newlib/libc/string/wcscoll_l.c43
-rw-r--r--newlib/libc/string/wcsncasecmp.c17
-rw-r--r--newlib/libc/string/wcsncasecmp_l.c56
-rw-r--r--newlib/libc/string/wcsxfrm.c4
-rw-r--r--newlib/libc/string/wcsxfrm_l.c47
-rw-r--r--newlib/libc/time/strftime.c100
-rw-r--r--winsup/cygwin/common.din9
-rw-r--r--winsup/cygwin/nlsfuncs.cc48
-rw-r--r--winsup/doc/posix.xml17
27 files changed, 816 insertions, 118 deletions
diff --git a/newlib/libc/ctype/Makefile.am b/newlib/libc/ctype/Makefile.am
index 0cda2a3e0..00b91bfe2 100644
--- a/newlib/libc/ctype/Makefile.am
+++ b/newlib/libc/ctype/Makefile.am
@@ -98,38 +98,71 @@ include $(srcdir)/../../Makefile.shared
CHEWOUT_FILES= \
isalnum.def \
+ isalnum_l.def \
isalpha.def \
+ isalpha_l.def \
isascii.def \
+ isascii_l.def \
isblank.def \
+ isblank_l.def \
iscntrl.def \
+ iscntrl_l.def \
isdigit.def \
+ isdigit_l.def \
islower.def \
+ islower_l.def \
isprint.def \
+ isprint_l.def \
ispunct.def \
+ ispunct_l.def \
isspace.def \
+ isspace_l.def \
isupper.def \
+ isupper_l.def \
iswalnum.def \
+ iswalnum_l.def \
iswalpha.def \
+ iswalpha_l.def \
iswblank.def \
+ iswblank_l.def \
iswcntrl.def \
+ iswcntrl_l.def \
iswctype.def \
+ iswctype_l.def \
iswdigit.def \
+ iswdigit_l.def \
iswgraph.def \
+ iswgraph_l.def \
iswlower.def \
+ iswlower_l.def \
iswprint.def \
+ iswprint_l.def \
iswpunct.def \
+ iswpunct_l.def \
iswspace.def \
+ iswspace_l.def \
iswupper.def \
+ iswupper_l.def \
iswxdigit.def \
+ iswxdigit_l.def \
isxdigit.def \
+ isxdigit_l.def \
toascii.def \
+ toascii_l.def \
tolower.def \
+ tolower_l.def \
toupper.def \
+ toupper_l.def \
towctrans.def \
+ towctrans_l.def \
towlower.def \
+ towlower_l.def \
towupper.def \
+ towupper_l.def \
wctrans.def \
- wctype.def
+ wctrans_l.def \
+ wctype.def \
+ wctype_l.def
CHAPTERS = ctype.tex
diff --git a/newlib/libc/ctype/Makefile.in b/newlib/libc/ctype/Makefile.in
index d29495ada..02f707162 100644
--- a/newlib/libc/ctype/Makefile.in
+++ b/newlib/libc/ctype/Makefile.in
@@ -426,38 +426,71 @@ DOCBOOK_CHAPTERS = $(CHAPTERS:.tex=.xml)
CLEANFILES = $(CHEWOUT_FILES) $(CHEWOUT_FILES:.def=.ref) $(DOCBOOK_OUT_FILES)
CHEWOUT_FILES = \
isalnum.def \
+ isalnum_l.def \
isalpha.def \
+ isalpha_l.def \
isascii.def \
+ isascii_l.def \
isblank.def \
+ isblank_l.def \
iscntrl.def \
+ iscntrl_l.def \
isdigit.def \
+ isdigit_l.def \
islower.def \
+ islower_l.def \
isprint.def \
+ isprint_l.def \
ispunct.def \
+ ispunct_l.def \
isspace.def \
+ isspace_l.def \
isupper.def \
+ isupper_l.def \
iswalnum.def \
+ iswalnum_l.def \
iswalpha.def \
+ iswalpha_l.def \
iswblank.def \
+ iswblank_l.def \
iswcntrl.def \
+ iswcntrl_l.def \
iswctype.def \
+ iswctype_l.def \
iswdigit.def \
+ iswdigit_l.def \
iswgraph.def \
+ iswgraph_l.def \
iswlower.def \
+ iswlower_l.def \
iswprint.def \
+ iswprint_l.def \
iswpunct.def \
+ iswpunct_l.def \
iswspace.def \
+ iswspace_l.def \
iswupper.def \
+ iswupper_l.def \
iswxdigit.def \
+ iswxdigit_l.def \
isxdigit.def \
+ isxdigit_l.def \
toascii.def \
+ toascii_l.def \
tolower.def \
+ tolower_l.def \
toupper.def \
+ toupper_l.def \
towctrans.def \
+ towctrans_l.def \
towlower.def \
+ towlower_l.def \
towupper.def \
+ towupper_l.def \
wctrans.def \
- wctype.def
+ wctrans_l.def \
+ wctype.def \
+ wctype_l.def
CHAPTERS = ctype.tex
all: all-am
diff --git a/newlib/libc/include/string.h b/newlib/libc/include/string.h
index 56c7fc25b..549d51184 100644
--- a/newlib/libc/include/string.h
+++ b/newlib/libc/include/string.h
@@ -16,6 +16,11 @@
#define __need_NULL
#include <stddef.h>
+#if __POSIX_VISIBLE >= 200809 || defined (_COMPILING_NEWLIB)
+struct __locale_t;
+typedef struct __locale_t *locale_t;
+#endif
+
_BEGIN_STD_C
_PTR _EXFUN(memchr,(const _PTR, int, size_t));
@@ -43,6 +48,14 @@ char *_EXFUN(strtok,(char *__restrict, const char *__restrict));
#endif
size_t _EXFUN(strxfrm,(char *__restrict, const char *__restrict, size_t));
+#if __POSIX_VISIBLE >= 200809
+extern int strcasecmp_l (const char *, const char *, locale_t);
+extern int strncasecmp_l (const char *, const char *, size_t, locale_t);
+extern int strcoll_l (const char *, const char *, locale_t);
+extern size_t strxfrm_l (char *__restrict, const char *__restrict, size_t,
+ locale_t);
+#endif
+
#if __MISC_VISIBLE || __POSIX_VISIBLE
char *_EXFUN(strtok_r,(char *__restrict, const char *__restrict, char **__restrict));
#endif
diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h
index 3a2b89b08..a03f642de 100644
--- a/newlib/libc/include/wchar.h
+++ b/newlib/libc/include/wchar.h
@@ -63,6 +63,11 @@ typedef __gnuc_va_list va_list;
#endif
#endif
+#if __POSIX_VISIBLE >= 200809 || defined (_COMPILING_NEWLIB)
+struct __locale_t;
+typedef struct __locale_t *locale_t;
+#endif
+
_BEGIN_STD_C
#if __POSIX_VISIBLE >= 200809 || _XSI_VISIBLE
@@ -162,6 +167,14 @@ int _EXFUN(wcswidth, (const wchar_t *, size_t));
#endif
size_t _EXFUN(wcsxfrm, (wchar_t *__restrict, const wchar_t *__restrict,
size_t));
+#if __POSIX_VISIBLE >= 200809
+extern int wcscasecmp_l (const wchar_t *, const wchar_t *, locale_t);
+extern int wcsncasecmp_l (const wchar_t *, const wchar_t *, size_t, locale_t);
+extern int wcscoll_l (const wchar_t *, const wchar_t *, locale_t);
+extern size_t wcsxfrm_l (wchar_t *__restrict, const wchar_t *__restrict, size_t,
+ locale_t);
+#endif
+
#if __XSI_VISIBLE
int _EXFUN(wcwidth, (const wchar_t));
#endif
diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h
index a73706316..8f5c93c9b 100644
--- a/newlib/libc/locale/setlocale.h
+++ b/newlib/libc/locale/setlocale.h
@@ -220,16 +220,14 @@ __get_current_locale ()
return _REENT->_locale ?: &__global_locale;
}
-#define __get_locale_ctype(__l) \
- ((const struct lc_ctype_T *) (__l)->lc_cat[LC_CTYPE].ptr)
-#ifdef __HAVE_LOCALE_INFO__
-#define __locale_mb_cur_max_l(__l) (__get_locale_ctype (__l)->mb_cur_max)
-#else
-#define __locale_mb_cur_max_l(__l) ((__l)->mb_cur_max)
-#endif
-
#ifdef __CYGWIN__
_ELIDABLE_INLINE const struct lc_collate_T *
+__get_locale_collate (struct __locale_t *locale)
+{
+ return (const struct lc_collate_T *) locale->lc_cat[LC_COLLATE].ptr;
+}
+
+_ELIDABLE_INLINE const struct lc_collate_T *
__get_current_collate_locale (void)
{
return (const struct lc_collate_T *) __get_current_locale ()->lc_cat[LC_COLLATE].ptr;
@@ -237,6 +235,22 @@ __get_current_collate_locale (void)
#endif
_ELIDABLE_INLINE const struct lc_ctype_T *
+__get_locale_ctype (struct __locale_t *locale)
+{
+ return (const struct lc_ctype_T *) (locale)->lc_cat[LC_CTYPE].ptr;
+}
+
+_ELIDABLE_INLINE int
+__locale_mb_cur_max_l (struct __locale_t *locale)
+{
+#ifdef __HAVE_LOCALE_INFO__
+ return __get_locale_ctype (locale)->mb_cur_max[0];
+#else
+ return locale->mb_cur_max[0];
+#endif
+}
+
+_ELIDABLE_INLINE const struct lc_ctype_T *
__get_current_ctype_locale (void)
{
return (const struct lc_ctype_T *) __get_current_locale ()->lc_cat[LC_CTYPE].ptr;
@@ -260,6 +274,12 @@ __get_current_time_locale (void)
return (const struct lc_time_T *) __get_current_locale ()->lc_cat[LC_TIME].ptr;
}
+_ELIDABLE_INLINE const struct lc_ctype_T *
+__get_locale_time (struct __locale_t *locale)
+{
+ return (const struct lc_time_T *) (locale)->lc_cat[LC_TIME].ptr;
+}
+
_ELIDABLE_INLINE const struct lc_messages_T *
__get_current_messages_locale (void)
{
diff --git a/newlib/libc/string/Makefile.am b/newlib/libc/string/Makefile.am
index 1c047f532..e1f7f3bb8 100644
--- a/newlib/libc/string/Makefile.am
+++ b/newlib/libc/string/Makefile.am
@@ -109,8 +109,16 @@ ELIX_4_SOURCES = \
memmem.c \
memrchr.c \
rawmemchr.c \
+ strcasecmp_l.c \
+ strcoll_l.c \
+ strncasecmp_l.c \
+ strxfrm_l.c \
wcscasecmp.c \
- wcsncasecmp.c
+ wcscasecmp_l.c \
+ wcscoll_l.c \
+ wcsncasecmp.c \
+ wcsncasecmp_l.c \
+ wcsxfrm_l.c
endif !ELIX_LEVEL_3
endif !ELIX_LEVEL_2
endif !ELIX_LEVEL_1
@@ -146,6 +154,8 @@ wcsncmp.def wcsncpy.def wcsnlen.def wcspbrk.def \
wcsrchr.def wcsspn.def wcsstr.def wcstok.def \
wcswidth.def wcsxfrm.def wcwidth.def wmemchr.def \
wmemcmp.def wmemcpy.def wmemmove.def wmemset.def \
-memmem.def memrchr.def rawmemchr.def strchrnul.def
+memmem.def memrchr.def rawmemchr.def strchrnul.def \
+strcasecmp_l.def strcoll_l.def strncasecmp_l.def strxfrm_l.def \
+wcscasecmp_l.def wcscoll_l.def wcsncasecmp_l.def wcsxfrm_l.def
CHAPTERS = strings.tex wcstrings.tex
diff --git a/newlib/libc/string/Makefile.in b/newlib/libc/string/Makefile.in
index 95826bb69..857d800ef 100644
--- a/newlib/libc/string/Makefile.in
+++ b/newlib/libc/string/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 = string
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
@@ -124,8 +119,16 @@ am__objects_1 = lib_a-bcopy.$(OBJEXT) lib_a-bzero.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-memmem.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-memrchr.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-rawmemchr.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-strcasecmp_l.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-strcoll_l.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-strncasecmp_l.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-strxfrm_l.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcscasecmp.$(OBJEXT) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcsncasecmp.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcscasecmp_l.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcscoll_l.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcsncasecmp.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcsncasecmp_l.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wcsxfrm_l.$(OBJEXT)
@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) \
@USE_LIBTOOL_FALSE@ $(am__objects_2) $(am__objects_3)
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
@@ -153,8 +156,16 @@ am__objects_4 = bcopy.lo bzero.lo explicit_bzero.lo index.lo memchr.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ memmem.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ memrchr.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ rawmemchr.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strcasecmp_l.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strcoll_l.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strncasecmp_l.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strxfrm_l.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcscasecmp.lo \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsncasecmp.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcscasecmp_l.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcscoll_l.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsncasecmp.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsncasecmp_l.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsxfrm_l.lo
@USE_LIBTOOL_TRUE@am_libstring_la_OBJECTS = $(am__objects_4) \
@USE_LIBTOOL_TRUE@ $(am__objects_5) $(am__objects_6)
libstring_la_OBJECTS = $(am_libstring_la_OBJECTS)
@@ -241,8 +252,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@
@@ -271,6 +284,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@
@@ -422,8 +436,16 @@ GENERAL_SOURCES = \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ memmem.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ memrchr.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ rawmemchr.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strcasecmp_l.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strcoll_l.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strncasecmp_l.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ strxfrm_l.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcscasecmp.c \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsncasecmp.c
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcscasecmp_l.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcscoll_l.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsncasecmp.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsncasecmp_l.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wcsxfrm_l.c
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@ELIX_4_SOURCES =
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@ELIX_4_SOURCES =
@@ -462,7 +484,9 @@ wcsncmp.def wcsncpy.def wcsnlen.def wcspbrk.def \
wcsrchr.def wcsspn.def wcsstr.def wcstok.def \
wcswidth.def wcsxfrm.def wcwidth.def wmemchr.def \
wmemcmp.def wmemcpy.def wmemmove.def wmemset.def \
-memmem.def memrchr.def rawmemchr.def strchrnul.def
+memmem.def memrchr.def rawmemchr.def strchrnul.def \
+strcasecmp_l.def strcoll_l.def strncasecmp_l.def strxfrm_l.def \
+wcscasecmp_l.def wcscoll_l.def wcsncasecmp_l.def wcsxfrm_l.def
CHAPTERS = strings.tex wcstrings.tex
all: all-am
@@ -510,12 +534,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}; \
+ }
libstring.la: $(libstring_la_OBJECTS) $(libstring_la_DEPENDENCIES) $(EXTRA_libstring_la_DEPENDENCIES)
$(libstring_la_LINK) $(am_libstring_la_rpath) $(libstring_la_OBJECTS) $(libstring_la_LIBADD) $(LIBS)
@@ -1056,18 +1082,66 @@ lib_a-rawmemchr.o: rawmemchr.c
lib_a-rawmemchr.obj: rawmemchr.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-rawmemchr.obj `if test -f 'rawmemchr.c'; then $(CYGPATH_W) 'rawmemchr.c'; else $(CYGPATH_W) '$(srcdir)/rawmemchr.c'; fi`
+lib_a-strcasecmp_l.o: strcasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcasecmp_l.o `test -f 'strcasecmp_l.c' || echo '$(srcdir)/'`strcasecmp_l.c
+
+lib_a-strcasecmp_l.obj: strcasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcasecmp_l.obj `if test -f 'strcasecmp_l.c'; then $(CYGPATH_W) 'strcasecmp_l.c'; else $(CYGPATH_W) '$(srcdir)/strcasecmp_l.c'; fi`
+
+lib_a-strcoll_l.o: strcoll_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcoll_l.o `test -f 'strcoll_l.c' || echo '$(srcdir)/'`strcoll_l.c
+
+lib_a-strcoll_l.obj: strcoll_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcoll_l.obj `if test -f 'strcoll_l.c'; then $(CYGPATH_W) 'strcoll_l.c'; else $(CYGPATH_W) '$(srcdir)/strcoll_l.c'; fi`
+
+lib_a-strncasecmp_l.o: strncasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncasecmp_l.o `test -f 'strncasecmp_l.c' || echo '$(srcdir)/'`strncasecmp_l.c
+
+lib_a-strncasecmp_l.obj: strncasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncasecmp_l.obj `if test -f 'strncasecmp_l.c'; then $(CYGPATH_W) 'strncasecmp_l.c'; else $(CYGPATH_W) '$(srcdir)/strncasecmp_l.c'; fi`
+
+lib_a-strxfrm_l.o: strxfrm_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strxfrm_l.o `test -f 'strxfrm_l.c' || echo '$(srcdir)/'`strxfrm_l.c
+
+lib_a-strxfrm_l.obj: strxfrm_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strxfrm_l.obj `if test -f 'strxfrm_l.c'; then $(CYGPATH_W) 'strxfrm_l.c'; else $(CYGPATH_W) '$(srcdir)/strxfrm_l.c'; fi`
+
lib_a-wcscasecmp.o: wcscasecmp.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcscasecmp.o `test -f 'wcscasecmp.c' || echo '$(srcdir)/'`wcscasecmp.c
lib_a-wcscasecmp.obj: wcscasecmp.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcscasecmp.obj `if test -f 'wcscasecmp.c'; then $(CYGPATH_W) 'wcscasecmp.c'; else $(CYGPATH_W) '$(srcdir)/wcscasecmp.c'; fi`
+lib_a-wcscasecmp_l.o: wcscasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcscasecmp_l.o `test -f 'wcscasecmp_l.c' || echo '$(srcdir)/'`wcscasecmp_l.c
+
+lib_a-wcscasecmp_l.obj: wcscasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcscasecmp_l.obj `if test -f 'wcscasecmp_l.c'; then $(CYGPATH_W) 'wcscasecmp_l.c'; else $(CYGPATH_W) '$(srcdir)/wcscasecmp_l.c'; fi`
+
+lib_a-wcscoll_l.o: wcscoll_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcscoll_l.o `test -f 'wcscoll_l.c' || echo '$(srcdir)/'`wcscoll_l.c
+
+lib_a-wcscoll_l.obj: wcscoll_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcscoll_l.obj `if test -f 'wcscoll_l.c'; then $(CYGPATH_W) 'wcscoll_l.c'; else $(CYGPATH_W) '$(srcdir)/wcscoll_l.c'; fi`
+
lib_a-wcsncasecmp.o: wcsncasecmp.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsncasecmp.o `test -f 'wcsncasecmp.c' || echo '$(srcdir)/'`wcsncasecmp.c
lib_a-wcsncasecmp.obj: wcsncasecmp.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsncasecmp.obj `if test -f 'wcsncasecmp.c'; then $(CYGPATH_W) 'wcsncasecmp.c'; else $(CYGPATH_W) '$(srcdir)/wcsncasecmp.c'; fi`
+lib_a-wcsncasecmp_l.o: wcsncasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsncasecmp_l.o `test -f 'wcsncasecmp_l.c' || echo '$(srcdir)/'`wcsncasecmp_l.c
+
+lib_a-wcsncasecmp_l.obj: wcsncasecmp_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsncasecmp_l.obj `if test -f 'wcsncasecmp_l.c'; then $(CYGPATH_W) 'wcsncasecmp_l.c'; else $(CYGPATH_W) '$(srcdir)/wcsncasecmp_l.c'; fi`
+
+lib_a-wcsxfrm_l.o: wcsxfrm_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsxfrm_l.o `test -f 'wcsxfrm_l.c' || echo '$(srcdir)/'`wcsxfrm_l.c
+
+lib_a-wcsxfrm_l.obj: wcsxfrm_l.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsxfrm_l.obj `if test -f 'wcsxfrm_l.c'; then $(CYGPATH_W) 'wcsxfrm_l.c'; else $(CYGPATH_W) '$(srcdir)/wcsxfrm_l.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
@@ -1123,6 +1197,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:
@@ -1233,7 +1321,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/string/strcasecmp.c b/newlib/libc/string/strcasecmp.c
index ebf23cd51..df8510b13 100644
--- a/newlib/libc/string/strcasecmp.c
+++ b/newlib/libc/string/strcasecmp.c
@@ -46,13 +46,11 @@ _DEFUN (strcasecmp, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
- _CONST unsigned char *ucs1 = (_CONST unsigned char *) s1;
- _CONST unsigned char *ucs2 = (_CONST unsigned char *) s2;
int d = 0;
for ( ; ; )
{
- _CONST int c1 = tolower(*ucs1++);
- _CONST int c2 = tolower(*ucs2++);
+ _CONST int c1 = tolower(*s1++);
+ _CONST int c2 = tolower(*s2++);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
diff --git a/newlib/libc/string/strcasecmp_l.c b/newlib/libc/string/strcasecmp_l.c
new file mode 100644
index 000000000..f87039d91
--- /dev/null
+++ b/newlib/libc/string/strcasecmp_l.c
@@ -0,0 +1,54 @@
+/*
+FUNCTION
+ <<strcasecmp_l>>---case-insensitive character string compare
+
+INDEX
+ strcasecmp_l
+
+ANSI_SYNOPSIS
+ #include <strings.h>
+ int strcasecmp_l(const char *<[a]>, const char *<[b]>,
+ locale_t <[locale]>);
+
+DESCRIPTION
+ <<strcasecmp_l>> compares the string at <[a]> to
+ the string at <[b]> in a case-insensitive manner.
+
+ if <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+RETURNS
+
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
+ both are converted to lowercase), <<strcasecmp_l>> returns a
+ number greater than zero. If the two strings match,
+ <<strcasecmp_l>> returns zero. If <<*<[a]>>> sorts
+ lexicographically before <<*<[b]>>>, <<strcasecmp_l>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strcasecmp_l>> is POSIX-1.2008.
+
+<<strcasecmp_l>> requires no supporting OS subroutines. It uses
+tolower_l() from elsewhere in this library.
+
+QUICKREF
+ strcasecmp_l
+*/
+
+#include <strings.h>
+#include <ctype.h>
+
+int
+strcasecmp_l (const char *s1, const char *s2, struct __locale_t *locale)
+{
+ int d = 0;
+ for ( ; ; )
+ {
+ const int c1 = tolower_l (*s1++, locale);
+ const int c2 = tolower_l (*s2++, locale);
+ if (((d = c1 - c2) != 0) || (c2 == '\0'))
+ break;
+ }
+ return d;
+}
diff --git a/newlib/libc/string/strcoll.c b/newlib/libc/string/strcoll.c
index 65dc38037..a6bb31a4e 100644
--- a/newlib/libc/string/strcoll.c
+++ b/newlib/libc/string/strcoll.c
@@ -20,6 +20,9 @@ DESCRIPTION
the string pointed to by <[strb]>, using an interpretation
appropriate to the current <<LC_COLLATE>> state.
+ (NOT Cygwin:) The current implementation of <<strcoll>> simply
+ uses <<strcmp>> and does not support any language-specific sorting.
+
RETURNS
If the first string is greater than the second string,
<<strcoll>> returns a number greater than zero. If the two
diff --git a/newlib/libc/string/strcoll_l.c b/newlib/libc/string/strcoll_l.c
new file mode 100644
index 000000000..5032f8439
--- /dev/null
+++ b/newlib/libc/string/strcoll_l.c
@@ -0,0 +1,46 @@
+/*
+FUNCTION
+ <<strcoll_l>>---locale-specific character string compare
+
+INDEX
+ strcoll_l
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int strcoll_l(const char *<[stra]>, const char * <[strb]>,
+ locale_t <[locale]>);
+
+DESCRIPTION
+ <<strcoll_l>> compares the string pointed to by <[stra]> to
+ the string pointed to by <[strb]>, using an interpretation
+ appropriate to the current <<LC_COLLATE>> state.
+
+ (NOT Cygwin:) The current implementation of <<strcoll_l>> simply
+ uses <<strcmp>> and does not support any language-specific sorting.
+
+ If <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+RETURNS
+ If the first string is greater than the second string,
+ <<strcoll_l>> returns a number greater than zero. If the two
+ strings are equivalent, <<strcoll_l>> returns zero. If the first
+ string is less than the second string, <<strcoll_l>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strcoll_l>> is POSIX-1.2008.
+
+<<strcoll_l>> requires no supporting OS subroutines.
+
+QUICKREF
+ strcoll_l ansi pure
+*/
+
+#include <string.h>
+
+int
+strcoll_l (const char *a, const char *b, struct __locale_t *locale)
+{
+ return strcmp (a, b);
+}
diff --git a/newlib/libc/string/strncasecmp.c b/newlib/libc/string/strncasecmp.c
index 27778e0f0..828f30bf9 100644
--- a/newlib/libc/string/strncasecmp.c
+++ b/newlib/libc/string/strncasecmp.c
@@ -49,13 +49,11 @@ _DEFUN (strncasecmp, (s1, s2, n),
_CONST char *s2 _AND
size_t n)
{
- _CONST unsigned char *ucs1 = (_CONST unsigned char *) s1;
- _CONST unsigned char *ucs2 = (_CONST unsigned char *) s2;
int d = 0;
for ( ; n != 0; n--)
{
- _CONST int c1 = tolower(*ucs1++);
- _CONST int c2 = tolower(*ucs2++);
+ _CONST int c1 = tolower(*s1++);
+ _CONST int c2 = tolower(*s2++);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
diff --git a/newlib/libc/string/strncasecmp_l.c b/newlib/libc/string/strncasecmp_l.c
new file mode 100644
index 000000000..41ae58265
--- /dev/null
+++ b/newlib/libc/string/strncasecmp_l.c
@@ -0,0 +1,56 @@
+/*
+FUNCTION
+ <<strncasecmp_l>>---case-insensitive character string compare
+
+INDEX
+ strncasecmp_l
+
+ANSI_SYNOPSIS
+ #include <strings.h>
+ int strncasecmp_l(const char *<[a]>, const char * <[b]>,
+ size_t <[length]>, locale_t <[locale]>);
+
+DESCRIPTION
+ <<strncasecmp_l>> compares up to <[length]> characters
+ from the string at <[a]> to the string at <[b]> in a
+ case-insensitive manner.
+
+ if <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+RETURNS
+
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
+ both are converted to lowercase), <<strncasecmp_l>> returns a
+ number greater than zero. If the two strings are equivalent,
+ <<strncasecmp_l>> returns zero. If <<*<[a]>>> sorts
+ lexicographically before <<*<[b]>>>, <<strncasecmp_l>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strncasecmp_l>> is POSIX-1.2008.
+
+<<strncasecmp_l>> requires no supporting OS subroutines. It uses
+tolower_l() from elsewhere in this library.
+
+QUICKREF
+ strncasecmp_l
+*/
+
+#include <strings.h>
+#include <ctype.h>
+
+int
+strncasecmp_l (const char *s1, const char *s2, size_t n,
+ struct __locale_t *locale)
+{
+ int d = 0;
+ for ( ; n != 0; n--)
+ {
+ const int c1 = tolower_l (*s1++, locale);
+ const int c2 = tolower_l (*s2++, locale);
+ if (((d = c1 - c2) != 0) || (c2 == '\0'))
+ break;
+ }
+ return d;
+}
diff --git a/newlib/libc/string/strxfrm.c b/newlib/libc/string/strxfrm.c
index 9d0ab882b..edc1272de 100644
--- a/newlib/libc/string/strxfrm.c
+++ b/newlib/libc/string/strxfrm.c
@@ -32,7 +32,8 @@ DESCRIPTION
copying takes place between objects that overlap, the behavior
is undefined.
- With a C locale, this function just copies.
+ (NOT Cygwin:) The current implementation of <<strxfrm>> simply copies
+ the input and does not support any language-specific transformations.
RETURNS
The <<strxfrm>> function returns the length of the transformed string
diff --git a/newlib/libc/string/strxfrm_l.c b/newlib/libc/string/strxfrm_l.c
new file mode 100644
index 000000000..a1f4fe295
--- /dev/null
+++ b/newlib/libc/string/strxfrm_l.c
@@ -0,0 +1,71 @@
+/*
+FUNCTION
+ <<strxfrm_l>>---transform string
+
+INDEX
+ strxfrm_l
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ size_t strxfrm_l(char *restrict <[s1]>, const char *restrict <[s2]>,
+ size_t <[n]>, locale_t <[locale]>);
+
+DESCRIPTION
+ This function transforms the string pointed to by <[s2]> and
+ places the resulting string into the array pointed to by
+ <[s1]>. The transformation is such that if the <<strcmp>>
+ function is applied to the two transformed strings, it returns
+ a value greater than, equal to, or less than zero,
+ correspoinding to the result of a <<strcoll>> function applied
+ to the same two original strings.
+
+ No more than <[n]> characters are placed into the resulting
+ array pointed to by <[s1]>, including the terminating null
+ character. If <[n]> is zero, <[s1]> may be a null pointer. If
+ copying takes place between objects that overlap, the behavior
+ is undefined.
+
+ (NOT Cygwin:) The current implementation of <<strxfrm_l>> simply copies
+ the input and does not support any language-specific transformations.
+
+ If <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+RETURNS
+ The <<strxfrm_l>> function returns the length of the transformed string
+ (not including the terminating null character). If the value returned
+ is <[n]> or more, the contents of the array pointed to by
+ <[s1]> are indeterminate.
+
+PORTABILITY
+<<strxfrm_l>> is POSIX-1.2008.
+
+<<strxfrm_l>> requires no supporting OS subroutines.
+
+QUICKREF
+ strxfrm_l ansi pure
+*/
+
+#include <string.h>
+
+size_t
+strxfrm_l (char *__restrict s1, const char *__restrict s2, size_t n,
+ struct __locale_t *locale)
+{
+ size_t res;
+ res = 0;
+ while (n-- > 0)
+ {
+ if ((*s1++ = *s2++) != '\0')
+ ++res;
+ else
+ return res;
+ }
+ while (*s2)
+ {
+ ++s2;
+ ++res;
+ }
+
+ return res;
+}
diff --git a/newlib/libc/string/wcscasecmp.c b/newlib/libc/string/wcscasecmp.c
index f9f169f8b..05f95619d 100644
--- a/newlib/libc/string/wcscasecmp.c
+++ b/newlib/libc/string/wcscasecmp.c
@@ -46,11 +46,13 @@ _DEFUN (wcscasecmp, (s1, s2),
_CONST wchar_t *s1 _AND
_CONST wchar_t *s2)
{
- while (*s1 != '\0' && towlower(*s1) == towlower(*s2))
+ int d = 0;
+ for ( ; ; )
{
- s1++;
- s2++;
+ const int c1 = towlower (*s1++);
+ const int c2 = towlower (*s2++);
+ if (((d = c1 - c2) != 0) || (c2 == '\0'))
+ break;
}
-
- return towlower(*s1) - towlower(*s2);
+ return d;
}
diff --git a/newlib/libc/string/wcscasecmp_l.c b/newlib/libc/string/wcscasecmp_l.c
new file mode 100644
index 000000000..329be0529
--- /dev/null
+++ b/newlib/libc/string/wcscasecmp_l.c
@@ -0,0 +1,54 @@
+/*
+FUNCTION
+ <<wcscasecmp_l>>---case-insensitive wide character string compare
+
+INDEX
+ wcscasecmp_l
+
+ANSI_SYNOPSIS
+ #include <wchar.h>
+ int wcscasecmp_l(const wchar_t *<[a]>, const wchar_t *<[b]>,
+ locale_t <[locale]>);
+
+DESCRIPTION
+ <<wcscasecmp_l>> compares the wide character string at <[a]> to
+ the wide character string at <[b]> in a case-insensitive manner.
+
+ if <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object,
+ the behaviour is undefined.
+
+RETURNS
+
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
+ both are converted to uppercase), <<wcscasecmp_l>> returns a
+ number greater than zero. If the two strings match,
+ <<wcscasecmp_l>> returns zero. If <<*<[a]>>> sorts
+ lexicographically before <<*<[b]>>>, <<wcscasecmp_l>> returns a
+ number less than zero.
+
+PORTABILITY
+<<wcscasecmp_l>> is POSIX-1.2008
+
+<<wcscasecmp_l>> requires no supporting OS subroutines. It uses
+tolower() from elsewhere in this library.
+
+QUICKREF
+ wcscasecmp_l
+*/
+
+#include <wchar.h>
+#include <wctype.h>
+
+int
+wcscasecmp_l (const wchar_t *s1, const wchar_t *s2, struct __locale_t *locale)
+{
+ int d = 0;
+ for ( ; ; )
+ {
+ const int c1 = towlower_l (*s1++, locale);
+ const int c2 = towlower_l (*s2++, locale);
+ if (((d = c1 - c2) != 0) || (c2 == '\0'))
+ break;
+ }
+ return d;
+}
diff --git a/newlib/libc/string/wcscoll.c b/newlib/libc/string/wcscoll.c
index 0f0513a58..726f4ca0b 100644
--- a/newlib/libc/string/wcscoll.c
+++ b/newlib/libc/string/wcscoll.c
@@ -21,8 +21,8 @@ DESCRIPTION
using an interpretation appropriate to the current <<LC_COLLATE>>
state.
- The current implementation of <<wcscoll>> simply uses <<wcscmp>>
- and does not support any language-specific sorting.
+ (NOT Cygwin:) The current implementation of <<wcscoll>> simply
+ uses <<wcscmp>> and does not support any language-specific sorting.
RETURNS
If the first string is greater than the second string,
diff --git a/newlib/libc/string/wcscoll_l.c b/newlib/libc/string/wcscoll_l.c
new file mode 100644
index 000000000..e71d02a75
--- /dev/null
+++ b/newlib/libc/string/wcscoll_l.c
@@ -0,0 +1,43 @@
+/*
+FUNCTION
+ <<wcscoll_l>>---locale-specific wide-character string compare
+
+INDEX
+ wcscoll_l
+
+ANSI_SYNOPSIS
+ #include <wchar.h>
+ int wcscoll_l(const wchar_t *<[stra]>, const wchar_t * <[strb]>,
+ locale_t <[locale]>);
+
+DESCRIPTION
+ <<wcscoll_l>> compares the wide-character string pointed to by
+ <[stra]> to the wide-character string pointed to by <[strb]>,
+ using an interpretation appropriate to the current <<LC_COLLATE>>
+ state.
+
+ (NOT Cygwin:) The current implementation of <<wcscoll_l>> simply
+ uses <<wcscmp>> and does not support any language-specific sorting.
+
+ If <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+RETURNS
+ If the first string is greater than the second string,
+ <<wcscoll_l>> returns a number greater than zero. If the two
+ strings are equivalent, <<wcscoll_l>> returns zero. If the first
+ string is less than the second string, <<wcscoll_l>> returns a
+ number less than zero.
+
+PORTABILITY
+<<wcscoll_l>> is POSIX-1.2008.
+*/
+
+#include <_ansi.h>
+#include <wchar.h>
+
+int
+wcscoll_l (const wchar_t *a, const wchar_t *b, struct __locale_t *locale)
+{
+ return wcscmp (a, b);
+}
diff --git a/newlib/libc/string/wcsncasecmp.c b/newlib/libc/string/wcsncasecmp.c
index 1634ca195..c6fc08ef6 100644
--- a/newlib/libc/string/wcsncasecmp.c
+++ b/newlib/libc/string/wcsncasecmp.c
@@ -49,16 +49,13 @@ _DEFUN (wcsncasecmp, (s1, s2, n),
_CONST wchar_t *s2 _AND
size_t n)
{
- if (n == 0)
- return 0;
-
- while (n-- != 0 && towlower(*s1) == towlower(*s2))
+ int d = 0;
+ for ( ; n != 0; n--)
{
- if (n == 0 || *s1 == '\0' || *s2 == '\0')
- break;
- s1++;
- s2++;
+ const int c1 = towlower (*s1++);
+ const int c2 = towlower (*s2++);
+ if (((d = c1 - c2) != 0) || (c2 == '\0'))
+ break;
}
-
- return towlower(*s1) - towlower(*s2);
+ return d;
}
diff --git a/newlib/libc/string/wcsncasecmp_l.c b/newlib/libc/string/wcsncasecmp_l.c
new file mode 100644
index 000000000..4b360b802
--- /dev/null
+++ b/newlib/libc/string/wcsncasecmp_l.c
@@ -0,0 +1,56 @@
+/*
+FUNCTION
+ <<wcsncasecmp_l>>---case-insensitive wide character string compare
+
+INDEX
+ wcsncasecmp_l
+
+ANSI_SYNOPSIS
+ #include <wchar.h>
+ int wcsncasecmp_l(const wchar_t *<[a]>, const wchar_t * <[b]>,
+ size_t <[length]>, locale_t <[locale]>);
+
+DESCRIPTION
+ <<wcsncasecmp_l>> compares up to <[length]> wide characters
+ from the string at <[a]> to the string at <[b]> in a
+ case-insensitive manner.
+
+ if <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+RETURNS
+
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
+ both are converted to uppercase), <<wcsncasecmp_l>> returns a
+ number greater than zero. If the two strings are equivalent,
+ <<wcsncasecmp_l>> returns zero. If <<*<[a]>>> sorts
+ lexicographically before <<*<[b]>>>, <<wcsncasecmp_l>> returns a
+ number less than zero.
+
+PORTABILITY
+POSIX-1.2008
+
+<<wcsncasecmp_l>> requires no supporting OS subroutines. It uses
+tolower() from elsewhere in this library.
+
+QUICKREF
+ wcsncasecmp_l
+*/
+
+#include <wchar.h>
+#include <wctype.h>
+
+int
+wcsncasecmp_l (const wchar_t *s1, const wchar_t *s2, size_t n,
+ struct __locale_t *locale)
+{
+ int d = 0;
+ for ( ; n != 0; n--)
+ {
+ const int c1 = towlower_l (*s1++, locale);
+ const int c2 = towlower_l (*s2++, locale);
+ if (((d = c1 - c2) != 0) || (c2 == '\0'))
+ break;
+ }
+ return d;
+}
diff --git a/newlib/libc/string/wcsxfrm.c b/newlib/libc/string/wcsxfrm.c
index d5a31728d..d267d274f 100644
--- a/newlib/libc/string/wcsxfrm.c
+++ b/newlib/libc/string/wcsxfrm.c
@@ -27,8 +27,8 @@ DESCRIPTION
If <[n]> is 0, <[stra]> may be a NULL pointer.
- The current implementation of <<wcsxfrm>> simply uses <<wcslcpy>>
- and does not support any language-specific transformations.
+ (NOT Cygwin:) The current implementation of <<wcsxfrm>> simply uses
+ <<wcslcpy>> and does not support any language-specific transformations.
RETURNS
<<wcsxfrm>> returns the length of the transformed wide character
diff --git a/newlib/libc/string/wcsxfrm_l.c b/newlib/libc/string/wcsxfrm_l.c
new file mode 100644
index 000000000..c44b0d639
--- /dev/null
+++ b/newlib/libc/string/wcsxfrm_l.c
@@ -0,0 +1,47 @@
+/*
+FUNCTION
+ <<wcsxfrm_l>>---locale-specific wide-character string transformation
+
+INDEX
+ wcsxfrm_l
+
+ANSI_SYNOPSIS
+ #include <wchar.h>
+ int wcsxfrm_l(wchar_t *__restrict <[stra]>,
+ const wchar_t *__restrict <[strb]>, size_t <[n]>,
+ locale_t <[locale]>);
+
+DESCRIPTION
+ <<wcsxfrm_l>> transforms the wide-character string pointed to by
+ <[strb]> to the wide-character string pointed to by <[stra]>,
+ Comparing two transformed wide strings with <<wcscmp>> should return
+ the same result as comparing the original strings with <<wcscoll>>.
+ No more than <[n]> wide characters are transformed, including the
+ trailing null character.
+
+ If <[n]> is 0, <[stra]> may be a NULL pointer.
+
+ If <[locale]> is LC_GLOBAL_LOCALE or not a valid locale object, the
+ behaviour is undefined.
+
+ (NOT Cygwin:) The current implementation of <<wcsxfrm_l>> simply uses
+ <<wcslcpy>> and does not support any language-specific transformations.
+
+RETURNS
+ <<wcsxfrm_l>> returns the length of the transformed wide character
+ string. if the return value is greater or equal to <[n]>, the
+ content of <[stra]> is undefined.
+
+PORTABILITY
+<<wcsxfrm_l>> is POSIX-1.2008.
+*/
+
+#include <_ansi.h>
+#include <wchar.h>
+
+size_t
+wcsxfrm_l (wchar_t *__restrict a, const wchar_t *__restrict b, size_t n,
+ struct __locale_t *locale)
+{
+ return wcslcpy (a, b, n);
+}
diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c
index 12c37ebea..0d5bbd503 100644
--- a/newlib/libc/time/strftime.c
+++ b/newlib/libc/time/strftime.c
@@ -4,7 +4,7 @@
/*
* strftime.c
* Original Author: G. Haley
- * Additions from: Eric Blake
+ * Additions from: Eric Blake, Corinna Vinschen
* Changes to allow dual use as wcstime, also: Craig Howland
*
* Places characters into the array pointed to by s as controlled by the string
@@ -17,16 +17,23 @@
/*
FUNCTION
-<<strftime>>---convert date and time to a formatted string
+<<strftime>>, <<strftime_l>>---convert date and time to a formatted string
INDEX
strftime
+INDEX
+ strftime_l
+
ANSI_SYNOPSIS
#include <time.h>
size_t strftime(char *restrict <[s]>, size_t <[maxsize]>,
const char *restrict <[format]>,
const struct tm *restrict <[timp]>);
+ size_t strftime_l(char *restrict <[s]>, size_t <[maxsize]>,
+ const char *restrict <[format]>,
+ const struct tm *restrict <[timp]>,
+ locale_t <[locale]>);
TRAD_SYNOPSIS
#include <time.h>
@@ -41,6 +48,9 @@ DESCRIPTION
<[timp]>) into a null-terminated string, starting at <[s]> and occupying
no more than <[maxsize]> characters.
+<<strftime_l>> is like <<strftime>> but creates a string in a format
+as expected in locale <[locale]>.
+
You control the format of the output using the string at <[format]>.
<<*<[format]>>> can contain two kinds of specifications: text to be
copied literally into the formatted string, and time conversion
@@ -258,11 +268,13 @@ value beforehand to distinguish between failure and an empty string.
This implementation does not support <<s>> being NULL, nor overlapping
<<s>> and <<format>>.
-<<strftime>> requires no supporting OS subroutines.
+<<strftime_l>> is POSIX-1.2008.
+
+<<strftime>> and <<strftime_l>> require no supporting OS subroutines.
BUGS
-<<strftime>> ignores the LC_TIME category of the current locale, hard-coding
-the "C" locale settings.
+(NOT Cygwin:) <<strftime>> ignores the LC_TIME category of the current
+locale, hard-coding the "C" locale settings.
*/
#include <newlib.h>
@@ -662,39 +674,16 @@ conv_to_alt_digits (CHAR *buf, size_t bufsiz, unsigned num, alt_digits_t *adi)
return 0;
}
-static size_t __strftime (CHAR *, size_t, const CHAR *, const struct tm *,
- era_info_t **, alt_digits_t **);
-
-size_t
-_DEFUN (strftime, (s, maxsize, format, tim_p),
- CHAR *__restrict s _AND
- size_t maxsize _AND
- _CONST CHAR *__restrict format _AND
- _CONST struct tm *__restrict tim_p)
-{
- era_info_t *era_info = NULL;
- alt_digits_t *alt_digits = NULL;
- size_t ret = __strftime (s, maxsize, format, tim_p, &era_info, &alt_digits);
- if (era_info)
- free_era_info (era_info);
- if (alt_digits)
- free_alt_digits (alt_digits);
- return ret;
-}
-
static size_t
__strftime (CHAR *s, size_t maxsize, const CHAR *format,
- const struct tm *tim_p, era_info_t **era_info,
- alt_digits_t **alt_digits)
-#else /* !_WANT_C99_TIME_FORMATS */
-# define __strftime(s,m,f,t,e,a) strftime((s),(m),(f),(t))
+ const struct tm *tim_p, struct __locale_t *locale,
+ era_info_t **era_info, alt_digits_t **alt_digits)
+#else
+static size_t
+__strftime (CHAR *s, size_t maxsize, const CHAR *format,
+ const struct tm *tim_p, struct __locale_t *locale)
-size_t
-_DEFUN (strftime, (s, maxsize, format, tim_p),
- CHAR *__restrict s _AND
- size_t maxsize _AND
- _CONST CHAR *__restrict format _AND
- _CONST struct tm *__restrict tim_p)
+#define __strftime(s,m,f,t,l,e,a) __strftime((s),(m),(f),(t),(l))
#endif /* !_WANT_C99_TIME_FORMATS */
{
size_t count = 0;
@@ -709,7 +698,7 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
unsigned long width;
int tzset_called = 0;
- const struct lc_time_T *_CurrentTimeLocale = __get_current_time_locale ();
+ const struct lc_time_T *_CurrentTimeLocale = __get_locale_time (locale);
for (;;)
{
while (*format && *format != CQ('%'))
@@ -840,7 +829,7 @@ recurse:
{
/* Recurse to avoid need to replicate %Y formation. */
len = __strftime (&s[count], maxsize - count, ctloc, tim_p,
- era_info, alt_digits);
+ locale, era_info, alt_digits);
if (len > 0)
count += len;
else
@@ -957,7 +946,7 @@ recurse:
}
STRCPY (fmt, CQ("Y-%m-%d"));
len = __strftime (&s[count], maxsize - count, fmtbuf, tim_p,
- era_info, alt_digits);
+ locale, era_info, alt_digits);
if (len > 0)
count += len;
else
@@ -1447,6 +1436,41 @@ recurse:
return count;
}
+size_t
+_DEFUN (strftime, (s, maxsize, format, tim_p),
+ CHAR *__restrict s _AND
+ size_t maxsize _AND
+ _CONST CHAR *__restrict format _AND
+ _CONST struct tm *__restrict tim_p)
+{
+ era_info_t *era_info = NULL;
+ alt_digits_t *alt_digits = NULL;
+ size_t ret = __strftime (s, maxsize, format, tim_p, __get_current_locale (),
+ &era_info, &alt_digits);
+ if (era_info)
+ free_era_info (era_info);
+ if (alt_digits)
+ free_alt_digits (alt_digits);
+ return ret;
+}
+
+#if !defined(MAKE_WCSFTIME)
+size_t
+strftime_l (char *__restrict s, size_t maxsize, const char *__restrict format,
+ const struct tm *__restrict tim_p, struct __locale_t *locale)
+{
+ era_info_t *era_info = NULL;
+ alt_digits_t *alt_digits = NULL;
+ size_t ret = __strftime (s, maxsize, format, tim_p, locale,
+ &era_info, &alt_digits);
+ if (era_info)
+ free_era_info (era_info);
+ if (alt_digits)
+ free_alt_digits (alt_digits);
+ return ret;
+}
+#endif
+
/* The remainder of this file can serve as a regression test. Compile
* with -D_REGRESSION_TEST. */
#if defined(_REGRESSION_TEST) /* [Test code: */
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index 7d80c3d97..114adc95c 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -1330,12 +1330,14 @@ stime SIGFE
stpcpy NOSIGFE
stpncpy NOSIGFE
strcasecmp NOSIGFE
+strcasecmp_l NOSIGFE
strcasestr NOSIGFE
strcat NOSIGFE
strchr NOSIGFE
strchrnul NOSIGFE
strcmp NOSIGFE
strcoll NOSIGFE
+strcoll_l NOSIGFE
strcpy NOSIGFE
strcspn NOSIGFE
strdup SIGFE
@@ -1343,11 +1345,13 @@ strerror SIGFE
strerror_r SIGFE
strfmon SIGFE
strftime SIGFE
+strftime_l SIGFE
strlcat NOSIGFE
strlcpy NOSIGFE
strlen NOSIGFE
strlwr NOSIGFE
strncasecmp NOSIGFE
+strncasecmp_l NOSIGFE
strncat NOSIGFE
strncmp NOSIGFE
strncpy NOSIGFE
@@ -1374,6 +1378,7 @@ strtoull NOSIGFE
strtoumax = strtoull NOSIGFE
strupr NOSIGFE
strxfrm NOSIGFE
+strxfrm_l NOSIGFE
swab NOSIGFE
swapcontext NOSIGFE
swprintf SIGFE
@@ -1495,10 +1500,12 @@ wcpcpy NOSIGFE
wcpncpy NOSIGFE
wcrtomb NOSIGFE
wcscasecmp NOSIGFE
+wcscasecmp_l NOSIGFE
wcscat NOSIGFE
wcschr NOSIGFE
wcscmp NOSIGFE
wcscoll NOSIGFE
+wcscoll_l NOSIGFE
wcscpy NOSIGFE
wcscspn NOSIGFE
wcsdup NOSIGFE
@@ -1507,6 +1514,7 @@ wcslcat NOSIGFE
wcslcpy NOSIGFE
wcslen NOSIGFE
wcsncasecmp NOSIGFE
+wcsncasecmp_l NOSIGFE
wcsncat NOSIGFE
wcsncmp NOSIGFE
wcsncpy NOSIGFE
@@ -1530,6 +1538,7 @@ wcstoull NOSIGFE
wcstoumax = wcstoull NOSIGFE
wcswidth NOSIGFE
wcsxfrm NOSIGFE
+wcsxfrm_l NOSIGFE
wctob NOSIGFE
wctomb NOSIGFE
wctrans NOSIGFE
diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc
index 9b19f2a45..714577143 100644
--- a/winsup/cygwin/nlsfuncs.cc
+++ b/winsup/cygwin/nlsfuncs.cc
@@ -1117,10 +1117,11 @@ __collate_load_locale (struct __locale_t *locale, const char *name,
transformation. The advantage is that we don't need any files with
collation information. */
extern "C" int
-wcscoll (const wchar_t *__restrict ws1, const wchar_t *__restrict ws2)
+wcscoll_l (const wchar_t *__restrict ws1, const wchar_t *__restrict ws2,
+ struct __locale_t *locale)
{
int ret;
- LCID collate_lcid = __get_current_collate_locale ()->lcid;
+ LCID collate_lcid = __get_locale_collate (locale)->lcid;
if (!collate_lcid)
return wcscmp (ws1, ws2);
@@ -1131,19 +1132,26 @@ wcscoll (const wchar_t *__restrict ws1, const wchar_t *__restrict ws2)
}
extern "C" int
-strcoll (const char *__restrict s1, const char *__restrict s2)
+wcscoll (const wchar_t *__restrict ws1, const wchar_t *__restrict ws2)
+{
+ return wcscoll_l (ws1, ws2, __get_current_locale ());
+}
+
+extern "C" int
+strcoll_l (const char *__restrict s1, const char *__restrict s2,
+ struct __locale_t *locale)
{
size_t n1, n2;
wchar_t *ws1, *ws2;
tmp_pathbuf tp;
int ret;
- LCID collate_lcid = __get_current_collate_locale ()->lcid;
+ LCID collate_lcid = __get_locale_collate (locale)->lcid;
if (!collate_lcid)
return strcmp (s1, s2);
/* The ANSI version of CompareString uses the default charset of the lcid,
so we must use the Unicode version. */
- mbtowc_p collate_mbtowc = __get_current_collate_locale ()->mbtowc;
+ mbtowc_p collate_mbtowc = __get_locale_collate (locale)->mbtowc;
n1 = lc_mbstowcs (collate_mbtowc, NULL, s1, 0) + 1;
ws1 = (n1 > NT_MAX_PATH ? (wchar_t *) malloc (n1 * sizeof (wchar_t))
: tp.w_get ());
@@ -1162,6 +1170,12 @@ strcoll (const char *__restrict s1, const char *__restrict s2)
return ret - CSTR_EQUAL;
}
+extern "C" int
+strcoll (const char *__restrict s1, const char *__restrict s2)
+{
+ return strcoll_l (s1, s2, __get_current_locale ());
+}
+
/* BSD. Used from glob.cc, fnmatch.c and regcomp.c. Make sure caller is
using wide chars. Unfortunately the definition of this functions hides
the required input type. */
@@ -1174,10 +1188,11 @@ __collate_range_cmp (int c1, int c2)
}
extern "C" size_t
-wcsxfrm (wchar_t *__restrict ws1, const wchar_t *__restrict ws2, size_t wsn)
+wcsxfrm_l (wchar_t *__restrict ws1, const wchar_t *__restrict ws2, size_t wsn,
+ struct __locale_t *locale)
{
size_t ret;
- LCID collate_lcid = __get_current_collate_locale ()->lcid;
+ LCID collate_lcid = __get_locale_collate (locale)->lcid;
if (!collate_lcid)
return wcslcpy (ws1, ws2, wsn);
@@ -1207,19 +1222,26 @@ wcsxfrm (wchar_t *__restrict ws1, const wchar_t *__restrict ws2, size_t wsn)
}
extern "C" size_t
-strxfrm (char *__restrict s1, const char *__restrict s2, size_t sn)
+wcsxfrm (wchar_t *__restrict ws1, const wchar_t *__restrict ws2, size_t wsn)
+{
+ return wcsxfrm_l (ws1, ws2, wsn, __get_current_locale ());
+}
+
+extern "C" size_t
+strxfrm_l (char *__restrict s1, const char *__restrict s2, size_t sn,
+ struct __locale_t *locale)
{
size_t ret = 0;
size_t n2;
wchar_t *ws2;
tmp_pathbuf tp;
- LCID collate_lcid = __get_current_collate_locale ()->lcid;
+ LCID collate_lcid = __get_locale_collate (locale)->lcid;
if (!collate_lcid)
return strlcpy (s1, s2, sn);
/* The ANSI version of LCMapString uses the default charset of the lcid,
so we must use the Unicode version. */
- mbtowc_p collate_mbtowc = __get_current_collate_locale ()->mbtowc;
+ mbtowc_p collate_mbtowc = __get_locale_collate (locale)->mbtowc;
n2 = lc_mbstowcs (collate_mbtowc, NULL, s2, 0) + 1;
ws2 = (n2 > NT_MAX_PATH ? (wchar_t *) malloc (n2 * sizeof (wchar_t))
: tp.w_get ());
@@ -1245,6 +1267,12 @@ strxfrm (char *__restrict s1, const char *__restrict s2, size_t sn)
return ret - 1;
}
+extern "C" size_t
+strxfrm (char *__restrict s1, const char *__restrict s2, size_t sn)
+{
+ return strxfrm_l (s1, s2, sn, __get_current_locale ());
+}
+
/* Fetch default ANSI codepage from locale info and generate a setlocale
compatible character set code. Called from newlib's setlocale(), if the
charset isn't given explicitely in the POSIX compatible locale specifier. */
diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml
index 38a5bbc89..bc38f3920 100644
--- a/winsup/doc/posix.xml
+++ b/winsup/doc/posix.xml
@@ -913,10 +913,12 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
stpcpy
stpncpy
strcasecmp
+ strcasecmp_l
strcat
strchr
strcmp
strcoll
+ strcoll_l
strcpy
strcspn
strdup
@@ -924,8 +926,10 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
strerror_r
strfmon
strftime
+ strftime_l
strlen
strncasecmp
+ strncasecmp_l
strncat
strncmp
strncpy
@@ -949,6 +953,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
strtoull
strtoumax
strxfrm
+ strxfrm_l
swab
swprintf
swscanf
@@ -1045,16 +1050,19 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
wcpncpy
wcrtomb
wcscasecmp
+ wcscasecmp_l
wcscat
wcschr
wcscmp
wcscoll
+ wcscoll_l
wcscpy
wcscspn
wcsdup
wcsftime
wcslen
wcsncasecmp
+ wcsncasecmp_l
wcsncat
wcsncmp
wcsncpy
@@ -1078,6 +1086,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
wcstoumax
wcswidth
wcsxfrm
+ wcsxfrm_l
wctob
wctomb
wctrans
@@ -1539,18 +1548,10 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
putmsg
setnetent
sigtimedwait
- strcasecmp_l
- strcoll_l
strfmon_l
- strncasecmp_l
- strxfrm_l
timer_getoverrun
ulimit
waitid
- wcscasecmp_l
- wcscoll_l
- wcsncasecmp_l
- wcsxfrm_l
</screen>
</sect1>