#include #include #include #include // ------------------------------------------------------------------------- typedef std::vector< std::string > TLines; typedef std::map< char, TLines > TParsedLines; typedef std::map< std::string, TLines > TVariables; // ------------------------------------------------------------------------- bool ReadFile( TParsedLines& lines, const std::string& fname ); void ExpandGroups( TLines& res, const TLines& lines ); void ExpandDefinitions( TLines& res, const TLines& lines, const TVariables& vars ); void PrintLines( const std::string& prefix, const std::string& suffix, const TLines& lines, std::ostream& out ); // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { if( argc < 5 ) { std::cerr << "Usage: " << argv[ 0 ] << " input_definitions library_name header_file source_file" << std::endl; return( 1 ); } // fi std::string input_definitions_fname = argv[ 1 ]; std::string library_name = argv[ 2 ]; std::string header_file_fname = argv[ 3 ]; std::string source_file_fname = argv[ 4 ]; // Read file and simple parse it TParsedLines lines; if( !ReadFile( lines, input_definitions_fname ) ) { std::cerr << "Error opening file: \"" << input_definitions_fname << "\"" << std::endl; return( 1 ); } // fi // Expand definitions TVariables vars; for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt ) { TLines tokens; cpPlugins::TokenizeString( tokens, *dIt, "=;" ); auto tIt = tokens.begin( ); auto vName = *tIt; tIt++; for( ; tIt != tokens.end( ); ++tIt ) vars[ vName ].push_back( *tIt ); TLines res; ExpandDefinitions( res, vars[ vName ], vars ); vars[ vName ] = res; } // rof // Expand groups TLines f_includes_groups, includes_groups, templates_groups, classes_groups; ExpandGroups( f_includes_groups, lines[ 'f' ] ); ExpandGroups( includes_groups, lines[ 'i' ] ); ExpandGroups( templates_groups, lines[ 't' ] ); ExpandGroups( classes_groups, lines[ 'c' ] ); // Expand definitions TLines f_includes_list, includes_list, templates_list, classes_list; ExpandDefinitions( f_includes_list, f_includes_groups, vars ); ExpandDefinitions( includes_list, includes_groups, vars ); ExpandDefinitions( templates_list, templates_groups, vars ); ExpandDefinitions( classes_list, classes_groups, vars ); // Write header file std::ofstream header_file( header_file_fname.c_str( ) ); if( !header_file ) { std::cerr << "Error opening \"" << header_file_fname << "\" for writing." << std::endl; return( 1 ); } // fi // Print header header_file << "#ifndef __" << library_name << "__H__" << std::endl << "#define __" << library_name << "__H__" << std::endl<< std::endl << "#include " << std::endl << "#include <" << library_name << "_Export.h>" << std::endl << std::endl; PrintLines( "", "", lines[ 'b' ], header_file ); header_file << std::endl; PrintLines( "#include <", ">", f_includes_list, header_file ); header_file << "#ifdef " << library_name << "_EXPORTS" << std::endl << "# define " << library_name << "_PREFIX template class " << library_name << "_EXPORT" << std::endl << "#else // " << library_name << "_EXPORTS" << std::endl << "# define " << library_name << "_PREFIX extern template class" << std::endl << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl; PrintLines( "#include <", ">", includes_list, header_file ); PrintLines( "#include <", ">", templates_list, header_file ); header_file << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl; PrintLines( "#include <", "xx>", templates_list, header_file ); header_file << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl; PrintLines( library_name + std::string( "_PREFIX " ), ";", classes_list, header_file ); header_file << std::endl << "#endif // __" << library_name << "__H__" << std::endl; header_file.close( ); // Write source file std::ofstream source_file( source_file_fname ); if( !source_file ) { std::cerr << "Error opening \"" << header_file_fname << "\" for writing." << std::endl; return( 1 ); } // fi source_file << "#include \"" << header_file_fname << "\"" << std::endl; source_file.close( ); return( 0 ); } // ------------------------------------------------------------------------- bool ReadFile( TParsedLines& lines, const std::string& fname ) { std::string buffer; if( cpPlugins::ReadFileIntoString( buffer, fname ) ) { std::istringstream input_stream( buffer ); // Read line by line std::string line; while( std::getline( input_stream, line ) ) { auto cmd_pos = line.end( ); auto arg_pos = line.end( ); auto lIt = line.begin( ); while( lIt != line.end( ) ) { if( !cpPlugins::IsBlank( *lIt ) ) { if( cmd_pos == line.end( ) ) { cmd_pos = lIt; ++lIt; } else if( arg_pos == line.end( ) ) { arg_pos = lIt; lIt = line.end( ); } // fi } else ++lIt; } // elihw char cmd = *cmd_pos; std::string arg; arg.resize( line.end( ) - arg_pos ); std::copy( arg_pos, line.end( ), arg.begin( ) ); lines[ cmd ].push_back( arg ); } // elihw return( true ); } else return( false ); } // ------------------------------------------------------------------------- void ExpandGroups( TLines& res, const TLines& lines ) { for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt ) { auto b_pos = lIt->find( "@{" ); if( b_pos != std::string::npos ) { unsigned int braces_count = 1; auto e_pos = b_pos; e_pos += 2; while( braces_count != 0 && e_pos < lIt->size( ) ) { auto v = ( *lIt )[ e_pos ]; braces_count += ( v == '{' )? 1: ( ( v == '}' )? -1: 0 ); e_pos++; } // elihw if( braces_count == 0 ) { auto replace = lIt->substr( b_pos, e_pos - b_pos ); auto expansion = replace.substr( 2, replace.size( ) - 3 ); TLines tokens; cpPlugins::TokenizeString( tokens, expansion, ";" ); for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt ) *tIt = cpPlugins::ReplaceString( *lIt, replace, *tIt ); ExpandGroups( res, tokens ); } // fi } else res.push_back( *lIt ); } // rof } // ------------------------------------------------------------------------- void ExpandDefinitions( TLines& res, const TLines& lines, const TVariables& vars ) { std::string seps = " ,;:{}[]()\"$&<>*."; for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt ) { auto b_pos = lIt->find( "#" ); if( b_pos != std::string::npos ) { TLines tokens; cpPlugins::TokenizeString( tokens, lIt->substr( b_pos ), seps ); std::string cmd = tokens[ 0 ]; auto vIt = vars.find( cmd ); if( vIt != vars.end( ) ) { if( vIt->second.size( ) > 0 ) { TLines new_res; for( auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt ) new_res.push_back( cpPlugins::ReplaceString( *lIt, cmd, *wIt ) ); ExpandDefinitions( res, new_res, vars ); } // fi } // fi } else res.push_back( cpPlugins::ReplaceString( cpPlugins::ReplaceString( *lIt, "{", "" ), "}", "" ) ); } // rof } // ------------------------------------------------------------------------- void PrintLines( const std::string& prefix, const std::string& suffix, const TLines& lines, std::ostream& out ) { for( auto i = lines.begin( ); i != lines.end( ); ++i ) out << prefix << *i << suffix << std::endl; } // eof - $RCSfile$