Replace FSF snail mail address with URLs.
[glibc.git] / intl / loadmsgcat.c
blob4e34a368be49d50099a435e97664399c253f1936
1 /* Load needed message catalogs.
2 Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
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
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
30 #include <ctype.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
36 #ifdef __GNUC__
37 # undef alloca
38 # define alloca __builtin_alloca
39 # define HAVE_ALLOCA 1
40 #else
41 # if defined HAVE_ALLOCA_H || defined _LIBC
42 # include <alloca.h>
43 # else
44 # ifdef _AIX
45 #pragma alloca
46 # else
47 # ifndef alloca
48 char *alloca ();
49 # endif
50 # endif
51 # endif
52 #endif
54 #include <stdlib.h>
55 #include <string.h>
57 #if defined HAVE_UNISTD_H || defined _LIBC
58 # include <unistd.h>
59 #endif
61 #ifdef _LIBC
62 # include <langinfo.h>
63 # include <locale.h>
64 #endif
66 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
67 || (defined _LIBC && defined _POSIX_MAPPED_FILES)
68 # include <sys/mman.h>
69 # undef HAVE_MMAP
70 # define HAVE_MMAP 1
71 #else
72 # undef HAVE_MMAP
73 #endif
75 #if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC
76 # include <stdint.h>
77 #endif
78 #if defined HAVE_INTTYPES_H || defined _LIBC
79 # include <inttypes.h>
80 #endif
82 #include "gmo.h"
83 #include "gettextP.h"
84 #include "hash-string.h"
85 #include "plural-exp.h"
87 #ifdef _LIBC
88 # include "../locale/localeinfo.h"
89 # include <not-cancel.h>
90 # include <bits/libc-lock.h>
91 #endif
93 /* Provide fallback values for macros that ought to be defined in <inttypes.h>.
94 Note that our fallback values need not be literal strings, because we don't
95 use them with preprocessor string concatenation. */
96 #if !defined PRId8 || PRI_MACROS_BROKEN
97 # undef PRId8
98 # define PRId8 "d"
99 #endif
100 #if !defined PRIi8 || PRI_MACROS_BROKEN
101 # undef PRIi8
102 # define PRIi8 "i"
103 #endif
104 #if !defined PRIo8 || PRI_MACROS_BROKEN
105 # undef PRIo8
106 # define PRIo8 "o"
107 #endif
108 #if !defined PRIu8 || PRI_MACROS_BROKEN
109 # undef PRIu8
110 # define PRIu8 "u"
111 #endif
112 #if !defined PRIx8 || PRI_MACROS_BROKEN
113 # undef PRIx8
114 # define PRIx8 "x"
115 #endif
116 #if !defined PRIX8 || PRI_MACROS_BROKEN
117 # undef PRIX8
118 # define PRIX8 "X"
119 #endif
120 #if !defined PRId16 || PRI_MACROS_BROKEN
121 # undef PRId16
122 # define PRId16 "d"
123 #endif
124 #if !defined PRIi16 || PRI_MACROS_BROKEN
125 # undef PRIi16
126 # define PRIi16 "i"
127 #endif
128 #if !defined PRIo16 || PRI_MACROS_BROKEN
129 # undef PRIo16
130 # define PRIo16 "o"
131 #endif
132 #if !defined PRIu16 || PRI_MACROS_BROKEN
133 # undef PRIu16
134 # define PRIu16 "u"
135 #endif
136 #if !defined PRIx16 || PRI_MACROS_BROKEN
137 # undef PRIx16
138 # define PRIx16 "x"
139 #endif
140 #if !defined PRIX16 || PRI_MACROS_BROKEN
141 # undef PRIX16
142 # define PRIX16 "X"
143 #endif
144 #if !defined PRId32 || PRI_MACROS_BROKEN
145 # undef PRId32
146 # define PRId32 "d"
147 #endif
148 #if !defined PRIi32 || PRI_MACROS_BROKEN
149 # undef PRIi32
150 # define PRIi32 "i"
151 #endif
152 #if !defined PRIo32 || PRI_MACROS_BROKEN
153 # undef PRIo32
154 # define PRIo32 "o"
155 #endif
156 #if !defined PRIu32 || PRI_MACROS_BROKEN
157 # undef PRIu32
158 # define PRIu32 "u"
159 #endif
160 #if !defined PRIx32 || PRI_MACROS_BROKEN
161 # undef PRIx32
162 # define PRIx32 "x"
163 #endif
164 #if !defined PRIX32 || PRI_MACROS_BROKEN
165 # undef PRIX32
166 # define PRIX32 "X"
167 #endif
168 #if !defined PRId64 || PRI_MACROS_BROKEN
169 # undef PRId64
170 # define PRId64 (sizeof (long) == 8 ? "ld" : "lld")
171 #endif
172 #if !defined PRIi64 || PRI_MACROS_BROKEN
173 # undef PRIi64
174 # define PRIi64 (sizeof (long) == 8 ? "li" : "lli")
175 #endif
176 #if !defined PRIo64 || PRI_MACROS_BROKEN
177 # undef PRIo64
178 # define PRIo64 (sizeof (long) == 8 ? "lo" : "llo")
179 #endif
180 #if !defined PRIu64 || PRI_MACROS_BROKEN
181 # undef PRIu64
182 # define PRIu64 (sizeof (long) == 8 ? "lu" : "llu")
183 #endif
184 #if !defined PRIx64 || PRI_MACROS_BROKEN
185 # undef PRIx64
186 # define PRIx64 (sizeof (long) == 8 ? "lx" : "llx")
187 #endif
188 #if !defined PRIX64 || PRI_MACROS_BROKEN
189 # undef PRIX64
190 # define PRIX64 (sizeof (long) == 8 ? "lX" : "llX")
191 #endif
192 #if !defined PRIdLEAST8 || PRI_MACROS_BROKEN
193 # undef PRIdLEAST8
194 # define PRIdLEAST8 "d"
195 #endif
196 #if !defined PRIiLEAST8 || PRI_MACROS_BROKEN
197 # undef PRIiLEAST8
198 # define PRIiLEAST8 "i"
199 #endif
200 #if !defined PRIoLEAST8 || PRI_MACROS_BROKEN
201 # undef PRIoLEAST8
202 # define PRIoLEAST8 "o"
203 #endif
204 #if !defined PRIuLEAST8 || PRI_MACROS_BROKEN
205 # undef PRIuLEAST8
206 # define PRIuLEAST8 "u"
207 #endif
208 #if !defined PRIxLEAST8 || PRI_MACROS_BROKEN
209 # undef PRIxLEAST8
210 # define PRIxLEAST8 "x"
211 #endif
212 #if !defined PRIXLEAST8 || PRI_MACROS_BROKEN
213 # undef PRIXLEAST8
214 # define PRIXLEAST8 "X"
215 #endif
216 #if !defined PRIdLEAST16 || PRI_MACROS_BROKEN
217 # undef PRIdLEAST16
218 # define PRIdLEAST16 "d"
219 #endif
220 #if !defined PRIiLEAST16 || PRI_MACROS_BROKEN
221 # undef PRIiLEAST16
222 # define PRIiLEAST16 "i"
223 #endif
224 #if !defined PRIoLEAST16 || PRI_MACROS_BROKEN
225 # undef PRIoLEAST16
226 # define PRIoLEAST16 "o"
227 #endif
228 #if !defined PRIuLEAST16 || PRI_MACROS_BROKEN
229 # undef PRIuLEAST16
230 # define PRIuLEAST16 "u"
231 #endif
232 #if !defined PRIxLEAST16 || PRI_MACROS_BROKEN
233 # undef PRIxLEAST16
234 # define PRIxLEAST16 "x"
235 #endif
236 #if !defined PRIXLEAST16 || PRI_MACROS_BROKEN
237 # undef PRIXLEAST16
238 # define PRIXLEAST16 "X"
239 #endif
240 #if !defined PRIdLEAST32 || PRI_MACROS_BROKEN
241 # undef PRIdLEAST32
242 # define PRIdLEAST32 "d"
243 #endif
244 #if !defined PRIiLEAST32 || PRI_MACROS_BROKEN
245 # undef PRIiLEAST32
246 # define PRIiLEAST32 "i"
247 #endif
248 #if !defined PRIoLEAST32 || PRI_MACROS_BROKEN
249 # undef PRIoLEAST32
250 # define PRIoLEAST32 "o"
251 #endif
252 #if !defined PRIuLEAST32 || PRI_MACROS_BROKEN
253 # undef PRIuLEAST32
254 # define PRIuLEAST32 "u"
255 #endif
256 #if !defined PRIxLEAST32 || PRI_MACROS_BROKEN
257 # undef PRIxLEAST32
258 # define PRIxLEAST32 "x"
259 #endif
260 #if !defined PRIXLEAST32 || PRI_MACROS_BROKEN
261 # undef PRIXLEAST32
262 # define PRIXLEAST32 "X"
263 #endif
264 #if !defined PRIdLEAST64 || PRI_MACROS_BROKEN
265 # undef PRIdLEAST64
266 # define PRIdLEAST64 PRId64
267 #endif
268 #if !defined PRIiLEAST64 || PRI_MACROS_BROKEN
269 # undef PRIiLEAST64
270 # define PRIiLEAST64 PRIi64
271 #endif
272 #if !defined PRIoLEAST64 || PRI_MACROS_BROKEN
273 # undef PRIoLEAST64
274 # define PRIoLEAST64 PRIo64
275 #endif
276 #if !defined PRIuLEAST64 || PRI_MACROS_BROKEN
277 # undef PRIuLEAST64
278 # define PRIuLEAST64 PRIu64
279 #endif
280 #if !defined PRIxLEAST64 || PRI_MACROS_BROKEN
281 # undef PRIxLEAST64
282 # define PRIxLEAST64 PRIx64
283 #endif
284 #if !defined PRIXLEAST64 || PRI_MACROS_BROKEN
285 # undef PRIXLEAST64
286 # define PRIXLEAST64 PRIX64
287 #endif
288 #if !defined PRIdFAST8 || PRI_MACROS_BROKEN
289 # undef PRIdFAST8
290 # define PRIdFAST8 "d"
291 #endif
292 #if !defined PRIiFAST8 || PRI_MACROS_BROKEN
293 # undef PRIiFAST8
294 # define PRIiFAST8 "i"
295 #endif
296 #if !defined PRIoFAST8 || PRI_MACROS_BROKEN
297 # undef PRIoFAST8
298 # define PRIoFAST8 "o"
299 #endif
300 #if !defined PRIuFAST8 || PRI_MACROS_BROKEN
301 # undef PRIuFAST8
302 # define PRIuFAST8 "u"
303 #endif
304 #if !defined PRIxFAST8 || PRI_MACROS_BROKEN
305 # undef PRIxFAST8
306 # define PRIxFAST8 "x"
307 #endif
308 #if !defined PRIXFAST8 || PRI_MACROS_BROKEN
309 # undef PRIXFAST8
310 # define PRIXFAST8 "X"
311 #endif
312 #if !defined PRIdFAST16 || PRI_MACROS_BROKEN
313 # undef PRIdFAST16
314 # define PRIdFAST16 "d"
315 #endif
316 #if !defined PRIiFAST16 || PRI_MACROS_BROKEN
317 # undef PRIiFAST16
318 # define PRIiFAST16 "i"
319 #endif
320 #if !defined PRIoFAST16 || PRI_MACROS_BROKEN
321 # undef PRIoFAST16
322 # define PRIoFAST16 "o"
323 #endif
324 #if !defined PRIuFAST16 || PRI_MACROS_BROKEN
325 # undef PRIuFAST16
326 # define PRIuFAST16 "u"
327 #endif
328 #if !defined PRIxFAST16 || PRI_MACROS_BROKEN
329 # undef PRIxFAST16
330 # define PRIxFAST16 "x"
331 #endif
332 #if !defined PRIXFAST16 || PRI_MACROS_BROKEN
333 # undef PRIXFAST16
334 # define PRIXFAST16 "X"
335 #endif
336 #if !defined PRIdFAST32 || PRI_MACROS_BROKEN
337 # undef PRIdFAST32
338 # define PRIdFAST32 "d"
339 #endif
340 #if !defined PRIiFAST32 || PRI_MACROS_BROKEN
341 # undef PRIiFAST32
342 # define PRIiFAST32 "i"
343 #endif
344 #if !defined PRIoFAST32 || PRI_MACROS_BROKEN
345 # undef PRIoFAST32
346 # define PRIoFAST32 "o"
347 #endif
348 #if !defined PRIuFAST32 || PRI_MACROS_BROKEN
349 # undef PRIuFAST32
350 # define PRIuFAST32 "u"
351 #endif
352 #if !defined PRIxFAST32 || PRI_MACROS_BROKEN
353 # undef PRIxFAST32
354 # define PRIxFAST32 "x"
355 #endif
356 #if !defined PRIXFAST32 || PRI_MACROS_BROKEN
357 # undef PRIXFAST32
358 # define PRIXFAST32 "X"
359 #endif
360 #if !defined PRIdFAST64 || PRI_MACROS_BROKEN
361 # undef PRIdFAST64
362 # define PRIdFAST64 PRId64
363 #endif
364 #if !defined PRIiFAST64 || PRI_MACROS_BROKEN
365 # undef PRIiFAST64
366 # define PRIiFAST64 PRIi64
367 #endif
368 #if !defined PRIoFAST64 || PRI_MACROS_BROKEN
369 # undef PRIoFAST64
370 # define PRIoFAST64 PRIo64
371 #endif
372 #if !defined PRIuFAST64 || PRI_MACROS_BROKEN
373 # undef PRIuFAST64
374 # define PRIuFAST64 PRIu64
375 #endif
376 #if !defined PRIxFAST64 || PRI_MACROS_BROKEN
377 # undef PRIxFAST64
378 # define PRIxFAST64 PRIx64
379 #endif
380 #if !defined PRIXFAST64 || PRI_MACROS_BROKEN
381 # undef PRIXFAST64
382 # define PRIXFAST64 PRIX64
383 #endif
384 #if !defined PRIdMAX || PRI_MACROS_BROKEN
385 # undef PRIdMAX
386 # define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
387 #endif
388 #if !defined PRIiMAX || PRI_MACROS_BROKEN
389 # undef PRIiMAX
390 # define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
391 #endif
392 #if !defined PRIoMAX || PRI_MACROS_BROKEN
393 # undef PRIoMAX
394 # define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
395 #endif
396 #if !defined PRIuMAX || PRI_MACROS_BROKEN
397 # undef PRIuMAX
398 # define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
399 #endif
400 #if !defined PRIxMAX || PRI_MACROS_BROKEN
401 # undef PRIxMAX
402 # define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
403 #endif
404 #if !defined PRIXMAX || PRI_MACROS_BROKEN
405 # undef PRIXMAX
406 # define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
407 #endif
408 #if !defined PRIdPTR || PRI_MACROS_BROKEN
409 # undef PRIdPTR
410 # define PRIdPTR \
411 (sizeof (void *) == sizeof (long) ? "ld" : \
412 sizeof (void *) == sizeof (int) ? "d" : \
413 "lld")
414 #endif
415 #if !defined PRIiPTR || PRI_MACROS_BROKEN
416 # undef PRIiPTR
417 # define PRIiPTR \
418 (sizeof (void *) == sizeof (long) ? "li" : \
419 sizeof (void *) == sizeof (int) ? "i" : \
420 "lli")
421 #endif
422 #if !defined PRIoPTR || PRI_MACROS_BROKEN
423 # undef PRIoPTR
424 # define PRIoPTR \
425 (sizeof (void *) == sizeof (long) ? "lo" : \
426 sizeof (void *) == sizeof (int) ? "o" : \
427 "llo")
428 #endif
429 #if !defined PRIuPTR || PRI_MACROS_BROKEN
430 # undef PRIuPTR
431 # define PRIuPTR \
432 (sizeof (void *) == sizeof (long) ? "lu" : \
433 sizeof (void *) == sizeof (int) ? "u" : \
434 "llu")
435 #endif
436 #if !defined PRIxPTR || PRI_MACROS_BROKEN
437 # undef PRIxPTR
438 # define PRIxPTR \
439 (sizeof (void *) == sizeof (long) ? "lx" : \
440 sizeof (void *) == sizeof (int) ? "x" : \
441 "llx")
442 #endif
443 #if !defined PRIXPTR || PRI_MACROS_BROKEN
444 # undef PRIXPTR
445 # define PRIXPTR \
446 (sizeof (void *) == sizeof (long) ? "lX" : \
447 sizeof (void *) == sizeof (int) ? "X" : \
448 "llX")
449 #endif
451 /* @@ end of prolog @@ */
453 #ifdef _LIBC
454 /* Rename the non ISO C functions. This is required by the standard
455 because some ISO C functions will require linking with this object
456 file and the name space must not be polluted. */
457 # define open(name, flags) open_not_cancel_2 (name, flags)
458 # define close(fd) close_not_cancel_no_status (fd)
459 # define read(fd, buf, n) read_not_cancel (fd, buf, n)
460 # define mmap(addr, len, prot, flags, fd, offset) \
461 __mmap (addr, len, prot, flags, fd, offset)
462 # define munmap(addr, len) __munmap (addr, len)
463 #endif
465 /* For those losing systems which don't have `alloca' we have to add
466 some additional code emulating it. */
467 #ifdef HAVE_ALLOCA
468 # define freea(p) /* nothing */
469 #else
470 # define alloca(n) malloc (n)
471 # define freea(p) free (p)
472 #endif
475 /* Prototypes for local functions. Needed to ensure compiler checking of
476 function argument counts despite of K&R C function definition syntax. */
477 static const char *get_sysdep_segment_value PARAMS ((const char *name));
480 /* We need a sign, whether a new catalog was loaded, which can be associated
481 with all translations. This is important if the translations are
482 cached by one of GCC's features. */
483 int _nl_msg_cat_cntr;
486 /* Expand a system dependent string segment. Return NULL if unsupported. */
487 static const char *
488 get_sysdep_segment_value (name)
489 const char *name;
491 /* Test for an ISO C 99 section 7.8.1 format string directive.
492 Syntax:
493 P R I { d | i | o | u | x | X }
494 { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */
495 /* We don't use a table of 14 times 6 'const char *' strings here, because
496 data relocations cost startup time. */
497 if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
499 if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
500 || name[3] == 'x' || name[3] == 'X')
502 if (name[4] == '8' && name[5] == '\0')
504 if (name[3] == 'd')
505 return PRId8;
506 if (name[3] == 'i')
507 return PRIi8;
508 if (name[3] == 'o')
509 return PRIo8;
510 if (name[3] == 'u')
511 return PRIu8;
512 if (name[3] == 'x')
513 return PRIx8;
514 if (name[3] == 'X')
515 return PRIX8;
516 abort ();
518 if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
520 if (name[3] == 'd')
521 return PRId16;
522 if (name[3] == 'i')
523 return PRIi16;
524 if (name[3] == 'o')
525 return PRIo16;
526 if (name[3] == 'u')
527 return PRIu16;
528 if (name[3] == 'x')
529 return PRIx16;
530 if (name[3] == 'X')
531 return PRIX16;
532 abort ();
534 if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
536 if (name[3] == 'd')
537 return PRId32;
538 if (name[3] == 'i')
539 return PRIi32;
540 if (name[3] == 'o')
541 return PRIo32;
542 if (name[3] == 'u')
543 return PRIu32;
544 if (name[3] == 'x')
545 return PRIx32;
546 if (name[3] == 'X')
547 return PRIX32;
548 abort ();
550 if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
552 if (name[3] == 'd')
553 return PRId64;
554 if (name[3] == 'i')
555 return PRIi64;
556 if (name[3] == 'o')
557 return PRIo64;
558 if (name[3] == 'u')
559 return PRIu64;
560 if (name[3] == 'x')
561 return PRIx64;
562 if (name[3] == 'X')
563 return PRIX64;
564 abort ();
566 if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
567 && name[7] == 'S' && name[8] == 'T')
569 if (name[9] == '8' && name[10] == '\0')
571 if (name[3] == 'd')
572 return PRIdLEAST8;
573 if (name[3] == 'i')
574 return PRIiLEAST8;
575 if (name[3] == 'o')
576 return PRIoLEAST8;
577 if (name[3] == 'u')
578 return PRIuLEAST8;
579 if (name[3] == 'x')
580 return PRIxLEAST8;
581 if (name[3] == 'X')
582 return PRIXLEAST8;
583 abort ();
585 if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
587 if (name[3] == 'd')
588 return PRIdLEAST16;
589 if (name[3] == 'i')
590 return PRIiLEAST16;
591 if (name[3] == 'o')
592 return PRIoLEAST16;
593 if (name[3] == 'u')
594 return PRIuLEAST16;
595 if (name[3] == 'x')
596 return PRIxLEAST16;
597 if (name[3] == 'X')
598 return PRIXLEAST16;
599 abort ();
601 if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
603 if (name[3] == 'd')
604 return PRIdLEAST32;
605 if (name[3] == 'i')
606 return PRIiLEAST32;
607 if (name[3] == 'o')
608 return PRIoLEAST32;
609 if (name[3] == 'u')
610 return PRIuLEAST32;
611 if (name[3] == 'x')
612 return PRIxLEAST32;
613 if (name[3] == 'X')
614 return PRIXLEAST32;
615 abort ();
617 if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
619 if (name[3] == 'd')
620 return PRIdLEAST64;
621 if (name[3] == 'i')
622 return PRIiLEAST64;
623 if (name[3] == 'o')
624 return PRIoLEAST64;
625 if (name[3] == 'u')
626 return PRIuLEAST64;
627 if (name[3] == 'x')
628 return PRIxLEAST64;
629 if (name[3] == 'X')
630 return PRIXLEAST64;
631 abort ();
634 if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
635 && name[7] == 'T')
637 if (name[8] == '8' && name[9] == '\0')
639 if (name[3] == 'd')
640 return PRIdFAST8;
641 if (name[3] == 'i')
642 return PRIiFAST8;
643 if (name[3] == 'o')
644 return PRIoFAST8;
645 if (name[3] == 'u')
646 return PRIuFAST8;
647 if (name[3] == 'x')
648 return PRIxFAST8;
649 if (name[3] == 'X')
650 return PRIXFAST8;
651 abort ();
653 if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
655 if (name[3] == 'd')
656 return PRIdFAST16;
657 if (name[3] == 'i')
658 return PRIiFAST16;
659 if (name[3] == 'o')
660 return PRIoFAST16;
661 if (name[3] == 'u')
662 return PRIuFAST16;
663 if (name[3] == 'x')
664 return PRIxFAST16;
665 if (name[3] == 'X')
666 return PRIXFAST16;
667 abort ();
669 if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
671 if (name[3] == 'd')
672 return PRIdFAST32;
673 if (name[3] == 'i')
674 return PRIiFAST32;
675 if (name[3] == 'o')
676 return PRIoFAST32;
677 if (name[3] == 'u')
678 return PRIuFAST32;
679 if (name[3] == 'x')
680 return PRIxFAST32;
681 if (name[3] == 'X')
682 return PRIXFAST32;
683 abort ();
685 if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
687 if (name[3] == 'd')
688 return PRIdFAST64;
689 if (name[3] == 'i')
690 return PRIiFAST64;
691 if (name[3] == 'o')
692 return PRIoFAST64;
693 if (name[3] == 'u')
694 return PRIuFAST64;
695 if (name[3] == 'x')
696 return PRIxFAST64;
697 if (name[3] == 'X')
698 return PRIXFAST64;
699 abort ();
702 if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
703 && name[7] == '\0')
705 if (name[3] == 'd')
706 return PRIdMAX;
707 if (name[3] == 'i')
708 return PRIiMAX;
709 if (name[3] == 'o')
710 return PRIoMAX;
711 if (name[3] == 'u')
712 return PRIuMAX;
713 if (name[3] == 'x')
714 return PRIxMAX;
715 if (name[3] == 'X')
716 return PRIXMAX;
717 abort ();
719 if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
720 && name[7] == '\0')
722 if (name[3] == 'd')
723 return PRIdPTR;
724 if (name[3] == 'i')
725 return PRIiPTR;
726 if (name[3] == 'o')
727 return PRIoPTR;
728 if (name[3] == 'u')
729 return PRIuPTR;
730 if (name[3] == 'x')
731 return PRIxPTR;
732 if (name[3] == 'X')
733 return PRIXPTR;
734 abort ();
738 /* Test for a glibc specific printf() format directive flag. */
739 if (name[0] == 'I' && name[1] == '\0')
741 #if defined _LIBC || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
742 /* The 'I' flag, in numeric format directives, replaces ASCII digits
743 with the 'outdigits' defined in the LC_CTYPE locale facet. This is
744 used for Farsi (Persian) and maybe Arabic. */
745 return "I";
746 #else
747 return "";
748 #endif
750 /* Other system dependent strings are not valid. */
751 return NULL;
754 /* Load the message catalogs specified by FILENAME. If it is no valid
755 message catalog do nothing. */
756 void
757 internal_function
758 _nl_load_domain (domain_file, domainbinding)
759 struct loaded_l10nfile *domain_file;
760 struct binding *domainbinding;
762 __libc_lock_define_initialized_recursive (static, lock);
763 int fd = -1;
764 size_t size;
765 #ifdef _LIBC
766 struct stat64 st;
767 #else
768 struct stat st;
769 #endif
770 struct mo_file_header *data = (struct mo_file_header *) -1;
771 int use_mmap = 0;
772 struct loaded_domain *domain;
773 int revision;
774 const char *nullentry;
775 size_t nullentrylen;
777 __libc_lock_lock_recursive (lock);
778 if (domain_file->decided != 0)
780 /* There are two possibilities:
782 + is is the same thread calling again during this
783 initialization via _nl_find_msg. We have initialized
784 everything this call needs.
786 + this is another thread which tried to initialize this object.
787 Not necessary anymore since if the lock is available this
788 is finished.
790 __libc_lock_unlock_recursive (lock);
791 return;
794 domain_file->decided = -1;
795 domain_file->data = NULL;
797 /* Note that it would be useless to store domainbinding in domain_file
798 because domainbinding might be == NULL now but != NULL later (after
799 a call to bind_textdomain_codeset). */
801 /* If the record does not represent a valid locale the FILENAME
802 might be NULL. This can happen when according to the given
803 specification the locale file name is different for XPG and CEN
804 syntax. */
805 if (domain_file->filename == NULL)
806 goto out;
808 /* Try to open the addressed file. */
809 fd = open (domain_file->filename, O_RDONLY);
810 if (fd == -1)
811 goto out;
813 /* We must know about the size of the file. */
814 if (
815 #ifdef _LIBC
816 __builtin_expect (fstat64 (fd, &st) != 0, 0)
817 #else
818 __builtin_expect (fstat (fd, &st) != 0, 0)
819 #endif
820 || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
821 || __builtin_expect (size < sizeof (struct mo_file_header), 0))
822 /* Something went wrong. */
823 goto out;;
825 #ifdef HAVE_MMAP
826 /* Now we are ready to load the file. If mmap() is available we try
827 this first. If not available or it failed we try to load it. */
828 data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
829 MAP_PRIVATE, fd, 0);
831 if (__builtin_expect (data != MAP_FAILED, 1))
833 /* mmap() call was successful. */
834 close (fd);
835 fd = -1;
836 use_mmap = 1;
838 #endif
840 /* If the data is not yet available (i.e. mmap'ed) we try to load
841 it manually. */
842 if (data == MAP_FAILED)
844 size_t to_read;
845 char *read_ptr;
847 data = (struct mo_file_header *) malloc (size);
848 if (data == NULL)
849 goto out;
851 to_read = size;
852 read_ptr = (char *) data;
855 long int nb = (long int) TEMP_FAILURE_RETRY (read (fd, read_ptr,
856 to_read));
857 if (nb <= 0)
858 goto out;
860 read_ptr += nb;
861 to_read -= nb;
863 while (to_read > 0);
865 close (fd);
866 fd = -1;
869 /* Using the magic number we can test whether it really is a message
870 catalog file. */
871 if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
874 /* The magic number is wrong: not a message catalog file. */
875 #ifdef HAVE_MMAP
876 if (use_mmap)
877 munmap ((caddr_t) data, size);
878 else
879 #endif
880 free (data);
881 goto out;
884 domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
885 if (domain == NULL)
886 goto out;
887 domain_file->data = domain;
889 domain->data = (char *) data;
890 domain->use_mmap = use_mmap;
891 domain->mmap_size = size;
892 domain->must_swap = data->magic != _MAGIC;
893 domain->malloced = NULL;
895 /* Fill in the information about the available tables. */
896 revision = W (domain->must_swap, data->revision);
897 /* We support only the major revisions 0 and 1. */
898 switch (revision >> 16)
900 case 0:
901 case 1:
902 domain->nstrings = W (domain->must_swap, data->nstrings);
903 domain->orig_tab = (const struct string_desc *)
904 ((char *) data + W (domain->must_swap, data->orig_tab_offset));
905 domain->trans_tab = (const struct string_desc *)
906 ((char *) data + W (domain->must_swap, data->trans_tab_offset));
907 domain->hash_size = W (domain->must_swap, data->hash_tab_size);
908 domain->hash_tab =
909 (domain->hash_size > 2
910 ? (const nls_uint32 *)
911 ((char *) data + W (domain->must_swap, data->hash_tab_offset))
912 : NULL);
913 domain->must_swap_hash_tab = domain->must_swap;
915 /* Now dispatch on the minor revision. */
916 switch (revision & 0xffff)
918 case 0:
919 domain->n_sysdep_strings = 0;
920 domain->orig_sysdep_tab = NULL;
921 domain->trans_sysdep_tab = NULL;
922 break;
923 case 1:
924 default:
926 nls_uint32 n_sysdep_strings;
928 if (domain->hash_tab == NULL)
929 /* This is invalid. These minor revisions need a hash table. */
930 goto invalid;
932 n_sysdep_strings =
933 W (domain->must_swap, data->n_sysdep_strings);
934 if (n_sysdep_strings > 0)
936 nls_uint32 n_sysdep_segments;
937 const struct sysdep_segment *sysdep_segments;
938 const char **sysdep_segment_values;
939 const nls_uint32 *orig_sysdep_tab;
940 const nls_uint32 *trans_sysdep_tab;
941 nls_uint32 n_inmem_sysdep_strings;
942 size_t memneed;
943 char *mem;
944 struct sysdep_string_desc *inmem_orig_sysdep_tab;
945 struct sysdep_string_desc *inmem_trans_sysdep_tab;
946 nls_uint32 *inmem_hash_tab;
947 unsigned int i, j;
949 /* Get the values of the system dependent segments. */
950 n_sysdep_segments =
951 W (domain->must_swap, data->n_sysdep_segments);
952 sysdep_segments = (const struct sysdep_segment *)
953 ((char *) data
954 + W (domain->must_swap, data->sysdep_segments_offset));
955 sysdep_segment_values =
956 alloca (n_sysdep_segments * sizeof (const char *));
957 for (i = 0; i < n_sysdep_segments; i++)
959 const char *name =
960 (char *) data
961 + W (domain->must_swap, sysdep_segments[i].offset);
962 nls_uint32 namelen =
963 W (domain->must_swap, sysdep_segments[i].length);
965 if (!(namelen > 0 && name[namelen - 1] == '\0'))
967 freea (sysdep_segment_values);
968 goto invalid;
971 sysdep_segment_values[i] = get_sysdep_segment_value (name);
974 orig_sysdep_tab = (const nls_uint32 *)
975 ((char *) data
976 + W (domain->must_swap, data->orig_sysdep_tab_offset));
977 trans_sysdep_tab = (const nls_uint32 *)
978 ((char *) data
979 + W (domain->must_swap, data->trans_sysdep_tab_offset));
981 /* Compute the amount of additional memory needed for the
982 system dependent strings and the augmented hash table.
983 At the same time, also drop string pairs which refer to
984 an undefined system dependent segment. */
985 n_inmem_sysdep_strings = 0;
986 memneed = domain->hash_size * sizeof (nls_uint32);
987 for (i = 0; i < n_sysdep_strings; i++)
989 int valid = 1;
990 size_t needs[2];
992 for (j = 0; j < 2; j++)
994 const struct sysdep_string *sysdep_string =
995 (const struct sysdep_string *)
996 ((char *) data
997 + W (domain->must_swap,
998 j == 0
999 ? orig_sysdep_tab[i]
1000 : trans_sysdep_tab[i]));
1001 size_t need = 0;
1002 const struct segment_pair *p = sysdep_string->segments;
1004 if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
1005 for (p = sysdep_string->segments;; p++)
1007 nls_uint32 sysdepref;
1009 need += W (domain->must_swap, p->segsize);
1011 sysdepref = W (domain->must_swap, p->sysdepref);
1012 if (sysdepref == SEGMENTS_END)
1013 break;
1015 if (sysdepref >= n_sysdep_segments)
1017 /* Invalid. */
1018 freea (sysdep_segment_values);
1019 goto invalid;
1022 if (sysdep_segment_values[sysdepref] == NULL)
1024 /* This particular string pair is invalid. */
1025 valid = 0;
1026 break;
1029 need += strlen (sysdep_segment_values[sysdepref]);
1032 needs[j] = need;
1033 if (!valid)
1034 break;
1037 if (valid)
1039 n_inmem_sysdep_strings++;
1040 memneed += needs[0] + needs[1];
1043 memneed += 2 * n_inmem_sysdep_strings
1044 * sizeof (struct sysdep_string_desc);
1046 if (n_inmem_sysdep_strings > 0)
1048 unsigned int k;
1050 /* Allocate additional memory. */
1051 mem = (char *) malloc (memneed);
1052 if (mem == NULL)
1053 goto invalid;
1055 domain->malloced = mem;
1056 inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
1057 mem += n_inmem_sysdep_strings
1058 * sizeof (struct sysdep_string_desc);
1059 inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
1060 mem += n_inmem_sysdep_strings
1061 * sizeof (struct sysdep_string_desc);
1062 inmem_hash_tab = (nls_uint32 *) mem;
1063 mem += domain->hash_size * sizeof (nls_uint32);
1065 /* Compute the system dependent strings. */
1066 k = 0;
1067 for (i = 0; i < n_sysdep_strings; i++)
1069 int valid = 1;
1071 for (j = 0; j < 2; j++)
1073 const struct sysdep_string *sysdep_string =
1074 (const struct sysdep_string *)
1075 ((char *) data
1076 + W (domain->must_swap,
1077 j == 0
1078 ? orig_sysdep_tab[i]
1079 : trans_sysdep_tab[i]));
1080 const struct segment_pair *p =
1081 sysdep_string->segments;
1083 if (W (domain->must_swap, p->sysdepref)
1084 != SEGMENTS_END)
1085 for (p = sysdep_string->segments;; p++)
1087 nls_uint32 sysdepref;
1089 sysdepref =
1090 W (domain->must_swap, p->sysdepref);
1091 if (sysdepref == SEGMENTS_END)
1092 break;
1094 if (sysdep_segment_values[sysdepref] == NULL)
1096 /* This particular string pair is
1097 invalid. */
1098 valid = 0;
1099 break;
1103 if (!valid)
1104 break;
1107 if (valid)
1109 for (j = 0; j < 2; j++)
1111 const struct sysdep_string *sysdep_string =
1112 (const struct sysdep_string *)
1113 ((char *) data
1114 + W (domain->must_swap,
1115 j == 0
1116 ? orig_sysdep_tab[i]
1117 : trans_sysdep_tab[i]));
1118 const char *static_segments =
1119 (char *) data
1120 + W (domain->must_swap, sysdep_string->offset);
1121 const struct segment_pair *p =
1122 sysdep_string->segments;
1124 /* Concatenate the segments, and fill
1125 inmem_orig_sysdep_tab[k] (for j == 0) and
1126 inmem_trans_sysdep_tab[k] (for j == 1). */
1128 struct sysdep_string_desc *inmem_tab_entry =
1129 (j == 0
1130 ? inmem_orig_sysdep_tab
1131 : inmem_trans_sysdep_tab)
1132 + k;
1134 if (W (domain->must_swap, p->sysdepref)
1135 == SEGMENTS_END)
1137 /* Only one static segment. */
1138 inmem_tab_entry->length =
1139 W (domain->must_swap, p->segsize);
1140 inmem_tab_entry->pointer = static_segments;
1142 else
1144 inmem_tab_entry->pointer = mem;
1146 for (p = sysdep_string->segments;; p++)
1148 nls_uint32 segsize =
1149 W (domain->must_swap, p->segsize);
1150 nls_uint32 sysdepref =
1151 W (domain->must_swap, p->sysdepref);
1152 size_t n;
1154 if (segsize > 0)
1156 memcpy (mem, static_segments, segsize);
1157 mem += segsize;
1158 static_segments += segsize;
1161 if (sysdepref == SEGMENTS_END)
1162 break;
1164 n = strlen (sysdep_segment_values[sysdepref]);
1165 memcpy (mem, sysdep_segment_values[sysdepref], n);
1166 mem += n;
1169 inmem_tab_entry->length =
1170 mem - inmem_tab_entry->pointer;
1174 k++;
1177 if (k != n_inmem_sysdep_strings)
1178 abort ();
1180 /* Compute the augmented hash table. */
1181 for (i = 0; i < domain->hash_size; i++)
1182 inmem_hash_tab[i] =
1183 W (domain->must_swap_hash_tab, domain->hash_tab[i]);
1184 for (i = 0; i < n_inmem_sysdep_strings; i++)
1186 const char *msgid = inmem_orig_sysdep_tab[i].pointer;
1187 nls_uint32 hash_val = __hash_string (msgid);
1188 nls_uint32 idx = hash_val % domain->hash_size;
1189 nls_uint32 incr =
1190 1 + (hash_val % (domain->hash_size - 2));
1192 for (;;)
1194 if (inmem_hash_tab[idx] == 0)
1196 /* Hash table entry is empty. Use it. */
1197 inmem_hash_tab[idx] = 1 + domain->nstrings + i;
1198 break;
1201 if (idx >= domain->hash_size - incr)
1202 idx -= domain->hash_size - incr;
1203 else
1204 idx += incr;
1208 domain->n_sysdep_strings = n_inmem_sysdep_strings;
1209 domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
1210 domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
1212 domain->hash_tab = inmem_hash_tab;
1213 domain->must_swap_hash_tab = 0;
1215 else
1217 domain->n_sysdep_strings = 0;
1218 domain->orig_sysdep_tab = NULL;
1219 domain->trans_sysdep_tab = NULL;
1222 freea (sysdep_segment_values);
1224 else
1226 domain->n_sysdep_strings = 0;
1227 domain->orig_sysdep_tab = NULL;
1228 domain->trans_sysdep_tab = NULL;
1231 break;
1233 break;
1234 default:
1235 /* This is an invalid revision. */
1236 invalid:
1237 /* This is an invalid .mo file. */
1238 free (domain->malloced);
1239 #ifdef HAVE_MMAP
1240 if (use_mmap)
1241 munmap ((caddr_t) data, size);
1242 else
1243 #endif
1244 free (data);
1245 free (domain);
1246 domain_file->data = NULL;
1247 goto out;
1250 /* No caches of converted translations so far. */
1251 domain->conversions = NULL;
1252 domain->nconversions = 0;
1253 __libc_rwlock_init (domain->conversions_lock);
1255 /* Get the header entry and look for a plural specification. */
1256 nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
1257 EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
1259 out:
1260 if (fd != -1)
1261 close (fd);
1263 domain_file->decided = 1;
1265 __libc_lock_unlock_recursive (lock);
1269 #ifdef _LIBC
1270 void
1271 internal_function __libc_freeres_fn_section
1272 _nl_unload_domain (domain)
1273 struct loaded_domain *domain;
1275 size_t i;
1277 if (domain->plural != &__gettext_germanic_plural)
1278 __gettext_free_exp ((struct expression *) domain->plural);
1280 for (i = 0; i < domain->nconversions; i++)
1282 struct converted_domain *convd = &domain->conversions[i];
1284 free ((char *) convd->encoding);
1285 if (convd->conv_tab != NULL && convd->conv_tab != (char **) -1)
1286 free (convd->conv_tab);
1287 if (convd->conv != (__gconv_t) -1)
1288 __gconv_close (convd->conv);
1290 free (domain->conversions);
1291 __libc_rwlock_fini (domain->conversions_lock);
1293 free (domain->malloced);
1295 # ifdef _POSIX_MAPPED_FILES
1296 if (domain->use_mmap)
1297 munmap ((caddr_t) domain->data, domain->mmap_size);
1298 else
1299 # endif /* _POSIX_MAPPED_FILES */
1300 free ((void *) domain->data);
1302 free (domain);
1304 #endif