locale_t
newlocale(int mask, const char *name, locale_t src)
{
	struct _locale *dst;
	char head[_LOCALENAME_LEN_MAX * (_LC_LAST - 1)], *tail;
	const char *tokens[_LC_LAST - 1];
	_locale_set_t l;
	int i, howmany, categories[_LC_LAST - 1];

	if (name == NULL)
		name = _C_LOCALE;
	dst = malloc(sizeof(*dst));
	if (dst == NULL)
		return (locale_t)NULL;
	if (src == NULL)
		src = _current_locale();
	memcpy(dst, src, sizeof(*src));
	strlcpy(&head[0], name, sizeof(head));
	tokens[0] = (const char *)&head[0];
	tail = strchr(tokens[0], '/');
	if (tail == NULL) {
		for (i = 1; i < _LC_LAST; ++i) {
			if (mask & (1 << i)) {
				l = _find_category(i);
				_DIAGASSERT(l != NULL);
				(*l)(tokens[0], dst);
			}
		}
	} else {
		*tail++ = '\0';
		howmany = 0;
		for (i = 1; i < _LC_LAST; ++i) {
			if (mask & (1 << i))
				categories[howmany++] = i;
		}
		if (howmany-- > 0) {
			for (i = 1; i < howmany; ++i) {
				tokens[i] = (const char *)tail;
				tail = strchr(tokens[i], '/');
				if (tail == NULL) {
					free(dst);
					return NULL;
				}
			}
			tokens[howmany] = tail;
			tail = strchr(tokens[howmany], '/');
			if (tail != NULL) {
				free(dst);
				return NULL;
			}
			for (i = 0; i <= howmany; ++i) {
				l = _find_category(categories[i]);
				_DIAGASSERT(l != NULL);
				(*l)(tokens[i], dst);
			}
		}
	}
	return (locale_t)dst;
}
char *
__setlocale(int category, const char *name)
{
	_locale_set_t sl;
	struct _locale *impl;

	sl = _find_category(category);
	if (sl == NULL)
		return NULL;
	impl = _current_locale();
	return __UNCONST((*sl)(name, impl));
}
Esempio n. 3
0
 * macro required by all template headers
 */
#define _PREFIX(name)	__CONCAT(_generic_LC_ALL_, name)

#include "generic_lc_template_decl.h"

const char *
_generic_LC_ALL_setlocale(const char * __restrict name,
    struct _locale_impl_t * __restrict locale)
{
	_locale_category_t *l;
	char head[_LOCALENAME_LEN_MAX * (_LC_LAST - 1)], *tail;
	const char *tokens[_LC_LAST], *s, *t;
	int load_locale_success, i, j;

	l = _find_category(1);
	_DIAGASSERT(l != NULL);
	load_locale_success = 0;
	if (name != NULL) {
		strlcpy(&head[0], name, sizeof(head));
		tokens[1] = &head[0];
		tail = strchr(tokens[1], '/');
		if (tail == NULL) {
			for (i = 2; i < _LC_LAST; ++i)
				tokens[i] = tokens[1];
		} else {
			*tail++ = '\0';
			for (i = 2; i < _LC_LAST - 1; ++i) {
				tokens[i] = (const char *)tail;
				tail = strchr(tokens[i], '/');
				if (tail == NULL)