]> Creatis software - cpPlugins.git/blob - appli/bash/cpPlugins_HostCreator.cxx
ee11adf24c667c3453baca007f984d2c88f88c46
[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     << "cpPlugins_LoadedFilters( )" << std::endl << "{" << std::endl
121     << "  std::map< std::string, std::set< std::string > > classes;"
122     << std::endl;
123   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
124     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
125       out_stream
126         << "  classes[ \"" << iIt->first
127         << "\" ].insert( \"" << jIt->first << "\" );" << std::endl;
128   out_stream
129     << "  return( classes );" << std::endl
130     << "}" << std::endl << std::endl;
131
132   // Write creators
133   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
134   {
135     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
136     {
137       out_stream
138         << "extern \"C\" cpPlugins::ProcessObject::Pointer "
139         << iIt->first << "_" << jIt->first
140         << "( )" << std::endl << "{" << std::endl
141         << std::endl
142         << "  cpPlugins::ProcessObject::Pointer p;" << std::endl
143         << "  " << jIt->second << "::" << jIt->first << "::Pointer f = "
144         << jIt->second << "::" << jIt->first << "::New( );" << std::endl
145         << "  p = f.GetPointer( );" << std::endl << "  return( p );"
146         << std::endl;
147       out_stream
148         << "}" << std::endl << std::endl;
149
150     } // rof
151
152   } // rof
153   out_stream.close( );
154
155   return( 0 );
156 }
157
158 // eof - $RCSfile$