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