You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

loadmsgcat.c 36KB

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