l10nflist.c revision 5bc5a89c2a5c07b0237c13d37d869c986b5435fb
15bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Handle list of needed message catalogs
25bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
35bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
45bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
55bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   This program is free software; you can redistribute it and/or modify
65bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   it under the terms of the GNU General Public License as published by
75bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   the Free Software Foundation; either version 2, or (at your option)
85bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   any later version.
95bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   This program is distributed in the hope that it will be useful,
115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   but WITHOUT ANY WARRANTY; without even the implied warranty of
125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   GNU General Public License for more details.
145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   You should have received a copy of the GNU General Public License
165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   along with this program; if not, write to the Free Software Foundation,
175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#ifdef HAVE_CONFIG_H
205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <config.h>
215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
235bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
245bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if defined HAVE_STRING_H || defined _LIBC
255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef _GNU_SOURCE
265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define _GNU_SOURCE	1
275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <string.h>
295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#else
305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <strings.h>
315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef memcpy
325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !HAVE_STRCHR && !defined _LIBC
365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef strchr
375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define strchr index
385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if defined _LIBC || defined HAVE_ARGZ_H
425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <argz.h>
435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#include <ctype.h>
455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#include <sys/types.h>
465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if defined STDC_HEADERS || defined _LIBC
485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# include <stdlib.h>
495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#include "loadinfo.h"
525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* On some strange systems still no definition of NULL is found.  Sigh!  */
545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#ifndef NULL
555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# if defined __STDC__ && __STDC__
565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define NULL ((void *) 0)
575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# else
585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define NULL 0
595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* @@ end of prolog @@ */
635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#ifdef _LIBC
655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Rename the non ANSI C functions.  This is required by the standard
665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   because some ANSI C functions will require linking with this object
675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   file and the name space must not be polluted.  */
685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef stpcpy
695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#  define stpcpy(dest, src) __stpcpy(dest, src)
705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#else
725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# ifndef HAVE_STPCPY
735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *stpcpy PARAMS ((char *dest, const char *src));
745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# endif
755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Define function which are usually not available.  */
785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Returns the number of strings in ARGZ.  */
815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic size_t argz_count__ PARAMS ((const char *argz, size_t len));
825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic size_t
845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'oargz_count__ (argz, len)
855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *argz;
865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     size_t len;
875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t count = 0;
895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while (len > 0)
905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      size_t part_len = strlen (argz);
925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      argz += part_len + 1;
935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      len -= part_len + 1;
945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      count++;
955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return count;
975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_count
995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_count(argz, len) argz_count__ (argz, len)
1005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_COUNT */
1015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
1035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
1045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   except the last into the character SEP.  */
1055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
1065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic void
1085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'oargz_stringify__ (argz, len, sep)
1095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     char *argz;
1105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     size_t len;
1115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     int sep;
1125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while (len > 0)
1145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
1155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      size_t part_len = strlen (argz);
1165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      argz += part_len;
1175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      len -= part_len + 1;
1185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (len > 0)
1195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	*argz++ = sep;
1205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
1215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# undef __argz_stringify
1235bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
1245bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif	/* !_LIBC && !HAVE___ARGZ_STRINGIFY */
1255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
1275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *argz_next__ PARAMS ((char *argz, size_t argz_len,
1285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  const char *entry));
1295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *
1315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'oargz_next__ (argz, argz_len, entry)
1325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     char *argz;
1335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     size_t argz_len;
1345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     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 int pop PARAMS ((int x));
1565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic inline int
1585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'opop (x)
1595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     int x;
1605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* We assume that no more than 16 bits are used.  */
1625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x & ~0x5555) >> 1) + (x & 0x5555);
1635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x & ~0x3333) >> 2) + (x & 0x3333);
1645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x >> 4) + x) & 0x0f0f;
1655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  x = ((x >> 8) + x) & 0xff;
1665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return x;
1685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
1695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostruct loaded_l10nfile *
1725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
1735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o		    territory, codeset, normalized_codeset, modifier, special,
1745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o		    sponsor, revision, filename, do_allocate)
1755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     struct loaded_l10nfile **l10nfile_list;
1765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *dirlist;
1775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     size_t dirlist_len;
1785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     int mask;
1795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *language;
1805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *territory;
1815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *codeset;
1825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *normalized_codeset;
1835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *modifier;
1845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *special;
1855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *sponsor;
1865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *revision;
1875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *filename;
1885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     int do_allocate;
1895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
1905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *abs_filename;
1915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  struct loaded_l10nfile *last = NULL;
1925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  struct loaded_l10nfile *retval;
1935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *cp;
1945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t entries;
1955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int cnt;
1965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
1975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Allocate room for the full file name.  */
1985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  abs_filename = (char *) malloc (dirlist_len
1995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + strlen (language)
2005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & TERRITORY) != 0
2015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (territory) + 1 : 0)
2025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & XPG_CODESET) != 0
2035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (codeset) + 1 : 0)
2045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & XPG_NORM_CODESET) != 0
2055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (normalized_codeset) + 1 : 0)
2065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + (((mask & XPG_MODIFIER) != 0
2075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				      || (mask & CEN_AUDIENCE) != 0)
2085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (modifier) + 1 : 0)
2095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + ((mask & CEN_SPECIAL) != 0
2105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? strlen (special) + 1 : 0)
2115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + (((mask & CEN_SPONSOR) != 0
2125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				      || (mask & CEN_REVISION) != 0)
2135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				     ? (1 + ((mask & CEN_SPONSOR) != 0
2145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					     ? strlen (sponsor) + 1 : 0)
2155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					+ ((mask & CEN_REVISION) != 0
2165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o					   ? strlen (revision) + 1 : 0)) : 0)
2175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  + 1 + strlen (filename) + 1);
2185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (abs_filename == NULL)
2205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    return NULL;
2215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval = NULL;
2235bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  last = NULL;
2245bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Construct file name.  */
2265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  memcpy (abs_filename, dirlist, dirlist_len);
2275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  __argz_stringify (abs_filename, dirlist_len, ':');
2285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  cp = abs_filename + (dirlist_len - 1);
2295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  *cp++ = '/';
2305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  cp = stpcpy (cp, language);
2315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & TERRITORY) != 0)
2335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '_';
2355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, territory);
2365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & XPG_CODESET) != 0)
2385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '.';
2405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, codeset);
2415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & XPG_NORM_CODESET) != 0)
2435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '.';
2455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, normalized_codeset);
2465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
2485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      /* This component can be part of both syntaces but has different
2505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	 leading characters.  For CEN we use `+', else `@'.  */
2515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
2525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, modifier);
2535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & CEN_SPECIAL) != 0)
2555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = '+';
2575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      cp = stpcpy (cp, special);
2585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
2605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *cp++ = ',';
2625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if ((mask & CEN_SPONSOR) != 0)
2635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	cp = stpcpy (cp, sponsor);
2645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if ((mask & CEN_REVISION) != 0)
2655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	{
2665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *cp++ = '_';
2675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  cp = stpcpy (cp, revision);
2685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	}
2695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  *cp++ = '/';
2725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  stpcpy (cp, filename);
2735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* Look in list of already loaded domains whether it is already
2755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     available.  */
2765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  last = NULL;
2775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
2785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if (retval->filename != NULL)
2795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
2805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	int compare = strcmp (retval->filename, abs_filename);
2815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (compare == 0)
2825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  /* We found it!  */
2835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  break;
2845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (compare < 0)
2855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  {
2865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    /* It's not in the list.  */
2875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    retval = NULL;
2885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    break;
2895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  }
2905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	last = retval;
2925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
2935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
2945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval != NULL || do_allocate == 0)
2955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
2965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      free (abs_filename);
2975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      return retval;
2985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
2995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval = (struct loaded_l10nfile *)
3015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
3025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				* (1 << pop (mask))
3035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore 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;
3085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->decided = (__argz_count (dirlist, dirlist_len) != 1
3095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o		     || ((mask & XPG_CODESET) != 0
3105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o			 && (mask & XPG_NORM_CODESET) != 0));
3115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->data = NULL;
3125bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3135bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (last == NULL)
3145bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
3155bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      retval->next = *l10nfile_list;
3165bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *l10nfile_list = retval;
3175bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
3185bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  else
3195bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
3205bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      retval->next = last->next;
3215bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      last->next = retval;
3225bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
3235bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3245bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  entries = 0;
3255bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  /* If the DIRLIST is a real list the RETVAL entry corresponds not to
3265bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     a real file.  So we have to use the DIRLIST separation mechanism
3275bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     of the inner loop.  */
3285bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
3295bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (; cnt >= 0; --cnt)
3305bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if ((cnt & ~mask) == 0
3315bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
3325bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
3335bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
3345bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	/* Iterate over all elements of the DIRLIST.  */
3355bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	char *dir = NULL;
3365bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3375bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
3385bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	       != NULL)
3395bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  retval->successor[entries++]
3405bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	    = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
3415bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  language, territory, codeset,
3425bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  normalized_codeset, modifier, special,
3435bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o				  sponsor, revision, filename, 1);
3445bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
3455bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval->successor[entries] = NULL;
3465bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3475bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return retval;
3485bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
3495bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3505bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* Normalize codeset name.  There is no standard for the codeset
3515bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   names.  Normalization allows the user to use any of the common
3525bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   names.  */
3535bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'oconst char *
3545bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o_nl_normalize_codeset (codeset, name_len)
3555bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const unsigned char *codeset;
3565bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     size_t name_len;
3575bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
3585bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int len = 0;
3595bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  int only_digit = 1;
3605bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *retval;
3615bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  char *wp;
3625bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  size_t cnt;
3635bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3645bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  for (cnt = 0; cnt < name_len; ++cnt)
3655bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    if (isalnum (codeset[cnt]))
3665bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      {
3675bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	++len;
3685bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3695bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (isalpha (codeset[cnt]))
3705bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  only_digit = 0;
3715bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      }
3725bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3735bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
3745bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3755bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  if (retval != NULL)
3765bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    {
3775bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      if (only_digit)
3785bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	wp = stpcpy (retval, "iso");
3795bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      else
3805bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	wp = retval;
3815bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3825bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      for (cnt = 0; cnt < name_len; ++cnt)
3835bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	if (isalpha (codeset[cnt]))
3845bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *wp++ = tolower (codeset[cnt]);
3855bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	else if (isdigit (codeset[cnt]))
3865bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o	  *wp++ = codeset[cnt];
3875bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3885bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o      *wp = '\0';
3895bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    }
3905bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3915bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return (const char *) retval;
3925bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
3935bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3945bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3955bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* @@ begin of epilog @@ */
3965bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o
3975bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o/* We don't want libintl.a to depend on any other library.  So we
3985bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   avoid the non-standard function stpcpy.  In GNU C Library this
3995bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   function is available, though.  Also allow the symbol HAVE_STPCPY
4005bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o   to be defined.  */
4015bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#if !_LIBC && !HAVE_STPCPY
4025bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostatic char *
4035bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'ostpcpy (dest, src)
4045bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     char *dest;
4055bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o     const char *src;
4065bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o{
4075bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  while ((*dest++ = *src++) != '\0')
4085bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o    /* Do nothing. */ ;
4095bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o  return dest - 1;
4105bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o}
4115bc5a89c2a5c07b0237c13d37d869c986b5435fbTheodore Ts'o#endif
412