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