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