Back to index

tetex-bin  3.0
Defines | Functions | Variables
loadmsgcat.c File Reference
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include "gmo.h"
#include "gettextP.h"
#include "hash-string.h"
#include "plural-exp.h"

Go to the source code of this file.

Defines

#define _GNU_SOURCE   1
#define PRId8   "d"
#define PRIi8   "i"
#define PRIo8   "o"
#define PRIu8   "u"
#define PRIx8   "x"
#define PRIX8   "X"
#define PRId16   "d"
#define PRIi16   "i"
#define PRIo16   "o"
#define PRIu16   "u"
#define PRIx16   "x"
#define PRIX16   "X"
#define PRId32   "d"
#define PRIi32   "i"
#define PRIo32   "o"
#define PRIu32   "u"
#define PRIx32   "x"
#define PRIX32   "X"
#define PRId64   (sizeof (long) == 8 ? "ld" : "lld")
#define PRIi64   (sizeof (long) == 8 ? "li" : "lli")
#define PRIo64   (sizeof (long) == 8 ? "lo" : "llo")
#define PRIu64   (sizeof (long) == 8 ? "lu" : "llu")
#define PRIx64   (sizeof (long) == 8 ? "lx" : "llx")
#define PRIX64   (sizeof (long) == 8 ? "lX" : "llX")
#define PRIdLEAST8   "d"
#define PRIiLEAST8   "i"
#define PRIoLEAST8   "o"
#define PRIuLEAST8   "u"
#define PRIxLEAST8   "x"
#define PRIXLEAST8   "X"
#define PRIdLEAST16   "d"
#define PRIiLEAST16   "i"
#define PRIoLEAST16   "o"
#define PRIuLEAST16   "u"
#define PRIxLEAST16   "x"
#define PRIXLEAST16   "X"
#define PRIdLEAST32   "d"
#define PRIiLEAST32   "i"
#define PRIoLEAST32   "o"
#define PRIuLEAST32   "u"
#define PRIxLEAST32   "x"
#define PRIXLEAST32   "X"
#define PRIdLEAST64   PRId64
#define PRIiLEAST64   PRIi64
#define PRIoLEAST64   PRIo64
#define PRIuLEAST64   PRIu64
#define PRIxLEAST64   PRIx64
#define PRIXLEAST64   PRIX64
#define PRIdFAST8   "d"
#define PRIiFAST8   "i"
#define PRIoFAST8   "o"
#define PRIuFAST8   "u"
#define PRIxFAST8   "x"
#define PRIXFAST8   "X"
#define PRIdFAST16   "d"
#define PRIiFAST16   "i"
#define PRIoFAST16   "o"
#define PRIuFAST16   "u"
#define PRIxFAST16   "x"
#define PRIXFAST16   "X"
#define PRIdFAST32   "d"
#define PRIiFAST32   "i"
#define PRIoFAST32   "o"
#define PRIuFAST32   "u"
#define PRIxFAST32   "x"
#define PRIXFAST32   "X"
#define PRIdFAST64   PRId64
#define PRIiFAST64   PRIi64
#define PRIoFAST64   PRIo64
#define PRIuFAST64   PRIu64
#define PRIxFAST64   PRIx64
#define PRIXFAST64   PRIX64
#define PRIdMAX   (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
#define PRIiMAX   (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
#define PRIoMAX   (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
#define PRIuMAX   (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
#define PRIxMAX   (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
#define PRIXMAX   (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
#define PRIdPTR
#define PRIiPTR
#define PRIoPTR
#define PRIuPTR
#define PRIxPTR
#define PRIXPTR
#define alloca(n)   malloc (n)
#define freea(p)   free (p)
#define O_BINARY   0

Functions

char * alloca ()
static const char * get_sysdep_segment_value (const char *name)
const char *internal_function _nl_init_domain_conv (struct loaded_l10nfile *domain_file, struct loaded_domain *domain, struct binding *domainbinding)
void internal_function _nl_free_domain_conv (struct loaded_domain *domain)
void internal_function _nl_load_domain (struct loaded_l10nfile *domain_file, struct binding *domainbinding)

