Blame intl/loadmsgcat.c

Packit 6c4009
/* Load needed message catalogs.
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
Packit 6c4009
   This program is free software: you can redistribute it and/or modify
Packit 6c4009
   it under the terms of the GNU Lesser General Public License as published by
Packit 6c4009
   the Free Software Foundation; either version 2.1 of the License, or
Packit 6c4009
   (at your option) any later version.
Packit 6c4009
Packit 6c4009
   This program is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 6c4009
   GNU Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public License
Packit 6c4009
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
Packit 6c4009
   This must come before <config.h> because <config.h> may include
Packit 6c4009
   <features.h>, and once <features.h> has been included, it's too late.  */
Packit 6c4009
#ifndef _GNU_SOURCE
Packit 6c4009
# define _GNU_SOURCE    1
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef HAVE_CONFIG_H
Packit 6c4009
# include <config.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <assert.h>
Packit 6c4009
#include <ctype.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <fcntl.h>
Packit 6c4009
#include <sys/types.h>
Packit 6c4009
#include <sys/stat.h>
Packit 6c4009
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
Packit 6c4009
#if defined HAVE_UNISTD_H || defined _LIBC
Packit 6c4009
# include <unistd.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# include <langinfo.h>
Packit 6c4009
# include <locale.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
Packit 6c4009
    || (defined _LIBC && defined _POSIX_MAPPED_FILES)
Packit 6c4009
# include <sys/mman.h>
Packit 6c4009
# undef HAVE_MMAP
Packit 6c4009
# define HAVE_MMAP	1
Packit 6c4009
#else
Packit 6c4009
# undef HAVE_MMAP
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC
Packit 6c4009
# include <stdint.h>
Packit 6c4009
#endif
Packit 6c4009
#if defined HAVE_INTTYPES_H || defined _LIBC
Packit 6c4009
# include <inttypes.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include "gmo.h"
Packit 6c4009
#include "gettextP.h"
Packit 6c4009
#include "hash-string.h"
Packit 6c4009
#include "plural-exp.h"
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# include "../locale/localeinfo.h"
Packit 6c4009
# include <not-cancel.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Handle multi-threaded applications.  */
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# include <libc-lock.h>
Packit 6c4009
#else
Packit 6c4009
# include "lock.h"
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# define PRI_MACROS_BROKEN 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Provide fallback values for macros that ought to be defined in <inttypes.h>.
Packit 6c4009
   Note that our fallback values need not be literal strings, because we don't
Packit 6c4009
   use them with preprocessor string concatenation.  */
Packit 6c4009
#if !defined PRId8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRId8
Packit 6c4009
# define PRId8 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIi8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIi8
Packit 6c4009
# define PRIi8 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIo8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIo8
Packit 6c4009
# define PRIo8 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIu8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIu8
Packit 6c4009
# define PRIu8 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIx8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIx8
Packit 6c4009
# define PRIx8 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIX8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIX8
Packit 6c4009
# define PRIX8 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRId16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRId16
Packit 6c4009
# define PRId16 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIi16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIi16
Packit 6c4009
# define PRIi16 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIo16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIo16
Packit 6c4009
# define PRIo16 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIu16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIu16
Packit 6c4009
# define PRIu16 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIx16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIx16
Packit 6c4009
# define PRIx16 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIX16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIX16
Packit 6c4009
# define PRIX16 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRId32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRId32
Packit 6c4009
# define PRId32 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIi32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIi32
Packit 6c4009
# define PRIi32 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIo32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIo32
Packit 6c4009
# define PRIo32 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIu32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIu32
Packit 6c4009
# define PRIu32 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIx32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIx32
Packit 6c4009
# define PRIx32 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIX32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIX32
Packit 6c4009
# define PRIX32 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRId64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRId64
Packit 6c4009
# define PRId64 (sizeof (long) == 8 ? "ld" : "lld")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIi64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIi64
Packit 6c4009
# define PRIi64 (sizeof (long) == 8 ? "li" : "lli")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIo64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIo64
Packit 6c4009
# define PRIo64 (sizeof (long) == 8 ? "lo" : "llo")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIu64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIu64
Packit 6c4009
# define PRIu64 (sizeof (long) == 8 ? "lu" : "llu")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIx64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIx64
Packit 6c4009
# define PRIx64 (sizeof (long) == 8 ? "lx" : "llx")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIX64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIX64
Packit 6c4009
# define PRIX64 (sizeof (long) == 8 ? "lX" : "llX")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdLEAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdLEAST8
Packit 6c4009
# define PRIdLEAST8 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiLEAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiLEAST8
Packit 6c4009
# define PRIiLEAST8 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoLEAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoLEAST8
Packit 6c4009
# define PRIoLEAST8 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuLEAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuLEAST8
Packit 6c4009
# define PRIuLEAST8 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxLEAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxLEAST8
Packit 6c4009
# define PRIxLEAST8 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXLEAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXLEAST8
Packit 6c4009
# define PRIXLEAST8 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdLEAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdLEAST16
Packit 6c4009
# define PRIdLEAST16 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiLEAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiLEAST16
Packit 6c4009
# define PRIiLEAST16 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoLEAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoLEAST16
Packit 6c4009
# define PRIoLEAST16 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuLEAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuLEAST16
Packit 6c4009
# define PRIuLEAST16 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxLEAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxLEAST16
Packit 6c4009
# define PRIxLEAST16 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXLEAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXLEAST16
Packit 6c4009
# define PRIXLEAST16 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdLEAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdLEAST32
Packit 6c4009
# define PRIdLEAST32 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiLEAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiLEAST32
Packit 6c4009
# define PRIiLEAST32 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoLEAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoLEAST32
Packit 6c4009
# define PRIoLEAST32 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuLEAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuLEAST32
Packit 6c4009
# define PRIuLEAST32 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxLEAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxLEAST32
Packit 6c4009
# define PRIxLEAST32 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXLEAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXLEAST32
Packit 6c4009
# define PRIXLEAST32 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdLEAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdLEAST64
Packit 6c4009
# define PRIdLEAST64 PRId64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiLEAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiLEAST64
Packit 6c4009
# define PRIiLEAST64 PRIi64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoLEAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoLEAST64
Packit 6c4009
# define PRIoLEAST64 PRIo64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuLEAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuLEAST64
Packit 6c4009
# define PRIuLEAST64 PRIu64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxLEAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxLEAST64
Packit 6c4009
# define PRIxLEAST64 PRIx64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXLEAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXLEAST64
Packit 6c4009
# define PRIXLEAST64 PRIX64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdFAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdFAST8
Packit 6c4009
# define PRIdFAST8 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiFAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiFAST8
Packit 6c4009
# define PRIiFAST8 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoFAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoFAST8
Packit 6c4009
# define PRIoFAST8 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuFAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuFAST8
Packit 6c4009
# define PRIuFAST8 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxFAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxFAST8
Packit 6c4009
# define PRIxFAST8 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXFAST8 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXFAST8
Packit 6c4009
# define PRIXFAST8 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdFAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdFAST16
Packit 6c4009
# define PRIdFAST16 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiFAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiFAST16
Packit 6c4009
# define PRIiFAST16 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoFAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoFAST16
Packit 6c4009
# define PRIoFAST16 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuFAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuFAST16
Packit 6c4009
# define PRIuFAST16 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxFAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxFAST16
Packit 6c4009
# define PRIxFAST16 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXFAST16 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXFAST16
Packit 6c4009
# define PRIXFAST16 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdFAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdFAST32
Packit 6c4009
# define PRIdFAST32 "d"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiFAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiFAST32
Packit 6c4009
# define PRIiFAST32 "i"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoFAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoFAST32
Packit 6c4009
# define PRIoFAST32 "o"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuFAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuFAST32
Packit 6c4009
# define PRIuFAST32 "u"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxFAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxFAST32
Packit 6c4009
# define PRIxFAST32 "x"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXFAST32 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXFAST32
Packit 6c4009
# define PRIXFAST32 "X"
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdFAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdFAST64
Packit 6c4009
# define PRIdFAST64 PRId64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiFAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiFAST64
Packit 6c4009
# define PRIiFAST64 PRIi64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoFAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoFAST64
Packit 6c4009
# define PRIoFAST64 PRIo64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuFAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuFAST64
Packit 6c4009
# define PRIuFAST64 PRIu64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxFAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxFAST64
Packit 6c4009
# define PRIxFAST64 PRIx64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXFAST64 || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXFAST64
Packit 6c4009
# define PRIXFAST64 PRIX64
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdMAX || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdMAX
Packit 6c4009
# define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiMAX || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiMAX
Packit 6c4009
# define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoMAX || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoMAX
Packit 6c4009
# define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuMAX || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuMAX
Packit 6c4009
# define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxMAX || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxMAX
Packit 6c4009
# define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXMAX || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXMAX
Packit 6c4009
# define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIdPTR || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIdPTR
Packit 6c4009
# define PRIdPTR \
Packit 6c4009
  (sizeof (void *) == sizeof (long) ? "ld" : \
Packit 6c4009
   sizeof (void *) == sizeof (int) ? "d" : \
Packit 6c4009
   "lld")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIiPTR || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIiPTR
