203 lines
5.5 KiB
C++
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 );
|
|
}
|