Blame intl/textdomain.c

Packit 6c4009
/* Implementation of the textdomain(3) function.
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
Packit 6c4009
   This program is free software: you can redistribute it and/or modify
Packit 6c4009
   it under the terms of the GNU Lesser General Public License as published by
Packit 6c4009
   the Free Software Foundation; either version 2.1 of the License, or
Packit 6c4009
   (at your option) any later version.
Packit 6c4009
Packit 6c4009
   This program is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 6c4009
   GNU Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public License
Packit 6c4009
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifdef HAVE_CONFIG_H
Packit 6c4009
# include <config.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
Packit 6c4009
#include "gettextP.h"
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# include <libintl.h>
Packit 6c4009
#else
Packit 6c4009
# include "libgnuintl.h"
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Handle multi-threaded applications.  */
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# include <libc-lock.h>
Packit 6c4009
# define gl_rwlock_define __libc_rwlock_define
Packit 6c4009
# define gl_rwlock_wrlock __libc_rwlock_wrlock
Packit 6c4009
# define gl_rwlock_unlock __libc_rwlock_unlock
Packit 6c4009
#else
Packit 6c4009
# include "lock.h"
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* @@ end of prolog @@ */
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Names for the libintl functions are a problem.  They must not clash
Packit 6c4009
   with existing names and they should follow ANSI C.  But this source
Packit 6c4009
   code is also used in GNU C Library where the names have a __
Packit 6c4009
   prefix.  So we have to make a difference here.  */
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# define TEXTDOMAIN __textdomain
Packit 6c4009
# ifndef strdup
Packit 6c4009
#  define strdup(str) __strdup (str)
Packit 6c4009
# endif
Packit 6c4009
#else
Packit 6c4009
# define TEXTDOMAIN libintl_textdomain
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Lock variable to protect the global data in the gettext implementation.  */
Packit 6c4009
gl_rwlock_define (extern, _nl_state_lock attribute_hidden)
Packit 6c4009
Packit 6c4009
/* Set the current default message catalog to DOMAINNAME.
Packit 6c4009
   If DOMAINNAME is null, return the current default.
Packit 6c4009
   If DOMAINNAME is "", reset to the default of "messages".  */
Packit 6c4009
char *
Packit 6c4009
TEXTDOMAIN (const char *domainname)
Packit 6c4009
{
Packit 6c4009
  char *new_domain;
Packit 6c4009
  char *old_domain;
Packit 6c4009
Packit 6c4009
  /* A NULL pointer requests the current setting.  */
Packit 6c4009
  if (domainname == NULL)
Packit 6c4009
    return (char *) _nl_current_default_domain;
Packit 6c4009
Packit 6c4009
  gl_rwlock_wrlock (_nl_state_lock);
Packit 6c4009
Packit 6c4009
  old_domain = (char *) _nl_current_default_domain;
Packit 6c4009
Packit 6c4009
  /* If domain name is the null string set to default domain "messages".  */
Packit 6c4009
  if (domainname[0] == '\0'
Packit 6c4009
      || strcmp (domainname, _nl_default_default_domain) == 0)
Packit 6c4009
    {
Packit 6c4009
      _nl_current_default_domain = _nl_default_default_domain;
Packit 6c4009
      new_domain = (char *) _nl_current_default_domain;
Packit 6c4009
    }
Packit 6c4009
  else if (strcmp (domainname, old_domain) == 0)
Packit 6c4009
    /* This can happen and people will use it to signal that some
Packit 6c4009
       environment variable changed.  */
Packit 6c4009
    new_domain = old_domain;
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      /* If the following malloc fails `_nl_current_default_domain'
Packit 6c4009
	 will be NULL.  This value will be returned and so signals we
Packit 6c4009
	 are out of core.  */
Packit 6c4009
#if defined _LIBC || defined HAVE_STRDUP
Packit 6c4009
      new_domain = strdup (domainname);
Packit 6c4009
#else
Packit 6c4009
      size_t len = strlen (domainname) + 1;
Packit 6c4009
      new_domain = (char *) malloc (len);
Packit 6c4009
      if (new_domain != NULL)
Packit 6c4009
	memcpy (new_domain, domainname, len);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
      if (new_domain != NULL)
Packit 6c4009
	_nl_current_default_domain = new_domain;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* We use this possibility to signal a change of the loaded catalogs
Packit 6c4009
     since this is most likely the case and there is no other easy we
Packit 6c4009
     to do it.  Do it only when the call was successful.  */
Packit 6c4009
  if (new_domain != NULL)
Packit 6c4009
    {
Packit 6c4009
      ++_nl_msg_cat_cntr;
Packit 6c4009
Packit 6c4009
      if (old_domain != new_domain && old_domain != _nl_default_default_domain)
Packit 6c4009
	free (old_domain);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  gl_rwlock_unlock (_nl_state_lock);
Packit 6c4009
Packit 6c4009
  return new_domain;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
/* Alias for function name in GNU C Library.  */
Packit 6c4009
weak_alias (__textdomain, textdomain);
Packit 6c4009
#endif