aboutsummaryrefslogtreecommitdiff
path: root/locale
diff options
context:
space:
mode:
Diffstat (limited to 'locale')
-rw-r--r--locale/locale.h36
-rw-r--r--locale/newlocale.c10
2 files changed, 37 insertions, 9 deletions
diff --git a/locale/locale.h b/locale/locale.h
index 34463fd55e..c84eb01e8b 100644
--- a/locale/locale.h
+++ b/locale/locale.h
@@ -144,15 +144,43 @@ typedef __locale_t locale_t;
/* Return a reference to a data structure representing a set of locale
datasets. Unlike for the CATEGORY parameter for `setlocale' the
- CATEGORY_MASK parameter here uses a single bit for each category.
- I.e., 1 << LC_CTYPE means to load data for this category. If
- BASE is non-null the appropriate category information in the BASE
- record is replaced. */
+ CATEGORY_MASK parameter here uses a single bit for each category,
+ made by OR'ing together LC_*_MASK bits above. */
extern __locale_t __newlocale (int __category_mask, __const char *__locale,
__locale_t __base) __THROW;
extern __locale_t newlocale (int __category_mask, __const char *__locale,
__locale_t __base) __THROW;
+/* These are the bits that can be set in the CATEGORY_MASK argument to
+ `newlocale'. In the GNU implementation, LC_FOO_MASK has the value
+ of (1 << LC_FOO), but this is not a part of the interface that
+ callers can assume will be true. */
+# define LC_CTYPE_MASK (1 << __LC_CTYPE)
+# define LC_NUMERIC_MASK (1 << __LC_NUMERIC)
+# define LC_TIME_MASK (1 << __LC_TIME)
+# define LC_COLLATE_MASK (1 << __LC_COLLATE)
+# define LC_MONETARY_MASK (1 << __LC_MONETARY)
+# define LC_MESSAGES_MASK (1 << __LC_MESSAGES)
+# define LC_PAPER_MASK (1 << __LC_PAPER)
+# define LC_NAME_MASK (1 << __LC_NAME)
+# define LC_ADDRESS_MASK (1 << __LC_ADDRESS)
+# define LC_TELEPHONE_MASK (1 << __LC_TELEPHONE)
+# define LC_MEASUREMENT_MASK (1 << __LC_MEASUREMENT)
+# define LC_IDENTIFICATION_MASK (1 << __LC_IDENTIFICATION)
+# define LC_ALL_MASK (LC_CTYPE_MASK \
+ | LC_NUMERIC_MASK \
+ | LC_TIME_MASK \
+ | LC_COLLATE_MASK \
+ | LC_MONETARY_MASK \
+ | LC_MESSAGES_MASK \
+ | LC_PAPER_MASK \
+ | LC_NAME_MASK \
+ | LC_ADDRESS_MASK \
+ | LC_TELEPHONE_MASK \
+ | LC_MEASUREMENT_MASK \
+ | LC_IDENTIFICATION_MASK \
+ )
+
/* Return a duplicate of the set of locale in DATASET. All usage
counters are increased if necessary. */
extern __locale_t __duplocale (__locale_t __dataset) __THROW;
diff --git a/locale/newlocale.c b/locale/newlocale.c
index 1442f86e81..6bab98e219 100644
--- a/locale/newlocale.c
+++ b/locale/newlocale.c
@@ -104,6 +104,7 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
/* This is a composite name. Make a copy and split it up. */
char *np = strdupa (locale);
char *cp;
+ int specified_mask = 0;
while ((cp = strchr (np, '=')) != NULL)
{
@@ -118,6 +119,7 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
ERROR_RETURN;
/* Found the category this clause sets. */
+ specified_mask |= 1 << cnt;
newnames[cnt] = ++cp;
cp = strchr (cp, ';');
if (cp != NULL)
@@ -131,11 +133,9 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
break;
}
- for (cnt = 0; cnt < __LC_LAST; ++cnt)
- if (cnt != LC_ALL
- && (category_mask & 1 << cnt) != 0 && newnames[cnt] == locale)
- /* The composite name did not specify the category we need. */
- ERROR_RETURN;
+ if (category_mask &~ specified_mask)
+ /* The composite name did not specify all categories we need. */
+ ERROR_RETURN;
}
/* Now process all categories we are interested in. */