diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 597ed2bb0..8c86ccc58 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -29,9 +29,7 @@ using namespace wrap; /* ************************************************************************* */ void Class::matlab_proxy(const string& classFile) const { // open destination classFile - FileWriter file(classFile, "%"); -// if(!file) throw CantOpenFile(classFile); - if(verbose_) cerr << "generating " << classFile << endl; + FileWriter file(classFile, verbose_, "%"); // get the name of actual matlab object string matlabName = qualifiedName(); diff --git a/wrap/Constructor.cpp b/wrap/Constructor.cpp index 872d498fc..fda7db1b4 100644 --- a/wrap/Constructor.cpp +++ b/wrap/Constructor.cpp @@ -63,12 +63,9 @@ void Constructor::matlab_mfile(const string& toolboxPath, const string& qualifie // open destination m-file string wrapperFile = toolboxPath + "/" + matlabName + ".m"; - FileWriter file(wrapperFile, "%"); -// if(!file) throw CantOpenFile(wrapperFile); - if(verbose_) cerr << "generating " << wrapperFile << endl; + FileWriter file(wrapperFile, verbose_, "%"); // generate code -// generateHeaderComment(file, "%"); file.oss << "function result = " << matlabName << "(obj"; if (args.size()) file.oss << "," << args.names(); file.oss << ")" << endl; @@ -88,12 +85,9 @@ void Constructor::matlab_wrapper(const string& toolboxPath, // open destination wrapperFile string wrapperFile = toolboxPath + "/" + matlabName + ".cpp"; - FileWriter file(wrapperFile, "//"); -// if(!file) throw CantOpenFile(wrapperFile); - if(verbose_) cerr << "generating " << wrapperFile << endl; + FileWriter file(wrapperFile, verbose_, "//"); // generate code -// generateHeaderComment(file, "//"); generateIncludes(file, name, includes); generateUsingNamespace(file, using_namespaces); diff --git a/wrap/FileWriter.cpp b/wrap/FileWriter.cpp index 81b7364a3..3ced1ec44 100644 --- a/wrap/FileWriter.cpp +++ b/wrap/FileWriter.cpp @@ -17,37 +17,42 @@ using namespace boost::gregorian; using namespace wrap; /* ************************************************************************* */ -FileWriter::FileWriter(const string& filename, const string& comment_str) -: filename_(filename), comment_str_(comment_str) +FileWriter::FileWriter(const string& filename, bool verbose, const string& comment_str) +: verbose_(verbose),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; +void FileWriter::emit(bool add_header, bool force_overwrite) const { + if (verbose_) cerr << "generating " << filename_ << " "; + // read in file if it exists + string existing_contents; + bool file_exists = true; + try { + existing_contents = file_contents(filename_.c_str(), add_header); + } catch (CantOpenFile& e) { + file_exists = false; } - // 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 + // Only write a file if it is new, an update, or overwrite is forced + string new_contents = oss.str(); + if (force_overwrite || !file_exists || existing_contents != new_contents) { + 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 << new_contents; + ofs.close(); + if (verbose_) cerr << " ...complete" << endl; + } else { + if (verbose_) cerr << " ...no update" << endl; + } } /* ************************************************************************* */ diff --git a/wrap/FileWriter.h b/wrap/FileWriter.h index 256cacb31..f081b86ed 100644 --- a/wrap/FileWriter.h +++ b/wrap/FileWriter.h @@ -17,6 +17,7 @@ namespace wrap { class FileWriter { protected: + bool verbose_; std::string filename_; std::string comment_str_; @@ -24,7 +25,7 @@ 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=""); + FileWriter(const std::string& filename, bool verbose, 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; diff --git a/wrap/Makefile.am b/wrap/Makefile.am index b081de466..997646468 100644 --- a/wrap/Makefile.am +++ b/wrap/Makefile.am @@ -85,6 +85,8 @@ endif endif # Linux # Choose correct cp command by OS +# In linux, this will only copy the file if it is an update +# Macs use an older version of cp that doesn't support the -u flag cp_install = if LINUX cp_install += cp -ru @@ -102,9 +104,9 @@ source_mode = -m 644 wrap-install-matlab-toolbox: generate_toolbox install -d ${toolbox}/gtsam - install ${source_mode} -c ../toolbox/*.m ${toolbox}/gtsam - install ${source_mode} -c ../toolbox/*.cpp ${toolbox}/gtsam - install ${source_mode} -c ../toolbox/Makefile ${toolbox}/gtsam + ${cp_install} ../toolbox/*.m ${toolbox}/gtsam + ${cp_install} ../toolbox/*.cpp ${toolbox}/gtsam + ${cp_install} ../toolbox/Makefile ${toolbox}/gtsam ${cp_install} ../toolbox/@* ${toolbox}/gtsam wrap-install-bin: wrap diff --git a/wrap/Method.cpp b/wrap/Method.cpp index 07f381291..cf280c1d1 100644 --- a/wrap/Method.cpp +++ b/wrap/Method.cpp @@ -30,9 +30,7 @@ void Method::matlab_mfile(const string& classPath) const { // open destination m-file string wrapperFile = classPath + "/" + name + ".m"; - FileWriter file(wrapperFile.c_str(), "%"); -// if(!file) throw CantOpenFile(wrapperFile); - if(verbose_) cerr << "generating " << wrapperFile << endl; + FileWriter file(wrapperFile, verbose_); // generate code string returnType = returnVal.matlab_returnType(); @@ -55,14 +53,11 @@ void Method::matlab_wrapper(const string& classPath, const vector& using_namespaces, const std::vector& includes) const { // open destination wrapperFile string wrapperFile = classPath + "/" + name + ".cpp"; - FileWriter file(wrapperFile.c_str(), "//"); -// if(!file) throw CantOpenFile(wrapperFile); - if(verbose_) cerr << "generating " << wrapperFile << endl; + FileWriter file(wrapperFile, verbose_, "//"); // generate code // header -// generateHeaderComment(file, "//"); generateIncludes(file, className, includes); generateUsingNamespace(file, using_namespaces); diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 01d7b327c..9a819defb 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -281,18 +281,12 @@ void Module::matlab_code(const string& toolboxPath, // create make m-file string matlabMakeFileName = toolboxPath + "/make_" + name + ".m"; - FileWriter makeModuleMfile(matlabMakeFileName, "%"); -// filetream makeModuleMfile(matlabMakeFileName.c_str()); -// if(!makeModuleMfile) throw CantOpenFile(matlabMakeFileName); + FileWriter makeModuleMfile(matlabMakeFileName, verbose, "%"); // create the (actual) make file string makeFileName = toolboxPath + "/Makefile"; - FileWriter makeModuleMakefile(makeFileName, "#"); -// filetream makeModuleMakefile(makeFileName.c_str()); -// if(!makeModuleMakefile) throw CantOpenFile(makeFileName); + FileWriter makeModuleMakefile(makeFileName, verbose, "#"); - 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; @@ -300,8 +294,6 @@ void Module::matlab_code(const string& toolboxPath, makeModuleMfile.oss << "clear delims" << endl; makeModuleMfile.oss << "addpath(toolboxpath);" << endl << endl; - 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"; @@ -365,7 +357,6 @@ void Module::matlab_code(const string& toolboxPath, 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 makeModuleMakefile.oss << "\n\nclean: \n"; @@ -376,7 +367,6 @@ void Module::matlab_code(const string& toolboxPath, // finish Makefile makeModuleMakefile.oss << "\n" << endl; makeModuleMakefile.emit(true); -// makeModuleMakefile.emit(); } /* ************************************************************************* */ diff --git a/wrap/StaticMethod.cpp b/wrap/StaticMethod.cpp index dfa1a79b2..e066d41d8 100644 --- a/wrap/StaticMethod.cpp +++ b/wrap/StaticMethod.cpp @@ -31,9 +31,7 @@ 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"; - FileWriter file(wrapperFile, "%"); -// if(!file) throw CantOpenFile(wrapperFile); - if(verbose) cerr << "generating " << wrapperFile << endl; + FileWriter file(wrapperFile, verbose); // generate code string returnType = returnVal.matlab_returnType(); @@ -56,14 +54,11 @@ void StaticMethod::matlab_wrapper(const string& toolboxPath, const string& class // open destination wrapperFile string full_name = matlabClassName + "_" + name; string wrapperFile = toolboxPath + "/" + full_name + ".cpp"; - FileWriter file(wrapperFile, "%"); -// if(!file) throw CantOpenFile(wrapperFile); - if(verbose) cerr << "generating " << wrapperFile << endl; + FileWriter file(wrapperFile, verbose, "//"); // generate code // header -// generateHeaderComment(file, "//"); generateIncludes(file, className, includes); generateUsingNamespace(file, using_namespaces); diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index d923a7052..71373c8e6 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -101,12 +101,6 @@ bool files_equal(const string& expected, const string& actual, bool skipheader) return true; } -///* ************************************************************************* */ -//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) { string str = add? "shared_ptr<" : ""; diff --git a/wrap/utilities.h b/wrap/utilities.h index 753aaf118..ee7997645 100644 --- a/wrap/utilities.h +++ b/wrap/utilities.h @@ -82,10 +82,6 @@ bool files_equal(const std::string& expected, const std::string& actual, bool sk */ bool assert_equal(const std::string& expected, const std::string& actual); bool assert_equal(const std::vector& expected, const std::vector& actual); -/** - * emit a header at the top of generated files - */ -//void generateHeaderComment(FileWriter& file, const std::string& delimiter); // auxiliary function to wrap an argument into a shared_ptr template std::string maybe_shared_ptr(bool add, const std::string& type);