diff --git a/wrap/Argument.cpp b/wrap/Argument.cpp index 9e2065494..339fc4a97 100644 --- a/wrap/Argument.cpp +++ b/wrap/Argument.cpp @@ -34,29 +34,29 @@ string Argument::matlabClass() const { } /* ************************************************************************* */ -void Argument::matlab_unwrap(ofstream& ofs, const string& matlabName) const { - ofs << " "; +void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const { + file.oss << " "; string cppType = qualifiedType("::"); string matlabType = qualifiedType(); if (is_ptr) // A pointer: emit an "unwrap_shared_ptr" call which returns a pointer - ofs << "shared_ptr<" << cppType << "> " << name << " = unwrap_shared_ptr< "; + file.oss << "shared_ptr<" << cppType << "> " << name << " = unwrap_shared_ptr< "; else if (is_ref) // A reference: emit an "unwrap_shared_ptr" call and de-reference the pointer - ofs << cppType << "& " << name << " = *unwrap_shared_ptr< "; + file.oss << cppType << "& " << name << " = *unwrap_shared_ptr< "; else // Not a pointer or a reference: emit an "unwrap" call // unwrap is specified in matlab.h as a series of template specializations // that know how to unpack the expected MATLAB object // example: double tol = unwrap< double >(in[2]); // example: Vector v = unwrap< Vector >(in[1]); - ofs << cppType << " " << name << " = unwrap< "; + file.oss << cppType << " " << name << " = unwrap< "; - ofs << cppType << " >(" << matlabName; - if (is_ptr || is_ref) ofs << ", \"" << matlabType << "\""; - ofs << ");" << endl; + file.oss << cppType << " >(" << matlabName; + if (is_ptr || is_ref) file.oss << ", \"" << matlabType << "\""; + file.oss << ");" << endl; } /* ************************************************************************* */ @@ -107,12 +107,12 @@ string ArgumentList::names() const { } /* ************************************************************************* */ -void ArgumentList::matlab_unwrap(ofstream& ofs, int start) const { +void ArgumentList::matlab_unwrap(FileWriter& file, int start) const { int index = start; BOOST_FOREACH(Argument arg, *this) { stringstream buf; buf << "in[" << index << "]"; - arg.matlab_unwrap(ofs,buf.str()); + arg.matlab_unwrap(file,buf.str()); index++; } } diff --git a/wrap/Argument.h b/wrap/Argument.h index 9b9bd6bfb..2c71eed2b 100644 --- a/wrap/Argument.h +++ b/wrap/Argument.h @@ -20,6 +20,8 @@ #include #include +#include "FileWriter.h" + namespace wrap { /// Argument class @@ -40,7 +42,7 @@ struct Argument { std::string qualifiedType(const std::string& delim = "") const; /// MATLAB code generation, MATLAB to C++ - void matlab_unwrap(std::ofstream& ofs, const std::string& matlabName) const; + void matlab_unwrap(FileWriter& file, const std::string& matlabName) const; }; /// Argument list is just a container with Arguments @@ -59,10 +61,10 @@ struct ArgumentList: public std::vector { /** * emit code to unwrap arguments - * @param ofs output stream + * @param file output stream * @param start initial index for input array, set to 1 for method */ - void matlab_unwrap(std::ofstream& ofs, int start = 0) const; // MATLAB to C++ + void matlab_unwrap(FileWriter& file, int start = 0) const; // MATLAB to C++ }; } // \namespace wrap diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 47e01f00b..597ed2bb0 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -29,31 +29,31 @@ using namespace wrap; /* ************************************************************************* */ void Class::matlab_proxy(const string& classFile) const { // open destination classFile - ofstream ofs(classFile.c_str()); - if(!ofs) throw CantOpenFile(classFile); + FileWriter file(classFile, "%"); +// if(!file) throw CantOpenFile(classFile); if(verbose_) cerr << "generating " << classFile << endl; // get the name of actual matlab object string matlabName = qualifiedName(); // emit class proxy code - ofs << "classdef " << matlabName << endl; - ofs << " properties" << endl; - ofs << " self = 0" << endl; - ofs << " end" << endl; - ofs << " methods" << endl; - ofs << " function obj = " << matlabName << "(varargin)" << endl; + file.oss << "classdef " << matlabName << endl; + file.oss << " properties" << endl; + file.oss << " self = 0" << endl; + file.oss << " end" << endl; + file.oss << " methods" << endl; + file.oss << " function obj = " << matlabName << "(varargin)" << endl; BOOST_FOREACH(Constructor c, constructors) - c.matlab_proxy_fragment(ofs,matlabName); - ofs << " if nargin ~= 13 && obj.self == 0, error('" << matlabName << " constructor failed'); end" << endl; - ofs << " end" << endl; - ofs << " function display(obj), obj.print(''); end" << endl; - ofs << " function disp(obj), obj.display; end" << endl; - ofs << " end" << endl; - ofs << "end" << endl; + c.matlab_proxy_fragment(file,matlabName); + file.oss << " if nargin ~= 13 && obj.self == 0, error('" << matlabName << " constructor failed'); end" << endl; + file.oss << " end" << endl; + file.oss << " function display(obj), obj.print(''); end" << endl; + file.oss << " function disp(obj), obj.display; end" << endl; + file.oss << " end" << endl; + file.oss << "end" << endl; // close file - ofs.close(); + file.emit(false); } /* ************************************************************************* */ @@ -83,23 +83,23 @@ void Class::matlab_static_methods(const string& toolboxPath, const vector& using_namespaces) const; ///< emit method wrappers void matlab_static_methods(const std::string& classPath, const std::vector& using_namespaces) const; ///< emit static method wrappers - void matlab_make_fragment(std::ofstream& ofs, + void matlab_make_fragment(FileWriter& file, const std::string& toolboxPath, const std::string& mexFlags) const; ///< emit make fragment for global make script - void makefile_fragment(std::ofstream& ofs) const; ///< emit makefile fragment + void makefile_fragment(FileWriter& file) const; ///< emit makefile fragment std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter }; diff --git a/wrap/Constructor.cpp b/wrap/Constructor.cpp index fa7d4e913..872d498fc 100644 --- a/wrap/Constructor.cpp +++ b/wrap/Constructor.cpp @@ -32,28 +32,28 @@ string Constructor::matlab_wrapper_name(const string& className) const { } /* ************************************************************************* */ -void Constructor::matlab_proxy_fragment(ofstream& ofs, const string& className) const { +void Constructor::matlab_proxy_fragment(FileWriter& file, const string& className) const { size_t nrArgs = args.size(); // check for number of arguments... - ofs << " if (nargin == " << nrArgs; - if (nrArgs>0) ofs << " && "; + file.oss << " if (nargin == " << nrArgs; + if (nrArgs>0) file.oss << " && "; // ...and their types bool first = true; for(size_t i=0;i + +#include + +using namespace std; +using namespace boost::gregorian; +using namespace wrap; + +/* ************************************************************************* */ +FileWriter::FileWriter(const string& filename, const string& comment_str) +: filename_(filename), comment_str_(comment_str) +{ +} + +/* ************************************************************************* */ +void FileWriter::emit(bool add_header, bool force) const { + // Standard write - just overwrite for verification + ofstream ofs(filename_.c_str()); + if (!ofs) throw CantOpenFile(filename_); + + // header + if (add_header) { + date today = day_clock::local_day(); + ofs << comment_str_ << " automatically generated by wrap on " << today << endl; + } + + // dump in stringstream + ofs << oss.str(); + ofs.close(); + + // TODO: add the following checks + // check for existing file + + // if exists and we are not forcing writing, read and compare + + // if different, write the file with contents of this stream + + // add header + + +} +/* ************************************************************************* */ + + + + diff --git a/wrap/FileWriter.h b/wrap/FileWriter.h new file mode 100644 index 000000000..256cacb31 --- /dev/null +++ b/wrap/FileWriter.h @@ -0,0 +1,34 @@ +/** + * @file FileWriter.h + * + * @brief Wrapper for writing files and avoiding overwriting existing files + * This class wraps a stream object and will check that the file is + * actually different to write the new generated file. + * + * @date Jan 15, 2012 + * @author Alex Cunningham + */ + +#pragma once + +#include + +namespace wrap { + +class FileWriter { +protected: + std::string filename_; + std::string comment_str_; + +public: + std::ostringstream oss; ///< Primary stream for operating on the file + + /** Create a writer with a filename and delimiter for the header comment */ + FileWriter(const std::string& filename, const std::string& comment_str=""); + + /** Writes the contents of the stringstream to the file, checking if actually new */ + void emit(bool add_header, bool force=false) const; + +}; + +} // \namespace wrap diff --git a/wrap/Makefile.am b/wrap/Makefile.am index ed6a68a27..b081de466 100644 --- a/wrap/Makefile.am +++ b/wrap/Makefile.am @@ -19,7 +19,7 @@ if ENABLE_BUILD_TOOLBOX # Build a library from the core sources sources += utilities.cpp Argument.cpp ReturnValue.cpp Constructor.cpp -sources += Method.cpp StaticMethod.cpp Class.cpp Module.cpp +sources += Method.cpp StaticMethod.cpp Class.cpp Module.cpp FileWriter.cpp check_PROGRAMS += tests/testSpirit tests/testWrap if ENABLE_INSTALL_WRAP wrap_PROGRAMS += wrap diff --git a/wrap/Method.cpp b/wrap/Method.cpp index 0d9ba98e2..07f381291 100644 --- a/wrap/Method.cpp +++ b/wrap/Method.cpp @@ -30,21 +30,21 @@ void Method::matlab_mfile(const string& classPath) const { // open destination m-file string wrapperFile = classPath + "/" + name + ".m"; - ofstream ofs(wrapperFile.c_str()); - if(!ofs) throw CantOpenFile(wrapperFile); + FileWriter file(wrapperFile.c_str(), "%"); +// if(!file) throw CantOpenFile(wrapperFile); if(verbose_) cerr << "generating " << wrapperFile << endl; // generate code string returnType = returnVal.matlab_returnType(); - ofs << "function " << returnType << " = " << name << "(obj"; - if (args.size()) ofs << "," << args.names(); - ofs << ")" << endl; - ofs << "% usage: obj." << name << "(" << args.names() << ")" << endl; - ofs << " error('need to compile " << name << ".cpp');" << endl; - ofs << "end" << endl; + file.oss << "function " << returnType << " = " << name << "(obj"; + if (args.size()) file.oss << "," << args.names(); + file.oss << ")" << endl; + file.oss << "% usage: obj." << name << "(" << args.names() << ")" << endl; + file.oss << " error('need to compile " << name << ".cpp');" << endl; + file.oss << "end" << endl; // close file - ofs.close(); + file.emit(false); } /* ************************************************************************* */ @@ -55,51 +55,51 @@ void Method::matlab_wrapper(const string& classPath, const vector& using_namespaces, const std::vector& includes) const { // open destination wrapperFile string wrapperFile = classPath + "/" + name + ".cpp"; - ofstream ofs(wrapperFile.c_str()); - if(!ofs) throw CantOpenFile(wrapperFile); + FileWriter file(wrapperFile.c_str(), "//"); +// if(!file) throw CantOpenFile(wrapperFile); if(verbose_) cerr << "generating " << wrapperFile << endl; // generate code // header - generateHeaderComment(ofs, "//"); - generateIncludes(ofs, className, includes); - generateUsingNamespace(ofs, using_namespaces); +// generateHeaderComment(file, "//"); + generateIncludes(file, className, includes); + generateUsingNamespace(file, using_namespaces); // call - ofs << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; + file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; // start - ofs << "{\n"; + file.oss << "{\n"; // check arguments // extra argument obj -> nargin-1 is passed ! // example: checkArguments("equals",nargout,nargin-1,2); - ofs << " checkArguments(\"" << name << "\",nargout,nargin-1," << args.size() << ");\n"; + file.oss << " checkArguments(\"" << name << "\",nargout,nargin-1," << args.size() << ");\n"; // get class pointer // example: shared_ptr = unwrap_shared_ptr< Test >(in[0], "Test"); - ofs << " shared_ptr<" << cppClassName << "> self = unwrap_shared_ptr< " << cppClassName + file.oss << " shared_ptr<" << cppClassName << "> self = unwrap_shared_ptr< " << cppClassName << " >(in[0],\"" << matlabClassName << "\");" << endl; // unwrap arguments, see Argument.cpp - args.matlab_unwrap(ofs,1); + args.matlab_unwrap(file,1); // call method // example: bool result = self->return_field(t); - ofs << " "; + file.oss << " "; if (returnVal.type1!="void") - ofs << returnVal.return_type(true,ReturnValue::pair) << " result = "; - ofs << "self->" << name << "(" << args.names() << ");\n"; + file.oss << returnVal.return_type(true,ReturnValue::pair) << " result = "; + file.oss << "self->" << name << "(" << args.names() << ");\n"; // wrap result // example: out[0]=wrap(result); - returnVal.wrap_result(ofs); + returnVal.wrap_result(file); // finish - ofs << "}\n"; + file.oss << "}\n"; // close file - ofs.close(); + file.emit(true); } /* ************************************************************************* */ diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 06d745609..01d7b327c 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -15,6 +15,7 @@ **/ #include "Module.h" +#include "FileWriter.h" #include "utilities.h" #include "spirit_actors.h" @@ -24,7 +25,7 @@ #include #include -#include +//#include using namespace std; using namespace wrap; @@ -279,29 +280,31 @@ void Module::matlab_code(const string& toolboxPath, system(installCmd.c_str()); // create make m-file - string matlabMakeFile = toolboxPath + "/make_" + name + ".m"; - ofstream ofs(matlabMakeFile.c_str()); - if(!ofs) throw CantOpenFile(matlabMakeFile); + string matlabMakeFileName = toolboxPath + "/make_" + name + ".m"; + FileWriter makeModuleMfile(matlabMakeFileName, "%"); +// filetream makeModuleMfile(matlabMakeFileName.c_str()); +// if(!makeModuleMfile) throw CantOpenFile(matlabMakeFileName); // create the (actual) make file - string makeFile = toolboxPath + "/Makefile"; - ofstream make_ofs(makeFile.c_str()); - if(!make_ofs) throw CantOpenFile(makeFile); + string makeFileName = toolboxPath + "/Makefile"; + FileWriter makeModuleMakefile(makeFileName, "#"); +// filetream makeModuleMakefile(makeFileName.c_str()); +// if(!makeModuleMakefile) throw CantOpenFile(makeFileName); - if (verbose) cerr << "generating " << matlabMakeFile << endl; - generateHeaderComment(ofs,"%"); - ofs << "echo on" << endl << endl; - ofs << "toolboxpath = mfilename('fullpath');" << endl; - ofs << "delims = find(toolboxpath == '/');" << endl; - ofs << "toolboxpath = toolboxpath(1:(delims(end)-1));" << endl; - ofs << "clear delims" << endl; - ofs << "addpath(toolboxpath);" << endl << endl; + if (verbose) cerr << "generating " << matlabMakeFileName << endl; +// generateHeaderComment(makeModuleMfile,"%"); // In FileWriter constructor + makeModuleMfile.oss << "echo on" << endl << endl; + makeModuleMfile.oss << "toolboxpath = mfilename('fullpath');" << endl; + makeModuleMfile.oss << "delims = find(toolboxpath == '/');" << endl; + makeModuleMfile.oss << "toolboxpath = toolboxpath(1:(delims(end)-1));" << endl; + makeModuleMfile.oss << "clear delims" << endl; + makeModuleMfile.oss << "addpath(toolboxpath);" << endl << endl; - if (verbose) cerr << "generating " << makeFile << endl; - generateHeaderComment(make_ofs,"#"); - make_ofs << "\nMEX = mex\n"; - make_ofs << "MEXENDING = " << mexExt << "\n"; - make_ofs << "mex_flags = " << mexFlags << "\n\n"; + if (verbose) cerr << "generating " << makeFileName << endl; +// generateHeaderComment(makeModuleMakefile,"#"); // In FileWriter constructor + makeModuleMakefile.oss << "\nMEX = mex\n"; + makeModuleMakefile.oss << "MEXENDING = " << mexExt << "\n"; + makeModuleMakefile.oss << "mex_flags = " << mexFlags << "\n\n"; // Dependency check list vector validTypes = forward_declarations; @@ -315,13 +318,13 @@ void Module::matlab_code(const string& toolboxPath, validTypes.push_back("Matrix"); // add 'all' to Makefile - make_ofs << "all: "; + makeModuleMakefile.oss << "all: "; BOOST_FOREACH(Class cls, classes) { - make_ofs << cls.qualifiedName() << " "; + makeModuleMakefile.oss << cls.qualifiedName() << " "; //Create a list of parsed classes for dependency checking validTypes.push_back(cls.qualifiedName("::")); } - make_ofs << "\n\n"; + makeModuleMakefile.oss << "\n\n"; // generate proxy classes and wrappers BOOST_FOREACH(Class cls, classes) { @@ -349,29 +352,31 @@ void Module::matlab_code(const string& toolboxPath, cls.matlab_methods(classPath,using_namespaces); // add lines to make m-file - ofs << "%% " << cls.qualifiedName() << endl; - ofs << "cd(toolboxpath)" << endl; - cls.matlab_make_fragment(ofs, toolboxPath, mexFlags); + makeModuleMfile.oss << "%% " << cls.qualifiedName() << endl; + makeModuleMfile.oss << "cd(toolboxpath)" << endl; + cls.matlab_make_fragment(makeModuleMfile, toolboxPath, mexFlags); // add section to the (actual) make file - make_ofs << "# " << cls.qualifiedName() << endl; - cls.makefile_fragment(make_ofs); + makeModuleMakefile.oss << "# " << cls.qualifiedName() << endl; + cls.makefile_fragment(makeModuleMakefile); } // finish make m-file - ofs << "cd(toolboxpath)" << endl << endl; - ofs << "echo off" << endl; - ofs.close(); + makeModuleMfile.oss << "cd(toolboxpath)" << endl << endl; + makeModuleMfile.oss << "echo off" << endl; + makeModuleMfile.emit(true); // By default, compare existing file first +// makeModuleMfile.emit(); // make clean at end of Makefile - make_ofs << "\n\nclean: \n"; - make_ofs << "\trm -rf *.$(MEXENDING)\n"; + makeModuleMakefile.oss << "\n\nclean: \n"; + makeModuleMakefile.oss << "\trm -rf *.$(MEXENDING)\n"; BOOST_FOREACH(Class cls, classes) - make_ofs << "\trm -rf @" << cls.qualifiedName() << "/*.$(MEXENDING)\n"; + makeModuleMakefile.oss << "\trm -rf @" << cls.qualifiedName() << "/*.$(MEXENDING)\n"; // finish Makefile - make_ofs << "\n" << endl; - make_ofs.close(); + makeModuleMakefile.oss << "\n" << endl; + makeModuleMakefile.emit(true); +// makeModuleMakefile.emit(); } /* ************************************************************************* */ diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index 38d85d074..1aad0a08a 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -44,33 +44,33 @@ string ReturnValue::qualifiedType2(const string& delim) const { } /* ************************************************************************* */ -void ReturnValue::wrap_result(ostream& ofs) const { +void ReturnValue::wrap_result(FileWriter& file) const { string cppType1 = qualifiedType1("::"), matlabType1 = qualifiedType1(); string cppType2 = qualifiedType2("::"), matlabType2 = qualifiedType2(); if (isPair) { // first return value in pair if (isPtr1) // if we already have a pointer - ofs << " out[0] = wrap_shared_ptr(result.first,\"" << matlabType1 << "\");\n"; + file.oss << " out[0] = wrap_shared_ptr(result.first,\"" << matlabType1 << "\");\n"; else if (category1 == ReturnValue::CLASS) // if we are going to make one - ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result.first),\"" << matlabType1 << "\");\n"; + file.oss << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result.first),\"" << matlabType1 << "\");\n"; else // if basis type - ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n"; + file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n"; // second return value in pair if (isPtr2) // if we already have a pointer - ofs << " out[1] = wrap_shared_ptr(result.second,\"" << type2 << "\");\n"; + file.oss << " out[1] = wrap_shared_ptr(result.second,\"" << type2 << "\");\n"; else if (category2 == ReturnValue::CLASS) // if we are going to make one - ofs << " out[1] = wrap_shared_ptr(make_shared< " << cppType2 << " >(result.second),\"" << matlabType2 << "\");\n"; + file.oss << " out[1] = wrap_shared_ptr(make_shared< " << cppType2 << " >(result.second),\"" << matlabType2 << "\");\n"; else - ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n"; + file.oss << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n"; } else if (isPtr1) - ofs << " out[0] = wrap_shared_ptr(result,\"" << type1 << "\");\n"; + file.oss << " out[0] = wrap_shared_ptr(result,\"" << type1 << "\");\n"; else if (category1 == ReturnValue::CLASS) - ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result),\"" << matlabType1 << "\");\n"; + file.oss << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result),\"" << matlabType1 << "\");\n"; else if (type1!="void") - ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n"; + file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n"; } /* ************************************************************************* */ diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index eb2406d80..859e00433 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -8,7 +8,8 @@ */ #include -#include + +#include "FileWriter.h" #pragma once @@ -46,7 +47,7 @@ struct ReturnValue { std::string matlab_returnType() const; - void wrap_result(std::ostream& ofs) const; + void wrap_result(FileWriter& file) const; }; diff --git a/wrap/StaticMethod.cpp b/wrap/StaticMethod.cpp index ff4d31592..dfa1a79b2 100644 --- a/wrap/StaticMethod.cpp +++ b/wrap/StaticMethod.cpp @@ -31,21 +31,21 @@ void StaticMethod::matlab_mfile(const string& toolboxPath, const string& classNa // open destination m-file string full_name = className + "_" + name; string wrapperFile = toolboxPath + "/" + full_name + ".m"; - ofstream ofs(wrapperFile.c_str()); - if(!ofs) throw CantOpenFile(wrapperFile); + FileWriter file(wrapperFile, "%"); +// if(!file) throw CantOpenFile(wrapperFile); if(verbose) cerr << "generating " << wrapperFile << endl; // generate code string returnType = returnVal.matlab_returnType(); - ofs << "function " << returnType << " = " << full_name << "("; - if (args.size()) ofs << args.names(); - ofs << ")" << endl; - ofs << "% usage: x = " << full_name << "(" << args.names() << ")" << endl; - ofs << " error('need to compile " << full_name << ".cpp');" << endl; - ofs << "end" << endl; + file.oss << "function " << returnType << " = " << full_name << "("; + if (args.size()) file.oss << args.names(); + file.oss << ")" << endl; + file.oss << "% usage: x = " << full_name << "(" << args.names() << ")" << endl; + file.oss << " error('need to compile " << full_name << ".cpp');" << endl; + file.oss << "end" << endl; // close file - ofs.close(); + file.emit(false); } /* ************************************************************************* */ @@ -56,45 +56,45 @@ void StaticMethod::matlab_wrapper(const string& toolboxPath, const string& class // open destination wrapperFile string full_name = matlabClassName + "_" + name; string wrapperFile = toolboxPath + "/" + full_name + ".cpp"; - ofstream ofs(wrapperFile.c_str()); - if(!ofs) throw CantOpenFile(wrapperFile); + FileWriter file(wrapperFile, "%"); +// if(!file) throw CantOpenFile(wrapperFile); if(verbose) cerr << "generating " << wrapperFile << endl; // generate code // header - generateHeaderComment(ofs, "//"); - generateIncludes(ofs, className, includes); - generateUsingNamespace(ofs, using_namespaces); +// generateHeaderComment(file, "//"); + generateIncludes(file, className, includes); + generateUsingNamespace(file, using_namespaces); // call - ofs << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; + file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; // start - ofs << "{\n"; + file.oss << "{\n"; // check arguments // NOTE: for static functions, there is no object passed - ofs << " checkArguments(\"" << full_name << "\",nargout,nargin," << args.size() << ");\n"; + file.oss << " checkArguments(\"" << full_name << "\",nargout,nargin," << args.size() << ");\n"; // unwrap arguments, see Argument.cpp - args.matlab_unwrap(ofs,0); // We start at 0 because there is no self object + args.matlab_unwrap(file,0); // We start at 0 because there is no self object - ofs << " "; + file.oss << " "; // call method with default type if (returnVal.type1!="void") - ofs << returnVal.return_type(true,ReturnValue::pair) << " result = "; - ofs << cppClassName << "::" << name << "(" << args.names() << ");\n"; + file.oss << returnVal.return_type(true,ReturnValue::pair) << " result = "; + file.oss << cppClassName << "::" << name << "(" << args.names() << ");\n"; // wrap result // example: out[0]=wrap(result); - returnVal.wrap_result(ofs); + returnVal.wrap_result(file); // finish - ofs << "}\n"; + file.oss << "}\n"; // close file - ofs.close(); + file.emit(true); } /* ************************************************************************* */ diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index fb8309485..d923a7052 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -17,14 +17,12 @@ #include #include -#include #include "utilities.h" namespace wrap { using namespace std; -using namespace boost::gregorian; /* ************************************************************************* */ string file_contents(const string& filename, bool skipheader) { @@ -103,11 +101,11 @@ bool files_equal(const string& expected, const string& actual, bool skipheader) return true; } -/* ************************************************************************* */ -void generateHeaderComment(ofstream& ofs, const string& delimiter) { - date today = day_clock::local_day(); - ofs << delimiter << " automatically generated by wrap on " << today << endl; -} +///* ************************************************************************* */ +//void generateHeaderComment(FileWriter& file, const string& delimiter) { +// date today = day_clock::local_day(); +// file.oss << delimiter << " automatically generated by wrap on " << today << endl; +//} /* ************************************************************************* */ string maybe_shared_ptr(bool add, const string& type) { @@ -118,25 +116,25 @@ string maybe_shared_ptr(bool add, const string& type) { } /* ************************************************************************* */ -void generateUsingNamespace(ofstream& ofs, const vector& using_namespaces) { +void generateUsingNamespace(FileWriter& file, const vector& using_namespaces) { if (using_namespaces.empty()) return; BOOST_FOREACH(const string& s, using_namespaces) - ofs << "using namespace " << s << ";" << endl; + file.oss << "using namespace " << s << ";" << endl; } /* ************************************************************************* */ -void generateIncludes(ofstream& ofs, const string& class_name, +void generateIncludes(FileWriter& file, const string& class_name, const vector& includes) { - ofs << "#include " << endl; + file.oss << "#include " << endl; bool added_include = false; BOOST_FOREACH(const string& s, includes) { if (!s.empty()) { - ofs << "#include <" << s << ">" << endl; + file.oss << "#include <" << s << ">" << endl; added_include = true; } } if (!added_include) // add default include - ofs << "#include <" << class_name << ".h>" << endl; + file.oss << "#include <" << class_name << ".h>" << endl; } /* ************************************************************************* */ diff --git a/wrap/utilities.h b/wrap/utilities.h index 82475ebac..753aaf118 100644 --- a/wrap/utilities.h +++ b/wrap/utilities.h @@ -21,6 +21,8 @@ #include #include +#include "FileWriter.h" + namespace wrap { class CantOpenFile : public std::exception { @@ -49,18 +51,18 @@ class ParseFailed : public std::exception { }; class DependencyMissing : public std::exception { - private: - std::string dependency_; - std::string location_; - public: - DependencyMissing(const std::string& dep, const std::string& loc) { - dependency_ = dep; - location_ = loc; - } - ~DependencyMissing() throw() {} - virtual const char* what() const throw() { - return ("Missing dependency " + dependency_ + " in " + location_).c_str(); - } +private: + std::string dependency_; + std::string location_; +public: + DependencyMissing(const std::string& dep, const std::string& loc) { + dependency_ = dep; + location_ = loc; + } + ~DependencyMissing() throw() {} + virtual const char* what() const throw() { + return ("Missing dependency " + dependency_ + " in " + location_).c_str(); + } }; @@ -83,7 +85,7 @@ bool assert_equal(const std::vector& expected, const std::vector& using_namespaces); +void generateUsingNamespace(FileWriter& file, const std::vector& using_namespaces); /** * Creates the #include statements */ -void generateIncludes(std::ofstream& ofs, const std::string& class_name, +void generateIncludes(FileWriter& file, const std::string& class_name, const std::vector& includes); } // \namespace wrap