~ubuntu-branches/ubuntu/maverick/texinfo/maverick

« back to all changes in this revision

Viewing changes to intl/l10nflist.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2005-10-28 15:10:30 UTC
  • mto: (2.1.1 dapper) (3.1.4 hardy)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20051028151030-9nsf2s2k2z3fktjt
Tags: upstream-4.8
ImportĀ upstreamĀ versionĀ 4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
 
1
/* Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
2
2
   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
3
3
 
4
4
   This program is free software; you can redistribute it and/or modify it
58
58
# endif
59
59
#else
60
60
# ifndef HAVE_STPCPY
61
 
static char *stpcpy PARAMS ((char *dest, const char *src));
 
61
static char *stpcpy (char *dest, const char *src);
62
62
# endif
63
63
#endif
64
64
 
 
65
/* Pathname support.
 
66
   ISSLASH(C)           tests whether C is a directory separator character.
 
67
   IS_ABSOLUTE_PATH(P)  tests whether P is an absolute path.  If it is not,
 
68
                        it may be concatenated to a directory pathname.
 
69
 */
 
70
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
 
71
  /* Win32, OS/2, DOS */
 
72
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
 
73
# define HAS_DEVICE(P) \
 
74
    ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
 
75
     && (P)[1] == ':')
 
76
# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
 
77
#else
 
78
  /* Unix */
 
79
# define ISSLASH(C) ((C) == '/')
 
80
# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
 
81
#endif
 
82
 
65
83
/* Define function which are usually not available.  */
66
84
 
67
85
#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
68
86
/* Returns the number of strings in ARGZ.  */
69
 
static size_t argz_count__ PARAMS ((const char *argz, size_t len));
70
 
 
71
87
static size_t
72
 
argz_count__ (argz, len)
73
 
     const char *argz;
74
 
     size_t len;
 
88
argz_count__ (const char *argz, size_t len)
75
89
{
76
90
  size_t count = 0;
77
91
  while (len > 0)
85
99
}
86
100
# undef __argz_count
87
101
# define __argz_count(argz, len) argz_count__ (argz, len)
 
102
#else
 
103
# ifdef _LIBC
 
104
#  define __argz_count(argz, len) INTUSE(__argz_count) (argz, len)
 
105
# endif
88
106
#endif  /* !_LIBC && !HAVE___ARGZ_COUNT */
89
107
 
90
108
#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
91
109
/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
92
110
   except the last into the character SEP.  */
93
 
static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
94
 
 
95
111
static void
96
 
argz_stringify__ (argz, len, sep)
97
 
     char *argz;
98
 
     size_t len;
99
 
     int sep;
 
112
argz_stringify__ (char *argz, size_t len, int sep)
100
113
{
101
114
  while (len > 0)
102
115
    {
109
122
}
110
123
# undef __argz_stringify
111
124
# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
 
125
#else
 
126
# ifdef _LIBC
 
127
#  define __argz_stringify(argz, len, sep) \
 
128
  INTUSE(__argz_stringify) (argz, len, sep)
 
129
# endif
112
130
#endif  /* !_LIBC && !HAVE___ARGZ_STRINGIFY */
113
131
 
114
132
#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
115
 
static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
116
 
                                  const char *entry));
117
 
 
118
133
static char *
119
 
argz_next__ (argz, argz_len, entry)
120
 
     char *argz;
121
 
     size_t argz_len;
122
 
     const char *entry;
 
