1 #include <cpExtensions/Utility.h>
6 // -------------------------------------------------------------------------
7 typedef std::vector< std::string > TLines;
8 typedef std::map< char, TLines > TParsedLines;
9 typedef std::map< std::string, TLines > TVariables;
11 // -------------------------------------------------------------------------
12 bool ReadFile( TParsedLines& lines, const std::string& fname );
13 void ExpandGroups( TLines& res, const TLines& lines );
14 void ExpandDefinitions(
15 TLines& res, const TLines& lines, const TVariables& vars
18 const std::string& prefix, const std::string& suffix,
19 const TLines& lines, std::ostream& out
22 // -------------------------------------------------------------------------
23 int main( int argc, char* argv[] )
28 << "Usage: " << argv[ 0 ]
29 << " input_definitions library_name output_dir"
34 std::string input_definitions_fname = cpExtensions::CanonicalPath( argv[ 1 ] );
35 std::string library_name = argv[ 2 ];
36 std::string output_dir = cpExtensions::CanonicalPath( argv[ 3 ] );
38 // Build source files names
39 std::stringstream str_dir;
40 str_dir << output_dir;
41 if( !cpExtensions::IsPathSeparator( output_dir.back( ) ) )
42 str_dir << cpExtensions_PATH_SEPARATOR;
43 std::string header_file_fname = str_dir.str( );
44 std::string source_file_fname = header_file_fname;
45 header_file_fname += library_name + std::string( ".h" );
46 source_file_fname += library_name + std::string( ".cxx" );
48 // Read file and simple parse it
50 if( !ReadFile( lines, input_definitions_fname ) )
53 << "Error opening file: \""
54 << input_definitions_fname << "\""
62 for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
65 cpExtensions::TokenizeString( tokens, *dIt, "=;" );
66 auto tIt = tokens.begin( );
69 for( ; tIt != tokens.end( ); ++tIt )
70 vars[ vName ].push_back( *tIt );
73 ExpandDefinitions( res, vars[ vName ], vars );
79 TLines f_includes_groups, includes_groups, templates_groups, classes_groups;
80 ExpandGroups( f_includes_groups, lines[ 'f' ] );
81 ExpandGroups( includes_groups, lines[ 'i' ] );
82 ExpandGroups( templates_groups, lines[ 't' ] );
83 ExpandGroups( classes_groups, lines[ 'c' ] );
86 TLines f_includes_list, includes_list, templates_list, classes_list;
87 ExpandDefinitions( f_includes_list, f_includes_groups, vars );
88 ExpandDefinitions( includes_list, includes_groups, vars );
89 ExpandDefinitions( templates_list, templates_groups, vars );
90 ExpandDefinitions( classes_list, classes_groups, vars );
93 std::ofstream header_file( header_file_fname.c_str( ) );
97 << "Error opening \"" << header_file_fname
98 << "\" for writing." << std::endl;
105 << "#ifndef __" << library_name << "__H__" << std::endl
106 << "#define __" << library_name << "__H__" << std::endl<< std::endl
107 << "#include <cpExtensions/Config.h>" << std::endl
108 << "#include <" << library_name << "_Export.h>" << std::endl << std::endl;
109 PrintLines( "", "", lines[ 'b' ], header_file );
110 header_file << std::endl;
111 PrintLines( "#include <", ">", f_includes_list, header_file );
113 << "#ifdef " << library_name << "_EXPORTS" << std::endl
114 << "# define " << library_name << "_PREFIX template class "
115 << library_name << "_EXPORT" << std::endl
116 << "#else // " << library_name << "_EXPORTS" << std::endl
117 << "# define " << library_name
118 << "_PREFIX extern template class" << std::endl
120 << library_name << "_EXPORTS" << std::endl << std::endl;
121 PrintLines( "#include <", ">", includes_list, header_file );
122 PrintLines( "#include <", ">", templates_list, header_file );
124 << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl;
125 PrintLines( "#include <", "xx>", templates_list, header_file );
127 << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl;
129 library_name + std::string( "_PREFIX " ), ";", classes_list, header_file
132 << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
133 header_file.close( );
136 std::ofstream source_file( source_file_fname );
140 << "Error opening \"" << header_file_fname << "\" for writing." << std::endl;
145 << "#include \"" << header_file_fname << "\"" << std::endl;
146 source_file.close( );
151 // -------------------------------------------------------------------------
152 bool ReadFile( TParsedLines& lines, const std::string& fname )
155 if( cpExtensions::ReadFileIntoBuffer( buffer, fname ) )
157 std::istringstream input_stream( buffer );
161 while( std::getline( input_stream, line ) )
163 auto cmd_pos = line.end( );
164 auto arg_pos = line.end( );
165 auto lIt = line.begin( );
166 while( lIt != line.end( ) )
168 if( !cpExtensions::IsBlank( *lIt ) )
170 if( cmd_pos == line.end( ) )
175 else if( arg_pos == line.end( ) )
188 arg.resize( line.end( ) - arg_pos );
189 std::copy( arg_pos, line.end( ), arg.begin( ) );
190 lines[ cmd ].push_back( arg );
199 // -------------------------------------------------------------------------
200 void ExpandGroups( TLines& res, const TLines& lines )
202 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
204 auto b_pos = lIt->find( "@{" );
205 if( b_pos != std::string::npos )
207 unsigned int braces_count = 1;
210 while( braces_count != 0 && e_pos < lIt->size( ) )
212 auto v = ( *lIt )[ e_pos ];
213 braces_count += ( v == '{' )? 1: ( ( v == '}' )? -1: 0 );
217 if( braces_count == 0 )
219 auto replace = lIt->substr( b_pos, e_pos - b_pos );
220 auto expansion = replace.substr( 2, replace.size( ) - 3 );
222 cpExtensions::TokenizeString( tokens, expansion, ";" );
223 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
224 *tIt = cpExtensions::ReplaceString( *lIt, replace, *tIt );
225 ExpandGroups( res, tokens );
230 res.push_back( *lIt );
235 // -------------------------------------------------------------------------
236 void ExpandDefinitions(
237 TLines& res, const TLines& lines, const TVariables& vars
240 std::string seps = " ,;:{}[]()\"$&<>*.";
242 for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
244 auto b_pos = lIt->find( "#" );
245 if( b_pos != std::string::npos )
248 cpExtensions::TokenizeString( tokens, lIt->substr( b_pos ), seps );
249 std::string cmd = tokens[ 0 ];
250 auto vIt = vars.find( cmd );
251 if( vIt != vars.end( ) )
253 if( vIt->second.size( ) > 0 )
257 auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt
259 new_res.push_back( cpExtensions::ReplaceString( *lIt, cmd, *wIt ) );
260 ExpandDefinitions( res, new_res, vars );
268 cpExtensions::ReplaceString(
269 cpExtensions::ReplaceString( *lIt, "{", "" ), "}", ""
276 // -------------------------------------------------------------------------
278 const std::string& prefix, const std::string& suffix,
279 const TLines& lines, std::ostream& out
282 for( auto i = lines.begin( ); i != lines.end( ); ++i )
283 out << prefix << *i << suffix << std::endl;