loadmsgcat.c 33 KB

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