134
argz_next__ (char *argz, size_t argz_len, const char *entry)
123
135
{
124
136
  if (entry)
125
137
    {
140
152
 
141
153
 
142
154
/* Return number of bits set in X.  */
143
 
static int pop PARAMS ((int x));
144
 
 
145
155
static inline int
146
 
pop (x)
147
 
     int x;
 
156
pop (int x)
148
157
{
149
158
  /* We assume that no more than 16 bits are used.  */
150
159
  x = ((x & ~0x5555) >> 1) + (x & 0x5555);
157
166
 
158
167
 
159
168
struct loaded_l10nfile *
160
 
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
161
 
                    territory, codeset, normalized_codeset, modifier, special,
162
 
                    sponsor, revision, filename, do_allocate)
163
 
     struct loaded_l10nfile **l10nfile_list;
164
 
     const char *dirlist;
165
 
     size_t dirlist_len;
166
 
     int mask;
167
 
     const char *language;
168
 
     const char *territory;
169
 
     const char *codeset;
170
 
     const char *normalized_codeset;
171
 
     const char *modifier;
172
 
     const char *special;
173
 
     const char *sponsor;
174
 
     const char *revision;
175
 
     const char *filename;
176
 
     int do_allocate;
 
169
_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
 
170
                    const char *dirlist, size_t dirlist_len,
 
171
                    int mask, const char *language, const char *territory,
 
172
                    const char *codeset, const char *normalized_codeset,
 
173
                    const char *modifier, const char *special,
 
174
                    const char *sponsor, const char *revision,
 
175
                    const char *filename, int do_allocate)
177
176
{
178
177
  char *abs_filename;
179
 
  struct loaded_l10nfile *last = NULL;
 
178
  struct loaded_l10nfile **lastp;
180
179
  struct loaded_l10nfile *retval;
181
180
  char *cp;
 
181
  size_t dirlist_count;
182
182
  size_t entries;
183
183
  int cnt;
184
184
 
 
185
  /* If LANGUAGE contains an absolute directory specification, we ignore
 
186
     DIRLIST.  */
 
187
  if (IS_ABSOLUTE_PATH (language))
 
188
    dirlist_len = 0;
 
189
 
185
190
  /* Allocate room for the full file name.  */
186
191
  abs_filename = (char *) malloc (dirlist_len
187
192
                                  + strlen (language)
199
204
                                  + (((mask & CEN_SPONSOR) != 0
200
205
                                      || (mask & CEN_REVISION) != 0)
201
206
                                     ? (1 + ((mask & CEN_SPONSOR) != 0
202
 
                                             ? strlen (sponsor) + 1 : 0)
 
207
                                             ? strlen (sponsor) : 0)
203
208
                                        + ((mask & CEN_REVISION) != 0
204
209
                                           ? strlen (revision) + 1 : 0)) : 0)
205
210
                                  + 1 + strlen (filename) + 1);
207
212
  if (abs_filename == NULL)
208
213
    return NULL;
209
214
 
210
 
  retval = NULL;
211
 
  last = NULL;
212
 
 
213
215
  /* Construct file name.  */
214
 
  memcpy (abs_filename, dirlist, dirlist_len);
215
 
  __argz_stringify (abs_filename, dirlist_len, PATH_SEPARATOR);
216
 
  cp = abs_filename + (dirlist_len - 1);
217
 
  *cp++ = '/';
 
216
  cp = abs_filename;
 
217
  if (dirlist_len > 0)
 
218
    {
 
219
      memcpy (cp, dirlist, dirlist_len);
 
220
      __argz_stringify (cp, dirlist_len, PATH_SEPARATOR);
 
221
      cp += dirlist_len;
 
222
      cp[-1] = '/';
 
223
    }
 
224
 
218
225
  cp = stpcpy (cp, language);
219
226
 
220
227
  if ((mask & TERRITORY) != 0)
261
268
 
262
269
  /* Look in list of already loaded domains whether it is already
263
270
     available.  */
264
 
  last = NULL;
 
271
  lastp = l10nfile_list;
265
272
  for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
266
273
    if (retval->filename != NULL)
267
274
      {
276
283
            break;
277
284
          }
278
285
 
279
 
        last = retval;
 
286
        lastp = &retval->next;
280
287
      }
281
288
 
282
289
  if (retval != NULL || do_allocate == 0)
285
292
      return retval;
286
293
    }
287
294
 
288
 
  retval = (struct loaded_l10nfile *)
289
 
    malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
290
 
                                * (1 << pop (mask))
291
 
                                * sizeof (struct loaded_l10nfile *)));
 
295
  dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1);
 
296
 
 
297
  /* Allocate a new loaded_l10nfile.  */
 
298
  retval =
 
299
    (struct loaded_l10nfile *)
 
300
    malloc (sizeof (*retval)
 
301
            + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0))
 
