From owner-svn-src-all@FreeBSD.ORG Sun Mar 4 15:31:14 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 10EDA106566C; Sun, 4 Mar 2012 15:31:14 +0000 (UTC) (envelope-from theraven@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id F1D438FC08; Sun, 4 Mar 2012 15:31:13 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q24FVDdb040916; Sun, 4 Mar 2012 15:31:13 GMT (envelope-from theraven@svn.freebsd.org) Received: (from theraven@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q24FVDm5040897; Sun, 4 Mar 2012 15:31:13 GMT (envelope-from theraven@svn.freebsd.org) Message-Id: <201203041531.q24FVDm5040897@svn.freebsd.org> From: David Chisnall Date: Sun, 4 Mar 2012 15:31:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232498 - in head: etc/mtree include include/xlocale lib/libc/locale sys/sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 Mar 2012 15:31:14 -0000 Author: theraven Date: Sun Mar 4 15:31:13 2012 New Revision: 232498 URL: http://svn.freebsd.org/changeset/base/232498 Log: Reapply 227753 (xlocale cleanup), plus some fixes so that it passes build universe with gcc. Approved by: dim (mentor) Added: head/include/xlocale/ - copied from r231713, head/include/xlocale/ Deleted: head/include/_xlocale_ctype.h Modified: head/etc/mtree/BSD.include.dist head/include/Makefile head/include/ctype.h head/include/langinfo.h head/include/locale.h head/include/runetype.h head/include/string.h head/include/time.h head/include/wchar.h head/include/wctype.h head/include/xlocale.h head/include/xlocale/_ctype.h head/lib/libc/locale/Symbol.map head/lib/libc/locale/setrunelocale.c head/lib/libc/locale/table.c head/lib/libc/locale/xlocale.c head/lib/libc/locale/xlocale_private.h head/sys/sys/cdefs.h Modified: head/etc/mtree/BSD.include.dist ============================================================================== --- head/etc/mtree/BSD.include.dist Sun Mar 4 15:25:11 2012 (r232497) +++ head/etc/mtree/BSD.include.dist Sun Mar 4 15:31:13 2012 (r232498) @@ -329,4 +329,6 @@ .. vm .. + xlocale + .. .. Modified: head/include/Makefile ============================================================================== --- head/include/Makefile Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/Makefile Sun Mar 4 15:31:13 2012 (r232498) @@ -6,7 +6,7 @@ .include CLEANFILES= osreldate.h version vers.c -SUBDIR= arpa gssapi protocols rpcsvc rpc +SUBDIR= arpa gssapi protocols rpcsvc rpc xlocale INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \ db.h \ dirent.h dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \ @@ -24,7 +24,7 @@ INCS= a.out.h ar.h assert.h bitstring.h strings.h sysexits.h tar.h termios.h tgmath.h \ time.h timeconv.h timers.h ttyent.h \ ulimit.h unistd.h utime.h utmpx.h uuid.h varargs.h vis.h \ - wchar.h wctype.h wordexp.h xlocale.h _xlocale_ctype.h + wchar.h wctype.h wordexp.h xlocale.h MHDRS= float.h floatingpoint.h stdarg.h Modified: head/include/ctype.h ============================================================================== --- head/include/ctype.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/ctype.h Sun Mar 4 15:31:13 2012 (r232498) @@ -78,6 +78,10 @@ int isphonogram(int); int isrune(int); int isspecial(int); #endif + +#if __POSIX_VISIBLE >= 200809 +#include +#endif __END_DECLS #ifndef __cplusplus Modified: head/include/langinfo.h ============================================================================== --- head/include/langinfo.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/langinfo.h Sun Mar 4 15:31:13 2012 (r232498) @@ -130,6 +130,10 @@ typedef __nl_item nl_item; __BEGIN_DECLS char *nl_langinfo(nl_item); + +#if __POSIX_VISIBLE >= 200809 +#include +#endif __END_DECLS #endif /* !_LANGINFO_H_ */ Modified: head/include/locale.h ============================================================================== --- head/include/locale.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/locale.h Sun Mar 4 15:31:13 2012 (r232498) @@ -77,54 +77,11 @@ struct lconv { __BEGIN_DECLS struct lconv *localeconv(void); char *setlocale(int, const char *); -__END_DECLS #if __POSIX_VISIBLE >= 200809 - -#define LC_COLLATE_MASK (1<<0) -#define LC_CTYPE_MASK (1<<1) -#define LC_MESSAGES_MASK (1<<2) -#define LC_MONETARY_MASK (1<<3) -#define LC_NUMERIC_MASK (1<<4) -#define LC_TIME_MASK (1<<5) -#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \ - LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK) - -#define LC_GLOBAL_LOCALE ((locale_t)-1) - -__BEGIN_DECLS - -typedef struct _xlocale *locale_t; -/** - * Creates a new locale. - */ -locale_t newlocale(int mask, const char *locale, locale_t base); - -/** - * Returns an identical duplicate of the passed locale. The returned locale - * must be freed with freelocale(). The returned locale will share components - * with the original. - */ -locale_t duplocale(locale_t base); -/* - * Free a locale_t. This is quite a poorly named function. It actually - * disclaims a reference to a locale_t, rather than freeing it. - */ -int freelocale(locale_t loc); - -/* - * Returns the name of the locale for a particular component of a locale_t. - */ -const char *querylocale(int mask, locale_t loc); - -/* - * Installs the specified locale_t as this thread's locale. - */ -locale_t uselocale(locale_t loc); - +#include +#endif __END_DECLS -#endif /* __POSIX_VISIBLE >= 200809 */ - #endif /* _LOCALE_H_ */ Modified: head/include/runetype.h ============================================================================== --- head/include/runetype.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/runetype.h Sun Mar 4 15:31:13 2012 (r232498) @@ -85,11 +85,21 @@ typedef struct { #define _RUNE_MAGIC_1 "RuneMagi" /* Indicates version 0 of RuneLocale */ __BEGIN_DECLS extern const _RuneLocale _DefaultRuneLocale; -__attribute__((deprecated)) -extern _RuneLocale *_CurrentRuneLocale; -/* TODO: This is called quite a lot, so we should use a __thread variable when - * it's available. */ -extern _RuneLocale *__getCurrentRuneLocale(void); +extern const _RuneLocale *_CurrentRuneLocale; +#if defined(__NO_TLS) || defined(__RUNETYPE_INTERNAL) +extern const _RuneLocale *__getCurrentRuneLocale(void); +#else +extern _Thread_local const _RuneLocale *_ThreadRuneLocale; +static inline const _RuneLocale *__getCurrentRuneLocale(void) +{ + + if (_ThreadRuneLocale) + return _ThreadRuneLocale; + if (_CurrentRuneLocale) + return _CurrentRuneLocale; + return &_DefaultRuneLocale; +} +#endif /* __NO_TLS || __RUNETYPE_INTERNAL */ #define _CurrentRuneLocale (__getCurrentRuneLocale()) __END_DECLS Modified: head/include/string.h ============================================================================== --- head/include/string.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/string.h Sun Mar 4 15:31:13 2012 (r232498) @@ -132,6 +132,10 @@ void swab(const void * __restrict, void #endif /* _SWAB_DECLARED */ #endif /* __BSD_VISIBLE */ + +#if __POSIX_VISIBLE >= 200809 +#include +#endif __END_DECLS #endif /* _STRING_H_ */ Modified: head/include/time.h ============================================================================== --- head/include/time.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/time.h Sun Mar 4 15:31:13 2012 (r232498) @@ -183,6 +183,10 @@ void tzsetwall(void); time_t timelocal(struct tm * const); time_t timegm(struct tm * const); #endif /* __BSD_VISIBLE */ + +#if __POSIX_VISIBLE >= 200809 +#include +#endif __END_DECLS #endif /* !_TIME_H_ */ Modified: head/include/wchar.h ============================================================================== --- head/include/wchar.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/wchar.h Sun Mar 4 15:31:13 2012 (r232498) @@ -224,6 +224,10 @@ wchar_t *fgetwln(FILE * __restrict, size size_t wcslcat(wchar_t *, const wchar_t *, size_t); size_t wcslcpy(wchar_t *, const wchar_t *, size_t); #endif + +#if __POSIX_VISIBLE >= 200809 +#include +#endif __END_DECLS #endif /* !_WCHAR_H_ */ Modified: head/include/wctype.h ============================================================================== --- head/include/wctype.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/wctype.h Sun Mar 4 15:31:13 2012 (r232498) @@ -87,6 +87,11 @@ wint_t iswrune(wint_t); wint_t iswspecial(wint_t); wint_t nextwctype(wint_t, wctype_t); #endif + +#if __POSIX_VISIBLE >= 200809 +#define _XLOCALE_WCTYPES 1 +#include +#endif /* __POSIX_VISIBLE >= 200809 */ __END_DECLS #ifndef __cplusplus Modified: head/include/xlocale.h ============================================================================== --- head/include/xlocale.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/include/xlocale.h Sun Mar 4 15:31:13 2012 (r232498) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011 The FreeBSD Foundation + * Copyright (c) 2011, 2012 The FreeBSD Foundation * All rights reserved. * * This software was developed by David Chisnall under sponsorship from @@ -8,16 +8,16 @@ * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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) @@ -33,225 +33,52 @@ #define _XLOCALE_H_ #include - __BEGIN_DECLS +#include -/* - * Extended locale versions of the locale-aware functions from string.h. - * - * Include before to expose these. - */ #ifdef _STRING_H_ -int strcoll_l(const char *, const char *, locale_t); -size_t strxfrm_l(char *, const char *, size_t, locale_t); -int strcasecmp_l(const char *, const char *, locale_t); -char *strcasestr_l(const char *, const char *, locale_t); -int strncasecmp_l(const char *, const char *, size_t, locale_t); +#include #endif -/* - * Extended locale versions of the locale-aware functions from inttypes.h. - * - * Include before to expose these. - */ + #ifdef _INTTYPES_H_ -intmax_t -strtoimax_l(const char * __restrict, char ** __restrict, int, locale_t); -uintmax_t -strtoumax_l(const char * __restrict, char ** __restrict, int, locale_t); -intmax_t -wcstoimax_l(const wchar_t * __restrict, wchar_t ** __restrict, int , locale_t); -uintmax_t -wcstoumax_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); +#include #endif -/* - * Extended locale versions of the locale-aware functions from monetary.h. - * - * Include before to expose these. - */ + #ifdef _MONETARY_H_ -ssize_t strfmon_l(char *, size_t, locale_t, const char *, ...) -# if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 - __attribute__((__format__ (__strfmon__, 4, 5))) -# endif - ; +#include #endif -/* - * Extended locale versions of the locale-aware functions from stdlib.h. - * - * Include before to expose these. - */ #ifdef _STDLIB_H_ -double atof_l(const char *, locale_t); -int atoi_l(const char *, locale_t); -long atol_l(const char *, locale_t); -long long atoll_l(const char *, locale_t); -int mblen_l(const char *, size_t, locale_t); -size_t -mbstowcs_l(wchar_t * __restrict, const char * __restrict, size_t, locale_t); -int -mbtowc_l(wchar_t * __restrict, const char * __restrict, size_t, locale_t); -double strtod_l(const char *, char **, locale_t); -float strtof_l(const char *, char **, locale_t); -long strtol_l(const char *, char **, int, locale_t); -long double strtold_l(const char *, char **, locale_t); -long long strtoll_l(const char *, char **, int, locale_t); -unsigned long strtoul_l(const char *, char **, int, locale_t); -unsigned long long strtoull_l(const char *, char **, int, locale_t); -size_t -wcstombs_l(char * __restrict, const wchar_t * __restrict, size_t, locale_t); -int wctomb_l(char *, wchar_t, locale_t); - -int ___mb_cur_max_l(locale_t); -#define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) - +#include #endif -/* - * Extended locale versions of the locale-aware functions from time.h. - * - * Include before to expose these. - */ + #ifdef _TIME_H_ -size_t -strftime_l(char * __restrict, size_t, const char * __restrict, const - struct tm * __restrict, locale_t) -# if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 - __attribute__((__format__ (__strftime__, 3, 0))) -# endif - ; -char * -strptime_l(const char * __restrict, const char * __restrict, - struct tm * __restrict, locale_t); +#include #endif + #ifdef _LANGINFO_H_ -char *nl_langinfo_l(nl_item, locale_t); +#include #endif + #ifdef _CTYPE_H_ -#include <_xlocale_ctype.h> +#include #endif + #ifdef _WCTYPE_H_ -#define XLOCALE_WCTYPES 1 -#include <_xlocale_ctype.h> +#define _XLOCALE_WCTYPES 1 +#include #endif #ifdef _STDIO_H_ -int fprintf_l(FILE * __restrict, locale_t, const char * __restrict, ...) - __printflike(3, 4); -int fscanf_l(FILE * __restrict, locale_t, const char * __restrict, ...) - __scanflike(3, 4); -int printf_l(locale_t, const char * __restrict, ...) __printflike(2, 3); -int scanf_l(locale_t, const char * __restrict, ...) __scanflike(2, 3); -int sprintf_l(char * __restrict, locale_t, const char * __restrict, ...) - __printflike(3, 4); -int sscanf_l(const char * __restrict, locale_t, const char * __restrict, ...) - __scanflike(3, 4); -int vfprintf_l(FILE * __restrict, locale_t, const char * __restrict, __va_list) - __printflike(3, 0); -int vprintf_l(locale_t, const char * __restrict, __va_list) __printflike(2, 0); -int vsprintf_l(char * __restrict, locale_t, const char * __restrict, __va_list) - __printflike(3, 0); - -int snprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, - ...) __printflike(4, 5); -int vfscanf_l(FILE * __restrict, locale_t, const char * __restrict, __va_list) - __scanflike(3, 0); -int vscanf_l(locale_t, const char * __restrict, __va_list) __scanflike(2, 0); -int vsnprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, - __va_list) __printflike(4, 0); -int vsscanf_l(const char * __restrict, locale_t, const char * __restrict, - __va_list) __scanflike(3, 0); -int dprintf_l(int, locale_t, const char * __restrict, ...) __printflike(3, 4); -int vdprintf_l(int, locale_t, const char * __restrict, __va_list) - __printflike(3, 0); -int asprintf_l(char **, locale_t, const char *, ...) __printflike(3, 4); -int vasprintf_l(char **, locale_t, const char *, __va_list) __printflike(3, 0); +#include #endif -#ifdef _WCHAR_H_ -wint_t btowc_l(int, locale_t); -wint_t fgetwc_l(FILE *, locale_t); -wchar_t * -fgetws_l(wchar_t * __restrict, int, FILE * __restrict, locale_t); -wint_t fputwc_l(wchar_t, FILE *, locale_t); -int -fputws_l(const wchar_t * __restrict, FILE * __restrict, locale_t); -int -fwprintf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, - ...); -int -fwscanf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, ...); -wint_t getwc_l(FILE *, locale_t); -wint_t getwchar_l(locale_t); -size_t -mbrlen_l(const char * __restrict, size_t, mbstate_t * __restrict, locale_t); -size_t -mbrtowc_l(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); -int mbsinit_l(const mbstate_t *, locale_t); -size_t -mbsrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t, - mbstate_t * __restrict, locale_t); -wint_t putwc_l(wchar_t, FILE *, locale_t); -wint_t putwchar_l(wchar_t, locale_t); -int -swprintf_l(wchar_t * __restrict, size_t n, locale_t, - const wchar_t * __restrict, ...); -int -swscanf_l(const wchar_t * __restrict, locale_t, const wchar_t * __restrict, - ...); -wint_t ungetwc_l(wint_t, FILE *, locale_t); -int -vfwprintf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, - __va_list); -int -vswprintf_l(wchar_t * __restrict, size_t n, locale_t, - const wchar_t * __restrict, __va_list); -int vwprintf_l(locale_t, const wchar_t * __restrict, __va_list); -size_t -wcrtomb_l(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); -int wcscoll_l(const wchar_t *, const wchar_t *, locale_t); -size_t -wcsftime_l(wchar_t * __restrict, size_t, const wchar_t * __restrict, - const struct tm * __restrict, locale_t); -size_t -wcsrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t, - mbstate_t * __restrict, locale_t); -double wcstod_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t); -long -wcstol_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); -unsigned long -wcstoul_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); -int wcswidth_l(const wchar_t *, size_t, locale_t); -size_t -wcsxfrm_l(wchar_t * __restrict, const wchar_t * __restrict, size_t, locale_t); -int wctob_l(wint_t, locale_t); -int wcwidth_l(wchar_t, locale_t); -int wprintf_l(locale_t, const wchar_t * __restrict, ...); -int wscanf_l(locale_t, const wchar_t * __restrict, ...); - -int -vfwscanf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, - __va_list); -int vswscanf_l(const wchar_t * __restrict, locale_t, -const wchar_t *__restrict, __va_list); -int vwscanf_l(locale_t, const wchar_t * __restrict, __va_list); -float wcstof_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t); -long double -wcstold_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t); -long long -wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); -unsigned long long -wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); -size_t -mbsnrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t, size_t, - mbstate_t * __restrict, locale_t); -int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t); -int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t); -size_t -wcsnrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t, size_t, - mbstate_t * __restrict, locale_t); +#ifdef _WCHAR_H_ +#include #endif + + struct lconv *localeconv_l(locale_t); __END_DECLS Modified: head/include/xlocale/_ctype.h ============================================================================== --- head/include/xlocale/_ctype.h Tue Feb 14 21:36:55 2012 (r231713) +++ head/include/xlocale/_ctype.h Sun Mar 4 15:31:13 2012 (r232498) @@ -44,7 +44,8 @@ typedef struct _xlocale *locale_t; #endif -#ifndef _XLOCALE_CTYPE_H_ +#ifndef _XLOCALE_RUN_FUNCTIONS_DEFINED +#define _XLOCALE_RUN_FUNCTIONS_DEFINED 1 unsigned long ___runetype_l(__ct_rune_t, locale_t) __pure; __ct_rune_t ___tolower_l(__ct_rune_t, locale_t) __pure; __ct_rune_t ___toupper_l(__ct_rune_t, locale_t) __pure; @@ -83,8 +84,9 @@ __istype_l(__ct_rune_t _c, unsigned long } #define XLOCALE_ISCTYPE(fname, cat) \ - _XLOCALE_INLINE int isw##fname##_l(int c, locale_t l)\ - { return __istype_l(c, cat, l); } + _XLOCALE_INLINE int isw##fname##_l(int, locale_t);\ + _XLOCALE_INLINE int isw##fname##_l(int __c, locale_t __l)\ + { return __istype_l(__c, cat, __l); } #else static __inline int __sbmaskrune_l(__ct_rune_t _c, unsigned long _f, locale_t locale) @@ -102,6 +104,7 @@ __sbistype_l(__ct_rune_t _c, unsigned lo } #define XLOCALE_ISCTYPE(fname, cat) \ + _XLOCALE_INLINE int is##fname##_l(int c, locale_t l); \ _XLOCALE_INLINE int is##fname##_l(int c, locale_t l)\ { return __sbistype_l(c, cat, l); } #endif @@ -127,55 +130,63 @@ XLOCALE_ISCTYPE(xdigit, _CTYPE_X) #undef XLOCALE_ISCTYPE #ifdef _XLOCALE_WCTYPES -_XLOCALE_INLINE int towlower_l(int c, locale_t locale) +_XLOCALE_INLINE int towlower_l(int, locale_t); +_XLOCALE_INLINE int __wcwidth_l(__ct_rune_t, locale_t); +_XLOCALE_INLINE int towupper_l(int, locale_t); + +_XLOCALE_INLINE int towlower_l(int __c, locale_t __l) { int mb_sb_limit; - _RuneLocale *runes = __runes_for_locale(locale, &mb_sb_limit); - return (c < 0 || c >= _CACHED_RUNES) ? ___tolower_l(c, locale) : - runes->__maplower[c]; + _RuneLocale *__runes = __runes_for_locale(__l, &mb_sb_limit); + return (__c < 0 || __c >= _CACHED_RUNES) ? ___tolower_l(__c, __l) : + __runes->__maplower[__c]; } -_XLOCALE_INLINE int towupper_l(int c, locale_t locale) +_XLOCALE_INLINE int towupper_l(int __c, locale_t __l) { int mb_sb_limit; - _RuneLocale *runes = __runes_for_locale(locale, &mb_sb_limit); - return (c < 0 || c >= _CACHED_RUNES) ? ___toupper_l(c, locale) : - runes->__mapupper[c]; + _RuneLocale *__runes = __runes_for_locale(__l, &mb_sb_limit); + return (__c < 0 || __c >= _CACHED_RUNES) ? ___toupper_l(__c, __l) : + __runes->__mapupper[__c]; } _XLOCALE_INLINE int -__wcwidth_l(__ct_rune_t _c, locale_t locale) +__wcwidth_l(__ct_rune_t _c, locale_t __l) { unsigned int _x; if (_c == 0) return (0); - _x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, locale); + _x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, __l); if ((_x & _CTYPE_SWM) != 0) return ((_x & _CTYPE_SWM) >> _CTYPE_SWS); return ((_x & _CTYPE_R) != 0 ? 1 : -1); } -int iswctype_l(wint_t wc, wctype_t charclass, locale_t locale); -wctype_t wctype_l(const char *property, locale_t locale); -wint_t towctrans_l(wint_t wc, wctrans_t desc, locale_t locale); -wint_t nextwctype_l(wint_t wc, wctype_t wct, locale_t locale); -wctrans_t wctrans_l(const char *charclass, locale_t locale); +int iswctype_l(wint_t __wc, wctype_t __charclass, locale_t __l); +wctype_t wctype_l(const char *property, locale_t __l); +wint_t towctrans_l(wint_t __wc, wctrans_t desc, locale_t __l); +wint_t nextwctype_l(wint_t __wc, wctype_t wct, locale_t __l); +wctrans_t wctrans_l(const char *__charclass, locale_t __l); #undef _XLOCALE_WCTYPES #else -_XLOCALE_INLINE int digittoint_l(int c, locale_t locale) -{ return __sbmaskrune_l((c), 0xFF, locale); } - -_XLOCALE_INLINE int tolower_l(int c, locale_t locale) -{ - int mb_sb_limit; - _RuneLocale *runes = __runes_for_locale(locale, &mb_sb_limit); - return (c < 0 || c >= mb_sb_limit) ? c : - runes->__maplower[c]; -} -_XLOCALE_INLINE int toupper_l(int c, locale_t locale) -{ - int mb_sb_limit; - _RuneLocale *runes = __runes_for_locale(locale, &mb_sb_limit); - return (c < 0 || c >= mb_sb_limit) ? c : - runes->__mapupper[c]; +_XLOCALE_INLINE int digittoint_l(int, locale_t); +_XLOCALE_INLINE int tolower_l(int, locale_t); +_XLOCALE_INLINE int toupper_l(int, locale_t); + +_XLOCALE_INLINE int digittoint_l(int __c, locale_t __l) +{ return __sbmaskrune_l((__c), 0xFF, __l); } + +_XLOCALE_INLINE int tolower_l(int __c, locale_t __l) +{ + int __limit; + _RuneLocale *__runes = __runes_for_locale(__l, &__limit); + return (__c < 0 || __c >= __limit) ? __c : + __runes->__maplower[__c]; +} +_XLOCALE_INLINE int toupper_l(int __c, locale_t __l) +{ + int __limit; + _RuneLocale *__runes = __runes_for_locale(__l, &__limit); + return (__c < 0 || __c >= __limit) ? __c : + __runes->__mapupper[__c]; } #endif #endif /* (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \ Modified: head/lib/libc/locale/Symbol.map ============================================================================== --- head/lib/libc/locale/Symbol.map Sun Mar 4 15:25:11 2012 (r232497) +++ head/lib/libc/locale/Symbol.map Sun Mar 4 15:31:13 2012 (r232498) @@ -194,6 +194,7 @@ FBSD_1.3 { wcstoull_l; wcstoumax_l; __runes_for_locale; + _ThreadRuneLocale; }; FBSDprivate_1.0 { Modified: head/lib/libc/locale/setrunelocale.c ============================================================================== --- head/lib/libc/locale/setrunelocale.c Sun Mar 4 15:25:11 2012 (r232497) +++ head/lib/libc/locale/setrunelocale.c Sun Mar 4 15:31:13 2012 (r232498) @@ -38,6 +38,8 @@ #include __FBSDID("$FreeBSD$"); +#define __RUNETYPE_INTERNAL 1 + #include #include #include @@ -50,6 +52,15 @@ __FBSDID("$FreeBSD$"); #include "mblocal.h" #include "setlocale.h" +#undef _CurrentRuneLocale +extern _RuneLocale const *_CurrentRuneLocale; +#ifndef __NO_TLS +/* + * A cached version of the runes for this thread. Used by ctype.h + */ +_Thread_local const _RuneLocale *_ThreadRuneLocale; +#endif + extern int __mb_sb_limit; extern _RuneLocale *_Read_RuneMagi(FILE *); @@ -72,7 +83,8 @@ static void destruct_ctype(void *v) free(l->runes); free(l); } -_RuneLocale *__getCurrentRuneLocale(void) + +const _RuneLocale *__getCurrentRuneLocale(void) { return XLOCALE_CTYPE(__get_locale())->runes; } @@ -168,9 +180,24 @@ __wrap_setrunelocale(const char *locale) } __mb_cur_max = __xlocale_global_ctype.__mb_cur_max; __mb_sb_limit = __xlocale_global_ctype.__mb_sb_limit; + _CurrentRuneLocale = __xlocale_global_ctype.runes; return (_LDP_LOADED); } -void *__ctype_load(const char *locale, locale_t unused) + +#ifndef __NO_TLS +void +__set_thread_rune_locale(locale_t loc) { + + if (loc == NULL) { + _ThreadRuneLocale = &_DefaultRuneLocale; + } else { + _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes; + } +} +#endif + +void * +__ctype_load(const char *locale, locale_t unused) { struct xlocale_ctype *l = calloc(sizeof(struct xlocale_ctype), 1); l->header.header.destructor = destruct_ctype; Modified: head/lib/libc/locale/table.c ============================================================================== --- head/lib/libc/locale/table.c Sun Mar 4 15:25:11 2012 (r232497) +++ head/lib/libc/locale/table.c Sun Mar 4 15:31:13 2012 (r232498) @@ -251,7 +251,7 @@ const _RuneLocale _DefaultRuneLocale = { }; #undef _CurrentRuneLocale -_RuneLocale *_CurrentRuneLocale = (_RuneLocale*)&_DefaultRuneLocale; +const _RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale; _RuneLocale * __runes_for_locale(locale_t locale, int *mb_sb_limit) Modified: head/lib/libc/locale/xlocale.c ============================================================================== --- head/lib/libc/locale/xlocale.c Sun Mar 4 15:25:11 2012 (r232497) +++ head/lib/libc/locale/xlocale.c Sun Mar 4 15:31:13 2012 (r232498) @@ -6,17 +6,18 @@ * the FreeBSD Foundation. * * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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) @@ -31,6 +32,7 @@ #include #include #include +#include #include "libc_private.h" #include "xlocale_private.h" @@ -50,6 +52,17 @@ extern struct xlocale_component __xlocal */ extern struct xlocale_component __xlocale_C_collate; extern struct xlocale_component __xlocale_C_ctype; + +#ifndef __NO_TLS +/* + * The locale for this thread. + */ +_Thread_local locale_t __thread_locale; +#endif +/* + * Flag indicating that one or more per-thread locales exist. + */ +int __has_thread_locale; /* * Private functions in setlocale.c. */ @@ -103,6 +116,7 @@ static locale_t thread_local_locale; static void init_key(void) { + pthread_key_create(&locale_info_key, xlocale_release); pthread_setspecific(locale_info_key, (void*)42); if (pthread_getspecific(locale_info_key) == (void*)42) { @@ -110,6 +124,8 @@ static void init_key(void) } else { fake_tls = 1; } + /* At least one per-thread locale has now been set. */ + __has_thread_locale = 1; __detect_path_locale(); } @@ -118,12 +134,14 @@ static pthread_once_t once_control = PTH static locale_t get_thread_locale(void) { + _once(&once_control, init_key); return (fake_tls ? thread_local_locale : pthread_getspecific(locale_info_key)); } +#ifdef __NO_TLS locale_t __get_locale(void) { @@ -131,11 +149,13 @@ __get_locale(void) return (l ? l : &__xlocale_global_locale); } +#endif static void set_thread_locale(locale_t loc) { - pthread_once(&once_control, init_key); + + _once(&once_control, init_key); if (NULL != loc) { xlocale_retain((struct xlocale_refcounted*)loc); @@ -149,6 +169,10 @@ set_thread_locale(locale_t loc) } else { pthread_setspecific(locale_info_key, loc); } +#ifndef __NO_TLS + __thread_locale = loc; + __set_thread_rune_locale(loc); +#endif } /** @@ -159,6 +183,7 @@ static void destruct_locale(void *l) { locale_t loc = l; + for (int type=0 ; typecomponents[type]) { xlocale_release(loc->components[type]); @@ -177,6 +202,7 @@ static locale_t alloc_locale(void) { locale_t new = calloc(sizeof(struct _xlocale), 1); + new->header.destructor = destruct_locale; new->monetary_locale_changed = 1; new->numeric_locale_changed = 1; @@ -193,19 +219,23 @@ copyflags(locale_t new, locale_t old) static int dupcomponent(int type, locale_t base, locale_t new) { - /* Always copy from the global locale, since it has mutable components. */ + /* Always copy from the global locale, since it has mutable components. + */ struct xlocale_component *src = base->components[type]; + if (&__xlocale_global_locale == base) { new->components[type] = constructors[type](src->locale, new); if (new->components[type]) { - strncpy(new->components[type]->locale, src->locale, ENCODING_LEN); + strncpy(new->components[type]->locale, src->locale, + ENCODING_LEN); } } else if (base->components[type]) { new->components[type] = xlocale_retain(base->components[type]); } else { - /* If the component was NULL, return success - if base is a valid - * locale then the flag indicating that this isn't present should be - * set. If it isn't a valid locale, then we're stuck anyway. */ + /* If the component was NULL, return success - if base is a + * valid locale then the flag indicating that this isn't + * present should be set. If it isn't a valid locale, then + * we're stuck anyway. */ return 1; } return (0 != new->components[type]); @@ -244,9 +274,11 @@ locale_t newlocale(int mask, const char if (useenv) { realLocale = __get_locale_env(type); } - new->components[type] = constructors[type](realLocale, new); + new->components[type] = + constructors[type](realLocale, new); if (new->components[type]) { - strncpy(new->components[type]->locale, realLocale, ENCODING_LEN); + strncpy(new->components[type]->locale, + realLocale, ENCODING_LEN); } else { success = 0; break; @@ -319,7 +351,7 @@ const char *querylocale(int mask, locale return (NULL); if (loc->components[type]) return (loc->components[type]->locale); - return "C"; + return ("C"); } /* Modified: head/lib/libc/locale/xlocale_private.h ============================================================================== --- head/lib/libc/locale/xlocale_private.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/lib/libc/locale/xlocale_private.h Sun Mar 4 15:31:13 2012 (r232498) @@ -8,16 +8,16 @@ * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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) @@ -85,14 +85,14 @@ struct _xlocale { struct xlocale_refcounted header; /** Components for the locale. */ struct xlocale_component *components[XLC_LAST]; - /** Flag indicating if components[XLC_MONETARY] has changed since the last - * call to localeconv_l() with this locale. */ + /** Flag indicating if components[XLC_MONETARY] has changed since the + * last call to localeconv_l() with this locale. */ int monetary_locale_changed; /** Flag indicating whether this locale is actually using a locale for * LC_MONETARY (1), or if it should use the C default instead (0). */ int using_monetary_locale; - /** Flag indicating if components[XLC_NUMERIC] has changed since the last - * call to localeconv_l() with this locale. */ + /** Flag indicating if components[XLC_NUMERIC] has changed since the + * last call to localeconv_l() with this locale. */ int numeric_locale_changed; /** Flag indicating whether this locale is actually using a locale for * LC_NUMERIC (1), or if it should use the C default instead (0). */ @@ -170,12 +170,38 @@ extern struct _xlocale __xlocale_global_ extern struct _xlocale __xlocale_C_locale; /** + * Caches the rune table in TLS for fast access. + */ +void __set_thread_rune_locale(locale_t loc); +/** + * Flag indicating whether a per-thread locale has been set. If no per-thread + * locale has ever been set, then we always use the global locale. + */ +extern int __has_thread_locale; +#ifndef __NO_TLS +/** + * The per-thread locale. Avoids the need to use pthread lookup functions when + * getting the per-thread locale. + */ +extern _Thread_local locale_t __thread_locale; + +/** * Returns the current locale for this thread, or the global locale if none is * set. The caller does not have to free the locale. The return value from * this call is not guaranteed to remain valid after the locale changes. As * such, this should only be called within libc functions. */ +inline locale_t __get_locale(void) +{ + + if (!__has_thread_locale) { + return (&__xlocale_global_locale); + } + return (__thread_locale ? __thread_locale : &__xlocale_global_locale); +} +#else locale_t __get_locale(void); +#endif /** * Two magic values are allowed for locale_t objects. NULL and -1. This Modified: head/sys/sys/cdefs.h ============================================================================== --- head/sys/sys/cdefs.h Sun Mar 4 15:25:11 2012 (r232497) +++ head/sys/sys/cdefs.h Sun Mar 4 15:31:13 2012 (r232498) @@ -230,7 +230,8 @@ #define _Alignof(e) alignof(e) #define _Noreturn [[noreturn]] #define _Static_assert(e, s) static_assert(e, s) -#define _Thread_local thread_local +/* FIXME: change this to thread_local when clang in base supports it */ +#define _Thread_local __thread #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L /* Do nothing. They are language keywords. */ #else @@ -400,12 +401,18 @@ #define __printflike(fmtarg, firstvararg) #define __scanflike(fmtarg, firstvararg) #define __format_arg(fmtarg) +#define __strfmonlike(fmtarg, firstvararg) +#define __strftimelike(fmtarg, firstvararg) #else #define __printflike(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) #define __scanflike(fmtarg, firstvararg) \ __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) #define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg))) +#define __strfmonlike(fmtarg, firstvararg) \ + __attribute__((__format__ (__strfmon__, fmtarg, firstvararg))) +#define __strftimelike(fmtarg, firstvararg) \ + __attribute__((__format__ (__strftime__, fmtarg, firstvararg))) #endif /* Compiler-dependent macros that rely on FreeBSD-specific extensions. */ @@ -650,4 +657,8 @@ #define __has_builtin(x) 0 #endif +#if defined(__mips) || defined(__powerpc64__) +#define __NO_TLS 1 +#endif + #endif /* !_SYS_CDEFS_H_ */