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