Blame intl/loadmsgcat.c

Packit bbfece
/* Load needed message catalogs.
Packit bbfece
   Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
Packit bbfece
Packit bbfece
   This program is free software; you can redistribute it and/or modify it
Packit bbfece
   under the terms of the GNU Library General Public License as published
Packit bbfece
   by the Free Software Foundation; either version 2, or (at your option)
Packit bbfece
   any later version.
Packit bbfece
Packit bbfece
   This program is distributed in the hope that it will be useful,
Packit bbfece
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bbfece
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit bbfece
   Library General Public License for more details.
Packit bbfece
Packit bbfece
   You should have received a copy of the GNU Library General Public
Packit bbfece
   License along with this program; if not, write to the Free Software
Packit bbfece
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
Packit bbfece
   USA.  */
Packit bbfece
Packit bbfece
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
Packit bbfece
   This must come before <config.h> because <config.h> may include
Packit bbfece
   <features.h>, and once <features.h> has been included, it's too late.  */
Packit bbfece
#ifndef _GNU_SOURCE
Packit bbfece
# define _GNU_SOURCE    1
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#ifdef HAVE_CONFIG_H
Packit bbfece
# include <config.h>
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#include <ctype.h>
Packit bbfece
#include <errno.h>
Packit bbfece
#include <fcntl.h>
Packit bbfece
#include <sys/types.h>
Packit bbfece
#include <sys/stat.h>
Packit bbfece
Packit bbfece
#ifdef __GNUC__
Packit bbfece
# undef  alloca
Packit bbfece
# define alloca __builtin_alloca
Packit bbfece
# define HAVE_ALLOCA 1
Packit bbfece
#else
Packit bbfece
# ifdef _MSC_VER
Packit bbfece
#  include <malloc.h>
Packit bbfece
#  define alloca _alloca
Packit bbfece
# else
Packit bbfece
#  if defined HAVE_ALLOCA_H || defined _LIBC
Packit bbfece
#   include <alloca.h>
Packit bbfece
#  else
Packit bbfece
#   ifdef _AIX
Packit bbfece
 #pragma alloca
Packit bbfece
#   else
Packit bbfece
#    ifndef alloca
Packit bbfece
char *alloca ();
Packit bbfece
#    endif
Packit bbfece
#   endif
Packit bbfece
#  endif
Packit bbfece
# endif
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#include <stdlib.h>
Packit bbfece
#include <string.h>
Packit bbfece
Packit bbfece
#if defined HAVE_UNISTD_H || defined _LIBC
Packit bbfece
# include <unistd.h>
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#ifdef _LIBC
Packit bbfece
# include <langinfo.h>
Packit bbfece
# include <locale.h>
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
Packit bbfece
    || (defined _LIBC && defined _POSIX_MAPPED_FILES)
Packit bbfece
# include <sys/mman.h>
Packit bbfece
# undef HAVE_MMAP
Packit bbfece
# define HAVE_MMAP	1
Packit bbfece
#else
Packit bbfece
# undef HAVE_MMAP
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC
Packit bbfece
# include <stdint.h>
Packit bbfece
#endif
Packit bbfece
#if defined HAVE_INTTYPES_H || defined _LIBC
Packit bbfece
# include <inttypes.h>
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#include "gmo.h"
Packit bbfece
#include "gettextP.h"
Packit bbfece
#include "hash-string.h"
Packit bbfece
#include "plural-exp.h"
Packit bbfece
Packit bbfece
#ifdef _LIBC
Packit bbfece
# include "../locale/localeinfo.h"
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* Provide fallback values for macros that ought to be defined in <inttypes.h>.
Packit bbfece
   Note that our fallback values need not be literal strings, because we don't
Packit bbfece
   use them with preprocessor string concatenation.  */
