Browse Source

New POSIX xlocale implementation written from scratch.

Complete in the sense that all POSIX *locale(3) and *_l(3) functions
are included, but in OpenBSD, we of course only really care about
LC_CTYPE and we only support ASCII and UTF-8.
With important help from kettenis@, guenther@, and jca@.
Repeated testing in ports bulk builds by naddy@.
Additional testing by jca@, sebastia@, dcoppa@, and others.
OK kettenis@ dcoppa@, and guenther@ on an earlier version.
Riding guenther@'s libc/librthread major bump.
OPENBSD_6_2
schwarze 6 years ago
parent
commit
371b65730c
20 changed files with 630 additions and 109 deletions
  1. +112
    -2
      src/include/ctype.h
  2. +12
    -1
      src/include/langinfo.h
  3. +29
    -1
      src/include/locale.h
  4. +3
    -4
      src/include/stdlib.h
  5. +12
    -1
      src/include/string.h
  6. +10
    -1
      src/include/strings.h
  7. +14
    -1
      src/include/time.h
  8. +12
    -1
      src/include/wchar.h
  9. +30
    -1
      src/include/wctype.h
  10. +5
    -5
      src/lib/libc/string/Makefile.inc
  11. +56
    -20
      src/lib/libc/string/strcasecmp.3
  12. +21
    -0
      src/lib/libc/string/strcasecmp_l.c
  13. +40
    -13
      src/lib/libc/string/strcoll.3
  14. +14
    -0
      src/lib/libc/string/strcoll_l.c
  15. +52
    -23
      src/lib/libc/string/strerror.3
  16. +33
    -0
      src/lib/libc/string/strerror_l.c
  17. +40
    -17
      src/lib/libc/string/strxfrm.3
  18. +14
    -0
      src/lib/libc/string/strxfrm_l.c
  19. +58
    -18
      src/lib/libc/string/wcscasecmp.3
  20. +63
    -0
      src/lib/libc/string/wcscasecmp_l.c

+ 112
- 2
src/include/ctype.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: ctype.h,v 1.24 2014/05/26 01:49:36 guenther Exp $ */
/* $OpenBSD: ctype.h,v 1.25 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: ctype.h,v 1.14 1994/10/26 00:55:47 cgd Exp $ */
/*
@ -51,6 +51,13 @@
#define _X 0x40
#define _B 0x80
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
__BEGIN_DECLS
extern const char *_ctype_;
@ -84,9 +91,26 @@ int _tolower(int);
int _toupper(int);
#endif /* __BSD_VISIBLE || __XPG_VISIBLE */
#if __POSIX_VISIBLE >= 200809
int isalnum_l(int, locale_t);
int isalpha_l(int, locale_t);
int isblank_l(int, locale_t);
int iscntrl_l(int, locale_t);
int isdigit_l(int, locale_t);
int isgraph_l(int, locale_t);
int islower_l(int, locale_t);
int isprint_l(int, locale_t);
int ispunct_l(int, locale_t);
int isspace_l(int, locale_t);
int isupper_l(int, locale_t);
int isxdigit_l(int, locale_t);
int tolower_l(int, locale_t);
int toupper_l(int, locale_t);
#endif
#endif /* __GNUC__ || _ANSI_LIBRARY */
#if !defined(_ANSI_LIBRARY)
#if !defined(_ANSI_LIBRARY) && !defined(__cplusplus)
__only_inline int isalnum(int _c)
{
@ -187,6 +211,92 @@ __only_inline int _toupper(int _c)
}
#endif /* __BSD_VISIBLE || __XPG_VISIBLE */
#if __POSIX_VISIBLE >= 200809
__only_inline int
isalnum_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isalnum(_c);
}
__only_inline int
isalpha_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isalpha(_c);
}
__only_inline int
isblank_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isblank(_c);
}
__only_inline int
iscntrl_l(int _c, locale_t _l __attribute__((__unused__)))
{
return iscntrl(_c);
}
__only_inline int
isdigit_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isdigit(_c);
}
__only_inline int
isgraph_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isgraph(_c);
}
__only_inline int
islower_l(int _c, locale_t _l __attribute__((__unused__)))
{
return islower(_c);
}
__only_inline int
isprint_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isprint(_c);
}
__only_inline int
ispunct_l(int _c, locale_t _l __attribute__((__unused__)))
{
return ispunct(_c);
}
__only_inline int
isspace_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isspace(_c);
}
__only_inline int
isupper_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isupper(_c);
}
__only_inline int
isxdigit_l(int _c, locale_t _l __attribute__((__unused__)))
{
return isxdigit(_c);
}
__only_inline int
tolower_l(int _c, locale_t _l __attribute__((__unused__)))
{
return tolower(_c);
}
__only_inline int
toupper_l(int _c, locale_t _l __attribute__((__unused__)))
{
return toupper(_c);
}
#endif /* __POSIX_VISIBLE >= 200809 */
#endif /* !_ANSI_LIBRARY */
__END_DECLS


