~ubuntu-branches/ubuntu/raring/workrave/raring

1 by Michael Piefel
Import upstream version 1.6.2
1
/* Load needed message catalogs.
1.2.5 by Francois Marier
Import upstream version 1.9.0
2
   Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
1 by Michael Piefel
Import upstream version 1.6.2
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
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1 by Michael Piefel
Import upstream version 1.6.2
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__
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
37
# undef  alloca
1 by Michael Piefel
Import upstream version 1.6.2
38
# define alloca __builtin_alloca
39
# define HAVE_ALLOCA 1
40
#else
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
41
# ifdef _MSC_VER
42
#  include <malloc.h>
43
#  define alloca _alloca
1 by Michael Piefel
Import upstream version 1.6.2
44
# else
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
45
#  if defined HAVE_ALLOCA_H || defined _LIBC
46
#   include <alloca.h>
47
#  else
48
#   ifdef _AIX
1 by Michael Piefel
Import upstream version 1.6.2
49
 #pragma alloca
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
50
#   else
51
#    ifndef alloca
1 by Michael Piefel
Import upstream version 1.6.2
52
char *alloca ();
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
53
#    endif
1 by Michael Piefel
Import upstream version 1.6.2
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"
1.2.5 by Francois Marier
Import upstream version 1.9.0
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"
1 by Michael Piefel
Import upstream version 1.6.2
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.  */
1.2.5 by Francois Marier
Import upstream version 1.9.0
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)
1 by Michael Piefel
Import upstream version 1.6.2
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 *
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
511
get_sysdep_segment_value (const char *name)
1 by Michael Piefel
Import upstream version 1.6.2
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
    }
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
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
    }
1 by Michael Piefel
Import upstream version 1.6.2
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
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
780
_nl_load_domain (struct loaded_l10nfile *domain_file,
781
		 struct binding *domainbinding)
1 by Michael Piefel
Import upstream version 1.6.2
782
{
1.2.5 by Francois Marier
Import upstream version 1.9.0
783
  __libc_lock_define_initialized_recursive (static, lock)
784
  int fd = -1;
1 by Michael Piefel
Import upstream version 1.6.2
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;
1.2.5 by Francois Marier
Import upstream version 1.9.0
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;
1 by Michael Piefel
Import upstream version 1.6.2
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)
1.2.5 by Francois Marier
Import upstream version 1.9.0
825
    goto out;
1 by Michael Piefel
Import upstream version 1.6.2
826
827
  /* Try to open the addressed file.  */
828
  fd = open (domain_file->filename, O_RDONLY | O_BINARY);
829
  if (fd == -1)
1.2.5 by Francois Marier
Import upstream version 1.9.0
830
    goto out;
1 by Michael Piefel
Import upstream version 1.6.2
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))
1.2.5 by Francois Marier
Import upstream version 1.9.0
841
    /* Something went wrong.  */
842
    goto out;
1 by Michael Piefel
Import upstream version 1.6.2
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);
1.2.5 by Francois Marier
Import upstream version 1.9.0
854
      fd = -1;
1 by Michael Piefel
Import upstream version 1.6.2
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)
1.2.5 by Francois Marier
Import upstream version 1.9.0
868
	goto out;
1 by Michael Piefel
Import upstream version 1.6.2
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
1.2.5 by Francois Marier
Import upstream version 1.9.0
881
	      goto out;
1 by Michael Piefel
Import upstream version 1.6.2
882
	    }
883
	  read_ptr += nb;
884
	  to_read -= nb;
885
	}
886
      while (to_read > 0);
887
888
      close (fd);
1.2.5 by Francois Marier
Import upstream version 1.9.0
889
      fd = -1;
1 by Michael Piefel
Import upstream version 1.6.2
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);
1.2.5 by Francois Marier
Import upstream version 1.9.0
904
      goto out;
1 by Michael Piefel
Import upstream version 1.6.2
905
    }
906
907
  domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
908
  if (domain == NULL)
1.2.5 by Francois Marier
Import upstream version 1.9.0
909
    goto out;
1 by Michael Piefel
Import upstream version 1.6.2
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);
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
920
  /* We support only the major revisions 0 and 1.  */
1 by Michael Piefel
Import upstream version 1.6.2
921
  switch (revision >> 16)
