1
0
forked from Alepha/Alepha
Files
Alepha/IOStreams/LineComments.h

171 lines
4.1 KiB
C++

static_assert( __cplusplus > 2023'00 );
#pragma once
#include <Alepha/Alepha.h>
#include <cstdint>
#include <cassert>
#include <vector>
#include <iostream>
#include <string_view>
#include <algorithm>
#include <Alepha/error.h>
#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;
}