X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=inline;f=appli%2Fbash%2FBuildInstances.cxx.in;fp=appli%2Fbash%2FBuildInstances.cxx.in;h=79cbcf26873f3d34f31eb7408726c16f140063db;hb=3393941bf8f26babc7b592db434b40c1b747a687;hp=0000000000000000000000000000000000000000;hpb=bb04d28d6b6a805d4443dfea6145a396aefb5f6d;p=cpPlugins.git diff --git a/appli/bash/BuildInstances.cxx.in b/appli/bash/BuildInstances.cxx.in new file mode 100644 index 0000000..79cbcf2 --- /dev/null +++ b/appli/bash/BuildInstances.cxx.in @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------- +typedef std::map< char, std::vector< std::string > > TCommands; +typedef std::map< std::string, std::vector< std::string > > TDefinitions; + +// ------------------------------------------------------------------------- +void AddDefinitions( TDefinitions& defs, const std::string& cmd ); +void InitDefinitions( TDefinitions& defs ); +void Lines( TCommands& commands, const std::deque< std::string >& lines ); +void ExpandDefinitions( TDefinitions& defs ); +std::vector< std::string > Expand( + const std::vector< std::string >& commands, const TDefinitions& defs + ); + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + // Get parameters from input + if( argc < 5 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " definitions library_name source_prefix number_of_files" << std::endl; + return( 1 ); + + } // fi + std::string input_definitions = argv[ 1 ]; + std::string library_name = argv[ 2 ]; + std::string source_prefix = argv[ 3 ]; + std::string header_file = source_prefix + std::string( ".h" ); + std::stringstream nfiles_str( argv[ 4 ] ); + unsigned int number_of_files; + nfiles_str >> number_of_files; + + // Read input instances + std::string buffer; + if( !cpPlugins_bash::Read( buffer, input_definitions ) ) + { + std::cerr + << "Error reading input instances from \"" + << input_definitions << "\"" + << std::endl; + return( 1 ); + + } // fi + + // Put it in a line-by-line structure + std::deque< std::string > lines; + cpPlugins_bash::Tokenize( lines, buffer, "\n" ); + + // Parse commands + TCommands commands; + Lines( commands, lines ); + + // Init definitions + TDefinitions defs; + InitDefinitions( defs ); + auto dIt = commands.find( 'd' ); + if( dIt != commands.end( ) ) + { + for( auto vIt = dIt->second.begin( ); vIt != dIt->second.end( ); ++vIt ) + AddDefinitions( defs, *vIt ); + + } // fi + + // Expand definitions + ExpandDefinitions( defs ); + + // Expand code + std::vector< std::string > before; + auto bIt = commands.find( 'b' ); + if( bIt != commands.end( ) ) + before = bIt->second; + auto templates = Expand( commands[ 't' ], defs ); + auto includes = Expand( commands[ 'i' ], defs ); + auto classes = Expand( commands[ 'c' ], defs ); + + // Write header file + std::stringstream header; + header + << "#ifndef __" << library_name << "__h__" << std::endl + << "#define __" << library_name << "__h__" << std::endl << std::endl + << "#define ITK_MANUAL_INSTANTIATION" << std::endl; + for( auto i = before.begin( ); i != before.end( ); ++i ) + header << std::endl << *i; + header << std::endl; + for( auto i = includes.begin( ); i != includes.end( ); ++i ) + header << "#include <" << *i << ">" << std::endl; + for( auto i = templates.begin( ); i != templates.end( ); ++i ) + header << "#include <" << *i << ".h>" << std::endl; + header << std::endl; + for( auto i = classes.begin( ); i != classes.end( ); ++i ) + header + << "extern template class " << *i << ";" << std::endl; + header + << std::endl << "#endif // __" << library_name << "__H__" << std::endl; + if( !( cpPlugins_bash::Write( header.str( ), header_file ) ) ) + { + std::cerr << "Error writing header" << std::endl; + return( 1 ); + + } // fi + + // Write source code + unsigned int classes_per_file = + ( unsigned int )( + std::floor( double( classes.size( ) ) / double( number_of_files ) ) + ); + if( classes_per_file == 0 ) + classes_per_file = 1; + std::vector< std::vector< std::string > > all_lines( 1 ); + for( unsigned int c_id = 0; c_id < classes.size( ); ++c_id ) + { + all_lines[ all_lines.size( ) - 1 ].push_back( classes[ c_id ] ); + if( c_id % classes_per_file == classes_per_file - 1 ) + all_lines.push_back( std::vector< std::string >( ) ); + + } // rof + + // Paranoiac code + while( all_lines.size( ) > number_of_files ) + { + all_lines[ all_lines.size( ) - 2 ].insert( + all_lines[ all_lines.size( ) - 2 ].end( ), + all_lines[ all_lines.size( ) - 1 ].begin( ), + all_lines[ all_lines.size( ) - 1 ].end( ) + ); + all_lines.pop_back( ); + + } // elihw + while( all_lines.size( ) < number_of_files ) + all_lines.push_back( std::vector< std::string >( ) ); + + // Real write + for( unsigned int f_id = 0; f_id < all_lines.size( ); ++f_id ) + { + std::stringstream source; + source << "#define ITK_MANUAL_INSTANTIATION" << std::endl; + source + << "#include <" << library_name << "_Export.h>" + << std::endl; + for( auto i = before.begin( ); i != before.end( ); ++i ) + source << std::endl << *i; + source << std::endl; + if( templates.size( ) > 0 ) + { + for( auto i = includes.begin( ); i != includes.end( ); ++i ) + source << "#include <" << *i << ">" << std::endl; + + for( auto i = templates.begin( ); i != templates.end( ); ++i ) + { + source << "#include <" << *i << ".h>" << std::endl; + source << "#include <" << *i << ".hxx>" << std::endl; + + } // rof + source << std::endl; + + } // fi + for( + auto c_it = all_lines[ f_id ].begin( ); + c_it != all_lines[ f_id ].end( ); + ++c_it + ) + source + << "template class " << library_name << "_EXPORT " + << *c_it << ";" << std::endl; + source << std::endl << "// eof" << std::endl; + std::stringstream source_file; + source_file + << source_prefix << "_" << f_id << ".cxx"; + if( !( cpPlugins_bash::Write( source.str( ), source_file.str( ) ) ) ) + { + std::cerr << "Error writing header" << std::endl; + return( 1 ); + + } // fi + + } // rof + return( 0 ); +} + +// ------------------------------------------------------------------------- +void AddDefinitions( TDefinitions& defs, const std::string& cmd ) +{ + std::vector< std::string > tokens; + cpPlugins_bash::Tokenize( tokens, cmd, "=;" ); + for( unsigned int i = 1; i < tokens.size( ); ++i ) + defs[ tokens[ 0 ] ].push_back( tokens[ i ] ); +} + +// ------------------------------------------------------------------------- +void InitDefinitions( TDefinitions& defs ) +{ + AddDefinitions( defs, "integers=@cpPlugins_INTEGER_TYPES@" ); + AddDefinitions( defs, "reals=@cpPlugins_REAL_TYPES@" ); + AddDefinitions( defs, "colors=RGBPixel;RGBAPixel" ); + AddDefinitions( defs, "vectors=CovariantVector;Point;SymmetricSecondRankTensor;Vector" ); + AddDefinitions( defs, "tensors=DiffusionTensor3D" ); + AddDefinitions( defs, "matrices=Matrix" ); + AddDefinitions( defs, "process_dims=@cpPlugins_PROCESS_DIMENSIONS@" ); + AddDefinitions( defs, "visual_dims=@cpPlugins_VISUAL_DIMENSIONS@" ); + AddDefinitions( defs, "naturals=unsigned #integers#" ); + AddDefinitions( defs, "pixels=#integers#;#naturals#;#reals#" ); +} + +// ------------------------------------------------------------------------- +void Lines( TCommands& commands, const std::deque< std::string >& lines ) +{ + std::string buffer; + + for( auto l = lines.begin( ); l != lines.end( ); ++l ) + { + auto pos = l->find_first_not_of( " " ); + char cmd = std::tolower( ( *l )[ pos ] ); + commands[ cmd ].push_back( + l->substr( l->find_first_not_of( " ", pos + 1 ) ) + ); + + } // elihw +} + +// ------------------------------------------------------------------------- +void ExpandDefinitions( TDefinitions& defs ) +{ + for( auto d = defs.begin( ); d != defs.end( ); ++d ) + { + std::deque< std::string > q; + q.insert( q.end( ), d->second.begin( ), d->second.end( ) ); + + std::vector< std::string > n; + while( q.size( ) > 0 ) + { + auto v = q.front( ); + q.pop_front( ); + + auto pos = v.find( "#" ); + if( pos != std::string::npos ) + { + auto epos = v.find( "#", pos + 1 ); + auto tok = v.substr( pos, epos - pos + 1 ); + auto id = tok.substr( 1, tok.size( ) - 2 ); + auto rd = defs.find( id ); + if( rd != defs.end( ) ) + for( auto r = rd->second.begin( ); r != rd->second.end( ); ++r ) + q.push_back( cpPlugins_bash::Replace( v, tok, *r ) ); + } + else + n.push_back( v ); + + } // elihw + d->second = n; + + } // rof +} + +// ------------------------------------------------------------------------- +std::vector< std::string > Expand( + const std::vector< std::string >& commands, const TDefinitions& defs + ) +{ + std::vector< std::string > lines; + std::deque< std::string > q; + q.insert( q.end( ), commands.begin( ), commands.end( ) ); + while( q.size( ) > 0 ) + { + auto v = q.front( ); + q.pop_front( ); + + auto d_pos = v.find( "$" ); + auto n_pos = v.find( "#" ); + + if( d_pos != std::string::npos ) + { + auto e_pos = v.find( "$", d_pos + 1 ); + auto tok = v.substr( d_pos, e_pos - d_pos + 1 ); + std::vector< std::string > tokens; + cpPlugins_bash::Tokenize( tokens, tok, "$;" ); + for( auto t = tokens.begin( ); t != tokens.end( ); ++t ) + { + if( *t == " ") + q.push_front( cpPlugins_bash::Replace( v, tok, "" ) ); + else + q.push_front( cpPlugins_bash::Replace( v, tok, *t ) ); + + } // rof + } + else if( n_pos != std::string::npos ) + { + auto e_pos = v.find( "#", n_pos + 1 ); + auto tok = v.substr( n_pos, e_pos - n_pos + 1 ); + auto id = tok.substr( 1, tok.size( ) - 2 ); + auto rd = defs.find( id ); + if( rd != defs.end( ) ) + for( auto r = rd->second.begin( ); r != rd->second.end( ); ++r ) + q.push_front( cpPlugins_bash::Replace( v, tok, *r ) ); + } + else + lines.push_back( v ); + + } // elihw + + return( lines ); +} + +// eof - $RCSfile$