demotool/c-buildcfg.cc

203 lines
5.5 KiB
C++

#include "externals.hh"
#include "c-buildcfg.hh"
#include <ebcl/Files.hh>
#include <ebcl/SRDDefinitions.hh>
#include <ebcl/SRDParserConfig.hh>
#include <ebcl/SRDParser.hh>
#include <ebcl/SRDText.hh>
using namespace ebcl;
namespace {
/*= SRD PARSER FOR BUILD CONFIGURATIONS ======================================*/
using SP_Table_ = T_SharedPtr< T_BuildConfigurations >;
bool BCLStartConfig_( T_SRDParserData const& data )
{
*( data.targetData ) = T_BuildConfiguration{ };
return true;
}
bool BCLEndConfig_( T_SRDParserData const& data )
{
auto const& in{ *data.input };
auto& table{ *( data.targetData->value< SP_Table_ >( ) ) };
auto& bCfg{ data.currentData->value< T_BuildConfiguration >( ) };
if ( !table.add( in[ 1 ].stringValue( ) , std::move( bCfg ) ) ) {
data.errors.add( "duplicate configuration" , in[ 1 ] );
}
return true;
}
/*----------------------------------------------------------------------------*/
bool BCLResolutions_( T_SRDParserData const& data )
{
auto const& in{ *data.input };
auto& bCfg{ data.currentData->value< T_BuildConfiguration >( ) };
const uint32_t nin{ in.size( ) };
if ( nin == 2 && in[ 1 ].type( ) == E_SRDTokenType::WORD ) {
bCfg.resolutionChooser = true;
bCfg.resolutions.clear( );
return true;
}
for ( auto i = 1u ; i < nin ; i ++ ) {
auto const& l{ in[ i ].list( ) };
const auto w{ l[ 0 ].longValue( ) };
const auto h{ l[ 1 ].longValue( ) };
bool fail{ false };
if ( w <= 0 || w >= 16384 ) {
fail = true;
data.errors.add( "invalid width" , l[ 0 ] );
}
if ( h <= 0 || h >= 16384 ) {
fail = true;
data.errors.add( "invalid height" , l[ 1 ] );
}
if ( fail ) {
continue;
}
const auto res{ std::make_pair< uint32_t , uint32_t >( w , h ) };
if ( bCfg.resolutions.contains( res ) ) {
data.errors.add( InPlace( ) ,
"duplicate resolution" ,
in[ i ].location( ) ,
E_SRDErrorType::WARNING );
} else {
bCfg.resolutions.add( res );
}
}
return true;
}
/*----------------------------------------------------------------------------*/
T_SRDParserConfig BCLInitDefinitions_( ) noexcept
{
using namespace ebcl::SRD;
T_SRDParserDefs defs{ "default" };
defs.enumeration( "on-off" ) << "off" << "on";
defs << OnStart( []( T_SRDParserData const& data ) -> bool {
*( data.currentData ) = NewShared< T_BuildConfigurations >( );
return true;
} );
defs.context( "default" )
<< ( Rule( ) << "cfg" << Text( ) << EnterContext( "config" )
<< OnEnter( BCLStartConfig_ )
<< OnExit( BCLEndConfig_ ) )
;
defs.context( "config" )
<< ( Rule( ) << "resolutions"
<< ( Alt( ) << "chooser"
<< ( AtLeast( 1 ) << ( List( ) << Int32( ) << Int32( ) ) ) )
<< BCLResolutions_ )
<< ( Rule( ) << "optimizer" << "off"
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.optimize = false;
return true;
} )
<< ( Rule( ) << "optimizer" << "on" << EnterContext( "optim" )
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.optimize = true;
return true;
} )
;
defs.context( "optim" )
<< ( Rule( ) << "constant-folding" << "off"
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.constantFolding = false;
return true;
} )
<< ( Rule( ) << "constant-folding" << "on" << EnterContext( "opt-cf" )
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.constantFolding = true;
return true;
} )
<< ( Rule( ) << "dead-code-elimination" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.deadCodeElimination = true;
return true;
} )
;
defs.context( "opt-cf" )
<< ( Rule( ) << "fixed-resolution" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto const& in{ *d.input };
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.cfFixedSize = ( in[ 1 ].stringValue( ) == "on" );
return true;
} )
<< ( Rule( ) << "inputs" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto const& in{ *d.input };
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.cfInputs = ( in[ 1 ].stringValue( ) == "on" );
return true;
} )
;
return T_SRDParserConfig{ defs };
}
/*= BUILD CONFIGURATIONS LOADER ==============================================*/
struct T_BCLImpl_
{
T_SRDParserConfig pConfig;
T_BCLImpl_( ) noexcept;
T_BuildConfigurations load( T_String const& path );
};
/*----------------------------------------------------------------------------*/
T_BCLImpl_::T_BCLImpl_( ) noexcept
: pConfig{ BCLInitDefinitions_( ) }
{ }
T_BuildConfigurations T_BCLImpl_::load(
T_String const& path )
{
// TODO: keep errors so we get warnings/notes too
T_SRDParser parser{ pConfig };
T_SRDTextReader srdReader{ parser };
T_File input{ path , E_FileMode::READ_ONLY };
T_FileInputStream fis{ input };
srdReader.read( path , fis );
return std::move( *parser.getData< T_SharedPtr< T_BuildConfigurations > >( ) );
}
} // namespace <anon>
/*----------------------------------------------------------------------------*/
T_BuildConfigurationLoader::T_BuildConfigurationLoader( ) noexcept
: A_PrivateImplementation( new T_BCLImpl_( ) )
{ }
T_BuildConfigurations T_BuildConfigurationLoader::load(
T_String const& path )
{
return p< T_BCLImpl_ >( ).load( path );
}