summaryrefslogtreecommitdiff
path: root/lib/libc/string
diff options
context:
space:
mode:
authorDavid Chisnall <theraven@FreeBSD.org>2012-05-22 14:40:39 +0000
committerDavid Chisnall <theraven@FreeBSD.org>2012-05-22 14:40:39 +0000
commit131242c33e43ec8cfad986afe1fb949dde33a205 (patch)
tree59ae3f63e6ba7bd7343608892ae88413a6b01f48 /lib/libc/string
parent783950c14523afab7c5d1713d5c243bf6178ffba (diff)
Notes
Diffstat (limited to 'lib/libc/string')
-rw-r--r--lib/libc/string/Symbol.map8
-rw-r--r--lib/libc/string/strcasecmp.c33
-rw-r--r--lib/libc/string/strcasestr.c20
-rw-r--r--lib/libc/string/strcoll.c31
-rw-r--r--lib/libc/string/strxfrm.c22
-rw-r--r--lib/libc/string/wcscoll.c20
-rw-r--r--lib/libc/string/wcswidth.c16
-rw-r--r--lib/libc/string/wcsxfrm.c21
8 files changed, 140 insertions, 31 deletions
diff --git a/lib/libc/string/Symbol.map b/lib/libc/string/Symbol.map
index 19f33824b9dd..ef23465e182d 100644
--- a/lib/libc/string/Symbol.map
+++ b/lib/libc/string/Symbol.map
@@ -91,6 +91,14 @@ FBSD_1.1 {
wcsnlen;
};
+FBSD_1.3 {
+ strcasecmp_l;
+ strcasestr_l;
+ strncasecmp_l;
+ wcswidth_l;
+ wcwidth_l;
+};
+
FBSDprivate_1.0 {
__strtok_r;
};
diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c
index 4a474fee24a7..65e042e42a42 100644
--- a/lib/libc/string/strcasecmp.c
+++ b/lib/libc/string/strcasecmp.c
@@ -2,6 +2,11 @@
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,36 +40,48 @@ __FBSDID("$FreeBSD$");
#include <strings.h>
#include <ctype.h>
-
-typedef unsigned char u_char;
+#include "xlocale_private.h"
int
-strcasecmp(const char *s1, const char *s2)
+strcasecmp_l(const char *s1, const char *s2, locale_t locale)
{
const u_char
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
+ FIX_LOCALE(locale);
- while (tolower(*us1) == tolower(*us2++))
+ while (tolower_l(*us1, locale) == tolower_l(*us2++, locale))
if (*us1++ == '\0')
return (0);
- return (tolower(*us1) - tolower(*--us2));
+ return (tolower_l(*us1, locale) - tolower_l(*--us2, locale));
+}
+int
+strcasecmp(const char *s1, const char *s2)
+{
+ return strcasecmp_l(s1, s2, __get_locale());
}
int
-strncasecmp(const char *s1, const char *s2, size_t n)
+strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t locale)
{
+ FIX_LOCALE(locale);
if (n != 0) {
const u_char
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
do {
- if (tolower(*us1) != tolower(*us2++))
- return (tolower(*us1) - tolower(*--us2));
+ if (tolower_l(*us1, locale) != tolower_l(*us2++, locale))
+ return (tolower_l(*us1, locale) - tolower_l(*--us2, locale));
if (*us1++ == '\0')
break;
} while (--n != 0);
}
return (0);
}
+
+int
+strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ return strncasecmp_l(s1, s2, n, __get_locale());
+}
diff --git a/lib/libc/string/strcasestr.c b/lib/libc/string/strcasestr.c
index 9b28bf569a4d..5f39648a69bd 100644
--- a/lib/libc/string/strcasestr.c
+++ b/lib/libc/string/strcasestr.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,26 +40,33 @@ __FBSDID("$FreeBSD$");
#include <ctype.h>
#include <string.h>
+#include "xlocale_private.h"
/*
* Find the first occurrence of find in s, ignore case.
*/
char *
-strcasestr(const char *s, const char *find)
+strcasestr_l(const char *s, const char *find, locale_t locale)
{
char c, sc;
size_t len;
+ FIX_LOCALE(locale);
if ((c = *find++) != 0) {
- c = tolower((unsigned char)c);
+ c = tolower_l((unsigned char)c, locale);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
- } while ((char)tolower((unsigned char)sc) != c);
- } while (strncasecmp(s, find, len) != 0);
+ } while ((char)tolower_l((unsigned char)sc, locale) != c);
+ } while (strncasecmp_l(s, find, len, locale) != 0);
s--;
}
return ((char *)s);
}
+char *
+strcasestr(const char *s, const char *find)
+{
+ return strcasestr_l(s, find, __get_locale());
+}
diff --git a/lib/libc/string/strcoll.c b/lib/libc/string/strcoll.c
index 0da5c5730fc8..a918fcabfab6 100644
--- a/lib/libc/string/strcoll.c
+++ b/lib/libc/string/strcoll.c
@@ -3,6 +3,11 @@
* at Electronni Visti IA, Kiev, Ukraine.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -32,21 +37,26 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include "collate.h"
+#include <stdio.h>
+
int
-strcoll(const char *s, const char *s2)
+strcoll_l(const char *s, const char *s2, locale_t locale)
{
int len, len2, prim, prim2, sec, sec2, ret, ret2;
const char *t, *t2;
char *tt, *tt2;
+ FIX_LOCALE(locale);
+ struct xlocale_collate *table =
+ (struct xlocale_collate*)locale->components[XLC_COLLATE];
- if (__collate_load_error)
+ if (table->__collate_load_error)
return strcmp(s, s2);
len = len2 = 1;
ret = ret2 = 0;
- if (__collate_substitute_nontrivial) {
- t = tt = __collate_substitute(s);
- t2 = tt2 = __collate_substitute(s2);
+ if (table->__collate_substitute_nontrivial) {
+ t = tt = __collate_substitute(table, s);
+ t2 = tt2 = __collate_substitute(table, s2);
} else {
tt = tt2 = NULL;
t = s;
@@ -55,11 +65,11 @@ strcoll(const char *s, const char *s2)
while(*t && *t2) {
prim = prim2 = 0;
while(*t && !prim) {
- __collate_lookup(t, &len, &prim, &sec);
+ __collate_lookup(table, t, &len, &prim, &sec);
t += len;
}
while(*t2 && !prim2) {
- __collate_lookup(t2, &len2, &prim2, &sec2);
+ __collate_lookup(table, t2, &len2, &prim2, &sec2);
t2 += len2;
}
if(!prim || !prim2)
@@ -83,3 +93,10 @@ strcoll(const char *s, const char *s2)
return ret;
}
+
+int
+strcoll(const char *s, const char *s2)
+{
+ return strcoll_l(s, s2, __get_locale());
+}
+
diff --git a/lib/libc/string/strxfrm.c b/lib/libc/string/strxfrm.c
index a4c8019468d6..b758b0c4a383 100644
--- a/lib/libc/string/strxfrm.c
+++ b/lib/libc/string/strxfrm.c
@@ -3,6 +3,11 @@
* at Electronni Visti IA, Kiev, Ukraine.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,11 +38,22 @@ __FBSDID("$FreeBSD$");
#include "collate.h"
size_t
+strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, locale_t loc);
+size_t
strxfrm(char * __restrict dest, const char * __restrict src, size_t len)
{
+ return strxfrm_l(dest, src, len, __get_locale());
+}
+
+size_t
+strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, locale_t locale)
+{
int prim, sec, l;
size_t slen;
char *s, *ss;
+ FIX_LOCALE(locale);
+ struct xlocale_collate *table =
+ (struct xlocale_collate*)locale->components[XLC_COLLATE];
if (!*src) {
if (len > 0)
@@ -45,15 +61,15 @@ strxfrm(char * __restrict dest, const char * __restrict src, size_t len)
return 0;
}
- if (__collate_load_error)
+ if (table->__collate_load_error)
return strlcpy(dest, src, len);
slen = 0;
prim = sec = 0;
- ss = s = __collate_substitute(src);
+ ss = s = __collate_substitute(table, src);
while (*s) {
while (*s && !prim) {
- __collate_lookup(s, &l, &prim, &sec);
+ __collate_lookup(table, s, &l, &prim, &sec);
s += l;
}
if (prim) {
diff --git a/lib/libc/string/wcscoll.c b/lib/libc/string/wcscoll.c
index dbfbcfa919a7..3c51015807c2 100644
--- a/lib/libc/string/wcscoll.c
+++ b/lib/libc/string/wcscoll.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -41,12 +46,15 @@ static char *__mbsdup(const wchar_t *);
* with extended character sets.
*/
int
-wcscoll(const wchar_t *ws1, const wchar_t *ws2)
+wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t locale)
{
char *mbs1, *mbs2;
int diff, sverrno;
+ FIX_LOCALE(locale);
+ struct xlocale_collate *table =
+ (struct xlocale_collate*)locale->components[XLC_COLLATE];
- if (__collate_load_error || MB_CUR_MAX > 1)
+ if (table->__collate_load_error || MB_CUR_MAX > 1)
/*
* Locale has no special collating order, could not be
* loaded, or has an extended character set; do a fast binary
@@ -67,7 +75,7 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
return (wcscmp(ws1, ws2));
}
- diff = strcoll(mbs1, mbs2);
+ diff = strcoll_l(mbs1, mbs2, locale);
sverrno = errno;
free(mbs1);
free(mbs2);
@@ -76,6 +84,12 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
return (diff);
}
+int
+wcscoll(const wchar_t *ws1, const wchar_t *ws2)
+{
+ return wcscoll_l(ws1, ws2, __get_locale());
+}
+
static char *
__mbsdup(const wchar_t *ws)
{
diff --git a/lib/libc/string/wcswidth.c b/lib/libc/string/wcswidth.c
index b142074f1708..4095c8d8cb17 100644
--- a/lib/libc/string/wcswidth.c
+++ b/lib/libc/string/wcswidth.c
@@ -10,6 +10,11 @@
* This code is derived from software contributed to Berkeley by
* Paul Borman at Krystal Technologies.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -39,19 +44,26 @@
__FBSDID("$FreeBSD$");
#include <wchar.h>
+#include "xlocale_private.h"
int
-wcswidth(const wchar_t *pwcs, size_t n)
+wcswidth_l(const wchar_t *pwcs, size_t n, locale_t locale)
{
wchar_t wc;
int len, l;
+ FIX_LOCALE(locale);
len = 0;
while (n-- > 0 && (wc = *pwcs++) != L'\0') {
- if ((l = wcwidth(wc)) < 0)
+ if ((l = wcwidth_l(wc, locale)) < 0)
return (-1);
len += l;
}
return (len);
}
+int
+wcswidth(const wchar_t *pwcs, size_t n)
+{
+ return wcswidth_l(pwcs, n, __get_locale());
+}
diff --git a/lib/libc/string/wcsxfrm.c b/lib/libc/string/wcsxfrm.c
index 5e47ad946ee6..cea667e54815 100644
--- a/lib/libc/string/wcsxfrm.c
+++ b/lib/libc/string/wcsxfrm.c
@@ -3,6 +3,11 @@
* at Electronni Visti IA, Kiev, Ukraine.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -43,11 +48,14 @@ static char *__mbsdup(const wchar_t *);
* the logic used.
*/
size_t
-wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
+wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len, locale_t locale)
{
int prim, sec, l;
size_t slen;
char *mbsrc, *s, *ss;
+ FIX_LOCALE(locale);
+ struct xlocale_collate *table =
+ (struct xlocale_collate*)locale->components[XLC_COLLATE];
if (*src == L'\0') {
if (len != 0)
@@ -55,7 +63,7 @@ wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
return (0);
}
- if (__collate_load_error || MB_CUR_MAX > 1) {
+ if (table->__collate_load_error || MB_CUR_MAX > 1) {
slen = wcslen(src);
if (len > 0) {
if (slen < len)
@@ -71,10 +79,10 @@ wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
mbsrc = __mbsdup(src);
slen = 0;
prim = sec = 0;
- ss = s = __collate_substitute(mbsrc);
+ ss = s = __collate_substitute(table, mbsrc);
while (*s != '\0') {
while (*s != '\0' && prim == 0) {
- __collate_lookup(s, &l, &prim, &sec);
+ __collate_lookup(table, s, &l, &prim, &sec);
s += l;
}
if (prim != 0) {
@@ -93,6 +101,11 @@ wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
return (slen);
}
+size_t
+wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
+{
+ return wcsxfrm_l(dest, src, len, __get_locale());
+}
static char *
__mbsdup(const wchar_t *ws)