00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _GNU_SOURCE
00023 # define _GNU_SOURCE 1
00024 #endif
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #include <ctype.h>
00031 #include <errno.h>
00032 #include <fcntl.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035
00036 #ifdef __GNUC__
00037 # define alloca __builtin_alloca
00038 # define HAVE_ALLOCA 1
00039 #else
00040 # if defined HAVE_ALLOCA_H || defined _LIBC
00041 # include <alloca.h>
00042 # else
00043 # ifdef _AIX
00044 #pragma alloca
00045 # else
00046 # ifndef alloca
00047 char *alloca ();
00048 # endif
00049 # endif
00050 # endif
00051 #endif
00052
00053 #include <stdlib.h>
00054 #include <string.h>
00055
00056 #if defined HAVE_UNISTD_H || defined _LIBC
00057 # include <unistd.h>
00058 #endif
00059
00060 #ifdef _LIBC
00061 # include <langinfo.h>
00062 # include <locale.h>
00063 #endif
00064
00065 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
00066 || (defined _LIBC && defined _POSIX_MAPPED_FILES)
00067 # include <sys/mman.h>
00068 # undef HAVE_MMAP
00069 # define HAVE_MMAP 1
00070 #else
00071 # undef HAVE_MMAP
00072 #endif
00073
00074 #if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC
00075 # include <stdint.h>
00076 #endif
00077 #if defined HAVE_INTTYPES_H || defined _LIBC
00078 # include <inttypes.h>
00079 #endif
00080
00081 #include "gmo.h"
00082 #include "gettextP.h"
00083 #include "hash-string.h"
00084 #include "plural-exp.h"
00085
00086 #ifdef _LIBC
00087 # include "../locale/localeinfo.h"
00088 #endif
00089
00090
00091
00092
00093 #if !defined PRId8 || PRI_MACROS_BROKEN
00094 # undef PRId8
00095 # define PRId8 "d"
00096 #endif
00097 #if !defined PRIi8 || PRI_MACROS_BROKEN
00098 # undef PRIi8
00099 # define PRIi8 "i"
00100 #endif
00101 #if !defined PRIo8 || PRI_MACROS_BROKEN
00102 # undef PRIo8
00103 # define PRIo8 "o"
00104 #endif
00105 #if !defined PRIu8 || PRI_MACROS_BROKEN
00106 # undef PRIu8
00107 # define PRIu8 "u"
00108 #endif
00109 #if !defined PRIx8 || PRI_MACROS_BROKEN
00110 # undef PRIx8
00111 # define PRIx8 "x"
00112 #endif
00113 #if !defined PRIX8 || PRI_MACROS_BROKEN
00114 # undef PRIX8
00115 # define PRIX8 "X"
00116 #endif
00117 #if !defined PRId16 || PRI_MACROS_BROKEN
00118 # undef PRId16
00119 # define PRId16 "d"
00120 #endif
00121 #if !defined PRIi16 || PRI_MACROS_BROKEN
00122 # undef PRIi16
00123 # define PRIi16 "i"
00124 #endif
00125 #if !defined PRIo16 || PRI_MACROS_BROKEN
00126 # undef PRIo16
00127 # define PRIo16 "o"
00128 #endif
00129 #if !defined PRIu16 || PRI_MACROS_BROKEN
00130 # undef PRIu16
00131 # define PRIu16 "u"
00132 #endif
00133 #if !defined PRIx16 || PRI_MACROS_BROKEN
00134 # undef PRIx16
00135 # define PRIx16 "x"
00136 #endif
00137 #if !defined PRIX16 || PRI_MACROS_BROKEN
00138 # undef PRIX16
00139 # define PRIX16 "X"
00140 #endif
00141 #if !defined PRId32 || PRI_MACROS_BROKEN
00142 # undef PRId32
00143 # define PRId32 "d"
00144 #endif
00145 #if !defined PRIi32 || PRI_MACROS_BROKEN
00146 # undef PRIi32
00147 # define PRIi32 "i"
00148 #endif
00149 #if !defined PRIo32 || PRI_MACROS_BROKEN
00150 # undef PRIo32
00151 # define PRIo32 "o"
00152 #endif
00153 #if !defined PRIu32 || PRI_MACROS_BROKEN
00154 # undef PRIu32
00155 # define PRIu32 "u"
00156 #endif
00157 #if !defined PRIx32 || PRI_MACROS_BROKEN
00158 # undef PRIx32
00159 # define PRIx32 "x"
00160 #endif
00161 #if !defined PRIX32 || PRI_MACROS_BROKEN
00162 # undef PRIX32
00163 # define PRIX32 "X"
00164 #endif
00165 #if !defined PRId64 || PRI_MACROS_BROKEN
00166 # undef PRId64
00167 # define PRId64 (sizeof (long) == 8 ? "ld" : "lld")
00168 #endif
00169 #if !defined PRIi64 || PRI_MACROS_BROKEN
00170 # undef PRIi64
00171 # define PRIi64 (sizeof (long) == 8 ? "li" : "lli")
00172 #endif
00173 #if !defined PRIo64 || PRI_MACROS_BROKEN
00174 # undef PRIo64
00175 # define PRIo64 (sizeof (long) == 8 ? "lo" : "llo")
00176 #endif
00177 #if !defined PRIu64 || PRI_MACROS_BROKEN
00178 # undef PRIu64
00179 # define PRIu64 (sizeof (long) == 8 ? "lu" : "llu")
00180 #endif
00181 #if !defined PRIx64 || PRI_MACROS_BROKEN
00182 # undef PRIx64
00183 # define PRIx64 (sizeof (long) == 8 ? "lx" : "llx")
00184 #endif
00185 #if !defined PRIX64 || PRI_MACROS_BROKEN
00186 # undef PRIX64
00187 # define PRIX64 (sizeof (long) == 8 ? "lX" : "llX")
00188 #endif
00189 #if !defined PRIdLEAST8 || PRI_MACROS_BROKEN
00190 # undef PRIdLEAST8
00191 # define PRIdLEAST8 "d"
00192 #endif
00193 #if !defined PRIiLEAST8 || PRI_MACROS_BROKEN
00194 # undef PRIiLEAST8
00195 # define PRIiLEAST8 "i"
00196 #endif
00197 #if !defined PRIoLEAST8 || PRI_MACROS_BROKEN
00198 # undef PRIoLEAST8
00199 # define PRIoLEAST8 "o"
00200 #endif
00201 #if !defined PRIuLEAST8 || PRI_MACROS_BROKEN
00202 # undef PRIuLEAST8
00203 # define PRIuLEAST8 "u"
00204 #endif
00205 #if !defined PRIxLEAST8 || PRI_MACROS_BROKEN
00206 # undef PRIxLEAST8
00207 # define PRIxLEAST8 "x"
00208 #endif
00209 #if !defined PRIXLEAST8 || PRI_MACROS_BROKEN
00210 # undef PRIXLEAST8
00211 # define PRIXLEAST8 "X"
00212 #endif
00213 #if !defined PRIdLEAST16 || PRI_MACROS_BROKEN
00214 # undef PRIdLEAST16
00215 # define PRIdLEAST16 "d"
00216 #endif
00217 #if !defined PRIiLEAST16 || PRI_MACROS_BROKEN
00218 # undef PRIiLEAST16
00219 # define PRIiLEAST16 "i"
00220 #endif
00221 #if !defined PRIoLEAST16 || PRI_MACROS_BROKEN
00222 # undef PRIoLEAST16
00223 # define PRIoLEAST16 "o"
00224 #endif
00225 #if !defined PRIuLEAST16 || PRI_MACROS_BROKEN
00226 # undef PRIuLEAST16
00227 # define PRIuLEAST16 "u"
00228 #endif
00229 #if !defined PRIxLEAST16 || PRI_MACROS_BROKEN
00230 # undef PRIxLEAST16
00231 # define PRIxLEAST16 "x"
00232 #endif
00233 #if !defined PRIXLEAST16 || PRI_MACROS_BROKEN
00234 # undef PRIXLEAST16
00235 # define PRIXLEAST16 "X"
00236 #endif
00237 #if !defined PRIdLEAST32 || PRI_MACROS_BROKEN
00238 # undef PRIdLEAST32
00239 # define PRIdLEAST32 "d"
00240 #endif
00241 #if !defined PRIiLEAST32 || PRI_MACROS_BROKEN
00242 # undef PRIiLEAST32
00243 # define PRIiLEAST32 "i"
00244 #endif
00245 #if !defined PRIoLEAST32 || PRI_MACROS_BROKEN
00246 # undef PRIoLEAST32
00247 # define PRIoLEAST32 "o"
00248 #endif
00249 #if !defined PRIuLEAST32 || PRI_MACROS_BROKEN
00250 # undef PRIuLEAST32
00251 # define PRIuLEAST32 "u"
00252 #endif
00253 #if !defined PRIxLEAST32 || PRI_MACROS_BROKEN
00254 # undef PRIxLEAST32
00255 # define PRIxLEAST32 "x"
00256 #endif
00257 #if !defined PRIXLEAST32 || PRI_MACROS_BROKEN
00258 # undef PRIXLEAST32
00259 # define PRIXLEAST32 "X"
00260 #endif
00261 #if !defined PRIdLEAST64 || PRI_MACROS_BROKEN
00262 # undef PRIdLEAST64
00263 # define PRIdLEAST64 PRId64
00264 #endif
00265 #if !defined PRIiLEAST64 || PRI_MACROS_BROKEN
00266 # undef PRIiLEAST64
00267 # define PRIiLEAST64 PRIi64
00268 #endif
00269 #if !defined PRIoLEAST64 || PRI_MACROS_BROKEN
00270 # undef PRIoLEAST64
00271 # define PRIoLEAST64 PRIo64
00272 #endif
00273 #if !defined PRIuLEAST64 || PRI_MACROS_BROKEN
00274 # undef PRIuLEAST64
00275 # define PRIuLEAST64 PRIu64
00276 #endif
00277 #if !defined PRIxLEAST64 || PRI_MACROS_BROKEN
00278 # undef PRIxLEAST64
00279 # define PRIxLEAST64 PRIx64
00280 #endif
00281 #if !defined PRIXLEAST64 || PRI_MACROS_BROKEN
00282 # undef PRIXLEAST64
00283 # define PRIXLEAST64 PRIX64
00284 #endif
00285 #if !defined PRIdFAST8 || PRI_MACROS_BROKEN
00286 # undef PRIdFAST8
00287 # define PRIdFAST8 "d"
00288 #endif
00289 #if !defined PRIiFAST8 || PRI_MACROS_BROKEN
00290 # undef PRIiFAST8
00291 # define PRIiFAST8 "i"
00292 #endif
00293 #if !defined PRIoFAST8 || PRI_MACROS_BROKEN
00294 # undef PRIoFAST8
00295 # define PRIoFAST8 "o"
00296 #endif
00297 #if !defined PRIuFAST8 || PRI_MACROS_BROKEN
00298 # undef PRIuFAST8
00299 # define PRIuFAST8 "u"
00300 #endif
00301 #if !defined PRIxFAST8 || PRI_MACROS_BROKEN
00302 # undef PRIxFAST8
00303 # define PRIxFAST8 "x"
00304 #endif
00305 #if !defined PRIXFAST8 || PRI_MACROS_BROKEN
00306 # undef PRIXFAST8
00307 # define PRIXFAST8 "X"
00308 #endif
00309 #if !defined PRIdFAST16 || PRI_MACROS_BROKEN
00310 # undef PRIdFAST16
00311 # define PRIdFAST16 "d"
00312 #endif
00313 #if !defined PRIiFAST16 || PRI_MACROS_BROKEN
00314 # undef PRIiFAST16
00315 # define PRIiFAST16 "i"
00316 #endif
00317 #if !defined PRIoFAST16 || PRI_MACROS_BROKEN
00318 # undef PRIoFAST16
00319 # define PRIoFAST16 "o"
00320 #endif
00321 #if !defined PRIuFAST16 || PRI_MACROS_BROKEN
00322 # undef PRIuFAST16
00323 # define PRIuFAST16 "u"
00324 #endif
00325 #if !defined PRIxFAST16 || PRI_MACROS_BROKEN
00326 # undef PRIxFAST16
00327 # define PRIxFAST16 "x"
00328 #endif
00329 #if !defined PRIXFAST16 || PRI_MACROS_BROKEN
00330 # undef PRIXFAST16
00331 # define PRIXFAST16 "X"
00332 #endif
00333 #if !defined PRIdFAST32 || PRI_MACROS_BROKEN
00334 # undef PRIdFAST32
00335 # define PRIdFAST32 "d"
00336 #endif
00337 #if !defined PRIiFAST32 || PRI_MACROS_BROKEN
00338 # undef PRIiFAST32
00339 # define PRIiFAST32 "i"
00340 #endif
00341 #if !defined PRIoFAST32 || PRI_MACROS_BROKEN
00342 # undef PRIoFAST32
00343 # define PRIoFAST32 "o"
00344 #endif
00345 #if !defined PRIuFAST32 || PRI_MACROS_BROKEN
00346 # undef PRIuFAST32
00347 # define PRIuFAST32 "u"
00348 #endif
00349 #if !defined PRIxFAST32 || PRI_MACROS_BROKEN
00350 # undef PRIxFAST32
00351 # define PRIxFAST32 "x"
00352 #endif
00353 #if !defined PRIXFAST32 || PRI_MACROS_BROKEN
00354 # undef PRIXFAST32
00355 # define PRIXFAST32 "X"
00356 #endif
00357 #if !defined PRIdFAST64 || PRI_MACROS_BROKEN
00358 # undef PRIdFAST64
00359 # define PRIdFAST64 PRId64
00360 #endif
00361 #if !defined PRIiFAST64 || PRI_MACROS_BROKEN
00362 # undef PRIiFAST64
00363 # define PRIiFAST64 PRIi64
00364 #endif
00365 #if !defined PRIoFAST64 || PRI_MACROS_BROKEN
00366 # undef PRIoFAST64
00367 # define PRIoFAST64 PRIo64
00368 #endif
00369 #if !defined PRIuFAST64 || PRI_MACROS_BROKEN
00370 # undef PRIuFAST64
00371 # define PRIuFAST64 PRIu64
00372 #endif
00373 #if !defined PRIxFAST64 || PRI_MACROS_BROKEN
00374 # undef PRIxFAST64
00375 # define PRIxFAST64 PRIx64
00376 #endif
00377 #if !defined PRIXFAST64 || PRI_MACROS_BROKEN
00378 # undef PRIXFAST64
00379 # define PRIXFAST64 PRIX64
00380 #endif
00381 #if !defined PRIdMAX || PRI_MACROS_BROKEN
00382 # undef PRIdMAX
00383 # define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
00384 #endif
00385 #if !defined PRIiMAX || PRI_MACROS_BROKEN
00386 # undef PRIiMAX
00387 # define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
00388 #endif
00389 #if !defined PRIoMAX || PRI_MACROS_BROKEN
00390 # undef PRIoMAX
00391 # define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
00392 #endif
00393 #if !defined PRIuMAX || PRI_MACROS_BROKEN
00394 # undef PRIuMAX
00395 # define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
00396 #endif
00397 #if !defined PRIxMAX || PRI_MACROS_BROKEN
00398 # undef PRIxMAX
00399 # define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
00400 #endif
00401 #if !defined PRIXMAX || PRI_MACROS_BROKEN
00402 # undef PRIXMAX
00403 # define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
00404 #endif
00405 #if !defined PRIdPTR || PRI_MACROS_BROKEN
00406 # undef PRIdPTR
00407 # define PRIdPTR \
00408 (sizeof (void *) == sizeof (long) ? "ld" : \
00409 sizeof (void *) == sizeof (int) ? "d" : \
00410 "lld")
00411 #endif
00412 #if !defined PRIiPTR || PRI_MACROS_BROKEN
00413 # undef PRIiPTR
00414 # define PRIiPTR \
00415 (sizeof (void *) == sizeof (long) ? "li" : \
00416 sizeof (void *) == sizeof (int) ? "i" : \
00417 "lli")
00418 #endif
00419 #if !defined PRIoPTR || PRI_MACROS_BROKEN
00420 # undef PRIoPTR
00421 # define PRIoPTR \
00422 (sizeof (void *) == sizeof (long) ? "lo" : \
00423 sizeof (void *) == sizeof (int) ? "o" : \
00424 "llo")
00425 #endif
00426 #if !defined PRIuPTR || PRI_MACROS_BROKEN
00427 # undef PRIuPTR
00428 # define PRIuPTR \
00429 (sizeof (void *) == sizeof (long) ? "lu" : \
00430 sizeof (void *) == sizeof (int) ? "u" : \
00431 "llu")
00432 #endif
00433 #if !defined PRIxPTR || PRI_MACROS_BROKEN
00434 # undef PRIxPTR
00435 # define PRIxPTR \
00436 (sizeof (void *) == sizeof (long) ? "lx" : \
00437 sizeof (void *) == sizeof (int) ? "x" : \
00438 "llx")
00439 #endif
00440 #if !defined PRIXPTR || PRI_MACROS_BROKEN
00441 # undef PRIXPTR
00442 # define PRIXPTR \
00443 (sizeof (void *) == sizeof (long) ? "lX" : \
00444 sizeof (void *) == sizeof (int) ? "X" : \
00445 "llX")
00446 #endif
00447
00448
00449
00450 #ifdef _LIBC
00451
00452
00453
00454 # define open __open
00455 # define close __close
00456 # define read __read
00457 # define mmap __mmap
00458 # define munmap __munmap
00459 #endif
00460
00461
00462
00463 #ifdef HAVE_ALLOCA
00464 # define freea(p)
00465 #else
00466 # define alloca(n) malloc (n)
00467 # define freea(p) free (p)
00468 #endif
00469
00470
00471
00472 #if !defined O_BINARY && defined _O_BINARY
00473
00474 # define O_BINARY _O_BINARY
00475 # define O_TEXT _O_TEXT
00476 #endif
00477 #ifdef __BEOS__
00478
00479 # undef O_BINARY
00480 # undef O_TEXT
00481 #endif
00482
00483 #ifndef O_BINARY
00484 # define O_BINARY 0
00485 #endif
00486
00487
00488
00489
00490 static const char *get_sysdep_segment_value PARAMS ((const char *name));
00491
00492
00493
00494
00495
00496 int _nl_msg_cat_cntr;
00497
00498
00499
00500 static const char *
00501 get_sysdep_segment_value (name)
00502 const char *name;
00503 {
00504
00505
00506
00507
00508
00509
00510 if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
00511 {
00512 if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
00513 || name[3] == 'x' || name[3] == 'X')
00514 {
00515 if (name[4] == '8' && name[5] == '\0')
00516 {
00517 if (name[3] == 'd')
00518 return PRId8;
00519 if (name[3] == 'i')
00520 return PRIi8;
00521 if (name[3] == 'o')
00522 return PRIo8;
00523 if (name[3] == 'u')
00524 return PRIu8;
00525 if (name[3] == 'x')
00526 return PRIx8;
00527 if (name[3] == 'X')
00528 return PRIX8;
00529 abort ();
00530 }
00531 if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
00532 {
00533 if (name[3] == 'd')
00534 return PRId16;
00535 if (name[3] == 'i')
00536 return PRIi16;
00537 if (name[3] == 'o')
00538 return PRIo16;
00539 if (name[3] == 'u')
00540 return PRIu16;
00541 if (name[3] == 'x')
00542 return PRIx16;
00543 if (name[3] == 'X')
00544 return PRIX16;
00545 abort ();
00546 }
00547 if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
00548 {
00549 if (name[3] == 'd')
00550 return PRId32;
00551 if (name[3] == 'i')
00552 return PRIi32;
00553 if (name[3] == 'o')
00554 return PRIo32;
00555 if (name[3] == 'u')
00556 return PRIu32;
00557 if (name[3] == 'x')
00558 return PRIx32;
00559 if (name[3] == 'X')
00560 return PRIX32;
00561 abort ();
00562 }
00563 if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
00564 {
00565 if (name[3] == 'd')
00566 return PRId64;
00567 if (name[3] == 'i')
00568 return PRIi64;
00569 if (name[3] == 'o')
00570 return PRIo64;
00571 if (name[3] == 'u')
00572 return PRIu64;
00573 if (name[3] == 'x')
00574 return PRIx64;
00575 if (name[3] == 'X')
00576 return PRIX64;
00577 abort ();
00578 }
00579 if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
00580 && name[7] == 'S' && name[8] == 'T')
00581 {
00582 if (name[9] == '8' && name[10] == '\0')
00583 {
00584 if (name[3] == 'd')
00585 return PRIdLEAST8;
00586 if (name[3] == 'i')
00587 return PRIiLEAST8;
00588 if (name[3] == 'o')
00589 return PRIoLEAST8;
00590 if (name[3] == 'u')
00591 return PRIuLEAST8;
00592 if (name[3] == 'x')
00593 return PRIxLEAST8;
00594 if (name[3] == 'X')
00595 return PRIXLEAST8;
00596 abort ();
00597 }
00598 if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
00599 {
00600 if (name[3] == 'd')
00601 return PRIdLEAST16;
00602 if (name[3] == 'i')
00603 return PRIiLEAST16;
00604 if (name[3] == 'o')
00605 return PRIoLEAST16;
00606 if (name[3] == 'u')
00607 return PRIuLEAST16;
00608 if (name[3] == 'x')
00609 return PRIxLEAST16;
00610 if (name[3] == 'X')
00611 return PRIXLEAST16;
00612 abort ();
00613 }
00614 if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
00615 {
00616 if (name[3] == 'd')
00617 return PRIdLEAST32;
00618 if (name[3] == 'i')
00619 return PRIiLEAST32;
00620 if (name[3] == 'o')
00621 return PRIoLEAST32;
00622 if (name[3] == 'u')
00623 return PRIuLEAST32;
00624 if (name[3] == 'x')
00625 return PRIxLEAST32;
00626 if (name[3] == 'X')
00627 return PRIXLEAST32;
00628 abort ();
00629 }
00630 if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
00631 {
00632 if (name[3] == 'd')
00633 return PRIdLEAST64;
00634 if (name[3] == 'i')
00635 return PRIiLEAST64;
00636 if (name[3] == 'o')
00637 return PRIoLEAST64;
00638 if (name[3] == 'u')
00639 return PRIuLEAST64;
00640 if (name[3] == 'x')
00641 return PRIxLEAST64;
00642 if (name[3] == 'X')
00643 return PRIXLEAST64;
00644 abort ();
00645 }
00646 }
00647 if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
00648 && name[7] == 'T')
00649 {
00650 if (name[8] == '8' && name[9] == '\0')
00651 {
00652 if (name[3] == 'd')
00653 return PRIdFAST8;
00654 if (name[3] == 'i')
00655 return PRIiFAST8;
00656 if (name[3] == 'o')
00657 return PRIoFAST8;
00658 if (name[3] == 'u')
00659 return PRIuFAST8;
00660 if (name[3] == 'x')
00661 return PRIxFAST8;
00662 if (name[3] == 'X')
00663 return PRIXFAST8;
00664 abort ();
00665 }
00666 if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
00667 {
00668 if (name[3] == 'd')
00669 return PRIdFAST16;
00670 if (name[3] == 'i')
00671 return PRIiFAST16;
00672 if (name[3] == 'o')
00673 return PRIoFAST16;
00674 if (name[3] == 'u')
00675 return PRIuFAST16;
00676 if (name[3] == 'x')
00677 return PRIxFAST16;
00678 if (name[3] == 'X')
00679 return PRIXFAST16;
00680 abort ();
00681 }
00682 if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
00683 {
00684 if (name[3] == 'd')
00685 return PRIdFAST32;
00686 if (name[3] == 'i')
00687 return PRIiFAST32;
00688 if (name[3] == 'o')
00689 return PRIoFAST32;
00690 if (name[3] == 'u')
00691 return PRIuFAST32;
00692 if (name[3] == 'x')
00693 return PRIxFAST32;
00694 if (name[3] == 'X')
00695 return PRIXFAST32;
00696 abort ();
00697 }
00698 if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
00699 {
00700 if (name[3] == 'd')
00701 return PRIdFAST64;
00702 if (name[3] == 'i')
00703 return PRIiFAST64;
00704 if (name[3] == 'o')
00705 return PRIoFAST64;
00706 if (name[3] == 'u')
00707 return PRIuFAST64;
00708 if (name[3] == 'x')
00709 return PRIxFAST64;
00710 if (name[3] == 'X')
00711 return PRIXFAST64;
00712 abort ();
00713 }
00714 }
00715 if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
00716 && name[7] == '\0')
00717 {
00718 if (name[3] == 'd')
00719 return PRIdMAX;
00720 if (name[3] == 'i')
00721 return PRIiMAX;
00722 if (name[3] == 'o')
00723 return PRIoMAX;
00724 if (name[3] == 'u')
00725 return PRIuMAX;
00726 if (name[3] == 'x')
00727 return PRIxMAX;
00728 if (name[3] == 'X')
00729 return PRIXMAX;
00730 abort ();
00731 }
00732 if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
00733 && name[7] == '\0')
00734 {
00735 if (name[3] == 'd')
00736 return PRIdPTR;
00737 if (name[3] == 'i')
00738 return PRIiPTR;
00739 if (name[3] == 'o')
00740 return PRIoPTR;
00741 if (name[3] == 'u')
00742 return PRIuPTR;
00743 if (name[3] == 'x')
00744 return PRIxPTR;
00745 if (name[3] == 'X')
00746 return PRIXPTR;
00747 abort ();
00748 }
00749 }
00750 }
00751
00752 return NULL;
00753 }
00754
00755
00756
00757 const char *
00758 internal_function
00759 _nl_init_domain_conv (domain_file, domain, domainbinding)
00760 struct loaded_l10nfile *domain_file;
00761 struct loaded_domain *domain;
00762 struct binding *domainbinding;
00763 {
00764
00765
00766
00767
00768
00769 char *nullentry;
00770 size_t nullentrylen;
00771
00772
00773 domain->codeset_cntr =
00774 (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
00775 #ifdef _LIBC
00776 domain->conv = (__gconv_t) -1;
00777 #else
00778 # if HAVE_ICONV
00779 domain->conv = (iconv_t) -1;
00780 # endif
00781 #endif
00782 domain->conv_tab = NULL;
00783
00784
00785 nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);
00786
00787 if (nullentry != NULL)
00788 {
00789 #if defined _LIBC || HAVE_ICONV
00790 const char *charsetstr;
00791
00792 charsetstr = strstr (nullentry, "charset=");
00793 if (charsetstr != NULL)
00794 {
00795 size_t len;
00796 char *charset;
00797 const char *outcharset;
00798
00799 charsetstr += strlen ("charset=");
00800 len = strcspn (charsetstr, " \t\n");
00801
00802 charset = (char *) alloca (len + 1);
00803 # if defined _LIBC || HAVE_MEMPCPY
00804 *((char *) mempcpy (charset, charsetstr, len)) = '\0';
00805 # else
00806 memcpy (charset, charsetstr, len);
00807 charset[len] = '\0';
00808 # endif
00809
00810
00811
00812
00813
00814
00815 if (domainbinding != NULL && domainbinding->codeset != NULL)
00816 outcharset = domainbinding->codeset;
00817 else
00818 {
00819 outcharset = getenv ("OUTPUT_CHARSET");
00820 if (outcharset == NULL || outcharset[0] == '\0')
00821 {
00822 # ifdef _LIBC
00823 outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string;
00824 # else
00825 # if HAVE_ICONV
00826 extern const char *locale_charset PARAMS ((void));
00827 outcharset = locale_charset ();
00828 # endif
00829 # endif
00830 }
00831 }
00832
00833 # ifdef _LIBC
00834
00835 outcharset = norm_add_slashes (outcharset, "TRANSLIT");
00836 charset = norm_add_slashes (charset, NULL);
00837 if (__gconv_open (outcharset, charset, &domain->conv,
00838 GCONV_AVOID_NOCONV)
00839 != __GCONV_OK)
00840 domain->conv = (__gconv_t) -1;
00841 # else
00842 # if HAVE_ICONV
00843
00844
00845 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
00846 || _LIBICONV_VERSION >= 0x0105
00847 if (strchr (outcharset, '/') == NULL)
00848 {
00849 char *tmp;
00850
00851 len = strlen (outcharset);
00852 tmp = (char *) alloca (len + 10 + 1);
00853 memcpy (tmp, outcharset, len);
00854 memcpy (tmp + len, "//TRANSLIT", 10 + 1);
00855 outcharset = tmp;
00856
00857 domain->conv = iconv_open (outcharset, charset);
00858
00859 freea (outcharset);
00860 }
00861 else
00862 # endif
00863 domain->conv = iconv_open (outcharset, charset);
00864 # endif
00865 # endif
00866
00867 freea (charset);
00868 }
00869 #endif
00870 }
00871
00872 return nullentry;
00873 }
00874
00875
00876 void
00877 internal_function
00878 _nl_free_domain_conv (domain)
00879 struct loaded_domain *domain;
00880 {
00881 if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
00882 free (domain->conv_tab);
00883
00884 #ifdef _LIBC
00885 if (domain->conv != (__gconv_t) -1)
00886 __gconv_close (domain->conv);
00887 #else
00888 # if HAVE_ICONV
00889 if (domain->conv != (iconv_t) -1)
00890 iconv_close (domain->conv);
00891 # endif
00892 #endif
00893 }
00894
00895
00896
00897 void
00898 internal_function
00899 _nl_load_domain (domain_file, domainbinding)
00900 struct loaded_l10nfile *domain_file;
00901 struct binding *domainbinding;
00902 {
00903 int fd;
00904 size_t size;
00905 #ifdef _LIBC
00906 struct stat64 st;
00907 #else
00908 struct stat st;
00909 #endif
00910 struct mo_file_header *data = (struct mo_file_header *) -1;
00911 int use_mmap = 0;
00912 struct loaded_domain *domain;
00913 int revision;
00914 const char *nullentry;
00915
00916 domain_file->decided = 1;
00917 domain_file->data = NULL;
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 if (domain_file->filename == NULL)
00928 return;
00929
00930
00931 fd = open (domain_file->filename, O_RDONLY | O_BINARY);
00932 if (fd == -1)
00933 return;
00934
00935
00936 if (
00937 #ifdef _LIBC
00938 __builtin_expect (fstat64 (fd, &st) != 0, 0)
00939 #else
00940 __builtin_expect (fstat (fd, &st) != 0, 0)
00941 #endif
00942 || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
00943 || __builtin_expect (size < sizeof (struct mo_file_header), 0))
00944 {
00945
00946 close (fd);
00947 return;
00948 }
00949
00950 #ifdef HAVE_MMAP
00951
00952
00953 data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
00954 MAP_PRIVATE, fd, 0);
00955
00956 if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
00957 {
00958
00959 close (fd);
00960 use_mmap = 1;
00961 }
00962 #endif
00963
00964
00965
00966 if (data == (struct mo_file_header *) -1)
00967 {
00968 size_t to_read;
00969 char *read_ptr;
00970
00971 data = (struct mo_file_header *) malloc (size);
00972 if (data == NULL)
00973 return;
00974
00975 to_read = size;
00976 read_ptr = (char *) data;
00977 do
00978 {
00979 long int nb = (long int) read (fd, read_ptr, to_read);
00980 if (nb <= 0)
00981 {
00982 #ifdef EINTR
00983 if (nb == -1 && errno == EINTR)
00984 continue;
00985 #endif
00986 close (fd);
00987 return;
00988 }
00989 read_ptr += nb;
00990 to_read -= nb;
00991 }
00992 while (to_read > 0);
00993
00994 close (fd);
00995 }
00996
00997
00998
00999 if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
01000 0))
01001 {
01002
01003 #ifdef HAVE_MMAP
01004 if (use_mmap)
01005 munmap ((caddr_t) data, size);
01006 else
01007 #endif
01008 free (data);
01009 return;
01010 }
01011
01012 domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
01013 if (domain == NULL)
01014 return;
01015 domain_file->data = domain;
01016
01017 domain->data = (char *) data;
01018 domain->use_mmap = use_mmap;
01019 domain->mmap_size = size;
01020 domain->must_swap = data->magic != _MAGIC;
01021 domain->malloced = NULL;
01022
01023
01024 revision = W (domain->must_swap, data->revision);
01025
01026 switch (revision >> 16)
01027 {
01028 case 0:
01029 domain->nstrings = W (domain->must_swap, data->nstrings);
01030 domain->orig_tab = (const struct string_desc *)
01031 ((char *) data + W (domain->must_swap, data->orig_tab_offset));
01032 domain->trans_tab = (const struct string_desc *)
01033 ((char *) data + W (domain->must_swap, data->trans_tab_offset));
01034 domain->hash_size = W (domain->must_swap, data->hash_tab_size);
01035 domain->hash_tab =
01036 (domain->hash_size > 2
01037 ? (const nls_uint32 *)
01038 ((char *) data + W (domain->must_swap, data->hash_tab_offset))
01039 : NULL);
01040 domain->must_swap_hash_tab = domain->must_swap;
01041
01042
01043 switch (revision & 0xffff)
01044 {
01045 case 0:
01046 domain->n_sysdep_strings = 0;
01047 domain->orig_sysdep_tab = NULL;
01048 domain->trans_sysdep_tab = NULL;
01049 break;
01050 case 1:
01051 default:
01052 {
01053 nls_uint32 n_sysdep_strings;
01054
01055 if (domain->hash_tab == NULL)
01056
01057 goto invalid;
01058
01059 n_sysdep_strings =
01060 W (domain->must_swap, data->n_sysdep_strings);
01061 if (n_sysdep_strings > 0)
01062 {
01063 nls_uint32 n_sysdep_segments;
01064 const struct sysdep_segment *sysdep_segments;
01065 const char **sysdep_segment_values;
01066 const nls_uint32 *orig_sysdep_tab;
01067 const nls_uint32 *trans_sysdep_tab;
01068 size_t memneed;
01069 char *mem;
01070 struct sysdep_string_desc *inmem_orig_sysdep_tab;
01071 struct sysdep_string_desc *inmem_trans_sysdep_tab;
01072 nls_uint32 *inmem_hash_tab;
01073 unsigned int i;
01074
01075
01076 n_sysdep_segments =
01077 W (domain->must_swap, data->n_sysdep_segments);
01078 sysdep_segments = (const struct sysdep_segment *)
01079 ((char *) data
01080 + W (domain->must_swap, data->sysdep_segments_offset));
01081 sysdep_segment_values =
01082 alloca (n_sysdep_segments * sizeof (const char *));
01083 for (i = 0; i < n_sysdep_segments; i++)
01084 {
01085 const char *name =
01086 (char *) data
01087 + W (domain->must_swap, sysdep_segments[i].offset);
01088 nls_uint32 namelen =
01089 W (domain->must_swap, sysdep_segments[i].length);
01090
01091 if (!(namelen > 0 && name[namelen - 1] == '\0'))
01092 {
01093 freea (sysdep_segment_values);
01094 goto invalid;
01095 }
01096
01097 sysdep_segment_values[i] = get_sysdep_segment_value (name);
01098 }
01099
01100 orig_sysdep_tab = (const nls_uint32 *)
01101 ((char *) data
01102 + W (domain->must_swap, data->orig_sysdep_tab_offset));
01103 trans_sysdep_tab = (const nls_uint32 *)
01104 ((char *) data
01105 + W (domain->must_swap, data->trans_sysdep_tab_offset));
01106
01107
01108
01109 memneed = 2 * n_sysdep_strings
01110 * sizeof (struct sysdep_string_desc)
01111 + domain->hash_size * sizeof (nls_uint32);
01112 for (i = 0; i < 2 * n_sysdep_strings; i++)
01113 {
01114 const struct sysdep_string *sysdep_string =
01115 (const struct sysdep_string *)
01116 ((char *) data
01117 + W (domain->must_swap,
01118 i < n_sysdep_strings
01119 ? orig_sysdep_tab[i]
01120 : trans_sysdep_tab[i - n_sysdep_strings]));
01121 size_t need = 0;
01122 const struct segment_pair *p = sysdep_string->segments;
01123
01124 if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
01125 for (p = sysdep_string->segments;; p++)
01126 {
01127 nls_uint32 sysdepref;
01128
01129 need += W (domain->must_swap, p->segsize);
01130
01131 sysdepref = W (domain->must_swap, p->sysdepref);
01132 if (sysdepref == SEGMENTS_END)
01133 break;
01134
01135 if (sysdepref >= n_sysdep_segments)
01136 {
01137
01138 freea (sysdep_segment_values);
01139 goto invalid;
01140 }
01141
01142 need += strlen (sysdep_segment_values[sysdepref]);
01143 }
01144
01145 memneed += need;
01146 }
01147
01148
01149 mem = (char *) malloc (memneed);
01150 if (mem == NULL)
01151 goto invalid;
01152
01153 domain->malloced = mem;
01154 inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
01155 mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
01156 inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
01157 mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
01158 inmem_hash_tab = (nls_uint32 *) mem;
01159 mem += domain->hash_size * sizeof (nls_uint32);
01160
01161
01162 for (i = 0; i < 2 * n_sysdep_strings; i++)
01163 {
01164 const struct sysdep_string *sysdep_string =
01165 (const struct sysdep_string *)
01166 ((char *) data
01167 + W (domain->must_swap,
01168 i < n_sysdep_strings
01169 ? orig_sysdep_tab[i]
01170 : trans_sysdep_tab[i - n_sysdep_strings]));
01171 const char *static_segments =
01172 (char *) data
01173 + W (domain->must_swap, sysdep_string->offset);
01174 const struct segment_pair *p = sysdep_string->segments;
01175
01176
01177
01178
01179
01180
01181 if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END)
01182 {
01183
01184 inmem_orig_sysdep_tab[i].length =
01185 W (domain->must_swap, p->segsize);
01186 inmem_orig_sysdep_tab[i].pointer = static_segments;
01187 }
01188 else
01189 {
01190 inmem_orig_sysdep_tab[i].pointer = mem;
01191
01192 for (p = sysdep_string->segments;; p++)
01193 {
01194 nls_uint32 segsize =
01195 W (domain->must_swap, p->segsize);
01196 nls_uint32 sysdepref =
01197 W (domain->must_swap, p->sysdepref);
01198 size_t n;
01199
01200 if (segsize > 0)
01201 {
01202 memcpy (mem, static_segments, segsize);
01203 mem += segsize;
01204 static_segments += segsize;
01205 }
01206
01207 if (sysdepref == SEGMENTS_END)
01208 break;
01209
01210 n = strlen (sysdep_segment_values[sysdepref]);
01211 memcpy (mem, sysdep_segment_values[sysdepref], n);
01212 mem += n;
01213 }
01214
01215 inmem_orig_sysdep_tab[i].length =
01216 mem - inmem_orig_sysdep_tab[i].pointer;
01217 }
01218 }
01219
01220
01221 for (i = 0; i < domain->hash_size; i++)
01222 inmem_hash_tab[i] =
01223 W (domain->must_swap_hash_tab, domain->hash_tab[i]);
01224 for (i = 0; i < n_sysdep_strings; i++)
01225 {
01226 const char *msgid = inmem_orig_sysdep_tab[i].pointer;
01227 nls_uint32 hash_val = hash_string (msgid);
01228 nls_uint32 idx = hash_val % domain->hash_size;
01229 nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
01230
01231 for (;;)
01232 {
01233 if (inmem_hash_tab[idx] == 0)
01234 {
01235
01236 inmem_hash_tab[idx] = 1 + domain->nstrings + i;
01237 break;
01238 }
01239
01240 if (idx >= domain->hash_size - incr)
01241 idx -= domain->hash_size - incr;
01242 else
01243 idx += incr;
01244 }
01245 }
01246
01247 freea (sysdep_segment_values);
01248
01249 domain->n_sysdep_strings = n_sysdep_strings;
01250 domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
01251 domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
01252
01253 domain->hash_tab = inmem_hash_tab;
01254 domain->must_swap_hash_tab = 0;
01255 }
01256 else
01257 {
01258 domain->n_sysdep_strings = 0;
01259 domain->orig_sysdep_tab = NULL;
01260 domain->trans_sysdep_tab = NULL;
01261 }
01262 }
01263 break;
01264 }
01265 break;
01266 default:
01267
01268 invalid:
01269
01270 if (domain->malloced)
01271 free (domain->malloced);
01272 #ifdef HAVE_MMAP
01273 if (use_mmap)
01274 munmap ((caddr_t) data, size);
01275 else
01276 #endif
01277 free (data);
01278 free (domain);
01279 domain_file->data = NULL;
01280 return;
01281 }
01282
01283
01284
01285
01286 nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);
01287
01288
01289 EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
01290 }
01291
01292
01293 #ifdef _LIBC
01294 void
01295 internal_function
01296 _nl_unload_domain (domain)
01297 struct loaded_domain *domain;
01298 {
01299 if (domain->plural != &__gettext_germanic_plural)
01300 __gettext_free_exp (domain->plural);
01301
01302 _nl_free_domain_conv (domain);
01303
01304 if (domain->malloced)
01305 free (domain->malloced);
01306
01307 # ifdef _POSIX_MAPPED_FILES
01308 if (domain->use_mmap)
01309 munmap ((caddr_t) domain->data, domain->mmap_size);
01310 else
01311 # endif
01312 free ((void *) domain->data);
01313
01314 free (domain);
01315 }
01316 #endif