Revert "WIP: refactor Systemcall"

This reverts commit c8015878e1.

Committed by mistake obviously!
This commit is contained in:
Jean-Marc Lasgouttes 2022-10-28 18:04:45 +02:00
parent 6c2d4f9392
commit a852423781
4 changed files with 89 additions and 99 deletions

View File

@ -13,14 +13,13 @@
#include <config.h> #include <config.h>
#include "support/Systemcall.h"
#include "support/SystemcallPrivate.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/filetools.h" #include "support/filetools.h"
#include "support/gettext.h" #include "support/gettext.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/qstring_helpers.h" #include "support/qstring_helpers.h"
#include "support/Systemcall.h"
#include "support/SystemcallPrivate.h"
#include "support/os.h" #include "support/os.h"
#include "support/ProgressInterface.h" #include "support/ProgressInterface.h"
@ -164,20 +163,19 @@ namespace {
* "\a" -> "\a" * "\a" -> "\a"
* "a\"b" -> "a"""b" * "a\"b" -> "a"""b"
*/ */
QStringList const parsecmd(string const & incmd, string & infile, string & outfile, string const parsecmd(string const & incmd, string & infile, string & outfile,
string & errfile) string & errfile)
{ {
bool in_single_quote = false; bool in_single_quote = false;
bool in_double_quote = false; bool in_double_quote = false;
bool escaped = false; bool escaped = false;
string const python_call = os::python(); string const python_call = os::python();
QStringList arguments;
vector<string> outcmd(4); vector<string> outcmd(4);
size_t start = 0; size_t start = 0;
if (prefixIs(incmd, python_call + ' ')) { if (prefixIs(incmd, python_call)) {
arguments << QString::fromLocal8Bit(trim(os::python()).c_str()); outcmd[0] = os::python();
start = python_call.length() + 1; start = python_call.length();
} }
for (size_t i = start, o = 0; i < incmd.length(); ++i) { for (size_t i = start, o = 0; i < incmd.length(); ++i) {
@ -196,12 +194,30 @@ QStringList const parsecmd(string const & incmd, string & infile, string & outfi
outcmd[o] += c; outcmd[o] += c;
continue; continue;
} }
if (c == ' ' && !(in_double_quote || escaped)) { if (c == '"') {
if (o == 0) if (escaped) {
arguments << QString::fromLocal8Bit(trim(outcmd[o]).c_str()); // Don't triple double-quotes for redirection
o = 0; // files as these won't be parsed by QProcess
outcmd[o] += string(o ? "\"" : "\"\"\"");
escaped = false;
} else {
outcmd[o] += c;
in_double_quote = !in_double_quote;
}
} else if (c == '\\' && !escaped) {
escaped = true;
} else if (c == '>' && !(in_double_quote || escaped)) {
if (suffixIs(outcmd[o], " 2")) {
outcmd[o] = rtrim(outcmd[o], "2");
o = 2;
} else {
if (suffixIs(outcmd[o], " 1"))
outcmd[o] = rtrim(outcmd[o], "1");
o = 1;
}
} else if (c == '<' && !(in_double_quote || escaped)) {
o = 3;
#if defined (USE_MACOSX_PACKAGING) #if defined (USE_MACOSX_PACKAGING)
// FIXME!!!!
} else if (o == 0 && i > 4 && c == ' ' && !(in_double_quote || escaped)) { } else if (o == 0 && i > 4 && c == ' ' && !(in_double_quote || escaped)) {
// if a macOS app is detected with an additional argument // if a macOS app is detected with an additional argument
// use open command as prefix to get it work // use open command as prefix to get it work
@ -216,28 +232,6 @@ QStringList const parsecmd(string const & incmd, string & infile, string & outfi
} }
outcmd[o] += c; outcmd[o] += c;
#endif #endif
} else if (c == '"') {
if (escaped) {
outcmd[o] += c;
escaped = false;
} else
in_double_quote = !in_double_quote;
} else if (c == '\\' && !escaped) {
escaped = true;
} else if (c == '>' && o == 0 && !(in_double_quote || escaped)) {
if (outcmd[o] == "2") {
outcmd[o].clear();
o = 2;
outcmd[o].clear();
} else if (outcmd[o] == "1" || outcmd[o].empty()) {
outcmd[o].clear();
o = 1;
outcmd[o].clear();
}
} else if (c == '<' && o == 0 && outcmd[o].empty() && !(in_double_quote || escaped)) {
outcmd[o].clear();
o = 3;
outcmd[o].clear();
} else { } else {
if (escaped && in_double_quote) if (escaped && in_double_quote)
outcmd[o] += '\\'; outcmd[o] += '\\';
@ -248,7 +242,7 @@ QStringList const parsecmd(string const & incmd, string & infile, string & outfi
infile = trim(outcmd[3], " \""); infile = trim(outcmd[3], " \"");
outfile = trim(outcmd[1], " \""); outfile = trim(outcmd[1], " \"");
errfile = trim(outcmd[2], " \""); errfile = trim(outcmd[2], " \"");
return arguments; return trim(outcmd[0]);
} }
} // namespace } // namespace
@ -273,7 +267,8 @@ int Systemcall::startscript(Starttype how, string const & what,
string infile; string infile;
string outfile; string outfile;
string errfile; string errfile;
QStringList const cmd = parsecmd(what_ss, infile, outfile, errfile); QString const cmd = QString::fromLocal8Bit(
parsecmd(what_ss, infile, outfile, errfile).c_str());
SystemcallPrivate d(infile, outfile, errfile); SystemcallPrivate d(infile, outfile, errfile);
bool do_events = process_events || how == WaitLoop; bool do_events = process_events || how == WaitLoop;
@ -384,21 +379,27 @@ SystemcallPrivate::SystemcallPrivate(std::string const & sf, std::string const &
} }
void SystemcallPrivate::startProcess(string const & cmd, string const & path, void SystemcallPrivate::startProcess(QString const & cmd, string const & path,
string const & lpath, bool detached) string const & lpath, bool detached)
{ {
cmd_ = toqstr(cmd); cmd_ = cmd;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
// Set the environment for LaTeX // FIXME pass command and arguments separated in the first place
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); /* The versions of startDetached() and start() that accept a
for (auto const & v : latexEnvironment(path, lpath)) * QStringList object exist since Qt4, but it is only in Qt 5.15
latexenv.insert(toqstr(v.first), QString::fromLocal8Bit(v.second.c_str())); * that splitCommand() was introduced and the plain versions of
process_->setProcessEnvironment(env); * start/startDetached() have been deprecated.
* The cleanest solution would be to have parsecmd() produce a
// Parse the command line * QStringList for arguments, instead of transforming the string
QStringList arguments = parsecmd(cmd); * into something that the QProcess splitter accepts.
QString command = arguments.empty() ? QString() : arguments.takeFirst(); */
QStringList arguments = QProcess::splitCommand(toqstr(latexEnvCmdPrefix(path, lpath)) + cmd_);
QString command = (arguments.empty()) ? QString() : arguments.first();
if (arguments.size() == 1)
arguments.clear();
else if (!arguments.empty())
arguments.removeFirst();
#endif
if (detached) { if (detached) {
state = SystemcallPrivate::Running; state = SystemcallPrivate::Running;
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
@ -410,8 +411,11 @@ void SystemcallPrivate::startProcess(string const & cmd, string const & path,
if (err_file_.empty()) if (err_file_.empty())
process_->setStandardErrorFile(QProcess::nullDevice()); process_->setStandardErrorFile(QProcess::nullDevice());
#endif #endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
if (!QProcess::startDetached(command, arguments)) { if (!QProcess::startDetached(command, arguments)) {
#else
if (!QProcess::startDetached(toqstr(latexEnvCmdPrefix(path, lpath)) + cmd_)) {
#endif
state = SystemcallPrivate::Error; state = SystemcallPrivate::Error;
return; return;
} }
@ -419,7 +423,11 @@ void SystemcallPrivate::startProcess(string const & cmd, string const & path,
delete released; delete released;
} else if (process_) { } else if (process_) {
state = SystemcallPrivate::Starting; state = SystemcallPrivate::Starting;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
process_->start(command, arguments); process_->start(command, arguments);
#else
process_->start(toqstr(latexEnvCmdPrefix(path, lpath)) + cmd_);
#endif
} }
} }

View File

@ -44,7 +44,7 @@ public:
State state; State state;
bool waitWhile(State, bool processEvents, int timeout = -1); bool waitWhile(State, bool processEvents, int timeout = -1);
void startProcess(std::string const & cmd, std::string const & path, void startProcess(QString const & cmd, std::string const & path,
std::string const & lpath, bool detach); std::string const & lpath, bool detach);
int exitCode(); int exitCode();

View File

@ -737,13 +737,12 @@ string const replaceEnvironmentPath(string const & path)
// Return a command prefix for setting the environment of the TeX engine. // Return a command prefix for setting the environment of the TeX engine.
map <string,string> latexEnvironment(string const & path, string const & lpath) string latexEnvCmdPrefix(string const & path, string const & lpath)
{ {
map<string, string> env;
bool use_lpath = !(lpath.empty() || lpath == "." || lpath == "./"); bool use_lpath = !(lpath.empty() || lpath == "." || lpath == "./");
if (path.empty() || (lyxrc.texinputs_prefix.empty() && !use_lpath)) if (path.empty() || (lyxrc.texinputs_prefix.empty() && !use_lpath))
return env; return string();
string texinputs_prefix = lyxrc.texinputs_prefix.empty() ? string() string texinputs_prefix = lyxrc.texinputs_prefix.empty() ? string()
: os::latex_path_list( : os::latex_path_list(
@ -767,37 +766,30 @@ map <string,string> latexEnvironment(string const & path, string const & lpath)
texinputs_prefix.append(sep + abslpath); texinputs_prefix.append(sep + abslpath);
} }
if (os::shell() == os::UNIX)
return "env TEXINPUTS=\"." + sep + texinputs_prefix
+ sep + texinputs + "\" "
+ "BIBINPUTS=\"." + sep + allother_prefix
+ sep + bibinputs + "\" "
+ "BSTINPUTS=\"." + sep + allother_prefix
+ sep + bstinputs + "\" "
+ "TEXFONTS=\"." + sep + allother_prefix
+ sep + texfonts + "\" ";
else
// NOTE: the dummy blank dirs are necessary to force the // NOTE: the dummy blank dirs are necessary to force the
// QProcess parser to quote the argument (see bug 9453) // QProcess parser to quote the argument (see bug 9453)
string const dummy = (os::shell() == os::UNIX) ? string() : (" " + sep); return "cmd /d /c set \"TEXINPUTS=." + sep + " "
+ sep + texinputs_prefix
env.insert({ "TEXINPUTS", "." + sep + dummy + texinputs_prefix + sep + texinputs }); + sep + texinputs + "\" & "
env.insert({ "BIBINPUTS", "." + sep + dummy + allother_prefix + sep + bibinputs }); + "set \"BIBINPUTS=." + sep + " "
env.insert({ "BSTINPUTS", "." + sep + dummy + allother_prefix + sep + bstinputs }); + sep + allother_prefix
env.insert({ "TEXFONTS", "." + sep + dummy + allother_prefix + sep + texfonts }); + sep + bibinputs + "\" & "
+ "set \"BSTINPUTS=." + sep + " "
return env; + sep + allother_prefix
} + sep + bstinputs + "\" & "
+ "set \"TEXFONTS=." + sep + " "
+ sep + allother_prefix
// Return a command prefix for setting the environment of the TeX engine. + sep + texfonts + "\" & ";
string latexEnvCmdPrefix(string const & path, string const & lpath)
{
auto const env = latexEnvironment(path, lpath);
if (env.empty())
return string();
string prefix;
if (os::shell() == os::UNIX) {
prefix = "env ";
for (auto const & v : latexEnvironment(path, lpath))
prefix += v.first + "=" + v.second + " ";
} else {
prefix = "cmd /d /c ";
for (auto const & v : latexEnvironment(path, lpath))
prefix += "set \"" + v.first + "=" + v.second + "\" & ";
}
return prefix;
} }

View File

@ -14,10 +14,9 @@
#include "support/docstring.h" #include "support/docstring.h"
#include <map>
#include <set>
#include <string>
#include <utility> #include <utility>
#include <string>
#include <set>
namespace lyx { namespace lyx {
namespace support { namespace support {
@ -290,15 +289,6 @@ std::string const onlyFileName(std::string const & fname);
*/ */
std::string const replaceEnvironmentPath(std::string const & path); std::string const replaceEnvironmentPath(std::string const & path);
/**
Return a map to be used to set the environment of the TeX engine
with respect to the paths \p path and \p lpath.
*/
std::map <std::string, std::string>
latexEnvironment(std::string const & path, std::string const & lpath);
/** /**
Return a string to be used as a prefix to a command for setting the Return a string to be used as a prefix to a command for setting the
environment of the TeX engine with respect to the paths \p path and \p lpath. environment of the TeX engine with respect to the paths \p path and \p lpath.