~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/intl/loadmsgcat.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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