]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - locale/findlocale.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / locale / findlocale.c
index 22e8b530320055ede07ec86929e4a4d549a85494..872cadb5b9fa5a8844bd7b3f6313bb02d49ce01c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -56,7 +56,7 @@ struct __locale_data *const _nl_C[] attribute_hidden =
    which are somehow addressed.  */
 struct loaded_l10nfile *_nl_locale_file_list[__LC_LAST];
 
-const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR;
+const char _nl_default_locale_path[] attribute_hidden = COMPLOCALEDIR;
 
 /* Checks if the name is actually present, that is, not NULL and not
    empty.  */
@@ -79,8 +79,8 @@ valid_locale_name (const char *name)
     return 0;
   /* Directory traversal attempt.  */
   static const char slashdot[4] = {'/', '.', '.', '/'};
-  if (__glibc_unlikely (memmem (name, namelen,
-                               slashdot, sizeof (slashdot)) != NULL))
+  if (__glibc_unlikely (__memmem (name, namelen,
+                                 slashdot, sizeof (slashdot)) != NULL))
     return 0;
   if (namelen == 2 && __glibc_unlikely (name[0] == '.' && name [1] == '.'))
     return 0;
@@ -99,13 +99,12 @@ valid_locale_name (const char *name)
 }
 
 struct __locale_data *
-internal_function
 _nl_find_locale (const char *locale_path, size_t locale_path_len,
                 int category, const char **name)
 {
   int mask;
   /* Name of the locale for this category.  */
-  char *loc_name = (char *) *name;
+  const char *cloc_name = *name;
   const char *language;
   const char *modifier;
   const char *territory;
@@ -113,39 +112,39 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
   const char *normalized_codeset;
   struct loaded_l10nfile *locale_file;
 
-  if (loc_name[0] == '\0')
+  if (cloc_name[0] == '\0')
     {
       /* The user decides which locale to use by setting environment
         variables.  */
-      loc_name = getenv ("LC_ALL");
-      if (!name_present (loc_name))
-       loc_name = getenv (_nl_category_names.str
-                       + _nl_category_name_idxs[category]);
-      if (!name_present (loc_name))
-       loc_name = getenv ("LANG");
-      if (!name_present (loc_name))
-       loc_name = (char *) _nl_C_name;
+      cloc_name = getenv ("LC_ALL");
+      if (!name_present (cloc_name))
+       cloc_name = getenv (_nl_category_names.str
+                           + _nl_category_name_idxs[category]);
+      if (!name_present (cloc_name))
+       cloc_name = getenv ("LANG");
+      if (!name_present (cloc_name))
+       cloc_name = _nl_C_name;
     }
 
   /* We used to fall back to the C locale if the name contains a slash
      character '/', but we now check for directory traversal in
      valid_locale_name, so this is no longer necessary.  */
 
-  if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0
-      || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0)
+  if (__builtin_expect (strcmp (cloc_name, _nl_C_name), 1) == 0
+      || __builtin_expect (strcmp (cloc_name, _nl_POSIX_name), 1) == 0)
     {
       /* We need not load anything.  The needed data is contained in
         the library itself.  */
-      *name = (char *) _nl_C_name;
+      *name = _nl_C_name;
       return _nl_C[category];
     }
-  else if (!valid_locale_name (loc_name))
+  else if (!valid_locale_name (cloc_name))
     {
       __set_errno (EINVAL);
       return NULL;
     }
 
-  *name = loc_name;
+  *name = cloc_name;
 
   /* We really have to load some data.  First we try the archive,
      but only if there was no LOCPATH environment variable specified.  */
@@ -156,21 +155,32 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
       if (__glibc_likely (data != NULL))
        return data;
 
+      /* Nothing in the archive with the given name.  Expanding it as
+        an alias and retry.  */
+      cloc_name = _nl_expand_alias (*name);
+      if (cloc_name != NULL)
+       {
+         data = _nl_load_locale_from_archive (category, &cloc_name);
+         if (__builtin_expect (data != NULL, 1))
+           return data;
+       }
+
       /* Nothing in the archive.  Set the default path to search below.  */
       locale_path = _nl_default_locale_path;
       locale_path_len = sizeof _nl_default_locale_path;
     }
+  else
+    /* We really have to load some data.  First see whether the name is
+       an alias.  Please note that this makes it impossible to have "C"
+       or "POSIX" as aliases.  */
+    cloc_name = _nl_expand_alias (*name);
 
-  /* We really have to load some data.  First see whether the name is
-     an alias.  Please note that this makes it impossible to have "C"
-     or "POSIX" as aliases.  */
-  loc_name = (char *) _nl_expand_alias (*name);
-  if (loc_name == NULL)
+  if (cloc_name == NULL)
     /* It is no alias.  */
-    loc_name = (char *) *name;
+    cloc_name = *name;
 
   /* Make a writable copy of the locale name.  */
-  loc_name = strdupa (loc_name);
+  char *loc_name = strdupa (cloc_name);
 
   /* LOCALE can consist of up to four recognized parts for the XPG syntax:
 
@@ -321,7 +331,6 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
 /* Calling this function assumes the lock for handling global locale data
    is acquired.  */
 void
-internal_function
 _nl_remove_locale (int locale, struct __locale_data *data)
 {
   if (--data->usage_count == 0)