Back to index

tetex-bin  3.0
Classes | Defines | Functions | Variables
gettextP.h File Reference
#include <stddef.h>
#include "loadinfo.h"
#include "gmo.h"
#include "libgnuintl.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  loaded_domain
struct  binding

Defines

#define attribute_hidden    _nl_default_default_domain
#define __builtin_expect(expr, val)   (expr)
#define W(flag, data)   ((flag) ? SWAP (data) : (data))
#define ZERO   1
#define _INTL_REDIRECT_MACROS

Functions

const char * _nl_locale_name (int category, const char *categoryname)
struct loaded_l10nfile_nl_find_domain (const char *__dirname, char *__locale, const char *__domainname, struct binding *__domainbinding) internal_function
void _nl_load_domain (struct loaded_l10nfile *__domain, struct binding *__domainbinding) internal_function
void _nl_unload_domain (struct loaded_domain *__domain) internal_function
const char * _nl_init_domain_conv (struct loaded_l10nfile *__domain_file, struct loaded_domain *__domain, struct binding *__domainbinding) internal_function
void _nl_free_domain_conv (struct loaded_domain *__domain) internal_function
char * _nl_find_msg (struct loaded_l10nfile *domain_file, struct binding *domainbinding, const char *msgid, size_t *lengthp) internal_function
char * libintl_dcigettext (const char *__domainname, const char *__msgid1, const char *__msgid2, int __plural, unsigned long int __n, int __category)

Variables

static nls_uint32 nls_uint32 i
int _nl_msg_cat_cntr

Class Documentation

struct loaded_domain

Definition at line 81 of file gettextP.h.

Collaboration diagram for loaded_domain:
Class Members
int codeset_cntr
char ** conv_tab
const char * data
nls_uint32 hash_size
const nls_uint32 * hash_tab
void * malloced
size_t mmap_size
int must_swap
int must_swap_hash_tab
nls_uint32 n_sysdep_strings
unsigned long int nplurals
nls_uint32 nstrings
struct sysdep_string_desc * orig_sysdep_tab
struct string_desc * orig_tab
struct expression * plural
struct sysdep_string_desc * trans_sysdep_tab
struct string_desc * trans_tab
int use_mmap
struct binding

Definition at line 139 of file gettextP.h.

Collaboration diagram for binding:
Class Members
char * codeset
int codeset_cntr
char * dirname
char domainname
struct binding * next

Define Documentation

#define __builtin_expect (   expr,
  val 
)    (expr)

Definition at line 50 of file gettextP.h.

Definition at line 205 of file gettextP.h.

Definition at line 44 of file gettextP.h.

#define W (   flag,
  data 
)    ((flag) ? SWAP (data) : (data))

Definition at line 54 of file gettextP.h.

#define ZERO   1

Definition at line 134 of file gettextP.h.


Function Documentation

struct loaded_l10nfile* _nl_find_domain ( const char *  __dirname,
char *  __locale,
const char *  __domainname,
struct binding __domainbinding 
) [read]

Definition at line 50 of file finddomain.c.

{
  struct loaded_l10nfile *retval;
  const char *language;
  const char *modifier;
  const char *territory;
  const char *codeset;
  const char *normalized_codeset;
  const char *special;
  const char *sponsor;
  const char *revision;
  const char *alias_value;
  int mask;

  /* LOCALE can consist of up to four recognized parts for the XPG syntax:

              language[_territory[.codeset]][@modifier]

     and six parts for the CEN syntax:

       language[_territory][+audience][+special][,[sponsor][_revision]]

     Beside the first part all of them are allowed to be missing.  If
     the full specified locale is not found, the less specific one are
     looked for.  The various parts will be stripped off according to
     the following order:
              (1) revision
              (2) sponsor
              (3) special
              (4) codeset
              (5) normalized codeset
              (6) territory
              (7) audience/modifier
   */

  /* If we have already tested for this locale entry there has to
     be one data set in the list of loaded domains.  */
  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
                            strlen (dirname) + 1, 0, locale, NULL, NULL,
                            NULL, NULL, NULL, NULL, NULL, domainname, 0);
  if (retval != NULL)
    {
      /* We know something about this locale.  */
      int cnt;

      if (retval->decided == 0)
       _nl_load_domain (retval, domainbinding);

      if (retval->data != NULL)
       return retval;

      for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
       {
         if (retval->successor[cnt]->decided == 0)
           _nl_load_domain (retval->successor[cnt], domainbinding);

         if (retval->successor[cnt]->data != NULL)
           break;
       }
      return cnt >= 0 ? retval : NULL;
      /* NOTREACHED */
    }

  /* See whether the locale value is an alias.  If yes its value
     *overwrites* the alias name.  No test for the original value is
     done.  */
  alias_value = _nl_expand_alias (locale);
  if (alias_value != NULL)
    {
#if defined _LIBC || defined HAVE_STRDUP
      locale = strdup (alias_value);
      if (locale == NULL)
       return NULL;
#else
      size_t len = strlen (alias_value) + 1;
      locale = (char *) malloc (len);
      if (locale == NULL)
       return NULL;

      memcpy (locale, alias_value, len);
#endif
    }

  /* Now we determine the single parts of the locale name.  First
     look for the language.  Termination symbols are `_' and `@' if
     we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
  mask = _nl_explode_name (locale, &language, &modifier, &territory,
                        &codeset, &normalized_codeset, &special,
                        &sponsor, &revision);

  /* Create all possible locale entries which might be interested in
     generalization.  */
  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
                            strlen (dirname) + 1, mask, language, territory,
                            codeset, normalized_codeset, modifier, special,
                            sponsor, revision, domainname, 1);
  if (retval == NULL)
    /* This means we are out of core.  */
    return NULL;

  if (retval->decided == 0)
    _nl_load_domain (retval, domainbinding);
  if (retval->data == NULL)
    {
      int cnt;
      for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
       {
         if (retval->successor[cnt]->decided == 0)
           _nl_load_domain (retval->successor[cnt], domainbinding);
         if (retval->successor[cnt]->data != NULL)
           break;
       }
    }

  /* The room for an alias was dynamically allocated.  Free it now.  */
  if (alias_value != NULL)
    free (locale);

  /* The space for normalized_codeset is dynamically allocated.  Free it.  */
  if (mask & XPG_NORM_CODESET)
    free ((void *) normalized_codeset);

  return retval;
}