Packit 6c4009
# define PRIiPTR \
Packit 6c4009
  (sizeof (void *) == sizeof (long) ? "li" : \
Packit 6c4009
   sizeof (void *) == sizeof (int) ? "i" : \
Packit 6c4009
   "lli")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIoPTR || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIoPTR
Packit 6c4009
# define PRIoPTR \
Packit 6c4009
  (sizeof (void *) == sizeof (long) ? "lo" : \
Packit 6c4009
   sizeof (void *) == sizeof (int) ? "o" : \
Packit 6c4009
   "llo")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIuPTR || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIuPTR
Packit 6c4009
# define PRIuPTR \
Packit 6c4009
  (sizeof (void *) == sizeof (long) ? "lu" : \
Packit 6c4009
   sizeof (void *) == sizeof (int) ? "u" : \
Packit 6c4009
   "llu")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIxPTR || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIxPTR
Packit 6c4009
# define PRIxPTR \
Packit 6c4009
  (sizeof (void *) == sizeof (long) ? "lx" : \
Packit 6c4009
   sizeof (void *) == sizeof (int) ? "x" : \
Packit 6c4009
   "llx")
Packit 6c4009
#endif
Packit 6c4009
#if !defined PRIXPTR || PRI_MACROS_BROKEN
Packit 6c4009
# undef PRIXPTR
Packit 6c4009
# define PRIXPTR \
Packit 6c4009
  (sizeof (void *) == sizeof (long) ? "lX" : \
Packit 6c4009
   sizeof (void *) == sizeof (int) ? "X" : \
Packit 6c4009
   "llX")
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* @@ end of prolog @@ */
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
/* Rename the non ISO C functions.  This is required by the standard
Packit 6c4009
   because some ISO C functions will require linking with this object
Packit 6c4009
   file and the name space must not be polluted.  */
Packit 6c4009
# define open(name, flags)	__open_nocancel (name, flags)
Packit 6c4009
# define close(fd)		__close_nocancel_nostatus (fd)
Packit 6c4009
# define read(fd, buf, n)	__read_nocancel (fd, buf, n)
Packit 6c4009
# define mmap(addr, len, prot, flags, fd, offset) \
Packit 6c4009
  __mmap (addr, len, prot, flags, fd, offset)
Packit 6c4009
# define munmap(addr, len)	__munmap (addr, len)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* For systems that distinguish between text and binary I/O.
Packit 6c4009
   O_BINARY is usually declared in <fcntl.h>. */
Packit 6c4009
#if !defined O_BINARY && defined _O_BINARY
Packit 6c4009
  /* For MSC-compatible compilers.  */
Packit 6c4009
# define O_BINARY _O_BINARY
Packit 6c4009
# define O_TEXT _O_TEXT
Packit 6c4009
#endif
Packit 6c4009
#ifdef __BEOS__
Packit 6c4009
  /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect.  */
