#include "support/ForkedCalls.h"
#include "support/debug.h"
-#include "support/environment.h"
#include "support/filetools.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/bind.h"
-#include "LyXRC.h"
-
#include <cerrno>
#include <queue>
#include <sstream>
/////////////////////////////////////////////////////////////////////
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)
return retval_;
}
- command_ = what;
+ command_ = trim(what);
signal_.reset();
return run(Wait);
}
int ForkedCall::startScript(string const & what, SignalTypePtr signal)
{
- command_ = what;
+ command_ = trim(what);
signal_ = signal;
return run(DontWait);
// 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
// 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;
#include <config.h>
#include "support/debug.h"
-#include "support/environment.h"
#include "support/filetools.h"
#include "support/lstrings.h"
#include "support/qstring_helpers.h"
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()) {
command = "start /min " + command;
break;
}
- }
+ } else if (os::shell() == os::CMD_EXE)
+ command = subst(command, "cmd /d /c ", "");
return ::system(command.c_str());
}
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);
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()));
}
-
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_);
}
}
SystemcallPrivate::~SystemcallPrivate()
{
- if (!texinputs_.empty())
- setEnv("TEXINPUTS", texinputs_);
-
if (out_index_) {
out_data_[out_index_] = '\0';
out_index_ = 0;
/** 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(),
size_t err_index_;
///
std::string out_file_;
- ///
- std::string texinputs_;
/// Size of buffers.
static size_t const buffer_size_ = 200;
}
+// 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)
{
*/
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.