Back to index

tetex-bin  3.0
Defines | Functions
l10nflist.c File Reference
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <stdlib.h>
#include "loadinfo.h"

Go to the source code of this file.

Defines

#define _GNU_SOURCE   1
#define NULL   0
#define ISSLASH(C)   ((C) == '/')
#define IS_ABSOLUTE_PATH(P)   ISSLASH ((P)[0])
#define __argz_count(argz, len)   argz_count__ (argz, len)
#define __argz_stringify(argz, len, sep)   argz_stringify__ (argz, len, sep)
#define __argz_next(argz, len, entry)   argz_next__ (argz, len, entry)

Functions

static char * stpcpy (char *dest, const char *src)
static size_t argz_count__ (const char *argz, size_t len)
static void argz_stringify__ (char *argz, size_t len, int sep)
static char * argz_next__ (char *argz, size_t argz_len, const char *entry)
static int pop (int x)
struct loaded_l10nfile_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list, const char *dirlist, size_t dirlist_len, int mask, const char *language, const char *territory, const char *codeset, const char *normalized_codeset, const char *modifier, const char *special, const char *sponsor, const char *revision, const char *filename, int do_allocate)
const char * _nl_normalize_codeset (const char *codeset, size_t name_len)

Define Documentation

#define __argz_count (   argz,
  len 
)    argz_count__ (argz, len)

Definition at line 101 of file l10nflist.c.

#define __argz_next (   argz,
  len,
  entry 
)    argz_next__ (argz, len, entry)

Definition at line 150 of file l10nflist.c.

#define __argz_stringify (   argz,
  len,
  sep 
)    argz_stringify__ (argz, len, sep)

Definition at line 124 of file l10nflist.c.

#define _GNU_SOURCE   1

Definition at line 23 of file l10nflist.c.

#define IS_ABSOLUTE_PATH (   P)    ISSLASH ((P)[0])

Definition at line 80 of file l10nflist.c.

#define ISSLASH (   C)    ((C) == '/')

Definition at line 79 of file l10nflist.c.

#define NULL   0

Definition at line 46 of file l10nflist.c.


Function Documentation

struct loaded_l10nfile* _nl_make_l10nflist ( struct loaded_l10nfile **  l10nfile_list,
const char *  dirlist,
size_t  dirlist_len,
int  mask,
const char *  language,
const char *  territory,
const char *  codeset,
const char *  normalized_codeset,
const char *  modifier,
const char *  special,
const char *  sponsor,
const char *  revision,
const char *  filename,
int  do_allocate 
) [read]

Definition at line 169 of file l10nflist.c.

{
  char *abs_filename;
  struct loaded_l10nfile **lastp;
  struct loaded_l10nfile *retval;
  char *cp;
  size_t dirlist_count;
  size_t entries;
  int cnt;

  /* If LANGUAGE contains an absolute directory specification, we ignore
     DIRLIST.  */
  if (IS_ABSOLUTE_PATH (language))
    dirlist_len = 0;

  /* Allocate room for the full file name.  */
  abs_filename = (char *) malloc (dirlist_len
                              + strlen (language)
                              + ((mask & TERRITORY) != 0
                                 ? strlen (territory) + 1 : 0)
                              + ((mask & XPG_CODESET) != 0
                                 ? strlen (codeset) + 1 : 0)
                              + ((mask & XPG_NORM_CODESET) != 0
                                 ? strlen (normalized_codeset) + 1 : 0)
                              + (((mask & XPG_MODIFIER) != 0
                                  || (mask & CEN_AUDIENCE) != 0)
                                 ? strlen (modifier) + 1 : 0)
                              + ((mask & CEN_SPECIAL) != 0
                                 ? strlen (special) + 1 : 0)
                              + (((mask & CEN_SPONSOR) != 0
                                  || (mask & CEN_REVISION) != 0)
                                 ? (1 + ((mask & CEN_SPONSOR) != 0
                                        ? strlen (sponsor) : 0)
                                   + ((mask & CEN_REVISION) != 0
                                      ? strlen (revision) + 1 : 0)) : 0)
                              + 1 + strlen (filename) + 1);

  if (abs_filename == NULL)
    return NULL;

  /* Construct file name.  */
  cp = abs_filename;
  if (dirlist_len > 0)
    {
      memcpy (cp, dirlist, dirlist_len);
      __argz_stringify (cp, dirlist_len, PATH_SEPARATOR);
      cp += dirlist_len;
      cp[-1] = '/';
    }

  cp = stpcpy (cp, language);

  if ((mask & TERRITORY) != 0)
    {
      *cp++ = '_';
      cp = stpcpy (cp, territory);
    }
  if ((mask & XPG_CODESET) != 0)
    {
      *cp++ = '.';
      cp = stpcpy (cp, codeset);
    }
  if ((mask & XPG_NORM_CODESET) != 0)
    {
      *cp++ = '.';
      cp = stpcpy (cp, normalized_codeset);
    }
  if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
    {
      /* This component can be part of both syntaces but has different
        leading characters.  For CEN we use `+', else `@'.  */
      *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
      cp = stpcpy (cp, modifier);
    }
  if ((mask & CEN_SPECIAL) != 0)
    {
      *cp++ = '+';
      cp = stpcpy (cp, special);
    }
  if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
    {
      *cp++ = ',';
      if ((mask & CEN_SPONSOR) != 0)
       cp = stpcpy (cp, sponsor);
      if ((mask & CEN_REVISION) != 0)
       {
         *cp++ = '_';
         cp = stpcpy (cp, revision);
       }
    }

  *cp++ = '/';
  stpcpy (cp, filename);

  /* Look in list of already loaded domains whether it is already
     available.  */
  lastp = l10nfile_list;
  for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
    if (retval->filename != NULL)
      {
       int compare = strcmp (retval->filename, abs_filename);
       if (compare == 0)
         /* We found it!  */
         break;
       if (compare < 0)
         {
           /* It's not in the list.  */
           retval = NULL;
           break;
         }

       lastp = &retval->next;
      }

  if (retval != NULL || do_allocate == 0)
    {
      free (abs_filename);
      return retval;
    }

  dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1);

  /* Allocate a new loaded_l10nfile.  */
  retval =
    (struct loaded_l10nfile *)
    malloc (sizeof (*retval)
           + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0))
              * sizeof (struct loaded_l10nfile *)));
  if (retval == NULL)
    return NULL;

  retval->filename = abs_filename;

  /* We set retval->data to NULL here; it is filled in later.
     Setting retval->decided to 1 here means that retval does not
     correspond to a real file (dirlist_count > 1) or is not worth
     looking up (if an unnormalized codeset was specified).  */
  retval->decided = (dirlist_count > 1
                   || ((mask & XPG_CODESET) != 0
                      && (mask & XPG_NORM_CODESET) != 0));
  retval->data = NULL;

  retval->next = *lastp;
  *lastp = retval;

  entries = 0;
  /* Recurse to fill the inheritance list of RETVAL.
     If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL
     entry does not correspond to a real file; retval->filename contains
     colons.  In this case we loop across all elements of DIRLIST and
     across all bit patterns dominated by MASK.
     If the DIRLIST is a single directory or entirely redundant (i.e.
     DIRLIST_COUNT == 1), we loop across all bit patterns dominated by
     MASK, excluding MASK itself.
     In either case, we loop down from MASK to 0.  This has the effect
     that the extra bits in the locale name are dropped in this order:
     first the modifier, then the territory, then the codeset, then the
     normalized_codeset.  */
  for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt)
    if ((cnt & ~mask) == 0
       && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
       && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
      {
       if (dirlist_count > 1)
         {
           /* Iterate over all elements of the DIRLIST.  */
           char *dir = NULL;

           while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
                 != NULL)
             retval->successor[entries++]
              = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1,
                                  cnt, language, territory, codeset,
                                  normalized_codeset, modifier, special,
                                  sponsor, revision, filename, 1);
         }
       else
         retval->successor[entries++]
           = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len,
                              cnt, language, territory, codeset,
                              normalized_codeset, modifier, special,
                              sponsor, revision, filename, 1);
      }
  retval->successor[entries] = NULL;

  return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* _nl_normalize_codeset ( const char *  codeset,
size_t  name_len 
)

