Demo building - Build configurations

This commit is contained in:
Emmanuel BENOîT 2017-12-02 18:38:34 +01:00
parent 10361fec4f
commit d77943f953
5 changed files with 319 additions and 7 deletions

View file

@ -25,6 +25,7 @@ IMGUI = imgui.cpp imgui_draw.cpp
COMMON = \
common.cc \
c-buildcfg.cc \
c-camera.cc \
c-filewatcher.cc \
c-project.cc \

191
c-buildcfg.cc Normal file
View file

@ -0,0 +1,191 @@
#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" )
<< ( Rule( ) << "optimizer" << "on" << EnterContext( "optim" ) )
;
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& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.cfFixedSize = true;
return true;
} )
<< ( Rule( ) << "inputs" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.cfInputs = true;
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 );
}

59
c-buildcfg.hh Normal file
View file

@ -0,0 +1,59 @@
#pragma once
#ifndef REAL_BUILD
# include "externals.hh"
#endif
/*= BUILD CONFIGURATIONS =====================================================*/
// Build configuration
struct T_BuildConfiguration
{
// Targets -------------------------------------------------------------
// Resolutions
bool resolutionChooser{ true };
T_Array< std::pair< uint32_t , uint32_t > > resolutions;
// Enable optimizer?
bool optimize{ false };
// Constant folding ----------------------------------------------------
// Main toggle
bool constantFolding{ false };
// Optimize $width and $height away if the size is fixed
bool cfFixedSize{ false };
// Get rid of (get-input) for constant or undefined curves
bool cfInputs{ false };
// Dead code elimination -----------------------------------------------
bool deadCodeElimination{ false };
};
// Table of avaiable build configurations
using T_BuildConfigurations = T_KeyValueTable< T_String , T_BuildConfiguration >;
// Build configurations loader
struct T_BuildConfigurationLoader : public ebcl::A_PrivateImplementation
{
T_BuildConfigurationLoader( ) noexcept;
// Load build configurations from the specified path; may throw
// X_StreamError or X_SRDErrors
T_BuildConfigurations load( T_String const& path );
};
/*----------------------------------------------------------------------------*/
// Logger
using F_OPGenLog = std::function< T_StringBuilder( ) >;
using F_OPLogger = std::function< void( F_OPGenLog , uint32_t ) >;
// Runtime configuration (logger, etc.)
struct T_BuildRuntimeConfiguration
{
F_OPLogger logger{ [](auto,auto){} };
};

View file

@ -1,4 +1,5 @@
#pragma once
#include "c-buildcfg.hh"
#include "c-filewatcher.hh"
#include "c-opast.hh"
#include "c-project.hh"
@ -7,9 +8,6 @@
/*= PARSER ===================================================================*/
using F_OPGenLog = std::function< T_StringBuilder( ) >;
using F_OPLogger = std::function< void( F_OPGenLog , uint32_t ) >;
// Parser output. Consists in a root node as well as other details (table of
// constants, data types, etc...)
struct T_OpsParserOutput

View file

@ -44,7 +44,18 @@ void WriteSRDError(
T_StringBuilder& sb ,
T_SRDError const& error )
{
sb << error.location( ) << " - " << error.error( ) << "\n";
switch ( error.type( ) ) {
case E_SRDErrorType::ERROR:
sb << "[ERROR";
break;
case E_SRDErrorType::WARNING:
sb << " [WARN";
break;
case E_SRDErrorType::NOTE:
sb << " [NOTE";
break;
}
sb << '(' << error.location( ) << ")] " << error.error( ) << '\n';
}
@ -57,6 +68,7 @@ int main( int argc , char** argv )
// Parse command line
T_Optional< uint32_t > oLogLevel;
T_String oSrcPath;
T_String oBuildCfg;
int c;
while ( ( c = getopt_long( argc , argv , "L:s:c:" , CmdLineOpts_ , nullptr ) ) != -1 ) {
switch ( c ) {
@ -68,13 +80,17 @@ int main( int argc , char** argv )
case 's':
if ( oSrcPath ) {
fprintf( stderr , "Duplicate source path\n" );
exit( EXIT_FAILURE );
return EXIT_FAILURE;
}
oSrcPath = optarg;
break;
case 'c':
fprintf( stderr , "-c/--config option ignored for now\n" );
if ( oSrcPath ) {
fprintf( stderr , "Duplicate build configuration\n" );
return EXIT_FAILURE;
}
oBuildCfg = optarg;
break;
}
@ -88,9 +104,56 @@ int main( int argc , char** argv )
}
auto sb{ func( ) };
sb << '\0';
printf( "LOG{%d} %s\n" , level , sb.data( ) );
printf( "(%d) %s\n" , level , sb.data( ) );
} };
// Build configurations
const T_String bcfgFile( [&]() {
T_StringBuilder sb;
if ( oSrcPath ) {
sb << oSrcPath;
if ( !oSrcPath.endsWith( "/" ) ) {
sb << '/';
}
}
sb << "build.srd";
return T_String{ std::move( sb ) };
}( ) );
const T_BuildConfiguration cfg{ [&]() {
try {
T_BuildConfigurationLoader bcfgLoader;
T_BuildConfigurations cfs{ bcfgLoader.load( bcfgFile ) };
if ( oBuildCfg && !cfs.contains( oBuildCfg ) ) {
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
fprintf( stderr , "Build configuration not found\n" );
exit( EXIT_FAILURE );
}
if ( oBuildCfg ) {
return *cfs.get( oBuildCfg );
}
if ( cfs.size( ) ) {
return cfs[ 0 ];
}
return T_BuildConfiguration{ };
} catch ( X_StreamError const& e ) {
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
PrintStreamError( "Could not open" , bcfgFile , e );
exit( EXIT_FAILURE );
} catch ( X_SRDErrors const& e ) {
T_StringBuilder sb;
sb << "===== BUILD CONFIGURATIONS\n";
const auto nErrors( e.errors.size( ) );
for ( auto i = 0u ; i < nErrors ; i ++ ) {
WriteSRDError( sb , e.errors[ i ] );
}
sb << '\0';
fprintf( stderr , "%s" , sb.data( ) );
exit( EXIT_FAILURE );
}
} () };
// Open file
const T_String inputName( [&]() {
T_StringBuilder sb;