(root)/
binutils-2.41/
intl/
loadmsgcat.c
       1  /* Load needed message catalogs.
       2     Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or modify it
       5     under the terms of the GNU Library General Public License as published
       6     by the Free Software Foundation; either version 2, or (at your option)
       7     any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Library General Public License for more details.
      13  
      14     You should have received a copy of the GNU Library General Public
      15     License along with this program; if not, write to the Free Software
      16     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
      17     USA.  */
      18  
      19  /* Tell glibc's <string.h> to provide a prototype for mempcpy().
      20     This must come before <config.h> because <config.h> may include
      21     <features.h>, and once <features.h> has been included, it's too late.  */
      22  #ifndef _GNU_SOURCE
      23  # define _GNU_SOURCE    1
      24  #endif
      25  
      26  #ifdef HAVE_CONFIG_H
      27  # include <config.h>
      28  #endif
      29  
      30  #include <ctype.h>
      31  #include <errno.h>
      32  #include <fcntl.h>
      33  #include <sys/types.h>
      34  #include <sys/stat.h>
      35  
      36  #ifdef __GNUC__
      37  # undef  alloca
      38  # define alloca __builtin_alloca
      39  # define HAVE_ALLOCA 1
      40  #else
      41  # ifdef _MSC_VER
      42  #  include <malloc.h>
      43  #  define alloca _alloca
      44  # else
      45  #  if defined HAVE_ALLOCA_H || defined _LIBC
      46  #   include <alloca.h>
      47  #  else
      48  #   ifdef _AIX
      49   #pragma alloca
      50  #   else
      51  #    ifndef alloca
      52  char *alloca ();
      53  #    endif
      54  #   endif
      55  #  endif
      56  # endif
      57  #endif
      58  
      59  #include <stdlib.h>
      60  #include <string.h>
      61  
      62  #if defined HAVE_UNISTD_H || defined _LIBC
      63  # include <unistd.h>
      64  #endif
      65  
      66  #ifdef _LIBC
      67  # include <langinfo.h>
      68  # include <locale.h>
      69  #endif
      70  
      71  #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
      72      || (defined _LIBC && defined _POSIX_MAPPED_FILES)
      73  # include <sys/mman.h>
      74  # undef HAVE_MMAP
      75  # define HAVE_MMAP	1
      76  #else
      77  # undef HAVE_MMAP
      78  #endif
      79  
      80  #if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC
      81  # include <stdint.h>
      82  #endif
      83  #if defined HAVE_INTTYPES_H || defined _LIBC
      84  # include <inttypes.h>
      85  #endif
      86  
      87  #include "gmo.h"
      88  #include "gettextP.h"
      89  #include "hash-string.h"
      90  #include "plural-exp.h"
      91  
      92  #ifdef _LIBC
      93  # include "../locale/localeinfo.h"
      94  #endif
      95  
      96  /* Provide fallback values for macros that ought to be defined in <inttypes.h>.
      97     Note that our fallback values need not be literal strings, because we don't
      98     use them with preprocessor string concatenation.  */
      99  #if !defined PRId8 || PRI_MACROS_BROKEN
     100  # undef PRId8
     101  # define PRId8 "d"
     102  #endif
     103  #if !defined PRIi8 || PRI_MACROS_BROKEN
     104  # undef PRIi8
     105  # define PRIi8 "i"
     106  #endif
     107  #if !defined PRIo8 || PRI_MACROS_BROKEN
     108  # undef PRIo8
     109  # define PRIo8 "o"
     110  #endif
     111  #if !defined PRIu8 || PRI_MACROS_BROKEN
     112  # undef PRIu8
     113  # define PRIu8 "u"
     114  #endif
     115  #if !defined PRIx8 || PRI_MACROS_BROKEN
     116  # undef PRIx8
     117  # define PRIx8 "x"
     118  #endif
     119  #if !defined PRIX8 || PRI_MACROS_BROKEN
     120  # undef PRIX8
     121  # define PRIX8 "X"
     122  #endif
     123  #if !defined PRId16 || PRI_MACROS_BROKEN
     124  # undef PRId16
     125  # define PRId16 "d"
     126  #endif
     127  #if !defined PRIi16 || PRI_MACROS_BROKEN
     128  # undef PRIi16
     129  # define PRIi16 "i"
     130  #endif
     131  #if !defined PRIo16 || PRI_MACROS_BROKEN
     132  # undef PRIo16
     133  # define PRIo16 "o"
     134  #endif
     135  #if !defined PRIu16 || PRI_MACROS_BROKEN
     136  # undef PRIu16
     137  # define PRIu16 "u"
     138  #endif
     139  #if !defined PRIx16 || PRI_MACROS_BROKEN
     140  # undef PRIx16
     141  # define PRIx16 "x"
     142  #endif
     143  #if !defined PRIX16 || PRI_MACROS_BROKEN
     144  # undef PRIX16
     145  # define PRIX16 "X"
     146  #endif
     147  #if !defined PRId32 || PRI_MACROS_BROKEN
     148  # undef PRId32
     149  # define PRId32 "d"
     150  #endif
     151  #if !defined PRIi32 || PRI_MACROS_BROKEN
     152  # undef PRIi32
     153  # define PRIi32 "i"
     154  #endif
     155  #if !defined PRIo32 || PRI_MACROS_BROKEN
     156  # undef PRIo32
     157  # define PRIo32 "o"
     158  #endif
     159  #if !defined PRIu32 || PRI_MACROS_BROKEN
     160  # undef PRIu32
     161  # define PRIu32 "u"
     162  #endif
     163  #if !defined PRIx32 || PRI_MACROS_BROKEN
     164  # undef PRIx32
     165  # define PRIx32 "x"
     166  #endif
     167  #if !defined PRIX32 || PRI_MACROS_BROKEN
     168  # undef PRIX32
     169  # define PRIX32 "X"
     170  #endif
     171  #if !defined PRId64 || PRI_MACROS_BROKEN
     172  # undef PRId64
     173  # define PRId64 (sizeof (long) == 8 ? "ld" : "lld")
     174  #endif
     175  #if !defined PRIi64 || PRI_MACROS_BROKEN
     176  # undef PRIi64
     177  # define PRIi64 (sizeof (long) == 8 ? "li" : "lli")
     178  #endif
     179  #if !defined PRIo64 || PRI_MACROS_BROKEN
     180  # undef PRIo64
     181  # define PRIo64 (sizeof (long) == 8 ? "lo" : "llo")
     182  #endif
     183  #if !defined PRIu64 || PRI_MACROS_BROKEN
     184  # undef PRIu64
     185  # define PRIu64 (sizeof (long) == 8 ? "lu" : "llu")
     186  #endif
     187  #if !defined PRIx64 || PRI_MACROS_BROKEN
     188  # undef PRIx64
     189  # define PRIx64 (sizeof (long) == 8 ? "lx" : "llx")
     190  #endif
     191  #if !defined PRIX64 || PRI_MACROS_BROKEN
     192  # undef PRIX64
     193  # define PRIX64 (sizeof (long) == 8 ? "lX" : "llX")
     194  #endif
     195  #if !defined PRIdLEAST8 || PRI_MACROS_BROKEN
     196  # undef PRIdLEAST8
     197  # define PRIdLEAST8 "d"
     198  #endif
     199  #if !defined PRIiLEAST8 || PRI_MACROS_BROKEN
     200  # undef PRIiLEAST8
     201  # define PRIiLEAST8 "i"
     202  #endif
     203  #if !defined PRIoLEAST8 || PRI_MACROS_BROKEN
     204  # undef PRIoLEAST8
     205  # define PRIoLEAST8 "o"
     206  #endif
     207  #if !defined PRIuLEAST8 || PRI_MACROS_BROKEN
     208  # undef PRIuLEAST8
     209  # define PRIuLEAST8 "u"
     210  #endif
     211  #if !defined PRIxLEAST8 || PRI_MACROS_BROKEN
     212  # undef PRIxLEAST8
     213  # define PRIxLEAST8 "x"
     214  #endif
     215  #if !defined PRIXLEAST8 || PRI_MACROS_BROKEN
     216  # undef PRIXLEAST8
     217  # define PRIXLEAST8 "X"
     218  #endif
     219  #if !defined PRIdLEAST16 || PRI_MACROS_BROKEN
     220  # undef PRIdLEAST16
     221  # define PRIdLEAST16 "d"
     222  #endif
     223  #if !defined PRIiLEAST16 || PRI_MACROS_BROKEN
     224  # undef PRIiLEAST16
     225  # define PRIiLEAST16 "i"
     226  #endif
     227  #if !defined PRIoLEAST16 || PRI_MACROS_BROKEN
     228  # undef PRIoLEAST16
     229  # define PRIoLEAST16 "o"
     230  #endif
     231  #if !defined PRIuLEAST16 || PRI_MACROS_BROKEN
     232  # undef PRIuLEAST16
     233  # define PRIuLEAST16 "u"
     234  #endif
     235  #if !defined PRIxLEAST16 || PRI_MACROS_BROKEN
     236  # undef PRIxLEAST16
     237  # define PRIxLEAST16 "x"
     238  #endif
     239  #if !defined PRIXLEAST16 || PRI_MACROS_BROKEN
     240  # undef PRIXLEAST16
     241  # define PRIXLEAST16 "X"
     242  #endif
     243  #if !defined PRIdLEAST32 || PRI_MACROS_BROKEN
     244  # undef PRIdLEAST32
     245  # define PRIdLEAST32 "d"
     246  #endif
     247  #if !defined PRIiLEAST32 || PRI_MACROS_BROKEN
     248  # undef PRIiLEAST32
     249  # define PRIiLEAST32 "i"
     250  #endif
     251  #if !defined PRIoLEAST32 || PRI_MACROS_BROKEN
     252  # undef PRIoLEAST32
     253  # define PRIoLEAST32 "o"
     254  #endif
     255  #if !defined PRIuLEAST32 || PRI_MACROS_BROKEN
     256  # undef PRIuLEAST32
     257  # define PRIuLEAST32 "u"
     258  #endif
     259  #if !defined PRIxLEAST32 || PRI_MACROS_BROKEN
     260  # undef PRIxLEAST32
     261  # define PRIxLEAST32 "x"
     262  #endif
     263  #if !defined PRIXLEAST32 || PRI_MACROS_BROKEN
     264  # undef PRIXLEAST32
     265  # define PRIXLEAST32 "X"
     266  #endif
     267  #if !defined PRIdLEAST64 || PRI_MACROS_BROKEN
     268  # undef PRIdLEAST64
     269  # define PRIdLEAST64 PRId64
     270  #endif
     271  #if !defined PRIiLEAST64 || PRI_MACROS_BROKEN
     272  # undef PRIiLEAST64
     273  # define PRIiLEAST64 PRIi64
     274  #endif
     275  #if !defined PRIoLEAST64 || PRI_MACROS_BROKEN
     276  # undef PRIoLEAST64
     277  # define PRIoLEAST64 PRIo64
     278  #endif
     279  #if !defined PRIuLEAST64 || PRI_MACROS_BROKEN
     280  # undef PRIuLEAST64
     281  # define PRIuLEAST64 PRIu64
     282  #endif
     283  #if !defined PRIxLEAST64 || PRI_MACROS_BROKEN
     284  # undef PRIxLEAST64
     285  # define PRIxLEAST64 PRIx64
     286  #endif
     287  #if !defined PRIXLEAST64 || PRI_MACROS_BROKEN
     288  # undef PRIXLEAST64
     289  # define PRIXLEAST64 PRIX64
     290  #endif
     291  #if !defined PRIdFAST8 || PRI_MACROS_BROKEN
     292  # undef PRIdFAST8
     293  # define PRIdFAST8 "d"
     294  #endif
     295  #if !defined PRIiFAST8 || PRI_MACROS_BROKEN
     296  # undef PRIiFAST8
     297  # define PRIiFAST8 "i"
     298  #endif
     299  #if !defined PRIoFAST8 || PRI_MACROS_BROKEN
     300  # undef PRIoFAST8
     301  # define PRIoFAST8 "o"
     302  #endif
     303  #if !defined PRIuFAST8 || PRI_MACROS_BROKEN
     304  # undef PRIuFAST8
     305  # define PRIuFAST8 "u"
     306  #endif
     307  #if !defined PRIxFAST8 || PRI_MACROS_BROKEN
     308  # undef PRIxFAST8
     309  # define PRIxFAST8 "x"
     310  #endif
     311  #if !defined PRIXFAST8 || PRI_MACROS_BROKEN
     312  # undef PRIXFAST8
     313  # define PRIXFAST8 "X"
     314  #endif
     315  #if !defined PRIdFAST16 || PRI_MACROS_BROKEN
     316  # undef PRIdFAST16
     317  # define PRIdFAST16 "d"
     318  #endif
     319  #if !defined PRIiFAST16 || PRI_MACROS_BROKEN
     320  # undef PRIiFAST16
     321  # define PRIiFAST16 "i"
     322  #endif
     323  #if !defined PRIoFAST16 || PRI_MACROS_BROKEN
     324  # undef PRIoFAST16
     325  # define PRIoFAST16 "o"
     326  #endif
     327  #if !defined PRIuFAST16 || PRI_MACROS_BROKEN
     328  # undef PRIuFAST16
     329  # define PRIuFAST16 "u"
     330  #endif
     331  #if !defined PRIxFAST16 || PRI_MACROS_BROKEN
     332  # undef PRIxFAST16
     333  # define PRIxFAST16 "x"
     334  #endif
     335  #if !defined PRIXFAST16 || PRI_MACROS_BROKEN
     336  # undef PRIXFAST16
     337  # define PRIXFAST16 "X"
     338  #endif
     339  #if !defined PRIdFAST32 || PRI_MACROS_BROKEN
     340  # undef PRIdFAST32
     341  # define PRIdFAST32 "d"
     342  #endif
     343  #if !defined PRIiFAST32 || PRI_MACROS_BROKEN
     344  # undef PRIiFAST32
     345  # define PRIiFAST32 "i"
     346  #endif
     347  #if !defined PRIoFAST32 || PRI_MACROS_BROKEN
     348  # undef PRIoFAST32
     349  # define PRIoFAST32 "o"
     350  #endif
     351  #if !defined PRIuFAST32 || PRI_MACROS_BROKEN
     352  # undef PRIuFAST32
     353  # define PRIuFAST32 "u"
     354  #endif
     355  #if !defined PRIxFAST32 || PRI_MACROS_BROKEN
     356  # undef PRIxFAST32
     357  # define PRIxFAST32 "x"
     358  #endif
     359  #if !defined PRIXFAST32 || PRI_MACROS_BROKEN
     360  # undef PRIXFAST32
     361  # define PRIXFAST32 "X"
     362  #endif
     363  #if !defined PRIdFAST64 || PRI_MACROS_BROKEN
     364  # undef PRIdFAST64
     365  # define PRIdFAST64 PRId64
     366  #endif
     367  #if !defined PRIiFAST64 || PRI_MACROS_BROKEN
     368  # undef PRIiFAST64
     369  # define PRIiFAST64 PRIi64
     370  #endif
     371  #if !defined PRIoFAST64 || PRI_MACROS_BROKEN
     372  # undef PRIoFAST64
     373  # define PRIoFAST64 PRIo64
     374  #endif
     375  #if !defined PRIuFAST64 || PRI_MACROS_BROKEN
     376  # undef PRIuFAST64
     377  # define PRIuFAST64 PRIu64
     378  #endif
     379  #if !defined PRIxFAST64 || PRI_MACROS_BROKEN
     380  # undef PRIxFAST64
     381  # define PRIxFAST64 PRIx64
     382  #endif
     383  #if !defined PRIXFAST64 || PRI_MACROS_BROKEN
     384  # undef PRIXFAST64
     385  # define PRIXFAST64 PRIX64
     386  #endif
     387  #if !defined PRIdMAX || PRI_MACROS_BROKEN
     388  # undef PRIdMAX
     389  # define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
     390  #endif
     391  #if !defined PRIiMAX || PRI_MACROS_BROKEN
     392  # undef PRIiMAX
     393  # define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
     394  #endif
     395  #if !defined PRIoMAX || PRI_MACROS_BROKEN
     396  # undef PRIoMAX
     397  # define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
     398  #endif
     399  #if !defined PRIuMAX || PRI_MACROS_BROKEN
     400  # undef PRIuMAX
     401  # define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
     402  #endif
     403  #if !defined PRIxMAX || PRI_MACROS_BROKEN
     404  # undef PRIxMAX
     405  # define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
     406  #endif
     407  #if !defined PRIXMAX || PRI_MACROS_BROKEN
     408  # undef PRIXMAX
     409  # define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
     410  #endif
     411  #if !defined PRIdPTR || PRI_MACROS_BROKEN
     412  # undef PRIdPTR
     413  # define PRIdPTR \
     414    (sizeof (void *) == sizeof (long) ? "ld" : \
     415     sizeof (void *) == sizeof (int) ? "d" : \
     416     "lld")
     417  #endif
     418  #if !defined PRIiPTR || PRI_MACROS_BROKEN
     419  # undef PRIiPTR
     420  # define PRIiPTR \
     421    (sizeof (void *) == sizeof (long) ? "li" : \
     422     sizeof (void *) == sizeof (int) ? "i" : \
     423     "lli")
     424  #endif
     425  #if !defined PRIoPTR || PRI_MACROS_BROKEN
     426  # undef PRIoPTR
     427  # define PRIoPTR \
     428    (sizeof (void *) == sizeof (long) ? "lo" : \
     429     sizeof (void *) == sizeof (int) ? "o" : \
     430     "llo")
     431  #endif
     432  #if !defined PRIuPTR || PRI_MACROS_BROKEN
     433  # undef PRIuPTR
     434  # define PRIuPTR \
     435    (sizeof (void *) == sizeof (long) ? "lu" : \
     436     sizeof (void *) == sizeof (int) ? "u" : \
     437     "llu")
     438  #endif
     439  #if !defined PRIxPTR || PRI_MACROS_BROKEN
     440  # undef PRIxPTR
     441  # define PRIxPTR \
     442    (sizeof (void *) == sizeof (long) ? "lx" : \
     443     sizeof (void *) == sizeof (int) ? "x" : \
     444     "llx")
     445  #endif
     446  #if !defined PRIXPTR || PRI_MACROS_BROKEN
     447  # undef PRIXPTR
     448  # define PRIXPTR \
     449    (sizeof (void *) == sizeof (long) ? "lX" : \
     450     sizeof (void *) == sizeof (int) ? "X" : \
     451     "llX")
     452  #endif
     453  
     454  /* @@ end of prolog @@ */
     455  
     456  #ifdef _LIBC
     457  /* Rename the non ISO C functions.  This is required by the standard
     458     because some ISO C functions will require linking with this object
     459     file and the name space must not be polluted.  */
     460  # define open   __open
     461  # define close  __close
     462  # define read   __read
     463  # define mmap   __mmap
     464  # define munmap __munmap
     465  #endif
     466  
     467  /* For those losing systems which don't have `alloca' we have to add
     468     some additional code emulating it.  */
     469  #ifdef HAVE_ALLOCA
     470  # define freea(p) /* nothing */
     471  #else
     472  # define alloca(n) malloc (n)
     473  # define freea(p) free (p)
     474  #endif
     475  
     476  /* For systems that distinguish between text and binary I/O.
     477     O_BINARY is usually declared in <fcntl.h>. */
     478  #if !defined O_BINARY && defined _O_BINARY
     479    /* For MSC-compatible compilers.  */
     480  # define O_BINARY _O_BINARY
     481  # define O_TEXT _O_TEXT
     482  #endif
     483  #ifdef __BEOS__
     484    /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect.  */
     485  # undef O_BINARY
     486  # undef O_TEXT
     487  #endif
     488  /* On reasonable systems, binary I/O is the default.  */
     489  #ifndef O_BINARY
     490  # define O_BINARY 0
     491  #endif
     492  
     493  
     494  /* Prototypes for local functions.  Needed to ensure compiler checking of
     495     function argument counts despite of K&R C function definition syntax.  */
     496  static const char *get_sysdep_segment_value PARAMS ((const char *name));
     497  
     498  
     499  /* We need a sign, whether a new catalog was loaded, which can be associated
     500     with all translations.  This is important if the translations are
     501     cached by one of GCC's features.  */
     502  int _nl_msg_cat_cntr;
     503  
     504  
     505  /* Expand a system dependent string segment.  Return NULL if unsupported.  */
     506  static const char *
     507  get_sysdep_segment_value (name)
     508       const char *name;
     509  {
     510    /* Test for an ISO C 99 section 7.8.1 format string directive.
     511       Syntax:
     512       P R I { d | i | o | u | x | X }
     513       { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR }  */
     514    /* We don't use a table of 14 times 6 'const char *' strings here, because
     515       data relocations cost startup time.  */
     516    if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
     517      {
     518        if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
     519  	  || name[3] == 'x' || name[3] == 'X')
     520  	{
     521  	  if (name[4] == '8' && name[5] == '\0')
     522  	    {
     523  	      if (name[3] == 'd')
     524  		return PRId8;
     525  	      if (name[3] == 'i')
     526  		return PRIi8;
     527  	      if (name[3] == 'o')
     528  		return PRIo8;
     529  	      if (name[3] == 'u')
     530  		return PRIu8;
     531  	      if (name[3] == 'x')
     532  		return PRIx8;
     533  	      if (name[3] == 'X')
     534  		return PRIX8;
     535  	      abort ();
     536  	    }
     537  	  if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
     538  	    {
     539  	      if (name[3] == 'd')
     540  		return PRId16;
     541  	      if (name[3] == 'i')
     542  		return PRIi16;
     543  	      if (name[3] == 'o')
     544  		return PRIo16;
     545  	      if (name[3] == 'u')
     546  		return PRIu16;
     547  	      if (name[3] == 'x')
     548  		return PRIx16;
     549  	      if (name[3] == 'X')
     550  		return PRIX16;
     551  	      abort ();
     552  	    }
     553  	  if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
     554  	    {
     555  	      if (name[3] == 'd')
     556  		return PRId32;
     557  	      if (name[3] == 'i')
     558  		return PRIi32;
     559  	      if (name[3] == 'o')
     560  		return PRIo32;
     561  	      if (name[3] == 'u')
     562  		return PRIu32;
     563  	      if (name[3] == 'x')
     564  		return PRIx32;
     565  	      if (name[3] == 'X')
     566  		return PRIX32;
     567  	      abort ();
     568  	    }
     569  	  if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
     570  	    {
     571  	      if (name[3] == 'd')
     572  		return PRId64;
     573  	      if (name[3] == 'i')
     574  		return PRIi64;
     575  	      if (name[3] == 'o')
     576  		return PRIo64;
     577  	      if (name[3] == 'u')
     578  		return PRIu64;
     579  	      if (name[3] == 'x')
     580  		return PRIx64;
     581  	      if (name[3] == 'X')
     582  		return PRIX64;
     583  	      abort ();
     584  	    }
     585  	  if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
     586  	      && name[7] == 'S' && name[8] == 'T')
     587  	    {
     588  	      if (name[9] == '8' && name[10] == '\0')
     589  		{
     590  		  if (name[3] == 'd')
     591  		    return PRIdLEAST8;
     592  		  if (name[3] == 'i')
     593  		    return PRIiLEAST8;
     594  		  if (name[3] == 'o')
     595  		    return PRIoLEAST8;
     596  		  if (name[3] == 'u')
     597  		    return PRIuLEAST8;
     598  		  if (name[3] == 'x')
     599  		    return PRIxLEAST8;
     600  		  if (name[3] == 'X')
     601  		    return PRIXLEAST8;
     602  		  abort ();
     603  		}
     604  	      if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
     605  		{
     606  		  if (name[3] == 'd')
     607  		    return PRIdLEAST16;
     608  		  if (name[3] == 'i')
     609  		    return PRIiLEAST16;
     610  		  if (name[3] == 'o')
     611  		    return PRIoLEAST16;
     612  		  if (name[3] == 'u')
     613  		    return PRIuLEAST16;
     614  		  if (name[3] == 'x')
     615  		    return PRIxLEAST16;
     616  		  if (name[3] == 'X')
     617  		    return PRIXLEAST16;
     618  		  abort ();
     619  		}
     620  	      if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
     621  		{
     622  		  if (name[3] == 'd')
     623  		    return PRIdLEAST32;
     624  		  if (name[3] == 'i')
     625  		    return PRIiLEAST32;
     626  		  if (name[3] == 'o')
     627  		    return PRIoLEAST32;
     628  		  if (name[3] == 'u')
     629  		    return PRIuLEAST32;
     630  		  if (name[3] == 'x')
     631  		    return PRIxLEAST32;
     632  		  if (name[3] == 'X')
     633  		    return PRIXLEAST32;
     634  		  abort ();
     635  		}
     636  	      if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
     637  		{
     638  		  if (name[3] == 'd')
     639  		    return PRIdLEAST64;
     640  		  if (name[3] == 'i')
     641  		    return PRIiLEAST64;
     642  		  if (name[3] == 'o')
     643  		    return PRIoLEAST64;
     644  		  if (name[3] == 'u')
     645  		    return PRIuLEAST64;
     646  		  if (name[3] == 'x')
     647  		    return PRIxLEAST64;
     648  		  if (name[3] == 'X')
     649  		    return PRIXLEAST64;
     650  		  abort ();
     651  		}
     652  	    }
     653  	  if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
     654  	      && name[7] == 'T')
     655  	    {
     656  	      if (name[8] == '8' && name[9] == '\0')
     657  		{
     658  		  if (name[3] == 'd')
     659  		    return PRIdFAST8;
     660  		  if (name[3] == 'i')
     661  		    return PRIiFAST8;
     662  		  if (name[3] == 'o')
     663  		    return PRIoFAST8;
     664  		  if (name[3] == 'u')
     665  		    return PRIuFAST8;
     666  		  if (name[3] == 'x')
     667  		    return PRIxFAST8;
     668  		  if (name[3] == 'X')
     669  		    return PRIXFAST8;
     670  		  abort ();
     671  		}
     672  	      if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
     673  		{
     674  		  if (name[3] == 'd')
     675  		    return PRIdFAST16;
     676  		  if (name[3] == 'i')
     677  		    return PRIiFAST16;
     678  		  if (name[3] == 'o')
     679  		    return PRIoFAST16;
     680  		  if (name[3] == 'u')
     681  		    return PRIuFAST16;
     682  		  if (name[3] == 'x')
     683  		    return PRIxFAST16;
     684  		  if (name[3] == 'X')
     685  		    return PRIXFAST16;
     686  		  abort ();
     687  		}
     688  	      if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
     689  		{
     690  		  if (name[3] == 'd')
     691  		    return PRIdFAST32;
     692  		  if (name[3] == 'i')
     693  		    return PRIiFAST32;
     694  		  if (name[3] == 'o')
     695  		    return PRIoFAST32;
     696  		  if (name[3] == 'u')
     697  		    return PRIuFAST32;
     698  		  if (name[3] == 'x')
     699  		    return PRIxFAST32;
     700  		  if (name[3] == 'X')
     701  		    return PRIXFAST32;
     702  		  abort ();
     703  		}
     704  	      if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
     705  		{
     706  		  if (name[3] == 'd')
     707  		    return PRIdFAST64;
     708  		  if (name[3] == 'i')
     709  		    return PRIiFAST64;
     710  		  if (name[3] == 'o')
     711  		    return PRIoFAST64;
     712  		  if (name[3] == 'u')
     713  		    return PRIuFAST64;
     714  		  if (name[3] == 'x')
     715  		    return PRIxFAST64;
     716  		  if (name[3] == 'X')
     717  		    return PRIXFAST64;
     718  		  abort ();
     719  		}
     720  	    }
     721  	  if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
     722  	      && name[7] == '\0')
     723  	    {
     724  	      if (name[3] == 'd')
     725  		return PRIdMAX;
     726  	      if (name[3] == 'i')
     727  		return PRIiMAX;
     728  	      if (name[3] == 'o')
     729  		return PRIoMAX;
     730  	      if (name[3] == 'u')
     731  		return PRIuMAX;
     732  	      if (name[3] == 'x')
     733  		return PRIxMAX;
     734  	      if (name[3] == 'X')
     735  		return PRIXMAX;
     736  	      abort ();
     737  	    }
     738  	  if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
     739  	      && name[7] == '\0')
     740  	    {
     741  	      if (name[3] == 'd')
     742  		return PRIdPTR;
     743  	      if (name[3] == 'i')
     744  		return PRIiPTR;
     745  	      if (name[3] == 'o')
     746  		return PRIoPTR;
     747  	      if (name[3] == 'u')
     748  		return PRIuPTR;
     749  	      if (name[3] == 'x')
     750  		return PRIxPTR;
     751  	      if (name[3] == 'X')
     752  		return PRIXPTR;
     753  	      abort ();
     754  	    }
     755  	}
     756      }
     757    /* Other system dependent strings are not valid.  */
     758    return NULL;
     759  }
     760  
     761  /* Initialize the codeset dependent parts of an opened message catalog.
     762     Return the header entry.  */
     763  const char *
     764  internal_function
     765  _nl_init_domain_conv (domain_file, domain, domainbinding)
     766       struct loaded_l10nfile *domain_file;
     767       struct loaded_domain *domain;
     768       struct binding *domainbinding;
     769  {
     770    /* Find out about the character set the file is encoded with.
     771       This can be found (in textual form) in the entry "".  If this
     772       entry does not exist or if this does not contain the `charset='
     773       information, we will assume the charset matches the one the
     774       current locale and we don't have to perform any conversion.  */
     775    char *nullentry;
     776    size_t nullentrylen;
     777  
     778    /* Preinitialize fields, to avoid recursion during _nl_find_msg.  */
     779    domain->codeset_cntr =
     780      (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
     781  #ifdef _LIBC
     782    domain->conv = (__gconv_t) -1;
     783  #else
     784  # if HAVE_ICONV
     785    domain->conv = (iconv_t) -1;
     786  # endif
     787  #endif
     788    domain->conv_tab = NULL;
     789  
     790    /* Get the header entry.  */
     791    nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);
     792  
     793    if (nullentry != NULL)
     794      {
     795  #if defined _LIBC || HAVE_ICONV
     796        const char *charsetstr;
     797  
     798        charsetstr = strstr (nullentry, "charset=");
     799        if (charsetstr != NULL)
     800  	{
     801  	  size_t len;
     802  	  char *charset;
     803  	  const char *outcharset;
     804  
     805  	  charsetstr += strlen ("charset=");
     806  	  len = strcspn (charsetstr, " \t\n");
     807  
     808  	  charset = (char *) alloca (len + 1);
     809  # if defined _LIBC || HAVE_MEMPCPY
     810  	  *((char *) mempcpy (charset, charsetstr, len)) = '\0';
     811  # else
     812  	  memcpy (charset, charsetstr, len);
     813  	  charset[len] = '\0';
     814  # endif
     815  
     816  	  /* The output charset should normally be determined by the
     817  	     locale.  But sometimes the locale is not used or not correctly
     818  	     set up, so we provide a possibility for the user to override
     819  	     this.  Moreover, the value specified through
     820  	     bind_textdomain_codeset overrides both.  */
     821  	  if (domainbinding != NULL && domainbinding->codeset != NULL)
     822  	    outcharset = domainbinding->codeset;
     823  	  else
     824  	    {
     825  	      outcharset = getenv ("OUTPUT_CHARSET");
     826  	      if (outcharset == NULL || outcharset[0] == '\0')
     827  		{
     828  # ifdef _LIBC
     829  		  outcharset = _NL_CURRENT (LC_CTYPE, CODESET);
     830  # else
     831  #  if HAVE_ICONV
     832  		  extern const char *locale_charset PARAMS ((void));
     833  		  outcharset = locale_charset ();
     834  #  endif
     835  # endif
     836  		}
     837  	    }
     838  
     839  # ifdef _LIBC
     840  	  /* We always want to use transliteration.  */
     841  	  outcharset = norm_add_slashes (outcharset, "TRANSLIT");
     842  	  charset = norm_add_slashes (charset, NULL);
     843  	  if (__gconv_open (outcharset, charset, &domain->conv,
     844  			    GCONV_AVOID_NOCONV)
     845  	      != __GCONV_OK)
     846  	    domain->conv = (__gconv_t) -1;
     847  # else
     848  #  if HAVE_ICONV
     849  	  /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
     850  	     we want to use transliteration.  */
     851  #   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
     852         || _LIBICONV_VERSION >= 0x0105
     853  	  if (strchr (outcharset, '/') == NULL)
     854  	    {
     855  	      char *tmp;
     856  
     857  	      len = strlen (outcharset);
     858  	      tmp = (char *) alloca (len + 10 + 1);
     859  	      memcpy (tmp, outcharset, len);
     860  	      memcpy (tmp + len, "//TRANSLIT", 10 + 1);
     861  	      outcharset = tmp;
     862  
     863  	      domain->conv = iconv_open (outcharset, charset);
     864  
     865  	      freea (outcharset);
     866  	    }
     867  	  else
     868  #   endif
     869  	    domain->conv = iconv_open (outcharset, charset);
     870  #  endif
     871  # endif
     872  
     873  	  freea (charset);
     874  	}
     875  #endif /* _LIBC || HAVE_ICONV */
     876      }
     877  
     878    return nullentry;
     879  }
     880  
     881  /* Frees the codeset dependent parts of an opened message catalog.  */
     882  void
     883  internal_function
     884  _nl_free_domain_conv (domain)
     885       struct loaded_domain *domain;
     886  {
     887    if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
     888      free (domain->conv_tab);
     889  
     890  #ifdef _LIBC
     891    if (domain->conv != (__gconv_t) -1)
     892      __gconv_close (domain->conv);
     893  #else
     894  # if HAVE_ICONV
     895    if (domain->conv != (iconv_t) -1)
     896      iconv_close (domain->conv);
     897  # endif
     898  #endif
     899  }
     900  
     901  /* Load the message catalogs specified by FILENAME.  If it is no valid
     902     message catalog do nothing.  */
     903  void
     904  internal_function
     905  _nl_load_domain (domain_file, domainbinding)
     906       struct loaded_l10nfile *domain_file;
     907       struct binding *domainbinding;
     908  {
     909    int fd;
     910    size_t size;
     911  #ifdef _LIBC
     912    struct stat64 st;
     913  #else
     914    struct stat st;
     915  #endif
     916    struct mo_file_header *data = (struct mo_file_header *) -1;
     917    int use_mmap = 0;
     918    struct loaded_domain *domain;
     919    int revision;
     920    const char *nullentry;
     921  
     922    domain_file->decided = 1;
     923    domain_file->data = NULL;
     924  
     925    /* Note that it would be useless to store domainbinding in domain_file
     926       because domainbinding might be == NULL now but != NULL later (after
     927       a call to bind_textdomain_codeset).  */
     928  
     929    /* If the record does not represent a valid locale the FILENAME
     930       might be NULL.  This can happen when according to the given
     931       specification the locale file name is different for XPG and CEN
     932       syntax.  */
     933    if (domain_file->filename == NULL)
     934      return;
     935  
     936    /* Try to open the addressed file.  */
     937    fd = open (domain_file->filename, O_RDONLY | O_BINARY);
     938    if (fd == -1)
     939      return;
     940  
     941    /* We must know about the size of the file.  */
     942    if (
     943  #ifdef _LIBC
     944        __builtin_expect (fstat64 (fd, &st) != 0, 0)
     945  #else
     946        __builtin_expect (fstat (fd, &st) != 0, 0)
     947  #endif
     948        || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
     949        || __builtin_expect (size < sizeof (struct mo_file_header), 0))
     950      {
     951        /* Something went wrong.  */
     952        close (fd);
     953        return;
     954      }
     955  
     956  #ifdef HAVE_MMAP
     957    /* Now we are ready to load the file.  If mmap() is available we try
     958       this first.  If not available or it failed we try to load it.  */
     959    data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
     960  					 MAP_PRIVATE, fd, 0);
     961  
     962    if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
     963      {
     964        /* mmap() call was successful.  */
     965        close (fd);
     966        use_mmap = 1;
     967      }
     968  #endif
     969  
     970    /* If the data is not yet available (i.e. mmap'ed) we try to load
     971       it manually.  */
     972    if (data == (struct mo_file_header *) -1)
     973      {
     974        size_t to_read;
     975        char *read_ptr;
     976  
     977        data = (struct mo_file_header *) malloc (size);
     978        if (data == NULL)
     979  	return;
     980  
     981        to_read = size;
     982        read_ptr = (char *) data;
     983        do
     984  	{
     985  	  long int nb = (long int) read (fd, read_ptr, to_read);
     986  	  if (nb <= 0)
     987  	    {
     988  #ifdef EINTR
     989  	      if (nb == -1 && errno == EINTR)
     990  		continue;
     991  #endif
     992  	      close (fd);
     993  	      return;
     994  	    }
     995  	  read_ptr += nb;
     996  	  to_read -= nb;
     997  	}
     998        while (to_read > 0);
     999  
    1000        close (fd);
    1001      }
    1002  
    1003    /* Using the magic number we can test whether it really is a message
    1004       catalog file.  */
    1005    if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
    1006  			0))
    1007      {
    1008        /* The magic number is wrong: not a message catalog file.  */
    1009  #ifdef HAVE_MMAP
    1010        if (use_mmap)
    1011  	munmap ((caddr_t) data, size);
    1012        else
    1013  #endif
    1014  	free (data);
    1015        return;
    1016      }
    1017  
    1018    domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
    1019    if (domain == NULL)
    1020      return;
    1021    domain_file->data = domain;
    1022  
    1023    domain->data = (char *) data;
    1024    domain->use_mmap = use_mmap;
    1025    domain->mmap_size = size;
    1026    domain->must_swap = data->magic != _MAGIC;
    1027    domain->malloced = NULL;
    1028  
    1029    /* Fill in the information about the available tables.  */
    1030    revision = W (domain->must_swap, data->revision);
    1031    /* We support only the major revision 0.  */
    1032    switch (revision >> 16)
    1033      {
    1034      case 0:
    1035        domain->nstrings = W (domain->must_swap, data->nstrings);
    1036        domain->orig_tab = (const struct string_desc *)
    1037  	((char *) data + W (domain->must_swap, data->orig_tab_offset));
    1038        domain->trans_tab = (const struct string_desc *)
    1039  	((char *) data + W (domain->must_swap, data->trans_tab_offset));
    1040        domain->hash_size = W (domain->must_swap, data->hash_tab_size);
    1041        domain->hash_tab =
    1042  	(domain->hash_size > 2
    1043  	 ? (const nls_uint32 *)
    1044  	   ((char *) data + W (domain->must_swap, data->hash_tab_offset))
    1045  	 : NULL);
    1046        domain->must_swap_hash_tab = domain->must_swap;
    1047  
    1048        /* Now dispatch on the minor revision.  */
    1049        switch (revision & 0xffff)
    1050  	{
    1051  	case 0:
    1052  	  domain->n_sysdep_strings = 0;
    1053  	  domain->orig_sysdep_tab = NULL;
    1054  	  domain->trans_sysdep_tab = NULL;
    1055  	  break;
    1056  	case 1:
    1057  	default:
    1058  	  {
    1059  	    nls_uint32 n_sysdep_strings;
    1060  
    1061  	    if (domain->hash_tab == NULL)
    1062  	      /* This is invalid.  These minor revisions need a hash table.  */
    1063  	      goto invalid;
    1064  
    1065  	    n_sysdep_strings =
    1066  	      W (domain->must_swap, data->n_sysdep_strings);
    1067  	    if (n_sysdep_strings > 0)
    1068  	      {
    1069  		nls_uint32 n_sysdep_segments;
    1070  		const struct sysdep_segment *sysdep_segments;
    1071  		const char **sysdep_segment_values;
    1072  		const nls_uint32 *orig_sysdep_tab;
    1073  		const nls_uint32 *trans_sysdep_tab;
    1074  		size_t memneed;
    1075  		char *mem;
    1076  		struct sysdep_string_desc *inmem_orig_sysdep_tab;
    1077  		struct sysdep_string_desc *inmem_trans_sysdep_tab;
    1078  		nls_uint32 *inmem_hash_tab;
    1079  		unsigned int i;
    1080  
    1081  		/* Get the values of the system dependent segments.  */
    1082  		n_sysdep_segments =
    1083  		  W (domain->must_swap, data->n_sysdep_segments);
    1084  		sysdep_segments = (const struct sysdep_segment *)
    1085  		  ((char *) data
    1086  		   + W (domain->must_swap, data->sysdep_segments_offset));
    1087  		sysdep_segment_values =
    1088  		  alloca (n_sysdep_segments * sizeof (const char *));
    1089  		for (i = 0; i < n_sysdep_segments; i++)
    1090  		  {
    1091  		    const char *name =
    1092  		      (char *) data
    1093  		      + W (domain->must_swap, sysdep_segments[i].offset);
    1094  		    nls_uint32 namelen =
    1095  		      W (domain->must_swap, sysdep_segments[i].length);
    1096  
    1097  		    if (!(namelen > 0 && name[namelen - 1] == '\0'))
    1098  		      {
    1099  			freea (sysdep_segment_values);
    1100  			goto invalid;
    1101  		      }
    1102  
    1103  		    sysdep_segment_values[i] = get_sysdep_segment_value (name);
    1104  		  }
    1105  
    1106  		orig_sysdep_tab = (const nls_uint32 *)
    1107  		  ((char *) data
    1108  		   + W (domain->must_swap, data->orig_sysdep_tab_offset));
    1109  		trans_sysdep_tab = (const nls_uint32 *)
    1110  		  ((char *) data
    1111  		   + W (domain->must_swap, data->trans_sysdep_tab_offset));
    1112  
    1113  		/* Compute the amount of additional memory needed for the
    1114  		   system dependent strings and the augmented hash table.  */
    1115  		memneed = 2 * n_sysdep_strings
    1116  			  * sizeof (struct sysdep_string_desc)
    1117  			  + domain->hash_size * sizeof (nls_uint32);
    1118  		for (i = 0; i < 2 * n_sysdep_strings; i++)
    1119  		  {
    1120  		    const struct sysdep_string *sysdep_string =
    1121  		      (const struct sysdep_string *)
    1122  		      ((char *) data
    1123  		       + W (domain->must_swap,
    1124  			    i < n_sysdep_strings
    1125  			    ? orig_sysdep_tab[i]
    1126  			    : trans_sysdep_tab[i - n_sysdep_strings]));
    1127  		    size_t need = 0;
    1128  		    const struct segment_pair *p = sysdep_string->segments;
    1129  
    1130  		    if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
    1131  		      for (p = sysdep_string->segments;; p++)
    1132  			{
    1133  			  nls_uint32 sysdepref;
    1134  
    1135  			  need += W (domain->must_swap, p->segsize);
    1136  
    1137  			  sysdepref = W (domain->must_swap, p->sysdepref);
    1138  			  if (sysdepref == SEGMENTS_END)
    1139  			    break;
    1140  
    1141  			  if (sysdepref >= n_sysdep_segments)
    1142  			    {
    1143  			      /* Invalid.  */
    1144  			      freea (sysdep_segment_values);
    1145  			      goto invalid;
    1146  			    }
    1147  
    1148  			  need += strlen (sysdep_segment_values[sysdepref]);
    1149  			}
    1150  
    1151  		    memneed += need;
    1152  		  }
    1153  
    1154  		/* Allocate additional memory.  */
    1155  		mem = (char *) malloc (memneed);
    1156  		if (mem == NULL)
    1157  		  goto invalid;
    1158  
    1159  		domain->malloced = mem;
    1160  		inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
    1161  		mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
    1162  		inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
    1163  		mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
    1164  		inmem_hash_tab = (nls_uint32 *) mem;
    1165  		mem += domain->hash_size * sizeof (nls_uint32);
    1166  
    1167  		/* Compute the system dependent strings.  */
    1168  		for (i = 0; i < 2 * n_sysdep_strings; i++)
    1169  		  {
    1170  		    const struct sysdep_string *sysdep_string =
    1171  		      (const struct sysdep_string *)
    1172  		      ((char *) data
    1173  		       + W (domain->must_swap,
    1174  			    i < n_sysdep_strings
    1175  			    ? orig_sysdep_tab[i]
    1176  			    : trans_sysdep_tab[i - n_sysdep_strings]));
    1177  		    const char *static_segments =
    1178  		      (char *) data
    1179  		      + W (domain->must_swap, sysdep_string->offset);
    1180  		    const struct segment_pair *p = sysdep_string->segments;
    1181  
    1182  		    /* Concatenate the segments, and fill
    1183  		       inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and
    1184  		       inmem_trans_sysdep_tab[i-n_sysdep_strings] (for
    1185  		       i >= n_sysdep_strings).  */
    1186  
    1187  		    if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END)
    1188  		      {
    1189  			/* Only one static segment.  */
    1190  			inmem_orig_sysdep_tab[i].length =
    1191  			  W (domain->must_swap, p->segsize);
    1192  			inmem_orig_sysdep_tab[i].pointer = static_segments;
    1193  		      }
    1194  		    else
    1195  		      {
    1196  			inmem_orig_sysdep_tab[i].pointer = mem;
    1197  
    1198  			for (p = sysdep_string->segments;; p++)
    1199  			  {
    1200  			    nls_uint32 segsize =
    1201  			      W (domain->must_swap, p->segsize);
    1202  			    nls_uint32 sysdepref =
    1203  			      W (domain->must_swap, p->sysdepref);
    1204  			    size_t n;
    1205  
    1206  			    if (segsize > 0)
    1207  			      {
    1208  				memcpy (mem, static_segments, segsize);
    1209  				mem += segsize;
    1210  				static_segments += segsize;
    1211  			      }
    1212  
    1213  			    if (sysdepref == SEGMENTS_END)
    1214  			      break;
    1215  
    1216  			    n = strlen (sysdep_segment_values[sysdepref]);
    1217  			    memcpy (mem, sysdep_segment_values[sysdepref], n);
    1218  			    mem += n;
    1219  			  }
    1220  
    1221  			inmem_orig_sysdep_tab[i].length =
    1222  			  mem - inmem_orig_sysdep_tab[i].pointer;
    1223  		      }
    1224  		  }
    1225  
    1226  		/* Compute the augmented hash table.  */
    1227  		for (i = 0; i < domain->hash_size; i++)
    1228  		  inmem_hash_tab[i] =
    1229  		    W (domain->must_swap_hash_tab, domain->hash_tab[i]);
    1230  		for (i = 0; i < n_sysdep_strings; i++)
    1231  		  {
    1232  		    const char *msgid = inmem_orig_sysdep_tab[i].pointer;
    1233  		    nls_uint32 hash_val = hash_string (msgid);
    1234  		    nls_uint32 idx = hash_val % domain->hash_size;
    1235  		    nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
    1236  
    1237  		    for (;;)
    1238  		      {
    1239  			if (inmem_hash_tab[idx] == 0)
    1240  			  {
    1241  			    /* Hash table entry is empty.  Use it.  */
    1242  			    inmem_hash_tab[idx] = 1 + domain->nstrings + i;
    1243  			    break;
    1244  			  }
    1245  
    1246  			if (idx >= domain->hash_size - incr)
    1247  			  idx -= domain->hash_size - incr;
    1248  			else
    1249  			  idx += incr;
    1250  		      }
    1251  		  }
    1252  
    1253  		freea (sysdep_segment_values);
    1254  
    1255  		domain->n_sysdep_strings = n_sysdep_strings;
    1256  		domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
    1257  		domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
    1258  
    1259  		domain->hash_tab = inmem_hash_tab;
    1260  		domain->must_swap_hash_tab = 0;
    1261  	      }
    1262  	    else
    1263  	      {
    1264  		domain->n_sysdep_strings = 0;
    1265  		domain->orig_sysdep_tab = NULL;
    1266  		domain->trans_sysdep_tab = NULL;
    1267  	      }
    1268  	  }
    1269  	  break;
    1270  	}
    1271        break;
    1272      default:
    1273        /* This is an invalid revision.  */
    1274      invalid:
    1275        /* This is an invalid .mo file.  */
    1276        if (domain->malloced)
    1277  	free (domain->malloced);
    1278  #ifdef HAVE_MMAP
    1279        if (use_mmap)
    1280  	munmap ((caddr_t) data, size);
    1281        else
    1282  #endif
    1283  	free (data);
    1284        free (domain);
    1285        domain_file->data = NULL;
    1286        return;
    1287      }
    1288  
    1289    /* Now initialize the character set converter from the character set
    1290       the file is encoded with (found in the header entry) to the domain's
    1291       specified character set or the locale's character set.  */
    1292    nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);
    1293  
    1294    /* Also look for a plural specification.  */
    1295    EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
    1296  }
    1297  
    1298  
    1299  #ifdef _LIBC
    1300  void
    1301  internal_function
    1302  _nl_unload_domain (domain)
    1303       struct loaded_domain *domain;
    1304  {
    1305    if (domain->plural != &__gettext_germanic_plural)
    1306      __gettext_free_exp (domain->plural);
    1307  
    1308    _nl_free_domain_conv (domain);
    1309  
    1310    if (domain->malloced)
    1311      free (domain->malloced);
    1312  
    1313  # ifdef _POSIX_MAPPED_FILES
    1314    if (domain->use_mmap)
    1315      munmap ((caddr_t) domain->data, domain->mmap_size);
    1316    else
    1317  # endif	/* _POSIX_MAPPED_FILES */
    1318      free ((void *) domain->data);
    1319  
    1320    free (domain);
    1321  }
    1322  #endif