~ubuntu-branches/ubuntu/karmic/centerim/karmic

« back to all changes in this revision

Viewing changes to intl/dcigettext.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2009-03-26 19:51:53 UTC
  • mfrom: (1.1.5 upstream) (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090326195153-dxo63t1lwbp2m592
Tags: 4.22.7-1ubuntu1
* Merge from debian unstable, Ubuntu remaining changes:
  - Packages that Depend/Recommend/Suggest firefox (metapackage) must
    must alternatively Depend/Recommend/Suggest abrowser.
* Bugfix-only release, fixed bugs: LP: #146308 and LP: #186381.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Implementation of the internal dcigettext function.
2
 
   Copyright (C) 1995-1999, 2000-2006 Free Software Foundation, Inc.
 
2
   Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
3
3
 
4
4
   This program is free software; you can redistribute it and/or modify it
5
5
   under the terms of the GNU Library General Public License as published
27
27
# include <config.h>
28
28
#endif
29
29
 
30
 
/* NL_LOCALE_NAME does not work in glibc-2.4.  Ignore it.  */
31
 
#undef HAVE_NL_LOCALE_NAME
32
 
 
33
30
#include <sys/types.h>
34
31
 
35
32
#ifdef __GNUC__
90
87
# include <sys/param.h>
91
88
#endif
92
89
 
93
 
#if !defined _LIBC && HAVE_NL_LOCALE_NAME
94
 
# include <langinfo.h>
95
 
#endif
96
 
 
97
90
#include "gettextP.h"
98
91
#include "plural-exp.h"
99
92
#ifdef _LIBC
100
93
# include <libintl.h>
101
94
#else
102
 
# ifdef IN_LIBGLOCALE
103
 
#  include <libintl.h>
104
 
# endif
105
95
# include "libgnuintl.h"
106
96
#endif
107
97
#include "hash-string.h"
108
98
 
109
 
/* Handle multi-threaded applications.  */
 
99
/* Thread safetyness.  */
110
100
#ifdef _LIBC
111
101
# 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
102
#else
117
 
# include "lock.h"
 
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)
118
110
#endif
119
111
 
120
112
/* Alignment of types.  */
224
216
# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
225
217
#endif
226
218
 
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
219
/* This is the type used for the search tree where known translations
233
220
   are stored.  */
234
221
struct known_translation_t
235
222
{
236
223
  /* Domain in which to search.  */
237
 
  const char *domainname;
 
224
  char *domainname;
238
225
 
239
226
  /* The category.  */
240
227
  int category;
241
228
 
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
229
  /* State of the catalog counter at the point the string was found.  */
253
230
  int counter;
254
231
 
268
245
#if defined HAVE_TSEARCH || defined _LIBC
269
246
# include <search.h>
270
247
 
271
 
gl_rwlock_define_initialized (static, tree_lock)
272
 
 
273
248
static void *root;
274
249
 
275
250
# ifdef _LIBC
292
267
    {
293
268
      result = strcmp (s1->domainname, s2->domainname);
294
269
      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
 
        }
 
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;
311
274
    }
312
275
 
313
276
  return result;
314
277
}
315
278
#endif
316
279
 
 
280
#ifndef INTVARDEF
 
281
# define INTVARDEF(name)
 
282
#endif
 
283
#ifndef INTUSE
 
284
# define INTUSE(name) name
 
285
#endif
 
286
 
317
287
/* Name of the default domain used for gettext(3) prior any call to
318
288
   textdomain(3).  The default value for this is "messages".  */
319
289
const char _nl_default_default_domain[] attribute_hidden = "messages";
320
290
 
321
 
#ifndef IN_LIBGLOCALE
322
291
/* Value used as the default domain for gettext(3).  */
323
292
const char *_nl_current_default_domain attribute_hidden
324
293
     = _nl_default_default_domain;
325
 
#endif
326
294
 
327
295
/* Contains the default location of the message catalogs.  */
328
296
#if defined __EMX__
329
297
extern const char _nl_default_dirname[];
330
298
#else
331
 
# ifdef _LIBC
332
 
extern const char _nl_default_dirname[];
333
 
libc_hidden_proto (_nl_default_dirname)
334
 
