Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // std::ctype implementation details, generic version -*- C++ -*-
  2.  
  3. // Copyright (C) 2001-2015 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. //
  26. // ISO C++ 14882: 22.2.1.1.2  ctype virtual functions.
  27. //
  28.  
  29. // Written by Benjamin Kosnik <bkoz@redhat.com>
  30.  
  31. #include <locale>
  32. #include <cstdlib>
  33. #include <cstring>
  34. #include <cstdio>
  35.  
  36. namespace std _GLIBCXX_VISIBILITY(default)
  37. {
  38. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  39.  
  40.   // NB: The other ctype<char> specializations are in src/locale.cc and
  41.   // various /config/os/* files.
  42.   ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
  43.   : ctype<char>(0, false, __refs)
  44.   {    
  45.     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
  46.       {
  47.         this->_S_destroy_c_locale(this->_M_c_locale_ctype);
  48.         this->_S_create_c_locale(this->_M_c_locale_ctype, __s);
  49.       }
  50.   }
  51.  
  52.   ctype_byname<char>::~ctype_byname()
  53.   { }
  54.  
  55. #ifdef _GLIBCXX_USE_WCHAR_T  
  56.   ctype<wchar_t>::__wmask_type
  57.   ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw()
  58.   {
  59.     __wmask_type __ret;
  60.     switch (__m)
  61.       {
  62.       case space:
  63.         __ret = wctype("space");
  64.         break;
  65.       case print:
  66.         __ret = wctype("print");
  67.         break;
  68.       case cntrl:
  69.         __ret = wctype("cntrl");
  70.         break;
  71.       case upper:
  72.         __ret = wctype("upper");
  73.         break;
  74.       case lower:
  75.         __ret = wctype("lower");
  76.         break;
  77.       case alpha:
  78.         __ret = wctype("alpha");
  79.         break;
  80.       case digit:
  81.         __ret = wctype("digit");
  82.         break;
  83.       case punct:
  84.         __ret = wctype("punct");
  85.         break;
  86.       case xdigit:
  87.         __ret = wctype("xdigit");
  88.         break;
  89.       case alnum:
  90.         __ret = wctype("alnum");
  91.         break;
  92.       case graph:
  93.         __ret = wctype("graph");
  94.         break;
  95.       default:
  96.         // For some targets ctype_base::blank == ctype_base::space so check
  97.         // here to avoid a duplicate case error.
  98.         if (__m == blank)
  99.           __ret = wctype("blank");
  100.         else
  101.           __ret = __wmask_type();
  102.       }
  103.     return __ret;
  104.   };
  105.  
  106.   wchar_t
  107.   ctype<wchar_t>::do_toupper(wchar_t __c) const
  108.   { return towupper(__c); }
  109.  
  110.   const wchar_t*
  111.   ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
  112.   {
  113.     while (__lo < __hi)
  114.       {
  115.         *__lo = towupper(*__lo);
  116.         ++__lo;
  117.       }
  118.     return __hi;
  119.   }
  120.  
  121.   wchar_t
  122.   ctype<wchar_t>::do_tolower(wchar_t __c) const
  123.   { return towlower(__c); }
  124.  
  125.   const wchar_t*
  126.   ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
  127.   {
  128.     while (__lo < __hi)
  129.       {
  130.         *__lo = towlower(*__lo);
  131.         ++__lo;
  132.       }
  133.     return __hi;
  134.   }
  135.  
  136.   bool
  137.   ctype<wchar_t>::
  138.   do_is(mask __m, char_type __c) const
  139.   {
  140.     bool __ret = false;
  141.     // Generically, 15 (instead of 11) since we don't know the numerical
  142.     // encoding of the various categories in /usr/include/ctype.h.
  143.     const size_t __bitmasksize = 15;
  144.     for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
  145.       if (__m & _M_bit[__bitcur]
  146.           && iswctype(__c, _M_wmask[__bitcur]))
  147.         {
  148.           __ret = true;
  149.           break;
  150.         }
  151.     return __ret;    
  152.   }
  153.  
  154.   const wchar_t*
  155.   ctype<wchar_t>::
  156.   do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
  157.   {
  158.     for (;__lo < __hi; ++__vec, ++__lo)
  159.       {
  160.         // Generically, 15 (instead of 11) since we don't know the numerical
  161.         // encoding of the various categories in /usr/include/ctype.h.
  162.         const size_t __bitmasksize = 15;
  163.         mask __m = 0;
  164.         for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
  165.           if (iswctype(*__lo, _M_wmask[__bitcur]))
  166.             __m |= _M_bit[__bitcur];
  167.         *__vec = __m;
  168.       }
  169.     return __hi;
  170.   }
  171.  
  172.   const wchar_t*
  173.   ctype<wchar_t>::
  174.   do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
  175.   {
  176.     while (__lo < __hi && !this->do_is(__m, *__lo))
  177.       ++__lo;
  178.     return __lo;
  179.   }
  180.  
  181.   const wchar_t*
  182.   ctype<wchar_t>::
  183.   do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
  184.   {
  185.     while (__lo < __hi && this->do_is(__m, *__lo) != 0)
  186.       ++__lo;
  187.     return __lo;
  188.   }
  189.  
  190.   wchar_t
  191.   ctype<wchar_t>::
  192.   do_widen(char __c) const
  193.   { return _M_widen[static_cast<unsigned char>(__c)]; }
  194.  
  195.   const char*
  196.   ctype<wchar_t>::
  197.   do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
  198.   {
  199.     while (__lo < __hi)
  200.       {
  201.         *__dest = _M_widen[static_cast<unsigned char>(*__lo)];
  202.         ++__lo;
  203.         ++__dest;
  204.       }
  205.     return __hi;
  206.   }
  207.  
  208.   char
  209.   ctype<wchar_t>::
  210.   do_narrow(wchar_t __wc, char __dfault) const
  211.   {
  212.     if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
  213.       return _M_narrow[__wc];
  214.     const int __c = wctob(__wc);
  215.     return (__c == EOF ? __dfault : static_cast<char>(__c));
  216.   }
  217.  
  218.   const wchar_t*
  219.   ctype<wchar_t>::
  220.   do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
  221.             char* __dest) const
  222.   {
  223.     if (_M_narrow_ok)
  224.       while (__lo < __hi)
  225.         {
  226.           if (*__lo >= 0 && *__lo < 128)
  227.             *__dest = _M_narrow[*__lo];
  228.           else
  229.             {
  230.               const int __c = wctob(*__lo);
  231.               *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
  232.             }
  233.           ++__lo;
  234.           ++__dest;
  235.         }
  236.     else
  237.       while (__lo < __hi)
  238.         {
  239.           const int __c = wctob(*__lo);
  240.           *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
  241.           ++__lo;
  242.           ++__dest;
  243.         }
  244.     return __hi;
  245.   }
  246.  
  247.   void
  248.   ctype<wchar_t>::_M_initialize_ctype() throw()
  249.   {
  250.     wint_t __i;
  251.     for (__i = 0; __i < 128; ++__i)
  252.       {
  253.         const int __c = wctob(__i);
  254.         if (__c == EOF)
  255.           break;
  256.         else
  257.           _M_narrow[__i] = static_cast<char>(__c);
  258.       }
  259.     if (__i == 128)
  260.       _M_narrow_ok = true;
  261.     else
  262.       _M_narrow_ok = false;
  263.     for (size_t __i = 0;
  264.          __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
  265.       _M_widen[__i] = btowc(__i);
  266.  
  267.     for (size_t __i = 0; __i <= 15; ++__i)
  268.       {
  269.         _M_bit[__i] = static_cast<mask>(1 << __i);
  270.         _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
  271.       }  
  272.   }
  273. #endif //  _GLIBCXX_USE_WCHAR_T
  274.  
  275. _GLIBCXX_END_NAMESPACE_VERSION
  276. } // namespace
  277.