Back to index

plt-scheme  4.2.1
Classes | Defines | Functions | Variables
localealias.c File Reference
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include "gettext.h"
#include "gettextP.h"

Go to the source code of this file.

Classes

struct  block_list
struct  alias_map

Defines

#define strchr   index
#define ADD_BLOCK(list, addr)
#define FREE_BLOCKS(list)
#define alloca(size)   (malloc (size))

Functions

char * alloca ()
char * getenv ()
void free ()
static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
static void extend_alias_table PARAMS ((void))
static int alias_compare PARAMS ((const struct alias_map *map1, const struct alias_map *map2))
const char * _nl_expand_alias (char *name) const
static size_t read_alias_file (char *fname, int fname_len) const
static void extend_alias_table ()
static int alias_compare (struct alias_map *map1, const struct alias_map *map2) const

Variables

static struct alias_mapmap
static size_t nmap = 0
static size_t maxmap = 0

Class Documentation

struct block_list

Definition at line 175 of file dcgettext.c.

Collaboration diagram for block_list:
Class Members
void * address
struct block_list * next
struct alias_map

Definition at line 116 of file localealias.c.

Class Members
const char * alias
const char * value

Define Documentation

#define ADD_BLOCK (   list,
  addr 
)
Value:
do {                                                                 \
    struct block_list *newp = (struct block_list *) malloc (sizeof (*newp));  \
    /* If we cannot get a free block we cannot add the new element to       \
       the list.  */                                                 \
    if (newp != NULL) {                                                     \
      newp->address = (addr);                                               \
      newp->next = (list);                                           \
      (list) = newp;                                                 \
    }                                                                \
  } while (0)

Definition at line 93 of file localealias.c.

#define alloca (   size)    (malloc (size))

Definition at line 112 of file localealias.c.

#define FREE_BLOCKS (   list)
Value:
do {                                                                 \
    while (list != NULL) {                                           \
      struct block_list *old = list;                                        \
      list = list->next;                                             \
      free (old);                                                    \
    }                                                                \
  } while (0)

Definition at line 103 of file localealias.c.

#define strchr   index

Definition at line 64 of file localealias.c.


Function Documentation

const char* _nl_expand_alias ( char *  name) const

Definition at line 136 of file localealias.c.