Packit 6c4009
# undef O_BINARY
Packit 6c4009
# undef O_TEXT
Packit 6c4009
#endif
Packit 6c4009
/* On reasonable systems, binary I/O is the default.  */
Packit 6c4009
#ifndef O_BINARY
Packit 6c4009
# define O_BINARY 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* We need a sign, whether a new catalog was loaded, which can be associated
Packit 6c4009
   with all translations.  This is important if the translations are
Packit 6c4009
   cached by one of GCC's features.  */
Packit 6c4009
int _nl_msg_cat_cntr;
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Expand a system dependent string segment.  Return NULL if unsupported.  */
Packit 6c4009
static const char *
Packit 6c4009
get_sysdep_segment_value (const char *name)
Packit 6c4009
{
Packit 6c4009
  /* Test for an ISO C 99 section 7.8.1 format string directive.
Packit 6c4009
     Syntax:
Packit 6c4009
     P R I { d | i | o | u | x | X }
Packit 6c4009
     { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR }  */
Packit 6c4009
  /* We don't use a table of 14 times 6 'const char *' strings here, because
Packit 6c4009
     data relocations cost startup time.  */
Packit 6c4009
  if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
Packit 6c4009
    {
Packit 6c4009
      if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
Packit 6c4009
	  || name[3] == 'x' || name[3] == 'X')
Packit 6c4009
	{
Packit 6c4009
	  if (name[4] == '8' && name[5] == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[3] == 'd')
Packit 6c4009
		return PRId8;
Packit 6c4009
	      if (name[3] == 'i')
Packit 6c4009
		return PRIi8;
Packit 6c4009
	      if (name[3] == 'o')
Packit 6c4009
		return PRIo8;
Packit 6c4009
	      if (name[3] == 'u')
Packit 6c4009
		return PRIu8;
Packit 6c4009
	      if (name[3] == 'x')
Packit 6c4009
		return PRIx8;
Packit 6c4009
	      if (name[3] == 'X')
Packit 6c4009
		return PRIX8;
Packit 6c4009
	      abort ();
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[3] == 'd')
Packit 6c4009
		return PRId16;
Packit 6c4009
	      if (name[3] == 'i')
Packit 6c4009
		return PRIi16;
Packit 6c4009
	      if (name[3] == 'o')
Packit 6c4009
		return PRIo16;
Packit 6c4009
	      if (name[3] == 'u')
Packit 6c4009
		return PRIu16;
Packit 6c4009
	      if (name[3] == 'x')
Packit 6c4009
		return PRIx16;
Packit 6c4009
	      if (name[3] == 'X')
Packit 6c4009
		return PRIX16;
Packit 6c4009
	      abort ();
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[3] == 'd')
Packit 6c4009
		return PRId32;
Packit 6c4009
	      if (name[3] == 'i')
Packit 6c4009
		return PRIi32;
Packit 6c4009
	      if (name[3] == 'o')
Packit 6c4009
		return PRIo32;
Packit 6c4009
	      if (name[3] == 'u')
Packit 6c4009
		return PRIu32;
Packit 6c4009
	      if (name[3] == 'x')
Packit 6c4009
		return PRIx32;
Packit 6c4009
	      if (name[3] == 'X')
Packit 6c4009
		return PRIX32;
Packit 6c4009
	      abort ();
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[3] == 'd')
Packit 6c4009
		return PRId64;
Packit 6c4009
	      if (name[3] == 'i')
Packit 6c4009
		return PRIi64;
Packit 6c4009
	      if (name[3] == 'o')
Packit 6c4009
		return PRIo64;
Packit 6c4009
	      if (name[3] == 'u')
Packit 6c4009
		return PRIu64;
Packit 6c4009
	      if (name[3] == 'x')
Packit 6c4009
		return PRIx64;
Packit 6c4009
	      if (name[3] == 'X')
Packit 6c4009
		return PRIX64;
Packit 6c4009
	      abort ();
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
Packit 6c4009
	      && name[7] == 'S' && name[8] == 'T')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[9] == '8' && name[10] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdLEAST8;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiLEAST8;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoLEAST8;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuLEAST8;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxLEAST8;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXLEAST8;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	      if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdLEAST16;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiLEAST16;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoLEAST16;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuLEAST16;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxLEAST16;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXLEAST16;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	      if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdLEAST32;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiLEAST32;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoLEAST32;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuLEAST32;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxLEAST32;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXLEAST32;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	      if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdLEAST64;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiLEAST64;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoLEAST64;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuLEAST64;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxLEAST64;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXLEAST64;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
Packit 6c4009
	      && name[7] == 'T')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[8] == '8' && name[9] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdFAST8;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiFAST8;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoFAST8;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuFAST8;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxFAST8;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXFAST8;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	      if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdFAST16;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiFAST16;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoFAST16;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuFAST16;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxFAST16;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXFAST16;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	      if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdFAST32;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiFAST32;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoFAST32;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuFAST32;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxFAST32;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXFAST32;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	      if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
Packit 6c4009
		{
Packit 6c4009
		  if (name[3] == 'd')
Packit 6c4009
		    return PRIdFAST64;
Packit 6c4009
		  if (name[3] == 'i')
Packit 6c4009
		    return PRIiFAST64;
Packit 6c4009
		  if (name[3] == 'o')
Packit 6c4009
		    return PRIoFAST64;
Packit 6c4009
		  if (name[3] == 'u')
Packit 6c4009
		    return PRIuFAST64;
Packit 6c4009
		  if (name[3] == 'x')
Packit 6c4009
		    return PRIxFAST64;
Packit 6c4009
		  if (name[3] == 'X')
Packit 6c4009
		    return PRIXFAST64;
Packit 6c4009
		  abort ();
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
Packit 6c4009
	      && name[7] == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[3] == 'd')
Packit 6c4009
		return PRIdMAX;
Packit 6c4009
	      if (name[3] == 'i')
Packit 6c4009
		return PRIiMAX;
Packit 6c4009
	      if (name[3] == 'o')
Packit 6c4009
		return PRIoMAX;
