1 /* Implementation of the bindtextdomain(3) function
2 Copyright (C) 1995, 1996, 1997, 1998, 2000 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. */
23 #if defined STDC_HEADERS || defined _LIBC
33 #if defined HAVE_STRING_H || defined _LIBC
38 # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
45 # include "libgettext.h"
51 /* We have to handle multi-threaded applications. */
52 # include <bits/libc-lock.h>
54 /* Provide dummy implementation if this is outside glibc. */
55 # define __libc_rwlock_define(CLASS, NAME)
56 # define __libc_rwlock_wrlock(NAME)
57 # define __libc_rwlock_unlock(NAME)
60 /* The internal variables in the standalone libintl.a must have different
61 names than the internal variables in GNU libc, otherwise programs
62 using libintl.a cannot be linked statically. */
64 # define _nl_default_dirname _nl_default_dirname__
65 # define _nl_domain_bindings _nl_domain_bindings__
68 /* @@ end of prolog @@ */
70 /* Contains the default location of the message catalogs. */
71 extern const char _nl_default_dirname[];
73 /* List with bindings of specific domains. */
74 extern struct binding *_nl_domain_bindings;
76 /* Lock variable to protect the global data in the gettext implementation. */
77 __libc_rwlock_define (extern, _nl_state_lock)
80 /* Names for the libintl functions are a problem. They must not clash
81 with existing names and they should follow ANSI C. But this source
82 code is also used in GNU C Library where the names have a __
83 prefix. So we have to make a difference here. */
85 # define BINDTEXTDOMAIN __bindtextdomain
86 # define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
88 # define strdup(str) __strdup (str)
91 # define BINDTEXTDOMAIN bindtextdomain__
92 # define BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset__
95 /* Prototypes for local functions. */
96 static void set_binding_values (const char *domainname, const char **dirnamep,
97 const char **codesetp);
99 /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
100 to be used for the DOMAINNAME message catalog.
101 If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
102 modified, only the current value is returned.
103 If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
104 modified nor returned. */
106 set_binding_values (domainname, dirnamep, codesetp)
107 const char *domainname;
108 const char **dirnamep;
109 const char **codesetp;
111 struct binding *binding;
114 /* Some sanity checks. */
115 if (domainname == NULL || domainname[0] == '\0')
124 __libc_rwlock_wrlock (_nl_state_lock);
128 for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
130 int compare = strcmp (domainname, binding->domainname);
136 /* It is not in the list. */
146 const char *dirname = *dirnamep;
149 /* The current binding has be to returned. */
150 *dirnamep = binding->dirname;
153 /* The domain is already bound. If the new value and the old
154 one are equal we simply do nothing. Otherwise replace the
156 char *result = binding->dirname;
157 if (strcmp (dirname, result) != 0)
159 if (strcmp (dirname, _nl_default_dirname) == 0)
160 result = (char *) _nl_default_dirname;
163 #if defined _LIBC || defined HAVE_STRDUP
164 result = strdup (dirname);
166 size_t len = strlen (dirname) + 1;
167 result = (char *) malloc (len);
168 if (__builtin_expect (result != NULL, 1))
169 memcpy (result, dirname, len);
173 if (__builtin_expect (result != NULL, 1))
175 if (binding->dirname != _nl_default_dirname)
176 free (binding->dirname);
178 binding->dirname = result;
188 const char *codeset = *codesetp;
191 /* The current binding has be to returned. */
192 *codesetp = binding->codeset;
195 /* The domain is already bound. If the new value and the old
196 one are equal we simply do nothing. Otherwise replace the
198 char *result = binding->codeset;
199 if (result == NULL || strcmp (codeset, result) != 0)
201 #if defined _LIBC || defined HAVE_STRDUP
202 result = strdup (codeset);
204 size_t len = strlen (codeset) + 1;
205 result = (char *) malloc (len);
206 if (__builtin_expect (result != NULL, 1))
207 memcpy (result, codeset, len);
210 if (__builtin_expect (result != NULL, 1))
212 if (binding->codeset != NULL)
213 free (binding->codeset);
215 binding->codeset = result;
223 else if ((dirnamep == NULL || *dirnamep == NULL)
224 && (codesetp == NULL || *codesetp == NULL))
226 /* Simply return the default values. */
228 *dirnamep = _nl_default_dirname;
234 /* We have to create a new binding. */
235 size_t len = strlen (domainname) + 1;
236 struct binding *new_binding =
237 (struct binding *) malloc (sizeof (*new_binding) + len);
239 if (__builtin_expect (new_binding == NULL, 0))
242 memcpy (new_binding->domainname, domainname, len);
246 const char *dirname = *dirnamep;
249 /* The default value. */
250 dirname = _nl_default_dirname;
253 if (strcmp (dirname, _nl_default_dirname) == 0)
254 dirname = _nl_default_dirname;
258 #if defined _LIBC || defined HAVE_STRDUP
259 result = strdup (dirname);
260 if (__builtin_expect (result == NULL, 0))
263 size_t len = strlen (dirname) + 1;
264 result = (char *) malloc (len);
265 if (__builtin_expect (result == NULL, 0))
267 memcpy (result, dirname, len);
273 new_binding->dirname = (char *) dirname;
276 /* The default value. */
277 new_binding->dirname = (char *) _nl_default_dirname;
281 const char *codeset = *codesetp;
287 #if defined _LIBC || defined HAVE_STRDUP
288 result = strdup (codeset);
289 if (__builtin_expect (result == NULL, 0))
292 size_t len = strlen (codeset) + 1;
293 result = (char *) malloc (len);
294 if (__builtin_expect (result == NULL, 0))
296 memcpy (result, codeset, len);
301 new_binding->codeset = (char *) codeset;
304 new_binding->codeset = NULL;
306 /* Now enqueue it. */
307 if (_nl_domain_bindings == NULL
308 || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
310 new_binding->next = _nl_domain_bindings;
311 _nl_domain_bindings = new_binding;
315 binding = _nl_domain_bindings;
316 while (binding->next != NULL
317 && strcmp (domainname, binding->next->domainname) > 0)
318 binding = binding->next;
320 new_binding->next = binding->next;
321 binding->next = new_binding;
326 /* Here we deal with memory allocation failures. */
330 if (new_binding->dirname != _nl_default_dirname)
331 free (new_binding->dirname);
342 /* If we modified any binding, we flush the caches. */
346 __libc_rwlock_unlock (_nl_state_lock);
349 /* Specify that the DOMAINNAME message catalog will be found
350 in DIRNAME rather than in the system locale data base. */
352 BINDTEXTDOMAIN (domainname, dirname)
353 const char *domainname;
356 set_binding_values (domainname, &dirname, NULL);
357 return (char *) dirname;
360 /* Specify the character encoding in which the messages from the
361 DOMAINNAME message catalog will be returned. */
363 BIND_TEXTDOMAIN_CODESET (domainname, codeset)
364 const char *domainname;
367 set_binding_values (domainname, NULL, &codeset);
368 return (char *) codeset;
372 /* Aliases for function names in GNU C Library. */
373 weak_alias (__bindtextdomain, bindtextdomain);
374 weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);