--- /dev/null
+// =========================================================================
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// =========================================================================
+
+#include <fstream>
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <streambuf>
+#include <string>
+#include <vector>
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/program_options.hpp>
+#include <boost/tokenizer.hpp>
+
+// -------------------------------------------------------------------------
+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 <memory>" << std::endl
+ << "#include <string>" << 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$