Implement all the POSIX _l functions.

Strictly speaking, this only implements the _l variants of the functions
we actually have. We're still missing nl_langinfo_l, for example, but we
don't have nl_langinfo either.

Change-Id: Ie711c7b04e7b9100932a13f5a5d5b28847eb4c12
This commit is contained in:
Elliott Hughes 2014-11-06 15:04:08 -08:00
parent 08a70184b4
commit b20c24456e
12 changed files with 96 additions and 215 deletions

View File

@ -206,16 +206,10 @@ libc_bionic_src_files := \
bionic/socket.cpp \
bionic/stat.cpp \
bionic/statvfs.cpp \
bionic/strcoll_l.cpp \
bionic/strerror.cpp \
bionic/strerror_r.cpp \
bionic/strftime_l.cpp \
bionic/strsignal.cpp \
bionic/strtold.cpp \
bionic/strtold_l.cpp \
bionic/strtoll_l.cpp \
bionic/strtoull_l.cpp \
bionic/strxfrm_l.cpp \
bionic/stubs.cpp \
bionic/symlink.cpp \
bionic/sysconf.cpp \

View File

@ -29,6 +29,10 @@
#include <locale.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <wchar.h>
#include "private/bionic_macros.h"
@ -171,3 +175,47 @@ locale_t uselocale(locale_t new_locale) {
return old_locale;
}
int strcasecmp_l(const char* s1, const char* s2, locale_t) {
return strcasecmp(s1, s2);
}
int strcoll_l(const char* s1, const char* s2, locale_t) {
return strcoll(s1, s2);
}
char* strerror_l(int error, locale_t) {
return strerror(error);
}
size_t strftime_l(char* s, size_t max, const char* format, const struct tm* tm, locale_t) {
return strftime(s, max, format, tm);
}
int strncasecmp_l(const char* s1, const char* s2, size_t n, locale_t) {
return strncasecmp(s1, s2, n);
}
long double strtold_l(const char* s, char** end_ptr, locale_t) {
return strtold(s, end_ptr);
}
long long strtoll_l(const char* s, char** end_ptr, int base, locale_t) {
return strtoll(s, end_ptr, base);
}
unsigned long long strtoull_l(const char* s, char** end_ptr, int base, locale_t) {
return strtoull(s, end_ptr, base);
}
size_t strxfrm_l(char* dst, const char* src, size_t n, locale_t) {
return strxfrm(dst, src, n);
}
int wcscasecmp_l(const wchar_t* ws1, const wchar_t* ws2, locale_t) {
return wcscasecmp(ws1, ws2);
}
int wcsncasecmp_l(const wchar_t* ws1, const wchar_t* ws2, size_t n, locale_t) {
return wcsncasecmp(ws1, ws2, n);
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
int strcoll_l(const char *s1, const char *s2, locale_t) {
return strcoll(s1, s2);
}

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <time.h>
size_t strftime_l(char *s, size_t max, const char *format, const struct tm *tm,
locale_t) {
return strftime(s, max, format, tm);
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdlib.h>
long double strtold_l(const char *nptr, char **endptr, locale_t) {
return strtold(nptr, endptr);
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdlib.h>
long long strtoll_l(const char *nptr, char **endptr, int base, locale_t) {
return strtoll(nptr, endptr, base);
}

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdlib.h>
unsigned long long strtoull_l(const char *nptr, char **endptr, int base,
locale_t) {
return strtoull(nptr, endptr, base);
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
size_t strxfrm_l(char *dest, const char *src, size_t n, locale_t) {
return strxfrm(dest, src, n);
}

View File

@ -58,8 +58,11 @@ extern char* stpcpy(char* __restrict, const char* __restrict);
extern char* strcpy(char* __restrict, const char* __restrict);
extern char* strcat(char* __restrict, const char* __restrict);
extern int strcasecmp(const char *, const char *) __purefunc;
extern int strncasecmp(const char *, const char *, size_t) __purefunc;
int strcasecmp(const char*, const char*) __purefunc;
int strcasecmp_l(const char*, const char*, locale_t) __purefunc;
int strncasecmp(const char*, const char*, size_t) __purefunc;
int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;
extern char* strdup(const char *);
extern char* strstr(const char *, const char *) __purefunc;
@ -68,6 +71,7 @@ extern char* strtok(char* __restrict, const char* __restrict);
extern char* strtok_r(char* __restrict, const char* __restrict, char** __restrict);
extern char* strerror(int);
extern char* strerror_l(int, locale_t);
#if defined(__USE_GNU)
extern char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r);
#else /* POSIX */

View File

@ -41,22 +41,23 @@
#include <sys/types.h>
#include <sys/cdefs.h>
#include <xlocale.h>
__BEGIN_DECLS
#if defined(__BIONIC_FORTIFY)
#define bcopy(b1, b2, len) \
(void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2)))
#define bzero(b, len) \
(void)(__builtin___memset_chk((b), '\0', (len), __bos0(b)))
#define bcopy(b1, b2, len) (void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2)))
#define bzero(b, len) (void)(__builtin___memset_chk((b), '\0', (len), __bos0(b)))
#else
#define bcopy(b1, b2, len) (void)(__builtin_memmove((b2), (b1), (len)))
#define bzero(b, len) (void)(__builtin_memset((b), '\0', (len)))
#endif
int ffs(int);
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
int strcasecmp(const char*, const char*) __purefunc;
int strcasecmp_l(const char*, const char*, locale_t) __purefunc;
int strncasecmp(const char*, const char*, size_t) __purefunc;
int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;
__END_DECLS

View File

@ -34,6 +34,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <time.h>
#include <xlocale.h>
#include <machine/wchar_limits.h>
@ -112,6 +113,7 @@ extern int vwprintf(const wchar_t*, va_list);
extern int vwscanf(const wchar_t*, va_list);
extern size_t wcrtomb(char *, wchar_t, mbstate_t *);
extern int wcscasecmp(const wchar_t *, const wchar_t *);
extern int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
extern wchar_t *wcscat(wchar_t *, const wchar_t *);
extern wchar_t *wcschr(const wchar_t *, wchar_t);
extern int wcscmp(const wchar_t *, const wchar_t *);
@ -121,6 +123,7 @@ extern size_t wcscspn(const wchar_t *, const wchar_t *);
extern size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *) __LIBC_ABI_PUBLIC__;
extern size_t wcslen(const wchar_t *);
extern int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
extern int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
extern wchar_t *wcsncat(wchar_t *, const wchar_t *, size_t);
extern int wcsncmp(const wchar_t *, const wchar_t *, size_t);
extern wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t);

