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 /* Prototypes for local functions. */
88 static void set_binding_values (const char *domainname
, const char **dirnamep
,
89 const char **codesetp
);
91 /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
92 to be used for the DOMAINNAME message catalog.
93 If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
94 modified, only the current value is returned.
95 If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
96 modified nor returned. */
98 set_binding_values (domainname
, dirnamep
, codesetp
)
99 const char *domainname
;
100 const char **dirnamep
;
101 const char **codesetp
;
103 struct binding
*binding
;
106 /* Some sanity checks. */
107 if (domainname
== NULL
|| domainname
[0] == '\0')
116 __libc_rwlock_wrlock (_nl_state_lock
);
120 for (binding
= _nl_domain_bindings
; binding
!= NULL
; binding
= binding
->next
)
122 int compare
= strcmp (domainname
, binding
->domainname
);
128 /* It is not in the list. */
138 const char *dirname
= *dirnamep
;
141 /* The current binding has be to returned. */
142 *dirnamep
= binding
->dirname
;
145 /* The domain is already bound. If the new value and the old
146 one are equal we simply do nothing. Otherwise replace the
148 char *result
= binding
->dirname
;
149 if (strcmp (dirname
, result
) != 0)
151 if (strcmp (dirname
, _nl_default_dirname
) == 0)
152 result
= (char *) _nl_default_dirname
;
155 #if defined _LIBC || defined HAVE_STRDUP
156 result
= strdup (dirname
);
158 size_t len
= strlen (dirname
) + 1;
159 result
= (char *) malloc (len
);
160 if (__builtin_expect (result
!= NULL
, 1))
161 memcpy (result
, dirname
, len
);
165 if (__builtin_expect (result
!= NULL
, 1))
167 if (binding
->dirname
!= _nl_default_dirname
)
168 free (binding
->dirname
);
170 binding
->dirname
= result
;
180 const char *codeset
= *codesetp
;
183 /* The current binding has be to returned. */
184 *codesetp
= binding
->codeset
;
187 /* The domain is already bound. If the new value and the old
188 one are equal we simply do nothing. Otherwise replace the
190 char *result
= binding
->codeset
;
191 if (result
== NULL
|| strcmp (codeset
, result
) != 0)
193 #if defined _LIBC || defined HAVE_STRDUP
194 result
= strdup (codeset
);
196 size_t len
= strlen (codeset
) + 1;
197 result
= (char *) malloc (len
);
198 if (__builtin_expect (result
!= NULL
, 1))
199 memcpy (result
, codeset
, len
);
202 if (__builtin_expect (result
!= NULL
, 1))
204 if (binding
->codeset
!= NULL
)
205 free (binding
->codeset
);
207 binding
->codeset
= result
;
215 else if ((dirnamep
== NULL
|| *dirnamep
== NULL
)
216 && (codesetp
== NULL
|| *codesetp
== NULL
))
218 /* Simply return the default values. */
220 *dirnamep
= _nl_default_dirname
;
226 /* We have to create a new binding. */
227 size_t len
= strlen (domainname
) + 1;
228 struct binding
*new_binding
=
229 (struct binding
*) malloc (sizeof (*new_binding
) + len
);
231 if (__builtin_expect (new_binding
== NULL
, 0))
234 memcpy (new_binding
->domainname
, domainname
, len
);
238 const char *dirname
= *dirnamep
;
241 /* The default value. */
242 dirname
= _nl_default_dirname
;
245 if (strcmp (dirname
, _nl_default_dirname
) == 0)
246 dirname
= _nl_default_dirname
;
250 #if defined _LIBC || defined HAVE_STRDUP
251 result
= strdup (dirname
);
252 if (__builtin_expect (result
== NULL
, 0))
255 size_t len
= strlen (dirname
) + 1;
256 result
= (char *) malloc (len
);
257 if (__builtin_expect (result
== NULL
, 0))
259 memcpy (result
, dirname
, len
);
265 new_binding
->dirname
= (char *) dirname
;
268 /* The default value. */
269 new_binding
->dirname
= (char *) _nl_default_dirname
;
273 const char *codeset
= *codesetp
;
279 #if defined _LIBC || defined HAVE_STRDUP
280 result
= strdup (codeset
);
281 if (__builtin_expect (result
== NULL
, 0))
284 size_t len
= strlen (codeset
) + 1;
285 result
= (char *) malloc (len
);
286 if (__builtin_expect (result
== NULL
, 0))
288 memcpy (result
, codeset
, len
);
293 new_binding
->codeset
= (char *) codeset
;
296 new_binding
->codeset
= NULL
;
298 /* Now enqueue it. */
299 if (_nl_domain_bindings
== NULL
300 || strcmp (domainname
, _nl_domain_bindings
->domainname
) < 0)
302 new_binding
->next
= _nl_domain_bindings
;
303 _nl_domain_bindings
= new_binding
;
307 binding
= _nl_domain_bindings
;
308 while (binding
->next
!= NULL
309 && strcmp (domainname
, binding
->next
->domainname
) > 0)
310 binding
= binding
->next
;
312 new_binding
->next
= binding
->next
;
313 binding
->next
= new_binding
;
318 /* Here we deal with memory allocation failures. */
322 if (new_binding
->dirname
!= _nl_default_dirname
)
323 free (new_binding
->dirname
);
334 /* If we modified any binding, we flush the caches. */
338 __libc_rwlock_unlock (_nl_state_lock
);
341 /* Specify that the DOMAINNAME message catalog will be found
342 in DIRNAME rather than in the system locale data base. */
344 BINDTEXTDOMAIN (domainname
, dirname
)
345 const char *domainname
;
348 set_binding_values (domainname
, &dirname
, NULL
);
349 return (char *) dirname
;
352 /* Specify the character encoding in which the messages from the
353 DOMAINNAME message catalog will be returned. */
355 BIND_TEXTDOMAIN_CODESET (domainname
, codeset
)
356 const char *domainname
;
359 set_binding_values (domainname
, NULL
, &codeset
);
360 return (char *) codeset
;
364 /* Aliases for function names in GNU C Library. */
365 weak_alias (__bindtextdomain
, bindtextdomain
);
366 weak_alias (__bind_textdomain_codeset
, bind_textdomain_codeset
);