-#include <algorithm>
-#include <cstring>
-#include <iostream>
-#include <iterator>
-#include <fstream>
+#include <cpPlugins_Config.h>
#include <map>
-#include <set>
-#include <sstream>
-#include <streambuf>
-#include <string>
#include <vector>
+#include <sstream>
// -------------------------------------------------------------------------
-typedef std::set< std::string > TSet;
-typedef std::map< std::string, TSet > TInstances;
-typedef std::vector< std::string > TVector;
+typedef std::vector< std::string > TLines;
+typedef std::map< char, TLines > TParsedLines;
+typedef std::map< std::string, TLines > TVariables;
// -------------------------------------------------------------------------
-TVector Tokenize( const std::string& str, const std::string& delims );
-TSet Combine( const TSet& X, const TSet& Y );
-void Replace(
- std::string& str, const std::string& sub, const std::string& nsub
+bool ReadFile( TParsedLines& lines, const std::string& fname );
+void ExpandGroups( TLines& res, const TLines& lines );
+void ExpandDefinitions(
+ TLines& res, const TLines& lines, const TVariables& vars
+ );
+void PrintLines(
+ const std::string& prefix, const std::string& suffix,
+ const TLines& lines, std::ostream& out
);
// -------------------------------------------------------------------------
{
std::cerr
<< "Usage: " << argv[ 0 ]
- << " input_definitions dir library_name header_filename"
+ << " input_definitions library_name header_file source_file"
<< std::endl;
return( 1 );
} // fi
- std::string input_definitions_file_name = argv[ 1 ];
- std::string dir = argv[ 2 ];
- std::string library_name = argv[ 3 ];
- std::string head_fname = argv[ 4 ];
-
- // Load file into a buffer
- std::ifstream file_stream( input_definitions_file_name.c_str( ) );
- if( !file_stream )
+ std::string input_definitions_fname = argv[ 1 ];
+ std::string library_name = argv[ 2 ];
+ std::string header_file_fname = argv[ 3 ];
+ std::string source_file_fname = argv[ 4 ];
+
+ // Read file and simple parse it
+ TParsedLines lines;
+ if( !ReadFile( lines, input_definitions_fname ) )
{
std::cerr
<< "Error opening file: \""
- << input_definitions_file_name << "\""
+ << input_definitions_fname << "\""
<< std::endl;
return( 1 );
} // fi
- std::string buf;
- file_stream.seekg( 0, std::ios::end );
- buf.reserve( file_stream.tellg( ) );
- file_stream.seekg( 0, std::ios::beg );
- buf.assign(
- ( std::istreambuf_iterator< char >( file_stream ) ),
- std::istreambuf_iterator< char >( )
- );
- file_stream.close( );
- std::istringstream input_str( buf );
-
- // Process file
- std::string line;
- TVector incl, first_incl;
- TInstances instances;
- TVector classes;
- while( std::getline( input_str, line ) )
- {
- if( line[ 0 ] == 'f' )
- {
- first_incl.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) );
- }
- else if( line[ 0 ] == 'i' )
- {
- incl.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) );
- }
- else if( line[ 0 ] == 'c' )
- {
- classes.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) );
- }
- else if( line[ 0 ] == 'a' )
- {
- TVector tokens = Tokenize( line, "=" );
-
- // Get argument name
- TVector arg_tokens = Tokenize( tokens[ 0 ], " " );
- std::string arg = arg_tokens[ 0 ];
- unsigned int i = 0;
- while( arg[ 0 ] != '#' && i < arg_tokens.size( ) )
- arg = arg_tokens[ ++i ];
-
- // Get values
- TVector values_tokens = Tokenize( tokens[ 1 ], ";" );
- for( auto t = values_tokens.begin( ); t != values_tokens.end( ); ++t )
- {
- std::string value = t->substr( t->find_first_not_of( ' ' ) );
- unsigned int value_len = value.size( );
- while( value[ value_len - 1 ] == ' ' && value_len > 0 )
- value_len--;
- value = value.substr( 0, value_len );
- if( value == "#integers" )
- {
- instances[ arg ].insert( "char" );
- instances[ arg ].insert( "short" );
- instances[ arg ].insert( "int" );
- instances[ arg ].insert( "long" );
- instances[ arg ].insert( "unsigned char" );
- instances[ arg ].insert( "unsigned short" );
- instances[ arg ].insert( "unsigned int" );
- instances[ arg ].insert( "unsigned long" );
- }
- else if( value == "#integers_ptr" )
- {
- instances[ arg ].insert( "char*" );
- instances[ arg ].insert( "short*" );
- instances[ arg ].insert( "int*" );
- instances[ arg ].insert( "long*" );
- instances[ arg ].insert( "unsigned char*" );
- instances[ arg ].insert( "unsigned short*" );
- instances[ arg ].insert( "unsigned int*" );
- instances[ arg ].insert( "unsigned long*" );
- }
- else if( value == "#floats" )
- {
- instances[ arg ].insert( "double" );
- instances[ arg ].insert( "float" );
- }
- else if( value == "#floats_ptr" )
- {
- instances[ arg ].insert( "double*" );
- instances[ arg ].insert( "float*" );
- }
- else if( value == "#all_dims" )
- {
- instances[ arg ].insert( "1" );
- instances[ arg ].insert( "2" );
- instances[ arg ].insert( "3" );
- instances[ arg ].insert( "4" );
- }
- else if( value == "#all_visual_dims" )
- {
- instances[ arg ].insert( "2" );
- instances[ arg ].insert( "3" );
- }
- else
- instances[ arg ].insert( value );
-
- } // rof
-
- } // fi
-
- } // elihw
-
- // Span all possible types
- TVector all_real_classes;
- for( auto clsIt = classes.begin( ); clsIt != classes.end( ); ++clsIt )
+ // Expand definitions
+ TVariables vars;
+ for( auto dIt = lines[ 'd' ].begin( ); dIt != lines[ 'd' ].end( ); ++dIt )
{
- // Extract types
- std::string name = clsIt->substr( clsIt->find_first_not_of( " " ) );
- std::string tok = name;
- auto sharpPos = tok.find_first_of( "#" );
- TInstances li;
- while( sharpPos != std::string::npos )
- {
- tok = tok.substr( sharpPos );
- auto spacePos = tok.find_first_of( " " );
- auto arg = tok.substr( 0, spacePos );
- auto aIt = instances.find( arg );
- if( aIt != instances.end( ) )
- li[ arg ] = aIt->second;
- tok = tok.substr( spacePos );
- sharpPos = tok.find_first_of( "#" );
-
- } // eliwh
- if( li.size( ) > 0 )
- {
- // Combine types
- TSet combs;
- if( li.size( ) > 1 )
- {
- auto iIt = li.begin( );
- auto jIt = iIt;
- jIt++;
- for( ; jIt != li.end( ); ++iIt, ++jIt )
- {
- if( iIt == li.begin( ) )
- combs = Combine( iIt->second, jIt->second );
- else
- combs = Combine( combs, jIt->second );
-
- } // rof
- }
- else
- combs = li.begin( )->second;
-
- // Write instantiations
- for( auto combIt = combs.begin( ); combIt != combs.end( ); ++combIt )
- {
- char* buffer = new char[ combIt->size( ) + 1 ];
- std::strcpy( buffer, combIt->c_str( ) );
- buffer[ combIt->size( ) ] = '\0';
- char* tok = std::strtok( buffer, "#" );
- std::map< std::string, std::string > real_instance;
- for( auto lIt = li.begin( ); lIt != li.end( ); ++lIt )
- {
- real_instance[ lIt->first ] = std::string( tok );
- tok = std::strtok( NULL, "#" );
+ TLines tokens;
+ cpPlugins::TokenizeString( tokens, *dIt, "=;" );
+ auto tIt = tokens.begin( );
+ auto vName = *tIt;
+ tIt++;
+ for( ; tIt != tokens.end( ); ++tIt )
+ vars[ vName ].push_back( *tIt );
+
+ TLines res;
+ ExpandDefinitions( res, vars[ vName ], vars );
+ vars[ vName ] = res;
- } // rof
- delete buffer;
+ } // rof
- std::string real_name = name;
- auto riIt = real_instance.begin( );
- for( ; riIt != real_instance.end( ); ++riIt )
- Replace( real_name, riIt->first, riIt->second );
- all_real_classes.push_back( real_name );
+ // Expand groups
+ TLines f_includes_groups, includes_groups, templates_groups, classes_groups;
+ ExpandGroups( f_includes_groups, lines[ 'f' ] );
+ ExpandGroups( includes_groups, lines[ 'i' ] );
+ ExpandGroups( templates_groups, lines[ 't' ] );
+ ExpandGroups( classes_groups, lines[ 'c' ] );
+
+ // Expand definitions
+ TLines f_includes_list, includes_list, templates_list, classes_list;
+ ExpandDefinitions( f_includes_list, f_includes_groups, vars );
+ ExpandDefinitions( includes_list, includes_groups, vars );
+ ExpandDefinitions( templates_list, templates_groups, vars );
+ ExpandDefinitions( classes_list, classes_groups, vars );
+
+ // Write header file
+ std::ofstream header_file( header_file_fname.c_str( ) );
+ if( !header_file )
+ {
+ std::cerr
+ << "Error opening \"" << header_file_fname
+ << "\" for writing." << std::endl;
+ return( 1 );
- } // rof
- }
- else
- all_real_classes.push_back( name );
+ } // fi
- } // rof
+ // Print header
+ header_file
+ << "#ifndef __" << library_name << "__H__" << std::endl
+ << "#define __" << library_name << "__H__" << std::endl<< std::endl
+ << "#include <cpPlugins_Config.h>" << std::endl
+ << "#include <" << library_name << "_Export.h>" << std::endl << std::endl;
+ PrintLines( "", "", lines[ 'b' ], header_file );
+ header_file << std::endl;
+ PrintLines( "#include <", ">", f_includes_list, header_file );
+ header_file
+ << "#ifdef " << library_name << "_EXPORTS" << std::endl
+ << "# define " << library_name << "_PREFIX template class "
+ << library_name << "_EXPORT" << std::endl
+ << "#else // " << library_name << "_EXPORTS" << std::endl
+ << "# define " << library_name
+ << "_PREFIX extern template class" << std::endl
+ << "#endif // "
+ << library_name << "_EXPORTS" << std::endl << std::endl;
+ PrintLines( "#include <", ">", includes_list, header_file );
+ PrintLines( "#include <", ">", templates_list, header_file );
+ header_file
+ << std::endl << "#ifdef " << library_name << "_EXPORTS" << std::endl;
+ PrintLines( "#include <", "xx>", templates_list, header_file );
+ header_file
+ << "#endif // " << library_name << "_EXPORTS" << std::endl << std::endl;
+ PrintLines(
+ library_name + std::string( "_PREFIX " ), ";", classes_list, header_file
+ );
+ header_file
+ << std::endl << "#endif // __" << library_name << "__H__" << std::endl;
+ header_file.close( );
- // Write files
- std::ofstream out_str( head_fname.c_str( ) );
- if( !out_str )
+ // Write source file
+ std::ofstream source_file( source_file_fname );
+ if( !source_file )
{
- std::cerr << "Error opening file \"" << head_fname << "\"" << std::endl;
+ std::cerr
+ << "Error opening \"" << header_file_fname << "\" for writing." << std::endl;
return( 1 );
} // fi
-
- out_str << "#ifndef __" << dir << "__" << library_name << "__H__" << std::endl;
- out_str << "#define __" << dir << "__" << library_name << "__H__" << std::endl << std::endl;
- out_str << "#include <" << dir << "/" << library_name << "_Export.h>" << std::endl;
-
- // First incl
- for( auto inclIt = first_incl.begin( ); inclIt != first_incl.end( ); ++inclIt )
- out_str
- << "#include <" << *inclIt << ">" << std::endl;
- out_str << std::endl;
-
- std::string base_name = dir + std::string( "_" ) + library_name;
- out_str
- << std::endl
- << "#ifdef " << base_name << "_EXPORTS" << std::endl
- << "# undef ITK_MANUAL_INSTANTIATION" << std::endl
- << "# define " << base_name << "_PREFIX template class " << base_name << "_EXPORT" << std::endl
- << "#else" << std::endl
- << "# define ITK_MANUAL_INSTANTIATION" << std::endl
- << "# define " << base_name << "_PREFIX extern template class" << std::endl
- << "#endif" << std::endl << std::endl;
-
- // Incl
- for( auto inclIt = incl.begin( ); inclIt != incl.end( ); ++inclIt )
- out_str
- << "#include <" << *inclIt << ">" << std::endl;
- out_str << std::endl;
-
- // All classes
- for( auto clsIt = all_real_classes.begin( ); clsIt != all_real_classes.end( ); ++clsIt )
- out_str
- << base_name << "_PREFIX " << *clsIt << ";" << std::endl;
- out_str << std::endl;
-
- out_str << "#endif // __" << dir << "__" << library_name << "__H__" << std::endl;
- out_str << std::endl << "// eof" << std::endl;
-
- out_str.close( );
+ source_file
+ << "#include \"" << header_file_fname << "\"" << std::endl;
+ source_file.close( );
return( 0 );
}
// -------------------------------------------------------------------------
-TVector Tokenize( const std::string& str, const std::string& delims )
+bool ReadFile( TParsedLines& lines, const std::string& fname )
{
- TVector tokens;
- if( str.size( ) > 0 )
+ std::string buffer;
+ if( cpPlugins::ReadFileIntoString( buffer, fname ) )
{
- char* buffer = new char[ str.size( ) + 1 ];
- std::strcpy( buffer, str.c_str( ) );
- buffer[ str.size( ) ] = '\0';
- char* it = std::strtok( buffer, delims.c_str( ) );
- while( it != NULL )
+ std::istringstream input_stream( buffer );
+
+ // Read line by line
+ std::string line;
+ while( std::getline( input_stream, line ) )
{
- tokens.push_back( std::string( it ) );
- it = std::strtok( NULL, delims.c_str( ) );
+ auto cmd_pos = line.end( );
+ auto arg_pos = line.end( );
+ auto lIt = line.begin( );
+ while( lIt != line.end( ) )
+ {
+ if( !cpPlugins::IsBlank( *lIt ) )
+ {
+ if( cmd_pos == line.end( ) )
+ {
+ cmd_pos = lIt;
+ ++lIt;
+ }
+ else if( arg_pos == line.end( ) )
+ {
+ arg_pos = lIt;
+ lIt = line.end( );
+
+ } // fi
+ }
+ else
+ ++lIt;
- } // elihw
- delete buffer;
+ } // elihw
+ char cmd = *cmd_pos;
+ std::string arg;
+ arg.resize( line.end( ) - arg_pos );
+ std::copy( arg_pos, line.end( ), arg.begin( ) );
+ lines[ cmd ].push_back( arg );
- } // fi
- return( tokens );
+ } // elihw
+ return( true );
+ }
+ else
+ return( false );
}
// -------------------------------------------------------------------------
-TSet Combine( const TSet& X, const TSet& Y )
+void ExpandGroups( TLines& res, const TLines& lines )
{
- TSet Z;
- for( auto xIt = X.begin( ); xIt != X.end( ); ++xIt )
+ for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
{
- for( auto yIt = Y.begin( ); yIt != Y.end( ); ++yIt )
+ auto b_pos = lIt->find( "@{" );
+ if( b_pos != std::string::npos )
{
- std::stringstream val;
- val << *xIt << "#" << *yIt;
- Z.insert( val.str( ) );
+ unsigned int braces_count = 1;
+ auto e_pos = b_pos;
+ e_pos += 2;
+ while( braces_count != 0 && e_pos < lIt->size( ) )
+ {
+ auto v = ( *lIt )[ e_pos ];
+ braces_count += ( v == '{' )? 1: ( ( v == '}' )? -1: 0 );
+ e_pos++;
- } // rof
+ } // elihw
+ if( braces_count == 0 )
+ {
+ auto replace = lIt->substr( b_pos, e_pos - b_pos );
+ auto expansion = replace.substr( 2, replace.size( ) - 3 );
+ TLines tokens;
+ cpPlugins::TokenizeString( tokens, expansion, ";" );
+ for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
+ *tIt = cpPlugins::ReplaceString( *lIt, replace, *tIt );
+ ExpandGroups( res, tokens );
+
+ } // fi
+ }
+ else
+ res.push_back( *lIt );
} // rof
- return( Z );
}
// -------------------------------------------------------------------------
-void Replace(
- std::string& str, const std::string& sub, const std::string& nsub
+void ExpandDefinitions(
+ TLines& res, const TLines& lines, const TVariables& vars
)
{
- size_t index = 0;
- while( true )
+ std::string seps = " ,;:{}[]()\"$&<>*.";
+
+ for( auto lIt = lines.begin( ); lIt != lines.end( ); ++lIt )
{
- index = str.find( sub, index );
- if( index == std::string::npos ) break;
- str.replace( index, sub.size( ), nsub );
- index += sub.size( );
+ auto b_pos = lIt->find( "#" );
+ if( b_pos != std::string::npos )
+ {
+ TLines tokens;
+ cpPlugins::TokenizeString( tokens, lIt->substr( b_pos ), seps );
+ std::string cmd = tokens[ 0 ];
+ auto vIt = vars.find( cmd );
+ if( vIt != vars.end( ) )
+ {
+ if( vIt->second.size( ) > 0 )
+ {
+ TLines new_res;
+ for(
+ auto wIt = vIt->second.begin( ); wIt != vIt->second.end( ); ++wIt
+ )
+ new_res.push_back( cpPlugins::ReplaceString( *lIt, cmd, *wIt ) );
+ ExpandDefinitions( res, new_res, vars );
+
+ } // fi
- } // elihw
+ } // fi
+ }
+ else
+ res.push_back(
+ cpPlugins::ReplaceString(
+ cpPlugins::ReplaceString( *lIt, "{", "" ), "}", ""
+ )
+ );
+
+ } // rof
+}
+
+// -------------------------------------------------------------------------
+void PrintLines(
+ const std::string& prefix, const std::string& suffix,
+ const TLines& lines, std::ostream& out
+ )
+{
+ for( auto i = lines.begin( ); i != lines.end( ); ++i )
+ out << prefix << *i << suffix << std::endl;
}
// eof - $RCSfile$