+ 12
- 1
src/include/langinfo.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: langinfo.h,v 1.7 2012/12/05 23:19:57 deraadt Exp $ */
/* $OpenBSD: langinfo.h,v 1.8 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: langinfo.h,v 1.3 1995/04/28 23:30:54 jtc Exp $ */
/*
@ -70,8 +70,19 @@
#define CODESET 51 /* Codeset name */
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
__BEGIN_DECLS
char *nl_langinfo(nl_item);
#if __POSIX_VISIBLE >= 200809
char *nl_langinfo_l(nl_item, locale_t);
#endif
__END_DECLS
#endif /* _LANGINFO_H_ */

+ 29
- 1
src/include/locale.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: locale.h,v 1.10 2016/09/09 18:12:37 millert Exp $ */
/* $OpenBSD: locale.h,v 1.11 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: locale.h,v 1.6 1994/10/26 00:56:02 cgd Exp $ */
/*
@ -76,9 +76,37 @@ struct lconv {
#include <sys/cdefs.h>
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#define LC_COLLATE_MASK (1 << LC_COLLATE)
#define LC_CTYPE_MASK (1 << LC_CTYPE)
#define LC_MONETARY_MASK (1 << LC_MONETARY)
#define LC_NUMERIC_MASK (1 << LC_NUMERIC)
#define LC_TIME_MASK (1 << LC_TIME)
#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
#define LC_ALL_MASK ((1 << _LC_LAST) - 2)
#define LC_GLOBAL_LOCALE ((locale_t)-1)
#endif /* __POSIX_VISIBLE >= 200809 */
__BEGIN_DECLS
struct lconv *localeconv(void);
char *setlocale(int, const char *);
#if __POSIX_VISIBLE >= 200809
locale_t duplocale(locale_t);
void freelocale(locale_t);
locale_t newlocale(int, const char *, locale_t);
locale_t uselocale(locale_t);
#endif
__END_DECLS
#endif /* _LOCALE_H_ */

+ 3
- 4
src/include/stdlib.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: stdlib.h,v 1.71 2017/05/11 11:52:18 tom Exp $ */
/* $OpenBSD: stdlib.h,v 1.72 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */
/*-
@ -82,8 +82,7 @@ typedef struct {
#define RAND_MAX 0x7fffffff
extern size_t __mb_cur_max;
#define MB_CUR_MAX __mb_cur_max
#define MB_CUR_MAX __mb_cur_max()
/*
* Some header files may define an abs macro.
@ -132,7 +131,7 @@ unsigned long
strtoul(const char *__restrict, char **__restrict, int);
int system(const char *);
/* these are currently just stubs */
size_t __mb_cur_max(void);
int mblen(const char *, size_t);
size_t mbstowcs(wchar_t *, const char *, size_t);
int wctomb(char *, wchar_t);


