4 #include "locale_impl.h"
8 static char buf[2+4*(LOCALE_NAME_MAX+1)];
10 static char *setlocale_one_unlocked(int cat, const char *name)
12 struct __locale_map *lm;
14 if (name) __setlocalecat(&libc.global_locale, cat, name);
18 return libc.global_locale.ctype_utf8 ? "C.UTF-8" : "C";
22 return libc.global_locale.messages_name[0]
23 ? libc.global_locale.messages_name : "C";
25 lm = libc.global_locale.cat[cat-2];
26 return lm ? lm->name : "C";
30 char *setlocale(int cat, const char *name)
32 static volatile int lock[2];
33 struct __locale_map *lm;
36 if (!libc.global_locale.messages_name) {
37 libc.global_locale.messages_name =
38 buf + 2 + 3*(LOCALE_NAME_MAX+1);
41 if ((unsigned)cat > LC_ALL) return 0;
45 /* For LC_ALL, setlocale is required to return a string which
46 * encodes the current setting for all categories. The format of
47 * this string is unspecified, and only the following code, which
48 * performs both the serialization and deserialization, depends
49 * on the format, so it can easily be changed if needed. */
52 char part[LOCALE_NAME_MAX+1];
53 if (name[0] && name[1]==';'
54 && strlen(name) > 2 + 3*(LOCALE_NAME_MAX+1)) {
57 setlocale(LC_CTYPE, part);
58 part[LOCALE_NAME_MAX] = 0;
59 for (i=LC_TIME; i<LC_MESSAGES; i++) {
60 memcpy(part, name + 2 + (i-2)*(LOCALE_NAME_MAX+1), LOCALE_NAME_MAX);
61 for (j=LOCALE_NAME_MAX-1; j && part[j]==';'; j--)
63 setlocale_one_unlocked(i, part);
65 setlocale_one_unlocked(LC_MESSAGES, name
66 + 2 + 3*(LOCALE_NAME_MAX+1));
68 for (i=0; i<LC_ALL; i++)
69 setlocale_one_unlocked(i, name);
72 memset(buf, ';', 2 + 3*(LOCALE_NAME_MAX+1));
73 buf[0] = libc.global_locale.ctype_utf8 ? 'U' : 'C';
74 for (i=LC_TIME; i<LC_MESSAGES; i++) {
75 lm = libc.global_locale.cat[i-2];
76 if (lm) memcpy(buf + 2 + (i-2)*(LOCALE_NAME_MAX+1),
77 lm->name, strlen(lm->name));
83 char *ret = setlocale_one_unlocked(cat, name);