#include #include #include #include #include #include // ------------------------------------------------------------------------- typedef std::pair< std::string, std::string > TPair; typedef std::map< std::string, TPair > TInfo; // ------------------------------------------------------------------------- bool is_valid_class( const std::string& str ) { return( str.find( "cpPluginsObject" ) != std::string::npos ); } // ------------------------------------------------------------------------- void process_header( TInfo& info, const std::string& file_name ) { std::string buffer; if( !( cpPlugins_bash::Read( buffer, file_name ) ) ) return; auto prev_pos = std::string::npos; prev_pos = 0; auto pos = buffer.find( "cpPluginsObject" ); while( pos != std::string::npos ) { // Get class names auto op = buffer.find( "(", pos ); auto cl = buffer.find( ")", pos ); std::vector< std::string > tokens; cpPlugins_bash::Tokenize( tokens, buffer.substr( op + 1, cl - op - 2 ), ",\n " ); std::string namespace_name = ""; auto preamble = buffer.substr( prev_pos, pos ); auto napos = preamble.find( "namespace" ); while( napos != std::string::npos ) { auto enapos = preamble.find( "{", napos + 1 ); auto tmp = preamble.substr( napos, enapos - napos + 1 ); std::vector< std::string > tokens2; cpPlugins_bash::Tokenize( tokens2, tmp, " \n\t{" ); namespace_name = tokens2.back( ); napos = preamble.find( "namespace", napos + 1 ); } // elihw auto class_name = tokens[ 0 ]; auto superclass_name = tokens[ 1 ]; auto category_name = tokens[ 2 ]; if( info.find( class_name ) == info.end( ) ) info[ class_name ] = TPair( category_name, namespace_name ); prev_pos = pos; pos = buffer.find( "cpPluginsObject", pos + 1 ); } // elihw } // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { if( argc < 4 ) { std::cerr << "Usage: " << argv[ 0 ] << " plugins_name output_file header_file_0.h header_file_0.h ..." << std::endl; return( 1 ); } // fi std::string plugins_name = argv[ 1 ]; std::string output_filename = argv[ 2 ]; // Parse all header files TInfo info; for( int i = 3; i < argc; ++i ) process_header( info, argv[ i ] ); if( info.size( ) == 0 ) { std::cerr << "ERROR: No valid input headers." << std::endl; return( 1 ); } // fi // Prepare prefixes #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) std::string export_prefix = "__declspec(dllexport)"; #else // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) std::string export_prefix = "__attribute__((visibility(\"default\")))"; #endif // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) // Output data std::stringstream out; // Include section out << "#include " << std::endl << "#include " << std::endl << "#include " << std::endl << "#include " << std::endl << std::endl; for( int i = 3; i < argc; ++i ) out << "#include \"" << argv[ i ] << "\"" < " << plugins_name << "_Data;" << std::endl << std::endl << "// -------------------------------------------------------------------------" << std::endl << "extern \"C\" void __attribute__ ((constructor))" << std::endl << plugins_name << "_Init( )" << std::endl << "{" << std::endl << "}" << std::endl << std::endl << "// -------------------------------------------------------------------------" << std::endl << "extern \"C\" void __attribute__ ((destructor))" << std::endl << plugins_name << "_Finish( )" << std::endl << "{" << std::endl << " // " << plugins_name << "_Data.clear( );" << std::endl << "}" << std::endl << std::endl << "// -------------------------------------------------------------------------" << std::endl << "extern \"C\" " << export_prefix << std::endl << "void " << plugins_name << "_LoadContents( )" << std::endl << "{" << std::endl << " if( " << plugins_name << "_Data.size( ) == 0 )" << std::endl << " {" << std::endl << " std::string sep = \"@\";" << std::endl; // Classes int id = 1; for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt, ++id ) { std::string class_name = iIt->second.second; if( class_name != "" ) class_name += std::string( "::" ); class_name += iIt->first; out << " " << class_name << "::Pointer ptr" << id << " =" << std::endl << " " << class_name << "::New( );" << std::endl << " std::string id" << id << " = ptr" << id << "->GetClassName( )" << " + sep + ptr" << id << "->GetClassCategory( );" << std::endl << " " << plugins_name << "_Data[ id" << id << " ] = ptr" << id << ";" << std::endl; } // rof // Remaining header out << std::endl << " } // fi" << std::endl << "}" << std::endl << std::endl << "// -------------------------------------------------------------------------" << std::endl << "extern \"C\" " << export_prefix << std::endl << "void cpPlugins_Contents( std::vector< std::string >* c )" << std::endl << "{" << std::endl << " " << plugins_name << "_LoadContents( );" << std::endl << " for( auto d : " << plugins_name << "_Data )" << std::endl << " c->push_back( d.first );" << std::endl << "}" << std::endl << std::endl << "// -------------------------------------------------------------------------" << std::endl << "extern \"C\" " << export_prefix << std::endl << "void cpPlugins_Creator( itk::LightObject::Pointer& ptr, const std::string& c, const std::string& f )" << std::endl << "{" << std::endl << " " << plugins_name << "_LoadContents( );" << std::endl << " ptr = NULL;" << std::endl << " std::string id = f + \"@\" + c;" << std::endl << " auto fIt = " << plugins_name << "_Data.find( id );" << std::endl << " if( fIt != " << plugins_name << "_Data.end( ) )" << std::endl << " ptr = fIt->second->CreateAnother( );" << std::endl << "}" << std::endl << std::endl << "// eof - $Automatic generated file$" << std::endl; // Real write if( !( cpPlugins_bash::Write( out.str( ), output_filename ) ) ) { std::cerr << "ERROR: Could not write file." << std::endl; return( 1 ); } // fi return( 0 ); } // eof - $RCSfile$