7 #include <appli/bash/Utility.h>
9 // -------------------------------------------------------------------------
10 typedef std::map< char, std::vector< std::string > > TCommands;
11 typedef std::map< std::string, std::vector< std::string > > TDefinitions;
13 // -------------------------------------------------------------------------
14 void AddDefinitions( TDefinitions& defs, const std::string& cmd );
15 void InitDefinitions( TDefinitions& defs );
16 void Lines( TCommands& commands, const std::deque< std::string >& lines );
17 void ExpandDefinitions( TDefinitions& defs );
18 std::vector< std::string > Expand(
19 const std::vector< std::string >& commands, const TDefinitions& defs
22 // -------------------------------------------------------------------------
23 int main( int argc, char* argv[] )
25 // Get parameters from input
29 << "Usage: " << argv[ 0 ]
30 << " definitions library_name source_prefix number_of_files" << std::endl;
34 std::string input_definitions = argv[ 1 ];
35 std::string library_name = argv[ 2 ];
36 std::string source_prefix = argv[ 3 ];
37 std::string header_file = source_prefix + std::string( ".h" );
38 std::stringstream nfiles_str( argv[ 4 ] );
39 unsigned int number_of_files;
40 nfiles_str >> number_of_files;
42 // Read input instances
44 if( !cpPlugins_bash::Read( buffer, input_definitions ) )
47 << "Error reading input instances from \""
48 << input_definitions << "\""
54 // Put it in a line-by-line structure
55 std::deque< std::string > lines;
56 cpPlugins_bash::Tokenize( lines, buffer, "\n" );
60 Lines( commands, lines );
64 InitDefinitions( defs );
65 auto dIt = commands.find( 'd' );
66 if( dIt != commands.end( ) )
68 for( auto vIt = dIt->second.begin( ); vIt != dIt->second.end( ); ++vIt )
69 AddDefinitions( defs, *vIt );
74 ExpandDefinitions( defs );
77 std::vector< std::string > before;
78 auto bIt = commands.find( 'b' );
79 if( bIt != commands.end( ) )
81 auto templates = Expand( commands[ 't' ], defs );
82 auto includes = Expand( commands[ 'i' ], defs );
83 auto classes = Expand( commands[ 'c' ], defs );
86 std::stringstream header;
88 << "#ifndef __" << library_name << "__h__" << std::endl
89 << "#define __" << library_name << "__h__" << std::endl << std::endl
90 << "#define ITK_MANUAL_INSTANTIATION" << std::endl;
91 for( auto i = before.begin( ); i != before.end( ); ++i )
92 header << std::endl << *i;
94 for( auto i = includes.begin( ); i != includes.end( ); ++i )
95 header << "#include <" << *i << ">" << std::endl;
96 for( auto i = templates.begin( ); i != templates.end( ); ++i )
97 header << "#include <" << *i << ".h>" << std::endl;
100 for( auto i = classes.begin( ); i != classes.end( ); ++i )
102 << "extern template class " << *i << ";" << std::endl;
105 << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
106 if( !( cpPlugins_bash::Write( header.str( ), header_file ) ) )
108 std::cerr << "Error writing header" << std::endl;
114 unsigned int classes_per_file =
116 std::floor( double( classes.size( ) ) / double( number_of_files ) )
118 if( classes_per_file == 0 )
119 classes_per_file = 1;
120 std::vector< std::vector< std::string > > all_lines( 1 );
121 for( unsigned int c_id = 0; c_id < classes.size( ); ++c_id )
123 all_lines[ all_lines.size( ) - 1 ].push_back( classes[ c_id ] );
124 if( c_id % classes_per_file == classes_per_file - 1 )
125 all_lines.push_back( std::vector< std::string >( ) );
130 while( all_lines.size( ) > number_of_files )
132 all_lines[ all_lines.size( ) - 2 ].insert(
133 all_lines[ all_lines.size( ) - 2 ].end( ),
134 all_lines[ all_lines.size( ) - 1 ].begin( ),
135 all_lines[ all_lines.size( ) - 1 ].end( )
137 all_lines.pop_back( );
140 while( all_lines.size( ) < number_of_files )
141 all_lines.push_back( std::vector< std::string >( ) );
144 for( unsigned int f_id = 0; f_id < all_lines.size( ); ++f_id )
146 std::stringstream source;
147 source << "#define ITK_MANUAL_INSTANTIATION" << std::endl;
149 << "#include <" << library_name << "_Export.h>"
151 for( auto i = before.begin( ); i != before.end( ); ++i )
152 source << std::endl << *i;
154 if( templates.size( ) > 0 )
156 for( auto i = includes.begin( ); i != includes.end( ); ++i )
157 source << "#include <" << *i << ">" << std::endl;
159 for( auto i = templates.begin( ); i != templates.end( ); ++i )
161 source << "#include <" << *i << ".h>" << std::endl;
162 source << "#include <" << *i << ".hxx>" << std::endl;
169 auto c_it = all_lines[ f_id ].begin( );
170 c_it != all_lines[ f_id ].end( );
174 << "template class " << library_name << "_EXPORT "
175 << *c_it << ";" << std::endl;
176 source << std::endl << "// eof" << std::endl;
177 std::stringstream source_file;
179 << source_prefix << "_" << f_id << ".cxx";
180 if( !( cpPlugins_bash::Write( source.str( ), source_file.str( ) ) ) )
182 std::cerr << "Error writing header" << std::endl;
191 // -------------------------------------------------------------------------
192 void AddDefinitions( TDefinitions& defs, const std::string& cmd )
194 std::vector< std::string > tokens;
195 cpPlugins_bash::Tokenize( tokens, cmd, "=;" );
196 for( unsigned int i = 1; i < tokens.size( ); ++i )
197 defs[ tokens[ 0 ] ].push_back( tokens[ i ] );
200 // -------------------------------------------------------------------------
201 void InitDefinitions( TDefinitions& defs )
203 AddDefinitions( defs, "integers=@cpPlugins_INTEGER_TYPES@" );
204 AddDefinitions( defs, "reals=@cpPlugins_REAL_TYPES@" );
205 AddDefinitions( defs, "colors=RGBPixel;RGBAPixel" );
206 AddDefinitions( defs, "vectors=CovariantVector;Point;SymmetricSecondRankTensor;Vector" );
207 AddDefinitions( defs, "tensors=DiffusionTensor3D" );
208 AddDefinitions( defs, "matrices=Matrix" );
209 AddDefinitions( defs, "process_dims=@cpPlugins_PROCESS_DIMENSIONS@" );
210 AddDefinitions( defs, "visual_dims=@cpPlugins_VISUAL_DIMENSIONS@" );
211 AddDefinitions( defs, "naturals=unsigned #integers#" );
212 AddDefinitions( defs, "pixels=#integers#;#naturals#;#reals#" );
215 // -------------------------------------------------------------------------
216 void Lines( TCommands& commands, const std::deque< std::string >& lines )
220 for( auto l = lines.begin( ); l != lines.end( ); ++l )
222 auto pos = l->find_first_not_of( " " );
223 char cmd = tolower( ( *l )[ pos ] );
224 commands[ cmd ].push_back(
225 l->substr( l->find_first_not_of( " ", pos + 1 ) )
231 // -------------------------------------------------------------------------
232 void ExpandDefinitions( TDefinitions& defs )
234 for( auto d = defs.begin( ); d != defs.end( ); ++d )
236 std::deque< std::string > q;
237 q.insert( q.end( ), d->second.begin( ), d->second.end( ) );
239 std::vector< std::string > n;
240 while( q.size( ) > 0 )
245 auto pos = v.find( "#" );
246 if( pos != std::string::npos )
248 auto epos = v.find( "#", pos + 1 );
249 auto tok = v.substr( pos, epos - pos + 1 );
250 auto id = tok.substr( 1, tok.size( ) - 2 );
251 auto rd = defs.find( id );
252 if( rd != defs.end( ) )
253 for( auto r = rd->second.begin( ); r != rd->second.end( ); ++r )
254 q.push_back( cpPlugins_bash::Replace( v, tok, *r ) );
265 // -------------------------------------------------------------------------
266 std::vector< std::string > Expand(
267 const std::vector< std::string >& commands, const TDefinitions& defs
270 std::vector< std::string > lines;
271 std::deque< std::string > q;
272 q.insert( q.end( ), commands.begin( ), commands.end( ) );
273 while( q.size( ) > 0 )
278 auto d_pos = v.find( "$" );
279 auto n_pos = v.find( "#" );
281 if( d_pos != std::string::npos )
283 auto e_pos = v.find( "$", d_pos + 1 );
284 auto tok = v.substr( d_pos, e_pos - d_pos + 1 );
285 std::vector< std::string > tokens;
286 cpPlugins_bash::Tokenize( tokens, tok, "$;" );
287 for( auto t = tokens.begin( ); t != tokens.end( ); ++t )
290 q.push_front( cpPlugins_bash::Replace( v, tok, "" ) );
292 q.push_front( cpPlugins_bash::Replace( v, tok, *t ) );
296 else if( n_pos != std::string::npos )
298 auto e_pos = v.find( "#", n_pos + 1 );
299 auto tok = v.substr( n_pos, e_pos - n_pos + 1 );
300 auto id = tok.substr( 1, tok.size( ) - 2 );
301 auto rd = defs.find( id );
302 if( rd != defs.end( ) )
303 for( auto r = rd->second.begin( ); r != rd->second.end( ); ++r )
304 q.push_front( cpPlugins_bash::Replace( v, tok, *r ) );
307 lines.push_back( v );