922
    {
923
    case 0:
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
924
    case 1:
1 by Michael Piefel
Import upstream version 1.6.2
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;
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
964
		nls_uint32 n_inmem_sysdep_strings;
1 by Michael Piefel
Import upstream version 1.6.2
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;
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
970
		unsigned int i, j;
1 by Michael Piefel
Import upstream version 1.6.2
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
		  alloca (n_sysdep_segments * sizeof (const char *));
980
		for (i = 0; i < n_sysdep_segments; i++)
981
		  {
982
		    const char *name =
983
		      (char *) data
984
		      + W (domain->must_swap, sysdep_segments[i].offset);
985
		    nls_uint32 namelen =
986
		      W (domain->must_swap, sysdep_segments[i].length);
987
988
		    if (!(namelen > 0 && name[namelen - 1] == '\0'))
989
		      {
990
			freea (sysdep_segment_values);
991
			goto invalid;
992
		      }
993
994
		    sysdep_segment_values[i] = get_sysdep_segment_value (name);
995
		  }
996
997
		orig_sysdep_tab = (const nls_uint32 *)
998
		  ((char *) data
999
		   + W (domain->must_swap, data->orig_sysdep_tab_offset));
1000
		trans_sysdep_tab = (const nls_uint32 *)
1001
		  ((char *) data
1002
		   + W (domain->must_swap, data->trans_sysdep_tab_offset));
1003
1004
		/* Compute the amount of additional memory needed for the
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1005
		   system dependent strings and the augmented hash table.
1006
		   At the same time, also drop string pairs which refer to
1007
		   an undefined system dependent segment.  */
1008
		n_inmem_sysdep_strings = 0;
1009
		memneed = domain->hash_size * sizeof (nls_uint32);
1010
		for (i = 0; i < n_sysdep_strings; i++)
1 by Michael Piefel
Import upstream version 1.6.2
1011
		  {
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1012
		    int valid = 1;
1013
		    size_t needs[2];
1014
1015
		    for (j = 0; j < 2; j++)
1016
		      {
1017
			const struct sysdep_string *sysdep_string =
1018
			  (const struct sysdep_string *)
1019
			  ((char *) data
1020
			   + W (domain->must_swap,
1021
				j == 0
1022
				? orig_sysdep_tab[i]
1023
				: trans_sysdep_tab[i]));
1024
			size_t need = 0;
1025
			const struct segment_pair *p = sysdep_string->segments;
1026
1027
			if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
1028
			  for (p = sysdep_string->segments;; p++)
1 by Michael Piefel
Import upstream version 1.6.2
1029
			    {
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1030
			      nls_uint32 sysdepref;
1031
1032
			      need += W (domain->must_swap, p->segsize);
1033
1034
			      sysdepref = W (domain->must_swap, p->sysdepref);
1035
			      if (sysdepref == SEGMENTS_END)
1036
				break;
1037
1038
			      if (sysdepref >= n_sysdep_segments)
1039
				{
1040
				  /* Invalid.  */
1041
				  freea (sysdep_segment_values);
1042
				  goto invalid;
1043
				}
1044
1045
			      if (sysdep_segment_values[sysdepref] == NULL)
1046
				{
1047
				  /* This particular string pair is invalid.  */
1048
				  valid = 0;
1049
				  break;
1050
				}
1051
1052
			      need += strlen (sysdep_segment_values[sysdepref]);
1 by Michael Piefel
Import upstream version 1.6.2
1053
			    }
1054
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1055
			needs[j] = need;
1056
			if (!valid)
1057
			  break;
1058
		      }
1 by Michael Piefel
Import upstream version 1.6.2
1059
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1060
		    if (valid)
1061
		      {
1062
			n_inmem_sysdep_strings++;
1063
			memneed += needs[0] + needs[1];
1064
		      }
1 by Michael Piefel
Import upstream version 1.6.2
1065
		  }
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1066
		memneed += 2 * n_inmem_sysdep_strings
1067
			   * sizeof (struct sysdep_string_desc);
1068
1069
		if (n_inmem_sysdep_strings > 0)
1 by Michael Piefel
Import upstream version 1.6.2
1070
		  {
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1071
		    unsigned int k;
1072
1073
		    /* Allocate additional memory.  */
1074
		    mem = (char *) malloc (memneed);
1075
		    if (mem == NULL)
1076
		      goto invalid;
1077
1078
		    domain->malloced = mem;
1079
		    inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
1080
		    mem += n_inmem_sysdep_strings
1081
			   * sizeof (struct sysdep_string_desc);
1082
		    inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
1083
		    mem += n_inmem_sysdep_strings
1084
			   * sizeof (struct sysdep_string_desc);
1085
		    inmem_hash_tab = (nls_uint32 *) mem;
1086
		    mem += domain->hash_size * sizeof (nls_uint32);
1087
1088
		    /* Compute the system dependent strings.  */
1089
		    k = 0;
1090
		    for (i = 0; i < n_sysdep_strings; i++)
1091
		      {
1092
			int valid = 1;
1093
1094
			for (j = 0; j < 2; j++)
1 by Michael Piefel
Import upstream version 1.6.2
1095
			  {
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1096
			    const struct sysdep_string *sysdep_string =
1097
			      (const struct sysdep_string *)
1098
			      ((char *) data
1099
			       + W (domain->must_swap,
1100
				    j == 0
1101
				    ? orig_sysdep_tab[i]
1102
				    : trans_sysdep_tab[i]));
1103
			    const struct segment_pair *p =
1104
			      sysdep_string->segments;
1105
1106
			    if (W (domain->must_swap, p->sysdepref)
1107
				!= SEGMENTS_END)
1108
			      for (p = sysdep_string->segments;; p++)
1109
				{
1110
				  nls_uint32 sysdepref;
1111
1112
				  sysdepref =
1113
				    W (domain->must_swap, p->sysdepref);
1114
				  if (sysdepref == SEGMENTS_END)
1115
				    break;
1116
1117
				  if (sysdep_segment_values[sysdepref] == NULL)
1118
				    {
1119
				      /* This particular string pair is
1120
					 invalid.  */
1121
				      valid = 0;
1122
				      break;
1123
				    }
1124
				}
1125
1126
			    if (!valid)
1 by Michael Piefel
Import upstream version 1.6.2
1127
			      break;
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1128
			  }
1129
1130
			if (valid)
1131
			  {
1132
			    for (j = 0; j < 2; j++)
1133
			      {
1134
				const struct sysdep_string *sysdep_string =
1135
				  (const struct sysdep_string *)
1136
				  ((char *) data
1137
				   + W (domain->must_swap,
1138
					j == 0
1139
					? orig_sysdep_tab[i]
1140
					: trans_sysdep_tab[i]));
1141
				const char *static_segments =
1142
				  (char *) data
1143
				  + W (domain->must_swap, sysdep_string->offset);
1144
				const struct segment_pair *p =
1145
				  sysdep_string->segments;
1146
1147
				/* Concatenate the segments, and fill
1148
				   inmem_orig_sysdep_tab[k] (for j == 0) and
1149
				   inmem_trans_sysdep_tab[k] (for j == 1).  */
1150
1151
				struct sysdep_string_desc *inmem_tab_entry =
1152
				  (j == 0
1153
				   ? inmem_orig_sysdep_tab
1154
				   : inmem_trans_sysdep_tab)
1155
				  + k;
1156
1157
				if (W (domain->must_swap, p->sysdepref)
1158
				    == SEGMENTS_END)
1159
				  {
1160
				    /* Only one static segment.  */
1161
				    inmem_tab_entry->length =
1162
				      W (domain->must_swap, p->segsize);
1163
				    inmem_tab_entry->pointer = static_segments;
1164
				  }
1165
				else
1166
				  {
1167
				    inmem_tab_entry->pointer = mem;
1168
1169
				    for (p = sysdep_string->segments;; p++)
1170
				      {
1171
					nls_uint32 segsize =
1172
					  W (domain->must_swap, p->segsize);
1173
					nls_uint32 sysdepref =
1174
					  W (domain->must_swap, p->sysdepref);
1175
					size_t n;
1176
1177
					if (segsize > 0)
1178
					  {
1179
					    memcpy (mem, static_segments, segsize);
1180
					    mem += segsize;
1181
					    static_segments += segsize;
1182
					  }
1183
1184
					if (sysdepref == SEGMENTS_END)
1185
					  break;
1186
1187
					n = strlen (sysdep_segment_values[sysdepref]);
1188
					memcpy (mem, sysdep_segment_values[sysdepref], n);
1189
					mem += n;
1190
				      }
1191
1192
				    inmem_tab_entry->length =
1193
				      mem - inmem_tab_entry->pointer;
1194
				  }
1195
			      }
1196
1197
			    k++;
1198
			  }
1199
		      }
1200
		    if (k != n_inmem_sysdep_strings)
1201
		      abort ();
1202
1203
		    /* Compute the augmented hash table.  */
1204
		    for (i = 0; i < domain->hash_size; i++)
1205
		      inmem_hash_tab[i] =
1206
			W (domain->must_swap_hash_tab, domain->hash_tab[i]);
1207
		    for (i = 0; i < n_inmem_sysdep_strings; i++)
1208
		      {
1209
			const char *msgid = inmem_orig_sysdep_tab[i].pointer;
1.2.5 by Francois Marier
Import upstream version 1.9.0
1210
			nls_uint32 hash_val = __hash_string (msgid);
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1211
			nls_uint32 idx = hash_val % domain->hash_size;
1212
			nls_uint32 incr =
1213
			  1 + (hash_val % (domain->hash_size - 2));
1214
1215
			for (;;)
1216
			  {
1217
			    if (inmem_hash_tab[idx] == 0)
1218
			      {
1219
				/* Hash table entry is empty.  Use it.  */
1220
				inmem_hash_tab[idx] = 1 + domain->nstrings + i;
1221
				break;
1222
			      }
1223
1224
			    if (idx >= domain->hash_size - incr)
1225
			      idx -= domain->hash_size - incr;
1226
			    else
1227
			      idx += incr;
1228
			  }
1229
		      }
1230
1231
		    domain->n_sysdep_strings = n_inmem_sysdep_strings;
1232
		    domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
1233
		    domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
1234
1235
		    domain->hash_tab = inmem_hash_tab;
1236
		    domain->must_swap_hash_tab = 0;
1 by Michael Piefel
Import upstream version 1.6.2
1237
		  }
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1238
		else
1 by Michael Piefel
Import upstream version 1.6.2
1239
		  {
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1240
		    domain->n_sysdep_strings = 0;
1241
		    domain->orig_sysdep_tab = NULL;
1242
		    domain->trans_sysdep_tab = NULL;
1 by Michael Piefel
Import upstream version 1.6.2
1243
		  }
1244
1245
		freea (sysdep_segment_values);
1246
	      }
