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
610eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#define stpcpy(dest, src) my_stpcpy(dest, src)
62b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostatic char *stpcpy (char *dest, const char *src);
635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
66a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o/* Pathname support.
67a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   ISSLASH(C)           tests whether C is a directory separator character.
68a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   IS_ABSOLUTE_PATH(P)  tests whether P is an absolute path.  If it is not,
69a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o                        it may be concatenated to a directory pathname.
70a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o */
71a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
72a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Win32, OS/2, DOS */
73a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define ISSLASH(C) ((C) == '/' || (C) == '\\')
74a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define HAS_DEVICE(P) \
75a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
76a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     && (P)[1] == ':')
77a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
78a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#else
79a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Unix */
80a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define ISSLASH(C) ((C) == '/')
81a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
82a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#endif
83a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Define function which are usually not available.  */
855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Returns the number of strings in ARGZ.  */
885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic size_t
89b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oargz_count__ (const char *argz, size_t len)
905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t count = 0;
925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while (len > 0)
935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      size_t part_len = strlen (argz);
955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      argz += part_len + 1;
965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      len -= part_len + 1;
975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      count++;
985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return count;
1005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_count
1025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_count(argz, len) argz_count__ (argz, len)
103a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#else
104a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# ifdef _LIBC
105a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#  define __argz_count(argz, len) INTUSE(__argz_count) (argz, len)
106a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# endif
1075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_COUNT */
1085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
1105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
1115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   except the last into the character SEP.  */
1125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic void
113b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oargz_stringify__ (char *argz, size_t len, int sep)
1145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while (len > 0)
1165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
1175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      size_t part_len = strlen (argz);
1185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      argz += part_len;
1195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      len -= part_len + 1;
1205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (len > 0)
1215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	*argz++ = sep;
1225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
1235bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1245bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_stringify
1255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
126a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#else
127a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# ifdef _LIBC
128a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o#  define __argz_stringify(argz, len, sep) \
129a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  INTUSE(__argz_stringify) (argz, len, sep)
130a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o# endif
1315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_STRINGIFY */
1325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
1345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *
135b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oargz_next__ (char *argz, size_t argz_len, const char *entry)
1365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (entry)
1385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
1395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (entry < argz + argz_len)
1405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o        entry = strchr (entry, '\0') + 1;
1415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return entry >= argz + argz_len ? NULL : (char *) entry;
1435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
1445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  else
1455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if (argz_len > 0)
1465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return argz;
1475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    else
1485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return 0;
1495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_next
1515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
1525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_NEXT */
1535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Return number of bits set in X.  */
1565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic inline int
157b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'opop (int x)
1585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* We assume that no more than 16 bits are used.  */
1605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x & ~0x5555) >> 1) + (x & 0x5555);
1615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x & ~0x3333) >> 2) + (x & 0x3333);
1625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x >> 4) + x) & 0x0f0f;
1635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x >> 8) + x) & 0xff;
1645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return x;
1665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
168efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostruct loaded_l10nfile *
170b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
171b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *dirlist, size_t dirlist_len,
172b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    int mask, const char *language, const char *territory,
173b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *codeset, const char *normalized_codeset,
174b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *modifier, const char *special,
175b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *sponsor, const char *revision,
176b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o		    const char *filename, int do_allocate)
1775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *abs_filename;
179a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  struct loaded_l10nfile **lastp;
1805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  struct loaded_l10nfile *retval;
1815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *cp;
182a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  size_t dirlist_count;
1835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t entries;
1845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int cnt;
1855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
186a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* If LANGUAGE contains an absolute directory specification, we ignore
187a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     DIRLIST.  */
188a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  if (IS_ABSOLUTE_PATH (language))
189a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    dirlist_len = 0;
190a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
1915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Allocate room for the full file name.  */
1925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  abs_filename = (char *) malloc (dirlist_len
1935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + strlen (language)
1945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & TERRITORY) != 0
1955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (territory) + 1 : 0)
1965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & XPG_CODESET) != 0
1975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (codeset) + 1 : 0)
1985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & XPG_NORM_CODESET) != 0
1995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (normalized_codeset) + 1 : 0)
2005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + (((mask & XPG_MODIFIER) != 0
2015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				      || (mask & CEN_AUDIENCE) != 0)
2025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (modifier) + 1 : 0)
2035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & CEN_SPECIAL) != 0
2045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (special) + 1 : 0)
2055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + (((mask & CEN_SPONSOR) != 0
2065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				      || (mask & CEN_REVISION) != 0)
2075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? (1 + ((mask & CEN_SPONSOR) != 0
208a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o					     ? strlen (sponsor) : 0)
2095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					+ ((mask & CEN_REVISION) != 0
2105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					   ? strlen (revision) + 1 : 0)) : 0)
2115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + 1 + strlen (filename) + 1);
2125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (abs_filename == NULL)
2145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    return NULL;
2155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Construct file name.  */
217a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  cp = abs_filename;
218a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  if (dirlist_len > 0)
219a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    {
220a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      memcpy (cp, dirlist, dirlist_len);
221a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      __argz_stringify (cp, dirlist_len, PATH_SEPARATOR);
222a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      cp += dirlist_len;
223a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o      cp[-1] = '/';
224a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    }
225a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
2265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  cp = stpcpy (cp, language);
2275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & TERRITORY) != 0)
2295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '_';
2315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, territory);
2325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & XPG_CODESET) != 0)
2345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '.';
2365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, codeset);
2375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & XPG_NORM_CODESET) != 0)
2395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '.';
2415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, normalized_codeset);
2425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
2445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      /* This component can be part of both syntaces but has different
2465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	 leading characters.  For CEN we use `+', else `@'.  */
2475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
2485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, modifier);
2495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & CEN_SPECIAL) != 0)
2515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '+';
2535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, special);
2545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
2565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = ',';
2585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if ((mask & CEN_SPONSOR) != 0)
2595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	cp = stpcpy (cp, sponsor);
2605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if ((mask & CEN_REVISION) != 0)
2615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	{
2625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *cp++ = '_';
2635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  cp = stpcpy (cp, revision);
2645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	}
2655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  *cp++ = '/';
2685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  stpcpy (cp, filename);
2695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Look in list of already loaded domains whether it is already
2715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     available.  */
272a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  lastp = l10nfile_list;
2735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
2745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if (retval->filename != NULL)
2755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
2765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	int compare = strcmp (retval->filename, abs_filename);
2775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (compare == 0)
2785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  /* We found it!  */
2795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  break;
2805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (compare < 0)
2815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  {
2825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    /* It's not in the list.  */
2835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    retval = NULL;
2845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    break;
2855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  }
2865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
287a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	lastp = &retval->next;
2885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
2895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval != NULL || do_allocate == 0)
2915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      free (abs_filename);
2935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return retval;
2945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
296a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1);
297a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
298a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Allocate a new loaded_l10nfile.  */
299a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  retval =
300a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    (struct loaded_l10nfile *)
301a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    malloc (sizeof (*retval)
302a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0))
303a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	       * sizeof (struct loaded_l10nfile *)));
3045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval == NULL)
3055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    return NULL;
3065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->filename = abs_filename;
308a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
309a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* We set retval->data to NULL here; it is filled in later.
310a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     Setting retval->decided to 1 here means that retval does not
311a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     correspond to a real file (dirlist_count > 1) or is not worth
312a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     looking up (if an unnormalized codeset was specified).  */
313a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  retval->decided = (dirlist_count > 1
3145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o		     || ((mask & XPG_CODESET) != 0
3155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o			 && (mask & XPG_NORM_CODESET) != 0));
3165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->data = NULL;
3175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
318a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  retval->next = *lastp;
319a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  *lastp = retval;
3205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  entries = 0;
322a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  /* Recurse to fill the inheritance list of RETVAL.
323a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL
324a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     entry does not correspond to a real file; retval->filename contains
325a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     colons.  In this case we loop across all elements of DIRLIST and
326a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     across all bit patterns dominated by MASK.
327a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     If the DIRLIST is a single directory or entirely redundant (i.e.
328a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     DIRLIST_COUNT == 1), we loop across all bit patterns dominated by
329a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     MASK, excluding MASK itself.
330a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     In either case, we loop down from MASK to 0.  This has the effect
331a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     that the extra bits in the locale name are dropped in this order:
332a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     first the modifier, then the territory, then the codeset, then the
333a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o     normalized_codeset.  */
334a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o  for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt)
3355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if ((cnt & ~mask) == 0
3365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
3375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
3385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
339a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	if (dirlist_count > 1)
340a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	  {
341a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    /* Iterate over all elements of the DIRLIST.  */
342a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    char *dir = NULL;
343a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o
344a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
345a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o		   != NULL)
346a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	      retval->successor[entries++]
347a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o		= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1,
348a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				      cnt, language, territory, codeset,
349a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				      normalized_codeset, modifier, special,
350a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				      sponsor, revision, filename, 1);
351a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	  }
352a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	else
3535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  retval->successor[entries++]
354a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	    = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len,
355a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o				  cnt, language, territory, codeset,
3565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  normalized_codeset, modifier, special,
3575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  sponsor, revision, filename, 1);
3585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
3595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->successor[entries] = NULL;
3605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return retval;
3625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
363efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
3645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Normalize codeset name.  There is no standard for the codeset
3655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   names.  Normalization allows the user to use any of the common
366a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   names.  The return value is dynamically allocated and has to be
367a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o   freed by the caller.  */
3685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'oconst char *
369b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o_nl_normalize_codeset (const char *codeset, size_t name_len)
3705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
3715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int len = 0;
3725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int only_digit = 1;
3735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *retval;
3745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *wp;
3755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t cnt;
3765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (cnt = 0; cnt < name_len; ++cnt)
378a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o    if (isalnum ((unsigned char) codeset[cnt]))
3795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
3805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	++len;
3815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
382a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	if (isalpha ((unsigned char) codeset[cnt]))
3835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  only_digit = 0;
3845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
3855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
3875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval != NULL)
3895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
3905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (only_digit)
3915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	wp = stpcpy (retval, "iso");
3925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      else
3935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	wp = retval;
3945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      for (cnt = 0; cnt < name_len; ++cnt)
396a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	if (isalpha ((unsigned char) codeset[cnt]))
397a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	  *wp++ = tolower ((unsigned char) codeset[cnt]);
398a04eba3f8868af1d9b7b504d3d430c55ed3dc777Theodore Ts'o	else if (isdigit ((unsigned char) codeset[cnt]))
3995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *wp++ = codeset[cnt];
4005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *wp = '\0';
4025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
4035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return (const char *) retval;
4055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
4065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* @@ begin of epilog @@ */
4095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
4105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* We don't want libintl.a to depend on any other library.  So we
4115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   avoid the non-standard function stpcpy.  In GNU C Library this
4125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   function is available, though.  Also allow the symbol HAVE_STPCPY
4135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   to be defined.  */
4145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !_LIBC && !HAVE_STPCPY
4155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *
416b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostpcpy (char *dest, const char *src)
4175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
4185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while ((*dest++ = *src++) != '\0')
4195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    /* Do nothing. */ ;
4205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return dest - 1;
4215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
4225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
423