Variables

int _nl_msg_cat_cntr

Define Documentation

#define _GNU_SOURCE   1

Definition at line 23 of file loadmsgcat.c.

#define alloca (   n)    malloc (n)

Definition at line 472 of file loadmsgcat.c.

#define freea (   p)    free (p)

Definition at line 473 of file loadmsgcat.c.

#define O_BINARY   0

Definition at line 490 of file loadmsgcat.c.

#define PRId16   "d"

Definition at line 125 of file loadmsgcat.c.

#define PRId32   "d"

Definition at line 149 of file loadmsgcat.c.

#define PRId64   (sizeof (long) == 8 ? "ld" : "lld")

Definition at line 173 of file loadmsgcat.c.

#define PRId8   "d"

Definition at line 101 of file loadmsgcat.c.

#define PRIdFAST16   "d"

Definition at line 317 of file loadmsgcat.c.

#define PRIdFAST32   "d"

Definition at line 341 of file loadmsgcat.c.

#define PRIdFAST64   PRId64

Definition at line 365 of file loadmsgcat.c.

#define PRIdFAST8   "d"

Definition at line 293 of file loadmsgcat.c.

#define PRIdLEAST16   "d"

Definition at line 221 of file loadmsgcat.c.

#define PRIdLEAST32   "d"

Definition at line 245 of file loadmsgcat.c.

#define PRIdLEAST64   PRId64

Definition at line 269 of file loadmsgcat.c.

#define PRIdLEAST8   "d"

Definition at line 197 of file loadmsgcat.c.

#define PRIdMAX   (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")

Definition at line 389 of file loadmsgcat.c.

#define PRIdPTR
Value:
(sizeof (void *) == sizeof (long) ? "ld" : \
   sizeof (void *) == sizeof (int) ? "d" : \
   "lld")

Definition at line 413 of file loadmsgcat.c.

#define PRIi16   "i"

Definition at line 129 of file loadmsgcat.c.

#define PRIi32   "i"

Definition at line 153 of file loadmsgcat.c.

#define PRIi64   (sizeof (long) == 8 ? "li" : "lli")

Definition at line 177 of file loadmsgcat.c.

#define PRIi8   "i"

Definition at line 105 of file loadmsgcat.c.

#define PRIiFAST16   "i"

Definition at line 321 of file loadmsgcat.c.

#define PRIiFAST32   "i"

Definition at line 345 of file loadmsgcat.c.

#define PRIiFAST64   PRIi64

Definition at line 369 of file loadmsgcat.c.

#define PRIiFAST8   "i"

Definition at line 297 of file loadmsgcat.c.

#define PRIiLEAST16   "i"

Definition at line 225 of file loadmsgcat.c.

#define PRIiLEAST32   "i"

Definition at line 249 of file loadmsgcat.c.

#define PRIiLEAST64   PRIi64

Definition at line 273 of file loadmsgcat.c.

#define PRIiLEAST8   "i"

Definition at line 201 of file loadmsgcat.c.

#define PRIiMAX   (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")

Definition at line 393 of file loadmsgcat.c.

#define PRIiPTR
Value:
(sizeof (void *) == sizeof (long) ? "li" : \
   sizeof (void *) == sizeof (int) ? "i" : \
   "lli")

Definition at line 420 of file loadmsgcat.c.

#define PRIo16   "o"

Definition at line 133 of file loadmsgcat.c.

#define PRIo32   "o"

Definition at line 157 of file loadmsgcat.c.

#define PRIo64   (sizeof (long) == 8 ? "lo" : "llo")

Definition at line 181 of file loadmsgcat.c.

#define PRIo8   "o"

Definition at line 109 of file loadmsgcat.c.

#define PRIoFAST16   "o"

Definition at line 325 of file loadmsgcat.c.

#define PRIoFAST32   "o"

Definition at line 349 of file loadmsgcat.c.

#define PRIoFAST64   PRIo64

