Deleted Added
full compact
setlocale.c (11702) setlocale.c (19964)
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 29 unchanged lines hidden (view full) ---

38static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
39#endif /* LIBC_SCCS and not lint */
40
41#include <limits.h>
42#include <locale.h>
43#include <rune.h>
44#include <stdlib.h>
45#include <string.h>
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 29 unchanged lines hidden (view full) ---

38static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
39#endif /* LIBC_SCCS and not lint */
40
41#include <limits.h>
42#include <locale.h>
43#include <rune.h>
44#include <stdlib.h>
45#include <string.h>
46#include <sys/stat.h>
46#include "collate.h"
47
48/*
49 * Category names for getenv()
50 */
51static char *categories[_LC_LAST] = {
52 "LC_ALL",
53 "LC_COLLATE",

--- 14 unchanged lines hidden (view full) ---

68 "C",
69 "C",
70};
71
72/*
73 * The locales we are going to try and load
74 */
75static char new_categories[_LC_LAST][32];
47#include "collate.h"
48
49/*
50 * Category names for getenv()
51 */
52static char *categories[_LC_LAST] = {
53 "LC_ALL",
54 "LC_COLLATE",

--- 14 unchanged lines hidden (view full) ---

69 "C",
70 "C",
71};
72
73/*
74 * The locales we are going to try and load
75 */
76static char new_categories[_LC_LAST][32];
77static char saved_categories[_LC_LAST][32];
76
77static char current_locale_string[_LC_LAST * 33];
78char *_PathLocale;
79
80static char *currentlocale __P((void));
81static char *loadlocale __P((int));
78
79static char current_locale_string[_LC_LAST * 33];
80char *_PathLocale;
81
82static char *currentlocale __P((void));
83static char *loadlocale __P((int));
84static int stub_load_locale __P((const char *));
82
83extern int __time_load_locale __P((const char *)); /* strftime.c */
84
85#ifdef XPG4
86extern int _xpg4_setrunelocale __P((char *));
87#endif
88
89char *
90setlocale(category, locale)
91 int category;
92 const char *locale;
93{
85
86extern int __time_load_locale __P((const char *)); /* strftime.c */
87
88#ifdef XPG4
89extern int _xpg4_setrunelocale __P((char *));
90#endif
91
92char *
93setlocale(category, locale)
94 int category;
95 const char *locale;
96{
94 int found, i, len;
97 int i, j, len;
95 char *env, *r;
96
98 char *env, *r;
99
97 if (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))
98 _PathLocale = _PATH_LOCALE;
99
100 if (category < 0 || category >= _LC_LAST)
100 if (category < LC_ALL || category >= _LC_LAST)
101 return (NULL);
102
103 if (!locale)
101 return (NULL);
102
103 if (!locale)
104 return (category ?
104 return (category != LC_ALL ?
105 current_categories[category] : currentlocale());
106
107 /*
108 * Default to the current locale for everything.
109 */
105 current_categories[category] : currentlocale());
106
107 /*
108 * Default to the current locale for everything.
109 */
110 for (i = 1; i < _LC_LAST; ++i)
110 for (i = 1; i < _LC_LAST; ++i) {
111 (void)strcpy(new_categories[i], current_categories[i]);
111 (void)strcpy(new_categories[i], current_categories[i]);
112 (void)strcpy(saved_categories[i], current_categories[i]);
113 }
112
113 /*
114 * Now go fill up new_categories from the locale argument
115 */
116 if (!*locale) {
117 env = getenv(categories[category]);
118
114
115 /*
116 * Now go fill up new_categories from the locale argument
117 */
118 if (!*locale) {
119 env = getenv(categories[category]);
120
119 if (!env)
120 env = getenv(categories[0]);
121 if (category != LC_ALL && (!env || !*env))
122 env = getenv(categories[LC_ALL]);
121
123
122 if (!env)
124 if (!env || !*env)
123 env = getenv("LANG");
124
125 env = getenv("LANG");
126
125 if (!env)
127 if (!env || !*env)
126 env = "C";
127
128 (void) strncpy(new_categories[category], env, 31);
129 new_categories[category][31] = 0;
128 env = "C";
129
130 (void) strncpy(new_categories[category], env, 31);
131 new_categories[category][31] = 0;
130 if (!category) {
132 if (category == LC_ALL) {
131 for (i = 1; i < _LC_LAST; ++i) {
133 for (i = 1; i < _LC_LAST; ++i) {
132 if (!(env = getenv(categories[i])))
133 env = new_categories[0];
134 if (!(env = getenv(categories[i])) || !*env)
135 env = new_categories[LC_ALL];
134 (void)strncpy(new_categories[i], env, 31);
135 new_categories[i][31] = 0;
136 }
137 }
136 (void)strncpy(new_categories[i], env, 31);
137 new_categories[i][31] = 0;
138 }
139 }
138 } else if (category) {
140 } else if (category != LC_ALL) {
139 (void)strncpy(new_categories[category], locale, 31);
140 new_categories[category][31] = 0;
141 } else {
142 if ((r = strchr(locale, '/')) == 0) {
143 for (i = 1; i < _LC_LAST; ++i) {
144 (void)strncpy(new_categories[i], locale, 31);
145 new_categories[i][31] = 0;
146 }

--- 11 unchanged lines hidden (view full) ---

158 while (*++r && *r != '/');
159 } while (*locale);
160 while (i < _LC_LAST)
161 (void)strcpy(new_categories[i],
162 new_categories[i-1]);
163 }
164 }
165
141 (void)strncpy(new_categories[category], locale, 31);
142 new_categories[category][31] = 0;
143 } else {
144 if ((r = strchr(locale, '/')) == 0) {
145 for (i = 1; i < _LC_LAST; ++i) {
146 (void)strncpy(new_categories[i], locale, 31);
147 new_categories[i][31] = 0;
148 }

--- 11 unchanged lines hidden (view full) ---

160 while (*++r && *r != '/');
161 } while (*locale);
162 while (i < _LC_LAST)
163 (void)strcpy(new_categories[i],
164 new_categories[i-1]);
165 }
166 }
167
166 if (category)
167 return (loadlocale(category));
168 if (category) {
169 if ((r = loadlocale(category)) == NULL) {
170 (void)strcpy(new_categories[category],
171 saved_categories[category]);
172 /* XXX can fail too */
173 (void)loadlocale(category);
174 }
175 return (r);
176 }
168
177
169 found = 0;
170 for (i = 1; i < _LC_LAST; ++i)
178 for (i = 1; i < _LC_LAST; ++i)
171 if (loadlocale(i) != NULL)
172 found = 1;
173 if (found)
174 return (currentlocale());
175 return (NULL);
179 if (loadlocale(i) == NULL) {
180 for (j = 1; j < i; j++) {
181 (void)strcpy(new_categories[j],
182 saved_categories[j]);
183 /* XXX can fail too */
184 (void)loadlocale(j);
185 }
186 return (NULL);
187 }
188 return (currentlocale());
176}
177
178/* To be compatible with crt0 hack */
179void
180_startup_setlocale(category, locale)
181 int category;
182 const char *locale;
183{
184#ifndef XPG4
185 (void) setlocale(category, locale);
186#endif
187}
188
189static char *
190currentlocale()
191{
189}
190
191/* To be compatible with crt0 hack */
192void
193_startup_setlocale(category, locale)
194 int category;
195 const char *locale;
196{
197#ifndef XPG4
198 (void) setlocale(category, locale);
199#endif
200}
201
202static char *
203currentlocale()
204{
192 int i, len;
205 int i;
193
194 (void)strcpy(current_locale_string, current_categories[1]);
195
196 for (i = 2; i < _LC_LAST; ++i)
197 if (strcmp(current_categories[1], current_categories[i])) {
206
207 (void)strcpy(current_locale_string, current_categories[1]);
208
209 for (i = 2; i < _LC_LAST; ++i)
210 if (strcmp(current_categories[1], current_categories[i])) {
198 len = strlen(current_categories[1]) + 1 +
199 strlen(current_categories[2]) + 1 +
200 strlen(current_categories[3]) + 1 +
201 strlen(current_categories[4]) + 1 +
202 strlen(current_categories[5]) + 1;
203 if (len > sizeof(current_locale_string))
204 return NULL;
205 (void) strcpy(current_locale_string, current_categories[1]);
206 (void) strcat(current_locale_string, "/");
207 (void) strcat(current_locale_string, current_categories[2]);
208 (void) strcat(current_locale_string, "/");
209 (void) strcat(current_locale_string, current_categories[3]);
210 (void) strcat(current_locale_string, "/");
211 (void) strcat(current_locale_string, current_categories[4]);
212 (void) strcat(current_locale_string, "/");
213 (void) strcat(current_locale_string, current_categories[5]);
214 break;
215 }
216 return (current_locale_string);
217}
218
219static char *
220loadlocale(category)
221 int category;
222{
211 (void) strcpy(current_locale_string, current_categories[1]);
212 (void) strcat(current_locale_string, "/");
213 (void) strcat(current_locale_string, current_categories[2]);
214 (void) strcat(current_locale_string, "/");
215 (void) strcat(current_locale_string, current_categories[3]);
216 (void) strcat(current_locale_string, "/");
217 (void) strcat(current_locale_string, current_categories[4]);
218 (void) strcat(current_locale_string, "/");
219 (void) strcat(current_locale_string, current_categories[5]);
220 break;
221 }
222 return (current_locale_string);
223}
224
225static char *
226loadlocale(category)
227 int category;
228{
223#if 0
224 char name[PATH_MAX];
225#endif
226 if (strcmp(new_categories[category],
229 char *encoding = new_categories[category];
230
231 if (strcmp(encoding,
227 current_categories[category]) == 0)
228 return (current_categories[category]);
229
232 current_categories[category]) == 0)
233 return (current_categories[category]);
234
235 if ( !_PathLocale
236 && strcmp(encoding, "C") && strcmp(encoding, "POSIX")
237 ) {
238 char *pl = getenv("PATH_LOCALE");
239
240 if (!pl)
241 _PathLocale = _PATH_LOCALE;
242 else if ( strlen(pl) + 45 > PATH_MAX
243 || !(_PathLocale = strdup(pl))
244 )
245 return (NULL);
246 }
247
230 if (category == LC_CTYPE) {
231#ifdef XPG4
248 if (category == LC_CTYPE) {
249#ifdef XPG4
232 if (_xpg4_setrunelocale(new_categories[LC_CTYPE]))
250 if (_xpg4_setrunelocale(encoding))
233#else
251#else
234 if (setrunelocale(new_categories[LC_CTYPE]))
252 if (setrunelocale(encoding))
235#endif
236 return (NULL);
253#endif
254 return (NULL);
237 (void)strcpy(current_categories[LC_CTYPE],
238 new_categories[LC_CTYPE]);
255 (void)strcpy(current_categories[LC_CTYPE], encoding);
239 return (current_categories[LC_CTYPE]);
240 }
241
242 if (category == LC_COLLATE) {
256 return (current_categories[LC_CTYPE]);
257 }
258
259 if (category == LC_COLLATE) {
243 if (__collate_load_tables(new_categories[LC_COLLATE]) < 0)
260 if (__collate_load_tables(encoding) < 0)
244 return (NULL);
261 return (NULL);
245 (void)strcpy(current_categories[LC_COLLATE],
246 new_categories[LC_COLLATE]);
262 (void)strcpy(current_categories[LC_COLLATE], encoding);
247 return (current_categories[LC_COLLATE]);
248 }
249
250 if (category == LC_TIME) {
263 return (current_categories[LC_COLLATE]);
264 }
265
266 if (category == LC_TIME) {
251 if (__time_load_locale(new_categories[LC_TIME]) < 0)
267 if (__time_load_locale(encoding) < 0)
252 return (NULL);
268 return (NULL);
253 (void)strcpy(current_categories[LC_TIME],
254 new_categories[LC_TIME]);
269 (void)strcpy(current_categories[LC_TIME], encoding);
255 return (current_categories[LC_TIME]);
256 }
257
270 return (current_categories[LC_TIME]);
271 }
272
258 if (!strcmp(new_categories[category], "C") ||
259 !strcmp(new_categories[category], "POSIX")) {
260
261 /*
262 * Some day this will need to reset the locale to the default
263 * C locale. Since we have no way to change them as of yet,
264 * there is no need to reset them.
265 */
266 (void)strcpy(current_categories[category],
267 new_categories[category]);
273 if (category == LC_MONETARY || category == LC_NUMERIC) {
274 if (stub_load_locale(encoding))
275 return (NULL);
276 (void)strcpy(current_categories[category], encoding);
268 return (current_categories[category]);
269 }
277 return (current_categories[category]);
278 }
279
280 /* Just in case...*/
281 return (NULL);
282}
283
284static int
285stub_load_locale(encoding)
286const char *encoding;
287{
288 char name[PATH_MAX];
289 struct stat st;
290
291 if (!encoding)
292 return(1);
293 /*
294 * The "C" and "POSIX" locale are always here.
295 */
296 if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX"))
297 return(0);
298 if (!_PathLocale)
299 return(1);
300 strcpy(name, _PathLocale);
301 strcat(name, "/");
302 strcat(name, encoding);
270#if 0
271 /*
272 * Some day we will actually look at this file.
273 */
303#if 0
304 /*
305 * Some day we will actually look at this file.
306 */
274 (void)snprintf(name, sizeof(name), "%s/%s/%s",
275 _PathLocale, new_categories[category], categories[category]);
276#endif
307#endif
277 switch (category) {
278 case LC_MONETARY:
279 case LC_NUMERIC:
280 return (NULL);
281 }
282 /* Just in case...*/
283 return (NULL);
308 return (stat(name, &st) != 0 || !S_ISDIR(st.st_mode));
284}
309}