home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / gettext / intl / loadmsgcat.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-18  |  35.7 KB  |  1,421 lines

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