]> Creatis software - cpPlugins.git/blob - appli/bash/cpPlugins_CreateInstances.cxx
Code cleaning
[cpPlugins.git] / appli / bash / cpPlugins_CreateInstances.cxx
1 #include <cpExtensions/Utility.h>
2 #include <map>
3 #include <vector>
4 #include <sstream>
5
6 // -------------------------------------------------------------------------
7 typedef std::vector< std::string >      TLines;
8 typedef std::map< char, TLines >        TParsedLines;
9 typedef std::map< std::string, TLines > TVariables;
10
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
16   );
17 void PrintLines(
18   const std::string& prefix, const std::string& suffix,
19   const TLines& lines, std::ostream& out
20   );
21
22 // -------------------------------------------------------------------------
23 int main( int argc, char* argv[] )
24 {
25   if( argc < 4 )
26   {
27     std::cerr
28       << "Usage: " << argv[ 0 ]
29       << " input_definitions library_name output_dir"
30       << std::endl;
31     return( 1 );
32
33   } // fi
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 ] );
37
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" );
47
48   // Read file and simple parse it
49   TParsedLines lines;
50   if( !ReadFile( lines, input_definitions_fname ) )
51   {
52     std::cerr
53       << "Error opening file: \""
54       << input_definitions_fname << "\""
55       << std::endl;
56     return( 1 );
57
58   } // fi
59
60   // Expand definitions
61   TVariables vars;
62   for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
63   {
64     TLines tokens;
65     cpExtensions::TokenizeString( tokens, *dIt, "=;" );
66     auto tIt = tokens.begin( );
67     auto vName = *tIt;
68     tIt++;
69     for( ; tIt != tokens.end( ); ++tIt )
70       vars[ vName ].push_back( *tIt );
71
72     TLines res;
73     ExpandDefinitions( res, vars[ vName ], vars );
74     vars[ vName ] = res;
75
76   } // rof
77
78   // Expand groups
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' ] );
84
85   // Expand definitions
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 );
91
92   // Write header file
93   std::ofstream header_file( header_file_fname.c_str( ) );
94   if( !header_file )
95   {
96     std::cerr
97       << "Error opening \"" << header_file_fname
98       << "\" for writing." << std::endl;
99     return( 1 );
100
101   } // fi
102
103   // Print header
104   header_file
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 );
112   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
119     << "#endif // "
120     << library_name << "_EXPORTS" << std::endl << std::endl;
121   PrintLines( "#include <", ">", includes_list, header_file );
122   PrintLines( "#include <", ">", templates_list, header_file );
123   header_file
124     << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl;
125   PrintLines( "#include <", "xx>", templates_list, header_file );
126   header_file
127     << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl;
128   PrintLines(
129     library_name + std::string( "_PREFIX " ), ";", classes_list, header_file
130     );
131   header_file
132     << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
133   header_file.close( );
134
135   // Write source file
136   std::ofstream source_file( source_file_fname );
137   if( !source_file )
138   {
139     std::cerr
140       << "Error opening \"" << header_file_fname << "\" for writing." << std::endl;
141     return( 1 );
142
143   } // fi
144   source_file
145     << "#include \"" << header_file_fname << "\"" << std::endl;
146   source_file.close( );
147
148   return( 0 );
149 }
150
151 // -------------------------------------------------------------------------
152 bool ReadFile( TParsedLines& lines, const std::string& fname )
153 {
154   std::string buffer;
155   if( cpExtensions::ReadFileIntoBuffer( buffer, fname ) )
156   {
157     std::istringstream input_stream( buffer );
158
159     // Read line by line
160     std::string line;
161     while( std::getline( input_stream, line ) )
162     {
163       auto cmd_pos = line.end( );
164       auto arg_pos = line.end( );
165       auto lIt = line.begin( );
166       while( lIt != line.end( ) )
167       {
168         if( !cpExtensions::IsBlank( *lIt ) )
169         {
170           if( cmd_pos == line.end( ) )
171           {
172             cmd_pos = lIt;
173             ++lIt;
174           }
175           else if( arg_pos == line.end( ) )
176           {
177             arg_pos = lIt;
178             lIt = line.end( );
179
180           } // fi
181         }
182         else
183           ++lIt;
184
185       } // elihw
186       char cmd = *cmd_pos;
187       std::string arg;
188       arg.resize( line.end( ) - arg_pos );
189       std::copy( arg_pos, line.end( ), arg.begin( ) );
190       lines[ cmd ].push_back( arg );
191
192     } // elihw
193     return( true );
194   }
195   else
196     return( false );
197 }
198
199 // -------------------------------------------------------------------------
200 void ExpandGroups( TLines& res, const TLines& lines )
201 {
202   for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
203   {
204     auto b_pos = lIt->find( "@{" );
205     if( b_pos != std::string::npos )
206     {
207       unsigned int braces_count = 1;
208       auto e_pos = b_pos;
209       e_pos += 2;
210       while( braces_count != 0 && e_pos < lIt->size( ) )
211       {
212         auto v = ( *lIt )[ e_pos ];
213         braces_count += ( v == '{' )? 1: ( ( v == '}' )? -1: 0 );
214         e_pos++;
215
216       } // elihw
217       if( braces_count == 0 )
218       {
219         auto replace = lIt->substr( b_pos, e_pos - b_pos );
220         auto expansion = replace.substr( 2, replace.size( ) - 3 );
221         TLines tokens;
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 );
226
227       } // fi
228     }
229     else
230       res.push_back( *lIt );
231
232   } // rof
233 }
234
235 // -------------------------------------------------------------------------
236 void ExpandDefinitions(
237   TLines& res, const TLines& lines, const TVariables& vars
238   )
239 {
240   std::string seps = " ,;:{}[]()\"$&<>*.";
241
242   for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
243   {
244     auto b_pos = lIt->find( "#" );
245     if( b_pos != std::string::npos )
246     {
247       TLines tokens;
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( ) )
252       {
253         if( vIt->second.size( ) > 0 )
254         {
255           TLines new_res;
256           for(
257             auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt
258             )
259             new_res.push_back( cpExtensions::ReplaceString( *lIt, cmd, *wIt ) );
260           ExpandDefinitions( res, new_res, vars );
261
262         } // fi
263
264       } // fi
265     }
266     else
267       res.push_back(
268         cpExtensions::ReplaceString(
269           cpExtensions::ReplaceString( *lIt, "{", "" ), "}", ""
270           )
271         );
272
273   } // rof
274 }
275
276 // -------------------------------------------------------------------------
277 void PrintLines(
278   const std::string& prefix, const std::string& suffix,
279   const TLines& lines, std::ostream& out
280   )
281 {
282   for( auto i = lines.begin( ); i != lines.end( ); ++i )
283     out << prefix << *i << suffix << std::endl;
284 }
285
286 // eof - $RCSfile$