demotool/c-buildcfg.cc

205 lines
5.5 KiB
C++
Raw Normal View History

2017-12-02 18:38:34 +01:00
#include "externals.hh"
2017-12-28 10:27:23 +01:00
#include "common.hh"
#include "c-project.hh"
2017-12-02 18:38:34 +01:00
#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;
}
bCfg.resolutionChooser = false;
2017-12-02 18:38:34 +01:00
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;
}
/*----------------------------------------------------------------------------*/
F_SRDHandler BCLToggle_(
ptrdiff_t const fldOffset ) noexcept
{
return [=]( T_SRDParserData const& d ) -> bool {
auto const& in{ *d.input };
char* bCfg{ (char*) &d.currentData->value< T_BuildConfiguration >( ) };
*(bool*)( bCfg + fldOffset ) = ( in[ 1 ].stringValue( ) == "on" );
return true;
};
}
#define M_BCL_TOGGLE_( N ) \
BCLToggle_( offsetof( T_BuildConfiguration , N ) )
/*----------------------------------------------------------------------------*/
2017-12-02 18:38:34 +01:00
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;
} )
2017-12-02 18:38:34 +01:00
;
defs.context( "optim" )
<< ( Rule( ) << "constant-folding" << "off"
<< M_BCL_TOGGLE_( constantFolding ) )
2017-12-02 18:38:34 +01:00
<< ( Rule( ) << "constant-folding" << "on" << EnterContext( "opt-cf" )
<< M_BCL_TOGGLE_( constantFolding ) )
<< ( Rule( ) << "constant-propagation" << Enum( "on-off" )
<< M_BCL_TOGGLE_( constantPropagation ) )
2017-12-02 18:38:34 +01:00
<< ( Rule( ) << "dead-code-elimination" << Enum( "on-off" )
<< M_BCL_TOGGLE_( deadCodeElimination ) )
<< ( Rule( ) << "function-inlining" << Enum( "on-off" )
<< M_BCL_TOGGLE_( inlineFunctions ) )
2017-12-02 18:38:34 +01:00
;
defs.context( "opt-cf" )
<< ( Rule( ) << "fixed-resolution" << Enum( "on-off" )
<< M_BCL_TOGGLE_( cfFixedSize ) )
2017-12-02 18:38:34 +01:00
<< ( Rule( ) << "inputs" << Enum( "on-off" )
<< M_BCL_TOGGLE_( cfInputs ) )
2017-12-02 18:38:34 +01:00
;
return T_SRDParserConfig{ defs };
}
/*= BUILD CONFIGURATIONS LOADER ==============================================*/
struct T_BCLImpl_
{
2017-12-28 10:27:23 +01:00
const T_String fileName{ T_String::Pooled( "build.srd" ) };
2017-12-02 18:38:34 +01:00
T_SRDParserConfig pConfig;
T_BCLImpl_( ) noexcept;
2017-12-28 10:27:23 +01:00
T_BuildConfigurations load( );
2017-12-02 18:38:34 +01:00
};
/*----------------------------------------------------------------------------*/
T_BCLImpl_::T_BCLImpl_( ) noexcept
: pConfig{ BCLInitDefinitions_( ) }
{ }
2017-12-28 10:27:23 +01:00
T_BuildConfigurations T_BCLImpl_::load( )
2017-12-02 18:38:34 +01:00
{
// TODO: keep errors so we get warnings/notes too
T_SRDParser parser{ pConfig };
T_SRDTextReader srdReader{ parser };
2017-12-28 10:27:23 +01:00
T_File input{ Common::Project( ).pathOf( fileName ) ,
E_FileMode::READ_ONLY };
2017-12-02 18:38:34 +01:00
T_FileInputStream fis{ input };
2017-12-28 10:27:23 +01:00
srdReader.read( fileName , fis );
2017-12-02 18:38:34 +01:00
return std::move( *parser.getData< T_SharedPtr< T_BuildConfigurations > >( ) );
}
} // namespace <anon>
/*----------------------------------------------------------------------------*/
T_BuildConfigurationLoader::T_BuildConfigurationLoader( ) noexcept
: A_PrivateImplementation( new T_BCLImpl_( ) )
{ }
2017-12-28 10:27:23 +01:00
T_BuildConfigurations T_BuildConfigurationLoader::load( )
2017-12-02 18:38:34 +01:00
{
2017-12-28 10:27:23 +01:00
return p< T_BCLImpl_ >( ).load( );
2017-12-02 18:38:34 +01:00
}