+ 12
- 1
src/include/string.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: string.h,v 1.31 2016/09/09 18:12:37 millert Exp $ */
/* $OpenBSD: string.h,v 1.32 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */
/*-
@ -52,6 +52,13 @@
typedef __size_t size_t;
#endif
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
__BEGIN_DECLS
void *memchr(const void *, int, size_t);
int memcmp(const void *, const void *, size_t);
@ -102,9 +109,13 @@ char *strdup(const char *);
#if __POSIX_VISIBLE >= 200809
char *stpcpy(char *__restrict, const char *__restrict);
char *stpncpy(char *__restrict, const char *__restrict, size_t);
int strcoll_l(const char *, const char *, locale_t);
char *strerror_l(int, locale_t);
char *strndup(const char *, size_t);
size_t strnlen(const char *, size_t);
char *strsignal(int);
size_t strxfrm_l(char *__restrict, const char *__restrict, size_t, locale_t)
__attribute__ ((__bounded__(__string__,1,3)));
#endif
#if __BSD_VISIBLE


+ 10
- 1
src/include/strings.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: strings.h,v 1.4 2015/11/20 23:40:32 millert Exp $ */
/* $OpenBSD: strings.h,v 1.5 2017/09/05 03:16:13 schwarze Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -47,6 +47,13 @@
typedef __size_t size_t;
#endif
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
__BEGIN_DECLS
#if __BSD_VISIBLE || (__XPG_VISIBLE >= 420 && __POSIX_VISIBLE <= 200112)
/*
@ -66,6 +73,8 @@ char *rindex(const char *, int);
int ffs(int);
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
int strcasecmp_l(const char *, const char *, locale_t);
int strncasecmp_l(const char *, const char *, size_t, locale_t);
#endif
__END_DECLS


+ 14
- 1
src/include/time.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: time.h,v 1.29 2016/09/09 18:12:37 millert Exp $ */
/* $OpenBSD: time.h,v 1.30 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: time.h,v 1.9 1994/10/26 00:56:35 cgd Exp $ */
/*
@ -99,6 +99,13 @@ typedef __pid_t pid_t;
#endif
#endif
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
struct tm {
int tm_sec; /* seconds after the minute [0-60] */
int tm_min; /* minutes after the hour [0-59] */
@ -160,6 +167,12 @@ int nanosleep(const struct timespec *, struct timespec *);
int clock_getcpuclockid(pid_t, clockid_t *);
#endif
#if __POSIX_VISIBLE >= 200809
size_t strftime_l(char *__restrict, size_t, const char *__restrict,
const struct tm *__restrict, locale_t)
__attribute__ ((__bounded__(__string__,1,2)));
#endif
#if __BSD_VISIBLE
void tzsetwall(void);
time_t timelocal(struct tm *);


+ 12
- 1
src/include/wchar.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: wchar.h,v 1.30 2016/09/09 18:12:37 millert Exp $ */
/* $OpenBSD: wchar.h,v 1.31 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: wchar.h,v 1.16 2003/03/07 07:11:35 tshiozak Exp $ */
/*-
@ -96,6 +96,13 @@ typedef __size_t size_t;
#define WCHAR_MAX 0x7fffffff
#endif
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
__BEGIN_DECLS
wint_t btowc(int);
size_t mbrlen(const char * __restrict, size_t, mbstate_t * __restrict);
@ -155,9 +162,13 @@ unsigned long int wcstoul(const wchar_t * __restrict, wchar_t ** __restrict,
#if __POSIX_VISIBLE >= 200809
FILE *open_wmemstream(wchar_t **, size_t *);
int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
wchar_t *wcsdup(const wchar_t *);
int wcscasecmp(const wchar_t *, const wchar_t *);
int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
size_t wcsxfrm_l(wchar_t *, const wchar_t *, size_t, locale_t);
size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t,
size_t, mbstate_t * __restrict)


+ 30
- 1
src/include/wctype.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: wctype.h,v 1.5 2006/01/06 18:53:04 millert Exp $ */
/* $OpenBSD: wctype.h,v 1.6 2017/09/05 03:16:13 schwarze Exp $ */
/* $NetBSD: wctype.h,v 1.5 2003/03/02 22:18:11 tshiozak Exp $ */
/*-
@ -54,6 +54,13 @@ typedef __wctype_t wctype_t;
#define WEOF ((wint_t)-1)
#endif
#if __POSIX_VISIBLE >= 200809
#ifndef _LOCALE_T_DEFINED_
#define _LOCALE_T_DEFINED_
typedef void *locale_t;
#endif
#endif
__BEGIN_DECLS
int iswalnum(wint_t);
int iswalpha(wint_t);
@ -73,6 +80,28 @@ wint_t towlower(wint_t);
wint_t towupper(wint_t);
wctrans_t wctrans(const char *);
wctype_t wctype(const char *);
#if __POSIX_VISIBLE >= 200809
int iswalnum_l(wint_t, locale_t);
int iswalpha_l(wint_t, locale_t);
int iswblank_l(wint_t, locale_t);
int iswcntrl_l(wint_t, locale_t);
int iswdigit_l(wint_t, locale_t);
int iswgraph_l(wint_t, locale_t);
int iswlower_l(wint_t, locale_t);
int iswprint_l(wint_t, locale_t);
int iswpunct_l(wint_t, locale_t);
int iswspace_l(wint_t, locale_t);
int iswupper_l(wint_t, locale_t);
int iswxdigit_l(wint_t, locale_t);
int iswctype_l(wint_t, wctype_t, locale_t);
wint_t towctrans_l(wint_t, wctrans_t, locale_t);
wint_t towlower_l(wint_t, locale_t);
wint_t towupper_l(wint_t, locale_t);
wctrans_t wctrans_l(const char *, locale_t);
wctype_t wctype_l(const char *, locale_t);
#endif
__END_DECLS
#endif /* _WCTYPE_H_ */

