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