diff options
Diffstat (limited to 'locale/setlocale.c')
-rw-r--r-- | locale/setlocale.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/locale/setlocale.c b/locale/setlocale.c index 094664216e..368027f743 100644 --- a/locale/setlocale.c +++ b/locale/setlocale.c @@ -1,20 +1,20 @@ -/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include <alloca.h> #include <argz.h> @@ -35,15 +35,15 @@ Boston, MA 02111-1307, USA. */ Both are weak references; if &_nl_current_CATEGORY is zero, then nothing is using the locale data. */ #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \ -extern const struct locale_data *_nl_current_##category; \ -extern const struct locale_data _nl_C_##category; \ +extern struct locale_data *_nl_current_##category; \ +extern struct locale_data _nl_C_##category; \ weak_extern (_nl_current_##category) weak_extern (_nl_C_##category) #include "categories.def" #undef DEFINE_CATEGORY /* Array indexed by category of pointers to _nl_current_CATEGORY slots. Elements are zero for categories whose data is never used. */ -static const struct locale_data * *const _nl_current[] = +static struct locale_data * *const _nl_current[] = { #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \ [category] = &_nl_current_##category, @@ -53,7 +53,7 @@ static const struct locale_data * *const _nl_current[] = /* Array indexed by category of pointers to _nl_C_CATEGORY slots. Elements are zero for categories whose data is never used. */ -const struct locale_data *const _nl_C[] = +struct locale_data *const _nl_C[] = { #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \ [category] = &_nl_C_##category, @@ -147,7 +147,7 @@ clever_copy (const char *string) /* Construct a new composite name. */ static inline char * -new_composite_name (int category, char *newnames[LC_ALL]) +new_composite_name (int category, const char *newnames[LC_ALL]) { size_t last_len; size_t cumlen = 0; @@ -157,9 +157,9 @@ new_composite_name (int category, char *newnames[LC_ALL]) for (i = 0; i < LC_ALL; ++i) { - char *name = (category == LC_ALL ? newnames[i] : - category == i ? newnames[0] : - (char *) _nl_current_names[i]); + const char *name = (category == LC_ALL ? newnames[i] : + category == i ? newnames[0] : + _nl_current_names[i]); last_len = strlen (name); cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1; if (i > 0 && same && strcmp (name, newnames[0]) != 0) @@ -184,9 +184,9 @@ new_composite_name (int category, char *newnames[LC_ALL]) for (i = 0; i < LC_ALL; ++i) { /* Add "CATEGORY=NAME;" to the string. */ - char *name = (category == LC_ALL ? newnames[i] : - category == i ? newnames[0] : - (char *) _nl_current_names[i]); + const char *name = (category == LC_ALL ? newnames[i] : + category == i ? newnames[0] : + _nl_current_names[i]); p = __stpcpy (p, _nl_category_names[i]); *p++ = '='; p = __stpcpy (p, name); @@ -211,7 +211,7 @@ setname (int category, const char *name) /* Put DATA in *_nl_current[CATEGORY]. */ static inline void -setdata (int category, const struct locale_data *data) +setdata (int category, struct locale_data *data) { if (_nl_current[category] != NULL) { @@ -264,8 +264,8 @@ setlocale (int category, const char *locale) for the individual categories can be selected by using a composite locale name. This is a semi-colon separated list of entries of the form `CATEGORY=VALUE'. */ - char *newnames[LC_ALL]; - const struct locale_data *newdata[LC_ALL]; + const char *newnames[LC_ALL]; + struct locale_data *newdata[LC_ALL]; /* Set all name pointers to the argument name. */ for (category = 0; category < LC_ALL; ++category) @@ -323,6 +323,11 @@ setlocale (int category, const char *locale) if (newdata[category] == NULL) break; + + /* We must not simply free a global locale since we have + no control over the usage. So we mark it as + un-deletable. */ + newdata[category]->usage_count = MAX_USAGE_COUNT; } else { @@ -356,8 +361,8 @@ setlocale (int category, const char *locale) } else { - const struct locale_data *newdata = NULL; - char *newname = (char *) locale; + struct locale_data *newdata = NULL; + const char *newname = locale; /* Protect global data. */ __libc_lock_lock (__libc_setlocale_lock); @@ -366,9 +371,13 @@ setlocale (int category, const char *locale) { /* Only actually load the data if anything will use it. */ newdata = _nl_find_locale (locale_path, locale_path_len, category, - (char **) &newname); + &newname); if (newdata == NULL) goto abort_single; + + /* We must not simply free a global locale since we have no + control over the usage. So we mark it as un-deletable. */ + newdata->usage_count = MAX_USAGE_COUNT; } /* Create new composite name. */ @@ -391,6 +400,6 @@ setlocale (int category, const char *locale) /* Critical section left. */ __libc_lock_unlock (__libc_setlocale_lock); - return newname; + return (char *) newname; } } |