Packit bbfece
#if !defined PRId8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRId8
Packit bbfece
# define PRId8 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIi8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIi8
Packit bbfece
# define PRIi8 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIo8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIo8
Packit bbfece
# define PRIo8 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIu8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIu8
Packit bbfece
# define PRIu8 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIx8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIx8
Packit bbfece
# define PRIx8 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIX8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIX8
Packit bbfece
# define PRIX8 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRId16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRId16
Packit bbfece
# define PRId16 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIi16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIi16
Packit bbfece
# define PRIi16 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIo16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIo16
Packit bbfece
# define PRIo16 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIu16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIu16
Packit bbfece
# define PRIu16 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIx16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIx16
Packit bbfece
# define PRIx16 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIX16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIX16
Packit bbfece
# define PRIX16 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRId32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRId32
Packit bbfece
# define PRId32 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIi32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIi32
Packit bbfece
# define PRIi32 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIo32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIo32
Packit bbfece
# define PRIo32 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIu32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIu32
Packit bbfece
# define PRIu32 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIx32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIx32
Packit bbfece
# define PRIx32 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIX32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIX32
Packit bbfece
# define PRIX32 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRId64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRId64
Packit bbfece
# define PRId64 (sizeof (long) == 8 ? "ld" : "lld")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIi64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIi64
Packit bbfece
# define PRIi64 (sizeof (long) == 8 ? "li" : "lli")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIo64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIo64
Packit bbfece
# define PRIo64 (sizeof (long) == 8 ? "lo" : "llo")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIu64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIu64
Packit bbfece
# define PRIu64 (sizeof (long) == 8 ? "lu" : "llu")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIx64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIx64
Packit bbfece
# define PRIx64 (sizeof (long) == 8 ? "lx" : "llx")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIX64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIX64
Packit bbfece
# define PRIX64 (sizeof (long) == 8 ? "lX" : "llX")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdLEAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdLEAST8
Packit bbfece
# define PRIdLEAST8 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiLEAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiLEAST8
Packit bbfece
# define PRIiLEAST8 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoLEAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoLEAST8
Packit bbfece
# define PRIoLEAST8 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuLEAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuLEAST8
Packit bbfece
# define PRIuLEAST8 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxLEAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxLEAST8
Packit bbfece
# define PRIxLEAST8 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXLEAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXLEAST8
Packit bbfece
# define PRIXLEAST8 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdLEAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdLEAST16
Packit bbfece
# define PRIdLEAST16 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiLEAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiLEAST16
Packit bbfece
# define PRIiLEAST16 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoLEAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoLEAST16
Packit bbfece
# define PRIoLEAST16 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuLEAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuLEAST16
Packit bbfece
# define PRIuLEAST16 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxLEAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxLEAST16
Packit bbfece
# define PRIxLEAST16 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXLEAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXLEAST16
Packit bbfece
# define PRIXLEAST16 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdLEAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdLEAST32
Packit bbfece
# define PRIdLEAST32 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiLEAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiLEAST32
Packit bbfece
# define PRIiLEAST32 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoLEAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoLEAST32
Packit bbfece
# define PRIoLEAST32 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuLEAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuLEAST32
Packit bbfece
# define PRIuLEAST32 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxLEAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxLEAST32
Packit bbfece
# define PRIxLEAST32 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXLEAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXLEAST32
Packit bbfece
# define PRIXLEAST32 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdLEAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdLEAST64
Packit bbfece
# define PRIdLEAST64 PRId64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiLEAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiLEAST64
Packit bbfece
# define PRIiLEAST64 PRIi64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoLEAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoLEAST64
Packit bbfece
# define PRIoLEAST64 PRIo64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuLEAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuLEAST64
Packit bbfece
# define PRIuLEAST64 PRIu64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxLEAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxLEAST64
Packit bbfece
# define PRIxLEAST64 PRIx64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXLEAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXLEAST64
Packit bbfece
# define PRIXLEAST64 PRIX64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdFAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdFAST8
Packit bbfece
# define PRIdFAST8 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiFAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiFAST8
Packit bbfece
# define PRIiFAST8 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoFAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoFAST8
Packit bbfece
# define PRIoFAST8 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuFAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuFAST8
Packit bbfece
# define PRIuFAST8 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxFAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxFAST8
Packit bbfece
# define PRIxFAST8 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXFAST8 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXFAST8
Packit bbfece
# define PRIXFAST8 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdFAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdFAST16
Packit bbfece
# define PRIdFAST16 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiFAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiFAST16
Packit bbfece
# define PRIiFAST16 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoFAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoFAST16
Packit bbfece
# define PRIoFAST16 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuFAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuFAST16
Packit bbfece
# define PRIuFAST16 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxFAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxFAST16
Packit bbfece
# define PRIxFAST16 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXFAST16 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXFAST16
Packit bbfece
# define PRIXFAST16 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdFAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdFAST32
Packit bbfece
# define PRIdFAST32 "d"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiFAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiFAST32
Packit bbfece
# define PRIiFAST32 "i"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoFAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoFAST32
Packit bbfece
# define PRIoFAST32 "o"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuFAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuFAST32
Packit bbfece
# define PRIuFAST32 "u"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxFAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxFAST32
Packit bbfece
# define PRIxFAST32 "x"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXFAST32 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXFAST32
Packit bbfece
# define PRIXFAST32 "X"
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdFAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdFAST64
Packit bbfece
# define PRIdFAST64 PRId64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiFAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiFAST64
Packit bbfece
# define PRIiFAST64 PRIi64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoFAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoFAST64
Packit bbfece
# define PRIoFAST64 PRIo64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuFAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuFAST64
Packit bbfece
# define PRIuFAST64 PRIu64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxFAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxFAST64
Packit bbfece
# define PRIxFAST64 PRIx64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXFAST64 || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXFAST64
Packit bbfece
# define PRIXFAST64 PRIX64
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdMAX || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdMAX
Packit bbfece
# define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiMAX || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiMAX
Packit bbfece
# define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoMAX || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoMAX
Packit bbfece
# define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuMAX || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuMAX
Packit bbfece
# define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxMAX || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxMAX
Packit bbfece
# define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXMAX || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXMAX
Packit bbfece
# define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIdPTR || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIdPTR
Packit bbfece
# define PRIdPTR \
Packit bbfece
  (sizeof (void *) == sizeof (long) ? "ld" : \
Packit bbfece
   sizeof (void *) == sizeof (int) ? "d" : \
Packit bbfece
   "lld")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIiPTR || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIiPTR
Packit bbfece
# define PRIiPTR \
Packit bbfece
  (sizeof (void *) == sizeof (long) ? "li" : \
Packit bbfece
   sizeof (void *) == sizeof (int) ? "i" : \
Packit bbfece
   "lli")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIoPTR || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIoPTR
Packit bbfece
# define PRIoPTR \
Packit bbfece
  (sizeof (void *) == sizeof (long) ? "lo" : \
Packit bbfece
   sizeof (void *) == sizeof (int) ? "o" : \
Packit bbfece
   "llo")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIuPTR || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIuPTR
Packit bbfece
# define PRIuPTR \
Packit bbfece
  (sizeof (void *) == sizeof (long) ? "lu" : \
Packit bbfece
   sizeof (void *) == sizeof (int) ? "u" : \
Packit bbfece
   "llu")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIxPTR || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIxPTR
Packit bbfece
# define PRIxPTR \
Packit bbfece
  (sizeof (void *) == sizeof (long) ? "lx" : \
Packit bbfece
   sizeof (void *) == sizeof (int) ? "x" : \
Packit bbfece
   "llx")
Packit bbfece
#endif
Packit bbfece
#if !defined PRIXPTR || PRI_MACROS_BROKEN
Packit bbfece
# undef PRIXPTR
Packit bbfece
# define PRIXPTR \
Packit bbfece
  (sizeof (void *) == sizeof (long) ? "lX" : \
Packit bbfece
   sizeof (void *) == sizeof (int) ? "X" : \
Packit bbfece
   "llX")
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* @@ end of prolog @@ */
Packit bbfece
Packit bbfece
#ifdef _LIBC
Packit bbfece
/* Rename the non ISO C functions.  This is required by the standard
Packit bbfece
   because some ISO C functions will require linking with this object
Packit bbfece
   file and the name space must not be polluted.  */
