Main Page | Data Structures | Directories | File List | Data Fields | Globals

localealias.c File Reference

#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "gettextP.h"

Go to the source code of this file.

Data Structures

struct  alias_map

Defines

#define _GNU_SOURCE   1
#define FEOF(fp)   feof (fp)
#define FGETS(buf, n, fp)   fgets (buf, n, fp)
#define alloca(n)   malloc (n)
#define freea(p)   free (p)

Functions

char * alloca ()
size_t read_alias_file PARAMS ((const char *fname, int fname_len))
size_t internal_function read_alias_file (char *fname, int fname_len) const
int extend_alias_table ()
int alias_compare (struct alias_map *map1, const struct alias_map *map2) const

Variables

char * string_space
size_t string_space_act
size_t string_space_max
alias_mapmap
size_t nmap
size_t maxmap


Define Documentation

#define _GNU_SOURCE   1
 

Definition at line 23 of file localealias.c.

#define alloca n   )     malloc (n)
 

Definition at line 97 of file localealias.c.

#define FEOF fp   )     feof (fp)
 

Definition at line 88 of file localealias.c.

#define FGETS buf,
n,
fp   )     fgets (buf, n, fp)
 

Definition at line 89 of file localealias.c.

#define freea  )     free (p)
 

Definition at line 98 of file localealias.c.


Function Documentation

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

Definition at line 390 of file localealias.c.

00393 {
00394 #if defined _LIBC || defined HAVE_STRCASECMP
00395   return strcasecmp (map1->alias, map2->alias);
00396 #else
00397   const unsigned char *p1 = (const unsigned char *) map1->alias;
00398   const unsigned char *p2 = (const unsigned char *) map2->alias;
00399   unsigned char c1, c2;
00400 
00401   if (p1 == p2)
00402     return 0;
00403 
00404   do
00405     {
00406       /* I know this seems to be odd but the tolower() function in
00407          some systems libc cannot handle nonalpha characters.  */
00408       c1 = isupper (*p1) ? tolower (*p1) : *p1;
00409       c2 = isupper (*p2) ? tolower (*p2) : *p2;
00410       if (c1 == '\0')
00411         break;
00412       ++p1;
00413       ++p2;
00414     }
00415   while (c1 == c2);
00416 
00417   return c1 - c2;
00418 #endif
00419 }

char* alloca  ) 
 

int extend_alias_table  )  [static]
 

Definition at line 358 of file localealias.c.

00359 {
00360   size_t new_size;
00361   struct alias_map *new_map;
00362 
00363   new_size = maxmap == 0 ? 100 : 2 * maxmap;
00364   new_map = (struct alias_map *) realloc (map, (new_size
00365                                                 * sizeof (struct alias_map)));
00366   if (new_map == NULL)
00367     /* Simply don't extend: we don't have any more core.  */
00368     return -1;
00369 
00370   map = new_map;
00371   maxmap = new_size;
00372   return 0;
00373 }

size_t read_alias_file PARAMS (const char *fname, int fname_len)   )  [static]
 

Definition at line 127 of file localealias.c.

00137 {
00138   static const char *locale_alias_path;
00139   struct alias_map *retval;
00140   const char *result = NULL;
00141   size_t added;
00142 
00143 #ifdef _LIBC
00144   __libc_lock_lock (lock);
00145 #endif
00146 
00147   if (locale_alias_path == NULL)
00148     locale_alias_path = LOCALE_ALIAS_PATH;
00149 
00150   do
00151     {
00152       struct alias_map item;
00153 
00154       item.alias = name;
00155 
00156       if (nmap > 0)
00157         retval = (struct alias_map *) bsearch (&item, map, nmap,
00158                                                sizeof (struct alias_map),
00159                                                (int (*) PARAMS ((const void *,
00160                                                                  const void *))
00161                                                 ) alias_compare);
00162       else
00163         retval = NULL;
00164 
00165       /* We really found an alias.  Return the value.  */
00166       if (retval != NULL)
00167         {
00168           result = retval->value;
00169           break;
00170         }
00171 
00172       /* Perhaps we can find another alias file.  */
00173       added = 0;
00174       while (added == 0 && locale_alias_path[0] != '\0')
00175         {
00176           const char *start;
00177 
00178           while (locale_alias_path[0] == PATH_SEPARATOR)
00179             ++locale_alias_path;
00180           start = locale_alias_path;
00181 
00182           while (locale_alias_path[0] != '\0'
00183                  && locale_alias_path[0] != PATH_SEPARATOR)
00184             ++locale_alias_path;
00185 
00186           if (start < locale_alias_path)
00187             added = read_alias_file (start, locale_alias_path - start);
00188         }
00189     }
00190   while (added != 0);
00191 
00192 #ifdef _LIBC
00193   __libc_lock_unlock (lock);
00194 #endif
00195 
00196   return result;
00197 }

size_t internal_function read_alias_file char *  fname,
int  fname_len
const [static]
 

Definition at line 202 of file localealias.c.

