/[zanavi_public1]/navit/intl/bindtextdom.c
ZANavi

Contents of /navit/intl/bindtextdom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 9808 byte(s)
import files
1 zoff99 2 /* Implementation of the bindtextdomain(3) function
2     Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
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     #ifdef HAVE_CONFIG_H
20     # include <config.h>
21     #endif
22    
23     #include <stddef.h>
24     #include <stdlib.h>
25     #include <string.h>
26    
27     #ifdef _LIBC
28     # include <libintl.h>
29     #else
30     # include "libgnuintl.h"
31     #endif
32     #include "gettextP.h"
33    
34     #ifdef _LIBC
35     /* We have to handle multi-threaded applications. */
36     # include <bits/libc-lock.h>
37     #else
38     /* Provide dummy implementation if this is outside glibc. */
39     # define __libc_rwlock_define(CLASS, NAME)
40     # define __libc_rwlock_wrlock(NAME)
41     # define __libc_rwlock_unlock(NAME)
42     #endif
43    
44     /* The internal variables in the standalone libintl.a must have different
45     names than the internal variables in GNU libc, otherwise programs
46     using libintl.a cannot be linked statically. */
47     #if !defined _LIBC
48     # define _nl_default_dirname libintl_nl_default_dirname
49     # define _nl_domain_bindings libintl_nl_domain_bindings
50     #endif
51    
52     /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
53     #ifndef offsetof
54     # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
55     #endif
56    
57     /* @@ end of prolog @@ */
58    
59     /* Contains the default location of the message catalogs. */
60     extern const char _nl_default_dirname[];
61     #ifdef _LIBC
62     extern const char _nl_default_dirname_internal[] attribute_hidden;
63     #else
64     # define INTUSE(name) name
65     #endif
66    
67     /* List with bindings of specific domains. */
68     extern struct binding *_nl_domain_bindings;
69    
70     /* Lock variable to protect the global data in the gettext implementation. */
71     __libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
72    
73    
74     /* Names for the libintl functions are a problem. They must not clash
75     with existing names and they should follow ANSI C. But this source
76     code is also used in GNU C Library where the names have a __
77     prefix. So we have to make a difference here. */
78     #ifdef _LIBC
79     # define BINDTEXTDOMAIN __bindtextdomain
80     # define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
81     # ifndef strdup
82     # define strdup(str) __strdup (str)
83     # endif
84     #else
85     # define BINDTEXTDOMAIN libintl_bindtextdomain
86     # define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset
87     #endif
88    
89     /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
90     to be used for the DOMAINNAME message catalog.
91     If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
92     modified, only the current value is returned.
93     If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
94     modified nor returned. */
95     static void
96     set_binding_values (const char *domainname,
97     const char **dirnamep, const char **codesetp)
98     {
99     struct binding *binding;
100     int modified;
101    
102     /* Some sanity checks. */
103     if (domainname == NULL || domainname[0] == '\0')
104     {
105     if (dirnamep)
106     *dirnamep = NULL;
107     if (codesetp)
108     *codesetp = NULL;
109     return;
110     }
111    
112     __libc_rwlock_wrlock (_nl_state_lock);
113    
114     modified = 0;
115    
116     for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
117     {
118     int compare = strcmp (domainname, binding->domainname);
119     if (compare == 0)
120     /* We found it! */
121     break;
122     if (compare < 0)
123     {
124     /* It is not in the list. */
125     binding = NULL;
126     break;
127     }
128     }
129    
130     if (binding != NULL)
131     {
132     if (dirnamep)
133     {
134     const char *dirname = *dirnamep;
135    
136     if (dirname == NULL)
137     /* The current binding has be to returned. */
138     *dirnamep = binding->dirname;
139     else
140     {
141     /* The domain is already bound. If the new value and the old
142     one are equal we simply do nothing. Otherwise replace the
143     old binding. */
144     char *result = binding->dirname;
145     if (strcmp (dirname, result) != 0)
146     {
147     if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
148     result = (char *) INTUSE(_nl_default_dirname);
149     else
150     {
151     #if defined _LIBC || defined HAVE_STRDUP
152     result = strdup (dirname);
153     #else
154     size_t len = strlen (dirname) + 1;
155     result = (char *) malloc (len);
156     if (__builtin_expect (result != NULL, 1))
157     memcpy (result, dirname, len);
158     #endif
159     }
160    
161     if (__builtin_expect (result != NULL, 1))
162     {
163     if (binding->dirname != INTUSE(_nl_default_dirname))
164     free (binding->dirname);
165    
166     binding->dirname = result;
167     modified = 1;
168     }
169     }
170     *dirnamep = result;
171     }
172     }
173    
174     if (codesetp)
175     {
176     const char *codeset = *codesetp;
177    
178     if (codeset == NULL)
179     /* The current binding has be to returned. */
180     *codesetp = binding->codeset;
181     else
182     {
183     /* The domain is already bound. If the new value and the old
184     one are equal we simply do nothing. Otherwise replace the
185     old binding. */
186     char *result = binding->codeset;
187     if (result == NULL || strcmp (codeset, result) != 0)
188     {
189     #if defined _LIBC || defined HAVE_STRDUP
190     result = strdup (codeset);
191     #else
192     size_t len = strlen (codeset) + 1;
193     result = (char *) malloc (len);
194     if (__builtin_expect (result != NULL, 1))
195     memcpy (result, codeset, len);
196     #endif
197    
198     if (__builtin_expect (result != NULL, 1))
199     {
200     if (binding->codeset != NULL)
201     free (binding->codeset);
202    
203     binding->codeset = result;
204     binding->codeset_cntr++;
205     modified = 1;
206     }
207     }
208     *codesetp = result;
209     }
210     }
211     }
212     else if ((dirnamep == NULL || *dirnamep == NULL)
213     && (codesetp == NULL || *codesetp == NULL))
214     {
215     /* Simply return the default values. */
216     if (dirnamep)
217     *dirnamep = INTUSE(_nl_default_dirname);
218     if (codesetp)
219     *codesetp = NULL;
220     }
221     else
222     {
223     /* We have to create a new binding. */
224     size_t len = strlen (domainname) + 1;
225     struct binding *new_binding =
226     (struct binding *) malloc (offsetof (struct binding, domainname) + len);
227    
228     if (__builtin_expect (new_binding == NULL, 0))
229     goto failed;
230    
231     memcpy (new_binding->domainname, domainname, len);
232    
233     if (dirnamep)
234     {
235     const char *dirname = *dirnamep;
236    
237     if (dirname == NULL)
238     /* The default value. */
239     dirname = INTUSE(_nl_default_dirname);
240     else
241     {
242     if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
243     dirname = INTUSE(_nl_default_dirname);
244     else
245     {
246     char *result;
247     #if defined _LIBC || defined HAVE_STRDUP
248     result = strdup (dirname);
249     if (__builtin_expect (result == NULL, 0))
250     goto failed_dirname;
251     #else
252     size_t len = strlen (dirname) + 1;
253     result = (char *) malloc (len);
254     if (__builtin_expect (result == NULL, 0))
255     goto failed_dirname;
256     memcpy (result, dirname, len);
257     #endif
258     dirname = result;
259     }
260     }
261     *dirnamep = dirname;
262     new_binding->dirname = (char *) dirname;
263     }
264     else
265     /* The default value. */
266     new_binding->dirname = (char *) INTUSE(_nl_default_dirname);
267    
268     new_binding->codeset_cntr = 0;
269    
270     if (codesetp)
271     {
272     const char *codeset = *codesetp;
273    
274     if (codeset != NULL)
275     {
276     char *result;
277    
278     #if defined _LIBC || defined HAVE_STRDUP
279     result = strdup (codeset);
280     if (__builtin_expect (result == NULL, 0))
281     goto failed_codeset;
282     #else
283     size_t len = strlen (codeset) + 1;
284     result = (char *) malloc (len);
285     if (__builtin_expect (result == NULL, 0))
286     goto failed_codeset;
287     memcpy (result, codeset, len);
288     #endif
289     codeset = result;
290     new_binding->codeset_cntr++;
291     }
292     *codesetp = codeset;
293     new_binding->codeset = (char *) codeset;
294     }
295     else
296     new_binding->codeset = NULL;
297    
298     /* Now enqueue it. */
299     if (_nl_domain_bindings == NULL
300     || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
301     {
302     new_binding->next = _nl_domain_bindings;
303     _nl_domain_bindings = new_binding;
304     }
305     else
306     {
307     binding = _nl_domain_bindings;
308     while (binding->next != NULL
309     && strcmp (domainname, binding->next->domainname) > 0)
310     binding = binding->next;
311    
312     new_binding->next = binding->next;
313     binding->next = new_binding;
314     }
315    
316     modified = 1;
317    
318     /* Here we deal with memory allocation failures. */
319     if (0)
320     {
321     failed_codeset:
322     if (new_binding->dirname != INTUSE(_nl_default_dirname))
323     free (new_binding->dirname);
324     failed_dirname:
325     free (new_binding);
326     failed:
327     if (dirnamep)
328     *dirnamep = NULL;
329     if (codesetp)
330     *codesetp = NULL;
331     }
332     }
333    
334     /* If we modified any binding, we flush the caches. */
335     if (modified)
336     ++_nl_msg_cat_cntr;
337    
338     __libc_rwlock_unlock (_nl_state_lock);
339     }
340    
341     /* Specify that the DOMAINNAME message catalog will be found
342     in DIRNAME rather than in the system locale data base. */
343     char *
344     BINDTEXTDOMAIN (const char *domainname, const char *dirname)
345     {
346     set_binding_values (domainname, &dirname, NULL);
347     return (char *) dirname;
348     }
349    
350     /* Specify the character encoding in which the messages from the
351     DOMAINNAME message catalog will be returned. */
352     char *
353     BIND_TEXTDOMAIN_CODESET (const char *domainname, const char *codeset)
354     {
355     set_binding_values (domainname, NULL, &codeset);
356     return (char *) codeset;
357     }
358    
359     #ifdef _LIBC
360     /* Aliases for function names in GNU C Library. */
361     weak_alias (__bindtextdomain, bindtextdomain);
362     weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);
363     #endif

   
Visit the ZANavi Wiki