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-2013 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.         __ret = __wmask_type();
  97.       }
  98.     return __ret;
  99.   };
  100.  
  101.   wchar_t
  102.   ctype<wchar_t>::do_toupper(wchar_t __c) const
  103.   { return towupper(__c); }
  104.  
  105.   const wchar_t*
  106.   ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
  107.   {
  108.     while (__lo < __hi)
  109.       {
  110.         *__lo = towupper(*__lo);
  111.         ++__lo;
  112.       }
  113.     return __hi;
  114.   }
  115.  
  116.   wchar_t
  117.   ctype<wchar_t>::do_tolower(wchar_t __c) const
  118.   { return towlower(__c); }
  119.  
  120.   const wchar_t*
  121.   ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
  122.   {
  123.     while (__lo < __hi)
  124.       {
  125.         *__lo = towlower(*__lo);
  126.         ++__lo;
  127.       }
  128.     return __hi;
  129.   }
  130.  
  131.   bool
  132.   ctype<wchar_t>::
  133.   do_is(mask __m, char_type __c) const
  134.   {
  135.     bool __ret = false;
  136.     // Generically, 15 (instead of 10) since we don't know the numerical
  137.     // encoding of the various categories in /usr/include/ctype.h.
  138.     const size_t __bitmasksize = 15;
  139.     for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
  140.       if (__m & _M_bit[__bitcur]
  141.           && iswctype(__c, _M_wmask[__bitcur]))
  142.         {
  143.           __ret = true;
  144.           break;
  145.         }
  146.     return __ret;    
  147.   }
  148.  
  149.   const wchar_t*
  150.   ctype<wchar_t>::
  151.   do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
  152.   {
  153.     for (;__lo < __hi; ++__vec, ++__lo)
  154.       {
  155.         // Generically, 15 (instead of 10) since we don't know the numerical
  156.         // encoding of the various categories in /usr/include/ctype.h.
  157.         const size_t __bitmasksize = 15;
  158.         mask __m = 0;
  159.         for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
  160.           if (iswctype(*__lo, _M_wmask[__bitcur]))
  161.             __m |= _M_bit[__bitcur];
  162.         *__vec = __m;
  163.       }
  164.     return __hi;
  165.   }
  166.  
  167.   const wchar_t*
  168.   ctype<wchar_t>::
  169.   do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
  170.   {
  171.     while (__lo < __hi && !this->do_is(__m, *__lo))
  172.       ++__lo;
  173.     return __lo;
  174.   }
  175.  
  176.   const wchar_t*
  177.   ctype<wchar_t>::
  178.   do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
  179.   {
  180.     while (__lo < __hi && this->do_is(__m, *__lo) != 0)
  181.       ++__lo;
  182.     return __lo;
  183.   }
  184.  
  185.   wchar_t
  186.   ctype<wchar_t>::
  187.   do_widen(char __c) const
  188.   { return _M_widen[static_cast<unsigned char>(__c)]; }
  189.  
  190.   const char*
  191.   ctype<wchar_t>::
  192.   do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
  193.   {
  194.     while (__lo < __hi)
  195.       {
  196.         *__dest = _M_widen[static_cast<unsigned char>(*__lo)];
  197.         ++__lo;
  198.         ++__dest;
  199.       }
  200.     return __hi;
  201.   }
  202.  
  203.   char
  204.   ctype<wchar_t>::
  205.   do_narrow(wchar_t __wc, char __dfault) const
  206.   {
  207.     if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
  208.       return _M_narrow[__wc];
  209.     const int __c = wctob(__wc);
  210.     return (__c == EOF ? __dfault : static_cast<char>(__c));
  211.   }
  212.  
  213.   const wchar_t*
  214.   ctype<wchar_t>::
  215.   do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
  216.             char* __dest) const
  217.   {
  218.     if (_M_narrow_ok)
  219.       while (__lo < __hi)
  220.         {
  221.           if (*__lo >= 0 && *__lo < 128)
  222.             *__dest = _M_narrow[*__lo];
  223.           else
  224.             {
  225.               const int __c = wctob(*__lo);
  226.               *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
  227.             }
  228.           ++__lo;
  229.           ++__dest;
  230.         }
  231.     else
  232.       while (__lo < __hi)
  233.         {
  234.           const int __c = wctob(*__lo);
  235.           *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
  236.           ++__lo;
  237.           ++__dest;
  238.         }
  239.     return __hi;
  240.   }
  241.  
  242.   void
  243.   ctype<wchar_t>::_M_initialize_ctype() throw()
  244.   {
  245.     wint_t __i;
  246.     for (__i = 0; __i < 128; ++__i)
  247.       {
  248.         const int __c = wctob(__i);
  249.         if (__c == EOF)
  250.           break;
  251.         else
  252.           _M_narrow[__i] = static_cast<char>(__c);
  253.       }
  254.     if (__i == 128)
  255.       _M_narrow_ok = true;
  256.     else
  257.       _M_narrow_ok = false;
  258.     for (size_t __i = 0;
  259.          __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
  260.       _M_widen[__i] = btowc(__i);
  261.  
  262.     for (size_t __i = 0; __i <= 15; ++__i)
  263.       {
  264.         _M_bit[__i] = static_cast<mask>(1 << __i);
  265.         _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
  266.       }  
  267.   }
  268. #endif //  _GLIBCXX_USE_WCHAR_T
  269.  
  270. _GLIBCXX_END_NAMESPACE_VERSION
  271. } // namespace
  272.