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, const TVariables& vars );
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 input_definitions_fname = argv[ 1 ];
43 std::string library_name = argv[ 2 ];
44 std::string header_file_fname = argv[ 3 ];
45 std::string source_file_fname = argv[ 4 ];
47 // Read file and simple parse it
49 if( !ReadFile( lines, input_definitions_fname ) )
52 << "Error opening file: \""
53 << input_definitions_fname << "\""
59 // Expand variable definitions
61 for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
63 auto tokens = Tokenize( *dIt, "=;" );
64 auto tIt = tokens.begin( );
67 for( ; tIt != tokens.end( ); ++tIt )
68 vars[ vName ].push_back( *tIt );
71 ExpandVariables( res, vars[ vName ], vars );
76 // First include section
77 TLines first_includes, normal_includes, template_includes, template_sources;
78 ParseIncludes( first_includes, lines[ 'f' ] );
79 ParseIncludes( normal_includes, lines[ 'i' ] );
80 ParseIncludes( template_includes, lines[ 't' ] );
81 ParseIncludes( template_sources, lines[ 't' ], "xx" );
85 ExpandGroups( pre_classes, lines[ 'c' ], vars );
89 ExpandVariables( real_classes, pre_classes, vars );
91 // Prepare header file
92 std::ofstream header_file( header_file_fname.c_str( ) );
96 << "Error opening \"" << header_file_fname
97 << "\" for writing." << std::endl;
104 << "#ifndef __" << library_name << "__H__" << std::endl
105 << "#define __" << library_name << "__H__" << std::endl<< std::endl
106 << "#include <cpPlugins_Config.h>" << std::endl
107 << "#include <" << library_name << "_Export.h>" << std::endl << std::endl;
108 PrintLines( "", "", lines[ 'b' ], header_file );
109 header_file << std::endl;
110 PrintLines( "", "", first_includes, header_file );
112 << "#ifdef " << library_name << "_EXPORTS" << std::endl
113 << "# define " << library_name << "_PREFIX template class "
114 << library_name << "_EXPORT" << std::endl
115 << "#else // " << library_name << "_EXPORTS" << std::endl
116 << "# define " << library_name
117 << "_PREFIX extern template class" << std::endl
119 << library_name << "_EXPORTS" << std::endl;
120 PrintLines( "", "", normal_includes, header_file );
121 PrintLines( "", "", template_includes, header_file );
123 << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl;
124 PrintLines( "", "", template_sources, header_file );
125 header_file << "#endif // " << library_name << "_EXPORTS" << std::endl;
126 header_file << std::endl;
128 library_name + std::string( "_PREFIX " ), ";", real_classes, header_file
131 << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
132 header_file.close( );
135 std::ofstream source_file( source_file_fname );
139 << "Error opening \"" << header_file_fname << "\" for writing." << std::endl;
144 << "#include \"" << header_file_fname << "\"" << std::endl;
145 source_file.close( );
149 // -------------------------------------------------------------------------
150 TLines Tokenize( const std::string& str, const std::string& delims )
153 if( str.size( ) > 0 )
155 char* buffer = new char[ str.size( ) + 1 ];
156 std::strcpy( buffer, str.c_str( ) );
157 buffer[ str.size( ) ] = '\0';
158 char* it = std::strtok( buffer, delims.c_str( ) );
161 tokens.push_back( std::string( it ) );
162 it = std::strtok( NULL, delims.c_str( ) );
171 // -------------------------------------------------------------------------
173 const std::string& str, const std::string& sub, const std::string& nsub
176 std::string res = str;
178 while( ( index = res.find( sub ) ) != std::string::npos )
179 res.replace( index, sub.size( ), nsub );
183 // -------------------------------------------------------------------------
184 bool ReadFile( TParsedLines& lines, const std::string& fname )
186 // Load file into a string stream
187 std::ifstream file_stream( fname.c_str( ) );
191 file_stream.seekg( 0, std::ios::end );
192 buffer.reserve( file_stream.tellg( ) );
193 file_stream.seekg( 0, std::ios::beg );
195 ( std::istreambuf_iterator< char >( file_stream ) ),
196 std::istreambuf_iterator< char >( )
198 file_stream.close( );
199 std::istringstream input_stream( buffer );
203 while( std::getline( input_stream, line ) )
205 auto cmd_pos = line.end( );
206 auto arg_pos = line.end( );
207 auto lIt = line.begin( );
208 while( lIt != line.end( ) )
210 if( !std::isblank( *lIt ) )
212 if( cmd_pos == line.end( ) )
217 else if( arg_pos == line.end( ) )
230 arg.resize( line.end( ) - arg_pos );
231 std::copy( arg_pos, line.end( ), arg.begin( ) );
232 lines[ cmd ].push_back( arg );
238 // -------------------------------------------------------------------------
239 void ExpandGroups( TLines& res, const TLines& lines, const TVariables& vars )
241 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
243 auto b_pos = lIt->find( "@{" );
244 if( b_pos != std::string::npos )
246 auto e_pos = lIt->find( "}" );
247 auto expansion = lIt->substr( b_pos + 2, e_pos - b_pos - 2 );
248 auto tokens = Tokenize( expansion, ";" );
249 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
251 auto vIt = vars.find( *tIt );
252 if( vIt != vars.end( ) )
254 auto wIt = vIt->second.begin( );
255 std::string values = *wIt;
256 for( wIt++; wIt != vIt->second.end( ); ++wIt )
257 values += ";" + *wIt;
258 *tIt = Replace( *lIt, vIt->first, values );
261 *tIt = lIt->substr( 0, b_pos ) + *tIt + lIt->substr( e_pos + 1 );
264 ExpandGroups( res, tokens, vars );
267 res.push_back( *lIt );
272 // -------------------------------------------------------------------------
273 void ExpandVariables( TLines& res, const TLines& lines, const TVariables& vars )
275 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
277 auto b_pos = lIt->find( "#" );
278 if( b_pos != std::string::npos )
280 auto tokens = Tokenize( lIt->substr( b_pos ), " ,;:{}[]()\"$&<>" );
281 std::string cmd = tokens[ 0 ];
282 auto vIt = vars.find( cmd );
283 if( vIt != vars.end( ) )
285 if( vIt->second.size( ) > 0 )
288 for( auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt )
289 new_res.push_back( Replace( *lIt, cmd, *wIt ) );
290 ExpandVariables( res, new_res, vars );
297 res.push_back( *lIt );
302 // -------------------------------------------------------------------------
303 void ParseIncludes( TLines& res, const TLines& lines, const std::string& ext )
305 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
307 std::string( "#include <" ) + *lIt + ext + std::string( ">" )
311 // -------------------------------------------------------------------------
313 const std::string& prefix, const std::string& suffix,
314 const TLines& lines, std::ostream& out
317 for( auto i = lines.begin( ); i != lines.end( ); ++i )
318 out << prefix << *i << suffix << std::endl;