2011-10-14 02:41:56 +08:00
/* ----------------------------------------------------------------------------
* GTSAM Copyright 2010 , Georgia Tech Research Corporation ,
* Atlanta , Georgia 30332 - 0415
* All Rights Reserved
* Authors : Frank Dellaert , et al . ( see THANKS for the full author list )
* See LICENSE for the license information
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
2011-10-14 11:23:14 +08:00
* @ file Module . ccp
* @ author Frank Dellaert
2012-03-30 13:34:23 +08:00
* @ author Alex Cunningham
* @ author Andrew Melim
2011-10-14 02:41:56 +08:00
* */
2011-10-14 12:43:06 +08:00
# include "Module.h"
2012-01-16 05:42:41 +08:00
# include "FileWriter.h"
2011-10-14 12:43:06 +08:00
# include "utilities.h"
2011-12-16 03:39:11 +08:00
# include "spirit_actors.h"
2011-10-14 02:41:56 +08:00
//#define BOOST_SPIRIT_DEBUG
2011-12-02 06:06:03 +08:00
# include <boost/spirit/include/classic_confix.hpp>
2011-12-09 04:51:17 +08:00
# include <boost/spirit/include/classic_clear_actor.hpp>
2012-07-05 22:05:00 +08:00
# include <boost/lambda/bind.hpp>
# include <boost/lambda/lambda.hpp>
2011-10-14 02:41:56 +08:00
# include <boost/foreach.hpp>
2012-05-24 05:23:27 +08:00
# include <boost/filesystem.hpp>
2012-06-27 02:52:27 +08:00
# include <boost/lexical_cast.hpp>
2011-10-14 02:41:56 +08:00
2011-10-14 12:43:06 +08:00
# include <iostream>
2012-06-27 02:52:27 +08:00
# include <algorithm>
2011-10-14 02:41:56 +08:00
using namespace std ;
2011-12-03 00:43:15 +08:00
using namespace wrap ;
2011-10-14 02:41:56 +08:00
using namespace BOOST_SPIRIT_CLASSIC_NS ;
2012-07-05 22:05:00 +08:00
namespace bl = boost : : lambda ;
2012-05-24 05:23:27 +08:00
namespace fs = boost : : filesystem ;
2011-10-14 02:41:56 +08:00
typedef rule < BOOST_SPIRIT_CLASSIC_NS : : phrase_scanner_t > Rule ;
/* ************************************************************************* */
// We parse an interface file into a Module object.
// The grammar is defined using the boost/spirit combinatorial parser.
// For example, str_p("const") parses the string "const", and the >>
// operator creates a sequence parser. The grammar below, composed of rules
// and with start rule [class_p], doubles as the specs for our interface files.
/* ************************************************************************* */
Module : : Module ( const string & interfacePath ,
2011-12-07 11:05:37 +08:00
const string & moduleName , bool enable_verbose ) : name ( moduleName ) , verbose ( enable_verbose )
2011-10-14 02:41:56 +08:00
{
// these variables will be imperatively updated to gradually build [cls]
// The one with postfix 0 are used to reset the variables after parse.
2012-07-05 22:05:00 +08:00
string methodName , methodName0 ;
bool isConst , isConst0 = false ;
2011-12-02 10:32:18 +08:00
ReturnValue retVal0 , retVal ;
2011-10-14 02:41:56 +08:00
Argument arg0 , arg ;
ArgumentList args0 , args ;
2012-06-27 02:52:27 +08:00
vector < string > arg_dup ; ///keep track of duplicates
2011-12-07 11:05:37 +08:00
Constructor constructor0 ( enable_verbose ) , constructor ( enable_verbose ) ;
2012-07-05 22:04:36 +08:00
Deconstructor deconstructor0 ( enable_verbose ) , deconstructor ( enable_verbose ) ;
2012-07-05 22:05:00 +08:00
//Method method0(enable_verbose), method(enable_verbose);
2011-12-07 11:05:37 +08:00
StaticMethod static_method0 ( enable_verbose ) , static_method ( enable_verbose ) ;
Class cls0 ( enable_verbose ) , cls ( enable_verbose ) ;
2011-12-16 03:39:11 +08:00
vector < string > namespaces , /// current namespace tag
namespace_includes , /// current set of includes
2012-05-05 03:14:58 +08:00
namespaces_return , /// namespace for current return type
using_namespace_current ; /// All namespaces from "using" declarations
2011-12-16 03:39:11 +08:00
string include_path = " " ;
2011-12-16 05:23:20 +08:00
string class_name = " " ;
2011-12-16 03:39:11 +08:00
const string null_str = " " ;
2011-10-14 02:41:56 +08:00
//----------------------------------------------------------------------------
// Grammar with actions that build the Class object. Actions are
// defined within the square brackets [] and are executed whenever a
// rule is successfully parsed. Define BOOST_SPIRIT_DEBUG to debug.
2011-12-09 04:50:38 +08:00
// The grammar is allows a very restricted C++ header
2012-01-29 03:44:33 +08:00
// lexeme_d turns off white space skipping
// http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html
2011-10-14 02:41:56 +08:00
// ----------------------------------------------------------------------------
2011-12-09 04:50:38 +08:00
Rule comments_p = comment_p ( " /* " , " */ " ) | comment_p ( " // " , eol_p ) ;
2011-12-02 06:06:03 +08:00
2011-12-07 11:05:37 +08:00
Rule basisType_p =
2012-05-05 02:50:36 +08:00
( str_p ( " string " ) | " bool " | " size_t " | " int " | " double " | " char " | " unsigned char " ) ;
2011-12-07 11:05:37 +08:00
2011-12-09 04:51:17 +08:00
Rule keywords_p =
( str_p ( " const " ) | " static " | " namespace " | basisType_p ) ;
2011-12-07 11:05:37 +08:00
Rule eigenType_p =
( str_p ( " Vector " ) | " Matrix " ) ;
2012-07-08 20:27:39 +08:00
Rule className_p = ( lexeme_d [ upper_p > > * ( alnum_p | ' _ ' ) ] - eigenType_p - keywords_p ) ;
2011-10-14 02:41:56 +08:00
2011-12-09 04:51:17 +08:00
Rule namespace_name_p = lexeme_d [ lower_p > > * ( alnum_p | ' _ ' ) ] - keywords_p ;
2011-12-09 04:51:15 +08:00
Rule namespace_arg_p = namespace_name_p [ push_back_a ( arg . namespaces ) ] > > str_p ( " :: " ) ;
2011-12-07 11:05:37 +08:00
Rule argEigenType_p =
2011-12-07 11:05:33 +08:00
eigenType_p [ assign_a ( arg . type ) ] > >
! ch_p ( ' * ' ) [ assign_a ( arg . is_ptr , true ) ] ;
2011-10-14 02:41:56 +08:00
2011-12-07 11:05:37 +08:00
Rule eigenRef_p =
! str_p ( " const " ) [ assign_a ( arg . is_const , true ) ] > >
eigenType_p [ assign_a ( arg . type ) ] > >
ch_p ( ' & ' ) [ assign_a ( arg . is_ref , true ) ] ;
2012-01-29 03:44:33 +08:00
Rule classArg_p =
! str_p ( " const " ) [ assign_a ( arg . is_const , true ) ] > >
* namespace_arg_p > >
2012-02-01 23:19:34 +08:00
className_p [ assign_a ( arg . type ) ] > >
2012-01-29 03:44:33 +08:00
( ch_p ( ' * ' ) [ assign_a ( arg . is_ptr , true ) ] | ch_p ( ' & ' ) [ assign_a ( arg . is_ref , true ) ] ) ;
2012-07-08 20:27:39 +08:00
Rule classParent_p =
* ( namespace_name_p [ push_back_a ( cls . qualifiedParent ) ] > > str_p ( " :: " ) ) > >
className_p [ push_back_a ( cls . qualifiedParent ) ] ;
2011-10-14 02:41:56 +08:00
Rule name_p = lexeme_d [ alpha_p > > * ( alnum_p | ' _ ' ) ] ;
Rule argument_p =
2012-01-29 03:44:33 +08:00
( ( basisType_p [ assign_a ( arg . type ) ] | argEigenType_p | eigenRef_p | classArg_p )
2011-12-09 04:51:15 +08:00
> > name_p [ assign_a ( arg . name ) ] )
2011-10-14 02:41:56 +08:00
[ push_back_a ( args , arg ) ]
[ assign_a ( arg , arg0 ) ] ;
Rule argumentList_p = ! argument_p > > * ( ' , ' > > argument_p ) ;
Rule constructor_p =
2011-12-02 06:06:03 +08:00
( className_p > > ' ( ' > > argumentList_p > > ' ) ' > > ' ; ' > > ! comments_p )
2012-06-27 02:52:27 +08:00
[ push_back_a ( constructor . args_list , args ) ]
[ assign_a ( args , args0 ) ] ;
//[assign_a(constructor.args,args)]
//[assign_a(constructor.name,cls.name)]
//[push_back_a(cls.constructors, constructor)]
//[assign_a(constructor,constructor0)];
2011-10-14 02:41:56 +08:00
2011-12-09 04:51:17 +08:00
Rule namespace_ret_p = namespace_name_p [ push_back_a ( namespaces_return ) ] > > str_p ( " :: " ) ;
2011-10-14 02:41:56 +08:00
Rule returnType1_p =
2011-12-07 11:05:37 +08:00
( basisType_p [ assign_a ( retVal . type1 ) ] [ assign_a ( retVal . category1 , ReturnValue : : BASIS ) ] ) |
2011-12-09 04:51:17 +08:00
( ( * namespace_ret_p ) [ assign_a ( retVal . namespaces1 , namespaces_return ) ] [ clear_a ( namespaces_return ) ]
> > ( className_p [ assign_a ( retVal . type1 ) ] [ assign_a ( retVal . category1 , ReturnValue : : CLASS ) ] ) > >
2011-12-07 11:05:37 +08:00
! ch_p ( ' * ' ) [ assign_a ( retVal . isPtr1 , true ) ] ) |
( eigenType_p [ assign_a ( retVal . type1 ) ] [ assign_a ( retVal . category1 , ReturnValue : : EIGEN ) ] ) ;
2011-10-14 02:41:56 +08:00
Rule returnType2_p =
2011-12-07 11:05:37 +08:00
( basisType_p [ assign_a ( retVal . type2 ) ] [ assign_a ( retVal . category2 , ReturnValue : : BASIS ) ] ) |
2011-12-09 04:51:17 +08:00
( ( * namespace_ret_p ) [ assign_a ( retVal . namespaces2 , namespaces_return ) ] [ clear_a ( namespaces_return ) ]
> > ( className_p [ assign_a ( retVal . type2 ) ] [ assign_a ( retVal . category2 , ReturnValue : : CLASS ) ] ) > >
2011-12-07 11:05:37 +08:00
! ch_p ( ' * ' ) [ assign_a ( retVal . isPtr2 , true ) ] ) |
( eigenType_p [ assign_a ( retVal . type2 ) ] [ assign_a ( retVal . category2 , ReturnValue : : EIGEN ) ] ) ;
2011-10-14 02:41:56 +08:00
Rule pair_p =
( str_p ( " pair " ) > > ' < ' > > returnType1_p > > ' , ' > > returnType2_p > > ' > ' )
2011-12-07 11:05:37 +08:00
[ assign_a ( retVal . isPair , true ) ] ;
2011-10-14 02:41:56 +08:00
2011-12-07 11:05:37 +08:00
Rule void_p = str_p ( " void " ) [ assign_a ( retVal . type1 ) ] ;
2011-10-14 02:41:56 +08:00
Rule returnType_p = void_p | returnType1_p | pair_p ;
Rule methodName_p = lexeme_d [ lower_p > > * ( alnum_p | ' _ ' ) ] ;
Rule method_p =
2012-07-05 22:05:00 +08:00
( returnType_p > > methodName_p [ assign_a ( methodName ) ] > >
2011-10-14 02:41:56 +08:00
' ( ' > > argumentList_p > > ' ) ' > >
2012-07-05 22:05:00 +08:00
! str_p ( " const " ) [ assign_a ( isConst , true ) ] > > ' ; ' > > * comments_p )
[ bl : : bind ( & Method : : addOverload ,
bl : : var ( cls . methods ) [ bl : : var ( methodName ) ] ,
verbose ,
bl : : var ( isConst ) ,
bl : : var ( methodName ) ,
bl : : var ( args ) ,
bl : : var ( retVal ) ) ]
[ assign_a ( isConst , isConst0 ) ]
[ assign_a ( methodName , methodName0 ) ]
2011-10-14 02:41:56 +08:00
[ assign_a ( args , args0 ) ]
2012-07-05 22:05:00 +08:00
[ assign_a ( retVal , retVal0 ) ] ;
2011-10-14 02:41:56 +08:00
2011-12-07 11:05:30 +08:00
Rule staticMethodName_p = lexeme_d [ ( upper_p | lower_p ) > > * ( alnum_p | ' _ ' ) ] ;
2011-12-02 10:32:18 +08:00
Rule static_method_p =
2012-07-05 22:05:00 +08:00
( str_p ( " static " ) > > returnType_p > > staticMethodName_p [ assign_a ( methodName ) ] > >
2011-12-02 10:32:18 +08:00
' ( ' > > argumentList_p > > ' ) ' > > ' ; ' > > * comments_p )
2012-07-05 22:05:00 +08:00
[ bl : : bind ( & StaticMethod : : addOverload ,
bl : : var ( cls . static_methods ) [ bl : : var ( methodName ) ] ,
verbose ,
bl : : var ( methodName ) ,
bl : : var ( args ) ,
bl : : var ( retVal ) ) ]
[ assign_a ( methodName , methodName0 ) ]
2011-12-02 10:32:18 +08:00
[ assign_a ( args , args0 ) ]
2012-07-05 22:05:00 +08:00
[ assign_a ( retVal , retVal0 ) ] ;
2011-12-02 10:32:18 +08:00
2011-12-16 00:18:03 +08:00
Rule functions_p = constructor_p | method_p | static_method_p ;
2011-12-02 10:32:18 +08:00
2011-12-16 03:39:11 +08:00
Rule include_p = str_p ( " #include " ) > > ch_p ( ' < ' ) > > ( * ( anychar_p - ' > ' ) ) [ assign_a ( include_path ) ] > > ch_p ( ' > ' ) ;
Rule class_p =
2012-07-03 02:18:11 +08:00
( ! * include_p
2011-12-16 03:39:11 +08:00
> > str_p ( " class " ) [ push_back_a ( cls . includes , include_path ) ] [ assign_a ( include_path , null_str ) ]
> > className_p [ assign_a ( cls . name ) ]
2012-07-08 20:27:39 +08:00
> > ( ( ' : ' > > classParent_p > > ' { ' ) | ' { ' ) // By having (parent >> '{' | '{') here instead of (!parent >> '{'), we trigger a parse error on a badly-formed parent spec
2011-12-16 03:39:11 +08:00
> > * ( functions_p | comments_p )
> > str_p ( " }; " ) )
2012-06-27 02:52:27 +08:00
[ assign_a ( constructor . name , cls . name ) ]
[ assign_a ( cls . constructor , constructor ) ]
2011-12-16 03:39:11 +08:00
[ assign_a ( cls . namespaces , namespaces ) ]
2012-05-05 03:14:58 +08:00
[ assign_a ( cls . using_namespaces , using_namespace_current ) ]
2011-12-16 03:39:11 +08:00
[ append_a ( cls . includes , namespace_includes ) ]
2012-07-05 22:04:36 +08:00
[ assign_a ( deconstructor . name , cls . name ) ]
[ assign_a ( cls . deconstructor , deconstructor ) ]
2011-12-16 03:39:11 +08:00
[ push_back_a ( classes , cls ) ]
2012-07-05 22:04:36 +08:00
[ assign_a ( deconstructor , deconstructor0 ) ]
2012-06-27 02:52:27 +08:00
[ assign_a ( constructor , constructor0 ) ]
2011-12-16 03:39:11 +08:00
[ assign_a ( cls , cls0 ) ] ;
Rule namespace_def_p =
2012-07-03 02:18:11 +08:00
( ! * include_p
2011-12-16 03:39:11 +08:00
> > str_p ( " namespace " ) [ push_back_a ( namespace_includes , include_path ) ] [ assign_a ( include_path , null_str ) ]
> > namespace_name_p [ push_back_a ( namespaces ) ]
> > ch_p ( ' { ' )
> > * ( class_p | namespace_def_p | comments_p )
> > str_p ( " }/// \\ namespace " ) // end namespace, avoid confusion with classes
> > ! namespace_name_p )
[ pop_a ( namespaces ) ]
[ pop_a ( namespace_includes ) ] ;
2011-12-09 04:51:05 +08:00
2011-12-16 05:23:20 +08:00
Rule using_namespace_p =
str_p ( " using " ) > > str_p ( " namespace " )
2012-05-05 03:14:58 +08:00
> > namespace_name_p [ push_back_a ( using_namespace_current ) ] > > ch_p ( ' ; ' ) ;
2011-12-10 04:29:47 +08:00
2012-02-01 23:19:34 +08:00
Rule forward_declaration_p =
str_p ( " class " ) > >
( * ( namespace_name_p > > str_p ( " :: " ) ) > > className_p ) [ push_back_a ( forward_declarations ) ]
> > ch_p ( ' ; ' ) ;
2011-12-16 05:23:20 +08:00
2012-02-01 23:19:34 +08:00
Rule module_content_p = comments_p | using_namespace_p | class_p | forward_declaration_p | namespace_def_p ;
2011-12-09 04:50:38 +08:00
Rule module_p = * module_content_p > > ! end_p ;
2011-10-14 02:41:56 +08:00
//----------------------------------------------------------------------------
// for debugging, define BOOST_SPIRIT_DEBUG
# ifdef BOOST_SPIRIT_DEBUG
BOOST_SPIRIT_DEBUG_NODE ( className_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( classPtr_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( classRef_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( basisType_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( name_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( argument_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( argumentList_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( constructor_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( returnType1_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( returnType2_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( pair_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( void_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( returnType_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( methodName_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( method_p ) ;
BOOST_SPIRIT_DEBUG_NODE ( class_p ) ;
2011-12-16 03:39:11 +08:00
BOOST_SPIRIT_DEBUG_NODE ( namespace_def_p ) ;
2011-10-14 02:41:56 +08:00
BOOST_SPIRIT_DEBUG_NODE ( module_p ) ;
# endif
//----------------------------------------------------------------------------
// read interface file
string interfaceFile = interfacePath + " / " + moduleName + " .h " ;
2011-12-09 04:50:38 +08:00
string contents = file_contents ( interfaceFile ) ;
2011-10-14 02:41:56 +08:00
// and parse contents
2011-12-02 06:06:05 +08:00
parse_info < const char * > info = parse ( contents . c_str ( ) , module_p , space_p ) ;
2011-10-14 02:41:56 +08:00
if ( ! info . full ) {
printf ( " parsing stopped at \n %.20s \n " , info . stop ) ;
throw ParseFailed ( info . length ) ;
}
}
2011-12-09 04:51:15 +08:00
/* ************************************************************************* */
2011-12-09 04:51:13 +08:00
template < class T >
2012-07-05 22:05:00 +08:00
void verifyArguments ( const vector < string > & validArgs , const map < string , T > & vt ) {
2012-07-06 01:08:40 +08:00
typedef typename map < string , T > : : value_type Name_Method ;
2012-07-05 22:05:00 +08:00
BOOST_FOREACH ( const Name_Method & name_method , vt ) {
const T & t = name_method . second ;
BOOST_FOREACH ( const ArgumentList & argList , t . argLists ) {
BOOST_FOREACH ( Argument arg , argList ) {
string fullType = arg . qualifiedType ( " :: " ) ;
if ( find ( validArgs . begin ( ) , validArgs . end ( ) , fullType )
= = validArgs . end ( ) )
throw DependencyMissing ( fullType , t . name ) ;
}
2011-12-09 04:51:13 +08:00
}
}
}
2011-12-16 05:23:20 +08:00
/* ************************************************************************* */
template < class T >
2012-07-05 22:05:00 +08:00
void verifyReturnTypes ( const vector < string > & validtypes , const map < string , T > & vt ) {
2012-07-06 01:08:40 +08:00
typedef typename map < string , T > : : value_type Name_Method ;
2012-07-05 22:05:00 +08:00
BOOST_FOREACH ( const Name_Method & name_method , vt ) {
const T & t = name_method . second ;
BOOST_FOREACH ( const ReturnValue & retval , t . returnVals ) {
if ( find ( validtypes . begin ( ) , validtypes . end ( ) , retval . qualifiedType1 ( " :: " ) ) = = validtypes . end ( ) )
throw DependencyMissing ( retval . qualifiedType1 ( " :: " ) , t . name ) ;
if ( retval . isPair & & find ( validtypes . begin ( ) , validtypes . end ( ) , retval . qualifiedType2 ( " :: " ) ) = = validtypes . end ( ) )
throw DependencyMissing ( retval . qualifiedType2 ( " :: " ) , t . name ) ;
}
2011-12-16 05:23:20 +08:00
}
}
2011-10-14 02:41:56 +08:00
/* ************************************************************************* */
2012-07-05 22:04:51 +08:00
void Module : : matlab_code ( const string & toolboxPath , const string & headerPath ) const {
2012-05-24 05:23:27 +08:00
fs : : create_directories ( toolboxPath ) ;
2011-10-14 02:41:56 +08:00
2012-07-05 22:04:36 +08:00
// create the unified .cpp switch file
const string wrapperName = name + " _wrapper " ;
string wrapperFileName = toolboxPath + " / " + wrapperName + " .cpp " ;
FileWriter wrapperFile ( wrapperFileName , verbose , " // " ) ;
vector < string > functionNames ; // Function names stored by index for switch
wrapperFile . oss < < " #include <wrap/matlab.h> \n " ;
wrapperFile . oss < < " #include <map> \n " ;
wrapperFile . oss < < " #include <boost/foreach.hpp> \n " ;
wrapperFile . oss < < " \n " ;
2011-12-16 05:23:20 +08:00
// Dependency check list
vector < string > validTypes = forward_declarations ;
validTypes . push_back ( " void " ) ;
validTypes . push_back ( " string " ) ;
validTypes . push_back ( " int " ) ;
validTypes . push_back ( " bool " ) ;
2012-01-24 02:28:11 +08:00
validTypes . push_back ( " char " ) ;
2012-05-05 02:50:36 +08:00
validTypes . push_back ( " unsigned char " ) ;
2011-12-16 05:23:20 +08:00
validTypes . push_back ( " size_t " ) ;
validTypes . push_back ( " double " ) ;
validTypes . push_back ( " Vector " ) ;
validTypes . push_back ( " Matrix " ) ;
2012-07-05 22:04:51 +08:00
//Create a list of parsed classes for dependency checking
BOOST_FOREACH ( Class cls , classes ) {
validTypes . push_back ( cls . qualifiedName ( " :: " ) ) ;
}
2011-12-07 00:50:27 +08:00
2012-07-05 22:04:36 +08:00
// Generate all includes
BOOST_FOREACH ( Class cls , classes ) {
generateIncludes ( wrapperFile , cls . name , cls . includes ) ;
}
wrapperFile . oss < < " \n " ;
// Generate all collectors
BOOST_FOREACH ( Class cls , classes ) {
const string matlabName = cls . qualifiedName ( ) , cppName = cls . qualifiedName ( " :: " ) ;
wrapperFile . oss < < " typedef std::set<boost::shared_ptr< " < < cppName < < " >*> "
< < " Collector_ " < < matlabName < < " ; \n " ;
wrapperFile . oss < < " static Collector_ " < < matlabName < <
" collector_ " < < matlabName < < " ; \n " ;
}
// generate mexAtExit cleanup function
wrapperFile . oss < < " void _deleteAllObjects() \n " ;
wrapperFile . oss < < " { \n " ;
BOOST_FOREACH ( Class cls , classes ) {
const string matlabName = cls . qualifiedName ( ) ;
const string cppName = cls . qualifiedName ( " :: " ) ;
const string collectorType = " Collector_ " + matlabName ;
const string collectorName = " collector_ " + matlabName ;
wrapperFile . oss < < " for( " < < collectorType < < " ::iterator iter = " < < collectorName < < " .begin(); \n " ;
wrapperFile . oss < < " iter != " < < collectorName < < " .end(); ) { \n " ;
wrapperFile . oss < < " delete *iter; \n " ;
wrapperFile . oss < < " " < < collectorName < < " .erase(iter++); \n " ;
wrapperFile . oss < < " } \n " ;
}
wrapperFile . oss < < " } \n " ;
2011-10-14 02:41:56 +08:00
// generate proxy classes and wrappers
BOOST_FOREACH ( Class cls , classes ) {
2012-07-05 22:05:00 +08:00
// create proxy class and wrapper code
2012-07-05 22:04:36 +08:00
string classFile = toolboxPath + " / " + cls . qualifiedName ( ) + " .m " ;
cls . matlab_proxy ( classFile , wrapperName , wrapperFile , functionNames ) ;
2011-10-14 02:41:56 +08:00
2011-12-09 04:51:13 +08:00
// verify all of the function arguments
2012-06-27 02:52:27 +08:00
//TODO:verifyArguments<ArgumentList>(validTypes, cls.constructor.args_list);
2011-12-16 05:23:20 +08:00
verifyArguments < StaticMethod > ( validTypes , cls . static_methods ) ;
verifyArguments < Method > ( validTypes , cls . methods ) ;
// verify function return types
verifyReturnTypes < StaticMethod > ( validTypes , cls . static_methods ) ;
verifyReturnTypes < Method > ( validTypes , cls . methods ) ;
2011-10-14 02:41:56 +08:00
}
2012-07-05 22:04:36 +08:00
// finish wrapper file
finish_wrapper ( wrapperFile , functionNames ) ;
wrapperFile . emit ( true ) ;
2011-10-14 02:41:56 +08:00
}
2012-07-05 22:04:36 +08:00
/* ************************************************************************* */
void Module : : finish_wrapper ( FileWriter & file , const std : : vector < std : : string > & functionNames ) const {
file . oss < < " void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) \n " ;
file . oss < < " { \n " ;
file . oss < < " mstream mout; \n " ; // Send stdout to MATLAB console, see matlab.h
file . oss < < " std::streambuf *outbuf = std::cout.rdbuf(&mout); \n \n " ;
file . oss < < " int id = unwrap<int>(in[0]); \n \n " ;
file . oss < < " switch(id) { \n " ;
for ( size_t id = 0 ; id < functionNames . size ( ) ; + + id ) {
file . oss < < " case " < < id < < " : \n " ;
file . oss < < " " < < functionNames [ id ] < < " (nargout, out, nargin-1, in+1); \n " ;
file . oss < < " break; \n " ;
}
file . oss < < " } \n " ;
file . oss < < " \n " ;
file . oss < < " std::cout.rdbuf(outbuf); \n " ; // Restore cout, see matlab.h
file . oss < < " } \n " ;
}
2011-10-14 02:41:56 +08:00
/* ************************************************************************* */