11 // -------------------------------------------------------------------------
12 typedef std::vector< std::string > TLines;
13 typedef std::map< char, TLines > TParsedLines;
14 typedef std::map< std::string, TLines > TVariables;
16 // -------------------------------------------------------------------------
17 TLines Tokenize( const std::string& str, const std::string& delims );
19 const std::string& str, const std::string& sub, const std::string& nsub
21 bool ReadFile( TParsedLines& lines, const std::string& fname );
22 void ExpandGroups( TLines& res, const TLines& lines );
23 void ExpandVariables( TLines& res, const TLines& lines, const TVariables& vars );
24 void ParseIncludes( TLines& res, const TLines& lines, const std::string& ext );
26 const std::string& prefix, const std::string& suffix,
27 const TLines& lines, std::ostream& out
30 // -------------------------------------------------------------------------
31 int main( int argc, char* argv[] )
36 << "Usage: " << argv[ 0 ]
37 << " input_definitions library_name header_file source_file"
42 std::string lname = argv[ 2 ];
44 // Read file and simple parse it
46 if( !ReadFile( lines, argv[ 1 ] ) )
49 << "Error opening file: \""
58 for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
60 auto tokens = Tokenize( *dIt, "=;" );
61 auto tIt = tokens.begin( );
64 for( ; tIt != tokens.end( ); ++tIt )
65 vars[ vName ].push_back( *tIt );
69 // First include section
70 TLines first_includes;
71 ParseIncludes( first_includes, lines[ 'f' ], "" );
73 TLines normal_includes;
74 ParseIncludes( normal_includes, lines[ 'i' ], "" );
76 TLines template_includes;
77 ParseIncludes( template_includes, lines[ 't' ], "" );
79 TLines template_sources;
80 ParseIncludes( template_sources, lines[ 't' ], "xx" );
84 ExpandGroups( classes, lines[ 'c' ] );
88 ExpandVariables( real_classes, classes, vars );
90 // Prepare precompiler options
92 std::stringstream global_header_stream;
94 << "#ifndef __" << lname << "__H__" << std::endl
95 << "#define __" << lname << "__H__" << std::endl<< std::endl
96 << "#include <cpPlugins_Config.h>" << std::endl << std::endl;
97 global_header.push_back( global_header_stream.str( ) );
100 std::stringstream macro_header_stream;
102 << "#ifdef " << lname << "_EXPORTS" << std::endl
103 << "# define " << lname << "_PREFIX template class "
104 << lname << "_EXPORT" << std::endl
105 << "#else // " << lname << "_EXPORTS" << std::endl
106 << "# define " << lname << "_PREFIX extern template class" << std::endl
107 << "#endif // " << lname << "_EXPORTS" << std::endl;
108 macro_header.push_back( macro_header_stream.str( ) );
110 TLines end_global_header;
111 std::stringstream end_global_header_stream;
112 end_global_header_stream
113 << "#endif // __" << lname << "__H__" << std::endl;
114 end_global_header.push_back( end_global_header_stream.str( ) );
117 std::ofstream header_file( argv[ 3 ] );
121 << "Error opening \"" << argv[ 3 ] << "\" for writing." << std::endl;
125 PrintLines( "", "", global_header, header_file );
127 << "#include <" << lname << "_Export.h>" << std::endl << std::endl;
128 PrintLines( "", "", lines[ 'b' ], header_file );
129 header_file << std::endl;
130 PrintLines( "", "", first_includes, header_file );
131 PrintLines( "", "", macro_header, header_file );
132 PrintLines( "", "", normal_includes, header_file );
133 PrintLines( "", "", template_includes, header_file );
134 header_file << std::endl << "#ifdef " << lname << "_EXPORTS" << std::endl;
135 PrintLines( "", "", template_sources, header_file );
136 header_file << "#endif // " << lname << "_EXPORTS" << std::endl;
137 header_file << std::endl;
138 PrintLines( lname + std::string( "_PREFIX " ), ";", real_classes, header_file );
139 header_file << std::endl;
140 PrintLines( "", "", end_global_header, header_file );
141 header_file.close( );
144 std::ofstream source_file( argv[ 4 ] );
148 << "Error opening \"" << argv[ 3 ] << "\" for writing." << std::endl;
153 << "#include \"" << argv[ 3 ] << "\"" << std::endl;
155 PrintLines( "", "", first_includes, source_file );
156 PrintLines( "", "", template_includes, source_file );
157 source_file << std::endl;
159 std::string( "template class " ) + lname + std::string( "_EXPORT " ),
160 ";", real_classes, source_file
163 source_file.close( );
167 // -------------------------------------------------------------------------
168 TLines Tokenize( const std::string& str, const std::string& delims )
171 if( str.size( ) > 0 )
173 char* buffer = new char[ str.size( ) + 1 ];
174 std::strcpy( buffer, str.c_str( ) );
175 buffer[ str.size( ) ] = '\0';
176 char* it = std::strtok( buffer, delims.c_str( ) );
179 tokens.push_back( std::string( it ) );
180 it = std::strtok( NULL, delims.c_str( ) );
189 // -------------------------------------------------------------------------
191 const std::string& str, const std::string& sub, const std::string& nsub
194 std::string res = str;
198 index = res.find( sub, index );
199 if( index == std::string::npos ) break;
200 res.replace( index, sub.size( ), nsub );
201 index += sub.size( );
207 // -------------------------------------------------------------------------
208 bool ReadFile( TParsedLines& lines, const std::string& fname )
210 // Load file into a string stream
211 std::ifstream file_stream( fname.c_str( ) );
215 file_stream.seekg( 0, std::ios::end );
216 buffer.reserve( file_stream.tellg( ) );
217 file_stream.seekg( 0, std::ios::beg );
219 ( std::istreambuf_iterator< char >( file_stream ) ),
220 std::istreambuf_iterator< char >( )
222 file_stream.close( );
223 std::istringstream input_stream( buffer );
227 while( std::getline( input_stream, line ) )
229 auto cmd_pos = line.end( );
230 auto arg_pos = line.end( );
231 auto lIt = line.begin( );
232 while( lIt != line.end( ) )
234 if( !std::isblank( *lIt ) )
236 if( cmd_pos == line.end( ) )
241 else if( arg_pos == line.end( ) )
254 arg.resize( line.end( ) - arg_pos );
255 std::copy( arg_pos, line.end( ), arg.begin( ) );
256 lines[ cmd ].push_back( arg );
262 // -------------------------------------------------------------------------
263 void ExpandGroups( TLines& res, const TLines& lines )
265 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
267 auto b_pos = lIt->find( "#{" );
268 if( b_pos != std::string::npos )
270 auto e_pos = lIt->find( "}" );
271 auto expansion = lIt->substr( b_pos + 2, e_pos - b_pos - 2 );
272 auto tokens = Tokenize( expansion, ";" );
273 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
274 *tIt = lIt->substr( 0, b_pos ) + *tIt + lIt->substr( e_pos + 1 );
275 ExpandGroups( res, tokens );
278 res.push_back( *lIt );
283 // -------------------------------------------------------------------------
284 void ExpandVariables( TLines& res, const TLines& lines, const TVariables& vars )
286 const char* int_types[] = { "char", "short", "int", "long" };
287 const char* float_types[] = { "float", "double" };
288 unsigned int n_int_types = 4, n_float_types = 2;
289 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
291 auto b_pos = lIt->find( "#" );
292 if( b_pos != std::string::npos )
294 auto tokens = Tokenize( lIt->substr( b_pos ), " ,;:{}[]()\"$&<>" );
295 std::string cmd = tokens[ 0 ];
297 cmd == "#int_types" || cmd == "#uint_types" || cmd == "#float_types"
300 const char** types = ( cmd == "#float_types" )? float_types: int_types;
301 unsigned int size = ( cmd == "#float_types" )? n_float_types: n_int_types;
302 std::string ustr = ( ( cmd == "#uint_types" )? "unsigned ": "" );
304 for( unsigned int i = 0; i < size; ++i )
305 new_res.push_back( Replace( *lIt, cmd, ustr + types[ i ] ) );
306 ExpandVariables( res, new_res, vars );
310 auto vIt = vars.find( cmd );
311 if( vIt != vars.end( ) )
315 auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt
317 new_res.push_back( Replace( *lIt, cmd, *wIt ) );
318 ExpandVariables( res, new_res, vars );
325 res.push_back( *lIt );
330 // -------------------------------------------------------------------------
331 void ParseIncludes( TLines& res, const TLines& lines, const std::string& ext )
333 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
335 std::string( "#include <" ) + *lIt + ext + std::string( ">" )
339 // -------------------------------------------------------------------------
341 const std::string& prefix, const std::string& suffix,
342 const TLines& lines, std::ostream& out
345 for( auto i = lines.begin( ); i != lines.end( ); ++i )
346 out << prefix << *i << suffix << std::endl;