+ 5
- 5
src/lib/libc/string/Makefile.inc View File

@ -1,17 +1,17 @@
# $OpenBSD: Makefile.inc,v 1.38 2016/03/30 06:38:41 jmc Exp $
# $OpenBSD: Makefile.inc,v 1.39 2017/09/05 03:16:13 schwarze Exp $
# string sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string
SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \
strcasecmp.c strcasestr.c strcoll.c strdup.c \
strerror.c strerror_r.c strmode.c strndup.c strnlen.c \
strsignal.c strtok.c strxfrm.c \
strcasecmp.c strcasecmp_l.c strcasestr.c strcoll.c strcoll_l.c \
strdup.c strerror.c strerror_l.c strerror_r.c strmode.c \
strndup.c strnlen.c strsignal.c strtok.c strxfrm.c strxfrm_l.c \
timingsafe_bcmp.c timingsafe_memcmp.c \
wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \
wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \
wmemmove.c wmemset.c wcsdup.c wcscasecmp.c
wmemmove.c wmemset.c wcsdup.c wcscasecmp.c wcscasecmp_l.c
# machine-dependent net sources
# ../arch/ARCH/Makefile.inc must include sources for:


+ 56
- 20
src/lib/libc/string/strcasecmp.3 View File

@ -1,7 +1,8 @@
.\" $OpenBSD: strcasecmp.3,v 1.13 2015/11/24 09:14:35 daniel Exp $
.\" $OpenBSD: strcasecmp.3,v 1.14 2017/09/05 03:16:13 schwarze Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Chris Torek.
@ -31,25 +32,43 @@
.\"
.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
.\"
.Dd $Mdocdate: November 24 2015 $
.Dd $Mdocdate: September 5 2017 $
.Dt STRCASECMP 3
.Os
.Sh NAME
.Nm strcasecmp ,
.Nm strncasecmp
.Nm strcasecmp_l ,
.Nm strncasecmp ,
.Nm strncasecmp_l
.Nd compare strings, ignoring case
.Sh SYNOPSIS
.In strings.h
.Ft int
.Fn strcasecmp "const char *s1" "const char *s2"
.Fo strcasecmp
.Fa "const char *s1"
.Fa "const char *s2"
.Fc
.Ft int
.Fn strncasecmp "const char *s1" "const char *s2" "size_t len"
.Fo strcasecmp_l
.Fa "const char *s1"
.Fa "const char *s2"
.Fa "locale_t locale"
.Fc
.Ft int
.Fo strncasecmp
.Fa "const char *s1"
.Fa "const char *s2"
.Fa "size_t len"
.Fc
.Ft int
.Fo strncasecmp_l
.Fa "const char *s1"
.Fa "const char *s2"
.Fa "size_t len"
.Fa "locale_t locale"
.Fc
.Sh DESCRIPTION
The
.Fn strcasecmp
and
.Fn strncasecmp
functions compare the NUL-terminated strings
These functions compare the NUL-terminated strings
.Fa s1
and
.Fa s2
@ -66,27 +85,44 @@ is greater than
.Ql \e0 .
.Pp
.Fn strncasecmp
compares at most
and
.Fn strncasecmp_l
compare at most
.Fa len
characters.
.Pp
On
.Ox ,
these functions always use the C locale and ignore
the global locale, the thread-specific locale, and the
.Fa locale
argument.
.Sh ENVIRONMENT
On other operating systems, the behaviour of
.Fn strcasecmp
and
.Fn strncasecmp
may depend on the
.Dv LC_CTYPE
.Xr locale 1 .
.Sh SEE ALSO
.Xr bcmp 3 ,
.Xr memcmp 3 ,
.Xr strcmp 3 ,
.Xr strcoll 3 ,
.Xr strxfrm 3 ,
.Xr wcscasecmp 3
.Sh STANDARDS
The
.Fn strcasecmp
and
.Fn strncasecmp
functions conform to
These functions conform to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn strcasecmp
and
.Fn strncasecmp
functions first appeared in
.Bx 4.3 Tahoe .
functions have been available since
.Bx 4.3 Tahoe ,
and
.Fn strcasecmp_l
and
.Fn strncasecmp_l
since
.Ox 6.2 .