Packit 6c4009
	      if (name[3] == 'u')
Packit 6c4009
		return PRIuMAX;
Packit 6c4009
	      if (name[3] == 'x')
Packit 6c4009
		return PRIxMAX;
Packit 6c4009
	      if (name[3] == 'X')
Packit 6c4009
		return PRIXMAX;
Packit 6c4009
	      abort ();
Packit 6c4009
	    }
Packit 6c4009
	  if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
Packit 6c4009
	      && name[7] == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      if (name[3] == 'd')
Packit 6c4009
		return PRIdPTR;
Packit 6c4009
	      if (name[3] == 'i')
Packit 6c4009
		return PRIiPTR;
Packit 6c4009
	      if (name[3] == 'o')
Packit 6c4009
		return PRIoPTR;
Packit 6c4009
	      if (name[3] == 'u')
Packit 6c4009
		return PRIuPTR;
Packit 6c4009
	      if (name[3] == 'x')
Packit 6c4009
		return PRIxPTR;
Packit 6c4009
	      if (name[3] == 'X')
Packit 6c4009
		return PRIXPTR;
Packit 6c4009
	      abort ();
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  /* Test for a glibc specific printf() format directive flag.  */
Packit 6c4009
  if (name[0] == 'I' && name[1] == '\0')
Packit 6c4009
    {
Packit 6c4009
#if defined _LIBC \
Packit 6c4009
    || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) \
Packit 6c4009
        && !defined __UCLIBC__)
Packit 6c4009
      /* The 'I' flag, in numeric format directives, replaces ASCII digits
Packit 6c4009
	 with the 'outdigits' defined in the LC_CTYPE locale facet.  This is
Packit 6c4009
	 used for Farsi (Persian), some Indic languages, and maybe Arabic.  */
Packit 6c4009
      return "I";
Packit 6c4009
#else
Packit 6c4009
      return "";
Packit 6c4009
#endif
Packit 6c4009
    }
Packit 6c4009
  /* Other system dependent strings are not valid.  */
Packit 6c4009
  return NULL;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Load the message catalogs specified by FILENAME.  If it is no valid
Packit 6c4009
   message catalog do nothing.  */
Packit 6c4009
void
Packit 6c4009
_nl_load_domain (struct loaded_l10nfile *domain_file,
Packit 6c4009
		 struct binding *domainbinding)
