11cc83814Sespie /* Implementation of the textdomain(3) function.
2*a1acfa9bSespie Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
3840175f0Skstailey
43fb98d4aSespie This program is free software; you can redistribute it and/or modify it
53fb98d4aSespie under the terms of the GNU Library General Public License as published
63fb98d4aSespie by the Free Software Foundation; either version 2, or (at your option)
7840175f0Skstailey any later version.
8840175f0Skstailey
9840175f0Skstailey This program is distributed in the hope that it will be useful,
10840175f0Skstailey but WITHOUT ANY WARRANTY; without even the implied warranty of
113fb98d4aSespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
123fb98d4aSespie Library General Public License for more details.
13840175f0Skstailey
143fb98d4aSespie You should have received a copy of the GNU Library General Public
153fb98d4aSespie License along with this program; if not, write to the Free Software
163fb98d4aSespie Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
173fb98d4aSespie USA. */
18840175f0Skstailey
19840175f0Skstailey #ifdef HAVE_CONFIG_H
20840175f0Skstailey # include <config.h>
21840175f0Skstailey #endif
22840175f0Skstailey
23840175f0Skstailey #include <stdlib.h>
24840175f0Skstailey #include <string.h>
25840175f0Skstailey
26840175f0Skstailey #ifdef _LIBC
27840175f0Skstailey # include <libintl.h>
28840175f0Skstailey #else
293fb98d4aSespie # include "libgnuintl.h"
303fb98d4aSespie #endif
313fb98d4aSespie #include "gettextP.h"
323fb98d4aSespie
333fb98d4aSespie #ifdef _LIBC
343fb98d4aSespie /* We have to handle multi-threaded applications. */
353fb98d4aSespie # include <bits/libc-lock.h>
363fb98d4aSespie #else
373fb98d4aSespie /* Provide dummy implementation if this is outside glibc. */
383fb98d4aSespie # define __libc_rwlock_define(CLASS, NAME)
393fb98d4aSespie # define __libc_rwlock_wrlock(NAME)
403fb98d4aSespie # define __libc_rwlock_unlock(NAME)
413fb98d4aSespie #endif
423fb98d4aSespie
433fb98d4aSespie /* The internal variables in the standalone libintl.a must have different
443fb98d4aSespie names than the internal variables in GNU libc, otherwise programs
453fb98d4aSespie using libintl.a cannot be linked statically. */
463fb98d4aSespie #if !defined _LIBC
47*a1acfa9bSespie # define _nl_default_default_domain libintl_nl_default_default_domain
48*a1acfa9bSespie # define _nl_current_default_domain libintl_nl_current_default_domain
49840175f0Skstailey #endif
50840175f0Skstailey
51840175f0Skstailey /* @@ end of prolog @@ */
52840175f0Skstailey
53840175f0Skstailey /* Name of the default text domain. */
54*a1acfa9bSespie extern const char _nl_default_default_domain[] attribute_hidden;
55840175f0Skstailey
56840175f0Skstailey /* Default text domain in which entries for gettext(3) are to be found. */
57*a1acfa9bSespie extern const char *_nl_current_default_domain attribute_hidden;
58840175f0Skstailey
59840175f0Skstailey
60840175f0Skstailey /* Names for the libintl functions are a problem. They must not clash
61840175f0Skstailey with existing names and they should follow ANSI C. But this source
62840175f0Skstailey code is also used in GNU C Library where the names have a __
63840175f0Skstailey prefix. So we have to make a difference here. */
64840175f0Skstailey #ifdef _LIBC
65840175f0Skstailey # define TEXTDOMAIN __textdomain
661cc83814Sespie # ifndef strdup
6728ea187bSespie # define strdup(str) __strdup (str)
681cc83814Sespie # endif
69840175f0Skstailey #else
70*a1acfa9bSespie # define TEXTDOMAIN libintl_textdomain
71840175f0Skstailey #endif
72840175f0Skstailey
733fb98d4aSespie /* Lock variable to protect the global data in the gettext implementation. */
__libc_rwlock_define(extern,_nl_state_lock attribute_hidden)74*a1acfa9bSespie __libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
753fb98d4aSespie
76840175f0Skstailey /* Set the current default message catalog to DOMAINNAME.
77840175f0Skstailey If DOMAINNAME is null, return the current default.
78840175f0Skstailey If DOMAINNAME is "", reset to the default of "messages". */
79840175f0Skstailey char *
80*a1acfa9bSespie TEXTDOMAIN (const char *domainname)
81840175f0Skstailey {
823fb98d4aSespie char *new_domain;
833fb98d4aSespie char *old_domain;
84840175f0Skstailey
85840175f0Skstailey /* A NULL pointer requests the current setting. */
86840175f0Skstailey if (domainname == NULL)
87840175f0Skstailey return (char *) _nl_current_default_domain;
88840175f0Skstailey
893fb98d4aSespie __libc_rwlock_wrlock (_nl_state_lock);
903fb98d4aSespie
913fb98d4aSespie old_domain = (char *) _nl_current_default_domain;
92840175f0Skstailey
93840175f0Skstailey /* If domain name is the null string set to default domain "messages". */
94840175f0Skstailey if (domainname[0] == '\0'
95840175f0Skstailey || strcmp (domainname, _nl_default_default_domain) == 0)
963fb98d4aSespie {
97840175f0Skstailey _nl_current_default_domain = _nl_default_default_domain;
983fb98d4aSespie new_domain = (char *) _nl_current_default_domain;
993fb98d4aSespie }
1003fb98d4aSespie else if (strcmp (domainname, old_domain) == 0)
1013fb98d4aSespie /* This can happen and people will use it to signal that some
1023fb98d4aSespie environment variable changed. */
1033fb98d4aSespie new_domain = old_domain;
104840175f0Skstailey else
105840175f0Skstailey {
106840175f0Skstailey /* If the following malloc fails `_nl_current_default_domain'
107840175f0Skstailey will be NULL. This value will be returned and so signals we
108840175f0Skstailey are out of core. */
10928ea187bSespie #if defined _LIBC || defined HAVE_STRDUP
1103fb98d4aSespie new_domain = strdup (domainname);
11128ea187bSespie #else
112840175f0Skstailey size_t len = strlen (domainname) + 1;
1133fb98d4aSespie new_domain = (char *) malloc (len);
1143fb98d4aSespie if (new_domain != NULL)
1153fb98d4aSespie memcpy (new_domain, domainname, len);
11628ea187bSespie #endif
1173fb98d4aSespie
1183fb98d4aSespie if (new_domain != NULL)
1193fb98d4aSespie _nl_current_default_domain = new_domain;
120840175f0Skstailey }
121840175f0Skstailey
1223fb98d4aSespie /* We use this possibility to signal a change of the loaded catalogs
1233fb98d4aSespie since this is most likely the case and there is no other easy we
1243fb98d4aSespie to do it. Do it only when the call was successful. */
1253fb98d4aSespie if (new_domain != NULL)
1263fb98d4aSespie {
1273fb98d4aSespie ++_nl_msg_cat_cntr;
128840175f0Skstailey
1293fb98d4aSespie if (old_domain != new_domain && old_domain != _nl_default_default_domain)
1303fb98d4aSespie free (old_domain);
1313fb98d4aSespie }
1323fb98d4aSespie
1333fb98d4aSespie __libc_rwlock_unlock (_nl_state_lock);
1343fb98d4aSespie
1353fb98d4aSespie return new_domain;
136840175f0Skstailey }
137840175f0Skstailey
138840175f0Skstailey #ifdef _LIBC
139840175f0Skstailey /* Alias for function name in GNU C Library. */
140840175f0Skstailey weak_alias (__textdomain, textdomain);
141840175f0Skstailey #endif
142