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