View File

@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <errno.h>
#include <locale.h>
#include <strings.h>
TEST(strings, ffs) {
@ -30,3 +31,33 @@ TEST(strings, ffs) {
ASSERT_EQ(27, ffs(0x04000000));
ASSERT_EQ(32, ffs(0x80000000));
}
TEST(strings, strcasecmp) {
ASSERT_EQ(0, strcasecmp("hello", "HELLO"));
ASSERT_LT(strcasecmp("hello1", "hello2"), 0);
ASSERT_GT(strcasecmp("hello2", "hello1"), 0);
}
TEST(strings, strcasecmp_l) {
locale_t l = newlocale(LC_ALL, "C", 0);
ASSERT_EQ(0, strcasecmp_l("hello", "HELLO", l));
ASSERT_LT(strcasecmp_l("hello1", "hello2", l), 0);
ASSERT_GT(strcasecmp_l("hello2", "hello1", l), 0);
freelocale(l);
}
TEST(strings, strncasecmp) {
ASSERT_EQ(0, strncasecmp("hello", "HELLO", 3));
ASSERT_EQ(0, strncasecmp("abcXX", "ABCYY", 3));
ASSERT_LT(strncasecmp("hello1", "hello2", 6), 0);
ASSERT_GT(strncasecmp("hello2", "hello1", 6), 0);
}
TEST(strings, strncasecmp_l) {
locale_t l = newlocale(LC_ALL, "C", 0);
ASSERT_EQ(0, strncasecmp_l("hello", "HELLO", 3, l));
ASSERT_EQ(0, strncasecmp_l("abcXX", "ABCYY", 3, l));
ASSERT_LT(strncasecmp_l("hello1", "hello2", 6, l), 0);
ASSERT_GT(strncasecmp_l("hello2", "hello1", 6, l), 0);
freelocale(l);
}