Demo building - Build configurations
This commit is contained in:
parent
10361fec4f
commit
d77943f953
5 changed files with 319 additions and 7 deletions
1
Makefile
1
Makefile
|
@ -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
191
c-buildcfg.cc
Normal 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
59
c-buildcfg.hh
Normal 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){} };
|
||||
};
|
||||
|
|
@ -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
|
||||
|
|
71
m-builder.cc
71
m-builder.cc
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue