aboutsummaryrefslogtreecommitdiff
path: root/intl/localealias.c
diff options
context:
space:
mode:
Diffstat (limited to 'intl/localealias.c')
-rw-r--r--intl/localealias.c186
1 files changed, 105 insertions, 81 deletions
diff --git a/intl/localealias.c b/intl/localealias.c
index 1d3f8ebabf..ff13ddeccd 100644
--- a/intl/localealias.c
+++ b/intl/localealias.c
@@ -1,20 +1,18 @@
/* Handle aliases for locale names.
Copyright (C) 1995-2014 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 Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
+ This program 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
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
This must come before <config.h> because <config.h> may include
@@ -39,14 +37,19 @@
# define alloca __builtin_alloca
# define HAVE_ALLOCA 1
#else
-# if defined HAVE_ALLOCA_H || defined _LIBC
-# include <alloca.h>
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
# else
-# ifdef _AIX
- #pragma alloca
+# if defined HAVE_ALLOCA_H || defined _LIBC
+# include <alloca.h>
# else
-# ifndef alloca
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca
char *alloca ();
+# endif
# endif
# endif
# endif
@@ -57,6 +60,12 @@ char *alloca ();
#include "gettextP.h"
+#ifdef ENABLE_RELOCATABLE
+# include "relocatable.h"
+#else
+# define relocate(pathname) (pathname)
+#endif
+
/* @@ end of prolog @@ */
#ifdef _LIBC
@@ -70,11 +79,13 @@ char *alloca ();
# endif
# define HAVE_MEMPCPY 1
# define HAVE___FSETLOCKING 1
+#endif
-/* We need locking here since we can be called from different places. */
+/* Handle multi-threaded applications. */
+#ifdef _LIBC
# include <bits/libc-lock.h>
-
-__libc_lock_define_initialized (static, lock);
+#else
+# include "lock.h"
#endif
#ifndef internal_function
@@ -99,16 +110,19 @@ __libc_lock_define_initialized (static, lock);
# define freea(p) free (p)
#endif
-#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
+#if defined _LIBC_REENTRANT || defined HAVE_DECL_FGETS_UNLOCKED
# undef fgets
# define fgets(buf, len, s) fgets_unlocked (buf, len, s)
#endif
-#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED
+#if defined _LIBC_REENTRANT || defined HAVE_DECL_FEOF_UNLOCKED
# undef feof
# define feof(s) feof_unlocked (s)
#endif
+__libc_lock_define_initialized (static, lock)
+
+
struct alias_map
{
const char *alias;
@@ -129,25 +143,25 @@ static size_t maxmap;
/* Prototypes for local functions. */
-static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
+static size_t read_alias_file (const char *fname, int fname_len)
internal_function;
-static int extend_alias_table PARAMS ((void));
-static int alias_compare PARAMS ((const struct alias_map *map1,
- const struct alias_map *map2));
+static int extend_alias_table (void);
+static int alias_compare (const struct alias_map *map1,
+ const struct alias_map *map2);
const char *
-_nl_expand_alias (name)
- const char *name;
+_nl_expand_alias (const char *name)
{
- static const char *locale_alias_path = LOCALE_ALIAS_PATH;
+ static const char *locale_alias_path;
struct alias_map *retval;
const char *result = NULL;
size_t added;
-#ifdef _LIBC
__libc_lock_lock (lock);
-#endif
+
+ if (locale_alias_path == NULL)
+ locale_alias_path = LOCALE_ALIAS_PATH;
do
{
@@ -158,8 +172,8 @@ _nl_expand_alias (name)
if (nmap > 0)
retval = (struct alias_map *) bsearch (&item, map, nmap,
sizeof (struct alias_map),
- (int (*) PARAMS ((const void *,
- const void *))
+ (int (*) (const void *,
+ const void *)
) alias_compare);
else
retval = NULL;
@@ -177,11 +191,12 @@ _nl_expand_alias (name)
{
const char *start;
- while (locale_alias_path[0] == ':')
+ while (locale_alias_path[0] == PATH_SEPARATOR)
++locale_alias_path;
start = locale_alias_path;
- while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
+ while (locale_alias_path[0] != '\0'
+ && locale_alias_path[0] != PATH_SEPARATOR)
++locale_alias_path;
if (start < locale_alias_path)
@@ -190,9 +205,7 @@ _nl_expand_alias (name)
}
while (added != 0);
-#ifdef _LIBC
__libc_lock_unlock (lock);
-#endif
return result;
}
@@ -200,9 +213,7 @@ _nl_expand_alias (name)
static size_t
internal_function
-read_alias_file (fname, fname_len)
- const char *fname;
- int fname_len;
+read_alias_file (const char *fname, int fname_len)
{
FILE *fp;
char *full_fname;
@@ -218,9 +229,13 @@ read_alias_file (fname, fname_len)
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
#endif
+#ifdef _LIBC
/* Note the file is opened with cancellation in the I/O functions
disabled. */
- fp = fopen (full_fname, "rce");
+ fp = fopen (relocate (full_fname), "rce");
+#else
+ fp = fopen (relocate (full_fname), "r");
+#endif
freea (full_fname);
if (fp == NULL)
return 0;
@@ -274,9 +289,6 @@ read_alias_file (fname, fname_len)
if (cp[0] != '\0')
{
- size_t alias_len;
- size_t value_len;
-
value = cp++;
while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
++cp;
@@ -292,48 +304,62 @@ read_alias_file (fname, fname_len)
else if (cp[0] != '\0')
*cp++ = '\0';
- if (nmap >= maxmap)
- if (__glibc_unlikely (extend_alias_table ()))
- goto out;
+#ifdef IN_LIBGLOCALE
+ /* glibc's locale.alias contains entries for ja_JP and ko_KR
+ that make it impossible to use a Japanese or Korean UTF-8
+ locale under the name "ja_JP" or "ko_KR". Ignore these
+ entries. */
+ if (strchr (alias, '_') == NULL)
+#endif
+ {
+ size_t alias_len;
+ size_t value_len;
- alias_len = strlen (alias) + 1;
- value_len = strlen (value) + 1;
+ if (nmap >= maxmap)
+ if (__builtin_expect (extend_alias_table (), 0))
+ goto out;
- if (string_space_act + alias_len + value_len > string_space_max)
- {
- /* Increase size of memory pool. */
- size_t new_size = (string_space_max
- + (alias_len + value_len > 1024
- ? alias_len + value_len : 1024));
- char *new_pool = (char *) realloc (string_space, new_size);
- if (new_pool == NULL)
- goto out;
-
- if (__glibc_unlikely (string_space != new_pool))
- {
- size_t i;
+ alias_len = strlen (alias) + 1;
+ value_len = strlen (value) + 1;
- for (i = 0; i < nmap; i++)
+ if (string_space_act + alias_len + value_len > string_space_max)
+ {
+ /* Increase size of memory pool. */
+ size_t new_size = (string_space_max
+ + (alias_len + value_len > 1024
+ ? alias_len + value_len : 1024));
+ char *new_pool = (char *) realloc (string_space, new_size);
+ if (new_pool == NULL)
+ goto out;
+
+ if (__builtin_expect (string_space != new_pool, 0))
{
- map[i].alias += new_pool - string_space;
- map[i].value += new_pool - string_space;
+ size_t i;
+
+ for (i = 0; i < nmap; i++)
+ {
+ map[i].alias += new_pool - string_space;
+ map[i].value += new_pool - string_space;
+ }
}
- }
- string_space = new_pool;
- string_space_max = new_size;
- }
+ string_space = new_pool;
+ string_space_max = new_size;
+ }
- map[nmap].alias = memcpy (&string_space[string_space_act],
- alias, alias_len);
- string_space_act += alias_len;
+ map[nmap].alias =
+ (const char *) memcpy (&string_space[string_space_act],
+ alias, alias_len);
+ string_space_act += alias_len;
- map[nmap].value = memcpy (&string_space[string_space_act],
- value, value_len);
- string_space_act += value_len;
+ map[nmap].value =
+ (const char *) memcpy (&string_space[string_space_act],
+ value, value_len);
+ string_space_act += value_len;
- ++nmap;
- ++added;
+ ++nmap;
+ ++added;
+ }
}
}
@@ -348,14 +374,14 @@ read_alias_file (fname, fname_len)
while (strchr (buf, '\n') == NULL);
}
-out:
+ out:
/* Should we test for ferror()? I think we have to silently ignore
errors. --drepper */
fclose (fp);
if (added > 0)
qsort (map, nmap, sizeof (struct alias_map),
- (int (*) PARAMS ((const void *, const void *))) alias_compare);
+ (int (*) (const void *, const void *)) alias_compare);
return added;
}
@@ -381,9 +407,7 @@ extend_alias_table (void)
static int
-alias_compare (map1, map2)
- const struct alias_map *map1;
- const struct alias_map *map2;
+alias_compare (const struct alias_map *map1, const struct alias_map *map2)
{
#if defined _LIBC || defined HAVE_STRCASECMP
return strcasecmp (map1->alias, map2->alias);