static_assert( __cplusplus > 2023'00 ); #pragma once #include #include #include #include #include #include #include #include #include "StackableStreambuf.h" #include "StreamState.h" namespace Alepha::Hydrogen::IOStreams ::detail:: LineComments_m { namespace C { const bool debug= false; const bool debugUnderflow= false or C::debug; } inline namespace exports {} struct LineComments_params {}; namespace exports { struct LineCommentsStreambuf; using DropComments= IOStreams::PushStack< LineComments_params >; } struct exports::LineCommentsStreambuf : public virtual StackableStreambuf, public virtual std::streambuf { private: enum { Active, Commented } state= Active; public: explicit LineCommentsStreambuf( std::ios &is ) : StackableStreambuf( is ) {} void writeChar( char ch ) override { throw "Unimpl"; } void drain() override { throw "Unimpl"; } int underflow() override { std::string_view view{ gptr(), egptr() }; while( view.empty() ) { if( gptr() == nullptr or gptr() >= underlying_egptr() ) { if( C::debugUnderflow ) { Alepha::error() << "Current view of buffer is empty." << std::endl; } const auto rv= forwardUnderflow(); if( C::debugUnderflow ) { Alepha::error() << "Underlying underflow returned `" << rv << "`" << std::endl; } if( rv == EOF ) { Alepha::error() << "Returning EOF from initial-kind read." << std::endl; setg( nullptr, nullptr, nullptr ); return rv; } view= { underlying_gptr(), underlying_egptr() }; } while( state == Commented ) { if( C::debugUnderflow ) { Alepha::error() << "Current state is `Commented`, underlying view peek is `" << view << "`" << std::endl; } while( not view.empty() ) { if( C::debugUnderflow ) { Alepha::error() << "Examining: `" << view.front() << "`" << std::endl; } if( view.front() == '\n' ) { if( C::debugUnderflow ) { Alepha::error() << "Found end of line." << std::endl; } state= Active; break; } underlying_sbumpc(); view.remove_prefix( 1 ); } if( state == Active ) break; if( C::debugUnderflow ) { Alepha::error() << "Underlying view exhausted, getting more..." << std::endl; } const auto rv= forwardUnderflow(); if( C::debugUnderflow ) { Alepha::error() << "Underlying view underflow returned `" << rv << "`" << std::endl; } if( rv == EOF ) { Alepha::error() << "Returning EOF from mid-comment read." << std::endl; setg( nullptr, nullptr, nullptr ); return rv; } view= { underlying_gptr(), underlying_egptr() }; } assert( state == Active ); assert( not view.empty() ); if( C::debugUnderflow ) { Alepha::error() << "Current state is `Active`, underlying view peek is `" << view << "`" << std::endl; } for( std::size_t i= 0; i < view.size(); ++i ) { if( C::debugUnderflow ) { Alepha::error() << "Looking at `" << view.at( i ) << "`'" << std::endl; } underlying_sbumpc(); if( view.at( i ) == '#' ) { view= view.substr( 0, i ); state= Commented; break; } } if( C::debugUnderflow ) { Alepha::error() << "Current state is `Active`, setting underlying view to `" << view << "`" << std::endl; } setg( (char *) view.data(), (char *) view.data(), (char *) view.data() + view.size() ); } if( C::debugUnderflow ) { Alepha::error() << "Normal return with first char being `" << view.front() << "`" << std::endl; } return view.front(); } }; inline void build_streambuf( std::istream &is, DropComments && ) { new LineCommentsStreambuf{ is }; } } namespace Alepha::Hydrogen::IOStreams::inline exports::inline LineComments_m { using namespace detail::LineComments_m::exports; }