Packit bbfece
# define open   __open
Packit bbfece
# define close  __close
Packit bbfece
# define read   __read
Packit bbfece
# define mmap   __mmap
Packit bbfece
# define munmap __munmap
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* For those losing systems which don't have `alloca' we have to add
Packit bbfece
   some additional code emulating it.  */
Packit bbfece
#ifdef HAVE_ALLOCA
Packit bbfece
# define freea(p) /* nothing */
Packit bbfece
#else
Packit bbfece
# define alloca(n) malloc (n)
Packit bbfece
# define freea(p) free (p)
Packit bbfece
#endif
Packit bbfece
Packit bbfece
/* For systems that distinguish between text and binary I/O.
Packit bbfece
   O_BINARY is usually declared in <fcntl.h>. */
Packit bbfece
#if !defined O_BINARY && defined _O_BINARY
Packit bbfece
  /* For MSC-compatible compilers.  */
Packit bbfece
# define O_BINARY _O_BINARY
Packit bbfece
# define O_TEXT _O_TEXT
Packit bbfece
#endif
Packit bbfece
#ifdef __BEOS__
Packit bbfece
  /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect.  */
Packit bbfece
# undef O_BINARY
Packit bbfece
# undef O_TEXT
Packit bbfece
#endif
Packit bbfece
/* On reasonable systems, binary I/O is the default.  */
Packit bbfece
#ifndef O_BINARY
Packit bbfece
# define O_BINARY 0
Packit bbfece
#endif
Packit bbfece
Packit bbfece
Packit bbfece
/* Prototypes for local functions.  Needed to ensure compiler checking of
Packit bbfece
   function argument counts despite of K&R C function definition syntax.  */
Packit bbfece
static const char *get_sysdep_segment_value PARAMS ((const char *name));
Packit bbfece
Packit bbfece
Packit bbfece
/* We need a sign, whether a new catalog was loaded, which can be associated
Packit bbfece
   with all translations.  This is important if the translations are
Packit bbfece
   cached by one of GCC's features.  */
Packit bbfece
int _nl_msg_cat_cntr;
Packit bbfece
Packit bbfece
Packit bbfece
/* Expand a system dependent string segment.  Return NULL if unsupported.  */
Packit bbfece
static const char *
Packit bbfece
get_sysdep_segment_value (name)
Packit bbfece
     const char *name;
