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