Here is the call graph for this function:

char* _nl_find_msg ( struct loaded_l10nfile domain_file,
struct binding domainbinding,
const char *  msgid,
size_t lengthp 
)

Definition at line 721 of file dcigettext.c.

{
  struct loaded_domain *domain;
  nls_uint32 nstrings;
  size_t act;
  char *result;
  size_t resultlen;

  if (domain_file->decided == 0)
    _nl_load_domain (domain_file, domainbinding);

  if (domain_file->data == NULL)
    return NULL;

  domain = (struct loaded_domain *) domain_file->data;

  nstrings = domain->nstrings;

  /* Locate the MSGID and its translation.  */
  if (domain->hash_tab != NULL)
    {
      /* Use the hashing table.  */
      nls_uint32 len = strlen (msgid);
      nls_uint32 hash_val = hash_string (msgid);
      nls_uint32 idx = hash_val % domain->hash_size;
      nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));

      while (1)
       {
         nls_uint32 nstr =
           W (domain->must_swap_hash_tab, domain->hash_tab[idx]);

         if (nstr == 0)
           /* Hash table entry is empty.  */
           return NULL;

         nstr--;

         /* Compare msgid with the original string at index nstr.
            We compare the lengths with >=, not ==, because plural entries
            are represented by strings with an embedded NUL.  */
         if (nstr < nstrings
             ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len
              && (strcmp (msgid,
                         domain->data + W (domain->must_swap,
                                         domain->orig_tab[nstr].offset))
                  == 0)
             : domain->orig_sysdep_tab[nstr - nstrings].length > len
              && (strcmp (msgid,
                         domain->orig_sysdep_tab[nstr - nstrings].pointer)
                  == 0))
           {
             act = nstr;
             goto found;
           }

         if (idx >= domain->hash_size - incr)
           idx -= domain->hash_size - incr;
         else
           idx += incr;
       }
      /* NOTREACHED */
    }
  else
    {
      /* Try the default method:  binary search in the sorted array of
        messages.  */
      size_t top, bottom;

      bottom = 0;
      top = nstrings;
      while (bottom < top)
       {
         int cmp_val;

         act = (bottom + top) / 2;
         cmp_val = strcmp (msgid, (domain->data
                                + W (domain->must_swap,
                                    domain->orig_tab[act].offset)));
         if (cmp_val < 0)
           top = act;
         else if (cmp_val > 0)
           bottom = act + 1;
         else
           goto found;
       }
      /* No translation was found.  */
      return NULL;
    }

 found:
  /* The translation was found at index ACT.  If we have to convert the
     string to use a different character set, this is the time.  */
  if (act < nstrings)
    {
      result = (char *)
       (domain->data + W (domain->must_swap, domain->trans_tab[act].offset));
      resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1;
    }
  else
    {
      result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer;
      resultlen = domain->trans_sysdep_tab[act - nstrings].length;
    }

