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)); }
* 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)