Packit 6c4009
{
Packit 6c4009
  __libc_lock_define_initialized_recursive (static, lock);
Packit 6c4009
  int fd = -1;
Packit 6c4009
  size_t size;
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
  struct stat64 st;
Packit 6c4009
#else
Packit 6c4009
  struct stat st;
Packit 6c4009
#endif
Packit 6c4009
  struct mo_file_header *data = (struct mo_file_header *) -1;
Packit 6c4009
  int use_mmap = 0;
Packit 6c4009
  struct loaded_domain *domain;
Packit 6c4009
  int revision;
Packit 6c4009
  const char *nullentry;
Packit 6c4009
  size_t nullentrylen;
Packit 6c4009
Packit 6c4009
  __libc_lock_lock_recursive (lock);
Packit 6c4009
  if (domain_file->decided != 0)
Packit 6c4009
    {
Packit 6c4009
      /* There are two possibilities:
Packit 6c4009
Packit 6c4009
	 + this is the same thread calling again during this initialization
Packit 6c4009
	   via _nl_find_msg.  We have initialized everything this call needs.
Packit 6c4009
Packit 6c4009
	 + this is another thread which tried to initialize this object.
Packit 6c4009
	   Not necessary anymore since if the lock is available this
Packit 6c4009
	   is finished.
Packit 6c4009
      */
Packit 6c4009
      goto done;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  domain_file->decided = -1;
Packit 6c4009
  domain_file->data = NULL;
Packit 6c4009
Packit 6c4009
  /* Note that it would be useless to store domainbinding in domain_file
Packit 6c4009
     because domainbinding might be == NULL now but != NULL later (after
Packit 6c4009
     a call to bind_textdomain_codeset).  */
Packit 6c4009
Packit 6c4009
  /* If the record does not represent a valid locale the FILENAME
Packit 6c4009
     might be NULL.  This can happen when according to the given
Packit 6c4009
     specification the locale file name is different for XPG and CEN
Packit 6c4009
     syntax.  */
Packit 6c4009
  if (domain_file->filename == NULL)
Packit 6c4009
    goto out;
Packit 6c4009
Packit 6c4009
  /* Try to open the addressed file.  */
Packit 6c4009
  fd = open (domain_file->filename, O_RDONLY | O_BINARY);
Packit 6c4009
  if (fd == -1)
Packit 6c4009
    goto out;
Packit 6c4009
Packit 6c4009
  /* We must know about the size of the file.  */
Packit 6c4009
  if (
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
      __builtin_expect (fstat64 (fd, &st) != 0, 0)
Packit 6c4009
#else
Packit 6c4009
      __builtin_expect (fstat (fd, &st) != 0, 0)
Packit 6c4009
#endif
Packit 6c4009
      || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
Packit 6c4009
      || __builtin_expect (size < sizeof (struct mo_file_header), 0))
Packit 6c4009
    /* Something went wrong.  */
Packit 6c4009
    goto out;
Packit 6c4009
Packit 6c4009
#ifdef HAVE_MMAP
Packit 6c4009
  /* Now we are ready to load the file.  If mmap() is available we try
Packit 6c4009
     this first.  If not available or it failed we try to load it.  */
Packit 6c4009
  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
Packit 6c4009
					 MAP_PRIVATE, fd, 0);
Packit 6c4009
Packit 6c4009
  if (__builtin_expect (data != MAP_FAILED, 1))
Packit 6c4009
    {
Packit 6c4009
      /* mmap() call was successful.  */
Packit 6c4009
      close (fd);
Packit 6c4009
      fd = -1;
Packit 6c4009
      use_mmap = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  assert (MAP_FAILED == (void *) -1);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /* If the data is not yet available (i.e. mmap'ed) we try to load
Packit 6c4009
     it manually.  */
Packit 6c4009
  if (data == (struct mo_file_header *) -1)
Packit 6c4009
    {
Packit 6c4009
      size_t to_read;
Packit 6c4009
      char *read_ptr;
Packit 6c4009
Packit 6c4009
      data = (struct mo_file_header *) malloc (size);
Packit 6c4009
      if (data == NULL)
Packit 6c4009
	goto out;
Packit 6c4009
Packit 6c4009
      to_read = size;
Packit 6c4009
      read_ptr = (char *) data;
Packit 6c4009
      do
Packit 6c4009
	{
Packit 6c4009
	  long int nb = (long int) read (fd, read_ptr, to_read);
Packit 6c4009
	  if (nb <= 0)
Packit 6c4009
	    {
Packit 6c4009
#ifdef EINTR
Packit 6c4009
	      if (nb == -1 && errno == EINTR)
Packit 6c4009
		continue;
Packit 6c4009
#endif
Packit 6c4009
	      goto out;
Packit 6c4009
	    }
Packit 6c4009
	  read_ptr += nb;
Packit 6c4009
	  to_read -= nb;
Packit 6c4009
	}
Packit 6c4009
      while (to_read > 0);
Packit 6c4009
Packit 6c4009
      close (fd);
Packit 6c4009
      fd = -1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Using the magic number we can test whether it really is a message
Packit 6c4009
     catalog file.  */
Packit 6c4009
  if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
Packit 6c4009
			0))
Packit 6c4009
    {
Packit 6c4009
      /* The magic number is wrong: not a message catalog file.  */
Packit 6c4009
#ifdef HAVE_MMAP
Packit 6c4009
      if (use_mmap)
Packit 6c4009
	munmap ((caddr_t) data, size);
Packit 6c4009
      else
Packit 6c4009
#endif
Packit 6c4009
	free (data);
Packit 6c4009
      goto out;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
Packit 6c4009
  if (domain == NULL)
Packit 6c4009
    goto out;
Packit 6c4009
  domain_file->data = domain;
Packit 6c4009
Packit 6c4009
  domain->data = (char *) data;
Packit 6c4009
  domain->use_mmap = use_mmap;
Packit 6c4009
  domain->mmap_size = size;
Packit 6c4009
  domain->must_swap = data->magic != _MAGIC;
Packit 6c4009
  domain->malloced = NULL;
Packit 6c4009
Packit 6c4009
  /* Fill in the information about the available tables.  */
Packit 6c4009
  revision = W (domain->must_swap, data->revision);
Packit 6c4009
  /* We support only the major revisions 0 and 1.  */
Packit 6c4009
  switch (revision >> 16)
Packit 6c4009
    {
Packit 6c4009
    case 0:
Packit 6c4009
    case 1:
Packit 6c4009
      domain->nstrings = W (domain->must_swap, data->nstrings);
Packit 6c4009
      domain->orig_tab = (const struct string_desc *)
Packit 6c4009
	((char *) data + W (domain->must_swap, data->orig_tab_offset));
Packit 6c4009
      domain->trans_tab = (const struct string_desc *)
Packit 6c4009
	((char *) data + W (domain->must_swap, data->trans_tab_offset));
Packit 6c4009
      domain->hash_size = W (domain->must_swap, data->hash_tab_size);
Packit 6c4009
      domain->hash_tab =
Packit 6c4009
	(domain->hash_size > 2
Packit 6c4009
	 ? (const nls_uint32 *)
Packit 6c4009
	   ((char *) data + W (domain->must_swap, data->hash_tab_offset))
Packit 6c4009
	 : NULL);
Packit 6c4009
      domain->must_swap_hash_tab = domain->must_swap;
Packit 6c4009
Packit 6c4009
      /* Now dispatch on the minor revision.  */
Packit 6c4009
      switch (revision & 0xffff)
Packit 6c4009
	{
Packit 6c4009
	case 0:
Packit 6c4009
	  domain->n_sysdep_strings = 0;
Packit 6c4009
	  domain->orig_sysdep_tab = NULL;
Packit 6c4009
	  domain->trans_sysdep_tab = NULL;
Packit 6c4009
	  break;
Packit 6c4009
	case 1:
Packit 6c4009
	default:
Packit 6c4009
	  {
Packit 6c4009
	    nls_uint32 n_sysdep_strings;
Packit 6c4009
Packit 6c4009
	    if (domain->hash_tab == NULL)
Packit 6c4009
	      /* This is invalid.  These minor revisions need a hash table.  */
Packit 6c4009
	      goto invalid;
Packit 6c4009
Packit 6c4009
	    n_sysdep_strings =
Packit 6c4009
	      W (domain->must_swap, data->n_sysdep_strings);
Packit 6c4009
	    if (n_sysdep_strings > 0)
Packit 6c4009
	      {
Packit 6c4009
		nls_uint32 n_sysdep_segments;
Packit 6c4009
		const struct sysdep_segment *sysdep_segments;
Packit 6c4009
		const char **sysdep_segment_values;
Packit 6c4009
		const nls_uint32 *orig_sysdep_tab;
Packit 6c4009
		const nls_uint32 *trans_sysdep_tab;
Packit 6c4009
		nls_uint32 n_inmem_sysdep_strings;
Packit 6c4009
		size_t memneed;
Packit 6c4009
		char *mem;
Packit 6c4009
		struct sysdep_string_desc *inmem_orig_sysdep_tab;
Packit 6c4009
		struct sysdep_string_desc *inmem_trans_sysdep_tab;
Packit 6c4009
		nls_uint32 *inmem_hash_tab;
Packit 6c4009
		unsigned int i, j;
Packit 6c4009
Packit 6c4009
		/* Get the values of the system dependent segments.  */
Packit 6c4009
		n_sysdep_segments =
Packit 6c4009
		  W (domain->must_swap, data->n_sysdep_segments);
Packit 6c4009
		sysdep_segments = (const struct sysdep_segment *)
Packit 6c4009
		  ((char *) data
Packit 6c4009
		   + W (domain->must_swap, data->sysdep_segments_offset));
Packit 6c4009
		sysdep_segment_values = calloc
Packit 6c4009
		  (n_sysdep_segments, sizeof (const char *));
Packit 6c4009
		if (sysdep_segment_values == NULL)
Packit 6c4009
		  goto invalid;
Packit 6c4009
		for (i = 0; i < n_sysdep_segments; i++)
Packit 6c4009
		  {
Packit 6c4009
		    const char *name =
Packit 6c4009
		      (char *) data
Packit 6c4009
		      + W (domain->must_swap, sysdep_segments[i].offset);
Packit 6c4009
		    nls_uint32 namelen =
Packit 6c4009
		      W (domain->must_swap, sysdep_segments[i].length);
Packit 6c4009
Packit 6c4009
		    if (!(namelen > 0 && name[namelen - 1] == '\0'))
Packit 6c4009
		      {
Packit 6c4009
			free (sysdep_segment_values);
Packit 6c4009
			goto invalid;
Packit 6c4009
		      }
Packit 6c4009
Packit 6c4009
		    sysdep_segment_values[i] = get_sysdep_segment_value (name);
Packit 6c4009
		  }
Packit 6c4009
Packit 6c4009
		orig_sysdep_tab = (const nls_uint32 *)
Packit 6c4009
		  ((char *) data
Packit 6c4009
		   + W (domain->must_swap, data->orig_sysdep_tab_offset));
Packit 6c4009
		trans_sysdep_tab = (const nls_uint32 *)
Packit 6c4009
		  ((char *) data
Packit 6c4009
		   + W (domain->must_swap, data->trans_sysdep_tab_offset));
Packit 6c4009
Packit 6c4009
		/* Compute the amount of additional memory needed for the
Packit 6c4009
		   system dependent strings and the augmented hash table.
Packit 6c4009
		   At the same time, also drop string pairs which refer to
Packit 6c4009
		   an undefined system dependent segment.  */
Packit 6c4009
		n_inmem_sysdep_strings = 0;
Packit 6c4009
		memneed = domain->hash_size * sizeof (nls_uint32);
Packit 6c4009
		for (i = 0; i < n_sysdep_strings; i++)
Packit 6c4009
		  {
Packit 6c4009
		    int valid = 1;
Packit 6c4009
		    size_t needs[2];
Packit 6c4009
Packit 6c4009
		    for (j = 0; j < 2; j++)
Packit 6c4009
		      {
Packit 6c4009
			const struct sysdep_string *sysdep_string =
Packit 6c4009
			  (const struct sysdep_string *)
Packit 6c4009
			  ((char *) data
Packit 6c4009
			   + W (domain->must_swap,
Packit 6c4009
				j == 0
Packit 6c4009
				? orig_sysdep_tab[i]
Packit 6c4009
				: trans_sysdep_tab[i]));
Packit 6c4009
			size_t need = 0;
Packit 6c4009
			const struct segment_pair *p = sysdep_string->segments;
Packit 6c4009
Packit 6c4009
			if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
Packit 6c4009
			  for (p = sysdep_string->segments;; p++)
Packit 6c4009
			    {
Packit 6c4009
			      nls_uint32 sysdepref;
Packit 6c4009
Packit 6c4009
			      need += W (domain->must_swap, p->segsize);
Packit 6c4009
Packit 6c4009
			      sysdepref = W (domain->must_swap, p->sysdepref);
Packit 6c4009
			      if (sysdepref == SEGMENTS_END)
Packit 6c4009
				break;
Packit 6c4009
Packit 6c4009
			      if (sysdepref >= n_sysdep_segments)
Packit 6c4009
				{
Packit 6c4009
				  /* Invalid.  */
Packit 6c4009
				  free (sysdep_segment_values);
Packit 6c4009
				  goto invalid;
Packit 6c4009
				}
Packit 6c4009
Packit 6c4009
			      if (sysdep_segment_values[sysdepref] == NULL)
Packit 6c4009
				{
Packit 6c4009
				  /* This particular string pair is invalid.  */
Packit 6c4009
				  valid = 0;
Packit 6c4009
				  break;
Packit 6c4009
				}
Packit 6c4009
Packit 6c4009
			      need += strlen (sysdep_segment_values[sysdepref]);
Packit 6c4009
			    }
Packit 6c4009
Packit 6c4009
			needs[j] = need;
Packit 6c4009
			if (!valid)
Packit 6c4009
			  break;
Packit 6c4009
		      }
Packit 6c4009
Packit 6c4009
		    if (valid)
Packit 6c4009
		      {
Packit 6c4009
			n_inmem_sysdep_strings++;
Packit 6c4009
			memneed += needs[0] + needs[1];
Packit 6c4009
		      }
Packit 6c4009
		  }
Packit 6c4009
		memneed += 2 * n_inmem_sysdep_strings
Packit 6c4009
			   * sizeof (struct sysdep_string_desc);
Packit 6c4009
Packit 6c4009
		if (n_inmem_sysdep_strings > 0)
Packit 6c4009
		  {
Packit 6c4009
		    unsigned int k;
Packit 6c4009
Packit 6c4009
		    /* Allocate additional memory.  */
Packit 6c4009
		    mem = (char *) malloc (memneed);
Packit 6c4009
		    if (mem == NULL)
Packit 6c4009
		      goto invalid;
Packit 6c4009
Packit 6c4009
		    domain->malloced = mem;
Packit 6c4009
		    inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
Packit 6c4009
		    mem += n_inmem_sysdep_strings
Packit 6c4009
			   * sizeof (struct sysdep_string_desc);
Packit 6c4009
		    inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
Packit 6c4009
		    mem += n_inmem_sysdep_strings
Packit 6c4009
			   * sizeof (struct sysdep_string_desc);
Packit 6c4009
		    inmem_hash_tab = (nls_uint32 *) mem;
Packit 6c4009
		    mem += domain->hash_size * sizeof (nls_uint32);
Packit 6c4009
Packit 6c4009
		    /* Compute the system dependent strings.  */
Packit 6c4009
		    k = 0;
Packit 6c4009
		    for (i = 0; i < n_sysdep_strings; i++)
Packit 6c4009
		      {
Packit 6c4009
			int valid = 1;
Packit 6c4009
Packit 6c4009
			for (j = 0; j < 2; j++)
Packit 6c4009
			  {
Packit 6c4009
			    const struct sysdep_string *sysdep_string =
Packit 6c4009
			      (const struct sysdep_string *)
Packit 6c4009
			      ((char *) data
Packit 6c4009
			       + W (domain->must_swap,
Packit 6c4009
				    j == 0
Packit 6c4009
				    ? orig_sysdep_tab[i]
Packit 6c4009
				    : trans_sysdep_tab[i]));
Packit 6c4009
			    const struct segment_pair *p =
Packit 6c4009
			      sysdep_string->segments;
Packit 6c4009
Packit 6c4009
			    if (W (domain->must_swap, p->sysdepref)
Packit 6c4009
				!= SEGMENTS_END)
Packit 6c4009
			      for (p = sysdep_string->segments;; p++)
Packit 6c4009
				{
Packit 6c4009
				  nls_uint32 sysdepref;
Packit 6c4009
Packit 6c4009
				  sysdepref =
Packit 6c4009
				    W (domain->must_swap, p->sysdepref);
Packit 6c4009
				  if (sysdepref == SEGMENTS_END)
Packit 6c4009
				    break;
Packit 6c4009
Packit 6c4009
				  if (sysdep_segment_values[sysdepref] == NULL)
Packit 6c4009
				    {
Packit 6c4009
				      /* This particular string pair is
Packit 6c4009
					 invalid.  */
Packit 6c4009
				      valid = 0;
Packit 6c4009
				      break;
Packit 6c4009
				    }
Packit 6c4009
				}
Packit 6c4009
Packit 6c4009
			    if (!valid)
Packit 6c4009
			      break;
Packit 6c4009
			  }
Packit 6c4009
Packit 6c4009
			if (valid)
Packit 6c4009
			  {
Packit 6c4009
			    for (j = 0; j < 2; j++)
Packit 6c4009
			      {
Packit 6c4009
				const struct sysdep_string *sysdep_string =
Packit 6c4009
				  (const struct sysdep_string *)
Packit 6c4009
				  ((char *) data
Packit 6c4009
				   + W (domain->must_swap,
Packit 6c4009
					j == 0
Packit 6c4009
					? orig_sysdep_tab[i]
Packit 6c4009
					: trans_sysdep_tab[i]));
Packit 6c4009
				const char *static_segments =
Packit 6c4009
				  (char *) data
Packit 6c4009
				  + W (domain->must_swap, sysdep_string->offset);
Packit 6c4009
				const struct segment_pair *p =
Packit 6c4009
				  sysdep_string->segments;
Packit 6c4009
Packit 6c4009
				/* Concatenate the segments, and fill
Packit 6c4009
				   inmem_orig_sysdep_tab[k] (for j == 0) and
Packit 6c4009
				   inmem_trans_sysdep_tab[k] (for j == 1).  */
Packit 6c4009
Packit 6c4009
				struct sysdep_string_desc *inmem_tab_entry =
Packit 6c4009
				  (j == 0
Packit 6c4009
				   ? inmem_orig_sysdep_tab
Packit 6c4009
				   : inmem_trans_sysdep_tab)
Packit 6c4009
				  + k;
Packit 6c4009
Packit 6c4009
				if (W (domain->must_swap, p->sysdepref)
Packit 6c4009
				    == SEGMENTS_END)
Packit 6c4009
				  {
Packit 6c4009
				    /* Only one static segment.  */
Packit 6c4009
				    inmem_tab_entry->length =
Packit 6c4009
				      W (domain->must_swap, p->segsize);
Packit 6c4009
				    inmem_tab_entry->pointer = static_segments;
Packit 6c4009
				  }
Packit 6c4009
				else
Packit 6c4009
				  {
Packit 6c4009
				    inmem_tab_entry->pointer = mem;
Packit 6c4009
Packit 6c4009
				    for (p = sysdep_string->segments;; p++)
Packit 6c4009
				      {
Packit 6c4009
					nls_uint32 segsize =
Packit 6c4009
					  W (domain->must_swap, p->segsize);
Packit 6c4009
					nls_uint32 sysdepref =
Packit 6c4009
					  W (domain->must_swap, p->sysdepref);
Packit 6c4009
					size_t n;
Packit 6c4009
Packit 6c4009
					if (segsize > 0)
Packit 6c4009
					  {
Packit 6c4009
					    memcpy (mem, static_segments, segsize);
Packit 6c4009
					    mem += segsize;
Packit 6c4009
					    static_segments += segsize;
Packit 6c4009
					  }
Packit 6c4009
Packit 6c4009
					if (sysdepref == SEGMENTS_END)
Packit 6c4009
					  break;
Packit 6c4009
Packit 6c4009
					n = strlen (sysdep_segment_values[sysdepref]);
Packit 6c4009
					memcpy (mem, sysdep_segment_values[sysdepref], n);
Packit 6c4009
					mem += n;
Packit 6c4009
				      }
Packit 6c4009
Packit 6c4009
				    inmem_tab_entry->length =
Packit 6c4009
				      mem - inmem_tab_entry->pointer;
Packit 6c4009
				  }
Packit 6c4009
			      }
Packit 6c4009
Packit 6c4009
			    k++;
Packit 6c4009
			  }
Packit 6c4009
		      }
Packit 6c4009
		    if (k != n_inmem_sysdep_strings)
Packit 6c4009
		      abort ();
Packit 6c4009
Packit 6c4009
		    /* Compute the augmented hash table.  */
Packit 6c4009
		    for (i = 0; i < domain->hash_size; i++)
Packit 6c4009
		      inmem_hash_tab[i] =
Packit 6c4009
			W (domain->must_swap_hash_tab, domain->hash_tab[i]);
Packit 6c4009
		    for (i = 0; i < n_inmem_sysdep_strings; i++)
Packit 6c4009
		      {
Packit 6c4009
			const char *msgid = inmem_orig_sysdep_tab[i].pointer;
Packit 6c4009
			nls_uint32 hash_val = __hash_string (msgid);
Packit 6c4009
			nls_uint32 idx = hash_val % domain->hash_size;
Packit 6c4009
			nls_uint32 incr =
Packit 6c4009
			  1 + (hash_val % (domain->hash_size - 2));
Packit 6c4009
Packit 6c4009
			for (;;)
Packit 6c4009
			  {
Packit 6c4009
			    if (inmem_hash_tab[idx] == 0)
Packit 6c4009
			      {
Packit 6c4009
				/* Hash table entry is empty.  Use it.  */
Packit 6c4009
				inmem_hash_tab[idx] = 1 + domain->nstrings + i;
Packit 6c4009
				break;
Packit 6c4009
			      }
Packit 6c4009
Packit 6c4009
			    if (idx >= domain->hash_size - incr)
Packit 6c4009
			      idx -= domain->hash_size - incr;
Packit 6c4009
			    else
Packit 6c4009
			      idx += incr;
Packit 6c4009
			  }
Packit 6c4009
		      }
Packit 6c4009
Packit 6c4009
		    domain->n_sysdep_strings = n_inmem_sysdep_strings;
Packit 6c4009
		    domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
Packit 6c4009
		    domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
Packit 6c4009
Packit 6c4009
		    domain->hash_tab = inmem_hash_tab;
Packit 6c4009
		    domain->must_swap_hash_tab = 0;
Packit 6c4009
		  }
Packit 6c4009
		else
Packit 6c4009
		  {
Packit 6c4009
		    domain->n_sysdep_strings = 0;
Packit 6c4009
		    domain->orig_sysdep_tab = NULL;
Packit 6c4009
		    domain->trans_sysdep_tab = NULL;
Packit 6c4009
		  }
Packit 6c4009
Packit 6c4009
		free (sysdep_segment_values);
Packit 6c4009
	      }
Packit 6c4009
	    else
Packit 6c4009
	      {
Packit 6c4009
		domain->n_sysdep_strings = 0;
Packit 6c4009
		domain->orig_sysdep_tab = NULL;
Packit 6c4009
		domain->trans_sysdep_tab = NULL;
Packit 6c4009
	      }
Packit 6c4009
	  }
Packit 6c4009
	  break;
Packit 6c4009
	}
Packit 6c4009
      break;
Packit 6c4009
    default:
Packit 6c4009
      /* This is an invalid revision.  */
Packit 6c4009
    invalid:
Packit 6c4009
      /* This is an invalid .mo file or we ran out of resources.  */
Packit 6c4009
      free (domain->malloced);
Packit 6c4009
#ifdef HAVE_MMAP
Packit 6c4009
      if (use_mmap)
Packit 6c4009
	munmap ((caddr_t) data, size);
Packit 6c4009
      else
Packit 6c4009
#endif
Packit 6c4009
	free (data);
Packit 6c4009
      free (domain);
Packit 6c4009
      domain_file->data = NULL;
Packit 6c4009
      goto out;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* No caches of converted translations so far.  */
Packit 6c4009
  domain->conversions = NULL;
Packit 6c4009
  domain->nconversions = 0;
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
  __libc_rwlock_init (domain->conversions_lock);
Packit 6c4009
#else
Packit 6c4009
  gl_rwlock_init (domain->conversions_lock);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /* Get the header entry and look for a plural specification.  */
Packit 6c4009
#ifdef IN_LIBGLOCALE
Packit 6c4009
  nullentry =
Packit 6c4009
    _nl_find_msg (domain_file, domainbinding, NULL, "", &nullentrylen);
Packit 6c4009
#else
Packit 6c4009
  nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
Packit 6c4009
#endif
Packit 6c4009
  if (__builtin_expect (nullentry == (char *) -1, 0))
Packit 6c4009
    {
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
      __libc_rwlock_fini (domain->conversions_lock);
Packit 6c4009
#endif
Packit 6c4009
      goto invalid;
Packit 6c4009
    }
Packit 6c4009
  EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
Packit 6c4009
Packit 6c4009
 out:
Packit 6c4009
  if (fd != -1)
Packit 6c4009
    close (fd);
Packit 6c4009
Packit 6c4009
  domain_file->decided = 1;
Packit 6c4009
Packit 6c4009
 done:
Packit 6c4009
  __libc_lock_unlock_recursive (lock);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
void
Packit 6c4009
__libc_freeres_fn_section
Packit 6c4009
_nl_unload_domain (struct loaded_domain *domain)
Packit 6c4009
{
Packit 6c4009
  size_t i;
Packit 6c4009
Packit 6c4009
  if (domain->plural != &__gettext_germanic_plural)
Packit 6c4009
    __gettext_free_exp ((struct expression *) domain->plural);
Packit 6c4009
Packit 6c4009
  for (i = 0; i < domain->nconversions; i++)
Packit 6c4009
    {
Packit 6c4009
      struct converted_domain *convd = &domain->conversions[i];
Packit 6c4009
Packit 6c4009
      free ((char *) convd->encoding);
Packit 6c4009
      if (convd->conv_tab != NULL && convd->conv_tab != (char **) -1)
Packit 6c4009
	free (convd->conv_tab);
Packit 6c4009
      if (convd->conv != (__gconv_t) -1)
Packit 6c4009
	__gconv_close (convd->conv);
Packit 6c4009
    }
Packit 6c4009
  free (domain->conversions);
Packit 6c4009
  __libc_rwlock_fini (domain->conversions_lock);
Packit 6c4009
Packit 6c4009
  free (domain->malloced);
Packit 6c4009
Packit 6c4009
# ifdef _POSIX_MAPPED_FILES
Packit 6c4009
  if (domain->use_mmap)
Packit 6c4009
    munmap ((caddr_t) domain->data, domain->mmap_size);
Packit 6c4009
  else
Packit 6c4009
# endif	/* _POSIX_MAPPED_FILES */
Packit 6c4009
    free ((void *) domain->data);
Packit 6c4009
Packit 6c4009
  free (domain);
Packit 6c4009
}
Packit 6c4009
#endif