Definition at line 368 of file l10nflist.c.

{
  int len = 0;
  int only_digit = 1;
  char *retval;
  char *wp;
  size_t cnt;

  for (cnt = 0; cnt < name_len; ++cnt)
    if (isalnum ((unsigned char) codeset[cnt]))
      {
       ++len;

       if (isalpha ((unsigned char) codeset[cnt]))
         only_digit = 0;
      }

  retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);

  if (retval != NULL)
    {
      if (only_digit)
       wp = stpcpy (retval, "iso");
      else
       wp = retval;

      for (cnt = 0; cnt < name_len; ++cnt)
       if (isalpha ((unsigned char) codeset[cnt]))
         *wp++ = tolower ((unsigned char) codeset[cnt]);
       else if (isdigit ((unsigned char) codeset[cnt]))
         *wp++ = codeset[cnt];

      *wp = '\0';
    }

  return (const char *) retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static size_t argz_count__ ( const char *  argz,
size_t  len 
) [static]

Definition at line 88 of file l10nflist.c.

{
  size_t count = 0;
  while (len > 0)
    {
      size_t part_len = strlen (argz);
      argz += part_len + 1;
      len -= part_len + 1;
      count++;
    }
  return count;
}

Here is the call graph for this function:

static char* argz_next__ ( char *  argz,
size_t  argz_len,
const char *  entry 
) [static]

Definition at line 134 of file l10nflist.c.

{
  if (entry)
    {
      if (entry < argz + argz_len)
        entry = strchr (entry, '\0') + 1;

      return entry >= argz + argz_len ? NULL : (char *) entry;
    }
  else
    if (argz_len > 0)
      return argz;
    else
      return 0;
}
static void argz_stringify__ ( char *  argz,
size_t  len,
int  sep 
) [static]

Definition at line 112 of file l10nflist.c.

{
  while (len > 0)
    {
      size_t part_len = strlen (argz);
      argz += part_len;
      len -= part_len + 1;
      if (len > 0)
       *argz++ = sep;
    }
}

Here is the call graph for this function:

static int pop ( int  x) [inline, static]

Definition at line 156 of file l10nflist.c.

{
  /* We assume that no more than 16 bits are used.  */
  x = ((x & ~0x5555) >> 1) + (x & 0x5555);
  x = ((x & ~0x3333) >> 2) + (x & 0x3333);
  x = ((x >> 4) + x) & 0x0f0f;
  x = ((x >> 8) + x) & 0xff;

  return x;
}
static char * stpcpy ( char *  dest,
const char *  src 
) [static]

Definition at line 415 of file l10nflist.c.

{
  while ((*dest++ = *src++) != '\0')
    /* Do nothing. */ ;
  return dest - 1;
}

Here is the caller graph for this function: