1*3d8817e4Smiod /* Implementation of the bindtextdomain(3) function
2*3d8817e4Smiod Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
3*3d8817e4Smiod
4*3d8817e4Smiod This program is free software; you can redistribute it and/or modify
5*3d8817e4Smiod it under the terms of the GNU General Public License as published by
6*3d8817e4Smiod the Free Software Foundation; either version 2, or (at your option)
7*3d8817e4Smiod any later version.
8*3d8817e4Smiod
9*3d8817e4Smiod This program is distributed in the hope that it will be useful,
10*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
11*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*3d8817e4Smiod GNU General Public License for more details.
13*3d8817e4Smiod
14*3d8817e4Smiod You should have received a copy of the GNU General Public License
15*3d8817e4Smiod along with this program; if not, write to the Free Software Foundation,
16*3d8817e4Smiod Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
17*3d8817e4Smiod
18*3d8817e4Smiod #ifdef HAVE_CONFIG_H
19*3d8817e4Smiod # include <config.h>
20*3d8817e4Smiod #endif
21*3d8817e4Smiod
22*3d8817e4Smiod #if defined STDC_HEADERS || defined _LIBC
23*3d8817e4Smiod # include <stdlib.h>
24*3d8817e4Smiod #else
25*3d8817e4Smiod # ifdef HAVE_MALLOC_H
26*3d8817e4Smiod # include <malloc.h>
27*3d8817e4Smiod # else
28*3d8817e4Smiod void free ();
29*3d8817e4Smiod # endif
30*3d8817e4Smiod #endif
31*3d8817e4Smiod
32*3d8817e4Smiod #if defined HAVE_STRING_H || defined _LIBC
33*3d8817e4Smiod # include <string.h>
34*3d8817e4Smiod #else
35*3d8817e4Smiod # include <strings.h>
36*3d8817e4Smiod # ifndef memcpy
37*3d8817e4Smiod # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
38*3d8817e4Smiod # endif
39*3d8817e4Smiod #endif
40*3d8817e4Smiod
41*3d8817e4Smiod #ifdef _LIBC
42*3d8817e4Smiod # include <libintl.h>
43*3d8817e4Smiod #else
44*3d8817e4Smiod # include "libgettext.h"
45*3d8817e4Smiod #endif
46*3d8817e4Smiod #include "gettext.h"
47*3d8817e4Smiod #include "gettextP.h"
48*3d8817e4Smiod
49*3d8817e4Smiod /* @@ end of prolog @@ */
50*3d8817e4Smiod
51*3d8817e4Smiod /* Contains the default location of the message catalogs. */
52*3d8817e4Smiod extern const char _nl_default_dirname[];
53*3d8817e4Smiod
54*3d8817e4Smiod /* List with bindings of specific domains. */
55*3d8817e4Smiod extern struct binding *_nl_domain_bindings;
56*3d8817e4Smiod
57*3d8817e4Smiod
58*3d8817e4Smiod /* Names for the libintl functions are a problem. They must not clash
59*3d8817e4Smiod with existing names and they should follow ANSI C. But this source
60*3d8817e4Smiod code is also used in GNU C Library where the names have a __
61*3d8817e4Smiod prefix. So we have to make a difference here. */
62*3d8817e4Smiod #ifdef _LIBC
63*3d8817e4Smiod # define BINDTEXTDOMAIN __bindtextdomain
64*3d8817e4Smiod # ifndef strdup
65*3d8817e4Smiod # define strdup(str) __strdup (str)
66*3d8817e4Smiod # endif
67*3d8817e4Smiod #else
68*3d8817e4Smiod # define BINDTEXTDOMAIN bindtextdomain__
69*3d8817e4Smiod #endif
70*3d8817e4Smiod
71*3d8817e4Smiod /* Specify that the DOMAINNAME message catalog will be found
72*3d8817e4Smiod in DIRNAME rather than in the system locale data base. */
73*3d8817e4Smiod char *
BINDTEXTDOMAIN(domainname,dirname)74*3d8817e4Smiod BINDTEXTDOMAIN (domainname, dirname)
75*3d8817e4Smiod const char *domainname;
76*3d8817e4Smiod const char *dirname;
77*3d8817e4Smiod {
78*3d8817e4Smiod struct binding *binding;
79*3d8817e4Smiod
80*3d8817e4Smiod /* Some sanity checks. */
81*3d8817e4Smiod if (domainname == NULL || domainname[0] == '\0')
82*3d8817e4Smiod return NULL;
83*3d8817e4Smiod
84*3d8817e4Smiod for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
85*3d8817e4Smiod {
86*3d8817e4Smiod int compare = strcmp (domainname, binding->domainname);
87*3d8817e4Smiod if (compare == 0)
88*3d8817e4Smiod /* We found it! */
89*3d8817e4Smiod break;
90*3d8817e4Smiod if (compare < 0)
91*3d8817e4Smiod {
92*3d8817e4Smiod /* It is not in the list. */
93*3d8817e4Smiod binding = NULL;
94*3d8817e4Smiod break;
95*3d8817e4Smiod }
96*3d8817e4Smiod }
97*3d8817e4Smiod
98*3d8817e4Smiod if (dirname == NULL)
99*3d8817e4Smiod /* The current binding has be to returned. */
100*3d8817e4Smiod return binding == NULL ? (char *) _nl_default_dirname : binding->dirname;
101*3d8817e4Smiod
102*3d8817e4Smiod if (binding != NULL)
103*3d8817e4Smiod {
104*3d8817e4Smiod /* The domain is already bound. If the new value and the old
105*3d8817e4Smiod one are equal we simply do nothing. Otherwise replace the
106*3d8817e4Smiod old binding. */
107*3d8817e4Smiod if (strcmp (dirname, binding->dirname) != 0)
108*3d8817e4Smiod {
109*3d8817e4Smiod char *new_dirname;
110*3d8817e4Smiod
111*3d8817e4Smiod if (strcmp (dirname, _nl_default_dirname) == 0)
112*3d8817e4Smiod new_dirname = (char *) _nl_default_dirname;
113*3d8817e4Smiod else
114*3d8817e4Smiod {
115*3d8817e4Smiod #if defined _LIBC || defined HAVE_STRDUP
116*3d8817e4Smiod new_dirname = strdup (dirname);
117*3d8817e4Smiod if (new_dirname == NULL)
118*3d8817e4Smiod return NULL;
119*3d8817e4Smiod #else
120*3d8817e4Smiod size_t len = strlen (dirname) + 1;
121*3d8817e4Smiod new_dirname = (char *) malloc (len);
122*3d8817e4Smiod if (new_dirname == NULL)
123*3d8817e4Smiod return NULL;
124*3d8817e4Smiod
125*3d8817e4Smiod memcpy (new_dirname, dirname, len);
126*3d8817e4Smiod #endif
127*3d8817e4Smiod }
128*3d8817e4Smiod
129*3d8817e4Smiod if (binding->dirname != _nl_default_dirname)
130*3d8817e4Smiod free (binding->dirname);
131*3d8817e4Smiod
132*3d8817e4Smiod binding->dirname = new_dirname;
133*3d8817e4Smiod }
134*3d8817e4Smiod }
135*3d8817e4Smiod else
136*3d8817e4Smiod {
137*3d8817e4Smiod /* We have to create a new binding. */
138*3d8817e4Smiod #if !defined _LIBC && !defined HAVE_STRDUP
139*3d8817e4Smiod size_t len;
140*3d8817e4Smiod #endif
141*3d8817e4Smiod struct binding *new_binding =
142*3d8817e4Smiod (struct binding *) malloc (sizeof (*new_binding));
143*3d8817e4Smiod
144*3d8817e4Smiod if (new_binding == NULL)
145*3d8817e4Smiod return NULL;
146*3d8817e4Smiod
147*3d8817e4Smiod #if defined _LIBC || defined HAVE_STRDUP
148*3d8817e4Smiod new_binding->domainname = strdup (domainname);
149*3d8817e4Smiod if (new_binding->domainname == NULL)
150*3d8817e4Smiod return NULL;
151*3d8817e4Smiod #else
152*3d8817e4Smiod len = strlen (domainname) + 1;
153*3d8817e4Smiod new_binding->domainname = (char *) malloc (len);
154*3d8817e4Smiod if (new_binding->domainname == NULL)
155*3d8817e4Smiod return NULL;
156*3d8817e4Smiod memcpy (new_binding->domainname, domainname, len);
157*3d8817e4Smiod #endif
158*3d8817e4Smiod
159*3d8817e4Smiod if (strcmp (dirname, _nl_default_dirname) == 0)
160*3d8817e4Smiod new_binding->dirname = (char *) _nl_default_dirname;
161*3d8817e4Smiod else
162*3d8817e4Smiod {
163*3d8817e4Smiod #if defined _LIBC || defined HAVE_STRDUP
164*3d8817e4Smiod new_binding->dirname = strdup (dirname);
165*3d8817e4Smiod if (new_binding->dirname == NULL)
166*3d8817e4Smiod return NULL;
167*3d8817e4Smiod #else
168*3d8817e4Smiod len = strlen (dirname) + 1;
169*3d8817e4Smiod new_binding->dirname = (char *) malloc (len);
170*3d8817e4Smiod if (new_binding->dirname == NULL)
171*3d8817e4Smiod return NULL;
172*3d8817e4Smiod memcpy (new_binding->dirname, dirname, len);
173*3d8817e4Smiod #endif
174*3d8817e4Smiod }
175*3d8817e4Smiod
176*3d8817e4Smiod /* Now enqueue it. */
177*3d8817e4Smiod if (_nl_domain_bindings == NULL
178*3d8817e4Smiod || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
179*3d8817e4Smiod {
180*3d8817e4Smiod new_binding->next = _nl_domain_bindings;
181*3d8817e4Smiod _nl_domain_bindings = new_binding;
182*3d8817e4Smiod }
183*3d8817e4Smiod else
184*3d8817e4Smiod {
185*3d8817e4Smiod binding = _nl_domain_bindings;
186*3d8817e4Smiod while (binding->next != NULL
187*3d8817e4Smiod && strcmp (domainname, binding->next->domainname) > 0)
188*3d8817e4Smiod binding = binding->next;
189*3d8817e4Smiod
190*3d8817e4Smiod new_binding->next = binding->next;
191*3d8817e4Smiod binding->next = new_binding;
192*3d8817e4Smiod }
193*3d8817e4Smiod
194*3d8817e4Smiod binding = new_binding;
195*3d8817e4Smiod }
196*3d8817e4Smiod
197*3d8817e4Smiod return binding->dirname;
198*3d8817e4Smiod }
199*3d8817e4Smiod
200*3d8817e4Smiod #ifdef _LIBC
201*3d8817e4Smiod /* Alias for function name in GNU C Library. */
202*3d8817e4Smiod weak_alias (__bindtextdomain, bindtextdomain);
203*3d8817e4Smiod #endif
204