#if defined _LIBC || HAVE_ICONV
  if (domain->codeset_cntr
      != (domainbinding != NULL ? domainbinding->codeset_cntr : 0))
    {
      /* The domain's codeset has changed through bind_textdomain_codeset()
        since the message catalog was initialized or last accessed.  We
        have to reinitialize the converter.  */
      _nl_free_domain_conv (domain);
      _nl_init_domain_conv (domain_file, domain, domainbinding);
    }

  if (
# ifdef _LIBC
      domain->conv != (__gconv_t) -1
# else
#  if HAVE_ICONV
      domain->conv != (iconv_t) -1
#  endif
# endif
      )
    {
      /* We are supposed to do a conversion.  First allocate an
        appropriate table with the same structure as the table
        of translations in the file, where we can put the pointers
        to the converted strings in.
        There is a slight complication with plural entries.  They
        are represented by consecutive NUL terminated strings.  We
        handle this case by converting RESULTLEN bytes, including
        NULs.  */

      if (domain->conv_tab == NULL
         && ((domain->conv_tab =
               (char **) calloc (nstrings + domain->n_sysdep_strings,
                               sizeof (char *)))
             == NULL))
       /* Mark that we didn't succeed allocating a table.  */
       domain->conv_tab = (char **) -1;

      if (__builtin_expect (domain->conv_tab == (char **) -1, 0))
       /* Nothing we can do, no more memory.  */
       goto converted;

      if (domain->conv_tab[act] == NULL)
       {
         /* We haven't used this string so far, so it is not
            translated yet.  Do this now.  */
         /* We use a bit more efficient memory handling.
            We allocate always larger blocks which get used over
            time.  This is faster than many small allocations.   */
         __libc_lock_define_initialized (static, lock)
# define INITIAL_BLOCK_SIZE 4080
         static unsigned char *freemem;
         static size_t freemem_size;

         const unsigned char *inbuf;
         unsigned char *outbuf;
         int malloc_count;
# ifndef _LIBC
         transmem_block_t *transmem_list = NULL;
# endif

         __libc_lock_lock (lock);

         inbuf = (const unsigned char *) result;
         outbuf = freemem + sizeof (size_t);

         malloc_count = 0;
         while (1)
           {
             transmem_block_t *newmem;
# ifdef _LIBC
             size_t non_reversible;
             int res;

             if (freemem_size < sizeof (size_t))
              goto resize_freemem;

             res = __gconv (domain->conv,
                          &inbuf, inbuf + resultlen,
                          &outbuf,
                          outbuf + freemem_size - sizeof (size_t),
                          &non_reversible);

             if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT)
              break;

             if (res != __GCONV_FULL_OUTPUT)
              {
                __libc_lock_unlock (lock);
                goto converted;
              }

             inbuf = result;
# else
#  if HAVE_ICONV
             const char *inptr = (const char *) inbuf;
             size_t inleft = resultlen;
             char *outptr = (char *) outbuf;
             size_t outleft;

             if (freemem_size < sizeof (size_t))
              goto resize_freemem;

             outleft = freemem_size - sizeof (size_t);
             if (iconv (domain->conv,
                      (ICONV_CONST char **) &inptr, &inleft,
                      &outptr, &outleft)
                != (size_t) (-1))
              {
                outbuf = (unsigned char *) outptr;
                break;
              }
             if (errno != E2BIG)
              {
                __libc_lock_unlock (lock);
                goto converted;
              }
#  endif
# endif

           resize_freemem:
             /* We must allocate a new buffer or resize the old one.  */
             if (malloc_count > 0)
              {
                ++malloc_count;
                freemem_size = malloc_count * INITIAL_BLOCK_SIZE;
                newmem = (transmem_block_t *) realloc (transmem_list,
                                                  freemem_size);
# ifdef _LIBC
                if (newmem != NULL)
                  transmem_list = transmem_list->next;
                else
                  {
                    struct transmem_list *old = transmem_list;

                    transmem_list = transmem_list->next;
                    free (old);
                  }
# endif
              }
             else
              {
                malloc_count = 1;
                freemem_size = INITIAL_BLOCK_SIZE;
                newmem = (transmem_block_t *) malloc (freemem_size);
              }
             if (__builtin_expect (newmem == NULL, 0))
              {
                freemem = NULL;
                freemem_size = 0;
                __libc_lock_unlock (lock);
                goto converted;
              }

# ifdef _LIBC
             /* Add the block to the list of blocks we have to free
                 at some point.  */
             newmem->next = transmem_list;
             transmem_list = newmem;

             freemem = newmem->data;
             freemem_size -= offsetof (struct transmem_list, data);
# else
             transmem_list = newmem;
             freemem = newmem;
# endif

             outbuf = freemem + sizeof (size_t);
           }

         /* We have now in our buffer a converted string.  Put this
            into the table of conversions.  */
         *(size_t *) freemem = outbuf - freemem - sizeof (size_t);
         domain->conv_tab[act] = (char *) freemem;
         /* Shrink freemem, but keep it aligned.  */
         freemem_size -= outbuf - freemem;
         freemem = outbuf;
         freemem += freemem_size & (alignof (size_t) - 1);
         freemem_size = freemem_size & ~ (alignof (size_t) - 1);

         __libc_lock_unlock (lock);
       }

      /* Now domain->conv_tab[act] contains the translation of all
        the plural variants.  */
      result = domain->conv_tab[act] + sizeof (size_t);
      resultlen = *(size_t *) domain->conv_tab[act];
    }

 converted:
  /* The result string is converted.  */

#endif /* _LIBC || HAVE_ICONV */

  *lengthp = resultlen;
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _nl_free_domain_conv ( struct loaded_domain __domain)

Definition at line 889 of file loadmsgcat.c.

