1
1
/* Implementation of the bindtextdomain(3) function
2
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
2
Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc.
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2, or (at your option)
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)
9
9
This program is distributed in the hope that it will be useful,
10
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
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 General Public License
15
along with this program; if not, write to the Free Software Foundation,
16
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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,
18
19
#ifdef HAVE_CONFIG_H
19
20
# include <config.h>
22
#if defined STDC_HEADERS || defined _LIBC
32
#if defined HAVE_STRING_H || defined _LIBC
37
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
42
28
# include <libintl.h>
44
# include "libgettext.h"
30
# include "libgnuintl.h"
47
32
#include "gettextP.h"
35
/* We have to handle multi-threaded applications. */
36
# include <bits/libc-lock.h>
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)
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. */
48
# define _nl_default_dirname _nl_default_dirname__
49
# define _nl_domain_bindings _nl_domain_bindings__
52
/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
54
# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
49
57
/* @@ end of prolog @@ */
51
59
/* Contains the default location of the message catalogs. */
61
72
prefix. So we have to make a difference here. */
63
74
# define BINDTEXTDOMAIN __bindtextdomain
75
# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
65
77
# define strdup(str) __strdup (str)
68
80
# define BINDTEXTDOMAIN bindtextdomain__
81
# define BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset__
71
/* Specify that the DOMAINNAME message catalog will be found
72
in DIRNAME rather than in the system locale data base. */
74
BINDTEXTDOMAIN (domainname, dirname)
84
/* Prototypes for local functions. */
85
static void set_binding_values PARAMS ((const char *domainname,
86
const char **dirnamep,
87
const char **codesetp));
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. */
96
set_binding_values (domainname, dirnamep, codesetp)
75
97
const char *domainname;
98
const char **dirnamep;
99
const char **codesetp;
78
101
struct binding *binding;
80
104
/* Some sanity checks. */
81
105
if (domainname == NULL || domainname[0] == '\0')
114
__libc_rwlock_wrlock (_nl_state_lock);
84
118
for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
99
/* The current binding has be to returned. */
100
return binding == NULL ? (char *) _nl_default_dirname : binding->dirname;
102
132
if (binding != NULL)
104
/* The domain is already bound. If the new value and the old
105
one are equal we simply do nothing. Otherwise replace the
107
if (strcmp (dirname, binding->dirname) != 0)
111
if (strcmp (dirname, _nl_default_dirname) == 0)
112
new_dirname = (char *) _nl_default_dirname;
115
#if defined _LIBC || defined HAVE_STRDUP
116
new_dirname = strdup (dirname);
117
if (new_dirname == NULL)
120
size_t len = strlen (dirname) + 1;
121
new_dirname = (char *) malloc (len);
122
if (new_dirname == NULL)
125
memcpy (new_dirname, dirname, len);
129
if (binding->dirname != _nl_default_dirname)
130
free (binding->dirname);
132
binding->dirname = new_dirname;
136
const char *dirname = *dirnamep;
139
/* The current binding has be to returned. */
140
*dirnamep = binding->dirname;
143
/* The domain is already bound. If the new value and the old
144
one are equal we simply do nothing. Otherwise replace the
146
char *result = binding->dirname;
147
if (strcmp (dirname, result) != 0)
149
if (strcmp (dirname, _nl_default_dirname) == 0)
150
result = (char *) _nl_default_dirname;
153
#if defined _LIBC || defined HAVE_STRDUP
154
result = strdup (dirname);
156
size_t len = strlen (dirname) + 1;
157
result = (char *) malloc (len);
158
if (__builtin_expect (result != NULL, 1))
159
memcpy (result, dirname, len);
163
if (__builtin_expect (result != NULL, 1))
165
if (binding->dirname != _nl_default_dirname)
166
free (binding->dirname);
168
binding->dirname = result;
178
const char *codeset = *codesetp;
181
/* The current binding has be to returned. */
182
*codesetp = binding->codeset;
185
/* The domain is already bound. If the new value and the old
186
one are equal we simply do nothing. Otherwise replace the
188
char *result = binding->codeset;
189
if (result == NULL || strcmp (codeset, result) != 0)
191
#if defined _LIBC || defined HAVE_STRDUP
192
result = strdup (codeset);
194
size_t len = strlen (codeset) + 1;
195
result = (char *) malloc (len);
196
if (__builtin_expect (result != NULL, 1))
197
memcpy (result, codeset, len);
200
if (__builtin_expect (result != NULL, 1))
202
if (binding->codeset != NULL)
203
free (binding->codeset);
205
binding->codeset = result;
206
binding->codeset_cntr++;
214
else if ((dirnamep == NULL || *dirnamep == NULL)
215
&& (codesetp == NULL || *codesetp == NULL))
217
/* Simply return the default values. */
219
*dirnamep = _nl_default_dirname;
137
225
/* We have to create a new binding. */
138
#if !defined _LIBC && !defined HAVE_STRDUP
226
size_t len = strlen (domainname) + 1;
141
227
struct binding *new_binding =
142
(struct binding *) malloc (sizeof (*new_binding));
144
if (new_binding == NULL)
147
#if defined _LIBC || defined HAVE_STRDUP
148
new_binding->domainname = strdup (domainname);
149
if (new_binding->domainname == NULL)
152
len = strlen (domainname) + 1;
153
new_binding->domainname = (char *) malloc (len);
154
if (new_binding->domainname == NULL)
228
(struct binding *) malloc (offsetof (struct binding, domainname) + len);
230
if (__builtin_expect (new_binding == NULL, 0))
156
233
memcpy (new_binding->domainname, domainname, len);
237
const char *dirname = *dirnamep;
240
/* The default value. */
241
dirname = _nl_default_dirname;
244
if (strcmp (dirname, _nl_default_dirname) == 0)
245
dirname = _nl_default_dirname;
249
#if defined _LIBC || defined HAVE_STRDUP
250
result = strdup (dirname);
251
if (__builtin_expect (result == NULL, 0))
254
size_t len = strlen (dirname) + 1;
255
result = (char *) malloc (len);
256
if (__builtin_expect (result == NULL, 0))
258
memcpy (result, dirname, len);
159
if (strcmp (dirname, _nl_default_dirname) == 0)
264
new_binding->dirname = (char *) dirname;
267
/* The default value. */
160
268
new_binding->dirname = (char *) _nl_default_dirname;
270
new_binding->codeset_cntr = 0;
274
const char *codeset = *codesetp;
163
280
#if defined _LIBC || defined HAVE_STRDUP
164
new_binding->dirname = strdup (dirname);
165
if (new_binding->dirname == NULL)
281
result = strdup (codeset);
282
if (__builtin_expect (result == NULL, 0))
168
len = strlen (dirname) + 1;
169
new_binding->dirname = (char *) malloc (len);
170
if (new_binding->dirname == NULL)
172
memcpy (new_binding->dirname, dirname, len);
285
size_t len = strlen (codeset) + 1;
286
result = (char *) malloc (len);
287
if (__builtin_expect (result == NULL, 0))
289
memcpy (result, codeset, len);
292
new_binding->codeset_cntr++;
295
new_binding->codeset = (char *) codeset;
298
new_binding->codeset = NULL;
176
300
/* Now enqueue it. */
177
301
if (_nl_domain_bindings == NULL
191
315
binding->next = new_binding;
194
binding = new_binding;
320
/* Here we deal with memory allocation failures. */
324
if (new_binding->dirname != _nl_default_dirname)
325
free (new_binding->dirname);
197
return binding->dirname;
336
/* If we modified any binding, we flush the caches. */
340
__libc_rwlock_unlock (_nl_state_lock);
343
/* Specify that the DOMAINNAME message catalog will be found
344
in DIRNAME rather than in the system locale data base. */
346
BINDTEXTDOMAIN (domainname, dirname)
347
const char *domainname;
350
set_binding_values (domainname, &dirname, NULL);
351
return (char *) dirname;
354
/* Specify the character encoding in which the messages from the
355
DOMAINNAME message catalog will be returned. */
357
BIND_TEXTDOMAIN_CODESET (domainname, codeset)
358
const char *domainname;
361
set_binding_values (domainname, NULL, &codeset);
362
return (char *) codeset;
201
/* Alias for function name in GNU C Library. */
366
/* Aliases for function names in GNU C Library. */
202
367
weak_alias (__bindtextdomain, bindtextdomain);
368
weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);