Definition at line 373 of file loadmsgcat.c.

#define PRIoFAST8   "o"

Definition at line 301 of file loadmsgcat.c.

#define PRIoLEAST16   "o"

Definition at line 229 of file loadmsgcat.c.

#define PRIoLEAST32   "o"

Definition at line 253 of file loadmsgcat.c.

#define PRIoLEAST64   PRIo64

Definition at line 277 of file loadmsgcat.c.

#define PRIoLEAST8   "o"

Definition at line 205 of file loadmsgcat.c.

#define PRIoMAX   (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")

Definition at line 397 of file loadmsgcat.c.

#define PRIoPTR
Value:
(sizeof (void *) == sizeof (long) ? "lo" : \
   sizeof (void *) == sizeof (int) ? "o" : \
   "llo")

Definition at line 427 of file loadmsgcat.c.

#define PRIu16   "u"

Definition at line 137 of file loadmsgcat.c.

#define PRIu32   "u"

Definition at line 161 of file loadmsgcat.c.

#define PRIu64   (sizeof (long) == 8 ? "lu" : "llu")

Definition at line 185 of file loadmsgcat.c.

#define PRIu8   "u"

Definition at line 113 of file loadmsgcat.c.

#define PRIuFAST16   "u"

Definition at line 329 of file loadmsgcat.c.

#define PRIuFAST32   "u"

Definition at line 353 of file loadmsgcat.c.

#define PRIuFAST64   PRIu64

Definition at line 377 of file loadmsgcat.c.

#define PRIuFAST8   "u"

Definition at line 305 of file loadmsgcat.c.

#define PRIuLEAST16   "u"

Definition at line 233 of file loadmsgcat.c.

#define PRIuLEAST32   "u"

Definition at line 257 of file loadmsgcat.c.

#define PRIuLEAST64   PRIu64

Definition at line 281 of file loadmsgcat.c.

#define PRIuLEAST8   "u"

Definition at line 209 of file loadmsgcat.c.

#define PRIuMAX   (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")

Definition at line 401 of file loadmsgcat.c.

#define PRIuPTR
Value:
(sizeof (void *) == sizeof (long) ? "lu" : \
   sizeof (void *) == sizeof (int) ? "u" : \
   "llu")

Definition at line 434 of file loadmsgcat.c.

#define PRIx16   "x"

Definition at line 141 of file loadmsgcat.c.

#define PRIX16   "X"

Definition at line 145 of file loadmsgcat.c.

#define PRIx32   "x"

Definition at line 165 of file loadmsgcat.c.

#define PRIX32   "X"

Definition at line 169 of file loadmsgcat.c.

#define PRIx64   (sizeof (long) == 8 ? "lx" : "llx")

Definition at line 189 of file loadmsgcat.c.

#define PRIX64   (sizeof (long) == 8 ? "lX" : "llX")

Definition at line 193 of file loadmsgcat.c.

#define PRIx8   "x"

Definition at line 117 of file loadmsgcat.c.

#define PRIX8   "X"

Definition at line 121 of file loadmsgcat.c.

#define PRIxFAST16   "x"

Definition at line 333 of file loadmsgcat.c.

#define PRIXFAST16   "X"

Definition at line 337 of file loadmsgcat.c.

#define PRIxFAST32   "x"

Definition at line 357 of file loadmsgcat.c.

#define PRIXFAST32   "X"

Definition at line 361 of file loadmsgcat.c.

#define PRIxFAST64   PRIx64

Definition at line 381 of file loadmsgcat.c.

#define PRIXFAST64   PRIX64

Definition at line 385 of file loadmsgcat.c.

#define PRIxFAST8   "x"

Definition at line 309 of file loadmsgcat.c.

#define PRIXFAST8   "X"

Definition at line 313 of file loadmsgcat.c.

#define PRIxLEAST16   "x"

Definition at line 237 of file loadmsgcat.c.

#define PRIXLEAST16   "X"

Definition at line 241 of file loadmsgcat.c.

#define PRIxLEAST32   "x"

