X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=appli%2Fbash%2FcpPlugins_CreateInstances.cxx;h=a286d9311d1737034fe37feb8efe92fecbf926be;hb=a45c494fd214d02909f227909db3d9e04986b130;hp=a09b822e1ef5bb909e8ad2997d800736e6d7f7a8;hpb=e29096b7c37e89da4cda28bde9102cdb9ff159ea;p=cpPlugins.git diff --git a/appli/bash/cpPlugins_CreateInstances.cxx b/appli/bash/cpPlugins_CreateInstances.cxx index a09b822..a286d93 100644 --- a/appli/bash/cpPlugins_CreateInstances.cxx +++ b/appli/bash/cpPlugins_CreateInstances.cxx @@ -1,25 +1,22 @@ -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include #include +#include // ------------------------------------------------------------------------- -typedef std::set< std::string > TSet; -typedef std::map< std::string, TSet > TInstances; -typedef std::vector< std::string > TVector; +typedef std::vector< std::string > TLines; +typedef std::map< char, TLines > TParsedLines; +typedef std::map< std::string, TLines > TVariables; // ------------------------------------------------------------------------- -TVector Tokenize( const std::string& str, const std::string& delims ); -TSet Combine( const TSet& X, const TSet& Y ); -void Replace( - std::string& str, const std::string& sub, const std::string& nsub +bool ReadFile( TParsedLines& lines, const std::string& fname ); +void ExpandGroups( TLines& res, const TLines& lines ); +void ExpandDefinitions( + TLines& res, const TLines& lines, const TVariables& vars + ); +void PrintLines( + const std::string& prefix, const std::string& suffix, + const TLines& lines, std::ostream& out ); // ------------------------------------------------------------------------- @@ -29,305 +26,252 @@ int main( int argc, char* argv[] ) { std::cerr << "Usage: " << argv[ 0 ] - << " input_definitions dir library_name header_filename" + << " input_definitions library_name header_file source_file" << std::endl; return( 1 ); } // fi - std::string input_definitions_file_name = argv[ 1 ]; - std::string dir = argv[ 2 ]; - std::string library_name = argv[ 3 ]; - std::string head_fname = argv[ 4 ]; - - // Load file into a buffer - std::ifstream file_stream( input_definitions_file_name.c_str( ) ); - if( !file_stream ) + std::string input_definitions_fname = argv[ 1 ]; + std::string library_name = argv[ 2 ]; + std::string header_file_fname = argv[ 3 ]; + std::string source_file_fname = argv[ 4 ]; + + // Read file and simple parse it + TParsedLines lines; + if( !ReadFile( lines, input_definitions_fname ) ) { std::cerr << "Error opening file: \"" - << input_definitions_file_name << "\"" + << input_definitions_fname << "\"" << std::endl; return( 1 ); } // fi - std::string buf; - file_stream.seekg( 0, std::ios::end ); - buf.reserve( file_stream.tellg( ) ); - file_stream.seekg( 0, std::ios::beg ); - buf.assign( - ( std::istreambuf_iterator< char >( file_stream ) ), - std::istreambuf_iterator< char >( ) - ); - file_stream.close( ); - std::istringstream input_str( buf ); - - // Process file - std::string line; - TVector incl, first_incl; - TInstances instances; - TVector classes; - while( std::getline( input_str, line ) ) - { - if( line[ 0 ] == 'f' ) - { - first_incl.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) ); - } - else if( line[ 0 ] == 'i' ) - { - incl.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) ); - } - else if( line[ 0 ] == 'c' ) - { - classes.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) ); - } - else if( line[ 0 ] == 'a' ) - { - TVector tokens = Tokenize( line, "=" ); - - // Get argument name - TVector arg_tokens = Tokenize( tokens[ 0 ], " " ); - std::string arg = arg_tokens[ 0 ]; - unsigned int i = 0; - while( arg[ 0 ] != '#' && i < arg_tokens.size( ) ) - arg = arg_tokens[ ++i ]; - - // Get values - TVector values_tokens = Tokenize( tokens[ 1 ], ";" ); - for( auto t = values_tokens.begin( ); t != values_tokens.end( ); ++t ) - { - std::string value = t->substr( t->find_first_not_of( ' ' ) ); - unsigned int value_len = value.size( ); - while( value[ value_len - 1 ] == ' ' && value_len > 0 ) - value_len--; - value = value.substr( 0, value_len ); - if( value == "#integers" ) - { - instances[ arg ].insert( "char" ); - instances[ arg ].insert( "short" ); - instances[ arg ].insert( "int" ); - instances[ arg ].insert( "long" ); - instances[ arg ].insert( "unsigned char" ); - instances[ arg ].insert( "unsigned short" ); - instances[ arg ].insert( "unsigned int" ); - instances[ arg ].insert( "unsigned long" ); - } - else if( value == "#integers_ptr" ) - { - instances[ arg ].insert( "char*" ); - instances[ arg ].insert( "short*" ); - instances[ arg ].insert( "int*" ); - instances[ arg ].insert( "long*" ); - instances[ arg ].insert( "unsigned char*" ); - instances[ arg ].insert( "unsigned short*" ); - instances[ arg ].insert( "unsigned int*" ); - instances[ arg ].insert( "unsigned long*" ); - } - else if( value == "#floats" ) - { - instances[ arg ].insert( "double" ); - instances[ arg ].insert( "float" ); - } - else if( value == "#floats_ptr" ) - { - instances[ arg ].insert( "double*" ); - instances[ arg ].insert( "float*" ); - } - else if( value == "#all_dims" ) - { - instances[ arg ].insert( "1" ); - instances[ arg ].insert( "2" ); - instances[ arg ].insert( "3" ); - instances[ arg ].insert( "4" ); - } - else if( value == "#all_visual_dims" ) - { - instances[ arg ].insert( "2" ); - instances[ arg ].insert( "3" ); - } - else - instances[ arg ].insert( value ); - - } // rof - - } // fi - - } // elihw - - // Span all possible types - TVector all_real_classes; - for( auto clsIt = classes.begin( ); clsIt != classes.end( ); ++clsIt ) + // Expand definitions + TVariables vars; + for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt ) { - // Extract types - std::string name = clsIt->substr( clsIt->find_first_not_of( " " ) ); - std::string tok = name; - auto sharpPos = tok.find_first_of( "#" ); - TInstances li; - while( sharpPos != std::string::npos ) - { - tok = tok.substr( sharpPos ); - auto spacePos = tok.find_first_of( " " ); - auto arg = tok.substr( 0, spacePos ); - auto aIt = instances.find( arg ); - if( aIt != instances.end( ) ) - li[ arg ] = aIt->second; - tok = tok.substr( spacePos ); - sharpPos = tok.find_first_of( "#" ); - - } // eliwh - if( li.size( ) > 0 ) - { - // Combine types - TSet combs; - if( li.size( ) > 1 ) - { - auto iIt = li.begin( ); - auto jIt = iIt; - jIt++; - for( ; jIt != li.end( ); ++iIt, ++jIt ) - { - if( iIt == li.begin( ) ) - combs = Combine( iIt->second, jIt->second ); - else - combs = Combine( combs, jIt->second ); - - } // rof - } - else - combs = li.begin( )->second; - - // Write instantiations - for( auto combIt = combs.begin( ); combIt != combs.end( ); ++combIt ) - { - char* buffer = new char[ combIt->size( ) ]; - std::strcpy( buffer, combIt->c_str( ) ); - char* tok = std::strtok( buffer, "#" ); - std::map< std::string, std::string > real_instance; - for( auto lIt = li.begin( ); lIt != li.end( ); ++lIt ) - { - real_instance[ lIt->first ] = std::string( tok ); - tok = std::strtok( NULL, "#" ); + TLines tokens; + cpPlugins::TokenizeString( tokens, *dIt, "=;" ); + auto tIt = tokens.begin( ); + auto vName = *tIt; + tIt++; + for( ; tIt != tokens.end( ); ++tIt ) + vars[ vName ].push_back( *tIt ); + + TLines res; + ExpandDefinitions( res, vars[ vName ], vars ); + vars[ vName ] = res; - } // rof + } // rof - std::string real_name = name; - auto riIt = real_instance.begin( ); - for( ; riIt != real_instance.end( ); ++riIt ) - Replace( real_name, riIt->first, riIt->second ); - all_real_classes.push_back( real_name ); - delete buffer; + // Expand groups + TLines f_includes_groups, includes_groups, templates_groups, classes_groups; + ExpandGroups( f_includes_groups, lines[ 'f' ] ); + ExpandGroups( includes_groups, lines[ 'i' ] ); + ExpandGroups( templates_groups, lines[ 't' ] ); + ExpandGroups( classes_groups, lines[ 'c' ] ); + + // Expand definitions + TLines f_includes_list, includes_list, templates_list, classes_list; + ExpandDefinitions( f_includes_list, f_includes_groups, vars ); + ExpandDefinitions( includes_list, includes_groups, vars ); + ExpandDefinitions( templates_list, templates_groups, vars ); + ExpandDefinitions( classes_list, classes_groups, vars ); + + // Write header file + std::ofstream header_file( header_file_fname.c_str( ) ); + if( !header_file ) + { + std::cerr + << "Error opening \"" << header_file_fname + << "\" for writing." << std::endl; + return( 1 ); - } // rof - } - else - all_real_classes.push_back( name ); + } // fi - } // rof + // Print header + header_file + << "#ifndef __" << library_name << "__H__" << std::endl + << "#define __" << library_name << "__H__" << std::endl<< std::endl + << "#include " << std::endl + << "#include <" << library_name << "_Export.h>" << std::endl << std::endl; + PrintLines( "", "", lines[ 'b' ], header_file ); + header_file << std::endl; + PrintLines( "#include <", ">", f_includes_list, header_file ); + header_file + << "#ifdef " << library_name << "_EXPORTS" << std::endl + << "# define " << library_name << "_PREFIX template class " + << library_name << "_EXPORT" << std::endl + << "#else // " << library_name << "_EXPORTS" << std::endl + << "# define " << library_name + << "_PREFIX extern template class" << std::endl + << "#endif // " + << library_name << "_EXPORTS" << std::endl << std::endl; + PrintLines( "#include <", ">", includes_list, header_file ); + PrintLines( "#include <", ">", templates_list, header_file ); + header_file + << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl; + PrintLines( "#include <", "xx>", templates_list, header_file ); + header_file + << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl; + PrintLines( + library_name + std::string( "_PREFIX " ), ";", classes_list, header_file + ); + header_file + << std::endl << "#endif // __" << library_name << "__H__" << std::endl; + header_file.close( ); - // Write files - std::ofstream out_str( head_fname.c_str( ) ); - if( !out_str ) + // Write source file + std::ofstream source_file( source_file_fname ); + if( !source_file ) { - std::cerr << "Error opening file \"" << head_fname << "\"" << std::endl; + std::cerr + << "Error opening \"" << header_file_fname << "\" for writing." << std::endl; return( 1 ); } // fi - - out_str << "#ifndef __" << dir << "__" << library_name << "__H__" << std::endl; - out_str << "#define __" << dir << "__" << library_name << "__H__" << std::endl << std::endl; - out_str << "#include <" << dir << "/" << library_name << "_Export.h>" << std::endl; - - // First incl - for( auto inclIt = first_incl.begin( ); inclIt != first_incl.end( ); ++inclIt ) - out_str - << "#include <" << *inclIt << ">" << std::endl; - out_str << std::endl; - - std::string base_name = dir + std::string( "_" ) + library_name; - out_str - << std::endl - << "#ifdef " << base_name << "_EXPORTS" << std::endl - << "# undef ITK_MANUAL_INSTANTIATION" << std::endl - << "# define " << base_name << "_PREFIX template class " << base_name << "_EXPORT" << std::endl - << "#else" << std::endl - << "# define ITK_MANUAL_INSTANTIATION" << std::endl - << "# define " << base_name << "_PREFIX extern template class" << std::endl - << "#endif" << std::endl << std::endl; - - // Incl - for( auto inclIt = incl.begin( ); inclIt != incl.end( ); ++inclIt ) - out_str - << "#include <" << *inclIt << ">" << std::endl; - out_str << std::endl; - - // All classes - for( auto clsIt = all_real_classes.begin( ); clsIt != all_real_classes.end( ); ++clsIt ) - out_str - << base_name << "_PREFIX " << *clsIt << ";" << std::endl; - out_str << std::endl; - - out_str << "#endif // __" << dir << "__" << library_name << "__H__" << std::endl; - out_str << std::endl << "// eof" << std::endl; - - out_str.close( ); + source_file + << "#include \"" << header_file_fname << "\"" << std::endl; + source_file.close( ); return( 0 ); } // ------------------------------------------------------------------------- -TVector Tokenize( const std::string& str, const std::string& delims ) +bool ReadFile( TParsedLines& lines, const std::string& fname ) { - TVector tokens; - if( str.size( ) > 0 ) + std::string buffer; + if( cpPlugins::ReadFileIntoString( buffer, fname ) ) { - char* buffer = new char[ str.size( ) + 1 ]; - std::strcpy( buffer, str.c_str( ) ); - buffer[ str.size( ) ] = '\0'; - char* it = std::strtok( buffer, delims.c_str( ) ); - while( it != NULL ) + std::istringstream input_stream( buffer ); + + // Read line by line + std::string line; + while( std::getline( input_stream, line ) ) { - tokens.push_back( std::string( it ) ); - it = std::strtok( NULL, delims.c_str( ) ); + auto cmd_pos = line.end( ); + auto arg_pos = line.end( ); + auto lIt = line.begin( ); + while( lIt != line.end( ) ) + { + if( !cpPlugins::IsBlank( *lIt ) ) + { + if( cmd_pos == line.end( ) ) + { + cmd_pos = lIt; + ++lIt; + } + else if( arg_pos == line.end( ) ) + { + arg_pos = lIt; + lIt = line.end( ); + + } // fi + } + else + ++lIt; - } // elihw - delete buffer; + } // elihw + char cmd = *cmd_pos; + std::string arg; + arg.resize( line.end( ) - arg_pos ); + std::copy( arg_pos, line.end( ), arg.begin( ) ); + lines[ cmd ].push_back( arg ); - } // fi - return( tokens ); + } // elihw + return( true ); + } + else + return( false ); } // ------------------------------------------------------------------------- -TSet Combine( const TSet& X, const TSet& Y ) +void ExpandGroups( TLines& res, const TLines& lines ) { - TSet Z; - for( auto xIt = X.begin( ); xIt != X.end( ); ++xIt ) + for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt ) { - for( auto yIt = Y.begin( ); yIt != Y.end( ); ++yIt ) + auto b_pos = lIt->find( "@{" ); + if( b_pos != std::string::npos ) { - std::stringstream val; - val << *xIt << "#" << *yIt; - Z.insert( val.str( ) ); + unsigned int braces_count = 1; + auto e_pos = b_pos; + e_pos += 2; + while( braces_count != 0 && e_pos < lIt->size( ) ) + { + auto v = ( *lIt )[ e_pos ]; + braces_count += ( v == '{' )? 1: ( ( v == '}' )? -1: 0 ); + e_pos++; - } // rof + } // elihw + if( braces_count == 0 ) + { + auto replace = lIt->substr( b_pos, e_pos - b_pos ); + auto expansion = replace.substr( 2, replace.size( ) - 3 ); + TLines tokens; + cpPlugins::TokenizeString( tokens, expansion, ";" ); + for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt ) + *tIt = cpPlugins::ReplaceString( *lIt, replace, *tIt ); + ExpandGroups( res, tokens ); + + } // fi + } + else + res.push_back( *lIt ); } // rof - return( Z ); } // ------------------------------------------------------------------------- -void Replace( - std::string& str, const std::string& sub, const std::string& nsub +void ExpandDefinitions( + TLines& res, const TLines& lines, const TVariables& vars ) { - size_t index = 0; - while( true ) + std::string seps = " ,;:{}[]()\"$&<>*."; + + for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt ) { - index = str.find( sub, index ); - if( index == std::string::npos ) break; - str.replace( index, sub.size( ), nsub ); - index += sub.size( ); + auto b_pos = lIt->find( "#" ); + if( b_pos != std::string::npos ) + { + TLines tokens; + cpPlugins::TokenizeString( tokens, lIt->substr( b_pos ), seps ); + std::string cmd = tokens[ 0 ]; + auto vIt = vars.find( cmd ); + if( vIt != vars.end( ) ) + { + if( vIt->second.size( ) > 0 ) + { + TLines new_res; + for( + auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt + ) + new_res.push_back( cpPlugins::ReplaceString( *lIt, cmd, *wIt ) ); + ExpandDefinitions( res, new_res, vars ); + + } // fi - } // elihw + } // fi + } + else + res.push_back( + cpPlugins::ReplaceString( + cpPlugins::ReplaceString( *lIt, "{", "" ), "}", "" + ) + ); + + } // rof +} + +// ------------------------------------------------------------------------- +void PrintLines( + const std::string& prefix, const std::string& suffix, + const TLines& lines, std::ostream& out + ) +{ + for( auto i = lines.begin( ); i != lines.end( ); ++i ) + out << prefix << *i << suffix << std::endl; } // eof - $RCSfile$