Add support for weston-terminal (#384)
* add support for weston-terminal * move NonExclusiveTemporaryFileOwner to utils * move wrapCommandForTerminalEmulator to utils
This commit is contained in:
parent
5fce5cead7
commit
c90f0bc313
|
@ -22,6 +22,7 @@
|
|||
#include "qt_utils/utils.h"
|
||||
#include "../utils.h"
|
||||
#include "../common.h"
|
||||
#include "settings.h"
|
||||
|
||||
enum RunProgramFlag {
|
||||
RPF_PAUSE_CONSOLE = 0x0001,
|
||||
|
@ -103,7 +104,7 @@ private:
|
|||
int mSyntaxCheckIssueCount;
|
||||
Compiler* mBackgroundSyntaxChecker;
|
||||
Runner* mRunner;
|
||||
TemporaryFileOwner mTempFileOwner;
|
||||
PNonExclusiveTemporaryFileOwner mTempFileOwner;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
QRecursiveMutex mCompileMutex;
|
||||
QRecursiveMutex mBackgroundSyntaxCheckMutex;
|
||||
|
|
|
@ -2360,7 +2360,7 @@ void DebugTarget::run()
|
|||
} + mArguments;
|
||||
QString cmd;
|
||||
QStringList arguments;
|
||||
std::unique_ptr<QTemporaryFile> fileOwner;
|
||||
PNonExclusiveTemporaryFileOwner fileOwner;
|
||||
#ifdef Q_OS_WIN
|
||||
if (pSettings->environment().useCustomTerminal()) {
|
||||
std::tie(cmd, arguments, fileOwner) = wrapCommandForTerminalEmulator(
|
||||
|
|
|
@ -125,6 +125,17 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Special Purpose",
|
||||
"terminals": [
|
||||
{
|
||||
"name": "Wayland Terminal",
|
||||
"path": "weston-terminal",
|
||||
"argsPattern": "$term --shell $tmpfile.sh",
|
||||
"comment": "integration with Weston compositor, for minimal Live CD/USB"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "With minor issue",
|
||||
"terminals": [
|
||||
|
|
|
@ -6545,83 +6545,3 @@ void Settings::Languages::setNoDebugDirectivesWhenGenerateASM(bool newNoDebugDir
|
|||
{
|
||||
mNoDebugDirectivesWhenGenerateASM = newNoDebugDirectivesWhenGenerateASM;
|
||||
}
|
||||
|
||||
std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>> wrapCommandForTerminalEmulator(const QString &terminal, const QStringList &argsPattern, const QStringList &payloadArgsWithArgv0)
|
||||
{
|
||||
QStringList wrappedArgs;
|
||||
std::unique_ptr<QTemporaryFile> temproryFile;
|
||||
for (const QString &patternItem : argsPattern) {
|
||||
if (patternItem == "$term")
|
||||
wrappedArgs.append(terminal);
|
||||
else if (patternItem == "$integrated_term")
|
||||
wrappedArgs.append(includeTrailingPathDelimiter(pSettings->dirs().appDir())+terminal);
|
||||
else if (patternItem == "$argv")
|
||||
wrappedArgs.append(payloadArgsWithArgv0);
|
||||
else if (patternItem == "$command" || patternItem == "$unix_command") {
|
||||
// “$command” is for compatibility; previously used on multiple Unix terms
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::BourneAgainShellPretty);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||
} else if (patternItem == "$dos_command") {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::WindowsCommandPrompt);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||
} else if (patternItem == "$lpCommandLine") {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::WindowsCreateProcess);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||
} else if (patternItem == "$tmpfile" || patternItem == "$tmpfile.command") {
|
||||
// “$tmpfile” is for compatibility; previously used on macOS Terminal.app
|
||||
temproryFile = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.command");
|
||||
if (temproryFile->open()) {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::BourneAgainShellPretty);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
temproryFile->write(escapedArgs.join(' ').toUtf8());
|
||||
temproryFile->write("\n");
|
||||
temproryFile->flush();
|
||||
QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
}
|
||||
wrappedArgs.push_back(temproryFile->fileName());
|
||||
} else if (patternItem == "$tmpfile.bat") {
|
||||
temproryFile = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.bat");
|
||||
if (temproryFile->open()) {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::WindowsCommandPrompt);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
temproryFile->write(escapedArgs.join(' ').toLocal8Bit());
|
||||
temproryFile->write("\r\n");
|
||||
temproryFile->flush();
|
||||
QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
}
|
||||
wrappedArgs.push_back(temproryFile->fileName());
|
||||
} else
|
||||
wrappedArgs.push_back(patternItem);
|
||||
}
|
||||
if (wrappedArgs.empty())
|
||||
return {QString(""), QStringList{}, std::move(temproryFile)};
|
||||
return {wrappedArgs[0], wrappedArgs.mid(1), std::move(temproryFile)};
|
||||
}
|
||||
|
||||
std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>> wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0)
|
||||
{
|
||||
return wrapCommandForTerminalEmulator(terminal, parseArguments(argsPattern, Settings::Environment::terminalArgsPatternMagicVariables(), false), payloadArgsWithArgv0);
|
||||
}
|
||||
|
|
|
@ -1615,11 +1615,6 @@ private:
|
|||
Languages mLanguages;
|
||||
};
|
||||
|
||||
|
||||
std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>> wrapCommandForTerminalEmulator(const QString &terminal, const QStringList &argsPattern, const QStringList &payloadArgsWithArgv0);
|
||||
|
||||
std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>> wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0);
|
||||
|
||||
extern Settings* pSettings;
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
|
|
@ -44,7 +44,7 @@ EnvironmentProgramsWidget::~EnvironmentProgramsWidget()
|
|||
}
|
||||
|
||||
auto EnvironmentProgramsWidget::resolveExecArguments(const QString &terminalPath, const QString &argsPattern)
|
||||
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>
|
||||
-> std::tuple<QString, QStringList, PNonExclusiveTemporaryFileOwner>
|
||||
{
|
||||
return wrapCommandForTerminalEmulator(terminalPath, argsPattern, platformCommandForTerminalArgsPreview());
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#ifndef ENVIRONMENTPROGRAMSWIDGET_H
|
||||
#define ENVIRONMENTPROGRAMSWIDGET_H
|
||||
|
||||
#include "settings.h"
|
||||
#include "settingswidget.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -34,7 +35,7 @@ public:
|
|||
|
||||
private:
|
||||
auto resolveExecArguments(const QString &terminalPath, const QString &argsPatter)
|
||||
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>;
|
||||
-> std::tuple<QString, QStringList, PNonExclusiveTemporaryFileOwner>;
|
||||
void updateCommandPreview(const QString &terminalPath, const QString &argsPatter);
|
||||
void autoDetectAndUpdateArgumentsPattern(const QString &terminalPath);
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "parser/cppparser.h"
|
||||
#include "compiler/executablerunner.h"
|
||||
#include <QComboBox>
|
||||
#include "utils/escape.h"
|
||||
#include "utils/parsearg.h"
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QDesktopServices>
|
||||
#include <windows.h>
|
||||
|
@ -25,6 +27,22 @@ using pIsWow64Process2_t = BOOL (WINAPI *)(
|
|||
);
|
||||
#endif
|
||||
|
||||
NonExclusiveTemporaryFileOwner::NonExclusiveTemporaryFileOwner(std::unique_ptr<QTemporaryFile> &tempFile) :
|
||||
filename(tempFile ? tempFile->fileName() : QString())
|
||||
{
|
||||
if (tempFile) {
|
||||
tempFile->flush();
|
||||
tempFile->setAutoRemove(false);
|
||||
tempFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NonExclusiveTemporaryFileOwner::~NonExclusiveTemporaryFileOwner()
|
||||
{
|
||||
if (!filename.isEmpty())
|
||||
QFile::remove(filename);
|
||||
}
|
||||
|
||||
FileType getFileType(const QString &filename)
|
||||
{
|
||||
if (filename.endsWith(".s",PATH_SENSITIVITY)) {
|
||||
|
@ -635,3 +653,96 @@ QByteArray stringToByteArray(const QString &content, bool isUTF8)
|
|||
else
|
||||
return content.toLocal8Bit();
|
||||
}
|
||||
|
||||
std::tuple<QString, QStringList, PNonExclusiveTemporaryFileOwner> wrapCommandForTerminalEmulator(const QString &terminal, const QStringList &argsPattern, const QStringList &payloadArgsWithArgv0)
|
||||
{
|
||||
QStringList wrappedArgs;
|
||||
std::unique_ptr<QTemporaryFile> temproryFile;
|
||||
for (const QString &patternItem : argsPattern) {
|
||||
if (patternItem == "$term")
|
||||
wrappedArgs.append(terminal);
|
||||
else if (patternItem == "$integrated_term")
|
||||
wrappedArgs.append(includeTrailingPathDelimiter(pSettings->dirs().appDir())+terminal);
|
||||
else if (patternItem == "$argv")
|
||||
wrappedArgs.append(payloadArgsWithArgv0);
|
||||
else if (patternItem == "$command" || patternItem == "$unix_command") {
|
||||
// “$command” is for compatibility; previously used on multiple Unix terms
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::BourneAgainShellPretty);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||
} else if (patternItem == "$dos_command") {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::WindowsCommandPrompt);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||
} else if (patternItem == "$lpCommandLine") {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::WindowsCreateProcess);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||
} else if (patternItem == "$tmpfile" || patternItem == "$tmpfile.command") {
|
||||
// “$tmpfile” is for compatibility; previously used on macOS Terminal.app
|
||||
temproryFile = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.command");
|
||||
if (temproryFile->open()) {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::BourneAgainShellPretty);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
temproryFile->write(escapedArgs.join(' ').toUtf8());
|
||||
temproryFile->write("\n");
|
||||
QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
}
|
||||
wrappedArgs.push_back(temproryFile->fileName());
|
||||
} else if (patternItem == "$tmpfile.sh") {
|
||||
temproryFile = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.command");
|
||||
if (temproryFile->open()) {
|
||||
QStringList escapedArgs = {"exec"};
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, false, EscapeArgumentRule::BourneAgainShellPretty);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
temproryFile->write("#!/bin/sh\n");
|
||||
temproryFile->write(escapedArgs.join(' ').toUtf8());
|
||||
temproryFile->write("\n");
|
||||
QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
}
|
||||
wrappedArgs.push_back(temproryFile->fileName());
|
||||
} else if (patternItem == "$tmpfile.bat") {
|
||||
temproryFile = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.bat");
|
||||
if (temproryFile->open()) {
|
||||
QStringList escapedArgs;
|
||||
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||
auto &arg = payloadArgsWithArgv0[i];
|
||||
auto escaped = escapeArgument(arg, i == 0, EscapeArgumentRule::WindowsCommandPrompt);
|
||||
escapedArgs.append(escaped);
|
||||
}
|
||||
temproryFile->write(escapedArgs.join(' ').toLocal8Bit());
|
||||
temproryFile->write("\r\n");
|
||||
QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
}
|
||||
wrappedArgs.push_back(temproryFile->fileName());
|
||||
} else
|
||||
wrappedArgs.push_back(patternItem);
|
||||
}
|
||||
if (wrappedArgs.empty())
|
||||
return {QString(""), QStringList{}, std::make_unique<NonExclusiveTemporaryFileOwner>(temproryFile)};
|
||||
return {wrappedArgs[0], wrappedArgs.mid(1), std::make_unique<NonExclusiveTemporaryFileOwner>(temproryFile)};
|
||||
}
|
||||
|
||||
std::tuple<QString, QStringList, PNonExclusiveTemporaryFileOwner> wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0)
|
||||
{
|
||||
return wrapCommandForTerminalEmulator(terminal, parseArguments(argsPattern, Settings::Environment::terminalArgsPatternMagicVariables(), false), payloadArgsWithArgv0);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
using SimpleIni = CSimpleIniA;
|
||||
using PSimpleIni = std::shared_ptr<SimpleIni>;
|
||||
using TemporaryFileOwner = std::unique_ptr<QTemporaryFile>;
|
||||
|
||||
enum class FileType{
|
||||
GAS, // GNU assembler source file (.s)
|
||||
|
@ -116,6 +115,21 @@ enum class ProblemCaseValidateType {
|
|||
IgnoreSpaces
|
||||
};
|
||||
|
||||
struct NonExclusiveTemporaryFileOwner {
|
||||
const QString filename;
|
||||
|
||||
// take ownership
|
||||
explicit NonExclusiveTemporaryFileOwner(std::unique_ptr<QTemporaryFile> &tempFile);
|
||||
|
||||
NonExclusiveTemporaryFileOwner(const NonExclusiveTemporaryFileOwner &) = delete;
|
||||
NonExclusiveTemporaryFileOwner(NonExclusiveTemporaryFileOwner &&) = delete;
|
||||
NonExclusiveTemporaryFileOwner& operator=(const NonExclusiveTemporaryFileOwner &) = delete;
|
||||
NonExclusiveTemporaryFileOwner& operator=(NonExclusiveTemporaryFileOwner &&) = delete;
|
||||
~NonExclusiveTemporaryFileOwner();
|
||||
};
|
||||
|
||||
using PNonExclusiveTemporaryFileOwner = std::unique_ptr<NonExclusiveTemporaryFileOwner>;
|
||||
|
||||
FileType getFileType(const QString& filename);
|
||||
|
||||
bool programHasConsole(const QString& filename);
|
||||
|
@ -180,4 +194,8 @@ QByteArray stringToByteArray(const QString& content, bool isUTF8);
|
|||
#define __builtin_unreachable() (__assume(0))
|
||||
#endif
|
||||
|
||||
std::tuple<QString, QStringList, PNonExclusiveTemporaryFileOwner> wrapCommandForTerminalEmulator(const QString &terminal, const QStringList &argsPattern, const QStringList &payloadArgsWithArgv0);
|
||||
|
||||
std::tuple<QString, QStringList, PNonExclusiveTemporaryFileOwner> wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0);
|
||||
|
||||
#endif // UTILS_H
|
||||
|
|
Loading…
Reference in New Issue