~ldgoodridge95/ubuntu/vivid/upstart/rm-libjson0-dev

« back to all changes in this revision

Viewing changes to intl/loadmsgcat.c

Tags: upstream-1.7
ImportĀ upstreamĀ versionĀ 1.7

Show diffs side-by-side

added added

removed removed

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