From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTP id 648FE3851C35; Wed, 5 May 2021 01:05:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 648FE3851C35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oliva@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 31B3F1172CC; Tue, 4 May 2021 21:05:12 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id gu0zoO8kdGRG; Tue, 4 May 2021 21:05:12 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 7B388117277; Tue, 4 May 2021 21:05:11 -0400 (EDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 145150IM137503 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 4 May 2021 22:05:01 -0300 From: Alexandre Oliva To: Jonathan Wakely Cc: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org, Olivier Hainque , Corentin Gay Subject: Re: ctype support for libstdc++ on VxWorks Organization: Free thinker, does not speak for AdaCore References: <20210504100235.GI3008@redhat.com> Errors-To: aoliva@lxoliva.fsfla.org Date: Tue, 04 May 2021 22:05:00 -0300 In-Reply-To: <20210504100235.GI3008@redhat.com> (Jonathan Wakely's message of "Tue, 4 May 2021 11:02:35 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 May 2021 01:05:15 -0000 On May 4, 2021, Jonathan Wakely wrote: > s/explicitely/explicitly/ Thanks. I also adjusted the attribution in that file. Here's what I'm checking in. ctype support for libstdc++ on VxWorks From: Corentin Gay for libstdc++-v3/ChangeLog * acinclude.m4: Add VxWorks-specific case for the configuration of ctypes. * configure: Regenerate. * config/locale/vxworks/ctype_members.cc: Add VxWorks-specific version. * config/os/vxworks/ctype_base.h: Adjust for VxWorks7+. * config/os/vxworks/ctype_configure_char.cc: Likewise. * config/os/vxworks/ctype_inline.h: Likewise. * testsuite/28_regex/traits/char/isctype.cc: Defines NEWLINE_IN_CLASS_BLANK if the target is VxWorks. * testsuite/28_regex/traits/wchar_t/isctype.cc: Likewise. --- libstdc++-v3/acinclude.m4 | 18 + .../config/locale/vxworks/ctype_members.cc | 292 ++++++++++++++++++++ libstdc++-v3/config/os/vxworks/ctype_base.h | 27 ++ .../config/os/vxworks/ctype_configure_char.cc | 10 + libstdc++-v3/config/os/vxworks/ctype_inline.h | 39 +++ libstdc++-v3/configure | 19 + .../testsuite/28_regex/traits/char/isctype.cc | 1 .../testsuite/28_regex/traits/wchar_t/isctype.cc | 1 8 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/config/locale/vxworks/ctype_members.cc diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 94897a654c950..90ecc4a87a253 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -2391,6 +2391,9 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [ darwin*) enable_clocale_flag=darwin ;; + vxworks*) + enable_clocale_flag=vxworks + ;; dragonfly* | freebsd*) enable_clocale_flag=dragonfly ;; @@ -2485,7 +2488,22 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [ CTIME_CC=config/locale/generic/time_members.cc CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h ;; + vxworks) + AC_MSG_RESULT(vxworks) + CLOCALE_H=config/locale/generic/c_locale.h + CLOCALE_CC=config/locale/generic/c_locale.cc + CCODECVT_CC=config/locale/generic/codecvt_members.cc + CCOLLATE_CC=config/locale/generic/collate_members.cc + CCTYPE_CC=config/locale/vxworks/ctype_members.cc + CMESSAGES_H=config/locale/generic/messages_members.h + CMESSAGES_CC=config/locale/generic/messages_members.cc + CMONEY_CC=config/locale/generic/monetary_members.cc + CNUMERIC_CC=config/locale/generic/numeric_members.cc + CTIME_H=config/locale/generic/time_members.h + CTIME_CC=config/locale/generic/time_members.cc + CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h + ;; dragonfly) AC_MSG_RESULT(dragonfly or freebsd) diff --git a/libstdc++-v3/config/locale/vxworks/ctype_members.cc b/libstdc++-v3/config/locale/vxworks/ctype_members.cc new file mode 100644 index 0000000000000..f9dd64c73ff78 --- /dev/null +++ b/libstdc++-v3/config/locale/vxworks/ctype_members.cc @@ -0,0 +1,292 @@ +// std::ctype implementation details, vxworks specific version -*- C++ -*- + +// Copyright (C) 2001-2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 22.2.1.1.2 ctype virtual functions. +// + +// Originally written by Benjamin Kosnik . +// Ported to vxworks by Corentin Gay . + +#include +#include +#include +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // NB: The other ctype specializations are in src/locale.cc and + // various /config/os/* files. + ctype_byname::ctype_byname(const char* __s, size_t __refs) + : ctype(0, false, __refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_ctype); + this->_S_create_c_locale(this->_M_c_locale_ctype, __s); + } + } + + ctype_byname::~ctype_byname() + { } + +#ifdef _GLIBCXX_USE_WCHAR_T + ctype::__wmask_type + ctype::_M_convert_to_wmask(const mask __m) const throw() + { + __wmask_type __ret; + + switch (__m) + { + case space: + __ret = wctype("space"); + break; + case print: + __ret = wctype("print"); + break; + case cntrl: + __ret = wctype("cntrl"); + break; + case upper: + __ret = wctype("upper"); + break; + case lower: + __ret = wctype("lower"); + break; + case alpha: + __ret = wctype("alpha"); + break; + case digit: + __ret = wctype("digit"); + break; + case punct: + __ret = wctype("punct"); + break; + case xdigit: + __ret = wctype("xdigit"); + break; + case alnum: + __ret = wctype("alnum"); + break; + case graph: + __ret = wctype("graph"); + break; + default: + __ret = __wmask_type(); + break; + } + return __ret; + }; + + wchar_t + ctype::do_toupper(wchar_t __c) const + { return towupper(__c); } + + const wchar_t* + ctype::do_toupper(wchar_t* __lo, const wchar_t* __hi) const + { + while (__lo < __hi) + { + *__lo = towupper(*__lo); + ++__lo; + } + return __hi; + } + + wchar_t + ctype::do_tolower(wchar_t __c) const + { return towlower(__c); } + + const wchar_t* + ctype::do_tolower(wchar_t* __lo, const wchar_t* __hi) const + { + while (__lo < __hi) + { + *__lo = towlower(*__lo); + ++__lo; + } + return __hi; + } + + bool + ctype:: + do_is(mask __m, char_type __c) const + { + bool __ret = false; + // In VxWorks, a ctype is a short int, thus if we go up to the 15th index, + // we will overflow. + const size_t __bitmasksize = 14; + + // VxWorks does not consider spaces to be blank, however, the testsuite + // and more generally the libstdc++ rely on it, we explicitly handle + // that case here. + if ((__m & blank) && isspace(__c)) + { + __ret = true; + } + else + { + for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) { + if (__m & _M_bit[__bitcur] + && iswctype(__c, _M_wmask[__bitcur])) + { + __ret = true; + break; + } + } + } + return __ret; + } + + const wchar_t* + ctype:: + do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const + { + for (;__lo < __hi; ++__vec, ++__lo) + { + const size_t __bitmasksize = 14; + // In VxWorks, a ctype is a short int, thus if we go up to the 15th index, + // we will overflow. + mask __m = 0; + // VxWorks does not consider space as blank, so let's add an explicit + // check. + if (isspace(*__lo)) + __m |= blank; + for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) + if (iswctype(*__lo, _M_wmask[__bitcur])) + __m |= _M_bit[__bitcur]; + *__vec = __m; + } + return __hi; + } + + const wchar_t* + ctype:: + do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const + { + while (__lo < __hi && !this->do_is(__m, *__lo)) + ++__lo; + return __lo; + } + + const wchar_t* + ctype:: + do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const + { + while (__lo < __hi && this->do_is(__m, *__lo) != 0) + ++__lo; + return __lo; + } + + wchar_t + ctype:: + do_widen(char __c) const + { return _M_widen[static_cast(__c)]; } + + const char* + ctype:: + do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const + { + while (__lo < __hi) + { + *__dest = _M_widen[static_cast(*__lo)]; + ++__lo; + ++__dest; + } + return __hi; + } + + char + ctype:: + do_narrow(wchar_t __wc, char __dfault) const + { + if (__wc >= 0 && __wc < 128 && _M_narrow_ok) + return _M_narrow[__wc]; + const int __c = wctob(__wc); + return (__c == EOF ? __dfault : static_cast(__c)); + } + + const wchar_t* + ctype:: + do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, + char* __dest) const + { + if (_M_narrow_ok) + while (__lo < __hi) + { + if (*__lo >= 0 && *__lo < 128) + *__dest = _M_narrow[*__lo]; + else + { + const int __c = wctob(*__lo); + *__dest = (__c == EOF ? __dfault : static_cast(__c)); + } + ++__lo; + ++__dest; + } + else + while (__lo < __hi) + { + const int __c = wctob(*__lo); + *__dest = (__c == EOF ? __dfault : static_cast(__c)); + ++__lo; + ++__dest; + } + return __hi; + } + + void + ctype::_M_initialize_ctype() throw() + { + wint_t __i; + for (__i = 0; __i < 128; ++__i) + { + const int __c = wctob(__i); + if (__c == EOF) + break; + else + _M_narrow[__i] = static_cast(__c); + } + if (__i == 128) + _M_narrow_ok = true; + else + _M_narrow_ok = false; + for (size_t __i = 0; + __i < sizeof(_M_widen) / sizeof(wint_t); ++__i) + _M_widen[__i] = btowc(__i); + + // In VxWorks, a ctype is a short int, thus if we go up to the 15th index, + // we will overflow. + for (size_t __i = 0; __i <= 14; ++__i) + { + _M_bit[__i] = static_cast(1 << __i); + _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]); + } + } +#endif // _GLIBCXX_USE_WCHAR_T +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/config/os/vxworks/ctype_base.h b/libstdc++-v3/config/os/vxworks/ctype_base.h index be60d791e27bf..951cb80d456ef 100644 --- a/libstdc++-v3/config/os/vxworks/ctype_base.h +++ b/libstdc++-v3/config/os/vxworks/ctype_base.h @@ -28,6 +28,8 @@ // Information extracted from target/h/ctype.h. +#include <_vxworks-versions.h> + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -35,6 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @brief Base class for ctype. struct ctype_base { +#if _VXWORKS_MAJOR_LT(7) && !defined(__RTP__) // Non-standard typedefs. typedef const unsigned char* __to_type; @@ -50,11 +53,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static const mask print = (_C_UPPER | _C_LOWER | _C_NUMBER | _C_WHITE_SPACE | _C_PUNCT); static const mask graph = _C_UPPER | _C_LOWER | _C_NUMBER | _C_PUNCT; - static const mask cntrl = _C_CONTROL; + static const mask cntrl = _C_CONTROL | _C_B; static const mask punct = _C_PUNCT; static const mask alnum = _C_UPPER | _C_LOWER | _C_NUMBER; #if __cplusplus >= 201103L static const mask blank = _C_WHITE_SPACE; +#endif +#else + // Non-standard typedefs. + typedef const short* __to_type; + + // NB: Offsets into ctype::_M_table force a particular size + // on the mask type. Because of this, we don't use an enum. + typedef short mask; + static const mask upper = _UP; + static const mask lower = _LO; + static const mask alpha = _UP|_LO|_XA; + static const mask digit = _DI; + static const mask xdigit = _XD; + static const mask space = _CN|_SP|_XS; + static const mask print = _DI|_LO|_PU|_SP|_UP|_XA; + static const mask graph = _DI|_LO|_PU|_UP|_XA; + static const mask cntrl = _BB; + static const mask punct = _PU; + static const mask alnum = _DI|_LO|_UP|_XA; +#if __cplusplus >= 201103L + static const mask blank = _SP|_XB; +#endif #endif }; diff --git a/libstdc++-v3/config/os/vxworks/ctype_configure_char.cc b/libstdc++-v3/config/os/vxworks/ctype_configure_char.cc index cd2eca1ae5157..34f12dbb1f78b 100644 --- a/libstdc++-v3/config/os/vxworks/ctype_configure_char.cc +++ b/libstdc++-v3/config/os/vxworks/ctype_configure_char.cc @@ -28,6 +28,8 @@ // ISO C++ 14882: 22.1 Locales // +#include <_vxworks-versions.h> + #include #include #include @@ -38,9 +40,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Information as gleaned from target/h/ctype.h +#if _VXWORKS_MAJOR_LT(7) && !defined(__RTP__) const ctype_base::mask* ctype::classic_table() throw() { return __ctype; } +#else + const ctype_base::mask* + ctype::classic_table() throw() + { return _Getpctype(); } +# define __toupper _CToupper +# define __tolower _CTolower +#endif ctype::ctype(__c_locale, const mask* __table, bool __del, size_t __refs) diff --git a/libstdc++-v3/config/os/vxworks/ctype_inline.h b/libstdc++-v3/config/os/vxworks/ctype_inline.h index cf8b389efddaf..885886fa92b75 100644 --- a/libstdc++-v3/config/os/vxworks/ctype_inline.h +++ b/libstdc++-v3/config/os/vxworks/ctype_inline.h @@ -36,10 +36,13 @@ // ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) // functions go in ctype.cc +#include <_vxworks-versions.h> + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _VXWORKS_MAJOR_LT(7) && !defined(__RTP__) bool ctype:: is(mask __m, char __c) const @@ -74,5 +77,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __low; } +#else + bool + ctype:: + is(mask __m, char __c) const + { return _Getpctype()[static_cast(__c)] & __m; } + + const char* + ctype:: + is(const char* __low, const char* __high, mask* __vec) const + { + while (__low < __high) + *__vec++ = _Getpctype()[static_cast(*__low++)]; + return __high; + } + + const char* + ctype:: + scan_is(mask __m, const char* __low, const char* __high) const + { + while (__low < __high + && !(_Getpctype()[static_cast(*__low)] & __m)) + ++__low; + return __low; + } + + const char* + ctype:: + scan_not(mask __m, const char* __low, const char* __high) const + { + while (__low < __high + && (_Getpctype()[static_cast(*__low)] & __m)) + ++__low; + return __low; + } +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 067b5d1ae8ebf..6f08b65c8ba76 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -16403,6 +16403,9 @@ fi darwin*) enable_clocale_flag=darwin ;; + vxworks*) + enable_clocale_flag=vxworks + ;; dragonfly* | freebsd*) enable_clocale_flag=dragonfly ;; @@ -16550,7 +16553,23 @@ $as_echo "darwin" >&6; } CTIME_CC=config/locale/generic/time_members.cc CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h ;; + vxworks) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: vxworks" >&5 +$as_echo "vxworks" >&6; } + CLOCALE_H=config/locale/generic/c_locale.h + CLOCALE_CC=config/locale/generic/c_locale.cc + CCODECVT_CC=config/locale/generic/codecvt_members.cc + CCOLLATE_CC=config/locale/generic/collate_members.cc + CCTYPE_CC=config/locale/vxworks/ctype_members.cc + CMESSAGES_H=config/locale/generic/messages_members.h + CMESSAGES_CC=config/locale/generic/messages_members.cc + CMONEY_CC=config/locale/generic/monetary_members.cc + CNUMERIC_CC=config/locale/generic/numeric_members.cc + CTIME_H=config/locale/generic/time_members.h + CTIME_CC=config/locale/generic/time_members.cc + CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h + ;; dragonfly) { $as_echo "$as_me:${as_lineno-$LINENO}: result: dragonfly or freebsd" >&5 $as_echo "dragonfly or freebsd" >&6; } diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc b/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc index a4dd73cf6eb4e..5dc5074c3da0b 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc @@ -1,6 +1,7 @@ // { dg-do run { target c++11 } } // { dg-timeout-factor 2 } // { dg-additional-options "-DNEWLINE_IN_CLASS_BLANK" { target newlib } } +// { dg-additional-options "-DNEWLINE_IN_CLASS_BLANK" { target *-vxworks*-* } } // // 2010-06-23 Stephen M. Webb diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc index d153c58483ae2..e3de5ea9ee911 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc @@ -1,6 +1,7 @@ // { dg-do run { target c++11 } } // { dg-timeout-factor 2 } // { dg-additional-options "-DNEWLINE_IN_CLASS_BLANK" { target newlib } } +// { dg-additional-options "-DNEWLINE_IN_CLASS_BLANK" { target *-vxworks*-* } } // Copyright (C) 2010-2021 Free Software Foundation, Inc. // -- Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer Disinformation flourishes because many people care deeply about injustice but very few check the facts. Ask me about