Packit bbfece
{
Packit bbfece
  /* Test for an ISO C 99 section 7.8.1 format string directive.
Packit bbfece
     Syntax:
Packit bbfece
     P R I { d | i | o | u | x | X }
Packit bbfece
     { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR }  */
Packit bbfece
  /* We don't use a table of 14 times 6 'const char *' strings here, because
Packit bbfece
     data relocations cost startup time.  */
Packit bbfece
  if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
Packit bbfece
    {
Packit bbfece
      if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
Packit bbfece
	  || name[3] == 'x' || name[3] == 'X')
Packit bbfece
	{
Packit bbfece
	  if (name[4] == '8' && name[5] == '\0')
Packit bbfece
	    {
Packit bbfece
	      if (name[3] == 'd')
Packit bbfece
		return PRId8;
Packit bbfece
	      if (name[3] == 'i')
Packit bbfece
		return PRIi8;
Packit bbfece
	      if (name[3] == 'o')
Packit bbfece
		return PRIo8;
Packit bbfece
	      if (name[3] == 'u')
Packit bbfece
		return PRIu8;
Packit bbfece
	      if (name[3] == 'x')
Packit bbfece
		return PRIx8;
Packit bbfece
	      if (name[3] == 'X')
Packit bbfece
		return PRIX8;
Packit bbfece
	      abort ();
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
Packit bbfece
	    {
Packit bbfece
	      if (name[3] == 'd')
Packit bbfece
		return PRId16;
Packit bbfece
	      if (name[3] == 'i')
Packit bbfece
		return PRIi16;
Packit bbfece
	      if (name[3] == 'o')
Packit bbfece
		return PRIo16;
Packit bbfece
	      if (name[3] == 'u')
Packit bbfece
		return PRIu16;
Packit bbfece
	      if (name[3] == 'x')
Packit bbfece
		return PRIx16;
Packit bbfece
	      if (name[3] == 'X')
Packit bbfece
		return PRIX16;
Packit bbfece
	      abort ();
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
Packit bbfece
	    {
Packit bbfece
	      if (name[3] == 'd')
Packit bbfece
		return PRId32;
Packit bbfece
	      if (name[3] == 'i')
Packit bbfece
		return PRIi32;
Packit bbfece
	      if (name[3] == 'o')
Packit bbfece
		return PRIo32;
Packit bbfece
	      if (name[3] == 'u')
Packit bbfece
		return PRIu32;
Packit bbfece
	      if (name[3] == 'x')
Packit bbfece
		return PRIx32;
Packit bbfece
	      if (name[3] == 'X')
Packit bbfece
		return PRIX32;
Packit bbfece
	      abort ();
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
Packit bbfece
	    {
Packit bbfece
	      if (name[3] == 'd')
Packit bbfece
		return PRId64;
Packit bbfece
	      if (name[3] == 'i')
Packit bbfece
		return PRIi64;
Packit bbfece
	      if (name[3] == 'o')
Packit bbfece
		return PRIo64;
Packit bbfece
	      if (name[3] == 'u')
Packit bbfece
		return PRIu64;
Packit bbfece
	      if (name[3] == 'x')
Packit bbfece
		return PRIx64;
Packit bbfece
	      if (name[3] == 'X')
Packit bbfece
		return PRIX64;
Packit bbfece
	      abort ();
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
Packit bbfece
	      && name[7] == 'S' && name[8] == 'T')
Packit bbfece
	    {
Packit bbfece
	      if (name[9] == '8' && name[10] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdLEAST8;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiLEAST8;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoLEAST8;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuLEAST8;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxLEAST8;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXLEAST8;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	      if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdLEAST16;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiLEAST16;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoLEAST16;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuLEAST16;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxLEAST16;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXLEAST16;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	      if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdLEAST32;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiLEAST32;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoLEAST32;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuLEAST32;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxLEAST32;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXLEAST32;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	      if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdLEAST64;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiLEAST64;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoLEAST64;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuLEAST64;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxLEAST64;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXLEAST64;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
Packit bbfece
	      && name[7] == 'T')
Packit bbfece
	    {
Packit bbfece
	      if (name[8] == '8' && name[9] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdFAST8;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiFAST8;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoFAST8;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuFAST8;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxFAST8;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXFAST8;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	      if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdFAST16;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiFAST16;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoFAST16;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuFAST16;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxFAST16;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXFAST16;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	      if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdFAST32;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiFAST32;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoFAST32;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuFAST32;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxFAST32;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXFAST32;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	      if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
Packit bbfece
		{
Packit bbfece
		  if (name[3] == 'd')
Packit bbfece
		    return PRIdFAST64;
Packit bbfece
		  if (name[3] == 'i')
Packit bbfece
		    return PRIiFAST64;
Packit bbfece
		  if (name[3] == 'o')
Packit bbfece
		    return PRIoFAST64;
Packit bbfece
		  if (name[3] == 'u')
Packit bbfece
		    return PRIuFAST64;
Packit bbfece
		  if (name[3] == 'x')
Packit bbfece
		    return PRIxFAST64;
Packit bbfece
		  if (name[3] == 'X')
Packit bbfece
		    return PRIXFAST64;
Packit bbfece
		  abort ();
Packit bbfece
		}
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
Packit bbfece
	      && name[7] == '\0')
Packit bbfece
	    {
Packit bbfece
	      if (name[3] == 'd')
Packit bbfece
		return PRIdMAX;
Packit bbfece
	      if (name[3] == 'i')
Packit bbfece
		return PRIiMAX;
Packit bbfece
	      if (name[3] == 'o')
Packit bbfece
		return PRIoMAX;
Packit bbfece
	      if (name[3] == 'u')
Packit bbfece
		return PRIuMAX;
Packit bbfece
	      if (name[3] == 'x')
Packit bbfece
		return PRIxMAX;
Packit bbfece
	      if (name[3] == 'X')
Packit bbfece
		return PRIXMAX;
Packit bbfece
	      abort ();
Packit bbfece
	    }
Packit bbfece
	  if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
Packit bbfece
	      && name[7] == '\0')
Packit bbfece
	    {
Packit bbfece
	      if (name[3] == 'd')
Packit bbfece
		return PRIdPTR;
Packit bbfece
	      if (name[3] == 'i')
Packit bbfece
		return PRIiPTR;
Packit bbfece
	      if (name[3] == 'o')
Packit bbfece
		return PRIoPTR;
Packit bbfece
	      if (name[3] == 'u')
Packit bbfece
		return PRIuPTR;
Packit bbfece
	      if (name[3] == 'x')
Packit bbfece
		return PRIxPTR;
Packit bbfece
	      if (name[3] == 'X')
Packit bbfece
		return PRIXPTR;
Packit bbfece
	      abort ();
Packit bbfece
	    }
Packit bbfece
	}
Packit bbfece
    }
Packit bbfece
  /* Other system dependent strings are not valid.  */
Packit bbfece
  return NULL;
Packit bbfece
}
Packit bbfece
Packit bbfece
/* Initialize the codeset dependent parts of an opened message catalog.
Packit bbfece
   Return the header entry.  */
Packit bbfece
const char *
Packit bbfece
internal_function
Packit bbfece
_nl_init_domain_conv (domain_file, domain, domainbinding)
Packit bbfece
     struct loaded_l10nfile *domain_file;
Packit bbfece
     struct loaded_domain *domain;
Packit bbfece
     struct binding *domainbinding;
Packit bbfece
{
Packit bbfece
  /* Find out about the character set the file is encoded with.
Packit bbfece
     This can be found (in textual form) in the entry "".  If this
Packit bbfece
     entry does not exist or if this does not contain the `charset='
Packit bbfece
     information, we will assume the charset matches the one the
Packit bbfece
     current locale and we don't have to perform any conversion.  */
Packit bbfece
  char *nullentry;
Packit bbfece
  size_t nullentrylen;
Packit bbfece
Packit bbfece
  /* Preinitialize fields, to avoid recursion during _nl_find_msg.  */
Packit bbfece
  domain->codeset_cntr =
Packit bbfece
    (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
Packit bbfece
#ifdef _LIBC
Packit bbfece
  domain->conv = (__gconv_t) -1;
Packit bbfece
#else
Packit bbfece
# if HAVE_ICONV
Packit bbfece
  domain->conv = (iconv_t) -1;
Packit bbfece
# endif
Packit bbfece
#endif
Packit bbfece
  domain->conv_tab = NULL;
Packit bbfece
Packit bbfece
  /* Get the header entry.  */
Packit bbfece
  nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);
Packit bbfece
Packit bbfece
  if (nullentry != NULL)
Packit bbfece
    {
Packit bbfece
#if defined _LIBC || HAVE_ICONV
Packit bbfece
      const char *charsetstr;
Packit bbfece
Packit bbfece
      charsetstr = strstr (nullentry, "charset=");
Packit bbfece
      if (charsetstr != NULL)
Packit bbfece
	{
Packit bbfece
	  size_t len;
Packit bbfece
	  char *charset;
Packit bbfece
	  const char *outcharset;
Packit bbfece
Packit bbfece
	  charsetstr += strlen ("charset=");
Packit bbfece
	  len = strcspn (charsetstr, " \t\n");
Packit bbfece
Packit bbfece
	  charset = (char *) alloca (len + 1);
Packit bbfece
# if defined _LIBC || HAVE_MEMPCPY
Packit bbfece
	  *((char *) mempcpy (charset, charsetstr, len)) = '\0';
Packit bbfece
# else
Packit bbfece
	  memcpy (charset, charsetstr, len);
Packit bbfece
	  charset[len] = '\0';
Packit bbfece
# endif
Packit bbfece
Packit bbfece
	  /* The output charset should normally be determined by the
Packit bbfece
	     locale.  But sometimes the locale is not used or not correctly
Packit bbfece
	     set up, so we provide a possibility for the user to override
Packit bbfece
	     this.  Moreover, the value specified through
Packit bbfece
	     bind_textdomain_codeset overrides both.  */
Packit bbfece
	  if (domainbinding != NULL && domainbinding->codeset != NULL)
Packit bbfece
	    outcharset = domainbinding->codeset;
Packit bbfece
	  else
Packit bbfece
	    {
Packit bbfece
	      outcharset = getenv ("OUTPUT_CHARSET");
Packit bbfece
	      if (outcharset == NULL || outcharset[0] == '\0')
Packit bbfece
		{
Packit bbfece
# ifdef _LIBC
Packit bbfece
		  outcharset = _NL_CURRENT (LC_CTYPE, CODESET);
Packit bbfece
# else
Packit bbfece
#  if HAVE_ICONV
Packit bbfece
		  extern const char *locale_charset PARAMS ((void));
Packit bbfece
		  outcharset = locale_charset ();
Packit bbfece
#  endif
Packit bbfece
# endif
Packit bbfece
		}
Packit bbfece
	    }
Packit bbfece
Packit bbfece
# ifdef _LIBC
Packit bbfece
	  /* We always want to use transliteration.  */
Packit bbfece
	  outcharset = norm_add_slashes (outcharset, "TRANSLIT");
Packit bbfece
	  charset = norm_add_slashes (charset, NULL);
Packit bbfece
	  if (__gconv_open (outcharset, charset, &domain->conv,
Packit bbfece
			    GCONV_AVOID_NOCONV)
Packit bbfece
	      != __GCONV_OK)
Packit bbfece
	    domain->conv = (__gconv_t) -1;
Packit bbfece
# else
Packit bbfece
#  if HAVE_ICONV
Packit bbfece
	  /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
Packit bbfece
	     we want to use transliteration.  */
Packit bbfece
#   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
Packit bbfece
       || _LIBICONV_VERSION >= 0x0105
Packit bbfece
	  if (strchr (outcharset, '/') == NULL)
Packit bbfece
	    {
Packit bbfece
	      char *tmp;
Packit bbfece
Packit bbfece
	      len = strlen (outcharset);
Packit bbfece
	      tmp = (char *) alloca (len + 10 + 1);
Packit bbfece
	      memcpy (tmp, outcharset, len);
Packit bbfece
	      memcpy (tmp + len, "//TRANSLIT", 10 + 1);
Packit bbfece
	      outcharset = tmp;
Packit bbfece
Packit bbfece
	      domain->conv = iconv_open (outcharset, charset);
Packit bbfece
Packit bbfece
	      freea (outcharset);
Packit bbfece
	    }
Packit bbfece
	  else
Packit bbfece
#   endif
Packit bbfece
	    domain->conv = iconv_open (outcharset, charset);
Packit bbfece
#  endif
Packit bbfece
# endif
Packit bbfece
Packit bbfece
	  freea (charset);
Packit bbfece
	}
Packit bbfece
#endif /* _LIBC || HAVE_ICONV */
Packit bbfece
    }
Packit bbfece
Packit bbfece
  return nullentry;
Packit bbfece
}
Packit bbfece
Packit bbfece
/* Frees the codeset dependent parts of an opened message catalog.  */
Packit bbfece
void
Packit bbfece
internal_function
Packit bbfece
_nl_free_domain_conv (domain)
Packit bbfece
     struct loaded_domain *domain;
Packit bbfece
{
Packit bbfece
  if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
Packit bbfece
    free (domain->conv_tab);
Packit bbfece
Packit bbfece
#ifdef _LIBC
Packit bbfece
  if (domain->conv != (__gconv_t) -1)
Packit bbfece
    __gconv_close (domain->conv);
Packit bbfece
#else
Packit bbfece
# if HAVE_ICONV
Packit bbfece
  if (domain->conv != (iconv_t) -1)
Packit bbfece
    iconv_close (domain->conv);
Packit bbfece
# endif
Packit bbfece
#endif
Packit bbfece
}
Packit bbfece
Packit bbfece
/* Load the message catalogs specified by FILENAME.  If it is no valid
Packit bbfece
   message catalog do nothing.  */
Packit bbfece
void
Packit bbfece
internal_function
Packit bbfece
_nl_load_domain (domain_file, domainbinding)
Packit bbfece
     struct loaded_l10nfile *domain_file;
Packit bbfece
     struct binding *domainbinding;
Packit bbfece
{
Packit bbfece
  int fd;
Packit bbfece
  size_t size;
Packit bbfece
#ifdef _LIBC
Packit bbfece
  struct stat64 st;
Packit bbfece
#else
Packit bbfece
  struct stat st;
Packit bbfece
#endif
Packit bbfece
  struct mo_file_header *data = (struct mo_file_header *) -1;
Packit bbfece
  int use_mmap = 0;
Packit bbfece
  struct loaded_domain *domain;
Packit bbfece
  int revision;
Packit bbfece
  const char *nullentry;
Packit bbfece
Packit bbfece
  domain_file->decided = 1;
Packit bbfece
  domain_file->data = NULL;
Packit bbfece
Packit bbfece
  /* Note that it would be useless to store domainbinding in domain_file
Packit bbfece
     because domainbinding might be == NULL now but != NULL later (after
Packit bbfece
     a call to bind_textdomain_codeset).  */
Packit bbfece
Packit bbfece
  /* If the record does not represent a valid locale the FILENAME
Packit bbfece
     might be NULL.  This can happen when according to the given
Packit bbfece
     specification the locale file name is different for XPG and CEN
Packit bbfece
     syntax.  */
Packit bbfece
  if (domain_file->filename == NULL)
Packit bbfece
    return;
Packit bbfece
Packit bbfece
  /* Try to open the addressed file.  */
Packit bbfece
  fd = open (domain_file->filename, O_RDONLY | O_BINARY);
Packit bbfece
  if (fd == -1)
Packit bbfece
    return;
Packit bbfece
Packit bbfece
  /* We must know about the size of the file.  */
Packit bbfece
  if (
Packit bbfece
#ifdef _LIBC
Packit bbfece
      __builtin_expect (fstat64 (fd, &st) != 0, 0)
Packit bbfece
#else
Packit bbfece
      __builtin_expect (fstat (fd, &st) != 0, 0)
Packit bbfece
#endif
Packit bbfece
      || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
Packit bbfece
      || __builtin_expect (size < sizeof (struct mo_file_header), 0))
Packit bbfece
    {
Packit bbfece
      /* Something went wrong.  */
Packit bbfece
      close (fd);
Packit bbfece
      return;
Packit bbfece
    }
Packit bbfece
Packit bbfece
#ifdef HAVE_MMAP
Packit bbfece
  /* Now we are ready to load the file.  If mmap() is available we try
Packit bbfece
     this first.  If not available or it failed we try to load it.  */
Packit bbfece
  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
Packit bbfece
					 MAP_PRIVATE, fd, 0);
Packit bbfece
Packit bbfece
  if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
Packit bbfece
    {
Packit bbfece
      /* mmap() call was successful.  */
Packit bbfece
      close (fd);
Packit bbfece
      use_mmap = 1;
Packit bbfece
    }
Packit bbfece
#endif
Packit bbfece
Packit bbfece
  /* If the data is not yet available (i.e. mmap'ed) we try to load
Packit bbfece
     it manually.  */
Packit bbfece
  if (data == (struct mo_file_header *) -1)
Packit bbfece
    {
Packit bbfece
      size_t to_read;
Packit bbfece
      char *read_ptr;
Packit bbfece
Packit bbfece
      data = (struct mo_file_header *) malloc (size);
Packit bbfece
      if (data == NULL)
Packit bbfece
	return;
Packit bbfece
Packit bbfece
      to_read = size;
Packit bbfece
      read_ptr = (char *) data;
Packit bbfece
      do
Packit bbfece
	{
Packit bbfece
	  long int nb = (long int) read (fd, read_ptr, to_read);
Packit bbfece
	  if (nb <= 0)
Packit bbfece
	    {
Packit bbfece
#ifdef EINTR
Packit bbfece
	      if (nb == -1 && errno == EINTR)
Packit bbfece
		continue;
Packit bbfece
#endif
Packit bbfece
	      close (fd);
Packit bbfece
	      return;
Packit bbfece
	    }
Packit bbfece
	  read_ptr += nb;
Packit bbfece
	  to_read -= nb;
Packit bbfece
	}
Packit bbfece
      while (to_read > 0);
Packit bbfece
Packit bbfece
      close (fd);
Packit bbfece
    }
Packit bbfece
Packit bbfece
  /* Using the magic number we can test whether it really is a message
Packit bbfece
     catalog file.  */
Packit bbfece
  if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
Packit bbfece
			0))
Packit bbfece
    {
Packit bbfece
      /* The magic number is wrong: not a message catalog file.  */
Packit bbfece
#ifdef HAVE_MMAP
Packit bbfece
      if (use_mmap)
Packit bbfece
	munmap ((caddr_t) data, size);
Packit bbfece
      else
Packit bbfece
#endif
Packit bbfece
	free (data);
Packit bbfece
      return;
Packit bbfece
    }
Packit bbfece
Packit bbfece
  domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
Packit bbfece
  if (domain == NULL)
Packit bbfece
    return;
Packit bbfece
  domain_file->data = domain;
Packit bbfece
Packit bbfece
  domain->data = (char *) data;
Packit bbfece
  domain->use_mmap = use_mmap;
Packit bbfece
  domain->mmap_size = size;
Packit bbfece
  domain->must_swap = data->magic != _MAGIC;
Packit bbfece
  domain->malloced = NULL;
Packit bbfece
Packit bbfece
  /* Fill in the information about the available tables.  */
Packit bbfece
  revision = W (domain->must_swap, data->revision);
Packit bbfece
  /* We support only the major revision 0.  */
Packit bbfece
  switch (revision >> 16)
Packit bbfece
    {
Packit bbfece
    case 0:
Packit bbfece
      domain->nstrings = W (domain->must_swap, data->nstrings);
Packit bbfece
      domain->orig_tab = (const struct string_desc *)
Packit bbfece
	((char *) data + W (domain->must_swap, data->orig_tab_offset));
Packit bbfece
      domain->trans_tab = (const struct string_desc *)
Packit bbfece
	((char *) data + W (domain->must_swap, data->trans_tab_offset));
Packit bbfece
      domain->hash_size = W (domain->must_swap, data->hash_tab_size);
Packit bbfece
      domain->hash_tab =
Packit bbfece
	(domain->hash_size > 2
Packit bbfece
	 ? (const nls_uint32 *)
Packit bbfece
	   ((char *) data + W (domain->must_swap, data->hash_tab_offset))
Packit bbfece
	 : NULL);
Packit bbfece
      domain->must_swap_hash_tab = domain->must_swap;
Packit bbfece
Packit bbfece
      /* Now dispatch on the minor revision.  */
Packit bbfece
      switch (revision & 0xffff)
Packit bbfece
	{
Packit bbfece
	case 0:
Packit bbfece
	  domain->n_sysdep_strings = 0;
Packit bbfece
	  domain->orig_sysdep_tab = NULL;
Packit bbfece
	  domain->trans_sysdep_tab = NULL;
Packit bbfece
	  break;
Packit bbfece
	case 1:
Packit bbfece
	default:
Packit bbfece
	  {
Packit bbfece
	    nls_uint32 n_sysdep_strings;
Packit bbfece
Packit bbfece
	    if (domain->hash_tab == NULL)
Packit bbfece
	      /* This is invalid.  These minor revisions need a hash table.  */
Packit bbfece
	      goto invalid;
Packit bbfece
Packit bbfece
	    n_sysdep_strings =
Packit bbfece
	      W (domain->must_swap, data->n_sysdep_strings);
Packit bbfece
	    if (n_sysdep_strings > 0)
Packit bbfece
	      {
Packit bbfece
		nls_uint32 n_sysdep_segments;
Packit bbfece
		const struct sysdep_segment *sysdep_segments;
Packit bbfece
		const char **sysdep_segment_values;
Packit bbfece
		const nls_uint32 *orig_sysdep_tab;
Packit bbfece
		const nls_uint32 *trans_sysdep_tab;
Packit bbfece
		size_t memneed;
Packit bbfece
		char *mem;
Packit bbfece
		struct sysdep_string_desc *inmem_orig_sysdep_tab;
Packit bbfece
		struct sysdep_string_desc *inmem_trans_sysdep_tab;
Packit bbfece
		nls_uint32 *inmem_hash_tab;
Packit bbfece
		unsigned int i;
Packit bbfece
Packit bbfece
		/* Get the values of the system dependent segments.  */
Packit bbfece
		n_sysdep_segments =
Packit bbfece
		  W (domain->must_swap, data->n_sysdep_segments);
Packit bbfece
		sysdep_segments = (const struct sysdep_segment *)
Packit bbfece
		  ((char *) data
Packit bbfece
		   + W (domain->must_swap, data->sysdep_segments_offset));
Packit bbfece
		sysdep_segment_values =
Packit bbfece
		  alloca (n_sysdep_segments * sizeof (const char *));
Packit bbfece
		for (i = 0; i < n_sysdep_segments; i++)
Packit bbfece
		  {
Packit bbfece
		    const char *name =
Packit bbfece
		      (char *) data
Packit bbfece
		      + W (domain->must_swap, sysdep_segments[i].offset);
Packit bbfece
		    nls_uint32 namelen =
Packit bbfece
		      W (domain->must_swap, sysdep_segments[i].length);
Packit bbfece
Packit bbfece
		    if (!(namelen > 0 && name[namelen - 1] == '\0'))
Packit bbfece
		      {
Packit bbfece
			freea (sysdep_segment_values);
Packit bbfece
			goto invalid;
Packit bbfece
		      }
Packit bbfece
Packit bbfece
		    sysdep_segment_values[i] = get_sysdep_segment_value (name);
Packit bbfece
		  }
Packit bbfece
Packit bbfece
		orig_sysdep_tab = (const nls_uint32 *)
Packit bbfece
		  ((char *) data
Packit bbfece
		   + W (domain->must_swap, data->orig_sysdep_tab_offset));
Packit bbfece
		trans_sysdep_tab = (const nls_uint32 *)
Packit bbfece
		  ((char *) data
Packit bbfece
		   + W (domain->must_swap, data->trans_sysdep_tab_offset));
Packit bbfece
Packit bbfece
		/* Compute the amount of additional memory needed for the
Packit bbfece
		   system dependent strings and the augmented hash table.  */
Packit bbfece
		memneed = 2 * n_sysdep_strings
Packit bbfece
			  * sizeof (struct sysdep_string_desc)
Packit bbfece
			  + domain->hash_size * sizeof (nls_uint32);
Packit bbfece
		for (i = 0; i < 2 * n_sysdep_strings; i++)
Packit bbfece
		  {
Packit bbfece
		    const struct sysdep_string *sysdep_string =
Packit bbfece
		      (const struct sysdep_string *)
Packit bbfece
		      ((char *) data
Packit bbfece
		       + W (domain->must_swap,
Packit bbfece
			    i < n_sysdep_strings
Packit bbfece
			    ? orig_sysdep_tab[i]
Packit bbfece
			    : trans_sysdep_tab[i - n_sysdep_strings]));
Packit bbfece
		    size_t need = 0;
Packit bbfece
		    const struct segment_pair *p = sysdep_string->segments;
Packit bbfece
Packit bbfece
		    if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
Packit bbfece
		      for (p = sysdep_string->segments;; p++)
Packit bbfece
			{
Packit bbfece
			  nls_uint32 sysdepref;
Packit bbfece
Packit bbfece
			  need += W (domain->must_swap, p->segsize);
Packit bbfece
Packit bbfece
			  sysdepref = W (domain->must_swap, p->sysdepref);
Packit bbfece
			  if (sysdepref == SEGMENTS_END)
Packit bbfece
			    break;
Packit bbfece
Packit bbfece
			  if (sysdepref >= n_sysdep_segments)
Packit bbfece
			    {
Packit bbfece
			      /* Invalid.  */
Packit bbfece
			      freea (sysdep_segment_values);
Packit bbfece
			      goto invalid;
Packit bbfece
			    }
Packit bbfece
Packit bbfece
			  need += strlen (sysdep_segment_values[sysdepref]);
Packit bbfece
			}
Packit bbfece
Packit bbfece
		    memneed += need;
Packit bbfece
		  }
Packit bbfece
Packit bbfece
		/* Allocate additional memory.  */
Packit bbfece
		mem = (char *) malloc (memneed);
Packit bbfece
		if (mem == NULL)
Packit bbfece
		  goto invalid;
Packit bbfece
Packit bbfece
		domain->malloced = mem;
Packit bbfece
		inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
Packit bbfece
		mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
Packit bbfece
		inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
Packit bbfece
		mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
Packit bbfece
		inmem_hash_tab = (nls_uint32 *) mem;
Packit bbfece
		mem += domain->hash_size * sizeof (nls_uint32);
Packit bbfece
Packit bbfece
		/* Compute the system dependent strings.  */
Packit bbfece
		for (i = 0; i < 2 * n_sysdep_strings; i++)
Packit bbfece
		  {
Packit bbfece
		    const struct sysdep_string *sysdep_string =
Packit bbfece
		      (const struct sysdep_string *)
Packit bbfece
		      ((char *) data
Packit bbfece
		       + W (domain->must_swap,
Packit bbfece
			    i < n_sysdep_strings
Packit bbfece
			    ? orig_sysdep_tab[i]
Packit bbfece
			    : trans_sysdep_tab[i - n_sysdep_strings]));
Packit bbfece
		    const char *static_segments =
Packit bbfece
		      (char *) data
Packit bbfece
		      + W (domain->must_swap, sysdep_string->offset);
Packit bbfece
		    const struct segment_pair *p = sysdep_string->segments;
Packit bbfece
Packit bbfece
		    /* Concatenate the segments, and fill
Packit bbfece
		       inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and
Packit bbfece
		       inmem_trans_sysdep_tab[i-n_sysdep_strings] (for
Packit bbfece
		       i >= n_sysdep_strings).  */
Packit bbfece
Packit bbfece
		    if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END)
Packit bbfece
		      {
Packit bbfece
			/* Only one static segment.  */
Packit bbfece
			inmem_orig_sysdep_tab[i].length =
Packit bbfece
			  W (domain->must_swap, p->segsize);
Packit bbfece
			inmem_orig_sysdep_tab[i].pointer = static_segments;
Packit bbfece
		      }
Packit bbfece
		    else
Packit bbfece
		      {
Packit bbfece
			inmem_orig_sysdep_tab[i].pointer = mem;
Packit bbfece
Packit bbfece
			for (p = sysdep_string->segments;; p++)
Packit bbfece
			  {
Packit bbfece
			    nls_uint32 segsize =
Packit bbfece
			      W (domain->must_swap, p->segsize);
Packit bbfece
			    nls_uint32 sysdepref =
Packit bbfece
			      W (domain->must_swap, p->sysdepref);
Packit bbfece
			    size_t n;
Packit bbfece
Packit bbfece
			    if (segsize > 0)
Packit bbfece
			      {
Packit bbfece
				memcpy (mem, static_segments, segsize);
Packit bbfece
				mem += segsize;
Packit bbfece
				static_segments += segsize;
Packit bbfece
			      }
Packit bbfece
Packit bbfece
			    if (sysdepref == SEGMENTS_END)
Packit bbfece
			      break;
Packit bbfece
Packit bbfece
			    n = strlen (sysdep_segment_values[sysdepref]);
Packit bbfece
			    memcpy (mem, sysdep_segment_values[sysdepref], n);
Packit bbfece
			    mem += n;
Packit bbfece
			  }
Packit bbfece
Packit bbfece
			inmem_orig_sysdep_tab[i].length =
Packit bbfece
			  mem - inmem_orig_sysdep_tab[i].pointer;
Packit bbfece
		      }
Packit bbfece
		  }
Packit bbfece
Packit bbfece
		/* Compute the augmented hash table.  */
Packit bbfece
		for (i = 0; i < domain->hash_size; i++)
Packit bbfece
		  inmem_hash_tab[i] =
Packit bbfece
		    W (domain->must_swap_hash_tab, domain->hash_tab[i]);
Packit bbfece
		for (i = 0; i < n_sysdep_strings; i++)
Packit bbfece
		  {
Packit bbfece
		    const char *msgid = inmem_orig_sysdep_tab[i].pointer;
Packit bbfece
		    nls_uint32 hash_val = hash_string (msgid);
Packit bbfece
		    nls_uint32 idx = hash_val % domain->hash_size;
Packit bbfece
		    nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
Packit bbfece
Packit bbfece
		    for (;;)
Packit bbfece
		      {
Packit bbfece
			if (inmem_hash_tab[idx] == 0)
Packit bbfece
			  {
Packit bbfece
			    /* Hash table entry is empty.  Use it.  */
Packit bbfece
			    inmem_hash_tab[idx] = 1 + domain->nstrings + i;
Packit bbfece
			    break;
Packit bbfece
			  }
Packit bbfece
Packit bbfece
			if (idx >= domain->hash_size - incr)
Packit bbfece
			  idx -= domain->hash_size - incr;
Packit bbfece
			else
Packit bbfece
			  idx += incr;
Packit bbfece
		      }
Packit bbfece
		  }
Packit bbfece
Packit bbfece
		freea (sysdep_segment_values);
Packit bbfece
Packit bbfece
		domain->n_sysdep_strings = n_sysdep_strings;
Packit bbfece
		domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
Packit bbfece
		domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
Packit bbfece
Packit bbfece
		domain->hash_tab = inmem_hash_tab;
Packit bbfece
		domain->must_swap_hash_tab = 0;
Packit bbfece
	      }
Packit bbfece
	    else
Packit bbfece
	      {
Packit bbfece
		domain->n_sysdep_strings = 0;
Packit bbfece
		domain->orig_sysdep_tab = NULL;
Packit bbfece
		domain->trans_sysdep_tab = NULL;
Packit bbfece
	      }
Packit bbfece
	  }
Packit bbfece
	  break;
Packit bbfece
	}
Packit bbfece
      break;
Packit bbfece
    default:
Packit bbfece
      /* This is an invalid revision.  */
Packit bbfece
    invalid:
Packit bbfece
      /* This is an invalid .mo file.  */
Packit bbfece
      if (domain->malloced)
Packit bbfece
	free (domain->malloced);
Packit bbfece
#ifdef HAVE_MMAP
Packit bbfece
      if (use_mmap)
Packit bbfece
	munmap ((caddr_t) data, size);
Packit bbfece
      else
Packit bbfece
#endif
Packit bbfece
	free (data);
Packit bbfece
      free (domain);
Packit bbfece
      domain_file->data = NULL;
Packit bbfece
      return;
Packit bbfece
    }
