1  // std::messages implementation details, GNU version -*- C++ -*-
       2  
       3  // Copyright (C) 2001-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /** @file bits/messages_members.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly. @headername{locale}
      28   */
      29  
      30  //
      31  // ISO C++ 14882: 22.2.7.1.2  messages functions
      32  //
      33  
      34  // Written by Benjamin Kosnik <bkoz@redhat.com>
      35  
      36  #include <libintl.h>
      37  
      38  namespace std _GLIBCXX_VISIBILITY(default)
      39  {
      40  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      41  
      42    // Non-virtual member functions.
      43    template<typename _CharT>
      44      messages<_CharT>::messages(size_t __refs)
      45      : facet(__refs), _M_c_locale_messages(_S_get_c_locale()),
      46        _M_name_messages(_S_get_c_name())
      47      { }
      48  
      49    template<typename _CharT>
      50      messages<_CharT>::messages(__c_locale __cloc, const char* __s,
      51  			       size_t __refs)
      52      : facet(__refs), _M_c_locale_messages(0), _M_name_messages(0)
      53      {
      54        if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
      55  	{
      56  	  const size_t __len = __builtin_strlen(__s) + 1;
      57  	  char* __tmp = new char[__len];
      58  	  __builtin_memcpy(__tmp, __s, __len);
      59  	  _M_name_messages = __tmp;
      60  	}
      61        else
      62  	_M_name_messages = _S_get_c_name();
      63  
      64        // Last to avoid leaking memory if new throws.
      65        _M_c_locale_messages = _S_clone_c_locale(__cloc);
      66      }
      67  
      68    template<typename _CharT>
      69      typename messages<_CharT>::catalog
      70      messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
      71  			   const char* __dir) const
      72      {
      73        bindtextdomain(__s.c_str(), __dir);
      74        return this->do_open(__s, __loc);
      75      }
      76  
      77    // Virtual member functions.
      78    template<typename _CharT>
      79      messages<_CharT>::~messages()
      80      {
      81        if (_M_name_messages != _S_get_c_name())
      82  	delete [] _M_name_messages;
      83        _S_destroy_c_locale(_M_c_locale_messages);
      84      }
      85  
      86    template<typename _CharT>
      87      typename messages<_CharT>::catalog
      88      messages<_CharT>::do_open(const basic_string<char>& __s,
      89  			      const locale&) const
      90      {
      91        // No error checking is done, assume the catalog exists and can
      92        // be used.
      93        textdomain(__s.c_str());
      94        return 0;
      95      }
      96  
      97    template<typename _CharT>
      98      void
      99      messages<_CharT>::do_close(catalog) const
     100      { }
     101  
     102    // messages_byname
     103    template<typename _CharT>
     104      messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs)
     105      : messages<_CharT>(__refs)
     106      {
     107        if (this->_M_name_messages != locale::facet::_S_get_c_name())
     108  	{
     109  	  delete [] this->_M_name_messages;
     110  	  if (__builtin_strcmp(__s, locale::facet::_S_get_c_name()) != 0)
     111  	    {
     112  	      const size_t __len = __builtin_strlen(__s) + 1;
     113  	      char* __tmp = new char[__len];
     114  	      __builtin_memcpy(__tmp, __s, __len);
     115  	      this->_M_name_messages = __tmp;
     116  	    }
     117  	  else
     118  	    this->_M_name_messages = locale::facet::_S_get_c_name();
     119  	}
     120  
     121        if (__builtin_strcmp(__s, "C") != 0
     122  	  && __builtin_strcmp(__s, "POSIX") != 0)
     123  	{
     124  	  this->_S_destroy_c_locale(this->_M_c_locale_messages);
     125  	  this->_S_create_c_locale(this->_M_c_locale_messages, __s);
     126  	}
     127      }
     128  
     129     //Specializations.
     130    template<>
     131      typename messages<char>::catalog
     132      messages<char>::do_open(const basic_string<char>&,
     133  			    const locale&) const;
     134  
     135    template<>
     136      void
     137      messages<char>::do_close(catalog) const;
     138  
     139  #ifdef _GLIBCXX_USE_WCHAR_T
     140    template<>
     141      typename messages<wchar_t>::catalog
     142      messages<wchar_t>::do_open(const basic_string<char>&,
     143  			       const locale&) const;
     144  
     145    template<>
     146      void
     147      messages<wchar_t>::do_close(catalog) const;
     148  #endif
     149  
     150  _GLIBCXX_END_NAMESPACE_VERSION
     151  } // namespace