summaryrefslogtreecommitdiff
path: root/locale/setlocale.c
diff options
context:
space:
mode:
Diffstat (limited to 'locale/setlocale.c')
-rw-r--r--locale/setlocale.c73
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;
}
}