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