{
  static const char *locale_alias_path = LOCALE_ALIAS_PATH;
  struct alias_map *retval;
  size_t added;

  do
    {
      struct alias_map item;

      item.alias = name;

      if (nmap > 0)
       retval = (struct alias_map *) bsearch (&item, map, nmap,
                                          sizeof (struct alias_map),
                                          (int (*) PARAMS ((const void *,
                                                         const void *))
                                          ) alias_compare);
      else
       retval = NULL;

      /* We really found an alias.  Return the value.  */
      if (retval != NULL)
       return retval->value;

      /* Perhaps we can find another alias file.  */
      added = 0;
      while (added == 0 && locale_alias_path[0] != '\0')
       {
         const char *start;

         while (locale_alias_path[0] == ':')
           ++locale_alias_path;
         start = locale_alias_path;

         while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
           ++locale_alias_path;

         if (start < locale_alias_path)
           added = read_alias_file (start, locale_alias_path - start);
       }
    }
  while (added != 0);

  return NULL;

Here is the call graph for this function:

Here is the caller graph for this function:

static int alias_compare ( struct alias_map map1,
const struct alias_map map2 
) const [static]

Definition at line 344 of file localealias.c.

{
#if defined _LIBC || defined HAVE_STRCASECMP
  return strcasecmp (map1->alias, map2->alias);
#else
  const unsigned char *p1 = (const unsigned char *) map1->alias;
  const unsigned char *p2 = (const unsigned char *) map2->alias;
  unsigned char c1, c2;

  if (p1 == p2)
    return 0;

  do
    {
      /* I know this seems to be odd but the tolower() function in
        some systems libc cannot handle nonalpha characters.  */
      c1 = isupper (*p1) ? tolower (*p1) : *p1;
      c2 = isupper (*p2) ? tolower (*p2) : *p2;
      if (c1 == '\0')
       break;
      ++p1;
      ++p2;
    }
  while (c1 == c2);

  return c1 - c2;
#endif

Here is the caller graph for this function:

char* alloca ( )
static void extend_alias_table ( ) [static]

Definition at line 321 of file localealias.c.

{
  size_t new_size;
  struct alias_map *new_map;

  new_size = maxmap == 0 ? 100 : 2 * maxmap;
  new_map = (struct alias_map *) malloc (new_size
                                    * sizeof (struct alias_map));
  if (new_map == NULL)
    /* Simply don't extend: we don't have any more core.  */
    return;

  memcpy (new_map, map, nmap * sizeof (struct alias_map));

  if (maxmap != 0)
    free (map);

  map = new_map;
  maxmap = new_size;

Here is the caller graph for this function:

void free ( )
char* getenv ( )
static size_t read_alias_file PARAMS ( (const char *fname, int fname_len)  ) [static]
static void extend_alias_table PARAMS ( (void ) [static]
static int alias_compare PARAMS ( (const struct alias_map *map1, const struct alias_map *map2)  ) [static]
static size_t read_alias_file ( char *  fname,
int  fname_len 
) const [static]

Definition at line 186 of file localealias.c.

{
#ifndef HAVE_ALLOCA
  struct block_list *block_list = NULL;
#endif
  FILE *fp;
  char *full_fname;
  size_t added;
  static const char aliasfile[] = "/locale.alias";

  full_fname = (char *) alloca (fname_len + sizeof aliasfile);
  ADD_BLOCK (block_list, full_fname);
  memcpy (full_fname, fname, fname_len);
  memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);

  fp = fopen (full_fname, "r");
  if (fp == NULL)
    {
      FREE_BLOCKS (block_list);
      return 0;
    }

  added = 0;
  while (!feof (fp))
    {
      /* It is a reasonable approach to use a fix buffer here because
        a) we are only interested in the first two fields
        b) these fields must be usable as file names and so must not
           be that long
       */
      char buf[BUFSIZ];
      char *alias;
      char *value;
      char *cp;

      if (fgets (buf, BUFSIZ, fp) == NULL)
       /* EOF reached.  */
       break;

      cp = buf;
      /* Ignore leading white space.  */
      while (isspace (cp[0]))
       ++cp;

      /* A leading '#' signals a comment line.  */
      if (cp[0] != '\0' && cp[0] != '#')
       {
         alias = cp++;
         while (cp[0] != '\0' && !isspace (cp[0]))
           ++cp;
         /* Terminate alias name.  */
         if (cp[0] != '\0')
           *cp++ = '\0';

         /* Now look for the beginning of the value.  */
         while (isspace (cp[0]))
           ++cp;

         if (cp[0] != '\0')
           {
             char *tp;
             size_t len;

             value = cp++;
             while (cp[0] != '\0' && !isspace (cp[0]))
              ++cp;
             /* Terminate value.  */
             if (cp[0] == '\n')
              {
                /* This has to be done to make the following test
                   for the end of line possible.  We are looking for
                   the terminating '\n' which do not overwrite here.  */
                *cp++ = '\0';
                *cp = '\n';
              }
             else if (cp[0] != '\0')
              *cp++ = '\0';

             if (nmap >= maxmap)
              extend_alias_table ();

             /* We cannot depend on strdup available in the libc.  Sigh!  */
             len = strlen (alias) + 1;
             tp = (char *) malloc (len);
             if (tp == NULL)
              {
                FREE_BLOCKS (block_list);
                return added;
              }
             memcpy (tp, alias, len);
             map[nmap].alias = tp;

             len = strlen (value) + 1;
             tp = (char *) malloc (len);
             if (tp == NULL)
              {
                FREE_BLOCKS (block_list);
                return added;
              }
             memcpy (tp, value, len);
             map[nmap].value = tp;

             ++nmap;
             ++added;
           }
       }

      /* Possibily not the whole line fitted into the buffer.  Ignore
        the rest of the line.  */
      while (strchr (cp, '\n') == NULL)
       {
         cp = buf;
         if (fgets (buf, BUFSIZ, fp) == NULL)
           /* Make sure the inner loop will be left.  The outer loop
              will exit at the `feof' test.  */
           *cp = '\n';
       }
    }

  /* Should we test for ferror()?  I think we have to silently ignore
     errors.  --drepper  */
  fclose (fp);

  if (added > 0)
    qsort (map, nmap, sizeof (struct alias_map),
          (int (*) PARAMS ((const void *, const void *))) alias_compare);

  FREE_BLOCKS (block_list);
  return added;

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct alias_map* map [static]

Definition at line 123 of file localealias.c.

size_t maxmap = 0 [static]

Definition at line 125 of file localealias.c.

size_t nmap = 0 [static]

Definition at line 124 of file localealias.c.