(file) Return to l10nflist.c CVS log (file) (dir) Up to [RizwankCVS] / testProject / source / src / intl

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

Rizwan Kassim
Powered by
ViewCVS 0.9.2