302
               * sizeof (struct loaded_l10nfile *)));
292
303
  if (retval == NULL)
293
304
    return NULL;
294
305
 
295
306
  retval->filename = abs_filename;
296
 
  retval->decided = (__argz_count (dirlist, dirlist_len) != 1
 
307
 
 
308
  /* We set retval->data to NULL here; it is filled in later.
 
309
     Setting retval->decided to 1 here means that retval does not
 
310
     correspond to a real file (dirlist_count > 1) or is not worth
 
311
     looking up (if an unnormalized codeset was specified).  */
 
312
  retval->decided = (dirlist_count > 1
297
313
                     || ((mask & XPG_CODESET) != 0
298
314
                         && (mask & XPG_NORM_CODESET) != 0));
299
315
  retval->data = NULL;
300
316
 
301
 
  if (last == NULL)
302
 
    {
303
 
      retval->next = *l10nfile_list;
304
 
      *l10nfile_list = retval;
305
 
    }
306
 
  else
307
 
    {
308
 
      retval->next = last->next;
309
 
      last->next = retval;
310
 
    }
 
317
  retval->next = *lastp;
 
318
  *lastp = retval;
311
319
 
312
320
  entries = 0;
313
 
  /* If the DIRLIST is a real list the RETVAL entry corresponds not to
314
 
     a real file.  So we have to use the DIRLIST separation mechanism
315
 
     of the inner loop.  */
316
 
  cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
317
 
  for (; cnt >= 0; --cnt)
 
321
  /* Recurse to fill the inheritance list of RETVAL.
 
322
     If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL
 
323
     entry does not correspond to a real file; retval->filename contains
 
324
     colons.  In this case we loop across all elements of DIRLIST and
 
325
     across all bit patterns dominated by MASK.
 
326
     If the DIRLIST is a single directory or entirely redundant (i.e.
 
327
     DIRLIST_COUNT == 1), we loop across all bit patterns dominated by
 
328
     MASK, excluding MASK itself.
 
329
     In either case, we loop down from MASK to 0.  This has the effect
 
330
     that the extra bits in the locale name are dropped in this order:
 
331
     first the modifier, then the territory, then the codeset, then the
 
332
     normalized_codeset.  */
 
333
  for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt)
318
334
    if ((cnt & ~mask) == 0
319
335
        && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
320
336
        && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
321
337
      {
322
 
        /* Iterate over all elements of the DIRLIST.  */
323
 
        char *dir = NULL;
 
338
        if (dirlist_count > 1)
 
339
          {
 
340
            /* Iterate over all elements of the DIRLIST.  */
 
341
            char *dir = NULL;
324
342
 
325
 
        while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
326
 
               != NULL)
 
343
            while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
 
344
                   != NULL)
 
345
              retval->successor[entries++]
 
346
                = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1,
 
347
                                      cnt, language, territory, codeset,
 
348
                                      normalized_codeset, modifier, special,
 
349
                                      sponsor, revision, filename, 1);
 
350
          }
 
351
        else
327
352
          retval->successor[entries++]
328
 
            = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
329
 
                                  language, territory, codeset,
 
353
            = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len,
 
354
                                  cnt, language, territory, codeset,
330
355
                                  normalized_codeset, modifier, special,
331
356
                                  sponsor, revision, filename, 1);
332
357
      }
340
365
   names.  The return value is dynamically allocated and has to be
341
366
   freed by the caller.  */
342
367
const char *
343
 
_nl_normalize_codeset (codeset, name_len)
344
 
     const char *codeset;
345
 
     size_t name_len;
 
368
_nl_normalize_codeset (const char *codeset, size_t name_len)
346
369
{
347
370
  int len = 0;
348
371
  int only_digit = 1;
389
412
   to be defined.  */
390
413
#if !_LIBC && !HAVE_STPCPY
391
414
static char *
392
 
stpcpy (dest, src)
393
 
     char *dest;
394
 
     const char *src;
 
415
stpcpy (char *dest, const char *src)
395
416
{
396
417
  while ((*dest++ = *src++) != '\0')
397
418
    /* Do nothing. */ ;