• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <locale.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "locale_impl.h"
5 #include "libc.h"
6 #include "lock.h"
7 
8 static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
9 
10 #ifndef __LITEOS__
Fresh(struct __locale_map * lm)11 static inline int Fresh(struct __locale_map *lm)
12 {
13 	if (lm != NULL) {
14 		return lm->flag;
15 	}
16 	return VALID;
17 }
18 #endif
19 
setlocale(int cat,const char * name)20 char *setlocale(int cat, const char *name)
21 {
22 	const struct __locale_map *lm;
23 	char flag = VALID;
24 	if ((unsigned)cat > LC_ALL) return 0;
25 
26 	LOCK(__locale_lock);
27 
28 	/* For LC_ALL, setlocale is required to return a string which
29 	 * encodes the current setting for all categories. The format of
30 	 * this string is unspecified, and only the following code, which
31 	 * performs both the serialization and deserialization, depends
32 	 * on the format, so it can easily be changed if needed. */
33 	if (cat == LC_ALL) {
34 		int i;
35 		if (name) {
36 			struct __locale_struct tmp_locale;
37 			char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
38 			const char *p = name;
39 			for (i=0; i<LC_ALL; i++) {
40 				const char *z = __strchrnul(p, ';');
41 				if (z-p <= LOCALE_NAME_MAX) {
42 					memcpy(part, p, z-p);
43 					part[z-p] = 0;
44 					if (*z) p = z+1;
45 				}
46 				lm = __get_locale(i, part);
47 				if (lm == LOC_MAP_FAILED) {
48 					UNLOCK(__locale_lock);
49 					return 0;
50 				}
51 #ifndef __LITEOS__
52 				if(Fresh(lm) == INVALID) {
53 					flag = INVALID;
54 				}
55 #endif
56 				tmp_locale.cat[i] = lm;
57 			}
58 			libc.global_locale = tmp_locale;
59 		}
60 		char *s = buf;
61 		const char *part;
62 		int same = 0;
63 		for (i=0; i<LC_ALL; i++) {
64 			const struct __locale_map *lm =
65 				libc.global_locale.cat[i];
66 			if (lm == libc.global_locale.cat[0]) same++;
67 			part = lm ? lm->name : "C";
68 			size_t l = strlen(part);
69 			memcpy(s, part, l);
70 			s[l] = ';';
71 			s += l+1;
72 		}
73 		*--s = 0;
74 		UNLOCK(__locale_lock);
75 		if (flag == INVALID) {
76 			return 0;
77 		}
78 		return same==LC_ALL ? (char *)part : buf;
79 	}
80 
81 	if (name) {
82 		lm = __get_locale(cat, name);
83 		if (lm == LOC_MAP_FAILED) {
84 			UNLOCK(__locale_lock);
85 			return 0;
86 		}
87 #ifndef __LITEOS__
88 		flag = Fresh(lm);
89 #endif
90 		libc.global_locale.cat[cat] = lm;
91 	} else {
92 		lm = libc.global_locale.cat[cat];
93 	}
94 	char *ret = lm ? (char *)lm->name : "C";
95 
96 	UNLOCK(__locale_lock);
97 	if (flag == INVALID) {
98 		return 0;
99 	}
100 	return ret;
101 }
102