// ========================================================================= // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ========================================================================= #include #include #include #include #include #include #include #include #include #include #include // ------------------------------------------------------------------------- typedef boost::filesystem::path TPath; typedef std::vector< std::string > TStrings; struct TData { TPath Input; TPath Output; TStrings Lines; }; TData Data; // ------------------------------------------------------------------------- bool Arguments( int argc, char* argv[] ); bool Read( const std::string& input, std::string& buffer ); bool Lines( const std::string& input, TStrings& lines ); int Parse( ); // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { if( Arguments( argc, argv ) ) { if( Lines( Data.Input.string( ), Data.Lines ) ) return( Parse( ) ); else return( 1 ); } else return( 1 ); } // ------------------------------------------------------------------------- bool Arguments( int argc, char* argv[] ) { // Declare the supported options. boost::program_options::options_description desc( "Allowed options" ); desc.add_options( ) ( "help,h", "produce help message" ) ( "input,i", boost::program_options::value< std::string >( ), "Input" ) ( "output,o", boost::program_options::value< std::string >( ), "Output" ) ; try { // Parse input arguments boost::program_options::variables_map vm; boost::program_options::store( boost::program_options::parse_command_line( argc, argv, desc ), vm ); boost::program_options::notify( vm ); if( vm.count( "help" ) ) { std::cerr << desc << std::endl; return( false ); } // fi if( vm.count( "input" ) == 0 || vm.count( "output" ) == 0 ) { std::cerr << "Invalid usage: --input and --output are required." << std::endl << desc << std::endl; return( false ); } // fi // Get values Data.Input = boost::filesystem::canonical( TPath( vm[ "input" ].as< std::string >( ) ) ); Data.Output = TPath( vm[ "output" ].as< std::string >( ) ); return( true ); } catch( std::exception& err ) { std::cerr << "===============================" << std::endl << "Error caught: " << err.what( ) << std::endl << "===============================" << std::endl << std::endl; std::cerr << desc << std::endl; return( false ); } // yrt } // ------------------------------------------------------------------------- bool Read( const std::string& input, std::string& buffer ) { std::ifstream in( input.c_str( ) ); if( !in ) { std::cerr << "===============================" << std::endl << "Error caught: " << std::endl << "could not load input file \"" << input << "\"" << std::endl << "===============================" << std::endl << std::endl; return( false ); } // fi typedef std::istreambuf_iterator< char > _TDIt; std::istringstream str( std::string( ( _TDIt( in ) ), _TDIt( ) ) ); buffer = str.str( ); in.close( ); return( true ); } // ------------------------------------------------------------------------- bool Lines( const std::string& input, TStrings& lines ) { std::string buffer; if( Read( input, buffer ) ) { lines.clear( ); std::istringstream str( buffer ); std::string line; while( std::getline( str, line ) ) lines.push_back( line ); return( true ); } else return( false ); } // ------------------------------------------------------------------------- int Parse( ) { typedef boost::char_separator< char > _TSep; typedef boost::tokenizer< _TSep > _TTok; std::set< std::string > classes; std::set< std::string > includes; for( const std::string& line: Data.Lines ) { _TSep sep( " \t" ); _TTok tokens( line, sep ); _TTok::const_iterator tIt = tokens.begin( ); std::size_t s = std::distance( tIt, tokens.end( ) ); if( s > 0 ) { std::string class_name = *tIt; if( class_name[ 0 ] == '@' ) { classes.insert( class_name.substr( 1 ) ); if( s == 1 ) { boost::algorithm::replace_all( class_name, "::", "/" ); class_name[ 0 ] = '<'; class_name += std::string( ".h>" ); includes.insert( class_name ); } else if( s > 1 ) for( tIt++; tIt != tokens.end( ); ++tIt ) includes.insert( *tIt ); } // end if } // end if } // end for // Create buffer std::stringstream oBuff; oBuff << "// Automatically generated, please do not edit." << std::endl << std::endl; oBuff << "#include " << std::endl << "#include " << std::endl; for( const std::string& s: includes ) oBuff << "#include " << s << std::endl; oBuff << std::endl << "extern \"C\" void* cpPlugins_Create( const char* name )" << std::endl << "{" << std::endl << " static std::shared_ptr< cpPlugins::ProcessObject > ptr;" << std::endl << " " << " std::string sName = name;" << std::endl << " "; for( const std::string& s: classes ) { oBuff << "if( sName == \"" << s << "\" )" << std::endl << " {" << std::endl << " " << s << "::SharedPtr p = " << s << "::New( );" << std::endl << " ptr = p->CastSharedPtr< cpPlugins::ProcessObject >( );" << std::endl << " }" << std::endl << " else "; } // rof oBuff << std::endl << " {" << std::endl << " return( NULL );" << std::endl << " }" << std::endl; oBuff << " return( reinterpret_cast< void* >( &ptr ) );" << std::endl << "}" << std::endl; oBuff << std::endl << "// eof" << std::endl; // Save file std::ofstream out( Data.Output.string( ).c_str( ) ); if( out ) { out << oBuff.str( ); out.close( ); } else { std::cerr << "===============================" << std::endl << "Error caught: " << std::endl << "could not write output file \"" << Data.Output.string( ) << "\"" << std::endl << "===============================" << std::endl << std::endl; return( 1 ); } // fi return( 0 ); } // eof - $RCSfile$