1247
	    else
1248
	      {
1249
		domain->n_sysdep_strings = 0;
1250
		domain->orig_sysdep_tab = NULL;
1251
		domain->trans_sysdep_tab = NULL;
1252
	      }
1253
	  }
1254
	  break;
1255
	}
1256
      break;
1257
    default:
1258
      /* This is an invalid revision.  */
1259
    invalid:
1260
      /* This is an invalid .mo file.  */
1261
      if (domain->malloced)
1262
	free (domain->malloced);
1263
#ifdef HAVE_MMAP
1264
      if (use_mmap)
1265
	munmap ((caddr_t) data, size);
1266
      else
1267
#endif
1268
	free (data);
1269
      free (domain);
1270
      domain_file->data = NULL;
1.2.5 by Francois Marier
Import upstream version 1.9.0
1271
      goto out;
1 by Michael Piefel
Import upstream version 1.6.2
1272
    }
1273
1.2.5 by Francois Marier
Import upstream version 1.9.0
1274
  /* No caches of converted translations so far.  */
1275
  domain->conversions = NULL;
1276
  domain->nconversions = 0;
1 by Michael Piefel
Import upstream version 1.6.2
1277
1.2.5 by Francois Marier
Import upstream version 1.9.0
1278
  /* Get the header entry and look for a plural specification.  */