+ 21
- 0
src/lib/libc/string/strcasecmp_l.c View File

@ -0,0 +1,21 @@
/* $OpenBSD: strcasecmp_l.c,v 1.1 2017/09/05 03:16:13 schwarze Exp $ */
/*
* Written in 2017 by Ingo Schwarze <schwarze@openbsd.org>.
* Released into the public domain.
*/
#include <string.h>
int
strcasecmp_l(const char *s1, const char *s2,
locale_t locale __attribute__((__unused__)))
{
return strcasecmp(s1, s2);
}
int
strncasecmp_l(const char *s1, const char *s2, size_t n,
locale_t locale __attribute__((__unused__)))
{
return strncasecmp(s1, s2, n);
}

+ 40
- 13
src/lib/libc/string/strcoll.3 View File

@ -1,4 +1,7 @@
.\" $OpenBSD: strcoll.3,v 1.10 2017/09/05 03:16:13 schwarze Exp $
.\"
.\" Copyright (c) 1990, 1991 The Regents of the University of California.
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
@ -29,45 +32,69 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $OpenBSD: strcoll.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
.\"
.Dd $Mdocdate: June 5 2013 $
.Dd $Mdocdate: September 5 2017 $
.Dt STRCOLL 3
.Os
.Sh NAME
.Nm strcoll
.Nm strcoll ,
.Nm strcoll_l
.Nd compare strings according to current collation
.Sh SYNOPSIS
.In string.h
.Ft int
.Fn strcoll "const char *s1" "const char *s2"
.Ft int
.Fn strcoll_l "const char *s1" "const char *s2" "locale_t locale"
.Sh DESCRIPTION
The
.Fn strcoll
function lexicographically compares the NUL-terminated strings
and
.Fn strcoll_l
functions lexicographically compare the NUL-terminated strings
.Fa s1
and
.Fa s2
according to the current locale collation
and returns an integer greater than, equal to, or less than 0,
and return an integer greater than, equal to, or less than 0,
according to whether
.Fa s1
is greater than, equal to, or less than
.Fa s2 .
.Pp
On
.Ox ,
they have the same effect as
.Xr strcmp 3 ,
and the global locale, the thread-specific locale, and the
.Fa locale
argument are ignored.
.Sh ENVIRONMENT
On other operating systems, the behaviour of
.Fn strcoll
may depend on the
.Dv LC_CTYPE
.Xr locale 1 .
.Sh SEE ALSO
.Xr bcmp 3 ,
.Xr memcmp 3 ,
.Xr newlocale 3 ,
.Xr setlocale 3 ,
.Xr strcasecmp 3 ,
.Xr strcmp 3 ,
.Xr strxfrm 3
.Xr strxfrm 3 ,
.Xr wcscoll 3
.Sh STANDARDS
The
.Fn strcoll
function conforms to
.St -ansiC .
.St -ansiC ,
and
.Fn strcoll_l
to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn strcoll
function first appeared in
.Bx 4.3 Reno .
function has been available since
.Bx 4.3 Reno ,
and
.Fn strcoll_l
since
.Ox 6.2 .

