]> git.lyx.org Git - features.git/commitdiff
Manage the setting of the latex environment for Systemcall and ForkedCall
authorEnrico Forestieri <forenr@lyx.org>
Mon, 26 Sep 2011 17:14:24 +0000 (17:14 +0000)
committerEnrico Forestieri <forenr@lyx.org>
Mon, 26 Sep 2011 17:14:24 +0000 (17:14 +0000)
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

src/support/ForkedCalls.cpp
src/support/Systemcall.cpp
src/support/Systemcall.h
src/support/SystemcallPrivate.h
src/support/filetools.cpp
src/support/filetools.h

index dede9fac3fed7bf376fb6077a39d63feeb769d03..1c5e663723f765e3aa547e4b108d729135007fdc 100644 (file)
@@ -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 <cerrno>
 #include <queue>
 #include <sstream>
@@ -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<char>::iterator it = vec.begin();
+       vector<char>::iterator itc = vec.begin();
        vector<char>::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<char *> argv;
index 741feb233843834c95a596e06e2f361edfea39f7..f8db8b0b689d633657b1ef761964653658cacc91 100644 (file)
@@ -14,7 +14,6 @@
 #include <config.h>
 
 #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;
index 71e4c6237d4bd218fc3695dbf27dffaa350854a5..1d4c75374a68148aac48b8d65b0c6b8ec960cbff 100644 (file)
@@ -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(),
index ee8aeb164cb9f964632b75ce970c70d74882ff04..c0a4c7755a66c016b902ff4bec941f178a23a235 100644 (file)
@@ -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;
index 7f701407748113ec65d9a3b5075a5bfe3dd45222..2cab1aa980261b9ba1f5b2e7258a525cd9ef66bc 100644 (file)
@@ -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)
 {
index 001c0f3ddc1476e80fb99677868fd82cfee7d097..48ebbd6046c5c174034b408cecdd415b7f95ab35 100644 (file)
@@ -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.