1279
#ifdef IN_LIBGLOCALE
1280
  nullentry =
1281
    _nl_find_msg (domain_file, domainbinding, NULL, "", &nullentrylen);
1282
#else
1283
  nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
1284
#endif
1 by Michael Piefel
Import upstream version 1.6.2
1285
  EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
1.2.5 by Francois Marier
Import upstream version 1.9.0
1286
1287
 out:
1288
  if (fd != -1)
1289
    close (fd);
1290
1291
  domain_file->decided = 1;
1292
1293
 done:
1294
  __libc_lock_unlock_recursive (lock);
1 by Michael Piefel
Import upstream version 1.6.2
1295
}
1296
1297
1298
#ifdef _LIBC
1299
void
1.2.5 by Francois Marier
Import upstream version 1.9.0
1300
internal_function __libc_freeres_fn_section
1.2.3 by Daniel Holbach
Import upstream version 1.8.4
1301
_nl_unload_domain (struct loaded_domain *domain)
1 by Michael Piefel
Import upstream version 1.6.2
1302
{
1.2.5 by Francois Marier
Import upstream version 1.9.0
1303
  size_t i;
1304
1 by Michael Piefel
Import upstream version 1.6.2
1305
  if (domain->plural != &__gettext_germanic_plural)
1306
    __gettext_free_exp (domain->plural);
1307
1.2.5 by Francois Marier
Import upstream version 1.9.0
1308
  for (i = 0; i < domain->nconversions; i++)
1309
    {
1310
      struct converted_domain *convd = &domain->conversions[i];
1311
1312
      free (convd->encoding);
1313
      if (convd->conv_tab != NULL && convd->conv_tab != (char **) -1)
1314
	free (convd->conv_tab);
1315
      if (convd->conv != (__gconv_t) -1)
1316
	__gconv_close (convd->conv);
1317
    }
1318
  if (domain->conversions != NULL)
1319
    free (domain->conversions);
1 by Michael Piefel
Import upstream version 1.6.2
1320
1321
  if (domain->malloced)
1322
    free (domain->malloced);
1323
1324
# ifdef _POSIX_MAPPED_FILES
1325
  if (domain->use_mmap)
1326
    munmap ((caddr_t) domain->data, domain->mmap_size);
1327
  else
1328
# endif	/* _POSIX_MAPPED_FILES */
1329
    free ((void *) domain->data);
1330
1331
  free (domain);
1332
}
1333
#endif