]> Creatis software - cpPlugins.git/blob - appli/bash/HostCreator.cxx
Moved to version 1.0
[cpPlugins.git] / appli / bash / HostCreator.cxx
1 // =========================================================================
2 // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
3 // =========================================================================
4
5 #include <fstream>
6 #include <iostream>
7 #include <set>
8 #include <sstream>
9 #include <streambuf>
10 #include <string>
11 #include <vector>
12
13 #include <boost/algorithm/string/replace.hpp>
14 #include <boost/filesystem/operations.hpp>
15 #include <boost/program_options.hpp>
16 #include <boost/tokenizer.hpp>
17
18 // -------------------------------------------------------------------------
19 typedef boost::filesystem::path TPath;
20 typedef std::vector< std::string > TStrings;
21 struct TData
22 {
23   TPath    Input;
24   TPath    Output;
25   TStrings Lines;
26 };
27 TData Data;
28
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 );
33 int Parse( );
34
35 // -------------------------------------------------------------------------
36 int main( int argc, char* argv[] )
37 {
38   if( Arguments( argc, argv ) )
39   {
40     if( Lines( Data.Input.string( ), Data.Lines ) )
41       return( Parse( ) );
42     else
43       return( 1 );
44   }
45   else
46     return( 1 );
47 }
48
49 // -------------------------------------------------------------------------
50 bool Arguments( int argc, char* argv[] )
51 {
52   // Declare the supported options.
53   boost::program_options::options_description desc( "Allowed options" );
54   desc.add_options( )
55     ( "help,h", "produce help message" )
56     (
57       "input,i",
58       boost::program_options::value< std::string >( ),
59       "Input"
60       )
61     (
62       "output,o",
63       boost::program_options::value< std::string >( ),
64       "Output"
65       )
66     ;
67
68   try
69   {
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
74       );
75     boost::program_options::notify( vm );
76     if( vm.count( "help" ) )
77     {
78       std::cerr << desc << std::endl;
79       return( false );
80
81     } // fi
82     if( vm.count( "input" ) == 0 || vm.count( "output" ) == 0 )
83     {
84       std::cerr
85         << "Invalid usage: --input and --output are required."
86         << std::endl << desc << std::endl;
87       return( false );
88
89     } // fi
90
91     // Get values
92     Data.Input =
93       boost::filesystem::canonical(
94         TPath( vm[ "input" ].as< std::string >( ) )
95         );
96     Data.Output = TPath( vm[ "output" ].as< std::string >( ) );
97     return( true );
98   }
99   catch( std::exception& err )
100   {
101     std::cerr
102       << "===============================" << std::endl
103       << "Error caught: " << err.what( ) << std::endl
104       << "===============================" << std::endl
105       << std::endl;
106     std::cerr << desc << std::endl;
107     return( false );
108
109   } // yrt
110 }
111
112 // -------------------------------------------------------------------------
113 bool Read( const std::string& input, std::string& buffer )
114 {
115   std::ifstream in( input.c_str( ) );
116   if( !in )
117   {
118     std::cerr
119       << "===============================" << std::endl
120       << "Error caught: " << std::endl
121       << "could not load input file \"" << input << "\"" << std::endl
122       << "===============================" << std::endl
123       << std::endl;
124     return( false );
125
126   } // fi
127   typedef std::istreambuf_iterator< char > _TDIt;
128   std::istringstream str( std::string( ( _TDIt( in ) ), _TDIt( ) ) );
129   buffer = str.str( );
130   in.close( );
131   return( true );
132 }
133
134 // -------------------------------------------------------------------------
135 bool Lines( const std::string& input, TStrings& lines )
136 {
137   std::string buffer;
138   if( Read( input, buffer ) )
139   {
140     lines.clear( );
141     std::istringstream str( buffer );
142     std::string line;
143     while( std::getline( str, line ) )
144       lines.push_back( line );
145     return( true );
146   }
147   else
148     return( false );
149 }
150
151 // -------------------------------------------------------------------------
152 int Parse( )
153 {
154   typedef boost::char_separator< char > _TSep;
155   typedef boost::tokenizer< _TSep > _TTok;
156   
157   std::set< std::string > classes;
158   std::set< std::string > includes;
159   for( const std::string& line: Data.Lines )
160   {
161     _TSep sep( " \t" );
162     _TTok tokens( line, sep );
163     _TTok::const_iterator tIt = tokens.begin( );
164     std::size_t s = std::distance( tIt, tokens.end( ) );
165     if( s > 0 )
166     {
167       std::string class_name = *tIt;
168       if( class_name[ 0 ] == '@' )
169       {
170         classes.insert( class_name.substr( 1 ) );
171         if( s == 1 )
172         {
173           boost::algorithm::replace_all( class_name, "::", "/" );
174           class_name[ 0 ] = '<';
175           class_name += std::string( ".h>" );
176           includes.insert( class_name );
177         }
178         else if( s > 1 )
179           for( tIt++; tIt != tokens.end( ); ++tIt )
180             includes.insert( *tIt );
181       } // end if
182     } // end if
183   } // end for
184
185   // Create buffer
186   std::stringstream oBuff;
187   oBuff
188     << "// Automatically generated, please do not edit."
189     << std::endl << std::endl;
190   oBuff
191     << "#include <memory>" << std::endl
192     << "#include <string>" << std::endl;
193   for( const std::string& s: includes )
194     oBuff << "#include " << s << std::endl;
195   oBuff
196     << std::endl
197     << "extern \"C\" void* cpPlugins_Create( const char* name )"
198     << std::endl
199     << "{" << std::endl
200     << "  static std::shared_ptr< cpPlugins::ProcessObject > ptr;"
201     << std::endl << "  "
202     << "  std::string sName = name;" << std::endl << "  ";
203   for( const std::string& s: classes )
204   {
205     oBuff
206       << "if( sName == \"" << s << "\" )" << std::endl
207       << "  {" << std::endl
208       << "    " << s << "::SharedPtr p = " << s << "::New( );"
209       << std::endl
210       << "    ptr = p->CastSharedPtr< cpPlugins::ProcessObject >( );"
211       << std::endl
212       << "  }" << std::endl
213       << "  else ";
214
215   } // rof
216   oBuff
217     << std::endl << "  {" << std::endl
218     << "    return( NULL );"
219     << std::endl << "  }" << std::endl;
220
221   oBuff
222     << "  return( reinterpret_cast< void* >( &ptr ) );" << std::endl
223     << "}" << std::endl;
224
225   oBuff << std::endl << "// eof" << std::endl;
226
227   // Save file
228   std::ofstream out( Data.Output.string( ).c_str( ) );
229   if( out )
230   {
231     out << oBuff.str( );
232     out.close( );
233   }
234   else
235   {
236     std::cerr
237       << "===============================" << std::endl
238       << "Error caught: " << std::endl
239       << "could not write output file \"" << Data.Output.string( )
240       << "\"" << std::endl
241       << "===============================" << std::endl
242       << std::endl;
243     return( 1 );
244
245   } // fi
246   return( 0 );
247 }
248
249 // eof - $RCSfile$