+ 14
- 0
src/lib/libc/string/strcoll_l.c View File

@ -0,0 +1,14 @@
/* $OpenBSD: strcoll_l.c,v 1.1 2017/09/05 03:16:13 schwarze Exp $ */
/*
* Written in 2017 by Ingo Schwarze <schwarze@openbsd.org>.
* Released into the public domain.
*/
#include <string.h>
int
strcoll_l(const char *s1, const char *s2,
locale_t locale __attribute__((__unused__)))
{
return strcmp(s1, s2);
}

+ 52
- 23
src/lib/libc/string/strerror.3 View File

@ -1,4 +1,7 @@
.\" $OpenBSD: strerror.3,v 1.15 2017/09/05 03:16:13 schwarze Exp $
.\"
.\" Copyright (c) 1980, 1991 Regents of the University of California.
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
@ -29,46 +32,61 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $OpenBSD: strerror.3,v 1.14 2014/11/30 21:21:59 schwarze Exp $
.\"
.Dd $Mdocdate: November 30 2014 $
.Dd $Mdocdate: September 5 2017 $
.Dt STRERROR 3
.Os
.Sh NAME
.Nm strerror ,
.Nm strerror_l ,
.Nm strerror_r
.Nd get error message string
.Sh SYNOPSIS
.In string.h
.Ft char *
.Fn strerror "int errnum"
.Ft char *
.Fn strerror_l "int errnum" "locale_t locale"
.Ft int
.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen"
.Sh DESCRIPTION
The
.Fn strerror
and
.Fn strerror_r
functions map the error number
These functions map the error number
.Fa errnum
to a language-dependent error message string.
to an error message string.
.Pp
.Fn strerror
returns a string containing a maximum of
and
.Fn strerror_l
return a string containing a maximum of
.Dv NL_TEXTMAX
characters, including the trailing NUL.
This string is not to be modified by the calling program,
but may be overwritten by subsequent calls to
.Fn strerror .
This string is not to be modified by the calling program.
The string returned by
.Fn strerror
may be overwritten by subsequent calls to
.Fn strerror
in any thread.
The string returned by
.Fn strerror_l
may be overwritten by subsequent calls to
.Fn strerror_l
in the same thread.
.Pp
.Fn strerror_r
is a thread safe version of
.Fn strerror
that places the error message in the specified buffer
.Fa strerrbuf .
.Pp
On
.Ox ,
the global locale, the thread-specific locale, and the
.Fa locale
argument are ignored.
.Sh RETURN VALUES
.Fn strerror
returns a pointer to the error message string.
and
.Fn strerror_l
return a pointer to the error message string.
If an error occurs, the error code is stored in
.Va errno .
.Pp
@ -77,11 +95,16 @@ returns zero upon successful completion.
If an error occurs, the error code is stored in
.Va errno
and the error code is returned.
.Sh ERRORS
.Sh ENVIRONMENT
On other operating systems, the behaviour of
.Fn strerror
and
.Fn strerror_r
may fail if:
may depend on the
.Dv LC_MESSAGES
.Xr locale 1 .
.Sh ERRORS
All these functions may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
.Fa errnum
@ -91,7 +114,7 @@ The returned error string will consist of an error message that includes
.El
.Pp
.Fn strerror_r
may fail if:
may also fail if:
.Bl -tag -width Er
.It Bq Er ERANGE
The error message is larger than
@ -101,6 +124,7 @@ The message will be truncated to fit.
.El
.Sh SEE ALSO
.Xr intro 2 ,
.Xr newlocale 3 ,
.Xr perror 3 ,
.Xr setlocale 3
.Sh STANDARDS
@ -109,15 +133,20 @@ The
function conforms to
.St -isoC-99 .
The
.Fn strerror_l
and
.Fn strerror_r
function conforms to
functions conform to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn strerror
function first appeared in
.Bx 4.3 Reno .
The
function has been available since
.Bx 4.3 Reno ,
.Fn strerror_r
function first appeared in
.Ox 3.3 .
since
.Ox 3.3 ,
and
.Fn strerror_l
since
.Ox 6.2 .

+ 33
- 0
src/lib/libc/string/strerror_l.c View File

