1 // =========================================================================
2 // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
3 // =========================================================================
13 #include <boost/algorithm/string/replace.hpp>
14 #include <boost/filesystem/operations.hpp>
15 #include <boost/program_options.hpp>
16 #include <boost/tokenizer.hpp>
18 // -------------------------------------------------------------------------
19 typedef boost::filesystem::path TPath;
20 typedef std::vector< std::string > TStrings;
29 // -------------------------------------------------------------------------
30 bool Arguments( int argc, char* argv[] );
31 bool Read( const std::string& input, std::string& buffer );
32 bool Lines( const std::string& input, TStrings& lines );
35 // -------------------------------------------------------------------------
36 int main( int argc, char* argv[] )
38 if( Arguments( argc, argv ) )
40 if( Lines( Data.Input.string( ), Data.Lines ) )
49 // -------------------------------------------------------------------------
50 bool Arguments( int argc, char* argv[] )
52 // Declare the supported options.
53 boost::program_options::options_description desc( "Allowed options" );
55 ( "help,h", "produce help message" )
58 boost::program_options::value< std::string >( ),
63 boost::program_options::value< std::string >( ),
70 // Parse input arguments
71 boost::program_options::variables_map vm;
72 boost::program_options::store(
73 boost::program_options::parse_command_line( argc, argv, desc ), vm
75 boost::program_options::notify( vm );
76 if( vm.count( "help" ) )
78 std::cerr << desc << std::endl;
82 if( vm.count( "input" ) == 0 || vm.count( "output" ) == 0 )
85 << "Invalid usage: --input and --output are required."
86 << std::endl << desc << std::endl;
93 boost::filesystem::canonical(
94 TPath( vm[ "input" ].as< std::string >( ) )
96 Data.Output = TPath( vm[ "output" ].as< std::string >( ) );
99 catch( std::exception& err )
102 << "===============================" << std::endl
103 << "Error caught: " << err.what( ) << std::endl
104 << "===============================" << std::endl
106 std::cerr << desc << std::endl;
112 // -------------------------------------------------------------------------
113 bool Read( const std::string& input, std::string& buffer )
115 std::ifstream in( input.c_str( ) );
119 << "===============================" << std::endl
120 << "Error caught: " << std::endl
121 << "could not load input file \"" << input << "\"" << std::endl
122 << "===============================" << std::endl
127 typedef std::istreambuf_iterator< char > _TDIt;
128 std::istringstream str( std::string( ( _TDIt( in ) ), _TDIt( ) ) );
134 // -------------------------------------------------------------------------
135 bool Lines( const std::string& input, TStrings& lines )
138 if( Read( input, buffer ) )
141 std::istringstream str( buffer );
143 while( std::getline( str, line ) )
144 lines.push_back( line );
151 // -------------------------------------------------------------------------
154 typedef boost::char_separator< char > _TSep;
155 typedef boost::tokenizer< _TSep > _TTok;
157 std::set< std::string > classes;
158 std::set< std::string > includes;
159 for( const std::string& line: Data.Lines )
162 _TTok tokens( line, sep );
163 _TTok::const_iterator tIt = tokens.begin( );
164 std::size_t s = std::distance( tIt, tokens.end( ) );
167 std::string class_name = *tIt;
168 if( class_name[ 0 ] == '@' )
170 classes.insert( class_name.substr( 1 ) );
173 boost::algorithm::replace_all( class_name, "::", "/" );
174 class_name[ 0 ] = '<';
175 class_name += std::string( ".h>" );
176 includes.insert( class_name );
179 for( tIt++; tIt != tokens.end( ); ++tIt )
180 includes.insert( *tIt );
186 std::stringstream oBuff;
188 << "// Automatically generated, please do not edit."
189 << std::endl << std::endl;
191 << "#include <memory>" << std::endl
192 << "#include <string>" << std::endl;
193 for( const std::string& s: includes )
194 oBuff << "#include " << s << std::endl;
197 << "extern \"C\" void* cpPlugins_Create( const char* name )"
200 << " static std::shared_ptr< cpPlugins::ProcessObject > ptr;"
202 << " std::string sName = name;" << std::endl << " ";
203 for( const std::string& s: classes )
206 << "if( sName == \"" << s << "\" )" << std::endl
208 << " " << s << "::SharedPtr p = " << s << "::New( );"
210 << " ptr = p->CastSharedPtr< cpPlugins::ProcessObject >( );"
217 << std::endl << " {" << std::endl
218 << " return( NULL );"
219 << std::endl << " }" << std::endl;
222 << " return( reinterpret_cast< void* >( &ptr ) );" << std::endl
225 oBuff << std::endl << "// eof" << std::endl;
228 std::ofstream out( Data.Output.string( ).c_str( ) );
237 << "===============================" << std::endl
238 << "Error caught: " << std::endl
239 << "could not write output file \"" << Data.Output.string( )
241 << "===============================" << std::endl