Fix WS
[platform/upstream/glibc.git] / intl / dcigettext.c
1 /* Implementation of the internal dcigettext function.
2    Copyright (C) 1995-2005, 2006, 2007, 2008, 2009, 2011
3    Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* Tell glibc's <string.h> to provide a prototype for mempcpy().
22    This must come before <config.h> because <config.h> may include
23    <features.h>, and once <features.h> has been included, it's too late.  */
24 #ifndef _GNU_SOURCE
25 # define _GNU_SOURCE    1
26 #endif
27
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 #include <sys/types.h>
33
34 #ifdef __GNUC__
35 # define alloca __builtin_alloca
36 # define HAVE_ALLOCA 1
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
51 #include <errno.h>
52 #ifndef errno
53 extern int errno;
54 #endif
55 #ifndef __set_errno
56 # define __set_errno(val) errno = (val)
57 #endif
58
59 #include <stddef.h>
60 #include <stdlib.h>
61 #include <string.h>
62
63 #if defined HAVE_UNISTD_H || defined _LIBC
64 # include <unistd.h>
65 #endif
66
67 #include <locale.h>
68
69 #if defined HAVE_SYS_PARAM_H || defined _LIBC
70 # include <sys/param.h>
71 #endif
72
73 #include "gettextP.h"
74 #include "plural-exp.h"
75 #ifdef _LIBC
76 # include <libintl.h>
77 #else
78 # include "libgnuintl.h"
79 #endif
80 #include "hash-string.h"
81
82 /* Thread safetyness.  */
83 #ifdef _LIBC
84 # include <bits/libc-lock.h>
85 #else
86 /* Provide dummy implementation if this is outside glibc.  */
87 # define __libc_lock_define_initialized(CLASS, NAME)
88 # define __libc_lock_lock(NAME)
89 # define __libc_lock_unlock(NAME)
90 # define __libc_rwlock_define_initialized(CLASS, NAME)
91 # define __libc_rwlock_rdlock(NAME)
92 # define __libc_rwlock_unlock(NAME)
93 #endif
94
95 /* Alignment of types.  */
96 #if defined __GNUC__ && __GNUC__ >= 2
97 # define alignof(TYPE) __alignof__ (TYPE)
98 #else
99 # define alignof(TYPE) \
100     ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2)
101 #endif
102
103 /* The internal variables in the standalone libintl.a must have different
104    names than the internal variables in GNU libc, otherwise programs
105    using libintl.a cannot be linked statically.  */
106 #if !defined _LIBC
107 # define _nl_default_default_domain libintl_nl_default_default_domain
108 # define _nl_current_default_domain libintl_nl_current_default_domain
109 # define _nl_default_dirname libintl_nl_default_dirname
110 # define _nl_domain_bindings libintl_nl_domain_bindings
111 #endif
112
113 /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>.  */
114 #ifndef offsetof
115 # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
116 #endif
117
118 /* @@ end of prolog @@ */
119
120 #ifdef _LIBC
121 /* Rename the non ANSI C functions.  This is required by the standard
122    because some ANSI C functions will require linking with this object
123    file and the name space must not be polluted.  */
124 # define getcwd __getcwd
125 # ifndef stpcpy
126 #  define stpcpy __stpcpy
127 # endif
128 # define tfind __tfind
129 #else
130 # if !defined HAVE_GETCWD
131 char *getwd ();
132 #  define getcwd(buf, max) getwd (buf)
133 # else
134 char *getcwd ();
135 # endif
136 # ifndef HAVE_STPCPY
137 static char *stpcpy PARAMS ((char *dest, const char *src));
138 # endif
139 # ifndef HAVE_MEMPCPY
140 static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
141 # endif
142 #endif
143
144 /* Amount to increase buffer size by in each try.  */
145 #define PATH_INCR 32
146
147 /* The following is from pathmax.h.  */
148 /* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
149    PATH_MAX but might cause redefinition warnings when sys/param.h is
150    later included (as on MORE/BSD 4.3).  */
151 #if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__)
152 # include <limits.h>
153 #endif
154
155 #ifndef _POSIX_PATH_MAX
156 # define _POSIX_PATH_MAX 255
157 #endif
158
159 #if !defined PATH_MAX && defined _PC_PATH_MAX
160 # define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
161 #endif
162
163 /* Don't include sys/param.h if it already has been.  */
164 #if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
165 # include <sys/param.h>
166 #endif
167
168 #if !defined PATH_MAX && defined MAXPATHLEN
169 # define PATH_MAX MAXPATHLEN
170 #endif
171
172 #ifndef PATH_MAX
173 # define PATH_MAX _POSIX_PATH_MAX
174 #endif
175
176 /* Whether to support different locales in different threads.  */
177 #if defined _LIBC || HAVE_NL_LOCALE_NAME
178 # define HAVE_PER_THREAD_LOCALE
179 #endif
180
181 /* This is the type used for the search tree where known translations
182    are stored.  */
183 struct known_translation_t
184 {
185   /* Domain in which to search.  */
186   const char *domainname;
187
188   /* The category.  */
189   int category;
190
191 #ifdef HAVE_PER_THREAD_LOCALE
192   /* Name of the relevant locale category, or "" for the global locale.  */
193   const char *localename;
194 #endif
195
196   /* State of the catalog counter at the point the string was found.  */
197   int counter;
198
199   /* Catalog where the string was found.  */
200   struct loaded_l10nfile *domain;
201
202   /* And finally the translation.  */
203   const char *translation;
204   size_t translation_length;
205
206   /* Pointer to the string in question.  */
207   union
208     {
209       char appended[ZERO];  /* used if domain != NULL */
210       const char *ptr;      /* used if domain == NULL */
211     }
212   msgid;
213 };
214
215 /* Root of the search tree with known translations.  We can use this
216    only if the system provides the `tsearch' function family.  */
217 #if defined HAVE_TSEARCH || defined _LIBC
218 # include <search.h>
219
220 static void *root;
221
222 # ifdef _LIBC
223 #  define tsearch __tsearch
224 # endif
225
226 /* Function to compare two entries in the table of known translations.  */
227 static int transcmp PARAMS ((const void *p1, const void *p2));
228 static int
229 transcmp (p1, p2)
230      const void *p1;
231      const void *p2;
232 {
233   const struct known_translation_t *s1;
234   const struct known_translation_t *s2;
235   int result;
236
237   s1 = (const struct known_translation_t *) p1;
238   s2 = (const struct known_translation_t *) p2;
239
240   result = strcmp (s1->domain != NULL ? s1->msgid.appended : s1->msgid.ptr,
241                    s2->domain != NULL ? s2->msgid.appended : s2->msgid.ptr);
242   if (result == 0)
243     {
244       result = strcmp (s1->domainname, s2->domainname);
245       if (result == 0)
246         {
247 #ifdef HAVE_PER_THREAD_LOCALE
248           result = strcmp (s1->localename, s2->localename);
249           if (result == 0)
250 #endif
251             /* We compare the category last (though this is the cheapest
252                operation) since it is hopefully always the same (namely
253                LC_MESSAGES).  */
254             result = s1->category - s2->category;
255         }
256     }
257
258   return result;
259 }
260 #endif
261
262 /* Name of the default domain used for gettext(3) prior any call to
263    textdomain(3).  The default value for this is "messages".  */
264 const char _nl_default_default_domain[] attribute_hidden = "messages";
265
266 /* Value used as the default domain for gettext(3).  */
267 const char *_nl_current_default_domain attribute_hidden
268      = _nl_default_default_domain;
269
270 /* Contains the default location of the message catalogs.  */
271
272 #ifdef _LIBC
273 extern const char _nl_default_dirname[];
274 libc_hidden_proto (_nl_default_dirname)
275 #endif
276 const char _nl_default_dirname[] = LOCALEDIR;
277 #ifdef _LIBC
278 libc_hidden_data_def (_nl_default_dirname)
279 #endif
280
281 /* List with bindings of specific domains created by bindtextdomain()
282    calls.  */
283 struct binding *_nl_domain_bindings;
284
285 /* Prototypes for local functions.  */
286 static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain,
287                                     unsigned long int n,
288                                     const char *translation,
289                                     size_t translation_len))
290      internal_function;
291 static const char *guess_category_value PARAMS ((int category,
292                                                  const char *categoryname))
293      internal_function;
294 #ifdef _LIBC
295 # include "../locale/localeinfo.h"
296 # define category_to_name(category) \
297   _nl_category_names.str + _nl_category_name_idxs[category]
298 #else
299 static const char *category_to_name PARAMS ((int category)) internal_function;
300 #endif
301
302
303 /* For those loosing systems which don't have `alloca' we have to add
304    some additional code emulating it.  */
305 #ifdef HAVE_ALLOCA
306 /* Nothing has to be done.  */
307 # define freea(p) /* nothing */
308 # define ADD_BLOCK(list, address) /* nothing */
309 # define FREE_BLOCKS(list) /* nothing */
310 #else
311 struct block_list
312 {
313   void *address;
314   struct block_list *next;
315 };
316 # define ADD_BLOCK(list, addr)                                                \
317   do {                                                                        \
318     struct block_list *newp = (struct block_list *) malloc (sizeof (*newp));  \
319     /* If we cannot get a free block we cannot add the new element to         \
320        the list.  */                                                          \
321     if (newp != NULL) {                                                       \
322       newp->address = (addr);                                                 \
323       newp->next = (list);                                                    \
324       (list) = newp;                                                          \
325     }                                                                         \
326   } while (0)
327 # define FREE_BLOCKS(list)                                                    \
328   do {                                                                        \
329     while (list != NULL) {                                                    \
330       struct block_list *old = list;                                          \
331       list = list->next;                                                      \
332       free (old->address);                                                    \
333       free (old);                                                             \
334     }                                                                         \
335   } while (0)
336 # undef alloca
337 # define alloca(size) (malloc (size))
338 # define freea(p) free (p)
339 #endif  /* have alloca */
340
341
342 #ifdef _LIBC
343 /* List of blocks allocated for translations.  */
344 typedef struct transmem_list
345 {
346   struct transmem_list *next;
347   char data[ZERO];
348 } transmem_block_t;
349 static struct transmem_list *transmem_list;
350 #else
351 typedef unsigned char transmem_block_t;
352 #endif
353 #if defined _LIBC || HAVE_ICONV
354 static const char *get_output_charset PARAMS ((struct binding *domainbinding))
355      internal_function;
356 #endif
357
358
359 /* Names for the libintl functions are a problem.  They must not clash
360    with existing names and they should follow ANSI C.  But this source
361    code is also used in GNU C Library where the names have a __
362    prefix.  So we have to make a difference here.  */
363 #ifdef _LIBC
364 # define DCIGETTEXT __dcigettext
365 #else
366 # define DCIGETTEXT libintl_dcigettext
367 #endif
368
369 /* Lock variable to protect the global data in the gettext implementation.  */
370 #ifdef _LIBC
371 __libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
372 #endif
373
374 /* Checking whether the binaries runs SUID must be done and glibc provides
375    easier methods therefore we make a difference here.  */
376 #ifdef _LIBC
377 # define ENABLE_SECURE __libc_enable_secure
378 # define DETERMINE_SECURE
379 #else
380 # ifndef HAVE_GETUID
381 #  define getuid() 0
382 # endif
383 # ifndef HAVE_GETGID
384 #  define getgid() 0
385 # endif
386 # ifndef HAVE_GETEUID
387 #  define geteuid() getuid()
388 # endif
389 # ifndef HAVE_GETEGID
390 #  define getegid() getgid()
391 # endif
392 static int enable_secure;
393 # define ENABLE_SECURE (enable_secure == 1)
394 # define DETERMINE_SECURE \
395   if (enable_secure == 0)                                                     \
396     {                                                                         \
397       if (getuid () != geteuid () || getgid () != getegid ())                 \
398         enable_secure = 1;                                                    \
399       else                                                                    \
400         enable_secure = -1;                                                   \
401     }
402 #endif
403
404 /* Get the function to evaluate the plural expression.  */
405 #include "plural-eval.c"
406
407 /* Look up MSGID in the DOMAINNAME message catalog for the current
408    CATEGORY locale and, if PLURAL is nonzero, search over string
409    depending on the plural form determined by N.  */
410 char *
411 DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
412      const char *domainname;
413      const char *msgid1;
414      const char *msgid2;
415      int plural;
416      unsigned long int n;
417      int category;
418 {
419 #ifndef HAVE_ALLOCA
420   struct block_list *block_list = NULL;
421 #endif
422   struct loaded_l10nfile *domain;
423   struct binding *binding;
424   const char *categoryname;
425   const char *categoryvalue;
426   char *dirname, *xdomainname;
427   char *single_locale;
428   char *retval;
429   size_t retlen;
430   int saved_errno;
431 #if defined HAVE_TSEARCH || defined _LIBC
432   struct known_translation_t search;
433   struct known_translation_t **foundp = NULL;
434 # ifdef HAVE_PER_THREAD_LOCALE
435   const char *localename;
436 # endif
437 #endif
438   size_t domainname_len;
439
440   /* If no real MSGID is given return NULL.  */
441   if (msgid1 == NULL)
442     return NULL;
443
444 #ifdef _LIBC
445   if (category < 0 || category >= __LC_LAST || category == LC_ALL)
446     /* Bogus.  */
447     return (plural == 0
448             ? (char *) msgid1
449             /* Use the Germanic plural rule.  */
450             : n == 1 ? (char *) msgid1 : (char *) msgid2);
451 #endif
452
453 #ifdef _LIBC
454   __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
455   __libc_rwlock_rdlock (__libc_setlocale_lock);
456 #endif
457
458   __libc_rwlock_rdlock (_nl_state_lock);
459
460   /* If DOMAINNAME is NULL, we are interested in the default domain.  If
461      CATEGORY is not LC_MESSAGES this might not make much sense but the
462      definition left this undefined.  */
463   if (domainname == NULL)
464     domainname = _nl_current_default_domain;
465
466 #if defined HAVE_TSEARCH || defined _LIBC
467   /* Try to find the translation among those which we found at
468      some time.  */
469   search.domain = NULL;
470   search.msgid.ptr = msgid1;
471   search.domainname = domainname;
472   search.category = category;
473 # ifdef HAVE_PER_THREAD_LOCALE
474 #  ifdef _LIBC
475   localename = strdupa (__current_locale_name (category));
476 #  endif
477   search.localename = localename;
478 # endif
479
480   /* Since tfind/tsearch manage a balanced tree, concurrent tfind and
481      tsearch calls can be fatal.  */
482   __libc_rwlock_define_initialized (static, tree_lock);
483   __libc_rwlock_rdlock (tree_lock);
484
485   foundp = (struct known_translation_t **) tfind (&search, &root, transcmp);
486
487   __libc_rwlock_unlock (tree_lock);
488
489   if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
490     {
491       /* Now deal with plural.  */
492       if (plural)
493         retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation,
494                                 (*foundp)->translation_length);
495       else
496         retval = (char *) (*foundp)->translation;
497
498 # ifdef _LIBC
499       __libc_rwlock_unlock (__libc_setlocale_lock);
500 # endif
501       __libc_rwlock_unlock (_nl_state_lock);
502       return retval;
503     }
504 #endif
505
506   /* Preserve the `errno' value.  */
507   saved_errno = errno;
508
509   /* See whether this is a SUID binary or not.  */
510   DETERMINE_SECURE;
511
512   /* First find matching binding.  */
513   for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
514     {
515       int compare = strcmp (domainname, binding->domainname);
516       if (compare == 0)
517         /* We found it!  */
518         break;
519       if (compare < 0)
520         {
521           /* It is not in the list.  */
522           binding = NULL;
523           break;
524         }
525     }
526
527   if (binding == NULL)
528     dirname = (char *) _nl_default_dirname;
529   else if (binding->dirname[0] == '/')
530     dirname = binding->dirname;
531   else
532     {
533       /* We have a relative path.  Make it absolute now.  */
534       size_t dirname_len = strlen (binding->dirname) + 1;
535       size_t path_max;
536       char *ret;
537
538       path_max = (unsigned int) PATH_MAX;
539       path_max += 2;            /* The getcwd docs say to do this.  */
540
541       for (;;)
542         {
543           dirname = (char *) alloca (path_max + dirname_len);
544           ADD_BLOCK (block_list, dirname);
545
546           __set_errno (0);
547           ret = getcwd (dirname, path_max);
548           if (ret != NULL || errno != ERANGE)
549             break;
550
551           path_max += path_max / 2;
552           path_max += PATH_INCR;
553         }
554
555       if (ret == NULL)
556         goto no_translation;
557
558       stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
559     }
560
561   /* Now determine the symbolic name of CATEGORY and its value.  */
562   categoryname = category_to_name (category);
563   categoryvalue = guess_category_value (category, categoryname);
564
565   domainname_len = strlen (domainname);
566   xdomainname = (char *) alloca (strlen (categoryname)
567                                  + domainname_len + 5);
568   ADD_BLOCK (block_list, xdomainname);
569
570   stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
571                   domainname, domainname_len),
572           ".mo");
573
574   /* Creating working area.  */
575   single_locale = (char *) alloca (strlen (categoryvalue) + 1);
576   ADD_BLOCK (block_list, single_locale);
577
578
579   /* Search for the given string.  This is a loop because we perhaps
580      got an ordered list of languages to consider for the translation.  */
581   while (1)
582     {
583       /* Make CATEGORYVALUE point to the next element of the list.  */
584       while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
585         ++categoryvalue;
586       if (categoryvalue[0] == '\0')
587         {
588           /* The whole contents of CATEGORYVALUE has been searched but
589              no valid entry has been found.  We solve this situation
590              by implicitly appending a "C" entry, i.e. no translation
591              will take place.  */
592           single_locale[0] = 'C';
593           single_locale[1] = '\0';
594         }
595       else
596         {
597           char *cp = single_locale;
598           while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
599             *cp++ = *categoryvalue++;
600           *cp = '\0';
601
602           /* When this is a SUID binary we must not allow accessing files
603              outside the dedicated directories.  */
604           if (ENABLE_SECURE && strchr (single_locale, '/') != NULL)
605             /* Ingore this entry.  */
606             continue;
607         }
608
609       /* If the current locale value is C (or POSIX) we don't load a
610          domain.  Return the MSGID.  */
611       if (strcmp (single_locale, "C") == 0
612           || strcmp (single_locale, "POSIX") == 0)
613         {
614         no_translation:
615           FREE_BLOCKS (block_list);
616           __libc_rwlock_unlock (__libc_setlocale_lock);
617           __libc_rwlock_unlock (_nl_state_lock);
618           __set_errno (saved_errno);
619           return (plural == 0
620                   ? (char *) msgid1
621                   /* Use the Germanic plural rule.  */
622                   : n == 1 ? (char *) msgid1 : (char *) msgid2);
623         }
624
625
626       /* Find structure describing the message catalog matching the
627          DOMAINNAME and CATEGORY.  */
628       domain = _nl_find_domain (dirname, single_locale, xdomainname, binding);
629
630       if (domain != NULL)
631         {
632           retval = _nl_find_msg (domain, binding, msgid1, 1, &retlen);
633
634           if (retval == NULL)
635             {
636               int cnt;
637
638               for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
639                 {
640                   retval = _nl_find_msg (domain->successor[cnt], binding,
641                                          msgid1, 1, &retlen);
642
643                   if (retval != NULL)
644                     {
645                       domain = domain->successor[cnt];
646                       break;
647                     }
648                 }
649             }
650
651           /* Returning -1 means that some resource problem exists
652              (likely memory) and that the strings could not be
653              converted.  Return the original strings.  */
654           if (__builtin_expect (retval == (char *) -1, 0))
655             goto no_translation;
656
657           if (retval != NULL)
658             {
659               /* Found the translation of MSGID1 in domain DOMAIN:
660                  starting at RETVAL, RETLEN bytes.  */
661               FREE_BLOCKS (block_list);
662 #if defined HAVE_TSEARCH || defined _LIBC
663               if (foundp == NULL)
664                 {
665                   /* Create a new entry and add it to the search tree.  */
666                   size_t msgid_len;
667                   size_t size;
668                   struct known_translation_t *newp;
669
670                   msgid_len = strlen (msgid1) + 1;
671                   size = offsetof (struct known_translation_t, msgid)
672                          + msgid_len + domainname_len + 1;
673 # ifdef HAVE_PER_THREAD_LOCALE
674                   size += strlen (localename) + 1;
675 # endif
676                   newp = (struct known_translation_t *) malloc (size);
677                   if (newp != NULL)
678                     {
679                       char *new_domainname;
680 # ifdef HAVE_PER_THREAD_LOCALE
681                       char *new_localename;
682 # endif
683
684                       new_domainname =
685                         mempcpy (newp->msgid.appended, msgid1, msgid_len);
686                       memcpy (new_domainname, domainname, domainname_len + 1);
687 # ifdef HAVE_PER_THREAD_LOCALE
688                       new_localename = new_domainname + domainname_len + 1;
689                       strcpy (new_localename, localename);
690 # endif
691                       newp->domainname = new_domainname;
692                       newp->category = category;
693 # ifdef HAVE_PER_THREAD_LOCALE
694                       newp->localename = new_localename;
695 # endif
696                       newp->counter = _nl_msg_cat_cntr;
697                       newp->domain = domain;
698                       newp->translation = retval;
699                       newp->translation_length = retlen;
700
701                       __libc_rwlock_wrlock (tree_lock);
702
703                       /* Insert the entry in the search tree.  */
704                       foundp = (struct known_translation_t **)
705                         tsearch (newp, &root, transcmp);
706
707                       __libc_rwlock_unlock (tree_lock);
708
709                       if (foundp == NULL
710                           || __builtin_expect (*foundp != newp, 0))
711                         /* The insert failed.  */
712                         free (newp);
713                     }
714                 }
715               else
716                 {
717                   /* We can update the existing entry.  */
718                   (*foundp)->counter = _nl_msg_cat_cntr;
719                   (*foundp)->domain = domain;
720                   (*foundp)->translation = retval;
721                   (*foundp)->translation_length = retlen;
722                 }
723 #endif
724               __set_errno (saved_errno);
725
726               /* Now deal with plural.  */
727               if (plural)
728                 retval = plural_lookup (domain, n, retval, retlen);
729
730               __libc_rwlock_unlock (__libc_setlocale_lock);
731               __libc_rwlock_unlock (_nl_state_lock);
732               return retval;
733             }
734         }
735     }
736   /* NOTREACHED */
737 }
738
739
740 char *
741 internal_function
742 _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
743      struct loaded_l10nfile *domain_file;
744      struct binding *domainbinding;
745      const char *msgid;
746      int convert;
747      size_t *lengthp;
748 {
749   struct loaded_domain *domain;
750   nls_uint32 nstrings;
751   size_t act;
752   char *result;
753   size_t resultlen;
754
755   if (domain_file->decided <= 0)
756     _nl_load_domain (domain_file, domainbinding);
757
758   if (domain_file->data == NULL)
759     return NULL;
760
761   domain = (struct loaded_domain *) domain_file->data;
762
763   nstrings = domain->nstrings;
764
765   /* Locate the MSGID and its translation.  */
766   if (domain->hash_tab != NULL)
767     {
768       /* Use the hashing table.  */
769       nls_uint32 len = strlen (msgid);
770       nls_uint32 hash_val = __hash_string (msgid);
771       nls_uint32 idx = hash_val % domain->hash_size;
772       nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
773
774       while (1)
775         {
776           nls_uint32 nstr =
777             W (domain->must_swap_hash_tab, domain->hash_tab[idx]);
778
779           if (nstr == 0)
780             /* Hash table entry is empty.  */
781             return NULL;
782
783           nstr--;
784
785           /* Compare msgid with the original string at index nstr.
786              We compare the lengths with >=, not ==, because plural entries
787              are represented by strings with an embedded NUL.  */
788           if (nstr < nstrings
789               ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len
790                 && (strcmp (msgid,
791                             domain->data + W (domain->must_swap,
792                                               domain->orig_tab[nstr].offset))
793                     == 0)
794               : domain->orig_sysdep_tab[nstr - nstrings].length > len
795                 && (strcmp (msgid,
796                             domain->orig_sysdep_tab[nstr - nstrings].pointer)
797                     == 0))
798             {
799               act = nstr;
800               goto found;
801             }
802
803           if (idx >= domain->hash_size - incr)
804             idx -= domain->hash_size - incr;
805           else
806             idx += incr;
807         }
808       /* NOTREACHED */
809     }
810   else
811     {
812       /* Try the default method:  binary search in the sorted array of
813          messages.  */
814       size_t top, bottom;
815
816       bottom = 0;
817       top = nstrings;
818       while (bottom < top)
819         {
820           int cmp_val;
821
822           act = (bottom + top) / 2;
823           cmp_val = strcmp (msgid, (domain->data
824                                     + W (domain->must_swap,
825                                          domain->orig_tab[act].offset)));
826           if (cmp_val < 0)
827             top = act;
828           else if (cmp_val > 0)
829             bottom = act + 1;
830           else
831             goto found;
832         }
833       /* No translation was found.  */
834       return NULL;
835     }
836
837  found:
838   /* The translation was found at index ACT.  If we have to convert the
839      string to use a different character set, this is the time.  */
840   if (act < nstrings)
841     {
842       result = (char *)
843         (domain->data + W (domain->must_swap, domain->trans_tab[act].offset));
844       resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1;
845     }
846   else
847     {
848       result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer;
849       resultlen = domain->trans_sysdep_tab[act - nstrings].length;
850     }
851
852 #if defined _LIBC || HAVE_ICONV
853   if (convert)
854     {
855       /* We are supposed to do a conversion.  */
856       const char *encoding = get_output_charset (domainbinding);
857
858       /* Protect against reallocation of the table.  */
859       __libc_rwlock_rdlock (domain->conversions_lock);
860
861       /* Search whether a table with converted translations for this
862          encoding has already been allocated.  */
863       size_t nconversions = domain->nconversions;
864       struct converted_domain *convd = NULL;
865       size_t i;
866
867       for (i = nconversions; i > 0; )
868         {
869           i--;
870           if (strcmp (domain->conversions[i].encoding, encoding) == 0)
871             {
872               convd = &domain->conversions[i];
873               break;
874             }
875         }
876
877       __libc_rwlock_unlock (domain->conversions_lock);
878
879       if (convd == NULL)
880         {
881           /* We have to allocate a new conversions table.  */
882           __libc_rwlock_wrlock (domain->conversions_lock);
883           nconversions = domain->nconversions;
884
885           /* Maybe in the meantime somebody added the translation.
886              Recheck.  */
887           for (i = nconversions; i > 0; )
888             {
889               i--;
890               if (strcmp (domain->conversions[i].encoding, encoding) == 0)
891                 {
892                   convd = &domain->conversions[i];
893                   goto found_convd;
894                 }
895             }
896
897           /* Allocate a table for the converted translations for this
898              encoding.  */
899           struct converted_domain *new_conversions =
900             (struct converted_domain *)
901             realloc (domain->conversions,
902                      (nconversions + 1) * sizeof (struct converted_domain));
903
904           if (__builtin_expect (new_conversions == NULL, 0))
905             {
906               /* Nothing we can do, no more memory.  We cannot use the
907                  translation because it might be encoded incorrectly.  */
908             unlock_fail:
909               __libc_rwlock_unlock (domain->conversions_lock);
910               return (char *) -1;
911             }
912
913           domain->conversions = new_conversions;
914
915           /* Copy the 'encoding' string to permanent storage.  */
916           encoding = strdup (encoding);
917           if (__builtin_expect (encoding == NULL, 0))
918             /* Nothing we can do, no more memory.  We cannot use the
919                translation because it might be encoded incorrectly.  */
920             goto unlock_fail;
921
922           convd = &new_conversions[nconversions];
923           convd->encoding = encoding;
924
925           /* Find out about the character set the file is encoded with.
926              This can be found (in textual form) in the entry "".  If this
927              entry does not exist or if this does not contain the 'charset='
928              information, we will assume the charset matches the one the
929              current locale and we don't have to perform any conversion.  */
930 # ifdef _LIBC
931           convd->conv = (__gconv_t) -1;
932 # else
933 #  if HAVE_ICONV
934           convd->conv = (iconv_t) -1;
935 #  endif
936 # endif
937           {
938             char *nullentry;
939             size_t nullentrylen;
940
941             /* Get the header entry.  This is a recursion, but it doesn't
942                reallocate domain->conversions because we pass convert = 0.  */
943             nullentry =
944               _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
945
946             if (nullentry != NULL)
947               {
948                 const char *charsetstr;
949
950                 charsetstr = strstr (nullentry, "charset=");
951                 if (charsetstr != NULL)
952                   {
953                     size_t len;
954                     char *charset;
955                     const char *outcharset;
956
957                     charsetstr += strlen ("charset=");
958                     len = strcspn (charsetstr, " \t\n");
959
960                     charset = (char *) alloca (len + 1);
961 # if defined _LIBC || HAVE_MEMPCPY
962                     *((char *) mempcpy (charset, charsetstr, len)) = '\0';
963 # else
964                     memcpy (charset, charsetstr, len);
965                     charset[len] = '\0';
966 # endif
967
968                     outcharset = encoding;
969
970 # ifdef _LIBC
971                     /* We always want to use transliteration.  */
972                     outcharset = norm_add_slashes (outcharset, "TRANSLIT");
973                     charset = norm_add_slashes (charset, "");
974                     int r = __gconv_open (outcharset, charset, &convd->conv,
975                                           GCONV_AVOID_NOCONV);
976                     if (__builtin_expect (r != __GCONV_OK, 0))
977                       {
978                         /* If the output encoding is the same there is
979                            nothing to do.  Otherwise do not use the
980                            translation at all.  */
981                         if (__builtin_expect (r != __GCONV_NULCONV, 1))
982                           {
983                             __libc_rwlock_unlock (domain->conversions_lock);
984                             free ((char *) encoding);
985                             return NULL;
986                           }
987
988                         convd->conv = (__gconv_t) -1;
989                       }
990 # else
991 #  if HAVE_ICONV
992                     /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
993                        we want to use transliteration.  */
994 #   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
995        || _LIBICONV_VERSION >= 0x0105
996                     if (strchr (outcharset, '/') == NULL)
997                       {
998                         char *tmp;
999
1000                         len = strlen (outcharset);
1001                         tmp = (char *) alloca (len + 10 + 1);
1002                         memcpy (tmp, outcharset, len);
1003                         memcpy (tmp + len, "//TRANSLIT", 10 + 1);
1004                         outcharset = tmp;
1005
1006                         convd->conv = iconv_open (outcharset, charset);
1007
1008                         freea (outcharset);
1009                       }
1010                     else
1011 #   endif
1012                       convd->conv = iconv_open (outcharset, charset);
1013 #  endif
1014 # endif
1015
1016                     freea (charset);
1017                   }
1018               }
1019           }
1020           convd->conv_tab = NULL;
1021           /* Here domain->conversions is still == new_conversions.  */
1022           domain->nconversions++;
1023
1024         found_convd:
1025           __libc_rwlock_unlock (domain->conversions_lock);
1026         }
1027
1028       if (
1029 # ifdef _LIBC
1030           convd->conv != (__gconv_t) -1
1031 # else
1032 #  if HAVE_ICONV
1033           convd->conv != (iconv_t) -1
1034 #  endif
1035 # endif
1036           )
1037         {
1038           __libc_lock_define_initialized (static, lock)
1039           /* We are supposed to do a conversion.  First allocate an
1040              appropriate table with the same structure as the table
1041              of translations in the file, where we can put the pointers
1042              to the converted strings in.
1043              There is a slight complication with plural entries.  They
1044              are represented by consecutive NUL terminated strings.  We
1045              handle this case by converting RESULTLEN bytes, including
1046              NULs.  */
1047
1048           if (__builtin_expect (convd->conv_tab == NULL, 0))
1049             {
1050               __libc_lock_lock (lock);
1051               if (convd->conv_tab == NULL)
1052                 {
1053                   convd->conv_tab
1054                     = calloc (nstrings + domain->n_sysdep_strings,
1055                               sizeof (char *));
1056                   if (convd->conv_tab != NULL)
1057                     goto not_translated_yet;
1058                   /* Mark that we didn't succeed allocating a table.  */
1059                   convd->conv_tab = (char **) -1;
1060                 }
1061               __libc_lock_unlock (lock);
1062             }
1063
1064           if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
1065             /* Nothing we can do, no more memory.  We cannot use the
1066                translation because it might be encoded incorrectly.  */
1067             return (char *) -1;
1068
1069           if (convd->conv_tab[act] == NULL)
1070             {
1071               __libc_lock_lock (lock);
1072             not_translated_yet:;
1073
1074               /* We haven't used this string so far, so it is not
1075                  translated yet.  Do this now.  */
1076               /* We use a bit more efficient memory handling.
1077                  We allocate always larger blocks which get used over
1078                  time.  This is faster than many small allocations.   */
1079 # define INITIAL_BLOCK_SIZE     4080
1080               static unsigned char *freemem;
1081               static size_t freemem_size;
1082
1083               const unsigned char *inbuf;
1084               unsigned char *outbuf;
1085               int malloc_count;
1086 # ifndef _LIBC
1087               transmem_block_t *transmem_list = NULL;
1088 # endif
1089
1090               inbuf = (const unsigned char *) result;
1091               outbuf = freemem + sizeof (size_t);
1092
1093               malloc_count = 0;
1094               while (1)
1095                 {
1096                   transmem_block_t *newmem;
1097 # ifdef _LIBC
1098                   size_t non_reversible;
1099                   int res;
1100
1101                   if (freemem_size < sizeof (size_t))
1102                     goto resize_freemem;
1103
1104                   res = __gconv (convd->conv,
1105                                  &inbuf, inbuf + resultlen,
1106                                  &outbuf,
1107                                  outbuf + freemem_size - sizeof (size_t),
1108                                  &non_reversible);
1109
1110                   if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT)
1111                     break;
1112
1113                   if (res != __GCONV_FULL_OUTPUT)
1114                     {
1115                       /* We should not use the translation at all, it
1116                          is incorrectly encoded.  */
1117                       __libc_lock_unlock (lock);
1118                       return NULL;
1119                     }
1120
1121                   inbuf = (const unsigned char *) result;
1122 # else
1123 #  if HAVE_ICONV
1124                   const char *inptr = (const char *) inbuf;
1125                   size_t inleft = resultlen;
1126                   char *outptr = (char *) outbuf;
1127                   size_t outleft;
1128
1129                   if (freemem_size < sizeof (size_t))
1130                     goto resize_freemem;
1131
1132                   outleft = freemem_size - sizeof (size_t);
1133                   if (iconv (convd->conv,
1134                              (ICONV_CONST char **) &inptr, &inleft,
1135                              &outptr, &outleft)
1136                       != (size_t) (-1))
1137                     {
1138                       outbuf = (unsigned char *) outptr;
1139                       break;
1140                     }
1141                   if (errno != E2BIG)
1142                     {
1143                       __libc_lock_unlock (lock);
1144                       return NULL;
1145                     }
1146 #  endif
1147 # endif
1148
1149                 resize_freemem:
1150                   /* We must allocate a new buffer or resize the old one.  */
1151                   if (malloc_count > 0)
1152                     {
1153                       ++malloc_count;
1154                       freemem_size = malloc_count * INITIAL_BLOCK_SIZE;
1155                       newmem = (transmem_block_t *) realloc (transmem_list,
1156                                                              freemem_size);
1157 # ifdef _LIBC
1158                       if (newmem != NULL)
1159                         transmem_list = transmem_list->next;
1160                       else
1161                         {
1162                           struct transmem_list *old = transmem_list;
1163
1164                           transmem_list = transmem_list->next;
1165                           free (old);
1166                         }
1167 # endif
1168                     }
1169                   else
1170                     {
1171                       malloc_count = 1;
1172                       freemem_size = INITIAL_BLOCK_SIZE;
1173                       newmem = (transmem_block_t *) malloc (freemem_size);
1174                     }
1175                   if (__builtin_expect (newmem == NULL, 0))
1176                     {
1177                       freemem = NULL;
1178                       freemem_size = 0;
1179                       __libc_lock_unlock (lock);
1180                       return (char *) -1;
1181                     }
1182
1183 # ifdef _LIBC
1184                   /* Add the block to the list of blocks we have to free
1185                      at some point.  */
1186                   newmem->next = transmem_list;
1187                   transmem_list = newmem;
1188
1189                   freemem = (unsigned char *) newmem->data;
1190                   freemem_size -= offsetof (struct transmem_list, data);
1191 # else
1192                   transmem_list = newmem;
1193                   freemem = newmem;
1194 # endif
1195
1196                   outbuf = freemem + sizeof (size_t);
1197                 }
1198
1199               /* We have now in our buffer a converted string.  Put this
1200                  into the table of conversions.  */
1201               *(size_t *) freemem = outbuf - freemem - sizeof (size_t);
1202               convd->conv_tab[act] = (char *) freemem;
1203               /* Shrink freemem, but keep it aligned.  */
1204               freemem_size -= outbuf - freemem;
1205               freemem = outbuf;
1206               freemem += freemem_size & (alignof (size_t) - 1);
1207               freemem_size = freemem_size & ~ (alignof (size_t) - 1);
1208
1209               __libc_lock_unlock (lock);
1210             }
1211
1212           /* Now convd->conv_tab[act] contains the translation of all
1213              the plural variants.  */
1214           result = convd->conv_tab[act] + sizeof (size_t);
1215           resultlen = *(size_t *) convd->conv_tab[act];
1216         }
1217     }
1218
1219   /* The result string is converted.  */
1220
1221 #endif /* _LIBC || HAVE_ICONV */
1222
1223   *lengthp = resultlen;
1224   return result;
1225 }
1226
1227
1228 /* Look up a plural variant.  */
1229 static char *
1230 internal_function
1231 plural_lookup (domain, n, translation, translation_len)
1232      struct loaded_l10nfile *domain;
1233      unsigned long int n;
1234      const char *translation;
1235      size_t translation_len;
1236 {
1237   struct loaded_domain *domaindata = (struct loaded_domain *) domain->data;
1238   unsigned long int index;
1239   const char *p;
1240
1241   index = plural_eval (domaindata->plural, n);
1242   if (index >= domaindata->nplurals)
1243     /* This should never happen.  It means the plural expression and the
1244        given maximum value do not match.  */
1245     index = 0;
1246
1247   /* Skip INDEX strings at TRANSLATION.  */
1248   p = translation;
1249   while (index-- > 0)
1250     {
1251 #ifdef _LIBC
1252       p = __rawmemchr (p, '\0');
1253 #else
1254       p = strchr (p, '\0');
1255 #endif
1256       /* And skip over the NUL byte.  */
1257       p++;
1258
1259       if (p >= translation + translation_len)
1260         /* This should never happen.  It means the plural expression
1261            evaluated to a value larger than the number of variants
1262            available for MSGID1.  */
1263         return (char *) translation;
1264     }
1265   return (char *) p;
1266 }
1267
1268 #ifndef _LIBC
1269 /* Return string representation of locale CATEGORY.  */
1270 static const char *
1271 internal_function
1272 category_to_name (category)
1273      int category;
1274 {
1275   const char *retval;
1276
1277   switch (category)
1278   {
1279 #ifdef LC_COLLATE
1280   case LC_COLLATE:
1281     retval = "LC_COLLATE";
1282     break;
1283 #endif
1284 #ifdef LC_CTYPE
1285   case LC_CTYPE:
1286     retval = "LC_CTYPE";
1287     break;
1288 #endif
1289 #ifdef LC_MONETARY
1290   case LC_MONETARY:
1291     retval = "LC_MONETARY";
1292     break;
1293 #endif
1294 #ifdef LC_NUMERIC
1295   case LC_NUMERIC:
1296     retval = "LC_NUMERIC";
1297     break;
1298 #endif
1299 #ifdef LC_TIME
1300   case LC_TIME:
1301     retval = "LC_TIME";
1302     break;
1303 #endif
1304 #ifdef LC_MESSAGES
1305   case LC_MESSAGES:
1306     retval = "LC_MESSAGES";
1307     break;
1308 #endif
1309 #ifdef LC_RESPONSE
1310   case LC_RESPONSE:
1311     retval = "LC_RESPONSE";
1312     break;
1313 #endif
1314 #ifdef LC_ALL
1315   case LC_ALL:
1316     /* This might not make sense but is perhaps better than any other
1317        value.  */
1318     retval = "LC_ALL";
1319     break;
1320 #endif
1321   default:
1322     /* If you have a better idea for a default value let me know.  */
1323     retval = "LC_XXX";
1324   }
1325
1326   return retval;
1327 }
1328 #endif
1329
1330 /* Guess value of current locale from value of the environment variables.  */
1331 static const char *
1332 internal_function
1333 guess_category_value (category, categoryname)
1334      int category;
1335      const char *categoryname;
1336 {
1337   const char *language;
1338   const char *retval;
1339
1340   /* The highest priority value is the `LANGUAGE' environment
1341      variable.  But we don't use the value if the currently selected
1342      locale is the C locale.  This is a GNU extension.  */
1343   language = getenv ("LANGUAGE");
1344   if (language != NULL && language[0] == '\0')
1345     language = NULL;
1346
1347   /* We have to proceed with the POSIX methods of looking to `LC_ALL',
1348      `LC_xxx', and `LANG'.  On some systems this can be done by the
1349      `setlocale' function itself.  */
1350 #ifdef _LIBC
1351   retval = __current_locale_name (category);
1352 #else
1353   retval = _nl_locale_name (category, categoryname);
1354 #endif
1355
1356   return language != NULL && strcmp (retval, "C") != 0 ? language : retval;
1357 }
1358
1359 #if defined _LIBC || HAVE_ICONV
1360 /* Returns the output charset.  */
1361 static const char *
1362 internal_function
1363 get_output_charset (domainbinding)
1364      struct binding *domainbinding;
1365 {
1366   /* The output charset should normally be determined by the locale.  But
1367      sometimes the locale is not used or not correctly set up, so we provide
1368      a possibility for the user to override this: the OUTPUT_CHARSET
1369      environment variable.  Moreover, the value specified through
1370      bind_textdomain_codeset overrides both.  */
1371   if (domainbinding != NULL && domainbinding->codeset != NULL)
1372     return domainbinding->codeset;
1373   else
1374     {
1375       /* For speed reasons, we look at the value of OUTPUT_CHARSET only
1376          once.  This is a user variable that is not supposed to change
1377          during a program run.  */
1378       static char *output_charset_cache;
1379       static int output_charset_cached;
1380
1381       if (!output_charset_cached)
1382         {
1383           const char *value = getenv ("OUTPUT_CHARSET");
1384
1385           if (value != NULL && value[0] != '\0')
1386             {
1387               size_t len = strlen (value) + 1;
1388               char *value_copy = (char *) malloc (len);
1389
1390               if (value_copy != NULL)
1391                 memcpy (value_copy, value, len);
1392               output_charset_cache = value_copy;
1393             }
1394           output_charset_cached = 1;
1395         }
1396
1397       if (output_charset_cache != NULL)
1398         return output_charset_cache;
1399       else
1400         {
1401 # ifdef _LIBC
1402           return _NL_CURRENT (LC_CTYPE, CODESET);
1403 # else
1404 #  if HAVE_ICONV
1405           extern const char *locale_charset PARAMS ((void));
1406           return locale_charset ();
1407 #  endif
1408 # endif
1409         }
1410     }
1411 }
1412 #endif
1413
1414 /* @@ begin of epilog @@ */
1415
1416 /* We don't want libintl.a to depend on any other library.  So we
1417    avoid the non-standard function stpcpy.  In GNU C Library this
1418    function is available, though.  Also allow the symbol HAVE_STPCPY
1419    to be defined.  */
1420 #if !_LIBC && !HAVE_STPCPY
1421 static char *
1422 stpcpy (dest, src)
1423      char *dest;
1424      const char *src;
1425 {
1426   while ((*dest++ = *src++) != '\0')
1427     /* Do nothing. */ ;
1428   return dest - 1;
1429 }
1430 #endif
1431
1432 #if !_LIBC && !HAVE_MEMPCPY
1433 static void *
1434 mempcpy (dest, src, n)
1435      void *dest;
1436      const void *src;
1437      size_t n;
1438 {
1439   return (void *) ((char *) memcpy (dest, src, n) + n);
1440 }
1441 #endif
1442
1443
1444 #ifdef _LIBC
1445 /* If we want to free all resources we have to do some work at
1446    program's end.  */
1447 libc_freeres_fn (free_mem)
1448 {
1449   void *old;
1450
1451   while (_nl_domain_bindings != NULL)
1452     {
1453       struct binding *oldp = _nl_domain_bindings;
1454       _nl_domain_bindings = _nl_domain_bindings->next;
1455       if (oldp->dirname != _nl_default_dirname)
1456         /* Yes, this is a pointer comparison.  */
1457         free (oldp->dirname);
1458       free (oldp->codeset);
1459       free (oldp);
1460     }
1461
1462   if (_nl_current_default_domain != _nl_default_default_domain)
1463     /* Yes, again a pointer comparison.  */
1464     free ((char *) _nl_current_default_domain);
1465
1466   /* Remove the search tree with the known translations.  */
1467   __tdestroy (root, free);
1468   root = NULL;
1469
1470   while (transmem_list != NULL)
1471     {
1472       old = transmem_list;
1473       transmem_list = transmem_list->next;
1474       free (old);
1475     }
1476 }
1477 #endif