@ -0,0 +1,33 @@
/* $OpenBSD: strerror_l.c,v 1.1 2017/09/05 03:16:13 schwarze Exp $ */
/*
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <limits.h>
#include <string.h>
#include "thread_private.h"
char *
strerror_l(int errnum, locale_t locale)
{
static char sel_buf[NL_TEXTMAX];
_THREAD_PRIVATE_KEY(strerror_l);
char *p = _THREAD_PRIVATE(strerror_l, sel_buf, NULL);
return p == NULL ? "no buffer available in strerror_l" :
strerror_r(errnum, p, sizeof(sel_buf)) ?
"strerror_r failure" : p;
}

+ 40
- 17
src/lib/libc/string/strxfrm.3 View File

@ -1,4 +1,7 @@
.\" $OpenBSD: strxfrm.3,v 1.11 2017/09/05 03:16:13 schwarze Exp $
.\"
.\" Copyright (c) 1990, 1991 The Regents of the University of California.
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
@ -29,24 +32,27 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $OpenBSD: strxfrm.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
.\"
.Dd $Mdocdate: June 5 2013 $
.Dd $Mdocdate: September 5 2017 $
.Dt STRXFRM 3
.Os
.Sh NAME
.Nm strxfrm
.Nm strxfrm ,
.Nm strxfrm_l
.Nd transform a string under locale
.Sh SYNOPSIS
.In string.h
.Ft size_t
.Fn strxfrm "char *dst" "const char *src" "size_t n"
.Ft size_t
.Fn strxfrm_l "char *dst" "const char *src" "size_t n" "locale_t locale"
.Sh DESCRIPTION
The idea of
.Fn strxfrm
and
.Fn strxfrm_l
is to
.Dq un-localize
a string: the function transforms
a string: the functions transform
.Ar src ,
storing the result in
.Ar dst ,
@ -55,25 +61,42 @@ such that
on transformed strings returns what
.Xr strcoll 3
on the original untransformed strings would return.
.Pp
On
.Ox ,
both have the same effect as
.Xr strlcpy 3 ,
and the global locale, the thread-specific locale, and the
.Fa locale
argument are ignored.
.Sh ENVIRONMENT
On other operating systems, the behaviour of
.Fn strxfrm
may depend on the
.Dv LC_CTYPE
.Xr locale 1 .
.Sh SEE ALSO
.Xr bcmp 3 ,
.Xr memcmp 3 ,
.Xr newlocale 3 ,
.Xr setlocale 3 ,
.Xr strcasecmp 3 ,
.Xr strcmp 3 ,
.Xr strcoll 3
.Xr strcoll 3 ,
.Xr strlcpy 3 ,
.Xr wcsxfrm 3
.Sh STANDARDS
The
.Fn strxfrm
function conforms to
.St -ansiC .
.St -ansiC ,
and
.Fn strxfrm_l
to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn strxfrm
function first appeared in
.Bx 4.3 Reno .
.Sh BUGS
Since locales are not fully implemented on
.Ox ,
.Fn strxfrm
just returns a copy of the original string.
function has been available since
.Bx 4.3 Reno ,
and
.Fn strxfrm_l
since
.Ox 6.2 .

+ 14
- 0
src/lib/libc/string/strxfrm_l.c View File

@ -0,0 +1,14 @@
/* $OpenBSD: strxfrm_l.c,v 1.1 2017/09/05 03:16:14 schwarze Exp $ */
/*
* Written in 2017 by Ingo Schwarze <schwarze@openbsd.org>.
* Released into the public domain.
*/
#include <string.h>
size_t
strxfrm_l(char *dst, const char *src, size_t n,
locale_t locale __attribute__((__unused__)))
{
return strxfrm(dst, src, n);
}

+ 58
- 18
src/lib/libc/string/wcscasecmp.3 View File

