97
98 static struct locale posix_locale = {
99 /* locdata */
100 .locdata = {
101 &__posix_ctype_locdata,
102 &__posix_numeric_locdata,
103 &__posix_time_locdata,
104 &__posix_collate_locdata,
105 &__posix_monetary_locdata,
106 &__posix_messages_locdata,
107 },
108 .ctype = &lc_ctype_posix,
109 .numeric = &lc_numeric_posix,
110 .collate = &lc_collate_posix,
111 .monetary = &lc_monetary_posix,
112 .messages = &lc_messages_posix,
113 .time = &lc_time_posix,
114 .runelocale = &_DefaultRuneLocale,
115 };
116
117 locale_t __global_locale = &posix_locale;
118
119 /*
120 * Category names for getenv() Note that this was modified
121 * for Solaris. See <iso/locale_iso.h>.
122 */
123 #define NUM_CATS 7
124 static char *categories[7] = {
125 "LC_CTYPE",
126 "LC_NUMERIC",
127 "LC_TIME",
128 "LC_COLLATE",
129 "LC_MONETARY",
130 "LC_MESSAGES",
131 "LC_ALL",
132 };
133
134 /*
135 * Prototypes.
136 */
137 static const char *get_locale_env(int);
138 static struct locdata *locdata_get(int, const const char *);
379 void
380 freelocale(locale_t loc)
381 {
382 int i;
383 for (i = 0; i < LC_ALL; i++)
384 __locdata_release(loc->locdata[i]);
385 if (loc != &posix_locale)
386 free(loc);
387 }
388
389 locale_t
390 newlocale(int catmask, const char *locname, locale_t base)
391 {
392 locale_t loc;
393 int i, e;
394
395 if (catmask & ~(LC_ALL_MASK)) {
396 errno = EINVAL;
397 return (NULL);
398 }
399 loc = duplocale(base != NULL ? base : __global_locale);
400 if (loc == NULL) {
401 return (NULL);
402 }
403
404 for (i = 0; i < LC_ALL; i++) {
405 struct locdata *ldata;
406 loc->loaded[i] = 0;
407 if (((1 << i) & catmask) == 0) {
408 /* Default to base locale if not overriding */
409 continue;
410 }
411 ldata = locdata_get(i, locname);
412 if (ldata == NULL) {
413 e = errno;
414 freelocale(loc);
415 errno = e;
416 return (NULL);
417 }
418 __locdata_release(loc->locdata[i]);
419 loc->locdata[i] = ldata;
420 }
421 if (base && base != __global_locale) {
422 freelocale(base);
423 }
424 loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
425 loc->ctype = loc->locdata[LC_CTYPE]->l_data[0];
426 loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
427 loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
428 loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
429 loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
430 loc->time = loc->locdata[LC_TIME]->l_data[0];
431 return (loc);
432 }
433
434 locale_t
435 uselocale(locale_t loc)
436 {
437 locale_t lastloc = __global_locale;
438 locale_t *locptr;
439
440 locptr = tsdalloc(_T_SETLOCALE, sizeof (locale_t), freelocptr);
441 /* Should never occur */
442 if (locptr == NULL) {
443 errno = EINVAL;
444 return (NULL);
445 }
446
447 if (*locptr != NULL)
448 lastloc = *locptr;
449
450 /* Argument loc is NULL if we are just querying. */
451 if (loc != NULL) {
452 /*
453 * Set it to LC_GLOBAL_LOCAL to return to using
454 * the global locale (setlocale).
455 */
456 if (loc == __global_locale) {
457 *locptr = NULL;
458 } else {
459 /* No validation of the provided locale at present */
460 *locptr = loc;
461 }
462 }
463
464 /*
465 * The caller is responsible for freeing, of course it would be
466 * gross error to call freelocale() on a locale object that is still
467 * in use.
468 */
469 return (lastloc);
470 }
|
97
98 static struct locale posix_locale = {
99 /* locdata */
100 .locdata = {
101 &__posix_ctype_locdata,
102 &__posix_numeric_locdata,
103 &__posix_time_locdata,
104 &__posix_collate_locdata,
105 &__posix_monetary_locdata,
106 &__posix_messages_locdata,
107 },
108 .ctype = &lc_ctype_posix,
109 .numeric = &lc_numeric_posix,
110 .collate = &lc_collate_posix,
111 .monetary = &lc_monetary_posix,
112 .messages = &lc_messages_posix,
113 .time = &lc_time_posix,
114 .runelocale = &_DefaultRuneLocale,
115 };
116
117 locale_t ___global_locale = &posix_locale;
118
119 locale_t
120 __global_locale(void)
121 {
122 return (___global_locale);
123 }
124
125 /*
126 * Category names for getenv() Note that this was modified
127 * for Solaris. See <iso/locale_iso.h>.
128 */
129 #define NUM_CATS 7
130 static char *categories[7] = {
131 "LC_CTYPE",
132 "LC_NUMERIC",
133 "LC_TIME",
134 "LC_COLLATE",
135 "LC_MONETARY",
136 "LC_MESSAGES",
137 "LC_ALL",
138 };
139
140 /*
141 * Prototypes.
142 */
143 static const char *get_locale_env(int);
144 static struct locdata *locdata_get(int, const const char *);
385 void
386 freelocale(locale_t loc)
387 {
388 int i;
389 for (i = 0; i < LC_ALL; i++)
390 __locdata_release(loc->locdata[i]);
391 if (loc != &posix_locale)
392 free(loc);
393 }
394
395 locale_t
396 newlocale(int catmask, const char *locname, locale_t base)
397 {
398 locale_t loc;
399 int i, e;
400
401 if (catmask & ~(LC_ALL_MASK)) {
402 errno = EINVAL;
403 return (NULL);
404 }
405 loc = duplocale(base != NULL ? base : ___global_locale);
406 if (loc == NULL) {
407 return (NULL);
408 }
409
410 for (i = 0; i < LC_ALL; i++) {
411 struct locdata *ldata;
412 loc->loaded[i] = 0;
413 if (((1 << i) & catmask) == 0) {
414 /* Default to base locale if not overriding */
415 continue;
416 }
417 ldata = locdata_get(i, locname);
418 if (ldata == NULL) {
419 e = errno;
420 freelocale(loc);
421 errno = e;
422 return (NULL);
423 }
424 __locdata_release(loc->locdata[i]);
425 loc->locdata[i] = ldata;
426 }
427 if (base && base != ___global_locale) {
428 freelocale(base);
429 }
430 loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
431 loc->ctype = loc->locdata[LC_CTYPE]->l_data[0];
432 loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
433 loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
434 loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
435 loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
436 loc->time = loc->locdata[LC_TIME]->l_data[0];
437 return (loc);
438 }
439
440 locale_t
441 uselocale(locale_t loc)
442 {
443 locale_t lastloc = ___global_locale;
444 locale_t *locptr;
445
446 locptr = tsdalloc(_T_SETLOCALE, sizeof (locale_t), freelocptr);
447 /* Should never occur */
448 if (locptr == NULL) {
449 errno = EINVAL;
450 return (NULL);
451 }
452
453 if (*locptr != NULL)
454 lastloc = *locptr;
455
456 /* Argument loc is NULL if we are just querying. */
457 if (loc != NULL) {
458 /*
459 * Set it to LC_GLOBAL_LOCAL to return to using
460 * the global locale (setlocale).
461 */
462 if (loc == ___global_locale) {
463 *locptr = NULL;
464 } else {
465 /* No validation of the provided locale at present */
466 *locptr = loc;
467 }
468 }
469
470 /*
471 * The caller is responsible for freeing, of course it would be
472 * gross error to call freelocale() on a locale object that is still
473 * in use.
474 */
475 return (lastloc);
476 }
|