{
  if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
    free (domain->conv_tab);

#ifdef _LIBC
  if (domain->conv != (__gconv_t) -1)
    __gconv_close (domain->conv);
#else
# if HAVE_ICONV
  if (domain->conv != (iconv_t) -1)
    iconv_close (domain->conv);
# endif
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* _nl_init_domain_conv ( struct loaded_l10nfile __domain_file,
struct loaded_domain __domain,
struct binding __domainbinding 
)

Definition at line 771 of file loadmsgcat.c.

{
  /* Find out about the character set the file is encoded with.
     This can be found (in textual form) in the entry "".  If this
     entry does not exist or if this does not contain the `charset='
     information, we will assume the charset matches the one the
     current locale and we don't have to perform any conversion.  */
  char *nullentry;
  size_t nullentrylen;

  /* Preinitialize fields, to avoid recursion during _nl_find_msg.  */
  domain->codeset_cntr =
    (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
#ifdef _LIBC
  domain->conv = (__gconv_t) -1;
#else
# if HAVE_ICONV
  domain->conv = (iconv_t) -1;
# endif
#endif
  domain->conv_tab = NULL;

  /* Get the header entry.  */
  nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);

  if (nullentry != NULL)
    {
#if defined _LIBC || HAVE_ICONV
      const char *charsetstr;

      charsetstr = strstr (nullentry, "charset=");
      if (charsetstr != NULL)
       {
         size_t len;
         char *charset;
         const char *outcharset;

         charsetstr += strlen ("charset=");
         len = strcspn (charsetstr, " \t\n");

         charset = (char *) alloca (len + 1);
# if defined _LIBC || HAVE_MEMPCPY
         *((char *) mempcpy (charset, charsetstr, len)) = '\0';
# else
         memcpy (charset, charsetstr, len);
         charset[len] = '\0';
# endif

         /* The output charset should normally be determined by the
            locale.  But sometimes the locale is not used or not correctly
            set up, so we provide a possibility for the user to override
            this.  Moreover, the value specified through
            bind_textdomain_codeset overrides both.  */
         if (domainbinding != NULL && domainbinding->codeset != NULL)
           outcharset = domainbinding->codeset;
         else
           {
             outcharset = getenv ("OUTPUT_CHARSET");
             if (outcharset == NULL || outcharset[0] == '\0')
              {
# ifdef _LIBC
                outcharset = _NL_CURRENT (LC_CTYPE, CODESET);
# else
#  if HAVE_ICONV
                extern const char *locale_charset (void);
                outcharset = locale_charset ();
#  endif
# endif
              }
           }

# ifdef _LIBC
         /* We always want to use transliteration.  */
         outcharset = norm_add_slashes (outcharset, "TRANSLIT");
         charset = norm_add_slashes (charset, NULL);
         if (__gconv_open (outcharset, charset, &domain->conv,
                         GCONV_AVOID_NOCONV)
             != __GCONV_OK)
           domain->conv = (__gconv_t) -1;
# else
#  if HAVE_ICONV
         /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
            we want to use transliteration.  */
#   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
       || _LIBICONV_VERSION >= 0x0105
         if (strchr (outcharset, '/') == NULL)
           {
             char *tmp;

             len = strlen (outcharset);
             tmp = (char *) alloca (len + 10 + 1);
             memcpy (tmp, outcharset, len);
             memcpy (tmp + len, "//TRANSLIT", 10 + 1);
             outcharset = tmp;

             domain->conv = iconv_open (outcharset, charset);

             freea (outcharset);
           }
         else
#   endif
           domain->conv = iconv_open (outcharset, charset);
#  endif
# endif

         freea (charset);
       }
#endif /* _LIBC || HAVE_ICONV */
    }

  return nullentry;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _nl_load_domain ( struct loaded_l10nfile __domain,
struct binding __domainbinding 
)

Definition at line 909 of file loadmsgcat.c.

{
  int fd;
  size_t size;
#ifdef _LIBC
  struct stat64 st;
#else
  struct stat st;
#endif
  struct mo_file_header *data = (struct mo_file_header *) -1;
  int use_mmap = 0;
  struct loaded_domain *domain;
  int revision;
  const char *nullentry;

  domain_file->decided = 1;
  domain_file->data = NULL;

  /* Note that it would be useless to store domainbinding in domain_file
     because domainbinding might be == NULL now but != NULL later (after
     a call to bind_textdomain_codeset).  */

  /* If the record does not represent a valid locale the FILENAME
     might be NULL.  This can happen when according to the given
     specification the locale file name is different for XPG and CEN
     syntax.  */
  if (domain_file->filename == NULL)
    return;

  /* Try to open the addressed file.  */
  fd = open (domain_file->filename, O_RDONLY | O_BINARY);
  if (fd == -1)
    return;

  /* We must know about the size of the file.  */
  if (
#ifdef _LIBC
      __builtin_expect (fstat64 (fd, &st) != 0, 0)
#else
      __builtin_expect (fstat (fd, &st) != 0, 0)
#endif
      || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
      || __builtin_expect (size < sizeof (struct mo_file_header), 0))
    {
      /* Something went wrong.  */
      close (fd);
      return;
    }

#ifdef HAVE_MMAP
  /* Now we are ready to load the file.  If mmap() is available we try
     this first.  If not available or it failed we try to load it.  */
  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
                                    MAP_PRIVATE, fd, 0);

  if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
    {
      /* mmap() call was successful.  */
      close (fd);
      use_mmap = 1;
    }
#endif

  /* If the data is not yet available (i.e. mmap'ed) we try to load
     it manually.  */
  if (data == (struct mo_file_header *) -1)
    {
      size_t to_read;
      char *read_ptr;

      data = (struct mo_file_header *) malloc (size);
      if (data == NULL)
       return;

      to_read = size;
      read_ptr = (char *) data;
      do
       {
         long int nb = (long int) read (fd, read_ptr, to_read);
         if (nb <= 0)
           {
#ifdef EINTR
             if (nb == -1 && errno == EINTR)
              continue;
#endif
             close (fd);
             return;
           }
         read_ptr += nb;
         to_read -= nb;
       }
      while (to_read > 0);

      close (fd);
    }

  /* Using the magic number we can test whether it really is a message
     catalog file.  */
  if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
                     0))
    {
      /* The magic number is wrong: not a message catalog file.  */
#ifdef HAVE_MMAP
      if (use_mmap)
       munmap ((caddr_t) data, size);
      else
#endif
       free (data);
      return;
    }

  domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
  if (domain == NULL)
    return;
  domain_file->data = domain;

  domain->data = (char *) data;
  domain->use_mmap = use_mmap;
  domain->mmap_size = size;
  domain->must_swap = data->magic != _MAGIC;
  domain->malloced = NULL;

  /* Fill in the information about the available tables.  */
  revision = W (domain->must_swap, data->revision);
  /* We support only the major revisions 0 and 1.  */
  switch (revision >> 16)
    {
    case 0:
    case 1:
      domain->nstrings = W (domain->must_swap, data->nstrings);
      domain->orig_tab = (const struct string_desc *)
       ((char *) data + W (domain->must_swap, data->orig_tab_offset));
      domain->trans_tab = (const struct string_desc *)
       ((char *) data + W (domain->must_swap, data->trans_tab_offset));
      domain->hash_size = W (domain->must_swap, data->hash_tab_size);
      domain->hash_tab =
       (domain->hash_size > 2
        ? (const nls_uint32 *)
          ((char *) data + W (domain->must_swap, data->hash_tab_offset))
        : NULL);
      domain->must_swap_hash_tab = domain->must_swap;

      /* Now dispatch on the minor revision.  */
      switch (revision & 0xffff)
       {
       case 0:
         domain->n_sysdep_strings = 0;
         domain->orig_sysdep_tab = NULL;
         domain->trans_sysdep_tab = NULL;
         break;
       case 1:
       default:
         {
           nls_uint32 n_sysdep_strings;

           if (domain->hash_tab == NULL)
             /* This is invalid.  These minor revisions need a hash table.  */
             goto invalid;

           n_sysdep_strings =
             W (domain->must_swap, data->n_sysdep_strings);
           if (n_sysdep_strings > 0)
             {
              nls_uint32 n_sysdep_segments;
              const struct sysdep_segment *sysdep_segments;
              const char **sysdep_segment_values;
              const nls_uint32 *orig_sysdep_tab;
              const nls_uint32 *trans_sysdep_tab;
              nls_uint32 n_inmem_sysdep_strings;
              size_t memneed;
              char *mem;
              struct sysdep_string_desc *inmem_orig_sysdep_tab;
              struct sysdep_string_desc *inmem_trans_sysdep_tab;
              nls_uint32 *inmem_hash_tab;
              unsigned int i, j;

              /* Get the values of the system dependent segments.  */
              n_sysdep_segments =
                W (domain->must_swap, data->n_sysdep_segments);
              sysdep_segments = (const struct sysdep_segment *)
                ((char *) data
                 + W (domain->must_swap, data->sysdep_segments_offset));
              sysdep_segment_values =
                alloca (n_sysdep_segments * sizeof (const char *));
              for (i = 0; i < n_sysdep_segments; i++)
                {
                  const char *name =
                    (char *) data
                    + W (domain->must_swap, sysdep_segments[i].offset);
                  nls_uint32 namelen =
                    W (domain->must_swap, sysdep_segments[i].length);

                  if (!(namelen > 0 && name[namelen - 1] == '\0'))
                    {
                     freea (sysdep_segment_values);
                     goto invalid;
                    }

                  sysdep_segment_values[i] = get_sysdep_segment_value (name);
                }

              orig_sysdep_tab = (const nls_uint32 *)
                ((char *) data
                 + W (domain->must_swap, data->orig_sysdep_tab_offset));
              trans_sysdep_tab = (const nls_uint32 *)
                ((char *) data
                 + W (domain->must_swap, data->trans_sysdep_tab_offset));

              /* Compute the amount of additional memory needed for the
                 system dependent strings and the augmented hash table.
                 At the same time, also drop string pairs which refer to
                 an undefined system dependent segment.  */
              n_inmem_sysdep_strings = 0;
              memneed = domain->hash_size * sizeof (nls_uint32);
              for (i = 0; i < n_sysdep_strings; i++)
                {
                  int valid = 1;
                  size_t needs[2];

                  for (j = 0; j < 2; j++)
                    {
                     const struct sysdep_string *sysdep_string =
                       (const struct sysdep_string *)
                       ((char *) data
                        + W (domain->must_swap,
                            j == 0
                            ? orig_sysdep_tab[i]
                            : trans_sysdep_tab[i]));
                     size_t need = 0;
                     const struct segment_pair *p = sysdep_string->segments;

                     if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
                       for (p = sysdep_string->segments;; p++)
                         {
                           nls_uint32 sysdepref;

                           need += W (domain->must_swap, p->segsize);

                           sysdepref = W (domain->must_swap, p->sysdepref);
                           if (sysdepref == SEGMENTS_END)
                            break;

                           if (sysdepref >= n_sysdep_segments)
                            {
                              /* Invalid.  */
                              freea (sysdep_segment_values);
                              goto invalid;
                            }

                           if (sysdep_segment_values[sysdepref] == NULL)
                            {
                              /* This particular string pair is invalid.  */
                              valid = 0;
                              break;
                            }

                           need += strlen (sysdep_segment_values[sysdepref]);
                         }

                     needs[j] = need;
                     if (!valid)
                       break;
                    }

                  if (valid)
                    {
                     n_inmem_sysdep_strings++;
                     memneed += needs[0] + needs[1];
                    }
                }
              memneed += 2 * n_inmem_sysdep_strings
                        * sizeof (struct sysdep_string_desc);

              if (n_inmem_sysdep_strings > 0)
                {
                  unsigned int k;

                  /* Allocate additional memory.  */
                  mem = (char *) malloc (memneed);
                  if (mem == NULL)
                    goto invalid;

                  domain->malloced = mem;
                  inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
                  mem += n_inmem_sysdep_strings
                        * sizeof (struct sysdep_string_desc);
                  inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
                  mem += n_inmem_sysdep_strings
                        * sizeof (struct sysdep_string_desc);
                  inmem_hash_tab = (nls_uint32 *) mem;
                  mem += domain->hash_size * sizeof (nls_uint32);

                  /* Compute the system dependent strings.  */
                  k = 0;
                  for (i = 0; i < n_sysdep_strings; i++)
                    {
                     int valid = 1;

                     for (j = 0; j < 2; j++)
                       {
                         const struct sysdep_string *sysdep_string =
                           (const struct sysdep_string *)
                           ((char *) data
                            + W (domain->must_swap,
                                j == 0
                                ? orig_sysdep_tab[i]
                                : trans_sysdep_tab[i]));
                         const struct segment_pair *p =
                           sysdep_string->segments;

                         if (W (domain->must_swap, p->sysdepref)
                            != SEGMENTS_END)
                           for (p = sysdep_string->segments;; p++)
                            {
                              nls_uint32 sysdepref;

                              sysdepref =
                                W (domain->must_swap, p->sysdepref);
                              if (sysdepref == SEGMENTS_END)
                                break;

                              if (sysdep_segment_values[sysdepref] == NULL)
                                {
                                  /* This particular string pair is
                                    invalid.  */
                                  valid = 0;
                                  break;
                                }
                            }

                         if (!valid)
                           break;
                       }

                     if (valid)
                       {
                         for (j = 0; j < 2; j++)
                           {
                            const struct sysdep_string *sysdep_string =
                              (const struct sysdep_string *)
                              ((char *) data
                               + W (domain->must_swap,
                                   j == 0
                                   ? orig_sysdep_tab[i]
                                   : trans_sysdep_tab[i]));
                            const char *static_segments =
                              (char *) data
                              + W (domain->must_swap, sysdep_string->offset);
                            const struct segment_pair *p =
                              sysdep_string->segments;

                            /* Concatenate the segments, and fill
                               inmem_orig_sysdep_tab[k] (for j == 0) and
                               inmem_trans_sysdep_tab[k] (for j == 1).  */

                            struct sysdep_string_desc *inmem_tab_entry =
                              (j == 0
                               ? inmem_orig_sysdep_tab
                               : inmem_trans_sysdep_tab)
                              + k;

                            if (W (domain->must_swap, p->sysdepref)
                                == SEGMENTS_END)
                              {
                                /* Only one static segment.  */
                                inmem_tab_entry->length =
                                  W (domain->must_swap, p->segsize);
                                inmem_tab_entry->pointer = static_segments;
                              }
                            else
                              {
                                inmem_tab_entry->pointer = mem;

                                for (p = sysdep_string->segments;; p++)
                                  {
                                   nls_uint32 segsize =
                                     W (domain->must_swap, p->segsize);
                                   nls_uint32 sysdepref =
                                     W (domain->must_swap, p->sysdepref);
                                   size_t n;

                                   if (segsize > 0)
                                     {
                                       memcpy (mem, static_segments, segsize);
                                       mem += segsize;
                                       static_segments += segsize;
                                     }

                                   if (sysdepref == SEGMENTS_END)
                                     break;

                                   n = strlen (sysdep_segment_values[sysdepref]);
                                   memcpy (mem, sysdep_segment_values[sysdepref], n);
                                   mem += n;
                                  }

                                inmem_tab_entry->length =
                                  mem - inmem_tab_entry->pointer;
                              }
                           }

                         k++;
                       }
                    }
                  if (k != n_inmem_sysdep_strings)
                    abort ();

                  /* Compute the augmented hash table.  */
                  for (i = 0; i < domain->hash_size; i++)
                    inmem_hash_tab[i] =
                     W (domain->must_swap_hash_tab, domain->hash_tab[i]);
                  for (i = 0; i < n_inmem_sysdep_strings; i++)
                    {
                     const char *msgid = inmem_orig_sysdep_tab[i].pointer;
                     nls_uint32 hash_val = hash_string (msgid);
                     nls_uint32 idx = hash_val % domain->hash_size;
                     nls_uint32 incr =
                       1 + (hash_val % (domain->hash_size - 2));

                     for (;;)
                       {
                         if (inmem_hash_tab[idx] == 0)
                           {
                            /* Hash table entry is empty.  Use it.  */
                            inmem_hash_tab[idx] = 1 + domain->nstrings + i;
                            break;
                           }

                         if (idx >= domain->hash_size - incr)
                           idx -= domain->hash_size - incr;
                         else
                           idx += incr;
                       }
                    }

                  domain->n_sysdep_strings = n_inmem_sysdep_strings;
                  domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
                  domain->trans_sysdep_tab = inmem_trans_sysdep_tab;

                  domain->hash_tab = inmem_hash_tab;
                  domain->must_swap_hash_tab = 0;
                }
              else
                {
                  domain->n_sysdep_strings = 0;
                  domain->orig_sysdep_tab = NULL;
                  domain->trans_sysdep_tab = NULL;
                }

              freea (sysdep_segment_values);
             }
           else
             {
              domain->n_sysdep_strings = 0;
              domain->orig_sysdep_tab = NULL;
              domain->trans_sysdep_tab = NULL;
             }
         }
         break;
       }
      break;
    default:
      /* This is an invalid revision.  */
    invalid:
      /* This is an invalid .mo file.  */
      if (domain->malloced)
       free (domain->malloced);
#ifdef HAVE_MMAP
      if (use_mmap)
       munmap ((caddr_t) data, size);
      else
#endif
       free (data);
      free (domain);
      domain_file->data = NULL;
      return;
    }

  /* Now initialize the character set converter from the character set
     the file is encoded with (found in the header entry) to the domain's
     specified character set or the locale's character set.  */
  nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);

  /* Also look for a plural specification.  */
  EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* _nl_locale_name ( int  category,
const char *  categoryname 
)