@ -1,7 +1,8 @@
.\" $OpenBSD: wcscasecmp.3,v 1.4 2013/07/16 15:21:11 schwarze Exp $
.\" $OpenBSD: wcscasecmp.3,v 1.5 2017/09/05 03:16:14 schwarze Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Chris Torek.
@ -31,25 +32,43 @@
.\"
.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
.\"
.Dd $Mdocdate: July 16 2013 $
.Dd $Mdocdate: September 5 2017 $
.Dt WCSCASECMP 3
.Os
.Sh NAME
.Nm wcscasecmp ,
.Nm wcsncasecmp
.Nm wcscasecmp_l ,
.Nm wcsncasecmp ,
.Nm wcsncasecmp_l
.Nd compare wide strings, ignoring case
.Sh SYNOPSIS
.In wchar.h
.Ft int
.Fn wcscasecmp "const wchar_t *s1" "const wchar_t *s2"
.Fo wcscasecmp
.Fa "const wchar_t *s1"
.Fa "const wchar_t *s2"
.Fc
.Ft int
.Fn wcsncasecmp "const wchar_t *s1" "const wchar_t *s2" "size_t len"
.Fo wcscasecmp_l
.Fa "const wchar_t *s1"
.Fa "const wchar_t *s2"
.Fa "locale_t locale"
.Fc
.Ft int
.Fo wcsncasecmp
.Fa "const wchar_t *s1"
.Fa "const wchar_t *s2"
.Fa "size_t len"
.Fc
.Ft int
.Fo wcsncasecmp_l
.Fa "const wchar_t *s1"
.Fa "const wchar_t *s2"
.Fa "size_t len"
.Fa "locale_t locale"
.Fc
.Sh DESCRIPTION
The
.Fn wcscasecmp
and
.Fn wcsncasecmp
functions compare the wide strings
These functions compare the wide strings
.Fa s1
and
.Fa s2
@ -61,28 +80,49 @@ is lexicographically greater than, equal to, or less than
after translation of each corresponding wide character to lower case.
The wide strings themselves are not modified.
.Pp
For the translation to lower case,
.Fn wcscasecmp
and
.Fn wcsncasecmp
use the thread-specific locale as defined with
.Xr uselocale 3 ,
falling back to the global locale defined with
.Xr setlocale 3 .
.Fn wcscasecmp_l
and
.Fn wcsncasecmp_l
use the
.Fa locale
argument instead.
.Pp
.Fn wcsncasecmp
compares at most
and
.Fn wcsncasecmp_l
compare at most
.Fa len
wide characters.
.Sh SEE ALSO
.Xr newlocale 3 ,
.Xr setlocale 3 ,
.Xr strcasecmp 3 ,
.Xr wcscmp 3 ,
.Xr wmemcmp 3
.Sh STANDARDS
The
.Fn wcscasecmp
and
.Fn wcsncasecmp
functions conform to
These functions conform to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn wcscasecmp
and
.Fn wcsncasecmp
functions first appeared in
.Ox 5.0 .
functions have been available since
.Ox 5.0 ,
and
.Fn wcscasecmp_l
and
.Fn wcsncasecmp_l
since
.Ox 6.2 .
.Sh AUTHORS
The
.Ox


+ 63
- 0
src/lib/libc/string/wcscasecmp_l.c View File

@ -0,0 +1,63 @@
/* $OpenBSD: wcscasecmp_l.c,v 1.1 2017/09/05 03:16:14 schwarze Exp $ */
/*
* Copyright (c) 2011 Marc Espie
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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 OPENBSD PROJECT 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 OPENBSD
* PROJECT 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 <wchar.h>
#include <wctype.h>
#include "locale/runetype.h"
int
wcscasecmp_l(const wchar_t *s1, const wchar_t *s2, locale_t locale)
{
wchar_t l1, l2;
while ((l1 = towlower_l(*s1++, locale)) ==
(l2 = towlower_l(*s2++, locale))) {
if (l1 == 0)
return (0);
}
/* XXX assumes wchar_t = int */
return ((rune_t)l1 - (rune_t)l2);
}
int
wcsncasecmp_l(const wchar_t *s1, const wchar_t *s2, size_t n, locale_t locale)
{
wchar_t l1, l2;
if (n == 0)
return (0);
do {
if (((l1 = towlower_l(*s1++, locale))) !=
(l2 = towlower_l(*s2++, locale))) {
/* XXX assumes wchar_t = int */
return ((rune_t)l1 - (rune_t)l2);
}
if (l1 == 0)
break;
} while (--n != 0);
return (0);
}

Loading…
Cancel
Save