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