From: <hug...@li...> - 2010-07-28 14:27:32
|
details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/40d2c64e8f3a changeset: 4164:40d2c64e8f3a user: Florian Achleitner <flo...@gm...> date: Tue Jul 27 12:22:58 2010 +0200 description: - Extract make exec with makefile input via a pipe and use it in test_filename --> double speed - capture stderr too details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/2fcd5c5ccfc2 changeset: 4165:2fcd5c5ccfc2 user: Florian Achleitner <flo...@gm...> date: Tue Jul 27 12:32:05 2010 +0200 description: add docu details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/bbbcff39b7ba changeset: 4166:bbbcff39b7ba user: Florian Achleitner <flo...@gm...> date: Tue Jul 27 22:37:31 2010 +0200 description: - make test_util wchar compatible - extend tester details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/e32b21d40e63 changeset: 4167:e32b21d40e63 user: Florian Achleitner <flo...@gm...> date: Wed Jul 28 09:15:55 2010 +0200 description: C++ify tester to overcome design problems. details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/08eea48ddb18 changeset: 4168:08eea48ddb18 user: Florian Achleitner <flo...@gm...> date: Wed Jul 28 10:29:09 2010 +0200 description: add TestConditional diffstat: src/hugin_base/makefilelib/CMakeLists.txt | 7 +- src/hugin_base/makefilelib/test_filenames.cpp | 34 ++- src/hugin_base/makefilelib/test_makefilelib.cpp | 170 +++++++++++++++-------- src/hugin_base/makefilelib/test_util.cpp | 117 ++++++++++++++++ src/hugin_base/makefilelib/test_util.h | 48 ++++++ 5 files changed, 300 insertions(+), 76 deletions(-) diffs (truncated from 515 to 500 lines): diff -r d735217f801b -r 08eea48ddb18 src/hugin_base/makefilelib/CMakeLists.txt --- a/src/hugin_base/makefilelib/CMakeLists.txt Tue Jul 27 00:04:46 2010 +0200 +++ b/src/hugin_base/makefilelib/CMakeLists.txt Wed Jul 28 10:29:09 2010 +0200 @@ -20,14 +20,15 @@ # additional libs target_link_libraries(makefilelib ${Boost_LIBRARIES}) - +# test_util +add_library(test_util STATIC test_util.cpp test_util.h) # tester executable add_executable(test_simple main.cpp) target_link_libraries(test_simple makefilelib) add_executable(test_filenames test_filenames.cpp) -target_link_libraries(test_filenames makefilelib ${Boost_LIBRARIES}) +target_link_libraries(test_filenames test_util makefilelib ${Boost_LIBRARIES}) add_executable(test_makefilelib test_makefilelib.cpp) -target_link_libraries(test_makefilelib makefilelib ${Boost_LIBRARIES}) \ No newline at end of file +target_link_libraries(test_makefilelib test_util makefilelib ${Boost_LIBRARIES}) \ No newline at end of file diff -r d735217f801b -r 08eea48ddb18 src/hugin_base/makefilelib/test_filenames.cpp --- a/src/hugin_base/makefilelib/test_filenames.cpp Tue Jul 27 00:04:46 2010 +0200 +++ b/src/hugin_base/makefilelib/test_filenames.cpp Wed Jul 28 10:29:09 2010 +0200 @@ -21,11 +21,14 @@ #include "Conditional.h" #include "StringAdapter.h" +#include "test_util.h" + #include <iostream> #include <locale> #include <vector> using namespace makefile; +using namespace makefile::tester; namespace fs = boost::filesystem; #ifdef USE_WCHAR @@ -36,6 +39,8 @@ ostream& cerr = std::cerr; #endif +#define START 0x20 + /** * Prints the tested characters. * @param out @@ -60,7 +65,7 @@ { std::vector<path> miss; char_type c[] = cstr("X.1"); - for(*c = 0x20; static_cast<uchar_type>(*c) < limit; (*c)++) + for(*c = START; static_cast<uchar_type>(*c) < limit; (*c)++) { path filename(c); ofstream file(dir / filename); @@ -92,10 +97,9 @@ const path makefile(cstr("makefile")); std::vector<path> miss; char_type c[] = cstr("X.1"); - for(*c = 0x20; static_cast<uchar_type>(*c) < limit; (*c)++) + for(*c = START; static_cast<uchar_type>(*c) < limit; (*c)++) { path filename(c); - ofstream makefilefile(dir / makefile); // If the filename cannot be stored in a Variable, theres no chance to bring it through. try { @@ -107,19 +111,22 @@ mffilename.getDef().add(); touch.add(); - makefile::Makefile::getSingleton().writeMakefile(makefilefile); - makefile::Makefile::clean(); - makefilefile.close(); string dirstring = dir.string(); - std::string command("cd " + StringAdapter(dirstring) + " && make"); - int makeerr = std::system(command.c_str()); + const char* argv[] = {"make", ("-C" + StringAdapter(dirstring)).c_str(), "-f-", NULL}; + std::stringbuf makeout, makeerr; + int ret = exec_make(argv, makeout, makeerr); - if(makeerr) - std::cerr << "make returned " << makeerr << std::endl; + + if(ret) + { + std::cerr << "make returned " << ret << std::endl; + std::cout << makeout.str(); + std::cerr << makeerr.str(); + } } catch(std::exception& e) { - std::cerr << "Variable exception: " << e.what() << "*c = " << static_cast<long>(*c) << std::endl; + std::cerr << "Variable exception: " << e.what() << std::endl; } if(!fs::exists(dir / filename)) @@ -159,7 +166,7 @@ }else{ limit = std::atoi(argv[1]); } - std::cout << "Creating " << static_cast<unsigned long>(limit) << " files in" << std::endl; + std::cout << "Creating " << static_cast<unsigned long>(limit) - START << " files in" << std::endl; path basepath(fs::initial_path<path>() / cstr("chartest_direct")); path basepathmake(fs::initial_path<path>() / cstr("chartest_make")); @@ -177,11 +184,12 @@ cout << cstr("Direct: Missing files ") << miss_direct.size() << std::endl; for(std::vector<path>::iterator i = miss_direct.begin(); i != miss_direct.end(); i++) cout << i->string() << cstr('\n'); - + cout << std::endl; std::vector<path> miss_make = createfiles_make(basepathmake, limit); cout << cstr("Make: Missing files ") << miss_make.size() << std::endl; for(std::vector<path>::iterator i = miss_make.begin(); i != miss_make.end(); i++) cout << i->string() << cstr('\n'); + cout << std::endl; return 0; } diff -r d735217f801b -r 08eea48ddb18 src/hugin_base/makefilelib/test_makefilelib.cpp --- a/src/hugin_base/makefilelib/test_makefilelib.cpp Tue Jul 27 00:04:46 2010 +0200 +++ b/src/hugin_base/makefilelib/test_makefilelib.cpp Wed Jul 28 10:29:09 2010 +0200 @@ -9,7 +9,7 @@ #include <iostream> #include <stdexcept> #include <cstdio> -#include <sys/wait.h> +#include <fstream> #include "Comment.h" #include "Variable.h" #include "VariableDef.h" @@ -22,6 +22,8 @@ #include "Conditional.h" #include "StringAdapter.h" +#include "test_util.h" + #include <boost/iostreams/stream.hpp> #include <boost/iostreams/device/file_descriptor.hpp> @@ -29,6 +31,8 @@ namespace fs = boost::filesystem; namespace io = boost::iostreams; +namespace makefile { namespace tester { + #ifdef USE_WCHAR ostream& cout = std::wcout; ostream& cerr = std::wcerr; @@ -37,80 +41,126 @@ ostream& cerr = std::cerr; #endif -bool run(const char* testname, const char* goodout) +struct TestComment : public Test { - // store 2 fd {read, write} - int fdmakein[2]; - int fdmakeout[2]; - if(pipe(fdmakein) || pipe(fdmakeout)) + Comment comment; + TestComment() + :Test("Comment", ""), + comment(cstr("First line")) { - std::cerr << "pipe() failed." << std::endl; - return false; + comment.appendLine(cstr("second line")); + comment.appendLine(cstr("third line\nfourth\r line")); + comment.add(); } - std::stringbuf makeoutbuf; +}; - if(fork()) - { // parent - close(fdmakein[0]); - close(fdmakeout[1]); +struct TestRule : public Test +{ + Rule rule, rule2; - io::stream<io::file_descriptor_sink> makein(fdmakein[1]); - io::stream<io::file_descriptor_source> makeout(fdmakeout[0]); - // Write the makefile to make's stdin - Makefile::getSingleton().writeMakefile(makein); - Makefile::getSingleton().clean(); - makein.close(); - makeout.get(makeoutbuf, '\0'); // delimiter \0 should read until eof. - wait(NULL); + TestRule() + :Test("Rule", "cp 1.in 1.out\ncp 2.in 2.out\nHello Make\n") + { + rule.addTarget(cstr("all")); + rule.addPrereq(cstr("1.out")); + rule.addPrereq(cstr("2.out")); + rule.addCommand(cstr("@echo Hello Make")); + rule.add(); + rule2.addTarget(cstr("%.out")); + rule2.addPrereq(cstr("%.in")); + rule2.addCommand(cstr("cp $*.in $@")); + rule2.add(); - } else { // child - close(fdmakein[1]); - close(fdmakeout[0]); - // replace stdin and stdout - if(dup2(fdmakein[0], 0) == -1 || dup2(fdmakeout[1], 1) == -1) - { - std::cerr << "Failed to switch std stream" << std::endl; - exit(-1); - } - - // execvp takes a NULL-terminated array of null-terminated strings. cool ;) - const char* const argv[] = {"make", "-f-", (char*) NULL}; - execvp(argv[0], (char* const*)argv); + std::ofstream in1("1.in"); in1.close(); + std::ofstream in2("2.in"); in2.close(); } - // Compare output - std::cout << "make says: " << makeoutbuf.str() << std::endl; - std::cout << testname << " "; - if(std::string(goodout) == makeoutbuf.str()) + bool precond() { - std::cout << "PASS" << std::endl; - return true; + return fs::exists("1.out") && fs::exists("2.out"); } - std::cout << "FAIL" << std::endl; - return false; + ~TestRule() + { + fs::remove("1.in"); fs::remove("2.in"); fs::remove("1.out"); fs::remove("2.out"); + } +}; + +struct TestConditional : public Test +{ + Variable var1, var2, var3, ifvar1, ifvar2, ifvar3, ifvar4, elsevar1, elsevar2, elsevar3, elsevar4; + ConditionalDEF cdef1, cdef2; + ConditionalEQ ceq1, ceq2; + Rule rule; + TestConditional() + :Test("Conditional", + "Results:\n" + "cond1 is true\n" + "cond2 is false\n" + "cond3 is true\n" + "cond4 is false\n"), + var1(cstr("VAR1"), cstr("equal")), + var2(cstr("VAR2"), cstr("equal")), + var3(cstr("VAR3"), cstr("nequal")), + ifvar1(cstr("TESTVAR1"), cstr("cond1 is true")), + ifvar2(cstr("TESTVAR2"), cstr("cond2 is true")), + ifvar3(cstr("TESTVAR3"), cstr("cond3 is true")), + ifvar4(cstr("TESTVAR4"), cstr("cond4 is true")), + elsevar1(ifvar1.getName(), cstr("cond1 is false")), + elsevar2(ifvar2.getName(), cstr("cond2 is false")), + elsevar3(ifvar3.getName(), cstr("cond3 is false")), + elsevar4(ifvar4.getName(), cstr("cond4 is false")), + cdef1(var1.getName()), + cdef2(cstr("THISISNOTDEFINED")), + ceq1(var1.getRef(), var2.getRef()), + ceq2(var1.getRef(), var3.getRef()) + { + var1.getDef().add(); + var2.getDef().add(); + var3.getDef().add(); + rule.addTarget(cstr("all")); + rule.addCommand(cstr("@echo Results:")); + rule.addCommand(cstr("@echo ") + ifvar1.getRef().toString()); + rule.addCommand(cstr("@echo ") + ifvar2.getRef().toString()); + rule.addCommand(cstr("@echo ") + ifvar3.getRef().toString()); + rule.addCommand(cstr("@echo ") + ifvar4.getRef().toString()); + + cdef1.addToIf(ifvar1.getDef()); + cdef1.addToElse(elsevar1.getDef()); + cdef2.addToIf(ifvar2.getDef()); + cdef2.addToElse(elsevar2.getDef()); + + ceq1.addToIf(ifvar3.getDef()); + ceq1.addToElse(elsevar3.getDef()); + ceq2.addToIf(ifvar4.getDef()); + ceq2.addToElse(elsevar4.getDef()); + + cdef1.add(); + cdef2.add(); + ceq1.add(); + ceq2.add(); + rule.add(); + +// ofstream mf("test.mk"); +// Makefile::getSingleton().writeMakefile(mf); + } +}; + +void do_test(bool& result, Test* test) +{ + result &= test->run(); + delete test; } -bool test_Comment() -{ - Comment comment(cstr("First line")); - comment.appendLine(cstr("second line")); - comment.appendLine(cstr("third line\nfourth\r line")); - comment.add(); - return run("Comment", ""); -} +}} // namespace +using namespace makefile::tester; -bool test_Rule() -{ - Rule rule; - rule.addTarget(cstr("all")); - rule.addCommand(cstr("@echo Hello Make")); - rule.add(); - return run("Rule", "Hello Make\n"); -} int main(int argc, char *argv[]) { bool result = true; - result &= test_Comment(); - result &= test_Rule(); + do_test(result, new TestComment); + do_test(result, new TestRule); + do_test(result, new TestConditional); return !result; // return 0 on success (= !true) } + + diff -r d735217f801b -r 08eea48ddb18 src/hugin_base/makefilelib/test_util.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugin_base/makefilelib/test_util.cpp Wed Jul 28 10:29:09 2010 +0200 @@ -0,0 +1,117 @@ +/** + * @file test_util.cpp + * @brief Useful functions for testers. + * Created on: Jul 27, 2010 + * @author Florian Achleitner <flo...@gm...> + */ + +#include <iostream> +#include <stdexcept> +#include <sstream> +#include <cstdio> +#include <sys/wait.h> +#include <iomanip> +#include "Makefile.h" +#include "test_util.h" + +#include <boost/iostreams/stream.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <boost/iostreams/code_converter.hpp> + +using namespace makefile; +namespace fs = boost::filesystem; +namespace io = boost::iostreams; + +namespace makefile { namespace tester { +/** + * Executes make with capturing stderr and stdout and feeding the makefile via stdin. + * @param argv as required by execvp (execvp takes a NULL-terminated array of null-terminated strings.) See manpage. + * @param makeoutbuf stdout of make goes here. + * @param makeerrbuf stderr of make goes here. + * @return return value of make. Uses macros to extract the value from wait(). See man wait. + */ +int exec_make(const char* const argv[], std::stringbuf& makeoutbuf, std::stringbuf& makeerrbuf) +{ + // store 2 fd per pipe {read, write} + int fdmakein[2]; + int fdmakeout[2]; + int fdmakeerr[2]; + if(pipe(fdmakein) || pipe(fdmakeout) || pipe(fdmakeerr)) + { + std::cerr << "pipe() failed." << std::endl; + return false; + } + + + if(fork()) + { // parent + close(fdmakein[0]); + close(fdmakeout[1]); + close(fdmakeerr[1]); + + // boost gives us a way to use those pipes in C++ style. + // the code_converter allows wchar mode Makefile to be written to a char-pipe +#ifdef USE_WCHAR + io::stream< io::code_converter<io::file_descriptor_sink> > makein(fdmakein[1]); +#else + io::stream<io::file_descriptor_sink> makein(fdmakein[1]); +#endif + io::stream<io::file_descriptor_source> makeout(fdmakeout[0]); + io::stream<io::file_descriptor_source> makeerr(fdmakeerr[0]); + + // Write the makefile to make's stdin + Makefile::getSingleton().writeMakefile(makein); + Makefile::getSingleton().clean(); + makein.close(); + + makeout.get(makeoutbuf, '\0'); // delimiter \0 should read until eof. + makeerr.get(makeerrbuf, '\0'); + + int status; + wait(&status); // status contains return value an some other flags + if(WIFEXITED(status)) // that can be evaluated by these macros (man wait) + { + return WEXITSTATUS(status); + } + // If WIFEXITED is false, something complicated happened (signal etc..). + std::cerr << "Command terminated abnormally. status=" << std::hex << status << std::endl; + return status; + + + } else { // child + close(fdmakein[1]); + close(fdmakeout[0]); + close(fdmakeerr[0]); + // replace stdin and stdout + if(dup2(fdmakein[0], 0) == -1 || dup2(fdmakeout[1], 1) == -1 || dup2(fdmakeerr[1], 2) == -1) + { + std::cerr << "Failed to switch std stream" << std::endl; + exit(-1); + } + + // execvp takes a NULL-terminated array of null-terminated strings. cool ;) + // like this const char* const argv[] = {"make", "-f-", (char*) NULL}; + execvp(argv[0], (char* const*)argv); + return -1; // exec should never return + } +} + +bool Test::run() +{ + const char* argv[] = {"make", "-f-", NULL}; + int status = exec_make(argv, makeoutbuf, makeerrbuf); + + std::cout << std::setw(30) << std::left << name; + if(eval()) + { + std::cout << "PASS" << std::endl; + return true; + } + std::cout << "FAIL" << std::endl; + std::cout << "ret: " << status << std::endl; + std::cout << "out: " << makeoutbuf.str() << std::endl; + std::cout << "cmp: " << goodout << std::endl; + std::cout << "err: " << makeerrbuf.str() << std::endl; + return false; +} +}} diff -r d735217f801b -r 08eea48ddb18 src/hugin_base/makefilelib/test_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugin_base/makefilelib/test_util.h Wed Jul 28 10:29:09 2010 +0200 @@ -0,0 +1,48 @@ +/** + * @file test_util.h + * @brief Prototype only. + * Created on: Jul 27, 2010 + * @author Florian Achleitner <flo...@gm...> + */ + +#ifndef TEST_UTIL_H_ +#define TEST_UTIL_H_ + +namespace makefile { namespace tester { +int exec_make(const char* const argv[], std::stringbuf& makeoutbuf, std::stringbuf& makeerrbuf); + +/** + * Base class for tests; + */ +class Test +{ + /// store makes output + std::stringbuf makeoutbuf, makeerrbuf; + /// Test's name + const char* name; + /// Output on stdout if test passes. + const char* goodout; + bool result; +public: + /// Prepare the MakefileItems + Test(const char* name_, const char* goodout_) + :name(name_), goodout(goodout_), result(false) {} + /// Eventual cleanup + virtual ~Test() {} + /// Execute the test + virtual bool run(); |
From: <hug...@li...> - 2010-08-09 15:33:28
|
details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/06085aca610f changeset: 4197:06085aca610f user: Florian Achleitner <flo...@gm...> date: Mon Aug 09 09:39:10 2010 +0200 description: - introduce a shortcut macro - remove all cstr() macro instances, this codes is not wchar aware at all. - more code details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/9c6081c38f44 changeset: 4198:9c6081c38f44 user: Florian Achleitner <flo...@gm...> date: Mon Aug 09 09:39:57 2010 +0200 description: Improve Variable: provide an unquoted value too details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/69006f5e31d5 changeset: 4199:69006f5e31d5 user: Florian Achleitner <flo...@gm...> date: Mon Aug 09 17:15:08 2010 +0200 description: more .. details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/4310a297512b changeset: 4200:4310a297512b user: Florian Achleitner <flo...@gm...> date: Mon Aug 09 17:26:27 2010 +0200 description: - Extend Variable to support vectors of values, often used for filenames. - template Manager::own_add details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/8cf8367f8ee2 changeset: 4201:8cf8367f8ee2 user: Florian Achleitner <flo...@gm...> date: Mon Aug 09 17:26:59 2010 +0200 description: simplify loop 4->1 diffstat: src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.cpp | 259 ++++++++- src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.h | 6 + src/hugin_base/makefilelib/AutoVariable.cpp | 8 +- src/hugin_base/makefilelib/AutoVariable.h | 3 +- src/hugin_base/makefilelib/Manager.h | 4 +- src/hugin_base/makefilelib/Variable.cpp | 49 +- src/hugin_base/makefilelib/Variable.h | 40 +- src/hugin_base/makefilelib/VariableDef.cpp | 2 +- src/hugin_base/makefilelib/test_makefilelib.cpp | 30 + 9 files changed, 332 insertions(+), 69 deletions(-) diffs (truncated from 658 to 500 lines): diff -r bb181c34d98c -r 8cf8367f8ee2 src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.cpp --- a/src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.cpp Fri Aug 06 17:28:30 2010 +0200 +++ b/src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.cpp Mon Aug 09 17:26:59 2010 +0200 @@ -31,91 +31,99 @@ #include <boost/smart_ptr/scoped_ptr.hpp> #include <boost/smart_ptr/shared_ptr.hpp> +/// Automates an very often occuring sequence +#define newVarDef(var, name, ...) \ +mf::Variable* var = mgr.own(new mf::Variable(name, __VA_ARGS__)); \ +var->getDef().add(); + namespace HuginBase { using namespace makefile; namespace mf = makefile; +/// constants +static const string hdrgrayRemappedExt = "_gray.pgm"; +static const string hdrRemappedExt = ".exr"; +const string ldrRemappedExt(".tif"); bool PanoramaMakefilelibExport::create() { mgr.own_add((new Comment( - cstr("makefile for panorama stitching, created by hugin using the new makefilelib")))); + "makefile for panorama stitching, created by hugin using the new makefilelib"))); //---------- // set temporary dir if defined if(!tmpDir.empty()) { #ifdef UNIX_LIKE - mgr.own_add(new Comment(cstr("set temporary directory for UNIX_LIKE"))); - mf::Variable* vtmpdir = mgr.own(new mf::Variable(cstr("TMPDIR"), tmpDir)); + mgr.own_add(new Comment("set temporary directory for UNIX_LIKE")); + mf::Variable* vtmpdir = mgr.own(new mf::Variable("TMPDIR", tmpDir)); vtmpdir->setExport(true); vtmpdir->getDef().add(); #else - mgr.own_add(new Comment(cstr("set temporary directory for not UNIX_LIKE"))); - mf::Variable* vtmpdir = mgr.own(new mf::Variable(cstr("TEMP"), tmpDir)); + mgr.own_add(new Comment("set temporary directory for not UNIX_LIKE")); + mf::Variable* vtmpdir = mgr.own(new mf::Variable("TEMP", tmpDir)); vtmpdir->setExport(true); vtmpdir->getDef().add(); - mf::Variable* vtmpdir2 = mgr.own(new mf::Variable(cstr("TMP"), tmpDir)); + mf::Variable* vtmpdir2 = mgr.own(new mf::Variable("TMP", tmpDir)); vtmpdir2->setExport(true); vtmpdir2->getDef().add(); #endif } #ifdef _WINDOWS - mgr.own_add(new Comment(cstr("Force using cmd.exe")); cwinshell.add()); - mf::Variable* winshell = mgr_own(new Variable(cstr("SHELL"), getenv("ComSpec"))); + mgr.own_add(new Comment("Force using cmd.exe"); cwinshell.add()); + mf::Variable* winshell = mgr_own(new Variable("SHELL", getenv("ComSpec"))); winshell->getDef().add(); #endif //---------- // set the tool commands - mgr.own_add(new Comment(cstr("Tool configuration"))); - mf::Variable* vnona = mgr.own(new mf::Variable(cstr("NONA"), progs.nona)); vnona->getDef().add(); - mf::Variable* vPTStitcher = mgr.own(new mf::Variable(cstr("PTSTITCHER"), progs.PTStitcher)); vPTStitcher->getDef().add(); - mf::Variable* vPTmender = mgr.own(new mf::Variable(cstr("PTMENDER"), progs.PTmender)); vPTmender->getDef().add(); - mf::Variable* vPTblender = mgr.own(new mf::Variable(cstr("PTBLENDER"), progs.PTblender)); vPTblender->getDef().add(); - mf::Variable* vPTmasker = mgr.own(new mf::Variable(cstr("PTMASKER"), progs.PTmasker)); vPTmasker->getDef().add(); - mf::Variable* vPTroller = mgr.own(new mf::Variable(cstr("PTROLLER"), progs.PTroller)); vPTroller->getDef().add(); - mf::Variable* venblend = mgr.own(new mf::Variable(cstr("ENBLEND"), progs.enblend)); venblend->getDef().add(); - mf::Variable* venfuse = mgr.own(new mf::Variable(cstr("ENFUSE"), progs.enfuse)); venfuse->getDef().add(); - mf::Variable* vsmartblend = mgr.own(new mf::Variable(cstr("SMARTBLEND"), progs.smartblend)); vsmartblend->getDef().add(); - mf::Variable* vhdrmerge = mgr.own(new mf::Variable(cstr("HDRMERGE"), progs.hdrmerge)); vhdrmerge->getDef().add(); + mgr.own_add(new Comment("Tool configuration")); + newVarDef(vnona, "NONA", progs.nona); + newVarDef(vPTStitcher, "PTSTITCHER", progs.PTStitcher); + newVarDef(vPTmender, "PTMENDER", progs.PTmender); + newVarDef(vPTblender, "PTBLENDER", progs.PTblender); + newVarDef(vPTmasker, "PTMASKER", progs.PTmasker); + newVarDef(vPTroller, "PTROLLER", progs.PTroller); + newVarDef(venblend, "ENBLEND", progs.enblend); + newVarDef(venfuse, "ENFUSE", progs.enfuse); + newVarDef(vsmartblend, "SMARTBLEND", progs.smartblend); + newVarDef(vhdrmerge, "HDRMERGE", progs.hdrmerge); #ifdef _WINDOWS - mf::Variable* vrm = mgr.own(new mf::Variable(cstr("RM"), cstr("del"))); + newVarDef(vrm, "RM", "del"); #else - mf::Variable* vrm = mgr.own(new mf::Variable(cstr("RM"), cstr("rm"))); + newVarDef(vrm, "RM", "rm"); #endif - vrm->getDef().add(); //---------- // if this is defined and we have .app in the exiftool command, we execute it with perl by prepending perl -w // to the command name. #ifdef MAC_SELF_CONTAINED_BUNDLE - mf::Variable* vexiftool = mgr.own(new mf::Variable(cstr("EXIFTOOL"), + mf::Variable* vexiftool = mgr.own(new mf::Variable("EXIFTOOL", progs.exiftool.find(".app") != std::string::npos ? - cstr("perl -w ") + progs.exiftool : + "perl -w " + progs.exiftool : progs.exiftool)); #else - mf::Variable* vexiftool = mgr.own(new mf::Variable(cstr("EXIFTOOL"), progs.exiftool)); + mf::Variable* vexiftool = mgr.own(new mf::Variable("EXIFTOOL", progs.exiftool)); #endif vexiftool->getDef().add(); //---------- // Project parameters - mgr.own_add(new Comment(cstr("Project parameters"))); + mgr.own_add(new Comment("Project parameters")); PanoramaOptions opts = pano.getOptions(); - mf::Variable* vhugin_projection = mgr.own(new mf::Variable(cstr("HUGIN_PROJECTION"), + mf::Variable* vhugin_projection = mgr.own(new mf::Variable("HUGIN_PROJECTION", opts.getProjection())); vhugin_projection->getDef().add(); - mf::Variable* vhugin_hfov = mgr.own(new mf::Variable(cstr("HUGIN_HFOV"), opts.getHFOV())); + mf::Variable* vhugin_hfov = mgr.own(new mf::Variable("HUGIN_HFOV", opts.getHFOV())); vhugin_hfov->getDef().add(); - mf::Variable* vhugin_width = mgr.own(new mf::Variable(cstr("HUGIN_WIDTH"), opts.getWidth())); + mf::Variable* vhugin_width = mgr.own(new mf::Variable("HUGIN_WIDTH", opts.getWidth())); vhugin_width->getDef().add(); - mf::Variable* vhugin_height = mgr.own(new mf::Variable(cstr("HUGIN_HEIGHT"), opts.getHeight())); - vhugin_width->getDef().add(); + mf::Variable* vhugin_height = mgr.own(new mf::Variable("HUGIN_HEIGHT", opts.getHeight())); + vhugin_height->getDef().add(); //---------- // options for the programs - mgr.own_add(new Comment(cstr("options for the programs"))); + mgr.own_add(new Comment("options for the programs")); // set remapper specific settings mf::Variable* vnonaldr = NULL; mf::Variable* vnonaopts = NULL; @@ -127,10 +135,10 @@ else if (opts.outputImageType == "jpg") val = "-z PACKBITS "; - vnonaldr = mgr.own(new mf::Variable(cstr("NONA_LDR_REMAPPED_COMP"), val, Makefile::NONE)); + vnonaldr = mgr.own(new mf::Variable("NONA_LDR_REMAPPED_COMP", val, Makefile::NONE)); vnonaldr->getDef().add(); - vnonaopts = mgr.own(new mf::Variable(cstr("NONA_OPTS"), + vnonaopts = mgr.own(new mf::Variable("NONA_OPTS", opts.remapUsingGPU ? "-g " : "", Makefile::NONE)); vnonaopts->getDef().add(); } @@ -153,7 +161,7 @@ valuestream << " -f" << roi.width() << "x" << roi.height() << "+" << roi.left() << "+" << roi.top(); else valuestream << " -f" << roi.width() << "x" << roi.height(); - venblendopts = mgr.own(new mf::Variable(cstr("ENBLEND_OPTS"), valuestream.str(), Makefile::NONE)); + venblendopts = mgr.own(new mf::Variable("ENBLEND_OPTS", valuestream.str(), Makefile::NONE)); venblendopts->getDef().add(); } @@ -164,7 +172,7 @@ else if (opts.outputImageType == "jpg") valuestream << "--compression " << opts.quality; - venblendldrcomp = mgr.own(new mf::Variable(cstr("ENBLEND_LDR_COMP"), valuestream.str(), Makefile::NONE)); + venblendldrcomp = mgr.own(new mf::Variable("ENBLEND_LDR_COMP", valuestream.str(), Makefile::NONE)); venblendldrcomp->getDef().add(); } @@ -173,7 +181,7 @@ if (opts.outputImageTypeHDR == "tif" && opts.outputImageTypeHDRCompression.size() != 0) { val += "--compression " + opts.outputImageTypeHDRCompression; } - venblendhdrcomp = mgr.own(new mf::Variable(cstr("ENBLEND_HDR_COMP"), val, Makefile::NONE)); + venblendhdrcomp = mgr.own(new mf::Variable("ENBLEND_HDR_COMP", val, Makefile::NONE)); venblendhdrcomp->getDef().add(); } } @@ -196,30 +204,191 @@ valuestream << " -k " << opts.colorReferenceImage; break; } - vptblenderopts = mgr.own(new mf::Variable(cstr("PTBLENDER_OPTS"), valuestream.str(), Makefile::NONE)); + vptblenderopts = mgr.own(new mf::Variable("PTBLENDER_OPTS", valuestream.str(), Makefile::NONE)); vptblenderopts->getDef().add(); } + //---------- mf::Variable* vsmartblendopts = NULL; if(opts.blendMode == PanoramaOptions::SMARTBLEND_BLEND) { - vsmartblendopts = mgr.own(new mf::Variable(cstr("SMARTBLEND_OPTS"), - opts.getHFOV() == 360.0 ? cstr(" -w") : cstr(""))); + vsmartblendopts = mgr.own(new mf::Variable( + "SMARTBLEND_OPTS", + opts.getHFOV() == 360.0 ? " -w" : "")); + vsmartblendopts->getDef().add(); // TODO: build smartblend command line from given images. (requires additional program) } - //---------- - //---------- - //---------- - //---------- + mf::Variable* vhdrmergeopts = NULL; + if(opts.hdrMergeMode == PanoramaOptions::HDRMERGE_AVERAGE) + { + vhdrmergeopts = mgr.own(new mf::Variable( + "HDRMERGE_OPTS", opts.hdrmergeOptions, Makefile::NONE)); + vhdrmergeopts->getDef().add(); + } - makefile.imbue(Makefile::locale); + //---------- + newVarDef(venfuseopts, + "ENFUSE_OPTS", + opts.getHFOV() == 360.0 ? " -w" : "", Makefile::NONE); + + //---------- + newVarDef(vexiftoolcopyargs, + "EXIFTOOL_COPY_ARGS", progs.exiftool_opts, Makefile::NONE); + + + //---------- + // Panorama output + mgr.own_add(new Comment("the output panorama")); + + newVarDef(vldrremappedprefix, + "LDR_REMAPPED_PREFIX", outputPrefix, Makefile::MAKE); + newVarDef(vldrremappedprefixshell, + "LDR_REMAPPED_PREFIX_SHELL", vldrremappedprefix->getValue(), Makefile::SHELL); + + newVarDef(vhdrstackremappedprefix, + "HDR_STACK_REMAPPED_PREFIX", outputPrefix + "_hdr_", Makefile::MAKE); + newVarDef(vhdrstackremappedprefixshell, + "HDR_STACK_REMAPPED_PREFIX_SHELL", vhdrstackremappedprefix->getValue(), Makefile::SHELL); + + newVarDef(vldrexposureremappedprefix, + "LDR_EXPOSURE_REMAPPED_PREFIX", outputPrefix + "_exposure_layers_", Makefile::MAKE); + newVarDef(vldrexposureremappedprefixshell, + "LDR_EXPOSURE_REMAPPED_PREFIX_SHELL", vldrexposureremappedprefix->getValue(), Makefile::SHELL); + + newVarDef(vprojectfile, "PROJECT_FILE", ptofile, Makefile::MAKE); + newVarDef(vprojectfileshell, "PROJECT_FILE_SHELL", ptofile, Makefile::SHELL); + + newVarDef(vldrblended, "LDR_BLENDED", outputPrefix + "." + opts.outputImageType, Makefile::MAKE); + newVarDef(vldrblendedshell, "LDR_BLENDED_SHELL", vldrblended->getValue(), Makefile::SHELL); + + newVarDef(vldrstackedblended, "LDR_STACKED_BLENDED", outputPrefix + "_fused." + opts.outputImageType, Makefile::MAKE); + newVarDef(vldrstackedblendedshell, "LDR_STACKED_BLENDED_SHELL", vldrstackedblended->getValue(), Makefile::SHELL); + + newVarDef(vldrexposurelayersfused, + "LDR_EXPOSURE_LAYERS_FUSED", outputPrefix + "_blended_fused." + opts.outputImageType, Makefile::MAKE); + newVarDef(vldrexposurelayersfusedshell, + "LDR_EXPOSURE_LAYERS_FUSED_SHELL", vldrexposurelayersfused->getValue(), Makefile::SHELL); + + newVarDef(vhdrblended, "HDR_BLENDED", outputPrefix + "_hdr." + opts.outputImageTypeHDR, Makefile::MAKE); + newVarDef(vhdrblendedshell, "HDR_BLENDED_SHELL", vhdrblended->getValue(), Makefile::SHELL); + + //---------- + // Input Image filenames + mgr.own_add(new Comment ("first input image")); + newVarDef(vinimage1, "INPUT_IMAGE_1", pano.getImage(0).getFilename(), Makefile::MAKE); + newVarDef(vinimage1shell, "INPUT_IMAGE_1_SHELL", pano.getImage(0).getFilename(), Makefile::SHELL); + + mgr.own_add(new Comment("all input images")); + // Assemble them all into one string + std::vector<std::string> inimages; + + for (unsigned int i=0; i < pano.getNrOfImages(); i++) + { + inimages.push_back(pano.getImage(i).getFilename()); + } + newVarDef(vinimages, "INPUT_IMAGES", inimages.begin(), inimages.end(), Makefile::MAKE, "\\\n"); + newVarDef(vinimagesshell, "INPUT_IMAGES_SHELL", inimages.begin(), inimages.end(), Makefile::SHELL, "\\\n"); + + //---------- + std::vector<std::string> remappedImages; + std::vector<std::string> remappedHDRImages; + std::vector<std::string> remappedHDRgrayImages; + + for (UIntSet::iterator it = images.begin(); it != images.end(); it++) + { + std::ostringstream fn1, fn2, fn3; + fn1 << outputPrefix << std::setfill('0') << std::setw(4) << *it << ldrRemappedExt; + fn2 << outputPrefix << "_hdr_" << std::setfill('0') << std::setw(4) << *it << hdrRemappedExt; + fn3 << outputPrefix << "_hdr_" << std::setfill('0') << std::setw(4) << *it << hdrgrayRemappedExt; + remappedImages.push_back(fn1.str()); + remappedHDRImages.push_back(fn2.str()); + remappedHDRgrayImages.push_back(fn3.str()); + } + mgr.own_add(new Comment("remapped images")); + newVarDef(vldrlayers, "LDR_LAYERS", remappedImages.begin(), remappedImages.end(), Makefile::MAKE, "\\\n"); + newVarDef(vldrlayersshell, "LDR_LAYERS_SHELL", remappedImages.begin(), remappedImages.end(), Makefile::SHELL, "\\\n"); + + mgr.own_add(new Comment("remapped images (hdr)")); + newVarDef(vhdrlayers, "HDR_LAYERS", remappedHDRImages.begin(), remappedHDRImages.end(), Makefile::MAKE, "\\\n"); + newVarDef(vhdrlayersshell, "HDR_LAYERS_SHELL", remappedHDRImages.begin(), remappedHDRImages.end(), Makefile::SHELL, "\\\n"); + + mgr.own_add(new Comment("remapped maxval images")); + newVarDef(vhdrgraylayers, "HDR_LAYERS_WEIGHTS", remappedHDRgrayImages.begin(), remappedHDRgrayImages.end(), Makefile::MAKE, "\\\n"); + newVarDef(vhdrgraylayersshell, "HDR_LAYERS_WEIGHTS_SHELL", remappedHDRgrayImages.begin(), remappedHDRgrayImages.end(), Makefile::SHELL, "\\\n"); + + //---------- + // hdr stacks + std::vector<mf::Variable*> hdr_stacks; + std::vector<mf::Variable*> hdr_stacks_shell; + std::vector<mf::Variable*> hdr_stacks_input; + std::vector<makefile::Variable*> hdr_stacks_input_shell; + createhdrstacks(hdr_stacks, hdr_stacks_shell, hdr_stacks_input, hdr_stacks_input_shell); + + + Makefile::getSingleton().writeMakefile(makefile); Makefile::getSingleton().clean(); return true; } +std::vector<UIntSet> getHDRStacks(const PanoramaData & pano, UIntSet allImgs); +void PanoramaMakefilelibExport::createhdrstacks(std::vector<mf::Variable*>& hdr_stacks, + std::vector<mf::Variable*>& hdr_stacks_shell, + std::vector<mf::Variable*>& hdr_stacks_input, + std::vector<makefile::Variable*>& hdr_stacks_input_shell) +{ + std::vector<UIntSet> stacks = getHDRStacks(pano, images); + mgr.own_add(new Comment("stacked images")); + std::ostringstream stknrs; + for (unsigned i=0; i < stacks.size(); i++) + { + stknrs << i << " "; + std::ostringstream filename, stackname; + filename << outputPrefix << "_stack_hdr_" << std::setfill('0') << std::setw(4) << i << hdrRemappedExt; + stackname << "HDR_STACK_" << i; + + std::vector<std::string> inputs; + for (UIntSet::iterator it = stacks[i].begin(); it != stacks[i].end(); it++) + { + std::ostringstream fns; + fns << outputPrefix << "_hdr_" << std::setfill('0') << std::setw(4) << *it << hdrRemappedExt; + inputs.push_back(fns.str()); + } + mf::Variable* v; + v = mgr.own(new mf::Variable(stackname.str(), filename.str(), Makefile::MAKE)); + hdr_stacks.push_back(v); + v->getDef().add(); + + v = mgr.own(new mf::Variable(stackname.str() + "_SHELL", filename.str(), Makefile::SHELL)); + hdr_stacks_shell.push_back(v); + v->getDef().add(); + + v= mgr.own(new mf::Variable(stackname.str() + "_INPUT", inputs.begin(), inputs.end(), Makefile::MAKE, "\\\n")); + hdr_stacks_input.push_back(v); + v->getDef().add(); + + v = mgr.own(new mf::Variable(stackname.str() + "_INPUT_SHELL", inputs.begin(), inputs.end(), Makefile::SHELL, "\\\n")); + hdr_stacks_input_shell.push_back(v); + v->getDef().add(); + } + newVarDef(vhdrstacksnr, "HDR_STACKS_NUMBERS", stknrs.str(), Makefile::NONE); + + std::string stackrefs; + std::string stackrefsshell; + std::vector<mf::Variable*>::iterator it, it2; + it = hdr_stacks.begin(); + it2 = hdr_stacks_shell.begin(); + for(; it != hdr_stacks.end() && it2 != hdr_stacks_shell.end(); it++, it2++) + { + stackrefs += (*it)->getRef().toString() + " "; + stackrefsshell += (*it2)->getRef().toString() + " "; + } + newVarDef(vstacks, "HDR_STACKS", stackrefs, Makefile::NONE); + newVarDef(vstacksshell, "HDR_STACKS_SHELL", stackrefsshell, Makefile::NONE); } + +} diff -r bb181c34d98c -r 8cf8367f8ee2 src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.h --- a/src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.h Fri Aug 06 17:28:30 2010 +0200 +++ b/src/hugin_base/algorithms/panorama_makefile/PanoramaMakefilelibExport.h Mon Aug 09 17:26:59 2010 +0200 @@ -14,6 +14,7 @@ #include <iosfwd> #include <makefilelib/Manager.h> #include <makefilelib/Makefile.h> +#include <makefilelib/Variable.h> /** @@ -74,6 +75,11 @@ std::ostringstream valuestream; bool create(); + + void createhdrstacks(std::vector<makefile::Variable*>& hdr_stacks, + std::vector<makefile::Variable*>& hdr_stacks_shell, + std::vector<makefile::Variable*>& hdr_stacks_input, + std::vector<makefile::Variable*>& hdr_stacks_input_shell); public: PanoramaMakefilelibExport(PanoramaData & pano_, const UIntSet & images_, diff -r bb181c34d98c -r 8cf8367f8ee2 src/hugin_base/makefilelib/AutoVariable.cpp --- a/src/hugin_base/makefilelib/AutoVariable.cpp Fri Aug 06 17:28:30 2010 +0200 +++ b/src/hugin_base/makefilelib/AutoVariable.cpp Mon Aug 09 17:26:59 2010 +0200 @@ -15,12 +15,16 @@ return 0; } -string AutoVariable::getValue() +inline const string AutoVariable::getValue() { throw(std::runtime_error("AutoVariables have no predefined value.")); } +inline const string AutoVariable::getquotedValue() +{ + return getValue(); +} -VariableDef& AutoVariable::getDef() +inline VariableDef& AutoVariable::getDef() { throw(std::runtime_error("AutoVariables can not be defined.")); } diff -r bb181c34d98c -r 8cf8367f8ee2 src/hugin_base/makefilelib/AutoVariable.h --- a/src/hugin_base/makefilelib/AutoVariable.h Fri Aug 06 17:28:30 2010 +0200 +++ b/src/hugin_base/makefilelib/AutoVariable.h Mon Aug 09 17:26:59 2010 +0200 @@ -33,7 +33,8 @@ {}; /// Has no value, exception. - virtual string getValue(); + virtual const string getValue(); + virtual const string getquotedValue(); /// Has no definition, exception. virtual VariableDef& getDef(); diff -r bb181c34d98c -r 8cf8367f8ee2 src/hugin_base/makefilelib/Manager.h --- a/src/hugin_base/makefilelib/Manager.h Fri Aug 06 17:28:30 2010 +0200 +++ b/src/hugin_base/makefilelib/Manager.h Mon Aug 09 17:26:59 2010 +0200 @@ -59,10 +59,12 @@ * with any further. * @param item */ - void own_add(PrimaryMakefileItem* item) + template<class MI> + MI* own_add(MI* item) { own(item); item->add(); + return item; } }; diff -r bb181c34d98c -r 8cf8367f8ee2 src/hugin_base/makefilelib/Variable.cpp --- a/src/hugin_base/makefilelib/Variable.cpp Fri Aug 06 17:28:30 2010 +0200 +++ b/src/hugin_base/makefilelib/Variable.cpp Mon Aug 09 17:26:59 2010 +0200 @@ -9,7 +9,7 @@ #include "StringAdapter.h" #include <stdexcept> #include <sstream> - +#include <algorithm> namespace makefile { @@ -32,17 +32,56 @@ */ void Variable::checkValue() { - static const regex invalid(cstr("\\R")); - if(boost::regex_search(value, invalid)) - throw std::invalid_argument("Bad Variable value: " + StringAdapter(value)); + static const regex invalid(cstr("[^\\\\]\\R")); + if(boost::regex_search(getValue(), invalid)) + throw std::invalid_argument("Bad Variable value: " + StringAdapter(getValue())); } +Variable::Variable(string name_, string value_, Makefile::QuoteMode quotemode_) +: name(name_), def(*this), ref(*this), quotemode(quotemode_), exported(false) +{ + values.push_back(value_); + checkName(); + checkValue(); +} Variable::Variable(string name_, double value_, Makefile::QuoteMode quotemode_) : name(name_), def(*this), ref(*this), quotemode(quotemode_), exported(false) { + checkName(); std::ostringstream val; val.imbue(Makefile::locale); val << value_; - value = val.str(); + values.push_back(val.str()); } + +Variable::Variable(string name_, std::vector<string>::iterator start, std::vector<string>::iterator end, + Makefile::QuoteMode quotemode_, string separator_) +: name(name_), separator(separator_), def(*this), ref(*this), quotemode(quotemode_), exported(false) +{ + checkName(); + copy(start, end, std::back_inserter(values)); + checkValue(); } |
From: <hug...@li...> - 2010-09-11 12:46:25
|
details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/cc9934911679 changeset: 4335:cc9934911679 user: tmodes date: Sat Sep 11 14:13:00 2010 +0200 description: Bug fix for running icpfind (Windows only) details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/ff81bf9151c4 changeset: 4336:ff81bf9151c4 user: tmodes date: Sat Sep 11 14:14:09 2010 +0200 description: Allow saving of log output * hugin_stitch_project manually with file select dialog * PTBatcherGUI automatically for failed projects details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/6a01edd02d52 changeset: 4337:6a01edd02d52 user: tmodes date: Sat Sep 11 14:43:19 2010 +0200 description: If cp detector has no path given, search also in hugins bin directory for suitable program (Windows only) details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/d4fea37964ba changeset: 4338:d4fea37964ba user: tmodes date: Sat Sep 11 14:45:03 2010 +0200 description: Assistant: Run cp detector always when there are unconnected images groups (not only when there are no cp) details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgrepo/h/hu/hugin/hugin/rev/b476a602385d changeset: 4339:b476a602385d user: tmodes date: Sat Sep 11 14:45:27 2010 +0200 description: Unified line endings diffstat: src/hugin1/base_wx/MyExternalCmdExecDialog.cpp | 4 + src/hugin1/base_wx/MyExternalCmdExecDialog.h | 3 + src/hugin1/base_wx/RunStitchPanel.cpp | 5 + src/hugin1/base_wx/RunStitchPanel.h | 3 + src/hugin1/hugin/xrc/batch_frame.xrc | 65 ++++ src/hugin1/icpfind/AutoCtrlPointCreator.cpp | 40 +- src/hugin1/ptbatcher/Batch.cpp | 54 +++- src/hugin1/ptbatcher/Batch.h | 17 + src/hugin1/ptbatcher/BatchFrame.cpp | 51 +- src/hugin1/ptbatcher/BatchFrame.h | 2 + src/hugin1/ptbatcher/CMakeLists.txt | 4 +- src/hugin1/ptbatcher/FailedProjectsDialog.cpp | 136 ++++++++ src/hugin1/ptbatcher/FailedProjectsDialog.h | 61 ++++ src/hugin1/ptbatcher/RunStitchFrame.cpp | 16 +- src/hugin1/ptbatcher/RunStitchFrame.h | 4 + src/hugin1/stitch_project/hugin_stitch_project.cpp | 21 +- src/hugin_base/algorithms/assistant_makefile/AssistantMakefilelibExport.cpp | 20 +- src/tools/checkpto.cpp | 152 +++++----- 18 files changed, 511 insertions(+), 147 deletions(-) diffs (truncated from 929 to 500 lines): diff -r fc38b89e608e -r b476a602385d src/hugin1/base_wx/MyExternalCmdExecDialog.cpp --- a/src/hugin1/base_wx/MyExternalCmdExecDialog.cpp Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/base_wx/MyExternalCmdExecDialog.cpp Sat Sep 11 14:45:27 2010 +0200 @@ -514,6 +514,10 @@ #endif } +bool MyExecPanel::SaveLog(const wxString &filename) +{ + return m_textctrl->SaveFile(filename); +}; // ---------------------------------------------------------------------------- // MyProcess diff -r fc38b89e608e -r b476a602385d src/hugin1/base_wx/MyExternalCmdExecDialog.h --- a/src/hugin1/base_wx/MyExternalCmdExecDialog.h Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/base_wx/MyExternalCmdExecDialog.h Sat Sep 11 14:45:27 2010 +0200 @@ -74,6 +74,9 @@ // for MyPipedProcess void OnProcessTerminated(MyPipedProcess *process, int pid, int status); //wxListBox *GetLogListBox() const { return m_lbox; } + /** save the content of the window into a given log file + @return true if log was saved successful */ + bool SaveLog(const wxString &filename); virtual ~MyExecPanel(); diff -r fc38b89e608e -r b476a602385d src/hugin1/base_wx/RunStitchPanel.cpp --- a/src/hugin1/base_wx/RunStitchPanel.cpp Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/base_wx/RunStitchPanel.cpp Sat Sep 11 14:45:27 2010 +0200 @@ -421,3 +421,8 @@ { return m_execPanel->GetPid(); } + +bool RunStitchPanel::SaveLog(const wxString &filename) +{ + return m_execPanel->SaveLog(filename); +}; diff -r fc38b89e608e -r b476a602385d src/hugin1/base_wx/RunStitchPanel.h --- a/src/hugin1/base_wx/RunStitchPanel.h Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/base_wx/RunStitchPanel.h Sat Sep 11 14:45:27 2010 +0200 @@ -72,6 +72,9 @@ void PauseStitch(); void ContinueStitch(); long GetPid(); + /** save the content of the window into a given log file + @return true if log was saved successful */ + bool SaveLog(const wxString &filename); private: bool m_paused; diff -r fc38b89e608e -r b476a602385d src/hugin1/hugin/xrc/batch_frame.xrc --- a/src/hugin1/hugin/xrc/batch_frame.xrc Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/hugin/xrc/batch_frame.xrc Sat Sep 11 14:45:27 2010 +0200 @@ -288,4 +288,69 @@ </object> </object> </object> + <object class="wxDialog" name="failed_project_dialog"> + <title>Status report</title> + <object class="wxBoxSizer"> + <orient>wxVERTICAL</orient> + <object class="sizeritem"> + <object class="wxBoxSizer"> + <orient>wxHORIZONTAL</orient> + <object class="sizeritem"> + <object class="wxSplitterWindow"> + <object class="wxPanel"> + <object class="wxStaticBoxSizer"> + <label>Failed projects</label> + <orient>wxVERTICAL</orient> + <object class="sizeritem"> + <object class="wxListBox" name="failed_list"> + <content/> + <style>wxLB_SINGLE</style> + </object> + <option>1</option> + <flag>wxALL|wxEXPAND</flag> + <border>6</border> + </object> + </object> + </object> + <object class="wxPanel"> + <object class="wxStaticBoxSizer"> + <label>Output</label> + <orient>wxVERTICAL</orient> + <object class="sizeritem"> + <object class="wxTextCtrl" name="failed_log"> + <style>wxTE_MULTILINE|wxTE_READONLY</style> + </object> + <option>1</option> + <flag>wxALL|wxEXPAND</flag> + <border>6</border> + </object> + </object> + </object> + <orientation>vertical</orientation> + <style>wxSP_NOBORDER|wxSP_NO_XP_THEME</style> + </object> + <option>1</option> + <flag>wxALL|wxEXPAND</flag> + </object> + </object> + <option>1</option> + <flag>wxALL|wxEXPAND</flag> + <border>5</border> + </object> + <object class="sizeritem"> + <object class="wxStdDialogButtonSizer"> + <object class="button"> + <object class="wxButton" name="wxID_OK"> + <label></label> + <label>&Close</label> + <default>1</default> + </object> + </object> + </object> + <flag>wxALL|wxEXPAND</flag> + <border>6</border> + </object> + </object> + <style>wxDEFAULT_DIALOG_STYLE|wxSYSTEM_MENU|wxRESIZE_BORDER|wxRESIZE_BOX|wxCLOSE_BOX</style> + </object> </resource> \ No newline at end of file diff -r fc38b89e608e -r b476a602385d src/hugin1/icpfind/AutoCtrlPointCreator.cpp --- a/src/hugin1/icpfind/AutoCtrlPointCreator.cpp Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/icpfind/AutoCtrlPointCreator.cpp Sat Sep 11 14:45:27 2010 +0200 @@ -151,8 +151,24 @@ wxString bundled=GetBundledProg(progName); if(!bundled.IsEmpty()) return bundled; +#else +#ifdef __WXMSW__ + wxFileName prog(progName); + if(prog.IsAbsolute()) + { + return progName; + } + else + { + wxPathList pathlist; + pathlist.Add(getExePath(wxTheApp->argv[0])); + pathlist.AddEnvList(wxT("PATH")); + return pathlist.FindAbsoluteValidPath(progName); + }; +#else + return progName; #endif - return progName; +#endif }; bool CanStartProg(wxString progName,wxWindow* parent) @@ -170,6 +186,9 @@ else { wxPathList pathlist; +#ifdef __WXMSW__ + pathlist.Add(getExePath(wxTheApp->argv[0])); +#endif pathlist.AddEnvList(wxT("PATH")); wxString path = pathlist.FindAbsoluteValidPath(progName); if(path.IsEmpty()) @@ -452,16 +471,6 @@ wxString generateKeysArgs=setting.GetArgs(); wxString matcherArgs = setting.GetArgsMatcher(); -#ifdef __WXMSW__ - // remember cwd. - wxString cwd = wxGetCwd(); - wxString apDir = wxPathOnly(generateKeysExe); - if (apDir.Len() > 0) - { - wxSetWorkingDirectory(apDir); - } -#endif - wxString tempDir= wxConfigBase::Get()->Read(wxT("tempDir"),wxT("")); if(!tempDir.IsEmpty()) if(tempDir.Last()!=wxFileName::GetPathSeparator()) @@ -557,10 +566,6 @@ _("Too many images selected"), parent ); return cps; } - apDir = wxPathOnly(matcherExe); - if (apDir.Len() > 0) { - wxSetWorkingDirectory(apDir); - } #endif wxString cmd = matcherExe + wxT(" ") + matcherArgs; @@ -602,11 +607,6 @@ // read and update control points cps = readUpdatedControlPoints((const char *)ptofile.mb_str(HUGIN_CONV_FILENAME), pano); -#ifdef __WXMSW__ - // set old cwd. - wxSetWorkingDirectory(cwd); -#endif - if (!wxRemoveFile(ptofile)) { DEBUG_DEBUG("could not remove temporary file: " << ptofile.c_str()); } diff -r fc38b89e608e -r b476a602385d src/hugin1/ptbatcher/Batch.cpp --- a/src/hugin1/ptbatcher/Batch.cpp Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/ptbatcher/Batch.cpp Sat Sep 11 14:45:27 2010 +0200 @@ -31,6 +31,8 @@ EVT_END_PROCESS(-1, Batch::OnProcessTerminate) END_EVENT_TABLE() +DEFINE_EVENT_TYPE(EVT_BATCH_FAILED) + Batch::Batch(wxFrame* parent, wxString path, bool bgui) : wxFrame(parent,wxID_ANY,_T("Batch")){ //default flag settings parallel = false; @@ -467,7 +469,31 @@ m_paused = false; i = GetIndex(event.GetId()); if (event.GetExitCode() != 0 || event.GetTimestamp()==-1) //timestamp is used as a fake exit code because it cannot be set manually - m_projList.Item(i).status=Project::FAILED; + { + m_projList.Item(i).status=Project::FAILED; + struct FailedProject failedProject; + failedProject.project=m_projList.Item(i).path; + failedProject.logfile=wxEmptyString; + //get filename for automatic saving of log file + wxFileName logFile(m_projList.Item(i).path); + logFile.MakeAbsolute(); + logFile.SetExt(wxT("log")); + wxString name=logFile.GetName(); + unsigned int i=1; + while(logFile.FileExists() && i<1000) + { + logFile.SetName(wxString::Format(wxT("%s_%d"),name.c_str(),i)); + i++; + }; + if(i<1000) + { + //now save log file + if(((RunStitchFrame*)(event.GetEventObject()))->SaveLog(logFile.GetFullPath())) + failedProject.logfile=logFile.GetFullPath(); + }; + //remember failed project + m_failedProjects.push_back(failedProject); + } else m_projList.Item(i).status=Project::FINISHED; if(!m_cancelled && !m_paused) @@ -487,8 +513,15 @@ else { if(gui) - //SetStatusText(_T("Project \""+m_projList.Item(i).path)+_T("\" finished. Batch completed with errors.")); + { SetStatusText(_("Batch completed with errors.")); + if(!shutdown) + { + //notify parent, that at least one project failed + wxCommandEvent e(EVT_BATCH_FAILED,wxID_ANY); + GetParent()->AddPendingEvent(e); + }; + } else //cout << "Project \"" << m_projList.Item(i).path.char_str() << "\" finished. Batch completed with errors." << endl; cout << "Batch completed with errors." << endl; @@ -749,6 +782,7 @@ cout << "Batch is empty." << endl; else if(!m_running) { + m_failedProjects.clear(); if(gui) ((wxFrame*)GetParent())->SetStatusText(_("Running batch...")); else @@ -961,3 +995,19 @@ m_stitchFrames.Item(i)->Show(isVisible); }; }; + +wxString Batch::GetFailedProjectName(unsigned int i) +{ + if(i>=0 && i<m_failedProjects.size()) + return m_failedProjects[i].project; + else + return wxEmptyString; +}; + +wxString Batch::GetFailedProjectLog(unsigned int i) +{ + if(i>=0 && i<m_failedProjects.size()) + return m_failedProjects[i].logfile; + else + return wxEmptyString; +}; diff -r fc38b89e608e -r b476a602385d src/hugin1/ptbatcher/Batch.h --- a/src/hugin1/ptbatcher/Batch.h Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/ptbatcher/Batch.h Sat Sep 11 14:45:27 2010 +0200 @@ -45,6 +45,12 @@ using namespace std; +struct FailedProject +{ + wxString project; + wxString logfile; +}; + class Batch : public wxFrame { public: @@ -133,6 +139,12 @@ * @param isVisible If true display the project output, otherwise hide it. */ void ShowOutput(bool isVisible=true); + /** returns number of failed projects */ + size_t GetFailedProjectsCount() { return m_failedProjects.size(); }; + /** returns project file name of failed project with index i */ + wxString GetFailedProjectName(unsigned int i); + /** returns log file name of failed project with index i */ + wxString GetFailedProjectLog(unsigned int i); private: //environment config objects @@ -150,6 +162,9 @@ bool m_paused; bool m_running; bool m_clearedInProgress; + + //vector, which stores the failed projects and filename of saved logfile + std::vector<FailedProject> m_failedProjects; //external program config PTPrograms progs; @@ -158,4 +173,6 @@ DECLARE_EVENT_TABLE() }; +DECLARE_EVENT_TYPE(EVT_BATCH_FAILED,-1) + #endif //BATCH_H diff -r fc38b89e608e -r b476a602385d src/hugin1/ptbatcher/BatchFrame.cpp --- a/src/hugin1/ptbatcher/BatchFrame.cpp Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/ptbatcher/BatchFrame.cpp Sat Sep 11 14:45:27 2010 +0200 @@ -28,6 +28,7 @@ #include <wx/stdpaths.h> #include "PTBatcherGUI.h" #include "FindPanoDialog.h" +#include "FailedProjectsDialog.h" /* file drag and drop handler method */ bool BatchDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) @@ -101,6 +102,7 @@ EVT_CLOSE(BatchFrame::OnClose) EVT_MENU(wxEVT_COMMAND_RELOAD_BATCH, BatchFrame::OnReloadBatch) EVT_MENU(wxEVT_COMMAND_UPDATE_LISTBOX, BatchFrame::OnUpdateListBox) + EVT_COMMAND(wxID_ANY, EVT_BATCH_FAILED, BatchFrame::OnBatchFailed) END_EVENT_TABLE() BatchFrame::BatchFrame(wxLocale* locale, wxString xrc) @@ -262,27 +264,27 @@ tempFile.Assign(m_batch->GetProject(i)->path); if(tempFile.FileExists()) { - if(m_batch->GetProject(i)->target==Project::STITCHING) - { - wxDateTime modify; - modify=tempFile.GetModificationTime(); - if(m_batch->GetProject(i)->skip) - { - change = true; - m_batch->GetProject(i)->skip = false; - m_batch->SetStatus(i,Project::WAITING); - projListBox->ReloadProject(projListBox->GetIndex(m_batch->GetProject(i)->id),m_batch->GetProject(i)); - } - else if(!modify.IsEqualTo(m_batch->GetProject(i)->modDate)) - { - change = true; - m_batch->GetProject(i)->modDate = modify; - m_batch->GetProject(i)->ResetOptions(); - m_batch->SetStatus(i,Project::WAITING); - projListBox->ReloadProject(projListBox->GetIndex(m_batch->GetProject(i)->id),m_batch->GetProject(i)); - } - } - } + wxDateTime modify; + modify=tempFile.GetModificationTime(); + if(m_batch->GetProject(i)->skip) + { + change = true; + m_batch->GetProject(i)->skip = false; + m_batch->SetStatus(i,Project::WAITING); + projListBox->ReloadProject(projListBox->GetIndex(m_batch->GetProject(i)->id),m_batch->GetProject(i)); + } + else if(!modify.IsEqualTo(m_batch->GetProject(i)->modDate)) + { + change = true; + m_batch->GetProject(i)->modDate = modify; + m_batch->GetProject(i)->ResetOptions(); + if(m_batch->GetProject(i)->target==Project::STITCHING) + { + m_batch->SetStatus(i,Project::WAITING); + }; + projListBox->ReloadProject(projListBox->GetIndex(m_batch->GetProject(i)->id),m_batch->GetProject(i)); + } + } else { if(m_batch->GetStatus(i) != Project::MISSING) @@ -1054,3 +1056,10 @@ if(max) this->Maximize(); } + +void BatchFrame::OnBatchFailed(wxCommandEvent &event) +{ + FailedProjectsDialog failedProjects_dlg(this,m_batch,m_xrcPrefix); + failedProjects_dlg.ShowModal(); + +}; \ No newline at end of file diff -r fc38b89e608e -r b476a602385d src/hugin1/ptbatcher/BatchFrame.h --- a/src/hugin1/ptbatcher/BatchFrame.h Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/ptbatcher/BatchFrame.h Sat Sep 11 14:45:27 2010 +0200 @@ -130,6 +130,8 @@ void OnReloadBatch(wxCommandEvent &event); /** called by thread to update listbox */ void OnUpdateListBox(wxCommandEvent &event); + /** called when batch was finished and there are failed projects */ + void OnBatchFailed(wxCommandEvent &event); DECLARE_EVENT_TABLE() //PTPrograms progs; diff -r fc38b89e608e -r b476a602385d src/hugin1/ptbatcher/CMakeLists.txt --- a/src/hugin1/ptbatcher/CMakeLists.txt Fri Sep 10 08:33:26 2010 +0200 +++ b/src/hugin1/ptbatcher/CMakeLists.txt Sat Sep 11 14:45:27 2010 +0200 @@ -9,9 +9,9 @@ set(PROGNAME_GUI PTBatcherGUI ) set(PTBATCHERGUI_SOURCE - PTBatcherGUI.cpp Batch.cpp RunStitchFrame.cpp ProjectArray.cpp ProjectListBox.cpp BatchFrame.cpp FindPanoDialog.cpp) + PTBatcherGUI.cpp Batch.cpp RunStitchFrame.cpp ProjectArray.cpp ProjectListBox.cpp BatchFrame.cpp FindPanoDialog.cpp FailedProjectsDialog.cpp) set( PTBATCHERGUI_HEADER PTBatcherGUI.h Batch.h RunStitchFrame.h ProjectArray.h ProjectListBox.h - BatchFrame.h DirTraverser.h FindPanoDialog.h PTBatcherGUI_rc.rc) + BatchFrame.h DirTraverser.h FindPanoDialog.h FailedProjectsDialog.h PTBatcherGUI_rc.rc) IF (WIN32) add_executable(${PROGNAME_GUI} WIN32 ${PTBATCHERGUI_SOURCE} ${PTBATCHERGUI_HEADER}) ELSEIF(APPLE) diff -r fc38b89e608e -r b476a602385d src/hugin1/ptbatcher/FailedProjectsDialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugin1/ptbatcher/FailedProjectsDialog.cpp Sat Sep 11 14:45:27 2010 +0200 @@ -0,0 +1,136 @@ +// -*- c-basic-offset: 4 -*- + +/** @file FailedProjectsDialog.cpp + * + * @brief implementation of failed projects dialog + * + * @author Thomas Modes + * + */ + +/* This is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "FailedProjectsDialog.h" +#include "common/wxPlatform.h" +#include "panoinc.h" +#include "Batch.h" + +BEGIN_EVENT_TABLE(FailedProjectsDialog,wxDialog) +EVT_LISTBOX(XRCID("failed_list"),FailedProjectsDialog::OnSelectProject) +END_EVENT_TABLE() + +FailedProjectsDialog::FailedProjectsDialog(wxWindow *parent,Batch *batch,wxString xrcPrefix) +{ + // load our children. some children might need special + // initialization. this will be done later. + wxXmlResource::Get()->LoadDialog(this,parent,wxT("failed_project_dialog")); + +#ifdef __WXMSW__ + wxIcon myIcon(xrcPrefix+ wxT("data/icon.ico"),wxBITMAP_TYPE_ICO); +#else + wxIcon myIcon(xrcPrefix + wxT("data/icon.png"),wxBITMAP_TYPE_PNG); +#endif + SetIcon(myIcon); + m_batch=batch; |