1*2a6b7db3Sskrll /* Implementation of the textdomain(3) function.
2*2a6b7db3Sskrll    Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc.
3*2a6b7db3Sskrll 
4*2a6b7db3Sskrll    This program is free software; you can redistribute it and/or modify it
5*2a6b7db3Sskrll    under the terms of the GNU Library General Public License as published
6*2a6b7db3Sskrll    by the Free Software Foundation; either version 2, or (at your option)
7*2a6b7db3Sskrll    any later version.
8*2a6b7db3Sskrll 
9*2a6b7db3Sskrll    This program is distributed in the hope that it will be useful,
10*2a6b7db3Sskrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
11*2a6b7db3Sskrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*2a6b7db3Sskrll    Library General Public License for more details.
13*2a6b7db3Sskrll 
14*2a6b7db3Sskrll    You should have received a copy of the GNU Library General Public
15*2a6b7db3Sskrll    License along with this program; if not, write to the Free Software
16*2a6b7db3Sskrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
17*2a6b7db3Sskrll    USA.  */
18*2a6b7db3Sskrll 
19*2a6b7db3Sskrll #ifdef HAVE_CONFIG_H
20*2a6b7db3Sskrll # include <config.h>
21*2a6b7db3Sskrll #endif
22*2a6b7db3Sskrll 
23*2a6b7db3Sskrll #include <stdlib.h>
24*2a6b7db3Sskrll #include <string.h>
25*2a6b7db3Sskrll 
26*2a6b7db3Sskrll #ifdef _LIBC
27*2a6b7db3Sskrll # include <libintl.h>
28*2a6b7db3Sskrll #else
29*2a6b7db3Sskrll # include "libgnuintl.h"
30*2a6b7db3Sskrll #endif
31*2a6b7db3Sskrll #include "gettextP.h"
32*2a6b7db3Sskrll 
33*2a6b7db3Sskrll #ifdef _LIBC
34*2a6b7db3Sskrll /* We have to handle multi-threaded applications.  */
35*2a6b7db3Sskrll # include <bits/libc-lock.h>
36*2a6b7db3Sskrll #else
37*2a6b7db3Sskrll /* Provide dummy implementation if this is outside glibc.  */
38*2a6b7db3Sskrll # define __libc_rwlock_define(CLASS, NAME)
39*2a6b7db3Sskrll # define __libc_rwlock_wrlock(NAME)
40*2a6b7db3Sskrll # define __libc_rwlock_unlock(NAME)
41*2a6b7db3Sskrll #endif
42*2a6b7db3Sskrll 
43*2a6b7db3Sskrll /* The internal variables in the standalone libintl.a must have different
44*2a6b7db3Sskrll    names than the internal variables in GNU libc, otherwise programs
45*2a6b7db3Sskrll    using libintl.a cannot be linked statically.  */
46*2a6b7db3Sskrll #if !defined _LIBC
47*2a6b7db3Sskrll # define _nl_default_default_domain libintl_nl_default_default_domain
48*2a6b7db3Sskrll # define _nl_current_default_domain libintl_nl_current_default_domain
49*2a6b7db3Sskrll #endif
50*2a6b7db3Sskrll 
51*2a6b7db3Sskrll /* @@ end of prolog @@ */
52*2a6b7db3Sskrll 
53*2a6b7db3Sskrll /* Name of the default text domain.  */
54*2a6b7db3Sskrll extern const char _nl_default_default_domain[] attribute_hidden;
55*2a6b7db3Sskrll 
56*2a6b7db3Sskrll /* Default text domain in which entries for gettext(3) are to be found.  */
57*2a6b7db3Sskrll extern const char *_nl_current_default_domain attribute_hidden;
58*2a6b7db3Sskrll 
59*2a6b7db3Sskrll 
60*2a6b7db3Sskrll /* Names for the libintl functions are a problem.  They must not clash
61*2a6b7db3Sskrll    with existing names and they should follow ANSI C.  But this source
62*2a6b7db3Sskrll    code is also used in GNU C Library where the names have a __
63*2a6b7db3Sskrll    prefix.  So we have to make a difference here.  */
64*2a6b7db3Sskrll #ifdef _LIBC
65*2a6b7db3Sskrll # define TEXTDOMAIN __textdomain
66*2a6b7db3Sskrll # ifndef strdup
67*2a6b7db3Sskrll #  define strdup(str) __strdup (str)
68*2a6b7db3Sskrll # endif
69*2a6b7db3Sskrll #else
70*2a6b7db3Sskrll # define TEXTDOMAIN libintl_textdomain
71*2a6b7db3Sskrll #endif
72*2a6b7db3Sskrll 
73*2a6b7db3Sskrll /* Lock variable to protect the global data in the gettext implementation.  */
74*2a6b7db3Sskrll __libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
75*2a6b7db3Sskrll 
76*2a6b7db3Sskrll /* Set the current default message catalog to DOMAINNAME.
77*2a6b7db3Sskrll    If DOMAINNAME is null, return the current default.
78*2a6b7db3Sskrll    If DOMAINNAME is "", reset to the default of "messages".  */
79*2a6b7db3Sskrll char *
80*2a6b7db3Sskrll TEXTDOMAIN (domainname)
81*2a6b7db3Sskrll      const char *domainname;
82*2a6b7db3Sskrll {
83*2a6b7db3Sskrll   char *new_domain;
84*2a6b7db3Sskrll   char *old_domain;
85*2a6b7db3Sskrll 
86*2a6b7db3Sskrll   /* A NULL pointer requests the current setting.  */
87*2a6b7db3Sskrll   if (domainname == NULL)
88*2a6b7db3Sskrll     return (char *) _nl_current_default_domain;
89*2a6b7db3Sskrll 
90*2a6b7db3Sskrll   __libc_rwlock_wrlock (_nl_state_lock);
91*2a6b7db3Sskrll 
92*2a6b7db3Sskrll   old_domain = (char *) _nl_current_default_domain;
93*2a6b7db3Sskrll 
94*2a6b7db3Sskrll   /* If domain name is the null string set to default domain "messages".  */
95*2a6b7db3Sskrll   if (domainname[0] == '\0'
96*2a6b7db3Sskrll       || strcmp (domainname, _nl_default_default_domain) == 0)
97*2a6b7db3Sskrll     {
98*2a6b7db3Sskrll       _nl_current_default_domain = _nl_default_default_domain;
99*2a6b7db3Sskrll       new_domain = (char *) _nl_current_default_domain;
100*2a6b7db3Sskrll     }
101*2a6b7db3Sskrll   else if (strcmp (domainname, old_domain) == 0)
102*2a6b7db3Sskrll     /* This can happen and people will use it to signal that some
103*2a6b7db3Sskrll        environment variable changed.  */
104*2a6b7db3Sskrll     new_domain = old_domain;
105*2a6b7db3Sskrll   else
106*2a6b7db3Sskrll     {
107*2a6b7db3Sskrll       /* If the following malloc fails `_nl_current_default_domain'
108*2a6b7db3Sskrll 	 will be NULL.  This value will be returned and so signals we
109*2a6b7db3Sskrll 	 are out of core.  */
110*2a6b7db3Sskrll #if defined _LIBC || defined HAVE_STRDUP
111*2a6b7db3Sskrll       new_domain = strdup (domainname);
112*2a6b7db3Sskrll #else
113*2a6b7db3Sskrll       size_t len = strlen (domainname) + 1;
114*2a6b7db3Sskrll       new_domain = (char *) malloc (len);
115*2a6b7db3Sskrll       if (new_domain != NULL)
116*2a6b7db3Sskrll 	memcpy (new_domain, domainname, len);
117*2a6b7db3Sskrll #endif
118*2a6b7db3Sskrll 
119*2a6b7db3Sskrll       if (new_domain != NULL)
120*2a6b7db3Sskrll 	_nl_current_default_domain = new_domain;
121*2a6b7db3Sskrll     }
122*2a6b7db3Sskrll 
123*2a6b7db3Sskrll   /* We use this possibility to signal a change of the loaded catalogs
124*2a6b7db3Sskrll      since this is most likely the case and there is no other easy we
125*2a6b7db3Sskrll      to do it.  Do it only when the call was successful.  */
126*2a6b7db3Sskrll   if (new_domain != NULL)
127*2a6b7db3Sskrll     {
128*2a6b7db3Sskrll       ++_nl_msg_cat_cntr;
129*2a6b7db3Sskrll 
130*2a6b7db3Sskrll       if (old_domain != new_domain && old_domain != _nl_default_default_domain)
131*2a6b7db3Sskrll 	free (old_domain);
132*2a6b7db3Sskrll     }
133*2a6b7db3Sskrll 
134*2a6b7db3Sskrll   __libc_rwlock_unlock (_nl_state_lock);
135*2a6b7db3Sskrll 
136*2a6b7db3Sskrll   return new_domain;
137*2a6b7db3Sskrll }
138*2a6b7db3Sskrll 
139*2a6b7db3Sskrll #ifdef _LIBC
140*2a6b7db3Sskrll /* Alias for function name in GNU C Library.  */
141*2a6b7db3Sskrll weak_alias (__textdomain, textdomain);
142*2a6b7db3Sskrll #endif
143