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 /* @@ end of prolog @@ */
62 /* Contains the default location of the message catalogs. */
63 extern const char _nl_default_dirname
[];
65 /* List with bindings of specific domains. */
66 extern struct binding
*_nl_domain_bindings
;
68 /* Lock variable to protect the global data in the gettext implementation. */
69 __libc_rwlock_define (extern, _nl_state_lock
)
72 /* Names for the libintl functions are a problem. They must not clash
73 with existing names and they should follow ANSI C. But this source
74 code is also used in GNU C Library where the names have a __
75 prefix. So we have to make a difference here. */
77 # define BINDTEXTDOMAIN __bindtextdomain
78 # define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
80 # define strdup(str) __strdup (str)
83 # define BINDTEXTDOMAIN bindtextdomain__
84 # define BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset__
87 /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
88 to be used for the DOMAINNAME message catalog.
89 If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
90 modified, only the current value is returned.
91 If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
92 modified nor returned. */
94 set_binding_values (domainname
, dirnamep
, codesetp
)
95 const char *domainname
;
96 const char **dirnamep
;
97 const char **codesetp
;
99 struct binding
*binding
;
102 /* Some sanity checks. */
103 if (domainname
== NULL
|| domainname
[0] == '\0')
112 __libc_rwlock_wrlock (_nl_state_lock
);
116 for (binding
= _nl_domain_bindings
; binding
!= NULL
; binding
= binding
->next
)
118 int compare
= strcmp (domainname
, binding
->domainname
);
124 /* It is not in the list. */
134 const char *dirname
= *dirnamep
;
137 /* The current binding has be to returned. */
138 *dirnamep
= binding
->dirname
;
141 /* The domain is already bound. If the new value and the old
142 one are equal we simply do nothing. Otherwise replace the
144 char *result
= binding
->dirname
;
145 if (strcmp (dirname
, result
) != 0)
147 if (strcmp (dirname
, _nl_default_dirname
) == 0)
148 result
= (char *) _nl_default_dirname
;
151 #if defined _LIBC || defined HAVE_STRDUP
152 result
= strdup (dirname
);
154 size_t len
= strlen (dirname
) + 1;
155 result
= (char *) malloc (len
);
156 if (__builtin_expect (result
!= NULL
, 1))
157 memcpy (result
, dirname
, len
);
161 if (__builtin_expect (result
!= NULL
, 1))
163 if (binding
->dirname
!= _nl_default_dirname
)
164 free (binding
->dirname
);
166 binding
->dirname
= result
;
176 const char *codeset
= *codesetp
;
179 /* The current binding has be to returned. */
180 *codesetp
= binding
->codeset
;
183 /* The domain is already bound. If the new value and the old
184 one are equal we simply do nothing. Otherwise replace the
186 char *result
= binding
->codeset
;
187 if (result
== NULL
|| strcmp (codeset
, result
) != 0)
189 #if defined _LIBC || defined HAVE_STRDUP
190 result
= strdup (codeset
);
192 size_t len
= strlen (codeset
) + 1;
193 result
= (char *) malloc (len
);
194 if (__builtin_expect (result
!= NULL
, 1))
195 memcpy (result
, codeset
, len
);
198 if (__builtin_expect (result
!= NULL
, 1))
200 if (binding
->codeset
!= NULL
)
201 free (binding
->codeset
);
203 binding
->codeset
= result
;
211 else if ((dirnamep
== NULL
|| *dirnamep
== NULL
)
212 && (codesetp
== NULL
|| *codesetp
== NULL
))
214 /* Simply return the default values. */
216 *dirnamep
= _nl_default_dirname
;
222 /* We have to create a new binding. */
223 size_t len
= strlen (domainname
) + 1;
224 struct binding
*new_binding
=
225 (struct binding
*) malloc (sizeof (*new_binding
) + len
);
227 if (__builtin_expect (new_binding
== NULL
, 0))
230 memcpy (new_binding
->domainname
, domainname
, len
);
234 const char *dirname
= *dirnamep
;
237 /* The default value. */
238 dirname
= _nl_default_dirname
;
241 if (strcmp (dirname
, _nl_default_dirname
) == 0)
242 dirname
= _nl_default_dirname
;
246 #if defined _LIBC || defined HAVE_STRDUP
247 result
= strdup (dirname
);
248 if (__builtin_expect (result
== NULL
, 0))
251 size_t len
= strlen (dirname
) + 1;
252 result
= (char *) malloc (len
);
253 if (__builtin_expect (result
== NULL
, 0))
255 memcpy (result
, dirname
, len
);
261 new_binding
->dirname
= (char *) dirname
;
264 /* The default value. */
265 new_binding
->dirname
= (char *) _nl_default_dirname
;
269 const char *codeset
= *codesetp
;
275 #if defined _LIBC || defined HAVE_STRDUP
276 result
= strdup (codeset
);
277 if (__builtin_expect (result
== NULL
, 0))
280 size_t len
= strlen (codeset
) + 1;
281 result
= (char *) malloc (len
);
282 if (__builtin_expect (result
== NULL
, 0))
284 memcpy (result
, codeset
, len
);
289 new_binding
->codeset
= (char *) codeset
;
292 new_binding
->codeset
= NULL
;
294 /* Now enqueue it. */
295 if (_nl_domain_bindings
== NULL
296 || strcmp (domainname
, _nl_domain_bindings
->domainname
) < 0)
298 new_binding
->next
= _nl_domain_bindings
;
299 _nl_domain_bindings
= new_binding
;
303 binding
= _nl_domain_bindings
;
304 while (binding
->next
!= NULL
305 && strcmp (domainname
, binding
->next
->domainname
) > 0)
306 binding
= binding
->next
;
308 new_binding
->next
= binding
->next
;
309 binding
->next
= new_binding
;
314 /* Here we deal with memory allocation failures. */
318 if (new_binding
->dirname
!= _nl_default_dirname
)
319 free (new_binding
->dirname
);
330 /* If we modified any binding, we flush the caches. */
334 __libc_rwlock_unlock (_nl_state_lock
);
337 /* Specify that the DOMAINNAME message catalog will be found
338 in DIRNAME rather than in the system locale data base. */
340 BINDTEXTDOMAIN (domainname
, dirname
)
341 const char *domainname
;
344 set_binding_values (domainname
, &dirname
, NULL
);
345 return (char *) dirname
;
348 /* Specify the character encoding in which the messages from the
349 DOMAINNAME message catalog will be returned. */
351 BIND_TEXTDOMAIN_CODESET (domainname
, codeset
)
352 const char *domainname
;
355 set_binding_values (domainname
, NULL
, &codeset
);
356 return (char *) codeset
;
360 /* Aliases for function names in GNU C Library. */
361 weak_alias (__bindtextdomain
, bindtextdomain
);
362 weak_alias (__bind_textdomain_codeset
, bind_textdomain_codeset
);