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

Contents of /navit/intl/bindtextdom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (8 years, 11 months ago) by zoff99
File MIME type: text/plain
File size: 9808 byte(s)
import files
1 /* 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