From: Enrico Forestieri Date: Mon, 26 Sep 2011 17:14:24 +0000 (+0000) Subject: Manage the setting of the latex environment for Systemcall and ForkedCall X-Git-Tag: 2.0.2~179 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=9c5a8a5baaa7e12f0cf773431cc6f9888546467d;p=features.git Manage the setting of the latex environment for Systemcall and ForkedCall in a central place. This is a backport of r39754 and r39758-r39762. No status line needed. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_2_0_X@39770 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/support/ForkedCalls.cpp b/src/support/ForkedCalls.cpp index dede9fac3f..1c5e663723 100644 --- a/src/support/ForkedCalls.cpp +++ b/src/support/ForkedCalls.cpp @@ -15,7 +15,6 @@ #include "support/ForkedCalls.h" #include "support/debug.h" -#include "support/environment.h" #include "support/filetools.h" #include "support/lstrings.h" #include "support/lyxlib.h" @@ -24,8 +23,6 @@ #include "support/bind.h" -#include "LyXRC.h" - #include #include #include @@ -274,23 +271,8 @@ int ForkedProcess::waitForChild() ///////////////////////////////////////////////////////////////////// ForkedCall::ForkedCall(string const & path) - : cmd_prefix_(empty_string()) -{ - if (path.empty() || lyxrc.texinputs_prefix.empty()) - return; - - string const texinputs = os::latex_path_list( - replaceCurdirPath(path, lyxrc.texinputs_prefix)); - string const sep = string(1, os::path_separator(os::TEXENGINE)); - string const env = getEnv("TEXINPUTS"); - - if (os::shell() == os::UNIX) - cmd_prefix_ = "env 'TEXINPUTS=." + sep + texinputs - + sep + env + "' "; - else - cmd_prefix_ = "cmd /d /c set TEXINPUTS=." + sep + texinputs - + sep + env + " & "; -} + : cmd_prefix_(to_filesystem8bit(from_utf8(latexEnvCmdPrefix(path)))) +{} int ForkedCall::startScript(Starttype wait, string const & what) @@ -300,7 +282,7 @@ int ForkedCall::startScript(Starttype wait, string const & what) return retval_; } - command_ = what; + command_ = trim(what); signal_.reset(); return run(Wait); } @@ -308,7 +290,7 @@ int ForkedCall::startScript(Starttype wait, string const & what) int ForkedCall::startScript(string const & what, SignalTypePtr signal) { - command_ = what; + command_ = trim(what); signal_ = signal; return run(DontWait); @@ -318,10 +300,11 @@ int ForkedCall::startScript(string const & what, SignalTypePtr signal) // generate child in background int ForkedCall::generateChild() { - string const line = trim(cmd_prefix_ + command_); - if (line.empty()) + if (command_.empty()) return 1; + string const line = cmd_prefix_ + command_; + #if !defined (_WIN32) // POSIX @@ -341,25 +324,44 @@ int ForkedCall::generateChild() // 2. If we are inside quotes, then don't replace the white space // but do remove the quotes themselves. We do this naively by // replacing the quote with '\0' which is fine if quotes - // delimit the entire word. + // delimit the entire word. However, if quotes do not delimit the + // entire word (i.e., open quote is inside word), simply discard + // them such as not to break the current word. char inside_quote = 0; + char c_before_open_quote = ' '; vector::iterator it = vec.begin(); + vector::iterator itc = vec.begin(); vector::iterator const end = vec.end(); - for (; it != end; ++it) { + for (; it != end; ++it, ++itc) { char const c = *it; if (!inside_quote) { - if (c == ' ') - *it = '\0'; - else if (c == '\'' || c == '"') { - *it = '\0'; + if (c == '\'' || c == '"') { + if (c_before_open_quote == ' ') + *itc = '\0'; + else + --itc; inside_quote = c; + } else { + if (c == ' ') + *itc = '\0'; + else + *itc = c; + c_before_open_quote = c; } } else if (c == inside_quote) { - *it = '\0'; + if (c_before_open_quote == ' ') + *itc = '\0'; + else + --itc; inside_quote = 0; - } + } else + *itc = c; } + // Clear what remains. + for (; itc != end; ++itc) + *itc = '\0'; + // Build an array of pointers to each word. it = vec.begin(); vector argv; diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp index 741feb2338..f8db8b0b68 100644 --- a/src/support/Systemcall.cpp +++ b/src/support/Systemcall.cpp @@ -14,7 +14,6 @@ #include #include "support/debug.h" -#include "support/environment.h" #include "support/filetools.h" #include "support/lstrings.h" #include "support/qstring_helpers.h" @@ -101,24 +100,8 @@ ProgressInterface* ProgressInterface::instance() int Systemcall::startscript(Starttype how, string const & what, std::string const & path, bool /*process_events*/) { - string command; - string const texinputs = os::latex_path_list( - replaceCurdirPath(path, lyxrc.texinputs_prefix)); - string const sep = string(1, os::path_separator(os::TEXENGINE)); - string const env = getEnv("TEXINPUTS"); - - switch (os::shell()) { - case os::UNIX: - command = path.empty() || lyxrc.texinputs_prefix.empty() ? what - : "env TEXINPUTS='." + sep + texinputs - + sep + env + "' " + what; - break; - case os::CMD_EXE: - command = path.empty() || lyxrc.texinputs_prefix.empty() ? what - : "set TEXINPUTS=." + sep + texinputs - + sep + env + " & " + what; - break; - } + string command = + to_filesystem8bit(from_utf8(latexEnvCmdPrefix(path))) + what; if (how == DontWait) { switch (os::shell()) { @@ -129,7 +112,8 @@ int Systemcall::startscript(Starttype how, string const & what, command = "start /min " + command; break; } - } + } else if (os::shell() == os::CMD_EXE) + command = subst(command, "cmd /d /c ", ""); return ::system(command.c_str()); } @@ -228,7 +212,7 @@ int Systemcall::startscript(Starttype how, string const & what, string const & path, bool process_events) { string outfile; - QString cmd = toqstr(parsecmd(what, outfile)); + QString cmd = QString::fromLocal8Bit(parsecmd(what, outfile).c_str()); SystemcallPrivate d(outfile); @@ -268,13 +252,12 @@ SystemcallPrivate::SystemcallPrivate(const std::string& of) : out_index_(0), err_index_(0), out_file_(of), - texinputs_(getEnv("TEXINPUTS")), process_events_(false) { if (!out_file_.empty()) { // Check whether we have to simply throw away the output. if (out_file_ != os::nulldev()) - process_->setStandardOutputFile(toqstr(out_file_)); + process_->setStandardOutputFile(QString::fromLocal8Bit(out_file_.c_str())); } connect(process_, SIGNAL(readyReadStandardOutput()), SLOT(stdOut())); @@ -285,27 +268,12 @@ SystemcallPrivate::SystemcallPrivate(const std::string& of) : } - void SystemcallPrivate::startProcess(QString const & cmd, string const & path) { cmd_ = cmd; if (process_) { - if (!path.empty() && !lyxrc.texinputs_prefix.empty()) { - string const texinputs = os::latex_path_list( - replaceCurdirPath(path, lyxrc.texinputs_prefix)); - string const sep = string(1, - os::path_separator(os::TEXENGINE)); - string const prefix = "." + sep + texinputs + sep; - if (prefixIs(texinputs_, prefix)) - texinputs_.clear(); - else - setEnv("TEXINPUTS", prefix + texinputs_); - } state = SystemcallPrivate::Starting; - if (os::shell() == os::CMD_EXE) - process_->start(QLatin1String("cmd /d /c ") + cmd_); - else - process_->start(cmd_); + process_->start(toqstr(latexEnvCmdPrefix(path)) + cmd_); } } @@ -362,9 +330,6 @@ bool SystemcallPrivate::waitWhile(State waitwhile, bool process_events, int time SystemcallPrivate::~SystemcallPrivate() { - if (!texinputs_.empty()) - setEnv("TEXINPUTS", texinputs_); - if (out_index_) { out_data_[out_index_] = '\0'; out_index_ = 0; diff --git a/src/support/Systemcall.h b/src/support/Systemcall.h index 71e4c6237d..1d4c75374a 100644 --- a/src/support/Systemcall.h +++ b/src/support/Systemcall.h @@ -40,9 +40,10 @@ public: /** Start child process. * The string "what" contains a commandline with arguments separated - * by spaces. The string "path" contains the path to be prepended to - * the TEXINPUTS environment variable. Unset "process_events" in - * case UI should be blocked while processing the external command. + * by spaces and encoded in the filesystem encoding. The string "path" + * contains the path to be prepended to the TEXINPUTS environment + * variable and encoded in utf-8. Unset "process_events" in case + * UI should be blocked while processing the external command. */ int startscript(Starttype how, std::string const & what, std::string const & path = empty_string(), diff --git a/src/support/SystemcallPrivate.h b/src/support/SystemcallPrivate.h index ee8aeb164c..c0a4c7755a 100644 --- a/src/support/SystemcallPrivate.h +++ b/src/support/SystemcallPrivate.h @@ -74,8 +74,6 @@ private: size_t err_index_; /// std::string out_file_; - /// - std::string texinputs_; /// Size of buffers. static size_t const buffer_size_ = 200; diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp index 7f70140774..2cab1aa980 100644 --- a/src/support/filetools.cpp +++ b/src/support/filetools.cpp @@ -578,6 +578,26 @@ string const replaceEnvironmentPath(string const & path) } +// Return a command prefix for setting the environment of the TeX engine. +string latexEnvCmdPrefix(string const & path) +{ + if (path.empty() || lyxrc.texinputs_prefix.empty()) + return string(); + + string const texinputs_prefix = os::latex_path_list( + replaceCurdirPath(path, lyxrc.texinputs_prefix)); + string const sep = string(1, os::path_separator(os::TEXENGINE)); + string const texinputs = getEnv("TEXINPUTS"); + + if (os::shell() == os::UNIX) + return "env TEXINPUTS=\"." + sep + texinputs_prefix + + sep + texinputs + "\" "; + else + return "cmd /d /c set TEXINPUTS=." + sep + texinputs_prefix + + sep + texinputs + " & "; +} + + // Replace current directory in all elements of a path list with a given path. string const replaceCurdirPath(string const & path, string const & pathlist) { diff --git a/src/support/filetools.h b/src/support/filetools.h index 001c0f3ddc..48ebbd6046 100644 --- a/src/support/filetools.h +++ b/src/support/filetools.h @@ -247,6 +247,12 @@ std::string const onlyFileName(std::string const & fname); */ std::string const replaceEnvironmentPath(std::string const & path); +/** + Return a string to be used as a prefix to a command for setting the + environment of the TeX engine with respect to the path \p path. + */ +std::string latexEnvCmdPrefix(std::string const & path); + /** Replace all references to a current directory (a lonely '.' or the prefix "./") in \c pathlist with \c path. Also prefixes all non-absolute paths with \c path.