Definition at line 261 of file loadmsgcat.c.

#define PRIXLEAST32   "X"

Definition at line 265 of file loadmsgcat.c.

#define PRIxLEAST64   PRIx64

Definition at line 285 of file loadmsgcat.c.

#define PRIXLEAST64   PRIX64

Definition at line 289 of file loadmsgcat.c.

#define PRIxLEAST8   "x"

Definition at line 213 of file loadmsgcat.c.

#define PRIXLEAST8   "X"

Definition at line 217 of file loadmsgcat.c.

#define PRIxMAX   (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")

Definition at line 405 of file loadmsgcat.c.

#define PRIXMAX   (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")

Definition at line 409 of file loadmsgcat.c.

#define PRIxPTR
Value:
(sizeof (void *) == sizeof (long) ? "lx" : \
   sizeof (void *) == sizeof (int) ? "x" : \
   "llx")

Definition at line 441 of file loadmsgcat.c.

#define PRIXPTR
Value:
(sizeof (void *) == sizeof (long) ? "lX" : \
   sizeof (void *) == sizeof (int) ? "X" : \
   "llX")

Definition at line 448 of file loadmsgcat.c.


Function Documentation

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* internal_function _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 internal_function _nl_load_domain ( struct loaded_l10nfile domain_file,
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:

char* alloca ( )
static const char* get_sysdep_segment_value ( const char *  name) [static]

Definition at line 502 of file loadmsgcat.c.

{
  /* Test for an ISO C 99 section 7.8.1 format string directive.
     Syntax:
     P R I { d | i | o | u | x | X }
     { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR }  */
  /* We don't use a table of 14 times 6 'const char *' strings here, because
     data relocations cost startup time.  */
  if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
    {
      if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
         || name[3] == 'x' || name[3] == 'X')
       {
         if (name[4] == '8' && name[5] == '\0')
           {
             if (name[3] == 'd')
              return PRId8;
             if (name[3] == 'i')
              return PRIi8;
             if (name[3] == 'o')
              return PRIo8;
             if (name[3] == 'u')
              return PRIu8;
             if (name[3] == 'x')
              return PRIx8;
             if (name[3] == 'X')
              return PRIX8;
             abort ();
           }
         if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
           {
             if (name[3] == 'd')
              return PRId16;
             if (name[3] == 'i')
              return PRIi16;
             if (name[3] == 'o')
              return PRIo16;
             if (name[3] == 'u')
              return PRIu16;
             if (name[3] == 'x')
              return PRIx16;
             if (name[3] == 'X')
              return PRIX16;
             abort ();
           }
         if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
           {
             if (name[3] == 'd')
              return PRId32;
             if (name[3] == 'i')
              return PRIi32;
             if (name[3] == 'o')
              return PRIo32;
             if (name[3] == 'u')
              return PRIu32;
             if (name[3] == 'x')
              return PRIx32;
             if (name[3] == 'X')
              return PRIX32;
             abort ();
           }
         if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
           {
             if (name[3] == 'd')
              return PRId64;
             if (name[3] == 'i')
              return PRIi64;
             if (name[3] == 'o')
              return PRIo64;
             if (name[3] == 'u')
              return PRIu64;
             if (name[3] == 'x')
              return PRIx64;
             if (name[3] == 'X')
              return PRIX64;
             abort ();
           }
         if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
             && name[7] == 'S' && name[8] == 'T')
           {
             if (name[9] == '8' && name[10] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdLEAST8;
                if (name[3] == 'i')
                  return PRIiLEAST8;
                if (name[3] == 'o')
                  return PRIoLEAST8;
                if (name[3] == 'u')
                  return PRIuLEAST8;
                if (name[3] == 'x')
                  return PRIxLEAST8;
                if (name[3] == 'X')
                  return PRIXLEAST8;
                abort ();
              }
             if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdLEAST16;
                if (name[3] == 'i')
                  return PRIiLEAST16;
                if (name[3] == 'o')
                  return PRIoLEAST16;
                if (name[3] == 'u')
                  return PRIuLEAST16;
                if (name[3] == 'x')
                  return PRIxLEAST16;
                if (name[3] == 'X')
                  return PRIXLEAST16;
                abort ();
              }
             if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdLEAST32;
                if (name[3] == 'i')
                  return PRIiLEAST32;
                if (name[3] == 'o')
                  return PRIoLEAST32;
                if (name[3] == 'u')
                  return PRIuLEAST32;
                if (name[3] == 'x')
                  return PRIxLEAST32;
                if (name[3] == 'X')
                  return PRIXLEAST32;
                abort ();
              }
             if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdLEAST64;
                if (name[3] == 'i')
                  return PRIiLEAST64;
                if (name[3] == 'o')
                  return PRIoLEAST64;
                if (name[3] == 'u')
                  return PRIuLEAST64;
                if (name[3] == 'x')
                  return PRIxLEAST64;
                if (name[3] == 'X')
                  return PRIXLEAST64;
                abort ();
              }
           }
         if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
             && name[7] == 'T')
           {
             if (name[8] == '8' && name[9] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdFAST8;
                if (name[3] == 'i')
                  return PRIiFAST8;
                if (name[3] == 'o')
                  return PRIoFAST8;
                if (name[3] == 'u')
                  return PRIuFAST8;
                if (name[3] == 'x')
                  return PRIxFAST8;
                if (name[3] == 'X')
                  return PRIXFAST8;
                abort ();
              }
             if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdFAST16;
                if (name[3] == 'i')
                  return PRIiFAST16;
                if (name[3] == 'o')
                  return PRIoFAST16;
                if (name[3] == 'u')
                  return PRIuFAST16;
                if (name[3] == 'x')
                  return PRIxFAST16;
                if (name[3] == 'X')
                  return PRIXFAST16;
                abort ();
              }
             if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdFAST32;
                if (name[3] == 'i')
                  return PRIiFAST32;
                if (name[3] == 'o')
                  return PRIoFAST32;
                if (name[3] == 'u')
                  return PRIuFAST32;
                if (name[3] == 'x')
                  return PRIxFAST32;
                if (name[3] == 'X')
                  return PRIXFAST32;
                abort ();
              }
             if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
              {
                if (name[3] == 'd')
                  return PRIdFAST64;
                if (name[3] == 'i')
                  return PRIiFAST64;
                if (name[3] == 'o')
                  return PRIoFAST64;
                if (name[3] == 'u')
                  return PRIuFAST64;
                if (name[3] == 'x')
                  return PRIxFAST64;
                if (name[3] == 'X')
                  return PRIXFAST64;
                abort ();
              }
           }
         if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
             && name[7] == '\0')
           {
             if (name[3] == 'd')
              return PRIdMAX;
             if (name[3] == 'i')
              return PRIiMAX;
             if (name[3] == 'o')
              return PRIoMAX;
             if (name[3] == 'u')
              return PRIuMAX;
             if (name[3] == 'x')
              return PRIxMAX;
             if (name[3] == 'X')
              return PRIXMAX;
             abort ();
           }
         if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
             && name[7] == '\0')
           {
             if (name[3] == 'd')
              return PRIdPTR;
             if (name[3] == 'i')
              return PRIiPTR;
             if (name[3] == 'o')
              return PRIoPTR;
             if (name[3] == 'u')
              return PRIuPTR;
             if (name[3] == 'x')
              return PRIxPTR;
             if (name[3] == 'X')
              return PRIXPTR;
             abort ();
           }
       }
    }
  /* Test for a glibc specific printf() format directive flag.  */
  if (name[0] == 'I' && name[1] == '\0')
    {
#if defined _LIBC || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
      /* The 'I' flag, in numeric format directives, replaces ASCII digits
        with the 'outdigits' defined in the LC_CTYPE locale facet.  This is
        used for Farsi (Persian) and maybe Arabic.  */
      return "I";
#else
      return "";
#endif
    }
  /* Other system dependent strings are not valid.  */
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 497 of file loadmsgcat.c.