~ubuntu-branches/ubuntu/natty/hello-debhelper/natty

« back to all changes in this revision

Viewing changes to intl/l10nflist.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2006-12-09 17:00:14 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209170014-817qbpd8jsc3g5xh
Tags: 2.2-1
* New upstream release.
* Repackaged source taken from hello package.
* Removed prerm and postinst, as info files are missing now.

Show diffs side-by-side

added added

removed removed

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