|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* Handle aliases for locale names
|
|
|
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. |
|
|
|
/* Handle aliases for locale names.
|
|
|
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. |
|
|
|
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. |
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify |
|
|
|
@ -79,6 +79,14 @@ void free (); |
|
|
|
because some ANSI C functions will require linking with this object |
|
|
|
file and the name space must not be polluted. */ |
|
|
|
# define strcasecmp __strcasecmp |
|
|
|
|
|
|
|
# define mempcpy __mempcpy |
|
|
|
# define HAVE_MEMPCPY 1 |
|
|
|
|
|
|
|
/* We need locking here since we can be called from different places. */ |
|
|
|
# include <bits/libc-lock.h> |
|
|
|
|
|
|
|
__libc_lock_define_initialized (static, lock); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
@ -125,13 +133,17 @@ struct alias_map |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static char *string_space = NULL; |
|
|
|
static size_t string_space_act = 0; |
|
|
|
static size_t string_space_max = 0; |
|
|
|
static struct alias_map *map; |
|
|
|
static size_t nmap = 0; |
|
|
|
static size_t maxmap = 0; |
|
|
|
|
|
|
|
|
|
|
|
/* Prototypes for local functions. */ |
|
|
|
static size_t read_alias_file PARAMS ((const char *fname, int fname_len)); |
|
|
|
static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) |
|
|
|
internal_function; |
|
|
|
static void extend_alias_table PARAMS ((void)); |
|
|
|
static int alias_compare PARAMS ((const struct alias_map *map1, |
|
|
|
const struct alias_map *map2)); |
|
|
|
@ -143,8 +155,13 @@ _nl_expand_alias (name) |
|
|
|
{ |
|
|
|
static const char *locale_alias_path = LOCALE_ALIAS_PATH; |
|
|
|
struct alias_map *retval; |
|
|
|
const char *result = NULL; |
|
|
|
size_t added; |
|
|
|
|
|
|
|
#ifdef _LIBC |
|
|
|
__libc_lock_lock (lock); |
|
|
|
#endif |
|
|
|
|
|
|
|
do |
|
|
|
{ |
|
|
|
struct alias_map item; |
|
|
|
@ -162,7 +179,10 @@ _nl_expand_alias (name) |
|
|
|
|
|
|
|
/* We really found an alias. Return the value. */ |
|
|
|
if (retval != NULL) |
|
|
|
return retval->value; |
|
|
|
{ |
|
|
|
result = retval->value; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
/* Perhaps we can find another alias file. */ |
|
|
|
added = 0; |
|
|
|
@ -183,11 +203,16 @@ _nl_expand_alias (name) |
|
|
|
} |
|
|
|
while (added != 0); |
|
|
|
|
|
|
|
return NULL; |
|
|
|
#ifdef _LIBC |
|
|
|
__libc_lock_unlock (lock); |
|
|
|
#endif |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static size_t |
|
|
|
internal_function |
|
|
|
read_alias_file (fname, fname_len) |
|
|
|
const char *fname; |
|
|
|
int fname_len; |
|
|
|
@ -202,8 +227,13 @@ read_alias_file (fname, fname_len) |
|
|
|
|
|
|
|
full_fname = (char *) alloca (fname_len + sizeof aliasfile); |
|
|
|
ADD_BLOCK (block_list, full_fname); |
|
|
|
#ifdef HAVE_MEMPCPY |
|
|
|
mempcpy (mempcpy (full_fname, fname, fname_len), |
|
|
|
aliasfile, sizeof aliasfile); |
|
|
|
#else |
|
|
|
memcpy (full_fname, fname, fname_len); |
|
|
|
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); |
|
|
|
#endif |
|
|
|
|
|
|
|
fp = fopen (full_fname, "r"); |
|
|
|
if (fp == NULL) |
|
|
|
@ -220,15 +250,28 @@ read_alias_file (fname, fname_len) |
|
|
|
b) these fields must be usable as file names and so must not |
|
|
|
be that long |
|
|
|
*/ |
|
|
|
char buf[BUFSIZ]; |
|
|
|
char *alias; |
|
|
|
char *value; |
|
|
|
char *cp; |
|
|
|
unsigned char buf[BUFSIZ]; |
|
|
|
unsigned char *alias; |
|
|
|
unsigned char *value; |
|
|
|
unsigned char *cp; |
|
|
|
|
|
|
|
if (fgets (buf, BUFSIZ, fp) == NULL) |
|
|
|
if (fgets (buf, sizeof buf, fp) == NULL) |
|
|
|
/* EOF reached. */ |
|
|
|
break; |
|
|
|
|
|
|
|
/* Possibly not the whole line fits into the buffer. Ignore
|
|
|
|
the rest of the line. */ |
|
|
|
if (strchr (buf, '\n') == NULL) |
|
|
|
{ |
|
|
|
char altbuf[BUFSIZ]; |
|
|
|
do |
|
|
|
if (fgets (altbuf, sizeof altbuf, fp) == NULL) |
|
|
|
/* Make sure the inner loop will be left. The outer loop
|
|
|
|
will exit at the `feof' test. */ |
|
|
|
break; |
|
|
|
while (strchr (altbuf, '\n') == NULL); |
|
|
|
} |
|
|
|
|
|
|
|
cp = buf; |
|
|
|
/* Ignore leading white space. */ |
|
|
|
while (isspace (cp[0])) |
|
|
|
@ -250,8 +293,8 @@ read_alias_file (fname, fname_len) |
|
|
|
|
|
|
|
if (cp[0] != '\0') |
|
|
|
{ |
|
|
|
char *tp; |
|
|
|
size_t len; |
|
|
|
size_t alias_len; |
|
|
|
size_t value_len; |
|
|
|
|
|
|
|
value = cp++; |
|
|
|
while (cp[0] != '\0' && !isspace (cp[0])) |
|
|
|
@ -271,42 +314,37 @@ read_alias_file (fname, fname_len) |
|
|
|
if (nmap >= maxmap) |
|
|
|
extend_alias_table (); |
|
|
|
|
|
|
|
/* We cannot depend on strdup available in the libc. Sigh! */ |
|
|
|
len = strlen (alias) + 1; |
|
|
|
tp = (char *) malloc (len); |
|
|
|
if (tp == NULL) |
|
|
|
{ |
|
|
|
FREE_BLOCKS (block_list); |
|
|
|
return added; |
|
|
|
} |
|
|
|
memcpy (tp, alias, len); |
|
|
|
map[nmap].alias = tp; |
|
|
|
alias_len = strlen (alias) + 1; |
|
|
|
value_len = strlen (value) + 1; |
|
|
|
|
|
|
|
len = strlen (value) + 1; |
|
|
|
tp = (char *) malloc (len); |
|
|
|
if (tp == NULL) |
|
|
|
if (string_space_act + alias_len + value_len > string_space_max) |
|
|
|
{ |
|
|
|
FREE_BLOCKS (block_list); |
|
|
|
return added; |
|
|
|
/* 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) |
|
|
|
{ |
|
|
|
FREE_BLOCKS (block_list); |
|
|
|
return added; |
|
|
|
} |
|
|
|
string_space = new_pool; |
|
|
|
string_space_max = new_size; |
|
|
|
} |
|
|
|
memcpy (tp, value, len); |
|
|
|
map[nmap].value = tp; |
|
|
|
|
|
|
|
map[nmap].alias = 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; |
|
|
|
|
|
|
|
++nmap; |
|
|
|
++added; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Possibly not the whole line fits into the buffer. Ignore
|
|
|
|
the rest of the line. */ |
|
|
|
while (strchr (cp, '\n') == NULL) |
|
|
|
{ |
|
|
|
cp = buf; |
|
|
|
if (fgets (buf, BUFSIZ, fp) == NULL) |
|
|
|
/* Make sure the inner loop will be left. The outer loop
|
|
|
|
will exit at the `feof' test. */ |
|
|
|
*cp = '\n'; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Should we test for ferror()? I think we have to silently ignore
|
|
|
|
@ -329,22 +367,30 @@ extend_alias_table () |
|
|
|
struct alias_map *new_map; |
|
|
|
|
|
|
|
new_size = maxmap == 0 ? 100 : 2 * maxmap; |
|
|
|
new_map = (struct alias_map *) malloc (new_size |
|
|
|
* sizeof (struct alias_map)); |
|
|
|
new_map = (struct alias_map *) realloc (map, (new_size |
|
|
|
* sizeof (struct alias_map))); |
|
|
|
if (new_map == NULL) |
|
|
|
/* Simply don't extend: we don't have any more core. */ |
|
|
|
return; |
|
|
|
|
|
|
|
memcpy (new_map, map, nmap * sizeof (struct alias_map)); |
|
|
|
|
|
|
|
if (maxmap != 0) |
|
|
|
free (map); |
|
|
|
|
|
|
|
map = new_map; |
|
|
|
maxmap = new_size; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef _LIBC |
|
|
|
static void __attribute__ ((unused)) |
|
|
|
free_mem (void) |
|
|
|
{ |
|
|
|
if (string_space != NULL) |
|
|
|
free (string_space); |
|
|
|
if (map != NULL) |
|
|
|
free (map); |
|
|
|
} |
|
|
|
text_set_element (__libc_subfreeres, free_mem); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
alias_compare (map1, map2) |
|
|
|
const struct alias_map *map1; |
|
|
|
|