* sysdeps/m68k/fpu/bits/mathinline.h: Don't define log2 as inline.
[glibc.git] / intl / bindtextdom.c
blobb1b1d87fa300b320d23b61dd899bc2b1734090bb
1 /* Implementation of the bindtextdomain(3) function
2 Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library 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.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 #if defined STDC_HEADERS || defined _LIBC
24 # include <stdlib.h>
25 #else
26 # ifdef HAVE_MALLOC_H
27 # include <malloc.h>
28 # else
29 void free ();
30 # endif
31 #endif
33 #if defined HAVE_STRING_H || defined _LIBC
34 # include <string.h>
35 #else
36 # include <strings.h>
37 # ifndef memcpy
38 # define memcpy(Dst, Src, Num) (bcopy (Src, Dst, Num), (Dst))
39 # endif
40 #endif
42 #ifdef _LIBC
43 # include <libintl.h>
44 #else
45 # include "libgnuintl.h"
46 #endif
47 #include "gettextP.h"
49 #ifdef _LIBC
50 /* We have to handle multi-threaded applications. */
51 # include <bits/libc-lock.h>
52 #else
53 /* Provide dummy implementation if this is outside glibc. */
54 # define __libc_rwlock_define(CLASS, NAME)
55 # define __libc_rwlock_wrlock(NAME)
56 # define __libc_rwlock_unlock(NAME)
57 #endif
59 /* The internal variables in the standalone libintl.a must have different
60 names than the internal variables in GNU libc, otherwise programs
61 using libintl.a cannot be linked statically. */
62 #if !defined _LIBC
63 # define _nl_default_dirname _nl_default_dirname__
64 # define _nl_domain_bindings _nl_domain_bindings__
65 #endif
67 /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
68 #ifndef offsetof
69 # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
70 #endif
72 /* @@ end of prolog @@ */
74 /* Contains the default location of the message catalogs. */
75 extern const char _nl_default_dirname[];
77 /* List with bindings of specific domains. */
78 extern struct binding *_nl_domain_bindings;
80 /* Lock variable to protect the global data in the gettext implementation. */
81 __libc_rwlock_define (extern, _nl_state_lock)
84 /* Names for the libintl functions are a problem. They must not clash
85 with existing names and they should follow ANSI C. But this source
86 code is also used in GNU C Library where the names have a __
87 prefix. So we have to make a difference here. */
88 #ifdef _LIBC
89 # define BINDTEXTDOMAIN __bindtextdomain
90 # define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
91 # ifndef strdup
92 # define strdup(str) __strdup (str)
93 # endif
94 #else
95 # define BINDTEXTDOMAIN bindtextdomain__
96 # define BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset__
97 #endif
99 /* Prototypes for local functions. */
100 static void set_binding_values PARAMS ((const char *domainname,
101 const char **dirnamep,
102 const char **codesetp));
104 /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
105 to be used for the DOMAINNAME message catalog.
106 If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
107 modified, only the current value is returned.
108 If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
109 modified nor returned. */
110 static void
111 set_binding_values (domainname, dirnamep, codesetp)
112 const char *domainname;
113 const char **dirnamep;
114 const char **codesetp;
116 struct binding *binding;
117 int modified;
119 /* Some sanity checks. */
120 if (domainname == NULL || domainname[0] == '\0')
122 if (dirnamep)
123 *dirnamep = NULL;
124 if (codesetp)
125 *codesetp = NULL;
126 return;
129 __libc_rwlock_wrlock (_nl_state_lock);
131 modified = 0;
133 for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
135 int compare = strcmp (domainname, binding->domainname);
136 if (compare == 0)
137 /* We found it! */
138 break;
139 if (compare < 0)
141 /* It is not in the list. */
142 binding = NULL;
143 break;
147 if (binding != NULL)
149 if (dirnamep)
151 const char *dirname = *dirnamep;
153 if (dirname == NULL)
154 /* The current binding has be to returned. */
155 *dirnamep = binding->dirname;
156 else
158 /* The domain is already bound. If the new value and the old
159 one are equal we simply do nothing. Otherwise replace the
160 old binding. */
161 char *result = binding->dirname;
162 if (strcmp (dirname, result) != 0)
164 if (strcmp (dirname, _nl_default_dirname) == 0)
165 result = (char *) _nl_default_dirname;
166 else
168 #if defined _LIBC || defined HAVE_STRDUP
169 result = strdup (dirname);
170 #else
171 size_t len = strlen (dirname) + 1;
172 result = (char *) malloc (len);
173 if (__builtin_expect (result != NULL, 1))
174 memcpy (result, dirname, len);
175 #endif
178 if (__builtin_expect (result != NULL, 1))
180 if (binding->dirname != _nl_default_dirname)
181 free (binding->dirname);
183 binding->dirname = result;
184 modified = 1;
187 *dirnamep = result;
191 if (codesetp)
193 const char *codeset = *codesetp;
195 if (codeset == NULL)
196 /* The current binding has be to returned. */
197 *codesetp = binding->codeset;
198 else
200 /* The domain is already bound. If the new value and the old
201 one are equal we simply do nothing. Otherwise replace the
202 old binding. */
203 char *result = binding->codeset;
204 if (result == NULL || strcmp (codeset, result) != 0)
206 #if defined _LIBC || defined HAVE_STRDUP
207 result = strdup (codeset);
208 #else
209 size_t len = strlen (codeset) + 1;
210 result = (char *) malloc (len);
211 if (__builtin_expect (result != NULL, 1))
212 memcpy (result, codeset, len);
213 #endif
215 if (__builtin_expect (result != NULL, 1))
217 if (binding->codeset != NULL)
218 free (binding->codeset);
220 binding->codeset = result;
221 ++binding->codeset_cntr;
222 modified = 1;
225 *codesetp = result;
229 else if ((dirnamep == NULL || *dirnamep == NULL)
230 && (codesetp == NULL || *codesetp == NULL))
232 /* Simply return the default values. */
233 if (dirnamep)
234 *dirnamep = _nl_default_dirname;
235 if (codesetp)
236 *codesetp = NULL;
238 else
240 /* We have to create a new binding. */
241 size_t len = strlen (domainname) + 1;
242 struct binding *new_binding =
243 (struct binding *) malloc (offsetof (struct binding, domainname) + len);
245 if (__builtin_expect (new_binding == NULL, 0))
246 goto failed;
248 memcpy (new_binding->domainname, domainname, len);
250 if (dirnamep)
252 const char *dirname = *dirnamep;
254 if (dirname == NULL)
255 /* The default value. */
256 dirname = _nl_default_dirname;
257 else
259 if (strcmp (dirname, _nl_default_dirname) == 0)
260 dirname = _nl_default_dirname;
261 else
263 char *result;
264 #if defined _LIBC || defined HAVE_STRDUP
265 result = strdup (dirname);
266 if (__builtin_expect (result == NULL, 0))
267 goto failed_dirname;
268 #else
269 size_t len = strlen (dirname) + 1;
270 result = (char *) malloc (len);
271 if (__builtin_expect (result == NULL, 0))
272 goto failed_dirname;
273 memcpy (result, dirname, len);
274 #endif
275 dirname = result;
278 *dirnamep = dirname;
279 new_binding->dirname = (char *) dirname;
281 else
282 /* The default value. */
283 new_binding->dirname = (char *) _nl_default_dirname;
285 new_binding->codeset_cntr = 0;
287 if (codesetp)
289 const char *codeset = *codesetp;
291 if (codeset != NULL)
293 char *result;
295 #if defined _LIBC || defined HAVE_STRDUP
296 result = strdup (codeset);
297 if (__builtin_expect (result == NULL, 0))
298 goto failed_codeset;
299 #else
300 size_t len = strlen (codeset) + 1;
301 result = (char *) malloc (len);
302 if (__builtin_expect (result == NULL, 0))
303 goto failed_codeset;
304 memcpy (result, codeset, len);
305 #endif
306 codeset = result;
307 ++new_binding->codeset_cntr;
309 *codesetp = codeset;
310 new_binding->codeset = (char *) codeset;
312 else
313 new_binding->codeset = NULL;
315 /* Now enqueue it. */
316 if (_nl_domain_bindings == NULL
317 || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
319 new_binding->next = _nl_domain_bindings;
320 _nl_domain_bindings = new_binding;
322 else
324 binding = _nl_domain_bindings;
325 while (binding->next != NULL
326 && strcmp (domainname, binding->next->domainname) > 0)
327 binding = binding->next;
329 new_binding->next = binding->next;
330 binding->next = new_binding;
333 modified = 1;
335 /* Here we deal with memory allocation failures. */
336 if (0)
338 failed_codeset:
339 if (new_binding->dirname != _nl_default_dirname)
340 free (new_binding->dirname);
341 failed_dirname:
342 free (new_binding);
343 failed:
344 if (dirnamep)
345 *dirnamep = NULL;
346 if (codesetp)
347 *codesetp = NULL;
351 /* If we modified any binding, we flush the caches. */
352 if (modified)
353 ++_nl_msg_cat_cntr;
355 __libc_rwlock_unlock (_nl_state_lock);
358 /* Specify that the DOMAINNAME message catalog will be found
359 in DIRNAME rather than in the system locale data base. */
360 char *
361 BINDTEXTDOMAIN (domainname, dirname)
362 const char *domainname;
363 const char *dirname;
365 set_binding_values (domainname, &dirname, NULL);
366 return (char *) dirname;
369 /* Specify the character encoding in which the messages from the
370 DOMAINNAME message catalog will be returned. */
371 char *
372 BIND_TEXTDOMAIN_CODESET (domainname, codeset)
373 const char *domainname;
374 const char *codeset;
376 set_binding_values (domainname, NULL, &codeset);
377 return (char *) codeset;
380 #ifdef _LIBC
381 /* Aliases for function names in GNU C Library. */
382 weak_alias (__bindtextdomain, bindtextdomain);
383 weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);
384 #endif