00205 {
00206   FILE *fp;
00207   char *full_fname;
00208   size_t added;
00209   static const char aliasfile[] = "/locale.alias";
00210 
00211   full_fname = (char *) alloca (fname_len + sizeof aliasfile);
00212 #ifdef HAVE_MEMPCPY
00213   mempcpy (mempcpy (full_fname, fname, fname_len),
00214            aliasfile, sizeof aliasfile);
00215 #else
00216   memcpy (full_fname, fname, fname_len);
00217   memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
00218 #endif
00219 
00220   fp = fopen (full_fname, "r");
00221   freea (full_fname);
00222   if (fp == NULL)
00223     return 0;
00224 
00225 #ifdef HAVE___FSETLOCKING
00226   /* No threads present.  */
00227   __fsetlocking (fp, FSETLOCKING_BYCALLER);
00228 #endif
00229 
00230   added = 0;
00231   while (!FEOF (fp))
00232     {
00233       /* It is a reasonable approach to use a fix buffer here because
00234          a) we are only interested in the first two fields
00235          b) these fields must be usable as file names and so must not
00236             be that long
00237        */
00238       char buf[BUFSIZ];
00239       char *alias;
00240       char *value;
00241       char *cp;
00242 
00243       if (FGETS (buf, sizeof buf, fp) == NULL)
00244         /* EOF reached.  */
00245         break;
00246 
00247       /* Possibly not the whole line fits into the buffer.  Ignore
00248          the rest of the line.  */
00249       if (strchr (buf, '\n') == NULL)
00250         {
00251           char altbuf[BUFSIZ];
00252           do
00253             if (FGETS (altbuf, sizeof altbuf, fp) == NULL)
00254               /* Make sure the inner loop will be left.  The outer loop
00255                  will exit at the `feof' test.  */
00256               break;
00257           while (strchr (altbuf, '\n') == NULL);
00258         }
00259 
00260       cp = buf;
00261       /* Ignore leading white space.  */
00262       while (isspace ((unsigned char) cp[0]))
00263         ++cp;
00264 
00265       /* A leading '#' signals a comment line.  */
00266       if (cp[0] != '\0' && cp[0] != '#')
00267         {
00268           alias = cp++;
00269           while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
00270             ++cp;
00271           /* Terminate alias name.  */
00272           if (cp[0] != '\0')
00273             *cp++ = '\0';
00274 
00275           /* Now look for the beginning of the value.  */
00276           while (isspace ((unsigned char) cp[0]))
00277             ++cp;
00278 
00279           if (cp[0] != '\0')
00280             {
00281               size_t alias_len;
00282               size_t value_len;
00283 
00284               value = cp++;
00285               while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
00286                 ++cp;
00287               /* Terminate value.  */
00288               if (cp[0] == '\n')
00289                 {
00290                   /* This has to be done to make the following test
00291                      for the end of line possible.  We are looking for
00292                      the terminating '\n' which do not overwrite here.  */
00293                   *cp++ = '\0';
00294                   *cp = '\n';
00295                 }
00296               else if (cp[0] != '\0')
00297                 *cp++ = '\0';
00298 
00299               if (nmap >= maxmap)
00300                 if (__builtin_expect (extend_alias_table (), 0))
00301                   return added;
00302 
00303               alias_len = strlen (alias) + 1;
00304               value_len = strlen (value) + 1;
00305 
00306               if (string_space_act + alias_len + value_len > string_space_max)
00307                 {
00308                   /* Increase size of memory pool.  */
00309                   size_t new_size = (string_space_max
00310                                      + (alias_len + value_len > 1024
00311                                         ? alias_len + value_len : 1024));
00312                   char *new_pool = (char *) realloc (string_space, new_size);
00313                   if (new_pool == NULL)
00314                     return added;
00315 
00316                   if (__builtin_expect (string_space != new_pool, 0))
00317                     {
00318                       size_t i;
00319 
00320                       for (i = 0; i < nmap; i++)
00321                         {
00322                           map[i].alias += new_pool - string_space;
00323                           map[i].value += new_pool - string_space;
00324                         }
00325                     }
00326 
00327                   string_space = new_pool;
00328                   string_space_max = new_size;
00329                 }
00330 
00331               map[nmap].alias = memcpy (&string_space[string_space_act],
00332                                         alias, alias_len);
00333               string_space_act += alias_len;
00334 
00335               map[nmap].value = memcpy (&string_space[string_space_act],
00336                                         value, value_len);
00337               string_space_act += value_len;
00338 
00339               ++nmap;
00340               ++added;
00341             }
00342         }
00343     }
00344 
00345   /* Should we test for ferror()?  I think we have to silently ignore
00346      errors.  --drepper  */
00347   fclose (fp);
00348 
00349   if (added > 0)
00350     qsort (map, nmap, sizeof (struct alias_map),
00351            (int (*) PARAMS ((const void *, const void *))) alias_compare);
00352 
00353   return added;
00354 }


Variable Documentation

struct alias_map* map [static]
 

Definition at line 121 of file localealias.c.

size_t maxmap [static]
 

Definition at line 123 of file localealias.c.

size_t nmap [static]
 

Definition at line 122 of file localealias.c.

char* string_space [static]
 

Definition at line 118 of file localealias.c.

size_t string_space_act [static]
 

Definition at line 119 of file localealias.c.

size_t string_space_max [static]
 

Definition at line 120 of file localealias.c.


Generated on Sun Dec 26 11:23:29 2004 for lincity by  doxygen 1.3.9.1