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
50char *alloca ();
51#    endif
52#   endif
53#  endif
54# endif
55#endif
56
57#include <errno.h>
58#ifndef errno
59extern 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
156char *getwd ();
157#  define getcwd(buf, max) getwd (buf)
158# else
159#  if VMS
160#   define getcwd(buf, max) (getcwd) (buf, max, 0)
161#  else
162char *getcwd ();
163#  endif
164# endif
165# ifndef HAVE_STPCPY
166static char *stpcpy (char *dest, const char *src);
167# endif
168# ifndef HAVE_MEMPCPY
169static 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.  */
234struct 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
271gl_rwlock_define_initialized (static, tree_lock)
272
273static 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.  */
280static int
281transcmp (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".  */
319const char _nl_default_default_domain[] attribute_hidden = "messages";
320
321#ifndef IN_LIBGLOCALE
322/* Value used as the default domain for gettext(3).  */
323const 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__
329extern const char _nl_default_dirname[];
330#else
331# ifdef _LIBC
332extern const char _nl_default_dirname[];
333libc_hidden_proto (_nl_default_dirname)
334# endif
335const char _nl_default_dirname[] = LOCALEDIR;
336# ifdef _LIBC
337libc_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.  */
344struct binding *_nl_domain_bindings;
345#endif
346
347/* Prototypes for local functions.  */
348static 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
354static const char *guess_category_value (int category,
355					 const char *categoryname,
356					 const char *localename)
357     internal_function;
358#else
359static 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
369static const char *category_to_name (int category) internal_function;
370#endif
371#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE
372static 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
385struct 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.  */
418typedef struct transmem_list
419{
420  struct transmem_list *next;
421  char data[ZERO];
422} transmem_block_t;
423static struct transmem_list *transmem_list;
424#else
425typedef 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.  */
440gl_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
460static 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
479char *
480gl_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
486char *
487DCIGETTEXT (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).  */
880char *
881internal_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.  */
1347static char *
1348internal_function
1349plural_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.  */
1385static const char *
1386internal_function
1387category_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.  */
1446static const char *
1447internal_function
1448#ifdef IN_LIBGLOCALE
1449guess_category_value (int category, const char *categoryname,
1450		      const char *locale)
1451
1452#else
1453guess_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.  */
1544static const char *
1545internal_function
1546get_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
1603static char *
1604stpcpy (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
1613static void *
1614mempcpy (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.  */
1624libc_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
1655