"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.2/intl/l10nflist.c" (23 Aug 2021, 10480 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
    2    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
    3 
    4    This program is free software; you can redistribute it and/or modify it
    5    under the terms of the GNU Library General Public License as published
    6    by the Free Software Foundation; either version 2, or (at your option)
    7    any later version.
    8 
    9    This program is distributed in the hope that it will be useful,
   10    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12    Library General Public License for more details.
   13 
   14    You should have received a copy of the GNU Library General Public
   15    License along with this program; if not, write to the Free Software
   16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   17    USA.  */
   18 
   19 /* Tell glibc's <string.h> to provide a prototype for stpcpy().
   20    This must come before <autoconf.h> because <autoconf.h> may include
   21    <features.h>, and once <features.h> has been included, it's too late.  */
   22 #ifndef _GNU_SOURCE
   23 # define _GNU_SOURCE    1
   24 #endif
   25 
   26 #ifdef HAVE_CONFIG_H
   27 # include <autoconf.h>
   28 #endif
   29 
   30 #include <string.h>
   31 #if !HAVE_STRCHR && !defined _LIBC
   32 # ifndef strchr
   33 #  define strchr index
   34 # endif
   35 #endif
   36 
   37 #if defined _LIBC || defined HAVE_ARGZ_H
   38 # include <argz.h>
   39 #endif
   40 #include <ctype.h>
   41 #include <sys/types.h>
   42 #include <stdlib.h>
   43 
   44 #include "loadinfo.h"
   45 
   46 /* On some strange systems still no definition of NULL is found.  Sigh!  */
   47 #ifndef NULL
   48 # if defined __STDC__ && __STDC__
   49 #  define NULL ((void *) 0)
   50 # else
   51 #  define NULL 0
   52 # endif
   53 #endif
   54 
   55 /* @@ end of prolog @@ */
   56 
   57 #ifdef _LIBC
   58 /* Rename the non ANSI C functions.  This is required by the standard
   59    because some ANSI C functions will require linking with this object
   60    file and the name space must not be polluted.  */
   61 # ifndef stpcpy
   62 #  define stpcpy(dest, src) __stpcpy(dest, src)
   63 # endif
   64 #else
   65 # ifndef HAVE_STPCPY
   66 static char *stpcpy PARAMS ((char *dest, const char *src));
   67 # endif
   68 #endif
   69 
   70 /* Define function which are usually not available.  */
   71 
   72 #if !defined _LIBC && !defined HAVE___ARGZ_COUNT
   73 /* Returns the number of strings in ARGZ.  */
   74 static size_t argz_count__ PARAMS ((const char *argz, size_t len));
   75 
   76 static size_t
   77 argz_count__ (argz, len)
   78      const char *argz;
   79      size_t len;
   80 {
   81   size_t count = 0;
   82   while (len > 0)
   83     {
   84       size_t part_len = strlen (argz);
   85       argz += part_len + 1;
   86       len -= part_len + 1;
   87       count++;
   88     }
   89   return count;
   90 }
   91 # undef __argz_count
   92 # define __argz_count(argz, len) argz_count__ (argz, len)
   93 #endif  /* !_LIBC && !HAVE___ARGZ_COUNT */
   94 
   95 #if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
   96 /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
   97    except the last into the character SEP.  */
   98 static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
   99 
  100 static void
  101 argz_stringify__ (argz, len, sep)
  102      char *argz;
  103      size_t len;
  104      int sep;
  105 {
  106   while (len > 0)
  107     {
  108       size_t part_len = strlen (argz);
  109       argz += part_len;
  110       len -= part_len + 1;
  111       if (len > 0)
  112     *argz++ = sep;
  113     }
  114 }
  115 # undef __argz_stringify
  116 # define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
  117 #endif  /* !_LIBC && !HAVE___ARGZ_STRINGIFY */
  118 
  119 #if !defined _LIBC && !defined HAVE___ARGZ_NEXT
  120 static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
  121                   const char *entry));
  122 
  123 static char *
  124 argz_next__ (argz, argz_len, entry)
  125      char *argz;
  126      size_t argz_len;
  127      const char *entry;
  128 {
  129   if (entry)
  130     {
  131       if (entry < argz + argz_len)
  132         entry = strchr (entry, '\0') + 1;
  133 
  134       return entry >= argz + argz_len ? NULL : (char *) entry;
  135     }
  136   else
  137     if (argz_len > 0)
  138       return argz;
  139     else
  140       return 0;
  141 }
  142 # undef __argz_next
  143 # define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
  144 #endif  /* !_LIBC && !HAVE___ARGZ_NEXT */
  145 
  146 
  147 /* Return number of bits set in X.  */
  148 static int pop PARAMS ((int x));
  149 
  150 static inline int
  151 pop (x)
  152      int x;
  153 {
  154   /* We assume that no more than 16 bits are used.  */
  155   x = ((x & ~0x5555) >> 1) + (x & 0x5555);
  156   x = ((x & ~0x3333) >> 2) + (x & 0x3333);
  157   x = ((x >> 4) + x) & 0x0f0f;
  158   x = ((x >> 8) + x) & 0xff;
  159 
  160   return x;
  161 }
  162 
  163 
  164 struct loaded_l10nfile *
  165 _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
  166             territory, codeset, normalized_codeset, modifier, special,
  167             sponsor, revision, filename, do_allocate)
  168      struct loaded_l10nfile **l10nfile_list;
  169      const char *dirlist;
  170      size_t dirlist_len;
  171      int mask;
  172      const char *language;
  173      const char *territory;
  174      const char *codeset;
  175      const char *normalized_codeset;
  176      const char *modifier;
  177      const char *special;
  178      const char *sponsor;
  179      const char *revision;
  180      const char *filename;
  181      int do_allocate;
  182 {
  183   char *abs_filename;
  184   struct loaded_l10nfile *last = NULL;
  185   struct loaded_l10nfile *retval;
  186   char *cp;
  187   size_t entries;
  188   int cnt;
  189 
  190   /* Allocate room for the full file name.  */
  191   abs_filename = (char *) malloc (dirlist_len
  192                   + strlen (language)
  193                   + ((mask & TERRITORY) != 0
  194                      ? strlen (territory) + 1 : 0)
  195                   + ((mask & XPG_CODESET) != 0
  196                      ? strlen (codeset) + 1 : 0)
  197                   + ((mask & XPG_NORM_CODESET) != 0
  198                      ? strlen (normalized_codeset) + 1 : 0)
  199                   + (((mask & XPG_MODIFIER) != 0
  200                       || (mask & CEN_AUDIENCE) != 0)
  201                      ? strlen (modifier) + 1 : 0)
  202                   + ((mask & CEN_SPECIAL) != 0
  203                      ? strlen (special) + 1 : 0)
  204                   + (((mask & CEN_SPONSOR) != 0
  205                       || (mask & CEN_REVISION) != 0)
  206                      ? (1 + ((mask & CEN_SPONSOR) != 0
  207                          ? strlen (sponsor) + 1 : 0)
  208                     + ((mask & CEN_REVISION) != 0
  209                        ? strlen (revision) + 1 : 0)) : 0)
  210                   + 1 + strlen (filename) + 1);
  211 
  212   if (abs_filename == NULL)
  213     return NULL;
  214 
  215   retval = NULL;
  216   last = NULL;
  217 
  218   /* Construct file name.  */
  219   memcpy (abs_filename, dirlist, dirlist_len);
  220   __argz_stringify (abs_filename, dirlist_len, PATH_SEPARATOR);
  221   cp = abs_filename + (dirlist_len - 1);
  222   *cp++ = '/';
  223   cp = stpcpy (cp, language);
  224 
  225   if ((mask & TERRITORY) != 0)
  226     {
  227       *cp++ = '_';
  228       cp = stpcpy (cp, territory);
  229     }
  230   if ((mask & XPG_CODESET) != 0)
  231     {
  232       *cp++ = '.';
  233       cp = stpcpy (cp, codeset);
  234     }
  235   if ((mask & XPG_NORM_CODESET) != 0)
  236     {
  237       *cp++ = '.';
  238       cp = stpcpy (cp, normalized_codeset);
  239     }
  240   if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
  241     {
  242       /* This component can be part of both syntaces but has different
  243      leading characters.  For CEN we use `+', else `@'.  */
  244       *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
  245       cp = stpcpy (cp, modifier);
  246     }
  247   if ((mask & CEN_SPECIAL) != 0)
  248     {
  249       *cp++ = '+';
  250       cp = stpcpy (cp, special);
  251     }
  252   if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
  253     {
  254       *cp++ = ',';
  255       if ((mask & CEN_SPONSOR) != 0)
  256     cp = stpcpy (cp, sponsor);
  257       if ((mask & CEN_REVISION) != 0)
  258     {
  259       *cp++ = '_';
  260       cp = stpcpy (cp, revision);
  261     }
  262     }
  263 
  264   *cp++ = '/';
  265   stpcpy (cp, filename);
  266 
  267   /* Look in list of already loaded domains whether it is already
  268      available.  */
  269   last = NULL;
  270   for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
  271     if (retval->filename != NULL)
  272       {
  273     int compare = strcmp (retval->filename, abs_filename);
  274     if (compare == 0)
  275       /* We found it!  */
  276       break;
  277     if (compare < 0)
  278       {
  279         /* It's not in the list.  */
  280         retval = NULL;
  281         break;
  282       }
  283 
  284     last = retval;
  285       }
  286 
  287   if (retval != NULL || do_allocate == 0)
  288     {
  289       free (abs_filename);
  290       return retval;
  291     }
  292 
  293   retval = (struct loaded_l10nfile *)
  294     malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
  295                 * (1 << pop (mask))
  296                 * sizeof (struct loaded_l10nfile *)));
  297   if (retval == NULL)
  298     return NULL;
  299 
  300   retval->filename = abs_filename;
  301   retval->decided = (__argz_count (dirlist, dirlist_len) != 1
  302              || ((mask & XPG_CODESET) != 0
  303              && (mask & XPG_NORM_CODESET) != 0));
  304   retval->data = NULL;
  305 
  306   if (last == NULL)
  307     {
  308       retval->next = *l10nfile_list;
  309       *l10nfile_list = retval;
  310     }
  311   else
  312     {
  313       retval->next = last->next;
  314       last->next = retval;
  315     }
  316 
  317   entries = 0;
  318   /* If the DIRLIST is a real list the RETVAL entry corresponds not to
  319      a real file.  So we have to use the DIRLIST separation mechanism
  320      of the inner loop.  */
  321   cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
  322   for (; cnt >= 0; --cnt)
  323     if ((cnt & ~mask) == 0
  324     && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
  325     && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
  326       {
  327     /* Iterate over all elements of the DIRLIST.  */
  328     char *dir = NULL;
  329 
  330     while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
  331            != NULL)
  332       retval->successor[entries++]
  333         = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
  334                   language, territory, codeset,
  335                   normalized_codeset, modifier, special,
  336                   sponsor, revision, filename, 1);
  337       }
  338   retval->successor[entries] = NULL;
  339 
  340   return retval;
  341 }
  342 
  343 /* Normalize codeset name.  There is no standard for the codeset
  344    names.  Normalization allows the user to use any of the common
  345    names.  The return value is dynamically allocated and has to be
  346    freed by the caller.  */
  347 const char *
  348 _nl_normalize_codeset (codeset, name_len)
  349      const char *codeset;
  350      size_t name_len;
  351 {
  352   int len = 0;
  353   int only_digit = 1;
  354   char *retval;
  355   char *wp;
  356   size_t cnt;
  357 
  358   for (cnt = 0; cnt < name_len; ++cnt)
  359     if (isalnum (codeset[cnt]))
  360       {
  361     ++len;
  362 
  363     if (isalpha (codeset[cnt]))
  364       only_digit = 0;
  365       }
  366 
  367   retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
  368 
  369   if (retval != NULL)
  370     {
  371       if (only_digit)
  372     wp = stpcpy (retval, "iso");
  373       else
  374     wp = retval;
  375 
  376       for (cnt = 0; cnt < name_len; ++cnt)
  377     if (isalpha (codeset[cnt]))
  378       *wp++ = tolower (codeset[cnt]);
  379     else if (isdigit (codeset[cnt]))
  380       *wp++ = codeset[cnt];
  381 
  382       *wp = '\0';
  383     }
  384 
  385   return (const char *) retval;
  386 }
  387 
  388 
  389 /* @@ begin of epilog @@ */
  390 
  391 /* We don't want libintl.a to depend on any other library.  So we
  392    avoid the non-standard function stpcpy.  In GNU C Library this
  393    function is available, though.  Also allow the symbol HAVE_STPCPY
  394    to be defined.  */
  395 #if !_LIBC && !HAVE_STPCPY
  396 static char *
  397 stpcpy (dest, src)
  398      char *dest;
  399      const char *src;
  400 {
  401   while ((*dest++ = *src++) != '\0')
  402     /* Do nothing. */ ;
  403   return dest - 1;
  404 }
  405 #endif