X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Flocale%2Fsetlocale.c;h=360c4437644b88f86ac8b9f0db5d92915019c8d7;hb=8ef9d46f4d0ff4f0073da6bee7ed0cb5f9035ead;hp=32a8fcab5fde043654ed06a16820f9464bce1981;hpb=63c188ec42e76ff768e81f6b65b11c68fc43351e;p=musl diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c index 32a8fcab..360c4437 100644 --- a/src/locale/setlocale.c +++ b/src/locale/setlocale.c @@ -3,44 +3,17 @@ #include #include "locale_impl.h" #include "libc.h" -#include "atomic.h" +#include "lock.h" -static char buf[2+4*(LOCALE_NAME_MAX+1)]; - -static char *setlocale_one_unlocked(int cat, const char *name) -{ - struct __locale_map *lm; - - if (name) __setlocalecat(&libc.global_locale, cat, name); - - switch (cat) { - case LC_CTYPE: - return libc.global_locale.ctype_utf8 ? "C.UTF-8" : "C"; - case LC_NUMERIC: - return "C"; - case LC_MESSAGES: - return libc.global_locale.messages_name[0] - ? libc.global_locale.messages_name : "C"; - default: - lm = libc.global_locale.cat[cat-2]; - return lm ? lm->name : "C"; - } -} +static char buf[LC_ALL*(LOCALE_NAME_MAX+1)]; char *setlocale(int cat, const char *name) { - static volatile int lock[2]; - struct __locale_map *lm; - int i, j; - - if (!libc.global_locale.messages_name) { - libc.global_locale.messages_name = - buf + 2 + 3*(LOCALE_NAME_MAX+1); - } + const struct __locale_map *lm; if ((unsigned)cat > LC_ALL) return 0; - LOCK(lock); + LOCK(__locale_lock); /* For LC_ALL, setlocale is required to return a string which * encodes the current setting for all categories. The format of @@ -48,41 +21,58 @@ char *setlocale(int cat, const char *name) * performs both the serialization and deserialization, depends * on the format, so it can easily be changed if needed. */ if (cat == LC_ALL) { + int i; if (name) { - char part[LOCALE_NAME_MAX+1]; - if (name[0] && name[1]==';' - && strlen(name) > 2 + 3*(LOCALE_NAME_MAX+1)) { - part[0] = name[0]; - part[1] = 0; - setlocale(LC_CTYPE, part); - part[LOCALE_NAME_MAX] = 0; - for (i=LC_TIME; iname, strlen(lm->name)); + char *s = buf; + const char *part; + int same = 0; + for (i=0; iname : "C"; + size_t l = strlen(part); + memcpy(s, part, l); + s[l] = ';'; + s += l+1; } - UNLOCK(lock); - return buf; + *--s = 0; + UNLOCK(__locale_lock); + return same==LC_ALL ? (char *)part : buf; } - char *ret = setlocale_one_unlocked(cat, name); + if (name) { + lm = __get_locale(cat, name); + if (lm == LOC_MAP_FAILED) { + UNLOCK(__locale_lock); + return 0; + } + libc.global_locale.cat[cat] = lm; + } else { + lm = libc.global_locale.cat[cat]; + } + char *ret = lm ? (char *)lm->name : "C"; - UNLOCK(lock); + UNLOCK(__locale_lock); return ret; }