# endif
335
299
const char _nl_default_dirname[] = LOCALEDIR;
336
 
# ifdef _LIBC
337
 
libc_hidden_data_def (_nl_default_dirname)
338
 
# endif
 
300
INTVARDEF (_nl_default_dirname)
339
301
#endif
340
302
 
341
 
#ifndef IN_LIBGLOCALE
342
303
/* List with bindings of specific domains created by bindtextdomain()
343
304
   calls.  */
344
305
struct binding *_nl_domain_bindings;
345
 
#endif
346
306
 
347
307
/* Prototypes for local functions.  */
348
308
static char *plural_lookup (struct loaded_l10nfile *domain,
349
309
                            unsigned long int n,
350
310
                            const char *translation, size_t translation_len)
351
311
     internal_function;
352
 
 
353
 
#ifdef IN_LIBGLOCALE
354
 
static const char *guess_category_value (int category,
355
 
                                         const char *categoryname,
356
 
                                         const char *localename)
357
 
     internal_function;
358
 
#else
359
312
static const char *guess_category_value (int category,
360
313
                                         const char *categoryname)
361
314
     internal_function;
362
 
#endif
363
 
 
364
315
#ifdef _LIBC
365
316
# include "../locale/localeinfo.h"
366
 
# define category_to_name(category) \
367
 
  _nl_category_names.str + _nl_category_name_idxs[category]
 
317
# define category_to_name(category)     _nl_category_names[category]
368
318
#else
369
319
static const char *category_to_name (int category) internal_function;
370
320
#endif
371
 
#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE
372
 
static const char *get_output_charset (struct binding *domainbinding)
373
 
     internal_function;
374
 
#endif
375
321
 
376
322
 
377
323
/* For those loosing systems which don't have `alloca' we have to add
437
383
#endif
438
384
 
439
385
/* Lock variable to protect the global data in the gettext implementation.  */
440
 
gl_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
 
386
#ifdef _LIBC
 
387
__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
 
388
#endif
441
389
 
442
390
/* Checking whether the binaries runs SUID must be done and glibc provides
443
391
   easier methods therefore we make a difference here.  */
475
423
/* Look up MSGID in the DOMAINNAME message catalog for the current
476
424
   CATEGORY locale and, if PLURAL is nonzero, search over string
477
425
   depending on the plural form determined by N.  */
478
 
#ifdef IN_LIBGLOCALE
479
 
char *
480
 
gl_dcigettext (const char *domainname,
481
 
               const char *msgid1, const char *msgid2,
482
 
               int plural, unsigned long int n,
483
 
               int category,
484
 
               const char *localename, const char *encoding)
485
 
#else
486
426
char *
487
427
DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
488
428
            int plural, unsigned long int n, int category)
489
 
#endif
490
429
{
491
430
#ifndef HAVE_ALLOCA
492
431
  struct block_list *block_list = NULL;
495
434
  struct binding *binding;
496
435
  const char *categoryname;
497
436
  const char *categoryvalue;
498
 
  const char *dirname;
499
 
  char *xdomainname;
 
437
  char *dirname, *xdomainname;
500
438
  char *single_locale;
501
439
  char *retval;
502
440
  size_t retlen;
505
443
  struct known_translation_t *search;
506
444
  struct known_translation_t **foundp = NULL;
507
445
  size_t msgid_len;
508
 
# if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE
509
 
  const char *localename;
510
 
# endif
511
446
#endif
512
447
  size_t domainname_len;
513
448
 
524
459
            : n == 1 ? (char *) msgid1 : (char *) msgid2);
525
460
#endif
526
461
 
527
 
  gl_rwlock_rdlock (_nl_state_lock);
 
462
  __libc_rwlock_rdlock (_nl_state_lock);
528
463
 
