]> Creatis software - cpPlugins.git/blob - appli/bash/cpPlugins_HostCreator.cxx
First dump for version 0.1.0
[cpPlugins.git] / appli / bash / cpPlugins_HostCreator.cxx
1 #include <algorithm>
2 #include <iostream>
3 #include <iterator>
4 #include <fstream>
5 #include <map>
6 #include <sstream>
7 #include <streambuf>
8 #include <vector>
9
10 // -------------------------------------------------------------------------
11 typedef std::map< std::string, std::string > TPair;
12 typedef std::map< std::string, TPair >        TInfo;
13
14 // -------------------------------------------------------------------------
15 bool is_valid_class( const std::string& str )
16 {
17   return( str.find( "cpPlugins_Id_Macro" ) != std::string::npos );
18 }
19
20 // -------------------------------------------------------------------------
21 void process_header( TInfo& info, const std::string& file_name )
22 {
23   // Load file into a buffer
24   std::ifstream file_stream( file_name.c_str( ) );
25   if( !file_stream )
26     return;
27   std::string buf;
28   file_stream.seekg( 0, std::ios::end );
29   buf.reserve( file_stream.tellg( ) );
30   file_stream.seekg( 0, std::ios::beg );
31   buf.assign(
32     ( std::istreambuf_iterator< char >( file_stream ) ),
33     std::istreambuf_iterator< char >( )
34     );
35   file_stream.close( );
36
37   // Replace separators with spaces
38   std::replace( buf.begin( ), buf.end( ), ',', ' ' );
39   std::replace( buf.begin( ), buf.end( ), ';', ' ' );
40   std::replace( buf.begin( ), buf.end( ), ':', ' ' );
41   std::replace( buf.begin( ), buf.end( ), '(', ' ' );
42   std::replace( buf.begin( ), buf.end( ), ')', ' ' );
43   std::replace( buf.begin( ), buf.end( ), '{', ' ' );
44   std::replace( buf.begin( ), buf.end( ), '}', ' ' );
45
46   // Tokenize buffer
47   std::istringstream tokenizer( buf );
48   std::vector< std::string > tokens;
49   std::copy(
50     std::istream_iterator< std::string >( tokenizer ),
51     std::istream_iterator< std::string >( ),
52     std::back_inserter( tokens )
53     );
54
55   // Find pivot
56   auto p = std::find_if( tokens.begin( ), tokens.end( ), is_valid_class );
57   if( p != tokens.end( ) )
58   {
59     // Find class name and category
60     auto cls_it = p; cls_it++;
61     auto cat_it = cls_it; cat_it++;
62
63     // Find namespace
64     typedef std::reverse_iterator< std::vector< std::string >::iterator > _RIt;
65     _RIt r_end( tokens.begin( ) );
66     _RIt r_begin( cls_it );
67     auto ns_it = std::find( r_begin, r_end, "namespace" ); ns_it--;
68
69     // Update info
70     info[ *cat_it ][ *cls_it ] = *ns_it;
71
72   } // fi
73 }
74
75 // -------------------------------------------------------------------------
76 int main( int argc, char* argv[] )
77 {
78   if( argc < 3 )
79   {
80     std::cerr
81       << "Usage: " << argv[ 0 ]
82       << " output_file header_file_0.h header_file_0.h ..."
83       << std::endl;
84     return( 1 );
85
86   } // fi
87
88   // Parse all header files
89   TInfo info;
90   for( int i = 2; i < argc; ++i )
91     process_header( info, argv[ i ] );
92   if( info.size( ) == 0 )
93   {
94     std::cerr << "ERROR: No valid input headers." << std::endl;
95     return( 1 );
96
97   } // fi
98
99   // Write data
100   std::ofstream out_stream( argv[ 1 ] );
101
102   // Write include section
103   out_stream
104     << "#include <map>" << std::endl
105     << "#include <set>" << std::endl;
106   for( int i = 2; i < argc; ++i )
107     out_stream << "#include \"" << argv[ i ] << "\"" <<std::endl;
108
109   // Write init/finish section
110   out_stream
111     << std::endl
112     << "void __attribute__ ((constructor)) _initialize( )" << std::endl
113     << "{" << std::endl << "}" << std::endl << std::endl
114     << "void __attribute__ ((destructor)) _finalize( )" << std::endl
115     << "{" << std::endl << "}" << std::endl << std::endl;
116
117   // Write access function
118   out_stream
119     << "extern \"C\" std::map< std::string, std::set< std::string > > "
120     << "LoadedFilters( )" << std::endl << "{" << std::endl
121     << "  std::map< std::string, std::set< std::string > > classes;"
122     << std::endl;
123   int i = 0;
124   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
125   {
126     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
127     {
128       out_stream
129         << "  auto f" << i << " = "
130         << jIt->second << "::" << jIt->first
131         << "::New( );" << std::endl
132         << "  classes[ f" << i << "->GetClassCategory( ) ].insert( "
133         << "f" << i << "->GetClassName( ) );" << std::endl;
134       i++;
135
136     } // rof
137
138   } // rof
139   out_stream
140     << "  return( classes );" << std::endl
141     << "}" << std::endl << std::endl;
142
143   // Write creators
144   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
145   {
146     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
147     {
148       out_stream
149         << "extern \"C\" cpPlugins::ProcessObject::Pointer "
150         << iIt->first << "_" << jIt->first
151         << "( )" << std::endl << "{" << std::endl
152         << std::endl
153         << "  cpPlugins::ProcessObject::Pointer p;" << std::endl
154         << "  " << jIt->second << "::" << jIt->first << "::Pointer f = "
155         << jIt->second << "::" << jIt->first << "::New( );" << std::endl
156         << "  p = f.GetPointer( );" << std::endl << "  return( p );"
157         << std::endl;
158       out_stream
159         << "}" << std::endl << std::endl;
160
161     } // rof
162
163   } // rof
164   out_stream.close( );
165
166   return( 0 );
167 }
168
169 // eof - $RCSfile$