Back to index

cell-binutils  2.17cvs20070401
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 PARAMS ((char *dest, const char *src))
static size_t argz_count__ PARAMS ((const char *argz, size_t len))
static size_t argz_count__ (char *argz, size_t len) const
static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep))
static void argz_stringify__ (char *argz, size_t len, int sep)
static char *argz_next__ PARAMS ((char *argz, size_t argz_len, const char *entry))
static char * argz_next__ (char *argz, size_t argz_len, const char *entry)
static int pop PARAMS ((int x))
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 (char *codeset, size_t name_len) const
static char * stpcpy (char *dest, const char *src)

Define Documentation

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

Definition at line 105 of file l10nflist.c.

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

Definition at line 165 of file l10nflist.c.

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

Definition at line 133 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 187 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 ( char *  codeset,
size_t  name_len 
) const

Definition at line 396 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__ ( char *  argz,
size_t  len 
) const [static]

Definition at line 90 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 146 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;
}

Here is the call graph for this function:

static void argz_stringify__ ( char *  argz,
size_t  len,
int  sep 
) [static]

Definition at line 118 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 char* stpcpy PARAMS ( (char *dest, const char *src ) [static]
static size_t argz_count__ PARAMS ( (const char *argz, size_t len ) [static]
static void argz_stringify__ PARAMS ( (char *argz, size_t len, int sep)  ) [static]
static char* argz_next__ PARAMS ( (char *argz, size_t argz_len, const char *entry)  ) [static]
static int pop PARAMS ( (int x ) [static]
static int pop ( int  x) [inline, static]

Definition at line 173 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;
}

Here is the caller graph for this function:

static char* stpcpy ( char *  dest,
const char *  src 
) [static]

Definition at line 445 of file l10nflist.c.

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