Packit bbfece
Packit bbfece
  /* Now initialize the character set converter from the character set
Packit bbfece
     the file is encoded with (found in the header entry) to the domain's
Packit bbfece
     specified character set or the locale's character set.  */
Packit bbfece
  nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);
Packit bbfece
Packit bbfece
  /* Also look for a plural specification.  */
Packit bbfece
  EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
Packit bbfece
}
Packit bbfece
Packit bbfece
Packit bbfece
#ifdef _LIBC
Packit bbfece
void
Packit bbfece
internal_function
Packit bbfece
_nl_unload_domain (domain)
Packit bbfece
     struct loaded_domain *domain;
Packit bbfece
{
Packit bbfece
  if (domain->plural != &__gettext_germanic_plural)
Packit bbfece
    __gettext_free_exp (domain->plural);
Packit bbfece
Packit bbfece
  _nl_free_domain_conv (domain);
Packit bbfece
Packit bbfece
  if (domain->malloced)
Packit bbfece
    free (domain->malloced);
Packit bbfece
Packit bbfece
# ifdef _POSIX_MAPPED_FILES
Packit bbfece
  if (domain->use_mmap)
Packit bbfece
    munmap ((caddr_t) domain->data, domain->mmap_size);
Packit bbfece
  else
Packit bbfece
# endif	/* _POSIX_MAPPED_FILES */
Packit bbfece
    free ((void *) domain->data);
Packit bbfece
Packit bbfece
  free (domain);
Packit bbfece
}
Packit bbfece
#endif