]> Creatis software - cpPlugins.git/blob - appli/bash/cpPlugins_HostCreator.cxx
Now it compiles again on Windows.
[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   for( int i = 2; i < argc; ++i )
104     out_stream << "#include \"" << argv[ i ] << "\"" <<std::endl;
105
106   // Write init/finish section
107   /* TODO:
108      out_stream
109      << std::endl
110      << "void __attribute__ ((constructor)) _initialize( )" << std::endl
111      << "{" << std::endl << "}" << std::endl << std::endl
112      << "void __attribute__ ((destructor)) _finalize( )" << std::endl
113      << "{" << std::endl << "}" << std::endl;
114   */
115
116   // Write access function
117   out_stream
118     << std::endl
119     << "extern \"C\" __declspec(dllexport) const char* "
120     << "cpPlugins_LoadedFilters( )" << std::endl << "{" << std::endl
121     << "  static std::string classes;"
122     << std::endl
123     << "  classes = \"\";" << std::endl;
124   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
125     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
126       out_stream
127         << "  classes += std::string( \"" << iIt->first
128         << ":" << jIt->first << ";\" );" << std::endl;
129   out_stream
130     << "  return( classes.c_str( ) );" << std::endl
131     << "}" << std::endl << std::endl;
132
133   // Write creators
134   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
135   {
136     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
137     {
138       out_stream
139         << "extern \"C\" __declspec(dllexport) void* "
140         << iIt->first << "_" << jIt->first
141         << "( )" << std::endl << "{" << std::endl
142         << "  static " << jIt->second << "::" << jIt->first << "::Pointer f;" << std::endl
143         << "  f = " << jIt->second << "::" << jIt->first << "::New( );" << std::endl
144         << "  return( &f );"
145         << std::endl;
146       out_stream
147         << "}" << std::endl << std::endl;
148
149     } // rof
150
151   } // rof
152   out_stream.close( );
153
154   return( 0 );
155 }
156
157 // eof - $RCSfile$