10 // -------------------------------------------------------------------------
11 typedef std::map< std::string, std::string > TPair;
12 typedef std::map< std::string, TPair > TInfo;
14 // -------------------------------------------------------------------------
15 bool is_valid_class( const std::string& str )
17 return( str.find( "cpPlugins_Id_Macro" ) != std::string::npos );
20 // -------------------------------------------------------------------------
21 void process_header( TInfo& info, const std::string& file_name )
23 // Load file into a buffer
24 std::ifstream file_stream( file_name.c_str( ) );
28 file_stream.seekg( 0, std::ios::end );
29 buf.reserve( file_stream.tellg( ) );
30 file_stream.seekg( 0, std::ios::beg );
32 ( std::istreambuf_iterator< char >( file_stream ) ),
33 std::istreambuf_iterator< char >( )
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( ), '}', ' ' );
47 std::istringstream tokenizer( buf );
48 std::vector< std::string > tokens;
50 std::istream_iterator< std::string >( tokenizer ),
51 std::istream_iterator< std::string >( ),
52 std::back_inserter( tokens )
56 auto p = std::find_if( tokens.begin( ), tokens.end( ), is_valid_class );
57 if( p != tokens.end( ) )
59 // Find class name and category
60 auto cls_it = p; cls_it++;
61 auto cat_it = cls_it; cat_it++;
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--;
70 info[ *cat_it ][ *cls_it ] = *ns_it;
75 // -------------------------------------------------------------------------
76 int main( int argc, char* argv[] )
81 << "Usage: " << argv[ 0 ]
82 << " output_file header_file_0.h header_file_0.h ..."
88 // Parse all header files
90 for( int i = 2; i < argc; ++i )
91 process_header( info, argv[ i ] );
92 if( info.size( ) == 0 )
94 std::cerr << "ERROR: No valid input headers." << std::endl;
100 std::ofstream out_stream( argv[ 1 ] );
102 // Write include section
103 for( int i = 2; i < argc; ++i )
104 out_stream << "#include \"" << argv[ i ] << "\"" <<std::endl;
106 // Write init/finish section
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;
116 #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
117 std::string export_prefix = "__declspec(dllexport)";
118 #else // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
119 std::string export_prefix = "__attribute__((visibility(\"default\")))";
120 #endif // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
122 // Write access function
125 << "extern \"C\" " << export_prefix << " const char* "
126 << "cpPlugins_LoadedFilters( )" << std::endl << "{" << std::endl
127 << " static std::string classes;"
129 << " classes = \"\";" << std::endl;
130 for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
131 for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
133 << " classes += std::string( \"" << iIt->first
134 << ":" << jIt->first << ";\" );" << std::endl;
136 << " return( classes.c_str( ) );" << std::endl
137 << "}" << std::endl << std::endl;
140 for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
142 for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
145 << "extern \"C\" " << export_prefix << " void* "
146 << iIt->first << "_" << jIt->first
147 << "( )" << std::endl << "{" << std::endl
148 << " static " << jIt->second << "::" << jIt->first << "::Pointer f;" << std::endl
149 << " f = " << jIt->second << "::" << jIt->first << "::New( );" << std::endl
153 << "}" << std::endl << std::endl;