529
464
  /* If DOMAINNAME is NULL, we are interested in the default domain.  If
530
465
     CATEGORY is not LC_MESSAGES this might not make much sense but the
546
481
  search = (struct known_translation_t *)
547
482
           alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
548
483
  memcpy (search->msgid, msgid1, msgid_len);
549
 
  search->domainname = domainname;
 
484
  search->domainname = (char *) domainname;
550
485
  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
486
 
584
487
  foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
585
 
 
586
 
  gl_rwlock_unlock (tree_lock);
587
 
 
588
488
  freea (search);
589
489
  if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
590
490
    {
595
495
      else
596
496
        retval = (char *) (*foundp)->translation;
597
497
 
598
 
      gl_rwlock_unlock (_nl_state_lock);
 
498
      __libc_rwlock_unlock (_nl_state_lock);
599
499
      return retval;
600
500
    }
601
501
#endif
607
507
  DETERMINE_SECURE;
608
508
 
609
509
  /* 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
510
  for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
617
511
    {
618
512
      int compare = strcmp (domainname, binding->domainname);
628
522
    }
629
523
 
630
524
  if (binding == NULL)
631
 
    dirname = _nl_default_dirname;
 
525
    dirname = (char *) INTUSE(_nl_default_dirname);
 
526
  else if (IS_ABSOLUTE_PATH (binding->dirname))
 
527
    dirname = binding->dirname;
632
528
  else
633
529
    {
634
 
      dirname = binding->dirname;
635
 
#endif
636
 
      if (!IS_ABSOLUTE_PATH (dirname))
 
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 (;;)
637
539
        {
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;
 
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;
668
550
        }
669
 
#ifndef IN_LIBGLOCALE
 
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);
670
558
    }
671
 
#endif
672
559
 
673
560
  /* Now determine the symbolic name of CATEGORY and its value.  */
674
561
  categoryname = category_to_name (category);
675
 
#ifdef IN_LIBGLOCALE
676
 
  categoryvalue = guess_category_value (category, categoryname, localename);
677
 
#else
678
562
  categoryvalue = guess_category_value (category, categoryname);
679
 
#endif
680
563
 
681
564
  domainname_len = strlen (domainname);
