l10nflist.c revision efc6f628e15de95bcd13e4f0ee223cb42115d520
1b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o/* Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
25bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
35bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   This program is free software; you can redistribute it and/or modify it
5a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   under the terms of the GNU Library General Public License as published
6a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   by the Free Software Foundation; either version 2, or (at your option)
75bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   any later version.
85bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
95bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   This program is distributed in the hope that it will be useful,
105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   but WITHOUT ANY WARRANTY; without even the implied warranty of
11a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   Library General Public License for more details.
13a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
14a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   You should have received a copy of the GNU Library General Public
15a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   License along with this program; if not, write to the Free Software
16a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   USA.  */
18a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
19a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o/* Tell glibc's <string.h> to provide a prototype for stpcpy().
20a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   This must come before <config.h> because <config.h> may include
21a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   <features.h>, and once <features.h> has been included, it's too late.  */
22a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#ifndef _GNU_SOURCE
23a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define _GNU_SOURCE	1
24a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#endif
255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#ifdef HAVE_CONFIG_H
275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <config.h>
285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
30a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#include <string.h>
315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if defined _LIBC || defined HAVE_ARGZ_H
335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <argz.h>
345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#include <ctype.h>
365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#include <sys/types.h>
37a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#include <stdlib.h>
385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#include "loadinfo.h"
405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* On some strange systems still no definition of NULL is found.  Sigh!  */
425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#ifndef NULL
435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# if defined __STDC__ && __STDC__
445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define NULL ((void *) 0)
455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# else
465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define NULL 0
475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* @@ end of prolog @@ */
515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#ifdef _LIBC
535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Rename the non ANSI C functions.  This is required by the standard
545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   because some ANSI C functions will require linking with this object
555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   file and the name space must not be polluted.  */
565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef stpcpy
575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define stpcpy(dest, src) __stpcpy(dest, src)
585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#else
605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef HAVE_STPCPY
61b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostatic char *stpcpy (char *dest, const char *src);
625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
65a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o/* Pathname support.
66a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   ISSLASH(C)           tests whether C is a directory separator character.
67a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   IS_ABSOLUTE_PATH(P)  tests whether P is an absolute path.  If it is not,
68a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o                        it may be concatenated to a directory pathname.
69a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o */
70a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
71a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Win32, OS/2, DOS */
72a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define ISSLASH(C) ((C) == '/' || (C) == '\\')
73a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define HAS_DEVICE(P) \
74a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
75a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     && (P)[1] == ':')
76a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
77a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#else
78a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Unix */
79a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define ISSLASH(C) ((C) == '/')
80a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
81a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#endif
82a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Define function which are usually not available.  */
845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Returns the number of strings in ARGZ.  */
875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic size_t
88b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oargz_count__ (const char *argz, size_t len)
895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t count = 0;
915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while (len > 0)
925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      size_t part_len = strlen (argz);
945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      argz += part_len + 1;
955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      len -= part_len + 1;
965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      count++;
975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return count;
995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_count
1015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_count(argz, len) argz_count__ (argz, len)
102a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#else
103a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# ifdef _LIBC
104a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#  define __argz_count(argz, len) INTUSE(__argz_count) (argz, len)
105a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# endif
1065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_COUNT */
1075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
1095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
1105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   except the last into the character SEP.  */
1115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic void
112b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oargz_stringify__ (char *argz, size_t len, int sep)
1135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while (len > 0)
1155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
1165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      size_t part_len = strlen (argz);
1175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      argz += part_len;
1185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      len -= part_len + 1;
1195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (len > 0)
1205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	*argz++ = sep;
1215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
1225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1235bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_stringify
1245bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
125a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#else
126a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# ifdef _LIBC
127a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#  define __argz_stringify(argz, len, sep) \
128a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  INTUSE(__argz_stringify) (argz, len, sep)
129a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# endif
1305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_STRINGIFY */
1315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
1335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *
134b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oargz_next__ (char *argz, size_t argz_len, const char *entry)
1355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (entry)
1375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
1385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (entry < argz + argz_len)
1395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o        entry = strchr (entry, '\0') + 1;
1405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return entry >= argz + argz_len ? NULL : (char *) entry;
1425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
1435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  else
1445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if (argz_len > 0)
1455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return argz;
1465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    else
1475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return 0;
1485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_next
1505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
1515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_NEXT */
1525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Return number of bits set in X.  */
1555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic inline int
156b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'opop (int x)
1575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* We assume that no more than 16 bits are used.  */
1595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x & ~0x5555) >> 1) + (x & 0x5555);
1605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x & ~0x3333) >> 2) + (x & 0x3333);
1615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x >> 4) + x) & 0x0f0f;
1625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x >> 8) + x) & 0xff;
1635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return x;
1655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
167efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostruct loaded_l10nfile *
169b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
170b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *dirlist, size_t dirlist_len,
171b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    int mask, const char *language, const char *territory,
172b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *codeset, const char *normalized_codeset,
173b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *modifier, const char *special,
174b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *sponsor, const char *revision,
175b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *filename, int do_allocate)
1765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *abs_filename;
178a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  struct loaded_l10nfile **lastp;
1795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  struct loaded_l10nfile *retval;
1805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *cp;
181a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  size_t dirlist_count;
1825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t entries;
1835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int cnt;
1845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
185a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* If LANGUAGE contains an absolute directory specification, we ignore
186a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     DIRLIST.  */
187a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  if (IS_ABSOLUTE_PATH (language))
188a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    dirlist_len = 0;
189a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
1905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Allocate room for the full file name.  */
1915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  abs_filename = (char *) malloc (dirlist_len
1925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + strlen (language)
1935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & TERRITORY) != 0
1945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (territory) + 1 : 0)
1955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & XPG_CODESET) != 0
1965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (codeset) + 1 : 0)
1975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & XPG_NORM_CODESET) != 0
1985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (normalized_codeset) + 1 : 0)
1995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + (((mask & XPG_MODIFIER) != 0
2005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				      || (mask & CEN_AUDIENCE) != 0)
2015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (modifier) + 1 : 0)
2025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & CEN_SPECIAL) != 0
2035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (special) + 1 : 0)
2045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + (((mask & CEN_SPONSOR) != 0
2055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				      || (mask & CEN_REVISION) != 0)
2065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? (1 + ((mask & CEN_SPONSOR) != 0
207a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o					     ? strlen (sponsor) : 0)
2085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					+ ((mask & CEN_REVISION) != 0
2095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					   ? strlen (revision) + 1 : 0)) : 0)
2105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + 1 + strlen (filename) + 1);
2115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (abs_filename == NULL)
2135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    return NULL;
2145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Construct file name.  */
216a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  cp = abs_filename;
217a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  if (dirlist_len > 0)
218a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    {
219a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      memcpy (cp, dirlist, dirlist_len);
220a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      __argz_stringify (cp, dirlist_len, PATH_SEPARATOR);
221a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      cp += dirlist_len;
222a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      cp[-1] = '/';
223a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    }
224a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
2255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  cp = stpcpy (cp, language);
2265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & TERRITORY) != 0)
2285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '_';
2305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, territory);
2315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & XPG_CODESET) != 0)
2335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '.';
2355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, codeset);
2365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & XPG_NORM_CODESET) != 0)
2385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '.';
2405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, normalized_codeset);
2415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
2435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      /* This component can be part of both syntaces but has different
2455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	 leading characters.  For CEN we use `+', else `@'.  */
2465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
2475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, modifier);
2485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & CEN_SPECIAL) != 0)
2505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '+';
2525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, special);
2535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
2555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = ',';
2575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if ((mask & CEN_SPONSOR) != 0)
2585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	cp = stpcpy (cp, sponsor);
2595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if ((mask & CEN_REVISION) != 0)
2605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	{
2615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *cp++ = '_';
2625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  cp = stpcpy (cp, revision);
2635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	}
2645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  *cp++ = '/';
2675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  stpcpy (cp, filename);
2685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Look in list of already loaded domains whether it is already
2705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     available.  */
271a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  lastp = l10nfile_list;
2725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
2735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if (retval->filename != NULL)
2745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
2755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	int compare = strcmp (retval->filename, abs_filename);
2765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (compare == 0)
2775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  /* We found it!  */
2785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  break;
2795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (compare < 0)
2805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  {
2815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    /* It's not in the list.  */
2825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    retval = NULL;
2835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    break;
2845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  }
2855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
286a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	lastp = &retval->next;
2875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
2885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval != NULL || do_allocate == 0)
2905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      free (abs_filename);
2925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return retval;
2935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
295a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1);
296a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
297a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Allocate a new loaded_l10nfile.  */
298a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  retval =
299a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    (struct loaded_l10nfile *)
300a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    malloc (sizeof (*retval)
301a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0))
302a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	       * sizeof (struct loaded_l10nfile *)));
3035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval == NULL)
3045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    return NULL;
3055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->filename = abs_filename;
307a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
308a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* We set retval->data to NULL here; it is filled in later.
309a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     Setting retval->decided to 1 here means that retval does not
310a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     correspond to a real file (dirlist_count > 1) or is not worth
311a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     looking up (if an unnormalized codeset was specified).  */
312a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  retval->decided = (dirlist_count > 1
3135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o		     || ((mask & XPG_CODESET) != 0
3145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o			 && (mask & XPG_NORM_CODESET) != 0));
3155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->data = NULL;
3165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
317a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  retval->next = *lastp;
318a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  *lastp = retval;
3195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  entries = 0;
321a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Recurse to fill the inheritance list of RETVAL.
322a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL
323a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     entry does not correspond to a real file; retval->filename contains
324a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     colons.  In this case we loop across all elements of DIRLIST and
325a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     across all bit patterns dominated by MASK.
326a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     If the DIRLIST is a single directory or entirely redundant (i.e.
327a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     DIRLIST_COUNT == 1), we loop across all bit patterns dominated by
328a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     MASK, excluding MASK itself.
329a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     In either case, we loop down from MASK to 0.  This has the effect
330a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     that the extra bits in the locale name are dropped in this order:
331a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     first the modifier, then the territory, then the codeset, then the
332a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     normalized_codeset.  */
333a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt)
3345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if ((cnt & ~mask) == 0
3355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
3365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
3375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
338a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	if (dirlist_count > 1)
339a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	  {
340a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    /* Iterate over all elements of the DIRLIST.  */
341a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    char *dir = NULL;
342a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
343a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
344a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o		   != NULL)
345a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	      retval->successor[entries++]
346a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o		= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1,
347a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				      cnt, language, territory, codeset,
348a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				      normalized_codeset, modifier, special,
349a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				      sponsor, revision, filename, 1);
350a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	  }
351a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	else
3525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  retval->successor[entries++]
353a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len,
354a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				  cnt, language, territory, codeset,
3555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  normalized_codeset, modifier, special,
3565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  sponsor, revision, filename, 1);
3575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
3585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->successor[entries] = NULL;
3595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return retval;
3615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
362efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
3635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Normalize codeset name.  There is no standard for the codeset
3645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   names.  Normalization allows the user to use any of the common
365a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   names.  The return value is dynamically allocated and has to be
366a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   freed by the caller.  */
3675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'oconst char *
368b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o_nl_normalize_codeset (const char *codeset, size_t name_len)
3695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
3705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int len = 0;
3715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int only_digit = 1;
3725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *retval;
3735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *wp;
3745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t cnt;
3755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (cnt = 0; cnt < name_len; ++cnt)
377a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    if (isalnum ((unsigned char) codeset[cnt]))
3785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
3795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	++len;
3805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
381a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	if (isalpha ((unsigned char) codeset[cnt]))
3825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  only_digit = 0;
3835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
3845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
3865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval != NULL)
3885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
3895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (only_digit)
3905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	wp = stpcpy (retval, "iso");
3915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      else
3925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	wp = retval;
3935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      for (cnt = 0; cnt < name_len; ++cnt)
395a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	if (isalpha ((unsigned char) codeset[cnt]))
396a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	  *wp++ = tolower ((unsigned char) codeset[cnt]);
397a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	else if (isdigit ((unsigned char) codeset[cnt]))
3985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *wp++ = codeset[cnt];
3995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *wp = '\0';
4015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
4025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return (const char *) retval;
4045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
4055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* @@ begin of epilog @@ */
4085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* We don't want libintl.a to depend on any other library.  So we
4105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   avoid the non-standard function stpcpy.  In GNU C Library this
4115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   function is available, though.  Also allow the symbol HAVE_STPCPY
4125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   to be defined.  */
4135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !_LIBC && !HAVE_STPCPY
4145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *
415b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostpcpy (char *dest, const char *src)
4165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
4175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while ((*dest++ = *src++) != '\0')
4185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    /* Do nothing. */ ;
4195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return dest - 1;
4205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
4215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
422