]> Creatis software - cpPlugins.git/blob - appli/bash/cpPlugins_CreateInstances.cxx
a286d9311d1737034fe37feb8efe92fecbf926be
[cpPlugins.git] / appli / bash / cpPlugins_CreateInstances.cxx
1 #include <cpPlugins_Config.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 < 5 )
26   {
27     std::cerr
28       << "Usage: " << argv[ 0 ]
29       << " input_definitions library_name header_file source_file"
30       << std::endl;
31     return( 1 );
32
33   } // fi
34   std::string input_definitions_fname = argv[ 1 ];
35   std::string library_name = argv[ 2 ];
36   std::string header_file_fname = argv[ 3 ];
37   std::string source_file_fname = argv[ 4 ];
38
39   // Read file and simple parse it
40   TParsedLines lines;
41   if( !ReadFile( lines, input_definitions_fname ) )
42   {
43     std::cerr
44       << "Error opening file: \""
45       << input_definitions_fname << "\""
46       << std::endl;
47     return( 1 );
48
49   } // fi
50
51   // Expand definitions
52   TVariables vars;
53   for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
54   {
55     TLines tokens;
56     cpPlugins::TokenizeString( tokens, *dIt, "=;" );
57     auto tIt = tokens.begin( );
58     auto vName = *tIt;
59     tIt++;
60     for( ; tIt != tokens.end( ); ++tIt )
61       vars[ vName ].push_back( *tIt );
62
63     TLines res;
64     ExpandDefinitions( res, vars[ vName ], vars );
65     vars[ vName ] = res;
66
67   } // rof
68
69   // Expand groups
70   TLines f_includes_groups, includes_groups, templates_groups, classes_groups;
71   ExpandGroups( f_includes_groups, lines[ 'f' ] );
72   ExpandGroups( includes_groups, lines[ 'i' ] );
73   ExpandGroups( templates_groups, lines[ 't' ] );
74   ExpandGroups( classes_groups, lines[ 'c' ] );
75
76   // Expand definitions
77   TLines f_includes_list, includes_list, templates_list, classes_list;
78   ExpandDefinitions( f_includes_list, f_includes_groups, vars );
79   ExpandDefinitions( includes_list, includes_groups, vars );
80   ExpandDefinitions( templates_list, templates_groups, vars );
81   ExpandDefinitions( classes_list, classes_groups, vars );
82
83   // Write header file
84   std::ofstream header_file( header_file_fname.c_str( ) );
85   if( !header_file )
86   {
87     std::cerr
88       << "Error opening \"" << header_file_fname
89       << "\" for writing." << std::endl;
90     return( 1 );
91
92   } // fi
93
94   // Print header
95   header_file
96     << "#ifndef __" << library_name << "__H__" << std::endl
97     << "#define __" << library_name << "__H__" << std::endl<< std::endl
98     << "#include <cpPlugins_Config.h>" << std::endl
99     << "#include <" << library_name << "_Export.h>" << std::endl << std::endl;
100   PrintLines( "", "", lines[ 'b' ], header_file );
101   header_file << std::endl;
102   PrintLines( "#include <", ">", f_includes_list, header_file );
103   header_file
104     << "#ifdef " << library_name << "_EXPORTS" << std::endl
105     << "#  define " << library_name << "_PREFIX template class "
106     << library_name << "_EXPORT" << std::endl
107     << "#else // " << library_name << "_EXPORTS" << std::endl
108     << "#  define " << library_name
109     << "_PREFIX extern template class" << std::endl
110     << "#endif // "
111     << library_name << "_EXPORTS" << std::endl << std::endl;
112   PrintLines( "#include <", ">", includes_list, header_file );
113   PrintLines( "#include <", ">", templates_list, header_file );
114   header_file
115     << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl;
116   PrintLines( "#include <", "xx>", templates_list, header_file );
117   header_file
118     << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl;
119   PrintLines(
120     library_name + std::string( "_PREFIX " ), ";", classes_list, header_file
121     );
122   header_file
123     << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
124   header_file.close( );
125
126   // Write source file
127   std::ofstream source_file( source_file_fname );
128   if( !source_file )
129   {
130     std::cerr
131       << "Error opening \"" << header_file_fname << "\" for writing." << std::endl;
132     return( 1 );
133
134   } // fi
135   source_file
136     << "#include \"" << header_file_fname << "\"" << std::endl;
137   source_file.close( );
138
139   return( 0 );
140 }
141
142 // -------------------------------------------------------------------------
143 bool ReadFile( TParsedLines& lines, const std::string& fname )
144 {
145   std::string buffer;
146   if( cpPlugins::ReadFileIntoString( buffer, fname ) )
147   {
148     std::istringstream input_stream( buffer );
149
150     // Read line by line
151     std::string line;
152     while( std::getline( input_stream, line ) )
153     {
154       auto cmd_pos = line.end( );
155       auto arg_pos = line.end( );
156       auto lIt = line.begin( );
157       while( lIt != line.end( ) )
158       {
159         if( !cpPlugins::IsBlank( *lIt ) )
160         {
161           if( cmd_pos == line.end( ) )
162           {
163             cmd_pos = lIt;
164             ++lIt;
165           }
166           else if( arg_pos == line.end( ) )
167           {
168             arg_pos = lIt;
169             lIt = line.end( );
170
171           } // fi
172         }
173         else
174           ++lIt;
175
176       } // elihw
177       char cmd = *cmd_pos;
178       std::string arg;
179       arg.resize( line.end( ) - arg_pos );
180       std::copy( arg_pos, line.end( ), arg.begin( ) );
181       lines[ cmd ].push_back( arg );
182
183     } // elihw
184     return( true );
185   }
186   else
187     return( false );
188 }
189
190 // -------------------------------------------------------------------------
191 void ExpandGroups( TLines& res, const TLines& lines )
192 {
193   for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
194   {
195     auto b_pos = lIt->find( "@{" );
196     if( b_pos != std::string::npos )
197     {
198       unsigned int braces_count = 1;
199       auto e_pos = b_pos;
200       e_pos += 2;
201       while( braces_count != 0 && e_pos < lIt->size( ) )
202       {
203         auto v = ( *lIt )[ e_pos ];
204         braces_count += ( v == '{' )? 1: ( ( v == '}' )? -1: 0 );
205         e_pos++;
206
207       } // elihw
208       if( braces_count == 0 )
209       {
210         auto replace = lIt->substr( b_pos, e_pos - b_pos );
211         auto expansion = replace.substr( 2, replace.size( ) - 3 );
212         TLines tokens;
213         cpPlugins::TokenizeString( tokens, expansion, ";" );
214         for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
215           *tIt = cpPlugins::ReplaceString( *lIt, replace, *tIt );
216         ExpandGroups( res, tokens );
217
218       } // fi
219     }
220     else
221       res.push_back( *lIt );
222
223   } // rof
224 }
225
226 // -------------------------------------------------------------------------
227 void ExpandDefinitions(
228   TLines& res, const TLines& lines, const TVariables& vars
229   )
230 {
231   std::string seps = " ,;:{}[]()\"$&<>*.";
232
233   for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
234   {
235     auto b_pos = lIt->find( "#" );
236     if( b_pos != std::string::npos )
237     {
238       TLines tokens;
239       cpPlugins::TokenizeString( tokens, lIt->substr( b_pos ), seps );
240       std::string cmd = tokens[ 0 ];
241       auto vIt = vars.find( cmd );
242       if( vIt != vars.end( ) )
243       {
244         if( vIt->second.size( ) > 0 )
245         {
246           TLines new_res;
247           for(
248             auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt
249             )
250             new_res.push_back( cpPlugins::ReplaceString( *lIt, cmd, *wIt ) );
251           ExpandDefinitions( res, new_res, vars );
252
253         } // fi
254
255       } // fi
256     }
257     else
258       res.push_back(
259         cpPlugins::ReplaceString(
260           cpPlugins::ReplaceString( *lIt, "{", "" ), "}", ""
261           )
262         );
263
264   } // rof
265 }
266
267 // -------------------------------------------------------------------------
268 void PrintLines(
269   const std::string& prefix, const std::string& suffix,
270   const TLines& lines, std::ostream& out
271   )
272 {
273   for( auto i = lines.begin( ); i != lines.end( ); ++i )
274     out << prefix << *i << suffix << std::endl;
275 }
276
277 // eof - $RCSfile$