682
565
  xdomainname = (char *) alloca (strlen (categoryname)
734
617
 
735
618
      if (domain != NULL)
736
619
        {
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
 
620
          retval = _nl_find_msg (domain, binding, msgid1, &retlen);
742
621
 
743
622
          if (retval == NULL)
744
623
            {
746
625
 
747
626
              for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
748
627
                {
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
 
628
                  retval = _nl_find_msg (domain->successor[cnt], binding,
 
629
                                         msgid1, &retlen);
756
630
 
757
631
                  if (retval != NULL)
758
632
                    {
762
636
                }
763
637
            }
764
638
 
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
639
          if (retval != NULL)
772
640
            {
773
641
              /* Found the translation of MSGID1 in domain DOMAIN:
777
645
              if (foundp == NULL)
778
646
                {
779
647
                  /* Create a new entry and add it to the search tree.  */
780
 
                  size_t size;
781
648
                  struct known_translation_t *newp;
782
649
 
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);
 
650
                  newp = (struct known_translation_t *)
 
651
                    malloc (offsetof (struct known_translation_t, msgid)
 
652
                            + msgid_len + domainname_len + 1);
789
653
                  if (newp != NULL)
790
654
                    {
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;
 
655
                      newp->domainname =
 
656
                        mempcpy (newp->msgid, msgid1, msgid_len);
 
657
                      memcpy (newp->domainname, domainname, domainname_len + 1);
803
658
                      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
659
                      newp->counter = _nl_msg_cat_cntr;
811
660
                      newp->domain = domain;
812
661
                      newp->translation = retval;
813
662
                      newp->translation_length = retlen;
814
663
 
815
 
                      gl_rwlock_wrlock (tree_lock);
816
 
 
817
664
                      /* Insert the entry in the search tree.  */
818
665
                      foundp = (struct known_translation_t **)
819
666
                        tsearch (newp, &root, transcmp);
820
 
 
821
 
                      gl_rwlock_unlock (tree_lock);
822
 
 
823
667
                      if (foundp == NULL
824
668
                          || __builtin_expect (*foundp != newp, 0))
825
669
                        /* The insert failed.  */
841
685
              if (plural)
842
686
                retval = plural_lookup (domain, n, retval, retlen);
843
687
 
844
 
              gl_rwlock_unlock (_nl_state_lock);
 
688
              __libc_rwlock_unlock (_nl_state_lock);
845
689
              return retval;
846
690
            }
847
691
        }
850
694
 return_untranslated:
851
695
  /* Return the untranslated MSGID.  */
852
696
  FREE_BLOCKS (block_list);
853
 
  gl_rwlock_unlock (_nl_state_lock);
 
697
  __libc_rwlock_unlock (_nl_state_lock);
854
698
#ifndef _LIBC
855
699
  if (!ENABLE_SECURE)
856
700
    {
872
716
}
873
717
 
874
718
 
875
 
/* Look up the translation of msgid within DOMAIN_FILE and DOMAINBINDING.
876
 
   Return it if found.  Return NULL if not found or in case of a conversion
877
 
   failure (problem in the particular message catalog).  Return (char *) -1
878
 
   in case of a memory allocation failure during conversion (only if
879
 
   ENCODING != NULL resp. CONVERT == true).  */
880
719
char *
881
720
internal_function
882
 
#ifdef IN_LIBGLOCALE
883
 
_nl_find_msg (struct loaded_l10nfile *domain_file,
884
 
              struct binding *domainbinding, const char *encoding,
885
 
              const char *msgid,
886
 
              size_t *lengthp)
887
 
#else
888
 
_nl_find_msg (struct loaded_l10nfile *domain_file,
889
 
              struct binding *domainbinding,
890
 
              const char *msgid, int convert,
891
 
              size_t *lengthp)
892
 
#endif
 
721
_nl_find_msg (struct loaded_l10nfile *domain_file,
 
722
              struct binding *domainbinding, const char *msgid,
 
723
              size_t *lengthp)
893
724
{
894
725
  struct loaded_domain *domain;
895
726
  nls_uint32 nstrings;
897
728
  char *result;
898
729
  size_t resultlen;
899
730
 
900
 
  if (domain_file->decided <= 0)
 
731
  if (domain_file->decided == 0)
901
732
    _nl_load_domain (domain_file, domainbinding);
902
733
 
903
734
  if (domain_file->data == NULL)
912
743
    {
913
744
      /* Use the hashing table.  */
914
745
      nls_uint32 len = strlen (msgid);
915
 
      nls_uint32 hash_val = __hash_string (msgid);
 
746
      nls_uint32 hash_val = hash_string (msgid);
916
747
      nls_uint32 idx = hash_val % domain->hash_size;
917
748
      nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
918
749
 
995
826
    }
996
827
 
997
828
#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)
 
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)
1195
878
# define INITIAL_BLOCK_SIZE     4080
1196
 
              static unsigned char *freemem;
1197
 
              static size_t freemem_size;
 
879
          static unsigned char *freemem;
 
880
          static size_t freemem_size;
1198
881
 
1199
 
              const unsigned char *inbuf;
1200
 
              unsigned char *outbuf;
1201
 
              int malloc_count;
 
882
          const unsigned char *inbuf;
 
883
          unsigned char *outbuf;
 
884
          int malloc_count;
1202
885
# ifndef _LIBC
1203
 
              transmem_block_t *transmem_list = NULL;
1204
 
# endif
1205
 
 
1206
 
              __libc_lock_lock (lock);
1207
 
 
1208
 
              inbuf = (const unsigned char *) result;
 
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
 
1209
995
              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
996
            }
1329
997
 
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];
 
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);
1334
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];
1335
1015
    }
1336
1016
 
 
1017
 converted:
1337
1018
  /* The result string is converted.  */
1338
1019
 
1339
1020
#endif /* _LIBC || HAVE_ICONV */
1445
1126
   or system-dependent defaults.  */
1446
1127
static const char *
1447
1128
internal_function
1448
 
#ifdef IN_LIBGLOCALE
1449
 
guess_category_value (int category, const char *categoryname,
1450
 
                      const char *locale)
1451
 
 
1452
 
#else
1453
1129
guess_category_value (int category, const char *categoryname)
1454
 