Definition at line 703 of file localename.c.

{
  const char *retval;

#ifndef WIN32

  /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
     On some systems this can be done by the 'setlocale' function itself.  */
# if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
  retval = setlocale (category, NULL);
# else
  /* Setting of LC_ALL overwrites all other.  */
  retval = getenv ("LC_ALL");
  if (retval == NULL || retval[0] == '\0')
    {
      /* Next comes the name of the desired category.  */
      retval = getenv (categoryname);
      if (retval == NULL || retval[0] == '\0')
       {
         /* Last possibility is the LANG environment variable.  */
         retval = getenv ("LANG");
         if (retval == NULL || retval[0] == '\0')
           /* We use C as the default domain.  POSIX says this is
              implementation defined.  */
           retval = "C";
       }
    }
# endif

  return retval;

#else /* WIN32 */

  /* Return an XPG style locale name language[_territory][@modifier].
     Don't even bother determining the codeset; it's not useful in this
     context, because message catalogs are not specific to a single
     codeset.  */

  LCID lcid;
  LANGID langid;
  int primary, sub;

  /* Let the user override the system settings through environment
     variables, as on POSIX systems.  */
  retval = getenv ("LC_ALL");
  if (retval != NULL && retval[0] != '\0')
    return retval;
  retval = getenv (categoryname);
  if (retval != NULL && retval[0] != '\0')
    return retval;
  retval = getenv ("LANG");
  if (retval != NULL && retval[0] != '\0')
    return retval;

  /* Use native Win32 API locale ID.  */
  lcid = GetThreadLocale ();

  /* Strip off the sorting rules, keep only the language part.  */
  langid = LANGIDFROMLCID (lcid);

  /* Split into language and territory part.  */
  primary = PRIMARYLANGID (langid);
  sub = SUBLANGID (langid);

  /* Dispatch on language.
     See also http://www.unicode.org/unicode/onlinedat/languages.html .
     For details about languages, see http://www.ethnologue.com/ .  */
  switch (primary)
    {
    case LANG_AFRIKAANS: return "af_ZA";
    case LANG_ALBANIAN: return "sq_AL";
    case LANG_AMHARIC: return "am_ET";
    case LANG_ARABIC:
      switch (sub)
       {
       case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
       case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
       case SUBLANG_ARABIC_EGYPT: return "ar_EG";
       case SUBLANG_ARABIC_LIBYA: return "ar_LY";
       case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
       case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
       case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
       case SUBLANG_ARABIC_OMAN: return "ar_OM";
       case SUBLANG_ARABIC_YEMEN: return "ar_YE";
       case SUBLANG_ARABIC_SYRIA: return "ar_SY";
       case SUBLANG_ARABIC_JORDAN: return "ar_JO";
       case SUBLANG_ARABIC_LEBANON: return "ar_LB";
       case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
       case SUBLANG_ARABIC_UAE: return "ar_AE";
       case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
       case SUBLANG_ARABIC_QATAR: return "ar_QA";
       }
      return "ar";
    case LANG_ARMENIAN: return "hy_AM";
    case LANG_ASSAMESE: return "as_IN";
    case LANG_AZERI:
      switch (sub)
       {
       /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
       case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
       case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
       }
      return "az";
    case LANG_BASQUE:
      return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
    case LANG_BELARUSIAN: return "be_BY";
    case LANG_BENGALI:
      switch (sub)
       {
       case SUBLANG_BENGALI_INDIA: return "bn_IN";
       case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
       }
      return "bn";
    case LANG_BULGARIAN: return "bg_BG";
    case LANG_BURMESE: return "my_MM";
    case LANG_CAMBODIAN: return "km_KH";
    case LANG_CATALAN: return "ca_ES";
    case LANG_CHEROKEE: return "chr_US";
    case LANG_CHINESE:
      switch (sub)
       {
       case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
       case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
       case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
       case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
       case SUBLANG_CHINESE_MACAU: return "zh_MO";
       }
      return "zh";
    case LANG_CROATIAN:            /* LANG_CROATIAN == LANG_SERBIAN
                             * What used to be called Serbo-Croatian
                             * should really now be two separate
                             * languages because of political reasons.
                             * (Says tml, who knows nothing about Serbian
                             * or Croatian.)
                             * (I can feel those flames coming already.)
                             */
      switch (sub)
       {
       case SUBLANG_DEFAULT: return "hr_HR";
       case SUBLANG_SERBIAN_LATIN: return "sr_CS";
       case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
       }
      return "hr";
    case LANG_CZECH: return "cs_CZ";
    case LANG_DANISH: return "da_DK";
    case LANG_DIVEHI: return "dv_MV";
    case LANG_DUTCH:
      switch (sub)
       {
       case SUBLANG_DUTCH: return "nl_NL";
       case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
       }
      return "nl";
    case LANG_EDO: return "bin_NG";
    case LANG_ENGLISH:
      switch (sub)
       {
       /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
        * English was the language spoken in England.
        * Oh well.
        */
       case SUBLANG_ENGLISH_US: return "en_US";
       case SUBLANG_ENGLISH_UK: return "en_GB";
       case SUBLANG_ENGLISH_AUS: return "en_AU";
       case SUBLANG_ENGLISH_CAN: return "en_CA";
       case SUBLANG_ENGLISH_NZ: return "en_NZ";
       case SUBLANG_ENGLISH_EIRE: return "en_IE";
       case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
       case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
       case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
       case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
       case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
       case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
       case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
       case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
       case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
       case SUBLANG_ENGLISH_INDIA: return "en_IN";
       case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
       case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
       }
      return "en";
    case LANG_ESTONIAN: return "et_EE";
    case LANG_FAEROESE: return "fo_FO";
    case LANG_FARSI: return "fa_IR";
    case LANG_FINNISH: return "fi_FI";
    case LANG_FRENCH:
      switch (sub)
       {
       case SUBLANG_FRENCH: return "fr_FR";
       case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
       case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
       case SUBLANG_FRENCH_SWISS: return "fr_CH";
       case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
       case SUBLANG_FRENCH_MONACO: return "fr_MC";
       case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
       case SUBLANG_FRENCH_REUNION: return "fr_RE";
       case SUBLANG_FRENCH_CONGO: return "fr_CG";
       case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
       case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
       case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
       case SUBLANG_FRENCH_MALI: return "fr_ML";
       case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
       case SUBLANG_FRENCH_HAITI: return "fr_HT";
       }
      return "fr";
    case LANG_FRISIAN: return "fy_NL";
    case LANG_FULFULDE:
      /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
      return "ff_NG";
    case LANG_GAELIC:
      switch (sub)
       {
       case 0x01: /* SCOTTISH */ return "gd_GB";
       case 0x02: /* IRISH */ return "ga_IE";
       }
      return "C";
    case LANG_GALICIAN: return "gl_ES";
    case LANG_GEORGIAN: return "ka_GE";
    case LANG_GERMAN:
      switch (sub)
       {
       case SUBLANG_GERMAN: return "de_DE";
       case SUBLANG_GERMAN_SWISS: return "de_CH";
       case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
       case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
       case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
       }
      return "de";
    case LANG_GREEK: return "el_GR";
    case LANG_GUARANI: return "gn_PY";
    case LANG_GUJARATI: return "gu_IN";
    case LANG_HAUSA: return "ha_NG";
    case LANG_HAWAIIAN:
      /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
        or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
      return "cpe_US";
    case LANG_HEBREW: return "he_IL";
    case LANG_HINDI: return "hi_IN";
    case LANG_HUNGARIAN: return "hu_HU";
    case LANG_IBIBIO: return "nic_NG";
    case LANG_ICELANDIC: return "is_IS";
    case LANG_IGBO: return "ig_NG";
    case LANG_INDONESIAN: return "id_ID";
    case LANG_INUKTITUT: return "iu_CA";
    case LANG_ITALIAN:
      switch (sub)
       {
       case SUBLANG_ITALIAN: return "it_IT";
       case SUBLANG_ITALIAN_SWISS: return "it_CH";
       }
      return "it";
    case LANG_JAPANESE: return "ja_JP";
    case LANG_KANNADA: return "kn_IN";
    case LANG_KANURI: return "kr_NG";
    case LANG_KASHMIRI:
      switch (sub)
       {
       case SUBLANG_DEFAULT: return "ks_PK";
       case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
       }
      return "ks";
    case LANG_KAZAK: return "kk_KZ";
    case LANG_KONKANI:
      /* FIXME: Adjust this when such locales appear on Unix.  */
      return "kok_IN";
    case LANG_KOREAN: return "ko_KR";
    case LANG_KYRGYZ: return "ky_KG";
    case LANG_LAO: return "lo_LA";
    case LANG_LATIN: return "la_VA";
    case LANG_LATVIAN: return "lv_LV";
    case LANG_LITHUANIAN: return "lt_LT";
    case LANG_MACEDONIAN: return "mk_MK";
    case LANG_MALAY:
      switch (sub)
       {
       case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
       case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
       }
      return "ms";
    case LANG_MALAYALAM: return "ml_IN";
    case LANG_MALTESE: return "mt_MT";
    case LANG_MANIPURI:
      /* FIXME: Adjust this when such locales appear on Unix.  */
      return "mni_IN";
    case LANG_MARATHI: return "mr_IN";
    case LANG_MONGOLIAN:
      return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
    case LANG_NEPALI:
      switch (sub)
       {
       case SUBLANG_DEFAULT: return "ne_NP";
       case SUBLANG_NEPALI_INDIA: return "ne_IN";
       }
      return "ne";
    case LANG_NORWEGIAN:
      switch (sub)
       {
       case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO";
       case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
       }
      return "no";
    case LANG_ORIYA: return "or_IN";
    case LANG_OROMO: return "om_ET";
    case LANG_PAPIAMENTU: return "pap_AN";
    case LANG_PASHTO:
      return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
    case LANG_POLISH: return "pl_PL";
    case LANG_PORTUGUESE:
      switch (sub)
       {
       case SUBLANG_PORTUGUESE: return "pt_PT";
       /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
          Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
       case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
       }
      return "pt";
    case LANG_PUNJABI:
      switch (sub)
       {
       case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
       case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
       }
      return "pa";
    case LANG_RHAETO_ROMANCE: return "rm_CH";
    case LANG_ROMANIAN:
      switch (sub)
       {
       case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
       case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
       }
      return "ro";
    case LANG_RUSSIAN:
      return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
    case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
    case LANG_SANSKRIT: return "sa_IN";
    case LANG_SINDHI:
      switch (sub)
       {
       case SUBLANG_SINDHI_INDIA: return "sd_IN";
       case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
       }
      return "sd";
    case LANG_SINHALESE: return "si_LK";
    case LANG_SLOVAK: return "sk_SK";
    case LANG_SLOVENIAN: return "sl_SI";
    case LANG_SOMALI: return "so_SO";
    case LANG_SORBIAN:
      /* FIXME: Adjust this when such locales appear on Unix.  */
      return "wen_DE";
    case LANG_SPANISH:
      switch (sub)
       {
       case SUBLANG_SPANISH: return "es_ES";
       case SUBLANG_SPANISH_MEXICAN: return "es_MX";
       case SUBLANG_SPANISH_MODERN:
         return "es_ES@modern";    /* not seen on Unix */
       case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
       case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
       case SUBLANG_SPANISH_PANAMA: return "es_PA";
       case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
       case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
       case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
       case SUBLANG_SPANISH_PERU: return "es_PE";
       case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
       case SUBLANG_SPANISH_ECUADOR: return "es_EC";
       case SUBLANG_SPANISH_CHILE: return "es_CL";
       case SUBLANG_SPANISH_URUGUAY: return "es_UY";
       case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
       case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
       case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
       case SUBLANG_SPANISH_HONDURAS: return "es_HN";
       case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
       case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
       }
      return "es";
    case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
    case LANG_SWAHILI: return "sw_KE";
    case LANG_SWEDISH:
      switch (sub)
       {
       case SUBLANG_DEFAULT: return "sv_SE";
       case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
       }
      return "sv";
    case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
    case LANG_TAGALOG: return "tl_PH";
    case LANG_TAJIK: return "tg_TJ";
    case LANG_TAMAZIGHT:
      switch (sub)
       {
       /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
       case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
       case SUBLANG_TAMAZIGHT_LATIN: return "ber_MA@latin";
       }
      return "ber_MA";
    case LANG_TAMIL:
      return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
    case LANG_TATAR: return "tt_RU";
    case LANG_TELUGU: return "te_IN";
    case LANG_THAI: return "th_TH";
    case LANG_TIBETAN: return "bo_CN";
    case LANG_TIGRINYA:
      switch (sub)
       {
       case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
       case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
       }
      return "ti";
    case LANG_TSONGA: return "ts_ZA";
    case LANG_TSWANA: return "tn_BW";
    case LANG_TURKISH: return "tr_TR";
    case LANG_TURKMEN: return "tk_TM";
    case LANG_UKRAINIAN: return "uk_UA";
    case LANG_URDU:
      switch (sub)
       {
       case SUBLANG_URDU_PAKISTAN: return "ur_PK";
       case SUBLANG_URDU_INDIA: return "ur_IN";
       }
      return "ur";
    case LANG_UZBEK:
      switch (sub)
       {
       case SUBLANG_UZBEK_LATIN: return "uz_UZ";
       case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
       }
      return "uz";
    case LANG_VENDA: return "ve_ZA";
    case LANG_VIETNAMESE: return "vi_VN";
    case LANG_WELSH: return "cy_GB";
    case LANG_XHOSA: return "xh_ZA";
    case LANG_YI: return "sit_CN";
    case LANG_YIDDISH: return "yi_IL";
    case LANG_YORUBA: return "yo_NG";
    case LANG_ZULU: return "zu_ZA";
    default: return "C";
    }

#endif
}

Here is the caller graph for this function:

void _nl_unload_domain ( struct loaded_domain __domain)
char* libintl_dcigettext ( const char *  __domainname,
const char *  __msgid1,
const char *  __msgid2,
int  __plural,
unsigned long int  __n,
int  __category 
)

Variable Documentation

Definition at line 497 of file loadmsgcat.c.

Definition at line 64 of file gettextP.h.