~ubuntu-branches/ubuntu/hardy/minicom/hardy

« back to all changes in this revision

Viewing changes to intl/l10nflist.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin A. Godisch
  • Date: 2006-10-27 05:41:23 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061027054123-9cyfsdx649zetdrv
Tags: 2.2-3
* Added upstream NEWS file, closes: #394827.
* Fixed spelling errors, closes: #395449.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 <config.h> because <config.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 <config.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