Add runner args abstraction and fix shm on macOS/BSD (#134)
* add runner args abstraction to allow different args patterns in various terminal apps; fix macOS shm IPC * extend platform support from Linux to XDG desktop * update build docs for Unix * improve terminal args pattern migration for macOS
This commit is contained in:
parent
18aa239b40
commit
7cf5d21b48
71
BUILD.md
71
BUILD.md
|
@ -198,11 +198,33 @@ To build with VS 2017 or later in Command Prompt:
|
||||||
"%JOM%" install
|
"%JOM%" install
|
||||||
```
|
```
|
||||||
|
|
||||||
# Linux
|
# Linux and Other freedesktop.org-conforming (XDG) Desktop Systems
|
||||||
|
|
||||||
- Install gcc and qt5
|
General steps:
|
||||||
- Optionally install fcitx5-qt for building with static version of Qt
|
|
||||||
- Open `Red_Panda_CPP.pro` with Qt Creator
|
- Install recent version of GCC (≥ 7) or Clang (≥ 6) that supports C++17.
|
||||||
|
- Install Qt 5 (≥ 5.12) Base, SVG and Tools modules, including both libraries and development files.
|
||||||
|
- Optionally install fcitx5-qt for building with static Qt library.
|
||||||
|
- Optionally install Qt Creator for development.
|
||||||
|
|
||||||
|
For build only:
|
||||||
|
|
||||||
|
1. Configure:
|
||||||
|
```bash
|
||||||
|
qmake PREFIX=/usr/local /path/to/src/Red_Panda_CPP.pro
|
||||||
|
```
|
||||||
|
2. Make:
|
||||||
|
```bash
|
||||||
|
make -j$(nproc)
|
||||||
|
```
|
||||||
|
3. Install:
|
||||||
|
```bash
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
For development:
|
||||||
|
|
||||||
|
1. Open `Red_Panda_CPP.pro` with Qt Creator
|
||||||
|
|
||||||
qmake variables:
|
qmake variables:
|
||||||
- `PREFIX`: default to `/usr/local`. It should be set to `/usr` or `/opt/redpanda-cpp` when packaging.
|
- `PREFIX`: default to `/usr/local`. It should be set to `/usr` or `/opt/redpanda-cpp` when packaging.
|
||||||
|
@ -296,7 +318,7 @@ Enter `RedPandaIDE` to launch RedPanda C++.
|
||||||
|
|
||||||
Note that makepkg checks out HEAD of the repo, so any change should be committed before building.
|
Note that makepkg checks out HEAD of the repo, so any change should be committed before building.
|
||||||
|
|
||||||
## AppImage
|
## Linux AppImage
|
||||||
|
|
||||||
1. Install dependency: Docker or Podman.
|
1. Install dependency: Docker or Podman.
|
||||||
|
|
||||||
|
@ -336,9 +358,9 @@ Note that makepkg checks out HEAD of the repo, so any change should be committed
|
||||||
|
|
||||||
It is possible to build Red Panda C++ for foreign architectures using targets’ native toolchains with QEMU user space emulation.
|
It is possible to build Red Panda C++ for foreign architectures using targets’ native toolchains with QEMU user space emulation.
|
||||||
|
|
||||||
Note: Always run emulated native build **in containers**. Mixing architectures may kill your system.
|
Note: Always run emulated native build **in containers or jails**. Mixing architectures may kill your system.
|
||||||
|
|
||||||
For Linux host, install statically linked QEMU user space emulator (package name is likely `qemu-user-static`) and make sure that binfmt support is enabled.
|
For Linux or BSD host, install statically linked QEMU user space emulator (package name is likely `qemu-user-static`) and make sure that binfmt support is enabled.
|
||||||
|
|
||||||
For Windows host, Docker and Podman should have QEMU user space emulation enabled. If not,
|
For Windows host, Docker and Podman should have QEMU user space emulation enabled. If not,
|
||||||
* For Docker:
|
* For Docker:
|
||||||
|
@ -350,3 +372,38 @@ For Windows host, Docker and Podman should have QEMU user space emulation enable
|
||||||
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-aarch64-static.conf /proc/sys/fs/binfmt_misc/register
|
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-aarch64-static.conf /proc/sys/fs/binfmt_misc/register
|
||||||
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-riscv64-static.conf /proc/sys/fs/binfmt_misc/register
|
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-riscv64-static.conf /proc/sys/fs/binfmt_misc/register
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
|
||||||
|
## Qt.io Qt Library
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
|
||||||
|
0. macOS 10.13 or later.
|
||||||
|
1. Install Xcode Command Line Tools:
|
||||||
|
```zsh
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
2. Install Qt with online installer from [Qt.io](https://www.qt.io/download-qt-installer-oss).
|
||||||
|
- Select the library (in _Qt_ group, _Qt 5.15.2_ subgroup, check _macOS_).
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
|
1. Set related variables:
|
||||||
|
```bash
|
||||||
|
SRC_DIR="~/redpanda-src"
|
||||||
|
BUILD_DIR="~/redpanda-build"
|
||||||
|
INSTALL_DIR="~/redpanda-pkg"
|
||||||
|
```
|
||||||
|
2. Navigate to build directory:
|
||||||
|
```bash
|
||||||
|
rm -rf "$BUILD_DIR" # optional for clean build
|
||||||
|
mkdir -p "$BUILD_DIR" && cd "$BUILD_DIR"
|
||||||
|
```
|
||||||
|
3. Configure, build and install:
|
||||||
|
```bash
|
||||||
|
~/Qt/5.15.2/clang_64/bin/qmake PREFIX="$INSTALL_DIR" "$SRC_DIR/Red_Panda_CPP.pro"
|
||||||
|
make -j$(sysctl -n hw.logicalcpu)
|
||||||
|
make install
|
||||||
|
~/Qt/5.15.2/clang_64/bin/macdeployqt "$INSTALL_DIR/bin/RedPandaIDE.app"
|
||||||
|
```
|
||||||
|
|
72
BUILD_cn.md
72
BUILD_cn.md
|
@ -198,12 +198,33 @@
|
||||||
"%JOM%" install
|
"%JOM%" install
|
||||||
```
|
```
|
||||||
|
|
||||||
# Linux
|
# Linux 和其他符合 freedesktop.org(XDG)规范的桌面系统
|
||||||
|
|
||||||
步骤:
|
通用步骤:
|
||||||
- 安装 gcc 和 qt5开发相关包
|
|
||||||
- 如果使用静态版本的 Qt 编译,还要安装 fcitx5-qt
|
- 安装支持 C++17 的 GCC(≥ 7)或 Clang(≥ 6)。
|
||||||
- 使用qtcreator打开Red_Panda_CPP.pro文件
|
- 安装 Qt 5(≥ 5.12)Base、SVG、Tools 模块,包括库和开发文件。
|
||||||
|
- 如果使用静态版本的 Qt 编译,还要安装 fcitx5-qt。
|
||||||
|
- 根据需要,安装 Qt Creator 用于开发。
|
||||||
|
|
||||||
|
仅构建:
|
||||||
|
|
||||||
|
1. 配置:
|
||||||
|
```bash
|
||||||
|
qmake PREFIX=/usr/local /path/to/src/Red_Panda_CPP.pro
|
||||||
|
```
|
||||||
|
2. 构建:
|
||||||
|
```bash
|
||||||
|
make -j$(nproc)
|
||||||
|
```
|
||||||
|
3. 安装:
|
||||||
|
```bash
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
开发:
|
||||||
|
|
||||||
|
1. 使用 Qt Creator 打开 `Red_Panda_CPP.pro` 文件。
|
||||||
|
|
||||||
qmake 变量:
|
qmake 变量:
|
||||||
- `PREFIX`:默认值是 `/usr/local`。打包时应该定义为 `/usr` 或 `/opt/redpanda-cpp`。
|
- `PREFIX`:默认值是 `/usr/local`。打包时应该定义为 `/usr` 或 `/opt/redpanda-cpp`。
|
||||||
|
@ -297,7 +318,7 @@ Windows 宿主的额外要求:
|
||||||
|
|
||||||
注意:makepkg 签出此存储库的 HEAD,因此构建之前务必提交所有变更。
|
注意:makepkg 签出此存储库的 HEAD,因此构建之前务必提交所有变更。
|
||||||
|
|
||||||
## AppImage
|
## Linux AppImage
|
||||||
|
|
||||||
1. 安装依赖包:Docker 或 Podman。
|
1. 安装依赖包:Docker 或 Podman。
|
||||||
|
|
||||||
|
@ -337,9 +358,9 @@ Windows 宿主的额外要求:
|
||||||
|
|
||||||
可以借助 QEMU 用户空间模拟,运行目标架构的本机工具链,来构建小熊猫 C++。
|
可以借助 QEMU 用户空间模拟,运行目标架构的本机工具链,来构建小熊猫 C++。
|
||||||
|
|
||||||
注意:始终**在容器中**运行模拟本机构建,因为混用不同架构的程序和库可能会损坏系统。
|
注意:始终**在容器或 jail 中**运行模拟本机构建,因为混用不同架构的程序和库可能会损坏系统。
|
||||||
|
|
||||||
对于 Linux 宿主,需要安装静态链接的 QEMU 用户空间模拟器(包名通常为 `qemu-user-static`)并确认已经启用 binfmt 支持。
|
对于 Linux 或 BSD 宿主,需要安装静态链接的 QEMU 用户空间模拟器(包名通常为 `qemu-user-static`)并确认已经启用 binfmt 支持。
|
||||||
|
|
||||||
对于 Windows 宿主,Docker 和 Podman 应该已经启用了 QEMU 用户空间模拟。如果没有启用,
|
对于 Windows 宿主,Docker 和 Podman 应该已经启用了 QEMU 用户空间模拟。如果没有启用,
|
||||||
* Docker:
|
* Docker:
|
||||||
|
@ -351,3 +372,38 @@ Windows 宿主的额外要求:
|
||||||
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-aarch64-static.conf /proc/sys/fs/binfmt_misc/register
|
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-aarch64-static.conf /proc/sys/fs/binfmt_misc/register
|
||||||
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-riscv64-static.conf /proc/sys/fs/binfmt_misc/register
|
wsl -d podman-machine-default sudo cp /usr/lib/binfmt.d/qemu-riscv64-static.conf /proc/sys/fs/binfmt_misc/register
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
|
||||||
|
## Qt.io 的 Qt 库
|
||||||
|
|
||||||
|
前置条件:
|
||||||
|
|
||||||
|
0. macOS 10.13 或更高版本。
|
||||||
|
1. 安装 Xcode 命令行工具:
|
||||||
|
```bash
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
2. 用 [Qt.io](https://www.qt.io/download-qt-installer-oss) 或[镜像站](https://mirrors.sjtug.sjtu.edu.cn/docs/qt)的在线安装器安装 Qt。
|
||||||
|
- 选中 Qt 库(“Qt” 组下的 “Qt 5.15.2” 小组,勾选 “macOS”)。
|
||||||
|
|
||||||
|
构建:
|
||||||
|
|
||||||
|
1. 设置相关变量:
|
||||||
|
```bash
|
||||||
|
SRC_DIR="~/redpanda-src"
|
||||||
|
BUILD_DIR="~/redpanda-build"
|
||||||
|
INSTALL_DIR="~/redpanda-pkg"
|
||||||
|
```
|
||||||
|
2. 定位到构建目录:
|
||||||
|
```bash
|
||||||
|
rm -rf "$BUILD_DIR" # 根据需要进行全新构建
|
||||||
|
mkdir -p "$BUILD_DIR" && cd "$BUILD_DIR"
|
||||||
|
```
|
||||||
|
3. 配置、构建、安装:
|
||||||
|
```bash
|
||||||
|
~/Qt/5.15.2/clang_64/bin/qmake PREFIX="$INSTALL_DIR" "$SRC_DIR/Red_Panda_CPP.pro"
|
||||||
|
make -j$(sysctl -n hw.logicalcpu)
|
||||||
|
make install
|
||||||
|
~/Qt/5.15.2/clang_64/bin/macdeployqt "$INSTALL_DIR/bin/RedPandaIDE.app"
|
||||||
|
```
|
||||||
|
|
|
@ -29,10 +29,6 @@ contains(QMAKE_HOST.arch, x86_64):{
|
||||||
}
|
}
|
||||||
|
|
||||||
macos: {
|
macos: {
|
||||||
# This package needs to be installed via homebrew before we can compile it
|
|
||||||
INCLUDEPATH += \
|
|
||||||
/opt/homebrew/opt/icu4c/include
|
|
||||||
|
|
||||||
QT += gui-private
|
QT += gui-private
|
||||||
|
|
||||||
ICON = ../macos/RedPandaIDE.icns
|
ICON = ../macos/RedPandaIDE.icns
|
||||||
|
@ -131,6 +127,7 @@ SOURCES += \
|
||||||
settingsdialog/editortooltipswidget.cpp \
|
settingsdialog/editortooltipswidget.cpp \
|
||||||
settingsdialog/environmentfolderswidget.cpp \
|
settingsdialog/environmentfolderswidget.cpp \
|
||||||
settingsdialog/environmentperformancewidget.cpp \
|
settingsdialog/environmentperformancewidget.cpp \
|
||||||
|
settingsdialog/environmentprogramswidget.cpp \
|
||||||
settingsdialog/environmentshortcutwidget.cpp \
|
settingsdialog/environmentshortcutwidget.cpp \
|
||||||
settingsdialog/executorproblemsetwidget.cpp \
|
settingsdialog/executorproblemsetwidget.cpp \
|
||||||
settingsdialog/formattergeneralwidget.cpp \
|
settingsdialog/formattergeneralwidget.cpp \
|
||||||
|
@ -254,6 +251,7 @@ HEADERS += \
|
||||||
settingsdialog/editortooltipswidget.h \
|
settingsdialog/editortooltipswidget.h \
|
||||||
settingsdialog/environmentfolderswidget.h \
|
settingsdialog/environmentfolderswidget.h \
|
||||||
settingsdialog/environmentperformancewidget.h \
|
settingsdialog/environmentperformancewidget.h \
|
||||||
|
settingsdialog/environmentprogramswidget.h \
|
||||||
settingsdialog/environmentshortcutwidget.h \
|
settingsdialog/environmentshortcutwidget.h \
|
||||||
settingsdialog/executorproblemsetwidget.h \
|
settingsdialog/executorproblemsetwidget.h \
|
||||||
settingsdialog/formattergeneralwidget.h \
|
settingsdialog/formattergeneralwidget.h \
|
||||||
|
@ -349,6 +347,7 @@ FORMS += \
|
||||||
settingsdialog/editortooltipswidget.ui \
|
settingsdialog/editortooltipswidget.ui \
|
||||||
settingsdialog/environmentfolderswidget.ui \
|
settingsdialog/environmentfolderswidget.ui \
|
||||||
settingsdialog/environmentperformancewidget.ui \
|
settingsdialog/environmentperformancewidget.ui \
|
||||||
|
settingsdialog/environmentprogramswidget.ui \
|
||||||
settingsdialog/environmentshortcutwidget.ui \
|
settingsdialog/environmentshortcutwidget.ui \
|
||||||
settingsdialog/executorproblemsetwidget.ui \
|
settingsdialog/executorproblemsetwidget.ui \
|
||||||
settingsdialog/formattergeneralwidget.ui \
|
settingsdialog/formattergeneralwidget.ui \
|
||||||
|
@ -469,21 +468,18 @@ win32: {
|
||||||
|
|
||||||
unix: {
|
unix: {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
settingsdialog/formatterpathwidget.h \
|
settingsdialog/formatterpathwidget.h
|
||||||
settingsdialog/environmentprogramswidget.h
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
settingsdialog/formatterpathwidget.cpp \
|
settingsdialog/formatterpathwidget.cpp
|
||||||
settingsdialog/environmentprogramswidget.cpp
|
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
settingsdialog/formatterpathwidget.ui \
|
settingsdialog/formatterpathwidget.ui
|
||||||
settingsdialog/environmentprogramswidget.ui
|
|
||||||
}
|
}
|
||||||
|
|
||||||
linux: {
|
linux: {
|
||||||
LIBS+= \
|
# legacy glibc compatibility -- modern Unices have all components in `libc.so`
|
||||||
-lrt
|
LIBS += -lrt
|
||||||
|
|
||||||
_LINUX_STATIC_IME_PLUGIN = $$(LINUX_STATIC_IME_PLUGIN)
|
_LINUX_STATIC_IME_PLUGIN = $$(LINUX_STATIC_IME_PLUGIN)
|
||||||
equals(_LINUX_STATIC_IME_PLUGIN, "ON") {
|
equals(_LINUX_STATIC_IME_PLUGIN, "ON") {
|
||||||
|
|
|
@ -62,11 +62,13 @@ void AutolinkManager::load()
|
||||||
file.write(content);
|
file.write(content);
|
||||||
file.close();
|
file.close();
|
||||||
preFile.close();
|
preFile.close();
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_MACOS)
|
||||||
QFile preFile(":/config/autolink-linux.json");
|
return;
|
||||||
|
#else // XDG desktop
|
||||||
|
QFile preFile(":/config/autolink-xdg.json");
|
||||||
if (!preFile.open(QFile::ReadOnly)) {
|
if (!preFile.open(QFile::ReadOnly)) {
|
||||||
throw FileError(QObject::tr("Can't open file '%1' for read.")
|
throw FileError(QObject::tr("Can't open file '%1' for read.")
|
||||||
.arg(":/config/autolink-linux.json"));
|
.arg(":/config/autolink-xdg.json"));
|
||||||
}
|
}
|
||||||
QByteArray content=preFile.readAll();
|
QByteArray content=preFile.readAll();
|
||||||
if (!file.open(QFile::WriteOnly|QFile::Truncate)) {
|
if (!file.open(QFile::WriteOnly|QFile::Truncate)) {
|
||||||
|
@ -76,8 +78,6 @@ void AutolinkManager::load()
|
||||||
file.write(content);
|
file.write(content);
|
||||||
file.close();
|
file.close();
|
||||||
preFile.close();
|
preFile.close();
|
||||||
#else
|
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (file.open(QFile::ReadOnly)) {
|
if (file.open(QFile::ReadOnly)) {
|
||||||
|
|
|
@ -177,9 +177,12 @@ void CompilerInfo::prepareCompilerOptions()
|
||||||
sl.append(QPair<QString,QString>("Strong","-strong"));
|
sl.append(QPair<QString,QString>("Strong","-strong"));
|
||||||
sl.append(QPair<QString,QString>("All","-all"));
|
sl.append(QPair<QString,QString>("All","-all"));
|
||||||
addOption(CC_CMD_OPT_STACK_PROTECTOR , QObject::tr("Check for stack smashing attacks (-fstack-protector)"), groupName, false, false, true, "-fstack-protector", CompilerOptionType::Choice, sl);
|
addOption(CC_CMD_OPT_STACK_PROTECTOR , QObject::tr("Check for stack smashing attacks (-fstack-protector)"), groupName, false, false, true, "-fstack-protector", CompilerOptionType::Choice, sl);
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
#if defined(Q_OS_UNIX)
|
||||||
sl.clear();
|
sl.clear();
|
||||||
sl.append(QPair<QString,QString>("Address","address"));
|
sl.append(QPair<QString,QString>("Address","address"));
|
||||||
|
# ifdef __aarch64__
|
||||||
|
sl.append(QPair<QString,QString>("Hardware-assisted Address","hwaddress"));
|
||||||
|
# endif
|
||||||
sl.append(QPair<QString,QString>("Thread","thread"));
|
sl.append(QPair<QString,QString>("Thread","thread"));
|
||||||
sl.append(QPair<QString,QString>("Leak","leak"));
|
sl.append(QPair<QString,QString>("Leak","leak"));
|
||||||
sl.append(QPair<QString,QString>("Undefined","undefined"));
|
sl.append(QPair<QString,QString>("Undefined","undefined"));
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include "projectcompiler.h"
|
#include "projectcompiler.h"
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
#include <sys/posix_shm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
enum RunProgramFlag {
|
enum RunProgramFlag {
|
||||||
RPF_PAUSE_CONSOLE = 0x0001,
|
RPF_PAUSE_CONSOLE = 0x0001,
|
||||||
|
@ -255,20 +258,32 @@ void CompilerManager::run(
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (consoleFlag!=0) {
|
if (consoleFlag!=0) {
|
||||||
QString sharedMemoryId = QUuid::createUuid().toString();
|
QString sharedMemoryId = QUuid::createUuid().toString();
|
||||||
QString newArguments = QString(" %1 %2 \"%3\" %4")
|
QString consolePauserPath = includeTrailingPathDelimiter(pSettings->dirs().appDir()) + CONSOLE_PAUSER;
|
||||||
.arg(consoleFlag)
|
QStringList execArgs = QStringList{
|
||||||
.arg(sharedMemoryId,localizePath(filename)).arg(arguments);
|
consolePauserPath,
|
||||||
|
QString::number(consoleFlag),
|
||||||
|
sharedMemoryId,
|
||||||
|
localizePath(filename)
|
||||||
|
} + splitProcessCommand(arguments);
|
||||||
|
auto [filename, args, fileOwner] = wrapCommandForTerminalEmulator(
|
||||||
|
pSettings->environment().terminalPathForExec(),
|
||||||
|
pSettings->environment().terminalArgumentsPattern(),
|
||||||
|
execArgs
|
||||||
|
);
|
||||||
//delete when thread finished
|
//delete when thread finished
|
||||||
execRunner = new ExecutableRunner(includeTrailingPathDelimiter(pSettings->dirs().appDir())+CONSOLE_PAUSER,newArguments,workDir);
|
execRunner = new ExecutableRunner(filename, args, workDir);
|
||||||
execRunner->setShareMemoryId(sharedMemoryId);
|
execRunner->setShareMemoryId(sharedMemoryId);
|
||||||
|
mTempFileOwner = std::move(fileOwner);
|
||||||
} else {
|
} else {
|
||||||
//delete when thread finished
|
//delete when thread finished
|
||||||
execRunner = new ExecutableRunner(filename,arguments,workDir);
|
execRunner = new ExecutableRunner(filename,splitProcessCommand(arguments),workDir);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
QString newArguments;
|
QStringList execArgs;
|
||||||
QString sharedMemoryId = "/r"+QUuid::createUuid().toString(QUuid::StringFormat::Id128);
|
QString sharedMemoryId = "/r"+QUuid::createUuid().toString(QUuid::StringFormat::Id128);
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
sharedMemoryId = sharedMemoryId.mid(0, PSHMNAMLEN);
|
||||||
|
#endif
|
||||||
if (consoleFlag!=0) {
|
if (consoleFlag!=0) {
|
||||||
QString consolePauserPath=includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+"consolepauser";
|
QString consolePauserPath=includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+"consolepauser";
|
||||||
if (!fileExists(consolePauserPath)) {
|
if (!fileExists(consolePauserPath)) {
|
||||||
|
@ -280,31 +295,40 @@ void CompilerManager::run(
|
||||||
|
|
||||||
}
|
}
|
||||||
if (redirectInput) {
|
if (redirectInput) {
|
||||||
newArguments = QString(" -e \"%1\" %2 %3 \"%4\" \"%5\" %6")
|
execArgs = QStringList{
|
||||||
.arg(consolePauserPath)
|
consolePauserPath,
|
||||||
.arg(consoleFlag)
|
QString::number(consoleFlag),
|
||||||
.arg(sharedMemoryId)
|
sharedMemoryId,
|
||||||
.arg(escapeSpacesInString(redirectInputFilename))
|
redirectInputFilename,
|
||||||
.arg(localizePath(escapeSpacesInString(filename)))
|
localizePath(filename),
|
||||||
.arg(arguments);
|
} + splitProcessCommand(arguments);
|
||||||
} else {
|
} else {
|
||||||
newArguments = QString(" -e \"%1\" %2 %3 \"%4\" %5")
|
execArgs = QStringList{
|
||||||
.arg(consolePauserPath)
|
consolePauserPath,
|
||||||
.arg(consoleFlag)
|
QString::number(consoleFlag),
|
||||||
.arg(sharedMemoryId,localizePath(escapeSpacesInString(filename))).arg(arguments);
|
sharedMemoryId,
|
||||||
|
localizePath(filename),
|
||||||
|
} + splitProcessCommand(arguments);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newArguments = QString(" -e \"%1\" %2")
|
execArgs = QStringList{
|
||||||
.arg(localizePath(escapeSpacesInString(filename))).arg(arguments);
|
localizePath(filename),
|
||||||
|
} + splitProcessCommand(arguments);
|
||||||
}
|
}
|
||||||
execRunner = new ExecutableRunner(pSettings->environment().terminalPathForExec(),newArguments,workDir);
|
auto [filename, args, fileOwner] = wrapCommandForTerminalEmulator(
|
||||||
|
pSettings->environment().terminalPathForExec(),
|
||||||
|
pSettings->environment().terminalArgumentsPattern(),
|
||||||
|
execArgs
|
||||||
|
);
|
||||||
|
execRunner = new ExecutableRunner(filename, args, workDir);
|
||||||
execRunner->setShareMemoryId(sharedMemoryId);
|
execRunner->setShareMemoryId(sharedMemoryId);
|
||||||
|
mTempFileOwner = std::move(fileOwner);
|
||||||
#endif
|
#endif
|
||||||
execRunner->setStartConsole(true);
|
execRunner->setStartConsole(true);
|
||||||
} else {
|
} else {
|
||||||
//delete when thread finished
|
//delete when thread finished
|
||||||
execRunner = new ExecutableRunner(filename,arguments,workDir);
|
execRunner = new ExecutableRunner(filename,splitProcessCommand(arguments),workDir);
|
||||||
}
|
}
|
||||||
if (redirectInput) {
|
if (redirectInput) {
|
||||||
execRunner->setRedirectInput(true);
|
execRunner->setRedirectInput(true);
|
||||||
execRunner->setRedirectInputFilename(redirectInputFilename);
|
execRunner->setRedirectInputFilename(redirectInputFilename);
|
||||||
|
@ -347,7 +371,7 @@ void CompilerManager::doRunProblem(const QString &filename, const QString &argum
|
||||||
if (mRunner!=nullptr) {
|
if (mRunner!=nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,arguments,workDir,problemCases);
|
OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,splitProcessCommand(arguments),workDir,problemCases);
|
||||||
mRunner = execRunner;
|
mRunner = execRunner;
|
||||||
if (pSettings->executor().enableCaseLimit()) {
|
if (pSettings->executor().enableCaseLimit()) {
|
||||||
execRunner->setExecTimeout(pSettings->executor().caseTimeout());
|
execRunner->setExecTimeout(pSettings->executor().caseTimeout());
|
||||||
|
@ -380,6 +404,7 @@ void CompilerManager::stopRun()
|
||||||
mRunner->stop();
|
mRunner->stop();
|
||||||
disconnect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
|
disconnect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
|
||||||
mRunner=nullptr;
|
mRunner=nullptr;
|
||||||
|
mTempFileOwner=nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +420,7 @@ void CompilerManager::stopPausing()
|
||||||
disconnect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
|
disconnect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
|
||||||
mRunner->stop();
|
mRunner->stop();
|
||||||
mRunner=nullptr;
|
mRunner=nullptr;
|
||||||
|
mTempFileOwner=nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +454,7 @@ void CompilerManager::onRunnerTerminated()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mRunnerMutex);
|
QMutexLocker locker(&mRunnerMutex);
|
||||||
mRunner=nullptr;
|
mRunner=nullptr;
|
||||||
|
mTempFileOwner=nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerManager::onRunnerPausing()
|
void CompilerManager::onRunnerPausing()
|
||||||
|
@ -438,6 +465,7 @@ void CompilerManager::onRunnerPausing()
|
||||||
disconnect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured);
|
disconnect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured);
|
||||||
connect(this, &CompilerManager::signalStopAllRunners, mRunner, &Runner::stop);
|
connect(this, &CompilerManager::signalStopAllRunners, mRunner, &Runner::stop);
|
||||||
mRunner=nullptr;
|
mRunner=nullptr;
|
||||||
|
mTempFileOwner=nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerManager::onCompileIssue(PCompileIssue issue)
|
void CompilerManager::onCompileIssue(PCompileIssue issue)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include "qt_utils/utils.h"
|
#include "qt_utils/utils.h"
|
||||||
|
#include "../utils.h"
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
|
|
||||||
class Runner;
|
class Runner;
|
||||||
|
@ -96,6 +97,7 @@ private:
|
||||||
int mSyntaxCheckIssueCount;
|
int mSyntaxCheckIssueCount;
|
||||||
Compiler* mBackgroundSyntaxChecker;
|
Compiler* mBackgroundSyntaxChecker;
|
||||||
Runner* mRunner;
|
Runner* mRunner;
|
||||||
|
TemporaryFileOwner mTempFileOwner;
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
QRecursiveMutex mCompileMutex;
|
QRecursiveMutex mCompileMutex;
|
||||||
QRecursiveMutex mBackgroundSyntaxCheckMutex;
|
QRecursiveMutex mBackgroundSyntaxCheckMutex;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#elif defined(Q_OS_LINUX)
|
#else
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ExecutableRunner::ExecutableRunner(const QString &filename, const QString &arguments, const QString &workDir
|
ExecutableRunner::ExecutableRunner(const QString &filename, const QStringList &arguments, const QString &workDir
|
||||||
,QObject* parent):
|
,QObject* parent):
|
||||||
Runner(filename,arguments,workDir,parent),
|
Runner(filename,arguments,workDir,parent),
|
||||||
mRedirectInput(false),
|
mRedirectInput(false),
|
||||||
|
@ -110,7 +110,7 @@ void ExecutableRunner::run()
|
||||||
|
|
||||||
mProcess = std::make_shared<QProcess>();
|
mProcess = std::make_shared<QProcess>();
|
||||||
mProcess->setProgram(mFilename);
|
mProcess->setProgram(mFilename);
|
||||||
mProcess->setArguments(splitProcessCommand(mArguments));
|
mProcess->setArguments(mArguments);
|
||||||
//qDebug()<<splitProcessCommand(mArguments);
|
//qDebug()<<splitProcessCommand(mArguments);
|
||||||
mProcess->setWorkingDirectory(mWorkDir);
|
mProcess->setWorkingDirectory(mWorkDir);
|
||||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
@ -162,7 +162,7 @@ void ExecutableRunner::run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(Q_OS_LINUX)
|
#else
|
||||||
int BUF_SIZE=1024;
|
int BUF_SIZE=1024;
|
||||||
char* pBuf=nullptr;
|
char* pBuf=nullptr;
|
||||||
int fd_shm = shm_open(mShareMemoryId.toLocal8Bit().data(),O_RDWR | O_CREAT,S_IRWXU);
|
int fd_shm = shm_open(mShareMemoryId.toLocal8Bit().data(),O_RDWR | O_CREAT,S_IRWXU);
|
||||||
|
@ -214,7 +214,6 @@ void ExecutableRunner::run()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
|
|
||||||
if (mStartConsole && !mPausing && pBuf) {
|
if (mStartConsole && !mPausing && pBuf) {
|
||||||
if (strncmp(pBuf,"FINISHED",sizeof("FINISHED"))==0) {
|
if (strncmp(pBuf,"FINISHED",sizeof("FINISHED"))==0) {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -226,7 +225,7 @@ void ExecutableRunner::run()
|
||||||
hSharedMemory = INVALID_HANDLE_VALUE;
|
hSharedMemory = INVALID_HANDLE_VALUE;
|
||||||
CloseHandle(hSharedMemory);
|
CloseHandle(hSharedMemory);
|
||||||
}
|
}
|
||||||
#elif defined(Q_OS_LINUX)
|
#else
|
||||||
if (pBuf) {
|
if (pBuf) {
|
||||||
munmap(pBuf,BUF_SIZE);
|
munmap(pBuf,BUF_SIZE);
|
||||||
pBuf = nullptr;
|
pBuf = nullptr;
|
||||||
|
@ -240,14 +239,13 @@ void ExecutableRunner::run()
|
||||||
emit pausingForFinish();
|
emit pausingForFinish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (pBuf)
|
if (pBuf)
|
||||||
UnmapViewOfFile(pBuf);
|
UnmapViewOfFile(pBuf);
|
||||||
if (hSharedMemory!=INVALID_HANDLE_VALUE && hSharedMemory!=NULL)
|
if (hSharedMemory!=INVALID_HANDLE_VALUE && hSharedMemory!=NULL)
|
||||||
CloseHandle(hSharedMemory);
|
CloseHandle(hSharedMemory);
|
||||||
#elif defined(Q_OS_LINUX)
|
#else
|
||||||
if (pBuf) {
|
if (pBuf) {
|
||||||
munmap(pBuf,BUF_SIZE);
|
munmap(pBuf,BUF_SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ExecutableRunner : public Runner
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ExecutableRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
ExecutableRunner(const QString& filename, const QStringList& arguments, const QString& workDir,
|
||||||
QObject* parent = nullptr);
|
QObject* parent = nullptr);
|
||||||
ExecutableRunner(const ExecutableRunner&)=delete;
|
ExecutableRunner(const ExecutableRunner&)=delete;
|
||||||
ExecutableRunner& operator=(const ExecutableRunner&)=delete;
|
ExecutableRunner& operator=(const ExecutableRunner&)=delete;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QStringList& arguments, const QString& workDir,
|
||||||
const QVector<POJProblemCase>& problemCases, QObject *parent):
|
const QVector<POJProblemCase>& problemCases, QObject *parent):
|
||||||
Runner(filename,arguments,workDir,parent),
|
Runner(filename,arguments,workDir,parent),
|
||||||
mExecTimeout(0),
|
mExecTimeout(0),
|
||||||
|
@ -37,7 +37,7 @@ OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QStrin
|
||||||
setWaitForFinishTime(100);
|
setWaitForFinishTime(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QStringList& arguments, const QString& workDir,
|
||||||
POJProblemCase problemCase, QObject *parent):
|
POJProblemCase problemCase, QObject *parent):
|
||||||
Runner(filename,arguments,workDir,parent),
|
Runner(filename,arguments,workDir,parent),
|
||||||
mExecTimeout(0),
|
mExecTimeout(0),
|
||||||
|
@ -64,7 +64,7 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
|
||||||
QElapsedTimer elapsedTimer;
|
QElapsedTimer elapsedTimer;
|
||||||
bool execTimeouted = false;
|
bool execTimeouted = false;
|
||||||
process.setProgram(mFilename);
|
process.setProgram(mFilename);
|
||||||
process.setArguments(splitProcessCommand(mArguments));
|
process.setArguments(mArguments);
|
||||||
process.setWorkingDirectory(mWorkDir);
|
process.setWorkingDirectory(mWorkDir);
|
||||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
QString path = env.value("PATH");
|
QString path = env.value("PATH");
|
||||||
|
|
|
@ -25,10 +25,10 @@ class OJProblemCasesRunner : public Runner
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
explicit OJProblemCasesRunner(const QString& filename, const QStringList& arguments, const QString& workDir,
|
||||||
const QVector<POJProblemCase>& problemCases,
|
const QVector<POJProblemCase>& problemCases,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
explicit OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
explicit OJProblemCasesRunner(const QString& filename, const QStringList& arguments, const QString& workDir,
|
||||||
POJProblemCase problemCase,
|
POJProblemCase problemCase,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
OJProblemCasesRunner(const OJProblemCasesRunner&)=delete;
|
OJProblemCasesRunner(const OJProblemCasesRunner&)=delete;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "runner.h"
|
#include "runner.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
Runner::Runner(const QString &filename, const QString &arguments, const QString &workDir
|
Runner::Runner(const QString &filename, const QStringList &arguments, const QString &workDir
|
||||||
,QObject *parent) : QThread(parent),
|
,QObject *parent) : QThread(parent),
|
||||||
mPausing(false),
|
mPausing(false),
|
||||||
mStop(false),
|
mStop(false),
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Runner : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Runner(const QString& filename, const QString& arguments, const QString& workDir, QObject *parent = nullptr);
|
explicit Runner(const QString& filename, const QStringList& arguments, const QString& workDir, QObject *parent = nullptr);
|
||||||
Runner(const Runner&)=delete;
|
Runner(const Runner&)=delete;
|
||||||
Runner operator=(const Runner&)=delete;
|
Runner operator=(const Runner&)=delete;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ protected:
|
||||||
bool mPausing;
|
bool mPausing;
|
||||||
bool mStop;
|
bool mStop;
|
||||||
QString mFilename;
|
QString mFilename;
|
||||||
QString mArguments;
|
QStringList mArguments; // without argv[0]
|
||||||
QString mWorkDir;
|
QString mWorkDir;
|
||||||
int mWaitForFinishTime;
|
int mWaitForFinishTime;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
<qresource prefix="/config">
|
<qresource prefix="/config">
|
||||||
<file alias="autolink.json">resources/autolink.json</file>
|
<file alias="autolink.json">resources/autolink.json</file>
|
||||||
<file alias="codesnippets.json">resources/codesnippets.json</file>
|
<file alias="codesnippets.json">resources/codesnippets.json</file>
|
||||||
<file alias="autolink-linux.json">resources/autolink-linux.json</file>
|
<file alias="autolink-xdg.json">resources/autolink-xdg.json</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -248,6 +248,23 @@ int main(int argc, char *argv[])
|
||||||
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
|
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
// in macOS GUI apps, `/usr/local/bin` is not in PATH by default
|
||||||
|
// follow the Unix way by prepending it to `/usr/bin`
|
||||||
|
{
|
||||||
|
QStringList pathList = getExecutableSearchPaths();
|
||||||
|
if (!pathList.contains("/usr/local/bin")) {
|
||||||
|
auto idxUsrBin = pathList.indexOf("/usr/bin");
|
||||||
|
if (idxUsrBin >= 0)
|
||||||
|
pathList.insert(idxUsrBin, "/usr/local/bin");
|
||||||
|
else
|
||||||
|
pathList.append("/usr/local/bin");
|
||||||
|
}
|
||||||
|
QString newPath = pathList.join(PATH_SEPARATOR);
|
||||||
|
qputenv("PATH", newPath.toUtf8());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
"header": "fmt/core.h",
|
||||||
|
"links": "-lfmt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "math.h",
|
||||||
|
"links": "-lm"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"execUseUTF8": true,
|
"execUseUTF8": true,
|
||||||
"header": "raylib.h",
|
"header": "raylib.h",
|
||||||
|
@ -11,5 +19,13 @@
|
||||||
{
|
{
|
||||||
"header": "rturtle.h",
|
"header": "rturtle.h",
|
||||||
"links": "-lrturtle"
|
"links": "-lrturtle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "thread",
|
||||||
|
"links": "-lpthread"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "threads.h",
|
||||||
|
"links": "-lpthread"
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -203,13 +203,13 @@ QString Settings::Dirs::appResourceDir() const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return appDir();
|
return appDir();
|
||||||
#elif defined(Q_OS_LINUX)
|
|
||||||
// in AppImage PREFIX is not true, resolve from relative path
|
|
||||||
const static QString absoluteResourceDir(QDir(appDir()).absoluteFilePath("../share/" APP_NAME));
|
|
||||||
return absoluteResourceDir;
|
|
||||||
#elif defined(Q_OS_MACOS)
|
#elif defined(Q_OS_MACOS)
|
||||||
// return QApplication::instance()->applicationDirPath();
|
// return QApplication::instance()->applicationDirPath();
|
||||||
return "";
|
return "";
|
||||||
|
#else // XDG desktop
|
||||||
|
// in AppImage or tarball PREFIX is not true, resolve from relative path
|
||||||
|
const static QString absoluteResourceDir(QDir(appDir()).absoluteFilePath("../share/" APP_NAME));
|
||||||
|
return absoluteResourceDir;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,13 +218,13 @@ QString Settings::Dirs::appLibexecDir() const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return appDir();
|
return appDir();
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_MACOS)
|
||||||
// in AppImage LIBEXECDIR is not true, resolve from relative path
|
return QApplication::instance()->applicationDirPath();
|
||||||
|
#else // XDG desktop
|
||||||
|
// in AppImage or tarball LIBEXECDIR is not true, resolve from relative path
|
||||||
const static QString relativeLibExecDir(QDir(PREFIX "/bin").relativeFilePath(LIBEXECDIR "/" APP_NAME));
|
const static QString relativeLibExecDir(QDir(PREFIX "/bin").relativeFilePath(LIBEXECDIR "/" APP_NAME));
|
||||||
const static QString absoluteLibExecDir(QDir(appDir()).absoluteFilePath(relativeLibExecDir));
|
const static QString absoluteLibExecDir(QDir(appDir()).absoluteFilePath(relativeLibExecDir));
|
||||||
return absoluteLibExecDir;
|
return absoluteLibExecDir;
|
||||||
#elif defined(Q_OS_MACOS)
|
|
||||||
return QApplication::instance()->applicationDirPath();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1473,16 +1473,16 @@ void Settings::Editor::doLoad()
|
||||||
mRightEdgeLineColor = colorValue("right_edge_line_color",Qt::yellow);
|
mRightEdgeLineColor = colorValue("right_edge_line_color",Qt::yellow);
|
||||||
|
|
||||||
//Editor font
|
//Editor font
|
||||||
#ifdef Q_OS_WIN
|
mFontName = stringValue("font_name",DEFAULT_MONO_FONT);
|
||||||
mFontName = stringValue("font_name","consolas");
|
QString defaultCjkFontName = CJK_MONO_FONT_SC;
|
||||||
mNonAsciiFontName = stringValue("non_ascii_font_name","consolas");
|
QString defaultLocaleName = QLocale::system().name();
|
||||||
#elif defined(Q_OS_MACOS)
|
if (defaultLocaleName == "zh_TW")
|
||||||
mFontName = stringValue("font_name","Menlo");
|
defaultCjkFontName = CJK_MONO_FONT_TC;
|
||||||
mNonAsciiFontName = stringValue("non_ascii_font_name","PingFang SC");
|
else if (defaultLocaleName == "ja_JP")
|
||||||
#else
|
defaultCjkFontName = CJK_MONO_FONT_J;
|
||||||
mFontName = stringValue("font_name","Dejavu Sans Mono");
|
else if (defaultLocaleName == "ko_KR")
|
||||||
mNonAsciiFontName = stringValue("non_ascii_font_name","Dejavu Sans Mono");
|
defaultCjkFontName = CJK_MONO_FONT_K;
|
||||||
#endif
|
mNonAsciiFontName = stringValue("non_ascii_font_name",defaultCjkFontName);
|
||||||
mFontSize = intValue("font_size",12);
|
mFontSize = intValue("font_size",12);
|
||||||
mFontOnlyMonospaced = boolValue("font_only_monospaced",true);
|
mFontOnlyMonospaced = boolValue("font_only_monospaced",true);
|
||||||
mLineSpacing = doubleValue("line_spacing",1.0);
|
mLineSpacing = doubleValue("line_spacing",1.0);
|
||||||
|
@ -1504,11 +1504,7 @@ void Settings::Editor::doLoad()
|
||||||
mGutterLineNumbersStartZero = boolValue("gutter_line_numbers_start_zero",false);
|
mGutterLineNumbersStartZero = boolValue("gutter_line_numbers_start_zero",false);
|
||||||
mGutterUseCustomFont = boolValue("gutter_use_custom_font",false);
|
mGutterUseCustomFont = boolValue("gutter_use_custom_font",false);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
mGutterFontName = stringValue("gutter_font_name",DEFAULT_MONO_FONT);
|
||||||
mGutterFontName = stringValue("gutter_font_name","consolas");
|
|
||||||
#else
|
|
||||||
mGutterFontName = stringValue("gutter_font_name","Dejavu Sans Mono");
|
|
||||||
#endif
|
|
||||||
mGutterFontSize = intValue("gutter_font_size",12);
|
mGutterFontSize = intValue("gutter_font_size",12);
|
||||||
mGutterFontOnlyMonospaced = boolValue("gutter_font_only_monospaced",true);
|
mGutterFontOnlyMonospaced = boolValue("gutter_font_only_monospaced",true);
|
||||||
|
|
||||||
|
@ -2999,11 +2995,11 @@ static void setDebugOptions(Settings::PCompilerSet pSet, bool enableAsan = false
|
||||||
pSet->setCompileOption(CC_CMD_OPT_USE_PIPE, COMPILER_OPTION_ON);
|
pSet->setCompileOption(CC_CMD_OPT_USE_PIPE, COMPILER_OPTION_ON);
|
||||||
|
|
||||||
if (enableAsan) {
|
if (enableAsan) {
|
||||||
|
#ifdef __aarch64__
|
||||||
|
pSet->setCompileOption(CC_CMD_OPT_ADDRESS_SANITIZER, "hwaddress");
|
||||||
|
#else
|
||||||
pSet->setCompileOption(CC_CMD_OPT_ADDRESS_SANITIZER, "address");
|
pSet->setCompileOption(CC_CMD_OPT_ADDRESS_SANITIZER, "address");
|
||||||
// pSet->setCustomCompileParams("-fsanitize=address");
|
#endif
|
||||||
// pSet->setUseCustomCompileParams(true);
|
|
||||||
// pSet->setCustomLinkParams("-fsanitize=address");
|
|
||||||
// pSet->setUseCustomLinkParams(true);
|
|
||||||
}
|
}
|
||||||
//Some windows gcc don't correctly support this
|
//Some windows gcc don't correctly support this
|
||||||
//pSet->setCompileOption(CC_CMD_OPT_STACK_PROTECTOR, "-strong");
|
//pSet->setCompileOption(CC_CMD_OPT_STACK_PROTECTOR, "-strong");
|
||||||
|
@ -3064,8 +3060,8 @@ bool Settings::CompilerSets::addSets(const QString &folder, const QString& c_pro
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# if defined(__x86_64__) || __SIZEOF_POINTER__ == 4
|
# if defined(__x86_64__) || defined(__aarch64__) || __SIZEOF_POINTER__ == 4
|
||||||
mDefaultIndex = (int)mList.size() - 1; // x86-64 Linux or 32-bit Unix, default to "debug with ASan"
|
mDefaultIndex = (int)mList.size() - 1; // x86-64, AArch64 Linux or 32-bit Unix, default to "debug with ASan"
|
||||||
# else
|
# else
|
||||||
mDefaultIndex = (int)mList.size() - 2; // other Unix, where ASan can be very slow, default to "debug"
|
mDefaultIndex = (int)mList.size() - 2; // other Unix, where ASan can be very slow, default to "debug"
|
||||||
# endif
|
# endif
|
||||||
|
@ -3576,17 +3572,20 @@ void Settings::Environment::doLoad()
|
||||||
{
|
{
|
||||||
//Appearance
|
//Appearance
|
||||||
mTheme = stringValue("theme","dark");
|
mTheme = stringValue("theme","dark");
|
||||||
QString defaultFontName = "Segoe UI";
|
QString defaultFontName = DEFAULT_UI_FONT;
|
||||||
QString defaultLocaleName = QLocale::system().name();
|
QString defaultLocaleName = QLocale::system().name();
|
||||||
if (defaultLocaleName == "zh_CN") {
|
{
|
||||||
QString fontName;
|
QString fontName;
|
||||||
#ifdef Q_OS_WINDOWS
|
if (defaultLocaleName == "zh_CN")
|
||||||
fontName = "Microsoft Yahei";
|
fontName = CJK_UI_FONT_SC;
|
||||||
#elif defined(Q_OS_MACOS)
|
else if (defaultLocaleName == "zh_TW")
|
||||||
fontName = "PingFang SC";
|
fontName = CJK_UI_FONT_TC;
|
||||||
#elif defined(Q_OS_LINUX)
|
else if (defaultLocaleName == "ja_JP")
|
||||||
fontName = "Noto Sans CJK";
|
fontName = CJK_UI_FONT_J;
|
||||||
#endif
|
else if (defaultLocaleName == "ko_KR")
|
||||||
|
fontName = CJK_UI_FONT_K;
|
||||||
|
else
|
||||||
|
fontName = DEFAULT_UI_FONT;
|
||||||
QFont font(fontName);
|
QFont font(fontName);
|
||||||
if (font.exactMatch()) {
|
if (font.exactMatch()) {
|
||||||
defaultFontName = fontName;
|
defaultFontName = fontName;
|
||||||
|
@ -3608,58 +3607,85 @@ void Settings::Environment::doLoad()
|
||||||
if (!fileExists(mDefaultOpenFolder)) {
|
if (!fileExists(mDefaultOpenFolder)) {
|
||||||
mDefaultOpenFolder = QDir::currentPath();
|
mDefaultOpenFolder = QDir::currentPath();
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
|
|
||||||
#define SYSTEM_TERMINAL(term) "/usr/bin/" #term, "/usr/local/bin/" #term
|
using AP = TerminalEmulatorArgumentsPattern;
|
||||||
const static QString terminals[] {
|
struct TerminalSearchItem {
|
||||||
|
QString appName;
|
||||||
|
AP argsPattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const TerminalSearchItem terminals[] {
|
||||||
|
/* explicitly installed terminals */
|
||||||
|
|
||||||
|
/* system */
|
||||||
|
{"conhost.exe", AP::ImplicitSystem}, // dummy for system default
|
||||||
|
|
||||||
|
/* will not actually be searched, just a list for users who dig into here */
|
||||||
|
{"conhost.exe", AP::MinusMinusAppendArgs}, // yes, it accepts GNU-style (--) arguments
|
||||||
|
{"wt.exe", AP::MinusMinusAppendArgs}, // generally okay, but “Test” does not work
|
||||||
|
{"alacritty.exe", AP::MinusEAppendArgs}, // GPU-accelerated
|
||||||
|
{"C:/Program Files/Alacritty/alacritty.exe", AP::MinusEAppendArgs},
|
||||||
|
{"C:/Program Files/konsole/bin/konsole.exe", AP::MinusEAppendArgs}, // generally okay, but “Test” does not work
|
||||||
|
{"C:/Program Files/Git/usr/bin/mintty.exe", AP::MinusEAppendArgs}, // Git Mintty
|
||||||
|
{"C:/msys64/usr/bin/mintty.exe", AP::MinusEAppendArgs}, // MSYS2 Mintty
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const TerminalSearchItem terminals[] {
|
||||||
/* modern, specialized or stylized terminal -- user who installed them are likely to prefer them */
|
/* modern, specialized or stylized terminal -- user who installed them are likely to prefer them */
|
||||||
SYSTEM_TERMINAL(alacritty), // GPU-accelerated
|
{"alacritty", AP::MinusEAppendArgs}, // GPU-accelerated
|
||||||
SYSTEM_TERMINAL(kitty), // GPU-accelerated
|
{"kitty", AP::MinusEAppendArgs}, // GPU-accelerated
|
||||||
SYSTEM_TERMINAL(wayst), // GPU-accelerated
|
{"wayst", AP::MinusEAppendArgs}, // GPU-accelerated
|
||||||
SYSTEM_TERMINAL(tilix), // tiling
|
|
||||||
SYSTEM_TERMINAL(cool-retro-term), // old CRT style
|
|
||||||
|
|
||||||
/* default terminal for DE */
|
{"coreterminal", AP::MinusEAppendCommandLine}, // lightweighted
|
||||||
SYSTEM_TERMINAL(konsole), // KDE
|
{"kermit", AP::MinusEAppendCommandLine}, // lightweighted
|
||||||
SYSTEM_TERMINAL(deepin-terminal), // DDE
|
{"roxterm", AP::MinusEAppendCommandLine}, // lightweighted
|
||||||
SYSTEM_TERMINAL(qterminal), // LXQt
|
{"sakura", AP::MinusEAppendCommandLine}, // lightweighted
|
||||||
SYSTEM_TERMINAL(lxterminal), // LXDE
|
{"termit", AP::MinusEAppendArgs}, // Lua scripting
|
||||||
|
{"termite", AP::MinusEAppendCommandLine}, // tiling, keyboard-centric
|
||||||
|
{"tilix", AP::MinusEAppendArgs}, // tiling
|
||||||
|
|
||||||
|
{"cool-retro-term", AP::MinusEAppendArgs}, // old CRT style
|
||||||
|
|
||||||
|
/* default terminal for XDG DE -- macOS user who installed them are likely to prefer them */
|
||||||
|
{"deepin-terminal", AP::MinusEAppendArgs}, // DDE
|
||||||
|
{"konsole", AP::MinusEAppendArgs}, // KDE
|
||||||
|
{"gnome-terminal", AP::MinusMinusAppendArgs}, // GNOME
|
||||||
|
{"io.elementary.terminal", AP::MinusEAppendCommandLine}, // Pantheon (elementary OS)
|
||||||
|
{"lxterminal", AP::MinusEAppendArgs}, // LXDE
|
||||||
|
{"mate-terminal", AP::MinusXAppendArgs}, // MATE
|
||||||
|
{"qterminal", AP::MinusEAppendArgs}, // LXQt
|
||||||
|
{"terminator", AP::MinusXAppendArgs}, // tiling, also seen in SBC images
|
||||||
|
{"terminology", AP::MinusEAppendCommandLine}, // Enlightenment
|
||||||
|
{"xfce4-terminal", AP::MinusXAppendArgs}, // Xfce
|
||||||
|
|
||||||
/* bundled terminal in AppImage */
|
/* bundled terminal in AppImage */
|
||||||
"alacritty",
|
{"./alacritty", AP::MinusEAppendArgs},
|
||||||
|
|
||||||
/* compatible, with minor issue */
|
/* compatible, with minor issue */
|
||||||
SYSTEM_TERMINAL(kgx), // GNOME Console, confirm to quit
|
{"kgx", AP::MinusMinusAppendArgs}, // GNOME Console, confirm to quit
|
||||||
SYSTEM_TERMINAL(coreterminal), // not so conforming when parsing args
|
|
||||||
SYSTEM_TERMINAL(sakura), // not so conforming when parsing args
|
|
||||||
|
|
||||||
/* compatible, without out-of-box hidpi support */
|
/* compatible, without out-of-box hidpi support on Linux */
|
||||||
SYSTEM_TERMINAL(mlterm),
|
{"mlterm", AP::MinusEAppendArgs},
|
||||||
SYSTEM_TERMINAL(st),
|
{"st", AP::MinusEAppendArgs},
|
||||||
SYSTEM_TERMINAL(terminology), // also not so conforming when parsing args
|
{"urxvt", AP::MinusEAppendArgs},
|
||||||
SYSTEM_TERMINAL(urxvt),
|
{"xterm", AP::MinusEAppendArgs},
|
||||||
SYSTEM_TERMINAL(xterm),
|
{"zutty", AP::MinusEAppendArgs},
|
||||||
SYSTEM_TERMINAL(zutty),
|
|
||||||
|
/* macOS system */
|
||||||
|
{"/Applications/iTerm.app/Contents/MacOS/iTerm2", AP::WriteCommandLineToTempFileThenTempFilename},
|
||||||
|
{"/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal", AP::WriteCommandLineToTempFileThenTempFilename},
|
||||||
|
{"/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal", AP::WriteCommandLineToTempFileThenTempFilename},
|
||||||
|
|
||||||
/* fallbacks */
|
/* fallbacks */
|
||||||
SYSTEM_TERMINAL(foot), // Wayland only
|
{"foot", AP::MinusEAppendArgs}, // Wayland only
|
||||||
SYSTEM_TERMINAL(x-terminal-emulator), // Debian alternatives
|
|
||||||
|
|
||||||
/* parameter incompatible */
|
/* parameter incompatible */
|
||||||
// "gnome-terminal",
|
// "guake", // drop down
|
||||||
// "guake",
|
// "hyper", // no execute support
|
||||||
// "hyper",
|
// "liri-terminal", // no execute support
|
||||||
// "io.elementary.terminal",
|
// "station", // no execute support
|
||||||
// "kermit",
|
// "tilda", // drop down
|
||||||
// "liri-terminal",
|
|
||||||
// "mate-terminal",
|
|
||||||
// "roxterm",
|
|
||||||
// "station",
|
|
||||||
// "terminator",
|
|
||||||
// "termite",
|
|
||||||
// "tilda",
|
|
||||||
// "xfce4-terminal",
|
|
||||||
// "yakuake",
|
|
||||||
|
|
||||||
/* incompatible -- other */
|
/* incompatible -- other */
|
||||||
// "aterm", // AUR broken, unable to test
|
// "aterm", // AUR broken, unable to test
|
||||||
|
@ -3667,22 +3693,57 @@ void Settings::Environment::doLoad()
|
||||||
// "rxvt", // no unicode support
|
// "rxvt", // no unicode support
|
||||||
// "shellinabox", // AUR broken, unable to test
|
// "shellinabox", // AUR broken, unable to test
|
||||||
};
|
};
|
||||||
#undef SYSTEM_TERMINAL
|
#endif
|
||||||
|
|
||||||
auto checkAndSetTerminalPath = [this](QString terminalPath) -> bool {
|
auto checkAndSetTerminalPath = [this](const TerminalSearchItem &searchItem) -> bool {
|
||||||
QDir appDir(pSettings->dirs().appDir());
|
#define DO_CHECK_AND_SET do { \
|
||||||
QString absoluteTerminalPath = appDir.absoluteFilePath(terminalPath);
|
if (termPathInfo.isFile() && termPathInfo.isReadable() && termPathInfo.isExecutable()) { \
|
||||||
QFileInfo termPathInfo(absoluteTerminalPath);
|
mTerminalPath = searchItem.appName; \
|
||||||
if (termPathInfo.isFile() && termPathInfo.isReadable() && termPathInfo.isExecutable()) {
|
mTerminalArgumentsPattern = searchItem.argsPattern; \
|
||||||
mTerminalPath = terminalPath;
|
return true; \
|
||||||
return true;
|
} \
|
||||||
} else {
|
} while (0)
|
||||||
return false;
|
|
||||||
|
switch (getPathUnixExecSemantics(searchItem.appName)) {
|
||||||
|
case UnixExecSemantics::Absolute: {
|
||||||
|
QFileInfo termPathInfo(searchItem.appName);
|
||||||
|
DO_CHECK_AND_SET;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case UnixExecSemantics::RelativeToCwd: {
|
||||||
|
QDir appDir(pSettings->dirs().appDir());
|
||||||
|
QString absoluteTerminalPath = appDir.absoluteFilePath(searchItem.appName);
|
||||||
|
QFileInfo termPathInfo(absoluteTerminalPath);
|
||||||
|
DO_CHECK_AND_SET;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UnixExecSemantics::SearchInPath: {
|
||||||
|
auto pathList = getExecutableSearchPaths();
|
||||||
|
for (auto &dir: pathList) {
|
||||||
|
QString absoluteTerminalPath = QDir(dir).absoluteFilePath(searchItem.appName);
|
||||||
|
QFileInfo termPathInfo(absoluteTerminalPath);
|
||||||
|
DO_CHECK_AND_SET;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
#undef DO_CHECK_AND_SET
|
||||||
|
|
||||||
// check saved terminal path
|
// check saved terminal path
|
||||||
if (!checkAndSetTerminalPath(stringValue("terminal_path", ""))) {
|
QString savedTerminalPath = stringValue("terminal_path", "");
|
||||||
|
int savedArgsPattern_ = intValue("terminal_arguments_pattern",
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
// macOS: old versions have set Terminal.app as default terminal
|
||||||
|
// fallback to temp file to work with Terminal.app for smooth migration
|
||||||
|
int(AP::WriteCommandLineToTempFileThenTempFilename)
|
||||||
|
#else
|
||||||
|
int(AP::MinusEAppendArgs) // Linux: keep old behaviour
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
AP savedArgsPattern = static_cast<AP>(savedArgsPattern_);
|
||||||
|
if (!checkAndSetTerminalPath(TerminalSearchItem{savedTerminalPath, savedArgsPattern})) {
|
||||||
// if saved terminal path is invalid, try determing terminal from our list
|
// if saved terminal path is invalid, try determing terminal from our list
|
||||||
for (auto terminal: terminals) {
|
for (auto terminal: terminals) {
|
||||||
if (checkAndSetTerminalPath(terminal))
|
if (checkAndSetTerminalPath(terminal))
|
||||||
|
@ -3691,11 +3752,6 @@ void Settings::Environment::doLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
mAStylePath = includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+"astyle";
|
mAStylePath = includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+"astyle";
|
||||||
#elif defined(Q_OS_MACOS)
|
|
||||||
mTerminalPath = stringValue("terminal_path",
|
|
||||||
"/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal");
|
|
||||||
mAStylePath = includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+"astyle";
|
|
||||||
#endif
|
|
||||||
mHideNonSupportFilesInFileView=boolValue("hide_non_support_files_file_view",true);
|
mHideNonSupportFilesInFileView=boolValue("hide_non_support_files_file_view",true);
|
||||||
mOpenFilesInSingleInstance = boolValue("open_files_in_single_instance",false);
|
mOpenFilesInSingleInstance = boolValue("open_files_in_single_instance",false);
|
||||||
}
|
}
|
||||||
|
@ -3757,13 +3813,11 @@ QString Settings::Environment::terminalPath() const
|
||||||
|
|
||||||
QString Settings::Environment::terminalPathForExec() const
|
QString Settings::Environment::terminalPathForExec() const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_LINUX
|
if (getPathUnixExecSemantics(mTerminalPath) == UnixExecSemantics::RelativeToCwd) {
|
||||||
// `mTerminalPath` can be reletive (bundled terminal in AppImage).
|
QDir appDir(pSettings->dirs().appDir());
|
||||||
QDir appDir(pSettings->dirs().appDir());
|
return appDir.absoluteFilePath(mTerminalPath);
|
||||||
return appDir.absoluteFilePath(mTerminalPath);
|
} else
|
||||||
#else
|
return mTerminalPath;
|
||||||
return mTerminalPath;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::Environment::setTerminalPath(const QString &terminalPath)
|
void Settings::Environment::setTerminalPath(const QString &terminalPath)
|
||||||
|
@ -3781,6 +3835,16 @@ void Settings::Environment::setAStylePath(const QString &aStylePath)
|
||||||
mAStylePath = aStylePath;
|
mAStylePath = aStylePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerminalEmulatorArgumentsPattern Settings::Environment::terminalArgumentsPattern() const
|
||||||
|
{
|
||||||
|
return mTerminalArgumentsPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::Environment::setTerminalArgumentsPattern(const TerminalEmulatorArgumentsPattern &argsPattern)
|
||||||
|
{
|
||||||
|
mTerminalArgumentsPattern = argsPattern;
|
||||||
|
}
|
||||||
|
|
||||||
bool Settings::Environment::useCustomIconSet() const
|
bool Settings::Environment::useCustomIconSet() const
|
||||||
{
|
{
|
||||||
return mUseCustomIconSet;
|
return mUseCustomIconSet;
|
||||||
|
@ -3845,10 +3909,9 @@ void Settings::Environment::doSave()
|
||||||
|
|
||||||
saveValue("current_folder",mCurrentFolder);
|
saveValue("current_folder",mCurrentFolder);
|
||||||
saveValue("default_open_folder",mDefaultOpenFolder);
|
saveValue("default_open_folder",mDefaultOpenFolder);
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
saveValue("terminal_path",mTerminalPath);
|
saveValue("terminal_path",mTerminalPath);
|
||||||
|
saveValue("terminal_arguments_pattern",int(mTerminalArgumentsPattern));
|
||||||
saveValue("asyle_path",mAStylePath);
|
saveValue("asyle_path",mAStylePath);
|
||||||
#endif
|
|
||||||
|
|
||||||
saveValue("hide_non_support_files_file_view",mHideNonSupportFilesInFileView);
|
saveValue("hide_non_support_files_file_view",mHideNonSupportFilesInFileView);
|
||||||
saveValue("open_files_in_single_instance",mOpenFilesInSingleInstance);
|
saveValue("open_files_in_single_instance",mOpenFilesInSingleInstance);
|
||||||
|
@ -4111,13 +4174,7 @@ void Settings::Executor::doLoad()
|
||||||
mProblemCaseValidateType =(ProblemCaseValidateType)intValue("problem_case_validate_type", (int)ProblemCaseValidateType::Exact);
|
mProblemCaseValidateType =(ProblemCaseValidateType)intValue("problem_case_validate_type", (int)ProblemCaseValidateType::Exact);
|
||||||
mRedirectStderrToToolLog = boolValue("redirect_stderr_to_toollog", false);
|
mRedirectStderrToToolLog = boolValue("redirect_stderr_to_toollog", false);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
mCaseEditorFontName = stringValue("case_editor_font_name",DEFAULT_MONO_FONT);
|
||||||
mCaseEditorFontName = stringValue("case_editor_font_name","consolas");
|
|
||||||
#elif defined(Q_OS_MACOS)
|
|
||||||
mCaseEditorFontName = stringValue("case_editor_font_name", "Menlo");
|
|
||||||
#else
|
|
||||||
mCaseEditorFontName = stringValue("case_editor_font_name","Dejavu Sans Mono");
|
|
||||||
#endif
|
|
||||||
mCaseEditorFontSize = intValue("case_editor_font_size",11);
|
mCaseEditorFontSize = intValue("case_editor_font_size",11);
|
||||||
mCaseEditorFontOnlyMonospaced = boolValue("case_editor_font_only_monospaced",true);
|
mCaseEditorFontOnlyMonospaced = boolValue("case_editor_font_only_monospaced",true);
|
||||||
int case_timeout = intValue("case_timeout", -1);
|
int case_timeout = intValue("case_timeout", -1);
|
||||||
|
|
|
@ -575,6 +575,9 @@ public:
|
||||||
QString AStylePath() const;
|
QString AStylePath() const;
|
||||||
void setAStylePath(const QString &aStylePath);
|
void setAStylePath(const QString &aStylePath);
|
||||||
|
|
||||||
|
TerminalEmulatorArgumentsPattern terminalArgumentsPattern() const;
|
||||||
|
void setTerminalArgumentsPattern(const TerminalEmulatorArgumentsPattern &argsPattern);
|
||||||
|
|
||||||
bool useCustomIconSet() const;
|
bool useCustomIconSet() const;
|
||||||
void setUseCustomIconSet(bool newUseCustomIconSet);
|
void setUseCustomIconSet(bool newUseCustomIconSet);
|
||||||
|
|
||||||
|
@ -606,6 +609,7 @@ public:
|
||||||
QString mDefaultOpenFolder;
|
QString mDefaultOpenFolder;
|
||||||
QString mTerminalPath;
|
QString mTerminalPath;
|
||||||
QString mAStylePath;
|
QString mAStylePath;
|
||||||
|
TerminalEmulatorArgumentsPattern mTerminalArgumentsPattern;
|
||||||
bool mHideNonSupportFilesInFileView;
|
bool mHideNonSupportFilesInFileView;
|
||||||
bool mOpenFilesInSingleInstance;
|
bool mOpenFilesInSingleInstance;
|
||||||
// _Base interface
|
// _Base interface
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "../settings.h"
|
#include "../settings.h"
|
||||||
#include "../iconsmanager.h"
|
#include "../iconsmanager.h"
|
||||||
#include "../systemconsts.h"
|
#include "../systemconsts.h"
|
||||||
|
#include "../compiler/executablerunner.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
@ -27,6 +28,16 @@ EnvironmentProgramsWidget::EnvironmentProgramsWidget(const QString& name, const
|
||||||
ui(new Ui::EnvironmentProgramsWidget)
|
ui(new Ui::EnvironmentProgramsWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
QFont monoFont(DEFAULT_MONO_FONT);
|
||||||
|
ui->rbImplicitSystem->setFont(monoFont);
|
||||||
|
ui->rbMinusEAppendArgs->setFont(monoFont);
|
||||||
|
ui->rbMinusXAppendArgs->setFont(monoFont);
|
||||||
|
ui->rbMinusMinusAppendArgs->setFont(monoFont);
|
||||||
|
ui->rbMinusEAppendCommandLine->setFont(monoFont);
|
||||||
|
ui->rbWriteCommandLineToTempFileThenTempFilename->setFont(monoFont);
|
||||||
|
#ifndef Q_OS_MACOS
|
||||||
|
hideMacosSpecificPattern();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentProgramsWidget::~EnvironmentProgramsWidget()
|
EnvironmentProgramsWidget::~EnvironmentProgramsWidget()
|
||||||
|
@ -34,14 +45,62 @@ EnvironmentProgramsWidget::~EnvironmentProgramsWidget()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::hideMacosSpecificPattern()
|
||||||
|
{
|
||||||
|
ui->rbWriteCommandLineToTempFileThenTempFilename->setVisible(false);
|
||||||
|
ui->rbWriteCommandLineToTempFileThenTempFilename->setEnabled(false);
|
||||||
|
ui->pbWriteCommandLineToTempFileThenTempFilename->setVisible(false);
|
||||||
|
ui->pbWriteCommandLineToTempFileThenTempFilename->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::testTerminal(const TerminalEmulatorArgumentsPattern &pattern)
|
||||||
|
{
|
||||||
|
auto [filename, arguments, fileOwner] = wrapCommandForTerminalEmulator(ui->txtTerminal->text(), pattern, {defaultShell(), "-c", "echo hello; sleep 3"});
|
||||||
|
ExecutableRunner runner(filename, arguments, "", nullptr);
|
||||||
|
runner.start();
|
||||||
|
runner.wait();
|
||||||
|
}
|
||||||
|
|
||||||
void EnvironmentProgramsWidget::doLoad()
|
void EnvironmentProgramsWidget::doLoad()
|
||||||
{
|
{
|
||||||
ui->txtTerminal->setText(pSettings->environment().terminalPath());
|
ui->txtTerminal->setText(pSettings->environment().terminalPath());
|
||||||
|
switch (pSettings->environment().terminalArgumentsPattern()) {
|
||||||
|
case TerminalEmulatorArgumentsPattern::ImplicitSystem:
|
||||||
|
ui->rbImplicitSystem->setChecked(true);
|
||||||
|
break;
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusEAppendArgs:
|
||||||
|
ui->rbMinusEAppendArgs->setChecked(true);
|
||||||
|
break;
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusXAppendArgs:
|
||||||
|
ui->rbMinusXAppendArgs->setChecked(true);
|
||||||
|
break;
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs:
|
||||||
|
ui->rbMinusMinusAppendArgs->setChecked(true);
|
||||||
|
break;
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine:
|
||||||
|
ui->rbMinusEAppendCommandLine->setChecked(true);
|
||||||
|
break;
|
||||||
|
case TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename:
|
||||||
|
ui->rbWriteCommandLineToTempFileThenTempFilename->setChecked(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProgramsWidget::doSave()
|
void EnvironmentProgramsWidget::doSave()
|
||||||
{
|
{
|
||||||
pSettings->environment().setTerminalPath(ui->txtTerminal->text());
|
pSettings->environment().setTerminalPath(ui->txtTerminal->text());
|
||||||
|
if (ui->rbImplicitSystem->isChecked())
|
||||||
|
pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::ImplicitSystem);
|
||||||
|
if (ui->rbMinusEAppendArgs->isChecked())
|
||||||
|
pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusEAppendArgs);
|
||||||
|
if (ui->rbMinusXAppendArgs->isChecked())
|
||||||
|
pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusXAppendArgs);
|
||||||
|
if (ui->rbMinusMinusAppendArgs->isChecked())
|
||||||
|
pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs);
|
||||||
|
if (ui->rbMinusEAppendCommandLine->isChecked())
|
||||||
|
pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine);
|
||||||
|
if (ui->rbWriteCommandLineToTempFileThenTempFilename->isChecked())
|
||||||
|
pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename);
|
||||||
pSettings->environment().save();
|
pSettings->environment().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,3 +120,62 @@ void EnvironmentProgramsWidget::on_btnChooseTerminal_clicked()
|
||||||
ui->txtTerminal->setText(filename);
|
ui->txtTerminal->setText(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_txtTerminal_textChanged(const QString &terminalPath)
|
||||||
|
{
|
||||||
|
QString terminalPathForExec;
|
||||||
|
if (getPathUnixExecSemantics(terminalPath) == UnixExecSemantics::RelativeToCwd) {
|
||||||
|
QDir appDir(pSettings->dirs().appDir());
|
||||||
|
terminalPathForExec = appDir.absoluteFilePath(terminalPath);
|
||||||
|
} else
|
||||||
|
terminalPathForExec = terminalPath;
|
||||||
|
QString terminalPathEscaped = escapeArgument(terminalPathForExec, true);
|
||||||
|
QString shell = defaultShell();
|
||||||
|
QStringList execArgs{shell, "-c", "echo hello; sleep 3"};
|
||||||
|
|
||||||
|
auto displayCommand = [this, &execArgs](const TerminalEmulatorArgumentsPattern &pattern) {
|
||||||
|
auto [filename, arguments, fileOwner] = wrapCommandForTerminalEmulator(ui->txtTerminal->text(), pattern, execArgs);
|
||||||
|
for (auto &arg : arguments)
|
||||||
|
arg = escapeArgument(arg, false);
|
||||||
|
return escapeArgument(filename, true) + " " + arguments.join(' ');
|
||||||
|
};
|
||||||
|
|
||||||
|
ui->rbImplicitSystem->setText(displayCommand(TerminalEmulatorArgumentsPattern::ImplicitSystem));
|
||||||
|
ui->rbMinusEAppendArgs->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusEAppendArgs));
|
||||||
|
ui->rbMinusXAppendArgs->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusXAppendArgs));
|
||||||
|
ui->rbMinusMinusAppendArgs->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs));
|
||||||
|
ui->rbMinusEAppendCommandLine->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine));
|
||||||
|
if (ui->rbWriteCommandLineToTempFileThenTempFilename->isEnabled())
|
||||||
|
ui->rbWriteCommandLineToTempFileThenTempFilename->setText(displayCommand(TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_pbImplicitSystem_clicked()
|
||||||
|
{
|
||||||
|
testTerminal(TerminalEmulatorArgumentsPattern::ImplicitSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_pbMinusEAppendArgs_clicked()
|
||||||
|
{
|
||||||
|
testTerminal(TerminalEmulatorArgumentsPattern::MinusEAppendArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_pbMinusXAppendArgs_clicked()
|
||||||
|
{
|
||||||
|
testTerminal(TerminalEmulatorArgumentsPattern::MinusXAppendArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_pbMinusMinusAppendArgs_clicked()
|
||||||
|
{
|
||||||
|
testTerminal(TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_pbMinusEAppendCommandLine_clicked()
|
||||||
|
{
|
||||||
|
testTerminal(TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::on_pbWriteCommandLineToTempFileThenTempFilename_clicked()
|
||||||
|
{
|
||||||
|
testTerminal(TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define ENVIRONMENTPROGRAMSWIDGET_H
|
#define ENVIRONMENTPROGRAMSWIDGET_H
|
||||||
|
|
||||||
#include "settingswidget.h"
|
#include "settingswidget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class EnvironmentProgramsWidget;
|
class EnvironmentProgramsWidget;
|
||||||
|
@ -30,6 +31,10 @@ class EnvironmentProgramsWidget : public SettingsWidget
|
||||||
public:
|
public:
|
||||||
explicit EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent = nullptr);
|
explicit EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent = nullptr);
|
||||||
~EnvironmentProgramsWidget();
|
~EnvironmentProgramsWidget();
|
||||||
|
void hideMacosSpecificPattern();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void testTerminal(const TerminalEmulatorArgumentsPattern &pattern);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::EnvironmentProgramsWidget *ui;
|
Ui::EnvironmentProgramsWidget *ui;
|
||||||
|
@ -41,6 +46,13 @@ protected:
|
||||||
void updateIcons(const QSize &size) override;
|
void updateIcons(const QSize &size) override;
|
||||||
private slots:
|
private slots:
|
||||||
void on_btnChooseTerminal_clicked();
|
void on_btnChooseTerminal_clicked();
|
||||||
|
void on_txtTerminal_textChanged(const QString &terminalPath);
|
||||||
|
void on_pbImplicitSystem_clicked();
|
||||||
|
void on_pbMinusEAppendArgs_clicked();
|
||||||
|
void on_pbMinusXAppendArgs_clicked();
|
||||||
|
void on_pbMinusMinusAppendArgs_clicked();
|
||||||
|
void on_pbMinusEAppendCommandLine_clicked();
|
||||||
|
void on_pbWriteCommandLineToTempFileThenTempFilename_clicked();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENVIRONMENTPROGRAMSWIDGET_H
|
#endif // ENVIRONMENTPROGRAMSWIDGET_H
|
||||||
|
|
|
@ -35,7 +35,141 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="0" colspan="3">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Terminal emulator arguments pattern</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbImplicitSystem">
|
||||||
|
<property name="text">
|
||||||
|
<string>sh -c "echo hello; sleep 3"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QPushButton" name="pbImplicitSystem">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbMinusEAppendArgs">
|
||||||
|
<property name="text">
|
||||||
|
<string>term -e sh -c "echo hello; sleep 3"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QPushButton" name="pbMinusEAppendArgs">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbMinusXAppendArgs">
|
||||||
|
<property name="text">
|
||||||
|
<string>term -x sh -c "echo hello; sleep 3"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QPushButton" name="pbMinusXAppendArgs">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbMinusMinusAppendArgs">
|
||||||
|
<property name="text">
|
||||||
|
<string>term -- sh -c "echo hello; sleep 3"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QPushButton" name="pbMinusMinusAppendArgs">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbMinusEAppendCommandLine">
|
||||||
|
<property name="text">
|
||||||
|
<string>term -e "sh -c \"echo hello; sleep 3\""</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QPushButton" name="pbMinusEAppendCommandLine">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbWriteCommandLineToTempFileThenTempFilename">
|
||||||
|
<property name="text">
|
||||||
|
<string>term /tmp/redpanda_XXXXXX.command</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="2">
|
||||||
|
<widget class="QPushButton" name="pbWriteCommandLineToTempFileThenTempFilename">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="lExpectedBahavior0">
|
||||||
|
<property name="text">
|
||||||
|
<string>On clicking “Test” for the correct pattern, the terminal emulator</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="lExpectedBahavior1">
|
||||||
|
<property name="text">
|
||||||
|
<string>• pops up;</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="lExpectedBahavior2">
|
||||||
|
<property name="text">
|
||||||
|
<string>• shows “hello”; and</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="lExpectedBahavior3">
|
||||||
|
<property name="text">
|
||||||
|
<string>• quits in 3 seconds.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
|
|
|
@ -21,12 +21,15 @@
|
||||||
#include "../systemconsts.h"
|
#include "../systemconsts.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
ExecutorGeneralWidget::ExecutorGeneralWidget(const QString& name, const QString& group, QWidget *parent):
|
ExecutorGeneralWidget::ExecutorGeneralWidget(const QString& name, const QString& group, QWidget *parent):
|
||||||
SettingsWidget(name,group,parent),
|
SettingsWidget(name,group,parent),
|
||||||
ui(new Ui::ExecutorGeneralWidget)
|
ui(new Ui::ExecutorGeneralWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
ui->txtParsedArgsInJson->setFont(QFont(DEFAULT_MONO_FONT));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutorGeneralWidget::~ExecutorGeneralWidget()
|
ExecutorGeneralWidget::~ExecutorGeneralWidget()
|
||||||
|
@ -73,3 +76,11 @@ void ExecutorGeneralWidget::updateIcons(const QSize &/*size*/)
|
||||||
pIconsManager->setIcon(ui->btnBrowse,IconsManager::ACTION_FILE_OPEN_FOLDER);
|
pIconsManager->setIcon(ui->btnBrowse,IconsManager::ACTION_FILE_OPEN_FOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExecutorGeneralWidget::on_txtExecuteParamaters_textChanged(const QString &commandLine)
|
||||||
|
{
|
||||||
|
QStringList parsed = splitProcessCommand(commandLine);
|
||||||
|
QJsonArray obj = QJsonArray::fromStringList(parsed);
|
||||||
|
ui->txtParsedArgsInJson->setText(QJsonDocument{obj}.toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@ private slots:
|
||||||
void on_btnBrowse_clicked();
|
void on_btnBrowse_clicked();
|
||||||
|
|
||||||
// SettingsWidget interface
|
// SettingsWidget interface
|
||||||
|
void on_txtExecuteParamaters_textChanged(const QString &commandLine);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateIcons(const QSize &size) override;
|
void updateIcons(const QSize &size) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,10 +55,21 @@
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="txtExecuteParamaters"/>
|
<widget class="QLineEdit" name="txtExecuteParamaters"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelParseArgsInJson">
|
||||||
|
<property name="text">
|
||||||
|
<string>Parsed argv array (represented in JSON):</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="txtParsedArgsInJson">
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -75,7 +86,6 @@
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
|
@ -88,7 +98,6 @@
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
|
@ -101,7 +110,6 @@
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "environmentshortcutwidget.h"
|
#include "environmentshortcutwidget.h"
|
||||||
#include "environmentfolderswidget.h"
|
#include "environmentfolderswidget.h"
|
||||||
#include "environmentperformancewidget.h"
|
#include "environmentperformancewidget.h"
|
||||||
|
#include "environmentprogramswidget.h"
|
||||||
#include "executorgeneralwidget.h"
|
#include "executorgeneralwidget.h"
|
||||||
#include "executorproblemsetwidget.h"
|
#include "executorproblemsetwidget.h"
|
||||||
#include "debuggeneralwidget.h"
|
#include "debuggeneralwidget.h"
|
||||||
|
@ -58,8 +59,7 @@
|
||||||
#include "environmentfileassociationwidget.h"
|
#include "environmentfileassociationwidget.h"
|
||||||
#include "projectversioninfowidget.h"
|
#include "projectversioninfowidget.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_LINUX
|
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) // XDG desktop
|
||||||
#include "environmentprogramswidget.h"
|
|
||||||
#include "formatterpathwidget.h"
|
#include "formatterpathwidget.h"
|
||||||
#endif
|
#endif
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -156,10 +156,8 @@ PSettingsDialog SettingsDialog::optionDialog()
|
||||||
widget = new EnvironmentShortcutWidget(tr("Shortcuts"),tr("Environment"));
|
widget = new EnvironmentShortcutWidget(tr("Shortcuts"),tr("Environment"));
|
||||||
dialog->addWidget(widget);
|
dialog->addWidget(widget);
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
widget = new EnvironmentProgramsWidget(tr("Terminal"),tr("Environment"));
|
widget = new EnvironmentProgramsWidget(tr("Terminal"),tr("Environment"));
|
||||||
dialog->addWidget(widget);
|
dialog->addWidget(widget);
|
||||||
#endif
|
|
||||||
|
|
||||||
widget = new EnvironmentPerformanceWidget(tr("Performance"),tr("Environment"));
|
widget = new EnvironmentPerformanceWidget(tr("Performance"),tr("Environment"));
|
||||||
dialog->addWidget(widget);
|
dialog->addWidget(widget);
|
||||||
|
@ -230,7 +228,7 @@ PSettingsDialog SettingsDialog::optionDialog()
|
||||||
widget = new FormatterGeneralWidget(tr("General"),tr("Code Formatter"));
|
widget = new FormatterGeneralWidget(tr("General"),tr("Code Formatter"));
|
||||||
dialog->addWidget(widget);
|
dialog->addWidget(widget);
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) // XDG desktop
|
||||||
widget = new FormatterPathWidget(tr("Program"),tr("Code Formatter"));
|
widget = new FormatterPathWidget(tr("Program"),tr("Code Formatter"));
|
||||||
dialog->addWidget(widget);
|
dialog->addWidget(widget);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#define APP_SETTSINGS_FILENAME "redpandacpp.ini"
|
#define APP_SETTSINGS_FILENAME "redpandacpp.ini"
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#define CONSOLE_PAUSER "consolepauser.exe"
|
#define CONSOLE_PAUSER "consolepauser.exe"
|
||||||
#define ASSEMBLER "nasm.exe"
|
|
||||||
#define GCC_PROGRAM "gcc.exe"
|
#define GCC_PROGRAM "gcc.exe"
|
||||||
#define GPP_PROGRAM "g++.exe"
|
#define GPP_PROGRAM "g++.exe"
|
||||||
#define GDB_PROGRAM "gdb.exe"
|
#define GDB_PROGRAM "gdb.exe"
|
||||||
|
@ -40,9 +39,8 @@
|
||||||
#define SDCC_PROGRAM "sdcc.exe"
|
#define SDCC_PROGRAM "sdcc.exe"
|
||||||
#define PACKIHX_PROGRAM "packihx.exe"
|
#define PACKIHX_PROGRAM "packihx.exe"
|
||||||
#define MAKEBIN_PROGRAM "makebin.exe"
|
#define MAKEBIN_PROGRAM "makebin.exe"
|
||||||
#elif defined(Q_OS_LINUX)
|
#else // Unix
|
||||||
#define CONSOLE_PAUSER "consolepauser"
|
#define CONSOLE_PAUSER "consolepauser"
|
||||||
#define ASSEMBLER "nasm"
|
|
||||||
#define GCC_PROGRAM "gcc"
|
#define GCC_PROGRAM "gcc"
|
||||||
#define GPP_PROGRAM "g++"
|
#define GPP_PROGRAM "g++"
|
||||||
#define GDB_PROGRAM "gdb"
|
#define GDB_PROGRAM "gdb"
|
||||||
|
@ -61,28 +59,6 @@
|
||||||
#define SDCC_PROGRAM "sdcc"
|
#define SDCC_PROGRAM "sdcc"
|
||||||
#define PACKIHX_PROGRAM "packihx"
|
#define PACKIHX_PROGRAM "packihx"
|
||||||
#define MAKEBIN_PROGRAM "makebin"
|
#define MAKEBIN_PROGRAM "makebin"
|
||||||
#elif defined(Q_OS_MACOS)
|
|
||||||
#define CONSOLE_PAUSER "consolepauser"
|
|
||||||
#define ASSEMBLER "nasm"
|
|
||||||
#define GCC_PROGRAM "gcc"
|
|
||||||
#define GPP_PROGRAM "g++"
|
|
||||||
#define GDB_PROGRAM "gdb"
|
|
||||||
#define GDB_SERVER_PROGRAM "gdbserver"
|
|
||||||
#define GDB32_PROGRAM "gdb32"
|
|
||||||
#define MAKE_PROGRAM "make"
|
|
||||||
#define WINDRES_PROGRAM ""
|
|
||||||
#define CLEAN_PROGRAM "rm -rf"
|
|
||||||
#define CPP_PROGRAM "cpp"
|
|
||||||
#define GIT_PROGRAM "git"
|
|
||||||
#define CLANG_PROGRAM "clang"
|
|
||||||
#define CLANG_CPP_PROGRAM "clang++"
|
|
||||||
#define LLDB_MI_PROGRAM "lldb-mi"
|
|
||||||
#define LLDB_SERVER_PROGRAM "lldb-server"
|
|
||||||
#define SDCC_PROGRAM "sdcc"
|
|
||||||
#define PACKIHX_PROGRAM "packihx"
|
|
||||||
#define MAKEBIN_PROGRAM "makebin"
|
|
||||||
#else
|
|
||||||
#error "Only support windows, Linux and MacOS now!"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEV_PROJECT_EXT "dev"
|
#define DEV_PROJECT_EXT "dev"
|
||||||
|
@ -128,7 +104,7 @@
|
||||||
# define MAKEFILE_NAME "makefile.win"
|
# define MAKEFILE_NAME "makefile.win"
|
||||||
# define XMAKEFILE_NAME "xmake.lua"
|
# define XMAKEFILE_NAME "xmake.lua"
|
||||||
# define ALL_FILE_WILDCARD "*.*"
|
# define ALL_FILE_WILDCARD "*.*"
|
||||||
#elif defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
#else // Unix
|
||||||
# define PATH_SENSITIVITY Qt::CaseSensitive
|
# define PATH_SENSITIVITY Qt::CaseSensitive
|
||||||
# define PATH_SEPARATOR ":"
|
# define PATH_SEPARATOR ":"
|
||||||
# define LINE_BREAKER "\n"
|
# define LINE_BREAKER "\n"
|
||||||
|
@ -142,8 +118,6 @@
|
||||||
# define MAKEFILE_NAME "makefile"
|
# define MAKEFILE_NAME "makefile"
|
||||||
# define XMAKEFILE_NAME "xmake.lua"
|
# define XMAKEFILE_NAME "xmake.lua"
|
||||||
# define ALL_FILE_WILDCARD "*"
|
# define ALL_FILE_WILDCARD "*"
|
||||||
#else
|
|
||||||
#error "Only support windows, linux and macos now!"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SDCC_IHX_SUFFIX "ihx"
|
#define SDCC_IHX_SUFFIX "ihx"
|
||||||
|
@ -151,6 +125,40 @@
|
||||||
#define SDCC_HEX_SUFFIX "hex"
|
#define SDCC_HEX_SUFFIX "hex"
|
||||||
#define SDCC_REL_SUFFIX "rel"
|
#define SDCC_REL_SUFFIX "rel"
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
# define DEFAULT_UI_FONT "Segoe UI"
|
||||||
|
# define CJK_UI_FONT_SC "Microsoft YaHei UI"
|
||||||
|
# define CJK_UI_FONT_TC "Microsoft JhengHei UI"
|
||||||
|
# define CJK_UI_FONT_J "Yu Gothic UI"
|
||||||
|
# define CJK_UI_FONT_K "Malgun Gothic"
|
||||||
|
# define DEFAULT_MONO_FONT "Consolas"
|
||||||
|
# define CJK_MONO_FONT_SC "Microsoft YaHei"
|
||||||
|
# define CJK_MONO_FONT_TC "Microsoft JhengHei"
|
||||||
|
# define CJK_MONO_FONT_J "Yu Gothic"
|
||||||
|
# define CJK_MONO_FONT_K "Malgun Gothic"
|
||||||
|
#elif defined(Q_OS_MACOS)
|
||||||
|
# define DEFAULT_UI_FONT "Helvetica Neue"
|
||||||
|
# define CJK_UI_FONT_SC "PingFang SC"
|
||||||
|
# define CJK_UI_FONT_TC "PingFang TC"
|
||||||
|
# define CJK_UI_FONT_J "Hiragino Sans"
|
||||||
|
# define CJK_UI_FONT_K "Apple SD Gothic Neo"
|
||||||
|
# define DEFAULT_MONO_FONT "Menlo"
|
||||||
|
# define CJK_MONO_FONT_SC CJK_UI_FONT_SC
|
||||||
|
# define CJK_MONO_FONT_TC CJK_UI_FONT_TC
|
||||||
|
# define CJK_MONO_FONT_J CJK_UI_FONT_J
|
||||||
|
# define CJK_MONO_FONT_K CJK_UI_FONT_K
|
||||||
|
#else // XDG desktop
|
||||||
|
# define DEFAULT_UI_FONT "Sans" // use fontconfig default
|
||||||
|
# define CJK_UI_FONT_SC "Noto Sans CJK SC"
|
||||||
|
# define CJK_UI_FONT_TC "Noto Sans CJK TC"
|
||||||
|
# define CJK_UI_FONT_J "Noto Sans CJK JP"
|
||||||
|
# define CJK_UI_FONT_K "Noto Sans CJK KR"
|
||||||
|
# define DEFAULT_MONO_FONT "Monospace" // use fontconfig default
|
||||||
|
# define CJK_MONO_FONT_SC CJK_UI_FONT_SC // intentionally: the "Mono" version is not stricly monospaced either, and has less weights
|
||||||
|
# define CJK_MONO_FONT_TC CJK_UI_FONT_TC
|
||||||
|
# define CJK_MONO_FONT_J CJK_UI_FONT_J
|
||||||
|
# define CJK_MONO_FONT_K CJK_UI_FONT_K
|
||||||
|
#endif
|
||||||
|
|
||||||
class SystemConsts
|
class SystemConsts
|
||||||
{
|
{
|
||||||
|
|
|
@ -1958,6 +1958,54 @@
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation>Todos os arquivos (%1)</translation>
|
<translation>Todos os arquivos (%1)</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Terminal emulator arguments pattern</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Test</source>
|
||||||
|
<translation type="unfinished">Testar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -e sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -x sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -- sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -e "sh -c \"echo hello; sleep 3\""</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>On clicking “Test” for the correct pattern, the terminal emulator</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>• pops up;</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>• shows “hello”; and</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>• quits in 3 seconds.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term /tmp/redpanda_XXXXXX.command</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EnvironmentShortcutModel</name>
|
<name>EnvironmentShortcutModel</name>
|
||||||
|
@ -2058,6 +2106,10 @@
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation>Todos os arquivos (%1)</translation>
|
<translation>Todos os arquivos (%1)</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Parsed argv array (represented in JSON):</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ExecutorProblemSetWidget</name>
|
<name>ExecutorProblemSetWidget</name>
|
||||||
|
|
|
@ -2689,7 +2689,72 @@ Are you really want to continue?</oldsource>
|
||||||
<translation>终端</translation>
|
<translation>终端</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="57"/>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="41"/>
|
||||||
|
<source>Terminal emulator arguments pattern</source>
|
||||||
|
<translation>终端模拟器参数模式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="54"/>
|
||||||
|
<source>sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="74"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="95"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="116"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="137"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="158"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="179"/>
|
||||||
|
<source>Test</source>
|
||||||
|
<translation>测试</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="88"/>
|
||||||
|
<source>term -e sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="109"/>
|
||||||
|
<source>term -x sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="130"/>
|
||||||
|
<source>term -- sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="151"/>
|
||||||
|
<source>term -e "sh -c \"echo hello; sleep 3\""</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="172"/>
|
||||||
|
<source>term /tmp/redpanda_XXXXXX.command</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="186"/>
|
||||||
|
<source>On clicking “Test” for the correct pattern, the terminal emulator</source>
|
||||||
|
<translation>点击正确的模式对应的 “测试” 按钮,终端模拟器将会</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="193"/>
|
||||||
|
<source>• pops up;</source>
|
||||||
|
<translation>• 弹出;</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="200"/>
|
||||||
|
<source>• shows “hello”; and</source>
|
||||||
|
<translation>• 显示 “hello”;</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="207"/>
|
||||||
|
<source>• quits in 3 seconds.</source>
|
||||||
|
<translation>• 并在 3 秒后关闭。</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="109"/>
|
||||||
<source>Choose Terminal Program</source>
|
<source>Choose Terminal Program</source>
|
||||||
<translation>选择终端程序</translation>
|
<translation>选择终端程序</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -2798,6 +2863,11 @@ Are you really want to continue?</oldsource>
|
||||||
<source>Parameters to pass to your program</source>
|
<source>Parameters to pass to your program</source>
|
||||||
<translation>运行程序的命令行参数</translation>
|
<translation>运行程序的命令行参数</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/executorgeneralwidget.ui" line="65"/>
|
||||||
|
<source>Parsed argv array (represented in JSON):</source>
|
||||||
|
<translation>argv 数组解析结果(以 JSON 表示):</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/executorgeneralwidget.ui" line="68"/>
|
<location filename="../settingsdialog/executorgeneralwidget.ui" line="68"/>
|
||||||
<source>Redirect input to the following file:</source>
|
<source>Redirect input to the following file:</source>
|
||||||
|
|
|
@ -1791,6 +1791,54 @@
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Terminal emulator arguments pattern</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Test</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -e sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -x sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -- sh -c "echo hello; sleep 3"</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term -e "sh -c \"echo hello; sleep 3\""</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>On clicking “Test” for the correct pattern, the terminal emulator</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>• pops up;</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>• shows “hello”; and</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>• quits in 3 seconds.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>term /tmp/redpanda_XXXXXX.command</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EnvironmentShortcutModel</name>
|
<name>EnvironmentShortcutModel</name>
|
||||||
|
@ -1891,6 +1939,10 @@
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Parsed argv array (represented in JSON):</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ExecutorProblemSetWidget</name>
|
<name>ExecutorProblemSetWidget</name>
|
||||||
|
|
|
@ -447,7 +447,7 @@ void executeFile(const QString &fileName, const QString ¶ms, const QString &
|
||||||
{
|
{
|
||||||
ExecutableRunner* runner=new ExecutableRunner(
|
ExecutableRunner* runner=new ExecutableRunner(
|
||||||
fileName,
|
fileName,
|
||||||
params,
|
splitProcessCommand(params),
|
||||||
workingDir);
|
workingDir);
|
||||||
runner->connect(runner, &QThread::finished,
|
runner->connect(runner, &QThread::finished,
|
||||||
[runner,tempFile](){
|
[runner,tempFile](){
|
||||||
|
@ -589,3 +589,190 @@ QColor alphaBlend(const QColor &lower, const QColor &upper) {
|
||||||
int(lower.blue() * wl + upper.blue() * wu)
|
int(lower.blue() * wl + upper.blue() * wu)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnixExecSemantics getPathUnixExecSemantics(const QString &path)
|
||||||
|
{
|
||||||
|
QFileInfo pathInfo(path);
|
||||||
|
if (pathInfo.isRelative()) {
|
||||||
|
if (path.contains('/'))
|
||||||
|
return UnixExecSemantics::RelativeToCwd;
|
||||||
|
else
|
||||||
|
return UnixExecSemantics::SearchInPath;
|
||||||
|
} else
|
||||||
|
return UnixExecSemantics::Absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList getExecutableSearchPaths()
|
||||||
|
{
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
QString path = env.value("PATH");
|
||||||
|
QStringList pathList = path.split(PATH_SEPARATOR);
|
||||||
|
return pathList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString escapeArgument(const QString &arg, [[maybe_unused]] bool isFirstArg)
|
||||||
|
{
|
||||||
|
auto argContainsOneOf = [&arg](auto... ch) { return (arg.contains(ch) || ...); };
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
// See https://stackoverflow.com/questions/31838469/how-do-i-convert-argv-to-lpcommandline-parameter-of-createprocess ,
|
||||||
|
// and https://learn.microsoft.com/en-gb/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way .
|
||||||
|
|
||||||
|
// TODO: investigate whether we need escaping for cmd.
|
||||||
|
|
||||||
|
if (!arg.isEmpty() && !argContainsOneOf(' ', '\t', '\n', '\v', '"'))
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
QString result = "\"";
|
||||||
|
for (auto it = arg.begin(); ; ++it) {
|
||||||
|
int nBackslash = 0;
|
||||||
|
while (it != arg.end() && *it == '\\') {
|
||||||
|
++it;
|
||||||
|
++nBackslash;
|
||||||
|
}
|
||||||
|
if (it == arg.end()) {
|
||||||
|
// Escape all backslashes, but let the terminating double quotation mark we add below be interpreted as a metacharacter.
|
||||||
|
result.append(QString('\\').repeated(nBackslash * 2));
|
||||||
|
break;
|
||||||
|
} else if (*it == '"') {
|
||||||
|
// Escape all backslashes and the following double quotation mark.
|
||||||
|
result.append(QString('\\').repeated(nBackslash * 2 + 1));
|
||||||
|
result.push_back(*it);
|
||||||
|
} else {
|
||||||
|
// Backslashes aren't special here.
|
||||||
|
result.append(QString('\\').repeated(nBackslash));
|
||||||
|
result.push_back(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push_back('"');
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
/* be speculative, but keep readability.
|
||||||
|
* ref. https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html
|
||||||
|
*/
|
||||||
|
if (arg.isEmpty())
|
||||||
|
return R"("")";
|
||||||
|
|
||||||
|
/* POSIX say the following reserved words (may) have special meaning:
|
||||||
|
* !, {, }, case, do, done, elif, else, esac, fi, for, if, in, then, until, while,
|
||||||
|
* [[, ]], function, select,
|
||||||
|
* only if used as the _first word_ of a command (or somewhere we dot not care).
|
||||||
|
*/
|
||||||
|
const static QSet<QString> reservedWord{
|
||||||
|
"!", "{", "}", "case", "do", "done", "elif", "else", "esac", "fi", "for", "if", "in", "then", "until", "while",
|
||||||
|
"[[", "]]", "function", "select",
|
||||||
|
};
|
||||||
|
if (isFirstArg && reservedWord.contains(arg))
|
||||||
|
return QString(R"("%1")").arg(arg);
|
||||||
|
|
||||||
|
/* POSIX say “shall quote”:
|
||||||
|
* '|', '&', ';', '<', '>', '(', ')', '$', '`', '\\', '"', '\'', ' ', '\t', '\n';
|
||||||
|
* and “may need to be quoted”:
|
||||||
|
* '*', '?', '[', '#', '~', '=', '%'.
|
||||||
|
* among which “may need to be quoted” there are 4 kinds:
|
||||||
|
* - wildcards '*', '?', '[' are “danger anywhere” (handle it as if “shall quote”);
|
||||||
|
* - comment '#', home '~', is “danger at first char in any word”;
|
||||||
|
* - (environment) variable '=' is “danger at any char in first word”;
|
||||||
|
* - foreground '%' is “danger at first char in first word”.
|
||||||
|
* although not mentioned by POSIX, bash’s brace expansion '{', '}' are also “danger anywhere”.
|
||||||
|
*/
|
||||||
|
bool isDoubleQuotingDanger = argContainsOneOf('$', '`', '\\', '"');
|
||||||
|
bool isSingleQuotingDanger = arg.contains('\'');
|
||||||
|
bool isDangerAnyChar = isDoubleQuotingDanger || isSingleQuotingDanger || argContainsOneOf(
|
||||||
|
'|', '&', ';', '<', '>', '(', ')', ' ', '\t', '\n',
|
||||||
|
'*', '?', '[',
|
||||||
|
'{', '}'
|
||||||
|
);
|
||||||
|
bool isDangerFirstChar = (arg[0] == '#') || (arg[0] == '~');
|
||||||
|
if (isFirstArg) {
|
||||||
|
isDangerAnyChar = isDangerAnyChar || arg.contains('=');
|
||||||
|
isDangerFirstChar = isDangerFirstChar || (arg[0] == '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
// a “safe” string
|
||||||
|
if (!isDangerAnyChar && !isDangerFirstChar)
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
// prefer more-common double quoting
|
||||||
|
if (!isDoubleQuotingDanger)
|
||||||
|
return QString(R"("%1")").arg(arg);
|
||||||
|
|
||||||
|
// and then check the opportunity of single quoting
|
||||||
|
if (!isSingleQuotingDanger)
|
||||||
|
return QString("'%1'").arg(arg);
|
||||||
|
|
||||||
|
// escaping is necessary
|
||||||
|
// use double quoting since it’s less tricky
|
||||||
|
QString result = "\"";
|
||||||
|
for (auto ch : arg) {
|
||||||
|
if (ch == '$' || ch == '`' || ch == '\\' || ch == '"')
|
||||||
|
result.push_back('\\');
|
||||||
|
result.push_back(ch);
|
||||||
|
}
|
||||||
|
result.push_back('"');
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* single quoting, which is roughly raw string, is possible and quite simple in programming:
|
||||||
|
* 1. replace each single quote with `'\''`, which contains
|
||||||
|
* - a single quote to close quoting,
|
||||||
|
* - an escaped single quote representing the single quote itself, and
|
||||||
|
* - a single quote to open quoting again;
|
||||||
|
* 2. enclose the string with a pair of single quotes.
|
||||||
|
* e.g. `o'clock` => `'o'\''clock'`, really tricky and hard to read.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
auto wrapCommandForTerminalEmulator(const QString &terminal, const TerminalEmulatorArgumentsPattern &argsPattern, const QStringList &argsWithArgv0)
|
||||||
|
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>
|
||||||
|
{
|
||||||
|
switch (argsPattern) {
|
||||||
|
case TerminalEmulatorArgumentsPattern::ImplicitSystem:
|
||||||
|
default: {
|
||||||
|
return {argsWithArgv0[0], argsWithArgv0.mid(1), nullptr};
|
||||||
|
}
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusEAppendArgs: {
|
||||||
|
return {terminal, QStringList{"-e"} + argsWithArgv0, nullptr};
|
||||||
|
}
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusXAppendArgs: {
|
||||||
|
return {terminal, QStringList{"-x"} + argsWithArgv0, nullptr};
|
||||||
|
}
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs: {
|
||||||
|
return {terminal, QStringList{"--"} + argsWithArgv0, nullptr};
|
||||||
|
}
|
||||||
|
case TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine: {
|
||||||
|
QStringList escapedArgs;
|
||||||
|
for (int i = 0; i < argsWithArgv0.length(); i++) {
|
||||||
|
auto &arg = argsWithArgv0[i];
|
||||||
|
auto escaped = escapeArgument(arg, i == 0);
|
||||||
|
escapedArgs.append(escaped);
|
||||||
|
}
|
||||||
|
return {terminal, QStringList{"-e", escapedArgs.join(' ')}, nullptr};
|
||||||
|
}
|
||||||
|
case TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename: {
|
||||||
|
auto fileOwner = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.command");
|
||||||
|
if (fileOwner->open()) {
|
||||||
|
QStringList escapedArgs;
|
||||||
|
for (int i = 0; i < argsWithArgv0.length(); i++) {
|
||||||
|
auto &arg = argsWithArgv0[i];
|
||||||
|
auto escaped = escapeArgument(arg, i == 0);
|
||||||
|
escapedArgs.append(escaped);
|
||||||
|
}
|
||||||
|
fileOwner->write(escapedArgs.join(' ').toUtf8());
|
||||||
|
fileOwner->write(QString('\n').toUtf8());
|
||||||
|
fileOwner->flush();
|
||||||
|
}
|
||||||
|
QFile(fileOwner->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||||
|
return {terminal, QStringList{fileOwner->fileName()}, std::move(fileOwner)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString defaultShell()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
return "powershell.exe";
|
||||||
|
#else
|
||||||
|
return "sh";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
|
#include <QTemporaryFile>
|
||||||
#define SI_NO_CONVERSION
|
#define SI_NO_CONVERSION
|
||||||
#include "SimpleIni.h"
|
#include "SimpleIni.h"
|
||||||
#include "qt_utils/utils.h"
|
#include "qt_utils/utils.h"
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
|
|
||||||
using SimpleIni = CSimpleIniA;
|
using SimpleIni = CSimpleIniA;
|
||||||
using PSimpleIni = std::shared_ptr<SimpleIni>;
|
using PSimpleIni = std::shared_ptr<SimpleIni>;
|
||||||
|
using TemporaryFileOwner = std::unique_ptr<QTemporaryFile>;
|
||||||
|
|
||||||
enum class FileType{
|
enum class FileType{
|
||||||
GAS, // GNU assembler source file (.s)
|
GAS, // GNU assembler source file (.s)
|
||||||
|
@ -113,6 +115,22 @@ enum class ProblemCaseValidateType {
|
||||||
IgnoreSpaces
|
IgnoreSpaces
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class UnixExecSemantics {
|
||||||
|
Absolute,
|
||||||
|
RelativeToCwd,
|
||||||
|
SearchInPath,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TerminalEmulatorArgumentsPattern {
|
||||||
|
ImplicitSystem = 0, // bash -c "echo hello, world; sleep 3"
|
||||||
|
MinusEAppendArgs, // term -e bash -c "echo hello, world; sleep 3" # xterm-compatible
|
||||||
|
MinusXAppendArgs, // term -x bash -c "echo hello, world; sleep 3" # some VTE-based
|
||||||
|
MinusMinusAppendArgs, // term -- bash -c "echo hello, world; sleep 3" # gnome-terminal, kgx
|
||||||
|
MinusEAppendCommandLine, // term -e "bash -c \"echo hello, world; sleep 3\"" # some lightweighted; alternative form for VTE-based
|
||||||
|
|
||||||
|
WriteCommandLineToTempFileThenTempFilename = 6226700, // macOS Terminal.app and iTerm2.app; 6226700 is how you dial “macOS00”
|
||||||
|
};
|
||||||
|
|
||||||
FileType getFileType(const QString& filename);
|
FileType getFileType(const QString& filename);
|
||||||
QStringList splitProcessCommand(const QString& cmd);
|
QStringList splitProcessCommand(const QString& cmd);
|
||||||
|
|
||||||
|
@ -165,4 +183,15 @@ void saveComboHistory(QComboBox* cb,const QString& text);
|
||||||
|
|
||||||
QColor alphaBlend(const QColor &lower, const QColor &upper);
|
QColor alphaBlend(const QColor &lower, const QColor &upper);
|
||||||
|
|
||||||
|
UnixExecSemantics getPathUnixExecSemantics(const QString &path);
|
||||||
|
|
||||||
|
QStringList getExecutableSearchPaths();
|
||||||
|
|
||||||
|
QString escapeArgument(const QString &arg, bool isFirstArg);
|
||||||
|
|
||||||
|
auto wrapCommandForTerminalEmulator(const QString &terminal, const TerminalEmulatorArgumentsPattern &argsPattern, const QStringList &argsWithArgv0)
|
||||||
|
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>;
|
||||||
|
|
||||||
|
QString defaultShell();
|
||||||
|
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
|
|
@ -25,7 +25,7 @@ void GitManager::createRepository(const QString &folder)
|
||||||
contents.append("*.o");
|
contents.append("*.o");
|
||||||
contents.append("*.exe");
|
contents.append("*.exe");
|
||||||
contents.append("*.layout");
|
contents.append("*.layout");
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_UNIX
|
||||||
contents.append("*.");
|
contents.append("*.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ QString GitManager::runGit(const QString& workingFolder, const QStringList &args
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
env.insert("PATH",pSettings->dirs().appDir());
|
env.insert("PATH",pSettings->dirs().appDir());
|
||||||
env.insert("GIT_ASKPASS",includeTrailingPathDelimiter(pSettings->dirs().appDir())+"redpanda-win-git-askpass.exe");
|
env.insert("GIT_ASKPASS",includeTrailingPathDelimiter(pSettings->dirs().appDir())+"redpanda-win-git-askpass.exe");
|
||||||
#elif defined(Q_OS_LINUX)
|
#else // Unix
|
||||||
env.insert(QProcessEnvironment::systemEnvironment());
|
env.insert(QProcessEnvironment::systemEnvironment());
|
||||||
env.insert("LANG","en");
|
env.insert("LANG","en");
|
||||||
env.insert("LANGUAGE","en");
|
env.insert("LANGUAGE","en");
|
||||||
|
|
|
@ -56,15 +56,7 @@ QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent),
|
||||||
mPaintLock = 0;
|
mPaintLock = 0;
|
||||||
mPainterLock = 0;
|
mPainterLock = 0;
|
||||||
mPainting = false;
|
mPainting = false;
|
||||||
#ifdef Q_OS_WIN
|
mFontDummy = QFont("monospace",14);
|
||||||
mFontDummy = QFont("Consolas",12);
|
|
||||||
#elif defined(Q_OS_LINUX)
|
|
||||||
mFontDummy = QFont("terminal",14);
|
|
||||||
#elif defined(Q_OS_MACOS)
|
|
||||||
mFontDummy = QFont("Menlo", 14);
|
|
||||||
#else
|
|
||||||
#error "Not supported!"
|
|
||||||
#endif
|
|
||||||
mFontDummy.setStyleStrategy(QFont::PreferAntialias);
|
mFontDummy.setStyleStrategy(QFont::PreferAntialias);
|
||||||
mDocument = std::make_shared<Document>(mFontDummy, mFontDummy, this);
|
mDocument = std::make_shared<Document>(mFontDummy, mFontDummy, this);
|
||||||
//fPlugins := TList.Create;
|
//fPlugins := TList.Create;
|
||||||
|
|
|
@ -108,7 +108,7 @@ const QSet<QString> ASMSyntaxer::ATTDirectives {
|
||||||
".seh_setframe",".seh_stackalloc",".seh_pushreg",
|
".seh_setframe",".seh_stackalloc",".seh_pushreg",
|
||||||
".seh_savereg",".seh_savemm",".seh_savexmm",
|
".seh_savereg",".seh_savemm",".seh_savexmm",
|
||||||
".seh_pushframe",".seh_scope",
|
".seh_pushframe",".seh_scope",
|
||||||
#elif defined(Q_OS_LINUX)
|
#else // Unix
|
||||||
".cfi_sections",".cfi_startproc",".cfi_endproc",
|
".cfi_sections",".cfi_startproc",".cfi_endproc",
|
||||||
".cfi_personality",".cfi_personality_id",".cfi_fde_data",
|
".cfi_personality",".cfi_personality_id",".cfi_fde_data",
|
||||||
".cfi_lsda",".cfi_inline_lsda",".cfi_def_cfa",
|
".cfi_lsda",".cfi_inline_lsda",".cfi_def_cfa",
|
||||||
|
|
|
@ -22,6 +22,7 @@ using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -184,15 +185,11 @@ int main(int argc, char** argv) {
|
||||||
//todo: handle error
|
//todo: handle error
|
||||||
printf("shm open failed %d:%s\n",errno,strerror(errno));
|
printf("shm open failed %d:%s\n",errno,strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
if (ftruncate(fd_shm,BUF_SIZE)==-1){
|
// `ftruncate` has already done in RedPandaIDE
|
||||||
printf("ftruncate failed %d:%s\n",errno,strerror(errno));
|
pBuf = (char*)mmap(NULL,BUF_SIZE,PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm,0);
|
||||||
//todo: set size error
|
if (pBuf == MAP_FAILED) {
|
||||||
} else {
|
printf("mmap failed %d:%s\n",errno,strerror(errno));
|
||||||
pBuf = (char*)mmap(NULL,BUF_SIZE,PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm,0);
|
pBuf = nullptr;
|
||||||
if (pBuf == MAP_FAILED) {
|
|
||||||
printf("mmap failed %d:%s\n",errno,strerror(errno));
|
|
||||||
pBuf = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue