diff options
Diffstat (limited to 'locale/programs/localedef.c')
-rw-r--r-- | locale/programs/localedef.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c index 72eb2d36e2..e9fb6d57a6 100644 --- a/locale/programs/localedef.c +++ b/locale/programs/localedef.c @@ -1,6 +1,6 @@ /* Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. -Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>. +Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 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 @@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ #include "error.h" #include "charset.h" #include "locfile.h" +#include "../intl/loadinfo.h" /* Undefine the following line in the production version. */ /* #define NDEBUG 1 */ @@ -95,7 +96,7 @@ void *xmalloc (size_t __n); /* Prototypes for local functions. */ static void usage (int status) __attribute__ ((noreturn)); static void error_print (void); -static const char *construct_output_path (const char *path); +static const char *construct_output_path (char *path); int @@ -424,25 +425,50 @@ error_print () contain a '/' character it is a relativ path. Otherwise it names the locale this definition is for. */ static const char * -construct_output_path (const char *path) +construct_output_path (char *path) { + char *normal = NULL; char *result; if (strchr (path, '/') == NULL) { - /* This is a system path. */ - int path_max_len = pathconf (LOCALE_PATH, _PC_PATH_MAX) + 1; - result = (char *) xmalloc (path_max_len); + /* This is a system path. First examine whether the locale name + contains a reference to the codeset. This should be + normalized. */ + char *startp, *endp; + + startp = path; + /* We must be prepared for finding a CEN name or a location of + the introducing `.' where it is not possible anymore. */ + while (*startp != '\0' && *startp != '@' && *startp != '.' + && *startp != '+' && *startp != ',') + ++startp; + if (*startp == '.') + { + /* We found a codeset specification. Now find the end. */ + endp = ++startp; + while (*endp != '\0' && *endp != '@') + ++endp; + + if (endp > startp) + normal = _nl_normalize_codeset (startp, endp - startp); + } - snprintf (result, path_max_len, "%s/%s", LOCALE_PATH, path); + /* We put an additional '\0' at the end of the string because at + the end of the function we need another byte for the trailing + '/'. */ + if (normal == NULL) + asprintf (&result, "%s/%s\0", LOCALE_PATH, path); + else + asprintf (&result, "%s/%.*s%s%s\0", LOCALE_PATH, startp - path, path, + normal, endp); } else { - char *t; - /* This is a user path. */ + /* This is a user path. Please note the additional byte in the + memory allocation. */ result = xmalloc (strlen (path) + 2); - t = stpcpy (result, path); - *t = '\0'; + strcpy (result, path); } errno = 0; |