10 #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
11 # define cpPlugins_STRTOK( A, B, N ) strtok_s( A, B, N )
12 #else // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
13 # define cpPlugins_STRTOK( A, B, N ) std::strtok( A, B )
14 #endif // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
16 // -------------------------------------------------------------------------
17 typedef std::vector< std::string > TLines;
18 typedef std::map< char, TLines > TParsedLines;
19 typedef std::map< std::string, TLines > TVariables;
21 // -------------------------------------------------------------------------
22 bool cpPlugins_ISBLANK( const char& value );
23 TLines Tokenize( const std::string& str, const std::string& delims );
25 const std::string& str, const std::string& sub, const std::string& nsub
27 bool ReadFile( TParsedLines& lines, const std::string& fname );
28 void ExpandGroups( TLines& res, const TLines& lines, const TVariables& vars );
29 void ExpandVariables( TLines& res, const TLines& lines, const TVariables& vars );
30 void ParseIncludes( TLines& res, const TLines& lines, const std::string& ext = "" );
32 const std::string& prefix, const std::string& suffix,
33 const TLines& lines, std::ostream& out
36 // -------------------------------------------------------------------------
37 int main( int argc, char* argv[] )
42 << "Usage: " << argv[ 0 ]
43 << " input_definitions library_name header_file source_file"
48 std::string input_definitions_fname = argv[ 1 ];
49 std::string library_name = argv[ 2 ];
50 std::string header_file_fname = argv[ 3 ];
51 std::string source_file_fname = argv[ 4 ];
53 // Read file and simple parse it
55 if( !ReadFile( lines, input_definitions_fname ) )
58 << "Error opening file: \""
59 << input_definitions_fname << "\""
65 // Expand variable definitions
67 for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
69 auto tokens = Tokenize( *dIt, "=;" );
70 auto tIt = tokens.begin( );
73 for( ; tIt != tokens.end( ); ++tIt )
74 vars[ vName ].push_back( *tIt );
77 ExpandVariables( res, vars[ vName ], vars );
82 // First include section
83 TLines first_includes, normal_includes, template_includes, template_sources;
84 ParseIncludes( first_includes, lines[ 'f' ] );
85 ParseIncludes( normal_includes, lines[ 'i' ] );
86 ParseIncludes( template_includes, lines[ 't' ] );
87 ParseIncludes( template_sources, lines[ 't' ], "xx" );
91 ExpandGroups( pre_classes, lines[ 'c' ], vars );
95 ExpandVariables( real_classes, pre_classes, vars );
97 // Prepare header file
98 std::ofstream header_file( header_file_fname.c_str( ) );
102 << "Error opening \"" << header_file_fname
103 << "\" for writing." << std::endl;
110 << "#ifndef __" << library_name << "__H__" << std::endl
111 << "#define __" << library_name << "__H__" << std::endl<< std::endl
112 << "#include <cpPlugins_Config.h>" << std::endl
113 << "#include <" << library_name << "_Export.h>" << std::endl << std::endl;
114 PrintLines( "", "", lines[ 'b' ], header_file );
115 header_file << std::endl;
116 PrintLines( "", "", first_includes, header_file );
118 << "#ifdef " << library_name << "_EXPORTS" << std::endl
119 << "# define " << library_name << "_PREFIX template class "
120 << library_name << "_EXPORT" << std::endl
121 << "#else // " << library_name << "_EXPORTS" << std::endl
122 << "# define " << library_name
123 << "_PREFIX extern template class" << std::endl
125 << library_name << "_EXPORTS" << std::endl;
126 PrintLines( "", "", normal_includes, header_file );
127 PrintLines( "", "", template_includes, header_file );
129 << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl;
130 PrintLines( "", "", template_sources, header_file );
131 header_file << "#endif // " << library_name << "_EXPORTS" << std::endl;
132 header_file << std::endl;
134 library_name + std::string( "_PREFIX " ), ";", real_classes, header_file
137 << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
138 header_file.close( );
141 std::ofstream source_file( source_file_fname );
145 << "Error opening \"" << header_file_fname << "\" for writing." << std::endl;
150 << "#include \"" << header_file_fname << "\"" << std::endl;
151 source_file.close( );
155 // -------------------------------------------------------------------------
156 bool cpPlugins_ISBLANK( const char& value )
158 return( value == ' ' || value == '\t' || value == '\n' || value == '\r' );
161 // -------------------------------------------------------------------------
162 TLines Tokenize( const std::string& str, const std::string& delims )
165 if( str.size( ) > 0 )
167 auto ssize = str.size( );
168 char* buffer = new char[ ssize + 1 ];
169 for( unsigned long i = 0; i < ssize; ++i )
170 buffer[ i ] = str[ i ];
171 buffer[ ssize ] = '\0';
173 char* it = cpPlugins_STRTOK( buffer, delims.c_str( ), &next );
176 tokens.push_back( std::string( it ) );
177 it = cpPlugins_STRTOK( NULL, delims.c_str( ), &next );
186 // -------------------------------------------------------------------------
188 const std::string& str, const std::string& sub, const std::string& nsub
191 std::string res = str;
193 while( ( index = res.find( sub ) ) != std::string::npos )
194 res.replace( index, sub.size( ), nsub );
198 // -------------------------------------------------------------------------
199 bool ReadFile( TParsedLines& lines, const std::string& fname )
201 // Load file into a string stream
202 std::ifstream file_stream( fname.c_str( ) );
206 file_stream.seekg( 0, std::ios::end );
207 buffer.reserve( ( unsigned int )( file_stream.tellg( ) ) );
208 file_stream.seekg( 0, std::ios::beg );
210 ( std::istreambuf_iterator< char >( file_stream ) ),
211 std::istreambuf_iterator< char >( )
213 file_stream.close( );
214 std::istringstream input_stream( buffer );
218 while( std::getline( input_stream, line ) )
220 auto cmd_pos = line.end( );
221 auto arg_pos = line.end( );
222 auto lIt = line.begin( );
223 while( lIt != line.end( ) )
225 if( !cpPlugins_ISBLANK( *lIt ) )
227 if( cmd_pos == line.end( ) )
232 else if( arg_pos == line.end( ) )
245 arg.resize( line.end( ) - arg_pos );
246 std::copy( arg_pos, line.end( ), arg.begin( ) );
247 lines[ cmd ].push_back( arg );
253 // -------------------------------------------------------------------------
254 void ExpandGroups( TLines& res, const TLines& lines, const TVariables& vars )
256 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
258 auto b_pos = lIt->find( "@{" );
259 if( b_pos != std::string::npos )
261 auto e_pos = lIt->find( "}" );
262 auto expansion = lIt->substr( b_pos + 2, e_pos - b_pos - 2 );
263 auto tokens = Tokenize( expansion, ";" );
264 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
266 auto vIt = vars.find( *tIt );
267 if( vIt != vars.end( ) )
269 auto wIt = vIt->second.begin( );
270 std::string values = *wIt;
271 for( wIt++; wIt != vIt->second.end( ); ++wIt )
272 values += ";" + *wIt;
273 *tIt = Replace( *lIt, vIt->first, values );
276 *tIt = lIt->substr( 0, b_pos ) + *tIt + lIt->substr( e_pos + 1 );
279 ExpandGroups( res, tokens, vars );
282 res.push_back( *lIt );
287 // -------------------------------------------------------------------------
288 void ExpandVariables( TLines& res, const TLines& lines, const TVariables& vars )
290 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
292 auto b_pos = lIt->find( "#" );
293 if( b_pos != std::string::npos )
295 auto tokens = Tokenize( lIt->substr( b_pos ), " ,;:{}[]()\"$&<>" );
296 std::string cmd = tokens[ 0 ];
297 auto vIt = vars.find( cmd );
298 if( vIt != vars.end( ) )
300 if( vIt->second.size( ) > 0 )
303 for( auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt )
304 new_res.push_back( Replace( *lIt, cmd, *wIt ) );
305 ExpandVariables( res, new_res, vars );
312 res.push_back( *lIt );
317 // -------------------------------------------------------------------------
318 void ParseIncludes( TLines& res, const TLines& lines, const std::string& ext )
320 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
322 std::string( "#include <" ) + *lIt + ext + std::string( ">" )
326 // -------------------------------------------------------------------------
328 const std::string& prefix, const std::string& suffix,
329 const TLines& lines, std::ostream& out
332 for( auto i = lines.begin( ); i != lines.end( ); ++i )
333 out << prefix << *i << suffix << std::endl;