]> Creatis software - cpPlugins.git/blob - appli/bash/CreateInstances.cxx
...
[cpPlugins.git] / appli / bash / CreateInstances.cxx
1 #include <bash/Config.h>
2
3 // -------------------------------------------------------------------------
4 int main( int argc, char* argv[] )
5 {
6   // Get inputs
7   if( argc < 4 )
8   {
9     std::cerr
10       << "Usage: " << argv[ 0 ]
11       << " definitons_file library_name output_prefix"
12       << std::endl;
13     return( 1 );
14
15   } // fi
16   std::string definitions_filename = argv[ 1 ];
17   std::string library_name = argv[ 2 ];
18   std::string output_prefix = argv[ 3 ];
19   unsigned int number_of_sources = cpPlugins_CONFIG_NUMBER_OF_FILES;
20
21   // Read inputs
22   std::string definitions_buffer;
23   if( !( cpPlugins_bash::Read( definitions_buffer, definitions_filename ) ) )
24   {
25     std::cout
26       << argv[ 0 ]
27       <<  ": Error reading definitions file \"" << definitions_filename
28       << "\"" << std::endl;
29     return( 1 );
30
31   } // fi
32
33   // Put it in a line-by-line structure
34   TStrings definitions_lines;
35   cpPlugins_bash::Tokenize( definitions_lines, definitions_buffer, "\n" );
36
37   // Parse input file
38   TCommands commands;
39   cpPlugins_bash::Parse( commands, definitions_lines );
40
41   // Load pre-compiled definitions
42   cpPlugins_bash::LoadDefinitions( commands );
43
44   // Expand definitions
45   TCommands definitions;
46   cpPlugins_bash::ExpandDefinitions( definitions, commands );
47   definitions[ "_export_" ].clear( );
48   definitions[ "_export_" ].push_back( library_name + std::string( "_EXPORT" ) );
49
50   // Expand data
51   TStrings tfiles, cfiles, instances, minstances;
52   cpPlugins_bash::Expand( tfiles, definitions, commands, "tinclude" );
53   cpPlugins_bash::Expand( cfiles, definitions, commands, "cinclude" );
54   cpPlugins_bash::Expand( instances, definitions, commands, "instances" );
55   cpPlugins_bash::Expand( minstances, definitions, commands, "minstances" );
56
57   // Build all instances
58   TStrings all_instances;
59   for( auto iIt = instances.begin( ); iIt != instances.end( ); ++iIt )
60   {
61     std::stringstream str;
62     str << "template class " << library_name << "_EXPORT " << *iIt;
63     all_instances.push_back( str.str( ) );
64
65   } // rof
66   for( auto iIt = minstances.begin( ); iIt != minstances.end( ); ++iIt )
67   {
68     std::stringstream str;
69     str << "template " << *iIt;
70     all_instances.push_back( str.str( ) );
71
72   } // rof
73
74   // Prepare header file
75   std::stringstream header;
76   header
77     << "// Automaticaly generated file. Please do not modify." << std::endl
78     << "#ifndef __" << library_name << "__h__" << std::endl
79     << "#define __" << library_name << "__h__" << std::endl << std::endl;
80
81   auto hIt = commands.find( "header" );
82   if( hIt != commands.end( ) )
83   {
84     for( auto vIt = hIt->second.begin( ); vIt != hIt->second.end( ); ++vIt )
85       header << *vIt << std::endl;
86     header << std::endl;
87
88   } // fi
89
90   if( tfiles.size( ) > 0 )
91   {
92     for( auto tIt = tfiles.begin( ); tIt != tfiles.end( ); ++tIt )
93     {
94       TStrings toks;
95       cpPlugins_bash::Tokenize( toks, *tIt, ":|" );
96       if( toks.size( ) == 3 )
97         header
98           << "#include <" << toks[ 0 ] << "." << toks[ 1 ] << ">" << std::endl;
99
100     } // rof
101     header << std::endl;
102
103   } // fi
104   header << "#endif // __" << library_name << "__h__" << std::endl;
105
106   // Write header
107   std::stringstream header_filename;
108   header_filename << output_prefix << ".h";
109   if( !( cpPlugins_bash::Write( header.str( ), header_filename.str( ) ) ) )
110   {
111     std::cerr << "Error writing header file." << std::endl;
112     return( 1 );
113
114   } // fi
115
116   // Write source code
117   unsigned int instances_per_file =
118     ( unsigned int )(
119       std::floor( double( all_instances.size( ) ) / double( number_of_sources ) )
120       );
121   if( instances_per_file == 0 )
122     instances_per_file = 1;
123   std::vector< std::vector< std::string > > all_lines( 1 );
124   for( unsigned int c_id = 0; c_id < all_instances.size( ); ++c_id )
125   {
126     all_lines[ all_lines.size( ) - 1 ].push_back( all_instances[ c_id ] );
127     if( c_id % instances_per_file == instances_per_file - 1 )
128       all_lines.push_back( std::vector< std::string >( ) );
129
130   } // rof
131
132   // Paranoiac code
133   while( all_lines.size( ) > number_of_sources )
134   {
135     all_lines[ all_lines.size( ) - 2 ].insert(
136       all_lines[ all_lines.size( ) - 2 ].end( ),
137       all_lines[ all_lines.size( ) - 1 ].begin( ),
138       all_lines[ all_lines.size( ) - 1 ].end( )
139       );
140     all_lines.pop_back( );
141
142   } // elihw
143   while( all_lines.size( ) < number_of_sources )
144     all_lines.push_back( std::vector< std::string >( ) );
145
146   // Real write
147   for( unsigned int f_id = 0; f_id < all_lines.size( ); ++f_id )
148   {
149     std::stringstream source;
150     source
151       << "#include <" << library_name << "_Export.h>"
152       << std::endl;
153     source
154       << "#include <" << output_prefix << ".h>"
155       << std::endl << std::endl;
156     if( tfiles.size( ) > 0 )
157     {
158       for( auto tIt = tfiles.begin( ); tIt != tfiles.end( ); ++tIt )
159       {
160         TStrings toks;
161         cpPlugins_bash::Tokenize( toks, *tIt, ":|" );
162         if( toks.size( ) == 3 )
163           source << "#include <" << toks[ 0 ] << "." << toks[ 2 ] << ">" << std::endl;
164
165       } // rof
166       source << std::endl;
167
168     } // fi
169
170     if( cfiles.size( ) > 0 )
171     {
172       for( auto cIt = cfiles.begin( ); cIt != cfiles.end( ); ++cIt )
173         source << "#include <" << *cIt << ">" << std::endl;
174       source << std::endl;
175
176     } // fi
177
178     for(
179       auto c_it = all_lines[ f_id ].begin( );
180       c_it != all_lines[ f_id ].end( );
181       ++c_it
182       )
183       source << *c_it << ";" << std::endl;
184     source << std::endl << "// eof" << std::endl;
185     std::stringstream source_file;
186     source_file
187       << output_prefix << "_" << f_id << ".cxx";
188     if( !( cpPlugins_bash::Write( source.str( ), source_file.str( ) ) ) )
189     {
190       std::cerr << "Error writing source code." << std::endl;
191       return( 1 );
192
193     } // fi
194
195   } // rof
196   return( 0 );
197 }
198
199 // eof - $RCSfile$