#endif
1455
1130
{
1456
1131
  const char *language;
1457
 
#ifndef IN_LIBGLOCALE
1458
1132
  const char *locale;
1459
 
# ifndef _LIBC
 
1133
#ifndef _LIBC
1460
1134
  const char *language_default;
1461
1135
  int locale_defaulted;
1462
 
# endif
1463
1136
#endif
1464
1137
 
1465
1138
  /* We use the settings in the following order:
1476
1149
       - If the system provides both a list of languages and a default locale,
1477
1150
         the former is used.  */
1478
1151
 
1479
 
#ifndef IN_LIBGLOCALE
1480
1152
  /* Fetch the locale name, through the POSIX method of looking to `LC_ALL',
1481
1153
     `LC_xxx', and `LANG'.  On some systems this can be done by the
1482
1154
     `setlocale' function itself.  */
1483
 
# ifdef _LIBC
 
1155
#ifdef _LIBC
1484
1156
  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
 
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
    }
1507
1165
#endif
1508
1166
 
1509
1167
  /* Ignore LANGUAGE and its system-dependent analogon if the locale is set
1525
1183
  language = getenv ("LANGUAGE");
1526
1184
  if (language != NULL && language[0] != '\0')
1527
1185
    return language;
1528
 
#if !defined IN_LIBGLOCALE && !defined _LIBC
 
1186
#ifndef _LIBC
1529
1187
  /* The next priority value is the locale name, if not defaulted.  */
1530
1188
  if (locale_defaulted)
1531
1189
    {
1539
1197
  return locale;
1540
1198
}
1541
1199
 
1542
 
#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE
1543
 
/* Returns the output charset.  */
1544
 
static const char *
1545
 
internal_function
1546
 
get_output_charset (struct binding *domainbinding)
1547
 
{
1548
 
  /* The output charset should normally be determined by the locale.  But
1549
 
     sometimes the locale is not used or not correctly set up, so we provide
1550
 
     a possibility for the user to override this: the OUTPUT_CHARSET
1551
 
     environment variable.  Moreover, the value specified through
1552
 
     bind_textdomain_codeset overrides both.  */
1553
 
  if (domainbinding != NULL && domainbinding->codeset != NULL)
1554
 
    return domainbinding->codeset;
1555
 
  else
1556
 
    {
1557
 
      /* For speed reasons, we look at the value of OUTPUT_CHARSET only
1558
 
         once.  This is a user variable that is not supposed to change
1559
 
         during a program run.  */
1560
 
      static char *output_charset_cache;
1561
 
      static int output_charset_cached;
1562
 
 
1563
 
      if (!output_charset_cached)
1564
 
        {
1565
 
          const char *value = getenv ("OUTPUT_CHARSET");
1566
 
 
1567
 
          if (value != NULL && value[0] != '\0')
1568
 
            {
1569
 
              size_t len = strlen (value) + 1;
1570
 
              char *value_copy = (char *) malloc (len);
1571
 
 
1572
 
              if (value_copy != NULL)
1573
 
                memcpy (value_copy, value, len);
1574
 
              output_charset_cache = value_copy;
1575
 
            }
1576
 
          output_charset_cached = 1;
1577
 
        }
1578
 
 
1579
 
      if (output_charset_cache != NULL)
1580
 
        return output_charset_cache;
1581
 
      else
1582
 
        {
1583
 
# ifdef _LIBC
1584
 
          return _NL_CURRENT (LC_CTYPE, CODESET);
1585
 
# else
1586
 
#  if HAVE_ICONV
1587
 
          extern const char *locale_charset (void);
1588
 
          return locale_charset ();
1589
 
#  endif
1590
 
# endif
1591
 
        }
1592
 
    }
1593
 
}
1594
 
#endif
1595
 
 
1596
1200
/* @@ begin of epilog @@ */
1597
1201
 
1598
1202
/* We don't want libintl.a to depend on any other library.  So we
1629
1233
    {
1630
1234
      struct binding *oldp = _nl_domain_bindings;
1631
1235
      _nl_domain_bindings = _nl_domain_bindings->next;
1632
 
      if (oldp->dirname != _nl_default_dirname)
 
1236
      if (oldp->dirname != INTUSE(_nl_default_dirname))
1633
1237
        /* Yes, this is a pointer comparison.  */
1634
1238
        free (oldp->dirname);
1635
1239
      free (oldp->codeset);