From 70696182dd80a04e89aaca6c0c9a0e5b83e0e776 Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Wed, 13 May 2009 18:29:58 +0000 Subject: [PATCH] Take into account output redirection when spawning a program. Now things should behave as before the QProcess era (I hope). The parser only accounts for output redirection, no fancy things such as piping are possible, yet. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29656 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/support/Systemcall.cpp | 46 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp index b7f0355fc6..70d071c1f0 100644 --- a/src/support/Systemcall.cpp +++ b/src/support/Systemcall.cpp @@ -14,6 +14,7 @@ #include #include "support/debug.h" +#include "support/lstrings.h" #include "support/qstring_helpers.h" #include "support/Systemcall.h" #include "support/os.h" @@ -40,9 +41,9 @@ static void killProcess(QProcess * p) // Reuse of instance +#ifndef USE_QPROCESS int Systemcall::startscript(Starttype how, string const & what) { -#ifndef USE_QPROCESS string command = what; if (how == DontWait) { @@ -57,14 +58,49 @@ int Systemcall::startscript(Starttype how, string const & what) } return ::system(command.c_str()); +} + #else - QString cmd = QString::fromLocal8Bit(what.c_str()); + +namespace { + +string const parsecmd(string const & cmd, string & outfile) +{ + bool inquote = false; + bool escaped = false; + + for (size_t i = 0; i < cmd.length(); ++i) { + char c = cmd[i]; + if (c == '"' && !escaped) + inquote = !inquote; + else if (c == '\\' && !escaped) + escaped = !escaped; + else if (c == '>' && !(inquote || escaped)) { + outfile = trim(cmd.substr(i + 1), " \""); + return trim(cmd.substr(0, i)); + } else + escaped = false; + } + outfile.erase(); + return cmd; + +} + +} // namespace anon + + +int Systemcall::startscript(Starttype how, string const & what) +{ + string outfile; + QString cmd = toqstr(parsecmd(what, outfile)); QProcess * process = new QProcess; // Qt won't start the process if we redirect stdout/stderr in // this way and they are not connected to a terminal (maybe // because we were launched from some desktop GUI). - if (os::is_terminal(os::STDOUT)) + if (!outfile.empty()) + process->setStandardOutputFile(toqstr(outfile)); + else if (os::is_terminal(os::STDOUT)) process->setStandardOutputFile(toqstr(os::stdoutdev())); if (os::is_terminal(os::STDERR)) process->setStandardErrorFile(toqstr(os::stderrdev())); @@ -99,7 +135,7 @@ int Systemcall::startscript(Starttype how, string const & what) // If the output has been redirected, we write it all at once. // Even if we are not running in a terminal, the output could go // to some log file, for example ~/.xsession-errors on *nix. - if (!os::is_terminal(os::STDOUT)) + if (!os::is_terminal(os::STDOUT) && outfile.empty()) cout << fromqstr(QString::fromLocal8Bit( process->readAllStandardOutput().data())); if (!os::is_terminal(os::STDERR)) @@ -108,8 +144,8 @@ int Systemcall::startscript(Starttype how, string const & what) killProcess(process); return exit_code; -#endif } +#endif } // namespace support } // namespace lyx