]> Creatis software - cpPlugins.git/blobdiff - appli/bash/BuildInstances.cxx.in
Architecture updated.
[cpPlugins.git] / appli / bash / BuildInstances.cxx.in
diff --git a/appli/bash/BuildInstances.cxx.in b/appli/bash/BuildInstances.cxx.in
new file mode 100644 (file)
index 0000000..79cbcf2
--- /dev/null
@@ -0,0 +1,312 @@
+#include <cmath>
+#include <deque>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <vector>
+#include <appli/bash/Utility.h>
+
+// -------------------------------------------------------------------------
+typedef std::map< char, std::vector< std::string > >        TCommands;
+typedef std::map< std::string, std::vector< std::string > > TDefinitions;
+
+// -------------------------------------------------------------------------
+void AddDefinitions( TDefinitions& defs, const std::string& cmd );
+void InitDefinitions( TDefinitions& defs );
+void Lines( TCommands& commands, const std::deque< std::string >& lines );
+void ExpandDefinitions( TDefinitions& defs );
+std::vector< std::string > Expand(
+  const std::vector< std::string >& commands, const TDefinitions& defs
+  );
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+  // Get parameters from input
+  if( argc < 5 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ]
+      << " definitions library_name source_prefix number_of_files" << std::endl;
+    return( 1 );
+
+  } // fi
+  std::string input_definitions = argv[ 1 ];
+  std::string library_name = argv[ 2 ];
+  std::string source_prefix = argv[ 3 ];
+  std::string header_file = source_prefix + std::string( ".h" );
+  std::stringstream nfiles_str( argv[ 4 ] );
+  unsigned int number_of_files;
+  nfiles_str >> number_of_files;
+
+  // Read input instances
+  std::string buffer;
+  if( !cpPlugins_bash::Read( buffer, input_definitions ) )
+  {
+    std::cerr
+      << "Error reading input instances from \""
+      << input_definitions << "\""
+      << std::endl;
+    return( 1 );
+
+  } // fi
+
+  // Put it in a line-by-line structure
+  std::deque< std::string > lines;
+  cpPlugins_bash::Tokenize( lines, buffer, "\n" );
+
+  // Parse commands
+  TCommands commands;
+  Lines( commands, lines );
+
+  // Init definitions
+  TDefinitions defs;
+  InitDefinitions( defs );
+  auto dIt = commands.find( 'd' );
+  if( dIt != commands.end( ) )
+  {
+    for( auto vIt = dIt->second.begin( ); vIt != dIt->second.end( ); ++vIt )
+      AddDefinitions( defs, *vIt );
+
+  } // fi
+
+  // Expand definitions
+  ExpandDefinitions( defs );
+
+  // Expand code
+  std::vector< std::string > before;
+  auto bIt = commands.find( 'b' );
+  if( bIt != commands.end( ) )
+    before = bIt->second;
+  auto templates = Expand( commands[ 't' ], defs );
+  auto includes = Expand( commands[ 'i' ], defs );
+  auto classes = Expand( commands[ 'c' ], defs );
+
+  // Write header file
+  std::stringstream header;
+  header
+    << "#ifndef __" << library_name << "__h__" << std::endl
+    << "#define __" << library_name << "__h__" << std::endl << std::endl
+    << "#define ITK_MANUAL_INSTANTIATION" << std::endl;
+  for( auto i = before.begin( ); i != before.end( ); ++i )
+    header << std::endl << *i;
+  header << std::endl;
+  for( auto i = includes.begin( ); i != includes.end( ); ++i )
+    header << "#include <" << *i << ">" << std::endl;
+  for( auto i = templates.begin( ); i != templates.end( ); ++i )
+    header << "#include <" << *i << ".h>" << std::endl;
+  header << std::endl;
+  for( auto i = classes.begin( ); i != classes.end( ); ++i )
+    header
+      << "extern template class " << *i << ";" << std::endl;
+  header
+    << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
+  if( !( cpPlugins_bash::Write( header.str( ), header_file ) ) )
+  {
+    std::cerr << "Error writing header" << std::endl;
+    return( 1 );
+
+  } // fi
+
+  // Write source code
+  unsigned int classes_per_file =
+    ( unsigned int )(
+      std::floor( double( classes.size( ) ) / double( number_of_files ) )
+      );
+  if( classes_per_file == 0 )
+    classes_per_file = 1;
+  std::vector< std::vector< std::string > > all_lines( 1 );
+  for( unsigned int c_id = 0; c_id < classes.size( ); ++c_id )
+  {
+    all_lines[ all_lines.size( ) - 1 ].push_back( classes[ c_id ] );
+    if( c_id % classes_per_file == classes_per_file - 1 )
+      all_lines.push_back( std::vector< std::string >( ) );
+
+  } // rof
+
+  // Paranoiac code
+  while( all_lines.size( ) > number_of_files )
+  {
+    all_lines[ all_lines.size( ) - 2 ].insert(
+      all_lines[ all_lines.size( ) - 2 ].end( ),
+      all_lines[ all_lines.size( ) - 1 ].begin( ),
+      all_lines[ all_lines.size( ) - 1 ].end( )
+      );
+    all_lines.pop_back( );
+
+  } // elihw
+  while( all_lines.size( ) < number_of_files )
+    all_lines.push_back( std::vector< std::string >( ) );
+
+  // Real write
+  for( unsigned int f_id = 0; f_id < all_lines.size( ); ++f_id )
+  {
+    std::stringstream source;
+    source << "#define ITK_MANUAL_INSTANTIATION" << std::endl;
+    source
+      << "#include <" << library_name << "_Export.h>"
+      << std::endl;
+    for( auto i = before.begin( ); i != before.end( ); ++i )
+      source << std::endl << *i;
+    source << std::endl;
+    if( templates.size( ) > 0 )
+    {
+      for( auto i = includes.begin( ); i != includes.end( ); ++i )
+        source << "#include <" << *i << ">" << std::endl;
+
+      for( auto i = templates.begin( ); i != templates.end( ); ++i )
+      {
+        source << "#include <" << *i << ".h>" << std::endl;
+        source << "#include <" << *i << ".hxx>" << std::endl;
+
+      } // rof
+      source << std::endl;
+
+    } // fi
+    for(
+      auto c_it = all_lines[ f_id ].begin( );
+      c_it != all_lines[ f_id ].end( );
+      ++c_it
+      )
+      source
+        << "template class " << library_name << "_EXPORT "
+        << *c_it << ";" << std::endl;
+    source << std::endl << "// eof" << std::endl;
+    std::stringstream source_file;
+    source_file
+      << source_prefix << "_" << f_id << ".cxx";
+    if( !( cpPlugins_bash::Write( source.str( ), source_file.str( ) ) ) )
+    {
+      std::cerr << "Error writing header" << std::endl;
+      return( 1 );
+
+    } // fi
+
+  } // rof
+  return( 0 );
+}
+
+// -------------------------------------------------------------------------
+void AddDefinitions( TDefinitions& defs, const std::string& cmd )
+{
+  std::vector< std::string > tokens;
+  cpPlugins_bash::Tokenize( tokens, cmd, "=;" );
+  for( unsigned int i = 1; i < tokens.size( ); ++i )
+    defs[ tokens[ 0 ] ].push_back( tokens[ i ] );
+}
+
+// -------------------------------------------------------------------------
+void InitDefinitions( TDefinitions& defs )
+{
+  AddDefinitions( defs, "integers=@cpPlugins_INTEGER_TYPES@" );
+  AddDefinitions( defs, "reals=@cpPlugins_REAL_TYPES@" );
+  AddDefinitions( defs, "colors=RGBPixel;RGBAPixel" );
+  AddDefinitions( defs, "vectors=CovariantVector;Point;SymmetricSecondRankTensor;Vector" );
+  AddDefinitions( defs, "tensors=DiffusionTensor3D" );
+  AddDefinitions( defs, "matrices=Matrix" );
+  AddDefinitions( defs, "process_dims=@cpPlugins_PROCESS_DIMENSIONS@" );
+  AddDefinitions( defs, "visual_dims=@cpPlugins_VISUAL_DIMENSIONS@" );
+  AddDefinitions( defs, "naturals=unsigned #integers#" );
+  AddDefinitions( defs, "pixels=#integers#;#naturals#;#reals#" );
+}
+
+// -------------------------------------------------------------------------
+void Lines( TCommands& commands, const std::deque< std::string >& lines )
+{
+  std::string buffer;
+
+  for( auto l = lines.begin( ); l != lines.end( ); ++l )
+  {
+    auto pos = l->find_first_not_of( " " );
+    char cmd = std::tolower( ( *l )[ pos ] );
+    commands[ cmd ].push_back(
+      l->substr( l->find_first_not_of( " ", pos + 1 ) )
+      );
+
+  } // elihw
+}
+
+// -------------------------------------------------------------------------
+void ExpandDefinitions( TDefinitions& defs )
+{
+  for( auto d = defs.begin( ); d != defs.end( ); ++d )
+  {
+    std::deque< std::string > q;
+    q.insert( q.end( ), d->second.begin( ), d->second.end( ) );
+
+    std::vector< std::string > n;
+    while( q.size( ) > 0 )
+    {
+      auto v = q.front( );
+      q.pop_front( );
+
+      auto pos = v.find( "#" );
+      if( pos != std::string::npos )
+      {
+        auto epos = v.find( "#", pos + 1 );
+        auto tok = v.substr( pos, epos - pos + 1 );
+        auto id = tok.substr( 1, tok.size( ) - 2 );
+        auto rd = defs.find( id );
+        if( rd != defs.end( ) )
+          for( auto r = rd->second.begin( ); r != rd->second.end( ); ++r )
+            q.push_back( cpPlugins_bash::Replace( v, tok, *r ) );
+      }
+      else
+        n.push_back( v );
+      
+    } // elihw
+    d->second = n;
+
+  } // rof
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string > Expand(
+  const std::vector< std::string >& commands, const TDefinitions& defs
+  )
+{
+  std::vector< std::string > lines;
+  std::deque< std::string > q;
+  q.insert( q.end( ), commands.begin( ), commands.end( ) );
+  while( q.size( ) > 0 )
+  {
+    auto v = q.front( );
+    q.pop_front( );
+
+    auto d_pos = v.find( "$" );
+    auto n_pos = v.find( "#" );
+
+    if( d_pos != std::string::npos )
+    {
+      auto e_pos = v.find( "$", d_pos + 1 );
+      auto tok = v.substr( d_pos, e_pos - d_pos + 1 );
+      std::vector< std::string > tokens;
+      cpPlugins_bash::Tokenize( tokens, tok, "$;" );
+      for( auto t = tokens.begin( ); t != tokens.end( ); ++t )
+      {
+        if( *t == " ")
+          q.push_front( cpPlugins_bash::Replace( v, tok, "" ) );
+        else
+          q.push_front( cpPlugins_bash::Replace( v, tok, *t ) );
+
+      } // rof
+    }
+    else if( n_pos != std::string::npos )
+    {
+      auto e_pos = v.find( "#", n_pos + 1 );
+      auto tok = v.substr( n_pos, e_pos - n_pos + 1 );
+      auto id = tok.substr( 1, tok.size( ) - 2 );
+      auto rd = defs.find( id );
+      if( rd != defs.end( ) )
+        for( auto r = rd->second.begin( ); r != rd->second.end( ); ++r )
+          q.push_front( cpPlugins_bash::Replace( v, tok, *r ) );
+    }
+    else
+      lines.push_back( v );
+
+  } // elihw
+
+  return( lines );
+}
+
+// eof - $RCSfile$