forked from Alepha/Alepha
Fix some bugs in iostream exception handling for expansions.
This commit is contained in:
@ -6,6 +6,8 @@ static_assert( __cplusplus > 2020'99 );
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
#include <Alepha/IOStreams/EnableExceptions.h>
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "AutoRAII.h"
|
#include "AutoRAII.h"
|
||||||
|
|
||||||
@ -39,22 +41,31 @@ namespace Alepha::Hydrogen ::detail:: string_algorithms_m
|
|||||||
void
|
void
|
||||||
writeChar( const char ch ) override
|
writeChar( const char ch ) override
|
||||||
{
|
{
|
||||||
|
if( C::debugExpansion ) error() << "Entry to write and got `" << ch << '`' << std::endl;
|
||||||
std::ostream current{ underlying };
|
std::ostream current{ underlying };
|
||||||
|
|
||||||
if( mode == Normal and ch == sigil )
|
if( mode == Normal and ch == sigil )
|
||||||
{
|
{
|
||||||
|
if( C::debugExpansion ) error() << "Normal and got `" << ch << '`' << std::endl;
|
||||||
mode= Symbol;
|
mode= Symbol;
|
||||||
varName.str( "" );
|
varName.str( "" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( mode == Symbol and ch == sigil )
|
if( mode == Symbol and ch == sigil )
|
||||||
{
|
{
|
||||||
|
if( C::debugExpansion ) error() << "Closed symbol and got `" << ch << '`' << std::endl;
|
||||||
mode= Normal;
|
mode= Normal;
|
||||||
const std::string name( varName.view() );
|
const std::string name( varName.view() );
|
||||||
|
if( C::debugExpansion )
|
||||||
|
{
|
||||||
|
error() << "Asked to expand `" << name << '`' << std::endl;
|
||||||
|
}
|
||||||
if( not name.empty() )
|
if( not name.empty() )
|
||||||
{
|
{
|
||||||
|
if( C::debugExpansion ) error() << "Name wasn't empty" << std::endl;
|
||||||
if( not substitutions.contains( name ) )
|
if( not substitutions.contains( name ) )
|
||||||
{
|
{
|
||||||
|
if( C::debugExpansion ) error() << "Throwing" << std::endl;
|
||||||
throw std::runtime_error{ "No such variable: `" + name +"`" };
|
throw std::runtime_error{ "No such variable: `" + name +"`" };
|
||||||
}
|
}
|
||||||
if( C::debugExpansion ) error() << "Expanding variable with name `" << name << "`" << std::endl;
|
if( C::debugExpansion ) error() << "Expanding variable with name `" << name << "`" << std::endl;
|
||||||
@ -64,6 +75,7 @@ namespace Alepha::Hydrogen ::detail:: string_algorithms_m
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( C::debugExpansion ) error() << "Stashing `" << ch << '`' << std::endl;
|
||||||
if( mode == Symbol ) current.rdbuf( &varName );
|
if( mode == Symbol ) current.rdbuf( &varName );
|
||||||
current << ch;
|
current << ch;
|
||||||
}
|
}
|
||||||
@ -76,7 +88,7 @@ namespace Alepha::Hydrogen ::detail:: string_algorithms_m
|
|||||||
{
|
{
|
||||||
if( C::debugIOStreamLifecycle ) error() << "Mode not being normal, we're throwing (" << ++throws << " times now)..." << std::endl;
|
if( C::debugIOStreamLifecycle ) error() << "Mode not being normal, we're throwing (" << ++throws << " times now)..." << std::endl;
|
||||||
mode= Normal;
|
mode= Normal;
|
||||||
throw std::runtime_error{ "Unterminated variable `" + varName.str() + " in expansion." };
|
throw std::runtime_error{ "Unterminated variable `" + varName.str() + "` in expansion." };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -92,6 +104,7 @@ namespace Alepha::Hydrogen ::detail:: string_algorithms_m
|
|||||||
exports::expandVariables( const std::string &text, const VarMap &vars, const char sigil )
|
exports::expandVariables( const std::string &text, const VarMap &vars, const char sigil )
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
IOStreams::EnableExceptions exc{ oss };
|
||||||
|
|
||||||
oss << StartSubstitutions{ sigil, vars };
|
oss << StartSubstitutions{ sigil, vars };
|
||||||
oss << text;
|
oss << text;
|
||||||
|
@ -38,7 +38,7 @@ static auto init= enroll <=[]
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
"An exception should be thrown when there is a trailing unenclosed variable."_test <=TableTest< Alepha::expandVariables >::ExceptionCases
|
"An exception should be thrown when there is a trailing unenclosed variable."_test <=TableTest< Alepha::expandVariables >::Cases
|
||||||
{
|
{
|
||||||
{ "Complete var",
|
{ "Complete var",
|
||||||
{ "$H$ $W$", { { "H", lambaste<="Hello" }, { "W", lambaste<="World" } }, '$' },
|
{ "$H$ $W$", { { "H", lambaste<="Hello" }, { "W", lambaste<="World" } }, '$' },
|
||||||
@ -46,11 +46,15 @@ static auto init= enroll <=[]
|
|||||||
},
|
},
|
||||||
{ "Complete var",
|
{ "Complete var",
|
||||||
{ "$H$ $W$", { { "H", lambaste<="Hello" }, { "W", lambaste<="World" } }, '$' },
|
{ "$H$ $W$", { { "H", lambaste<="Hello" }, { "W", lambaste<="World" } }, '$' },
|
||||||
std::type_identity< void >{}
|
"Hello World"
|
||||||
},
|
},
|
||||||
{ "Incomplete var",
|
{ "Incomplete var",
|
||||||
{ "$H$ $W", { { "H", lambaste<="Hello" }, { "W", lambaste<="World" } }, '$' },
|
{ "$H$ $W", { { "H", lambaste<="Hello" }, { "W", lambaste<="World" } }, '$' },
|
||||||
std::type_identity< std::exception >{}
|
std::runtime_error{ "Unterminated variable `W` in expansion." }
|
||||||
|
},
|
||||||
|
{ "Missing var",
|
||||||
|
{ "$H$ $W$", { { "W", lambaste<="World" } }, '$' },
|
||||||
|
std::runtime_error{ "No such variable: `H`" }
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user