From 28e71878fc79529c72aea3eed86424307f307e6c Mon Sep 17 00:00:00 2001 From: AOYAMA Kazuharu Date: Tue, 22 Feb 2022 15:27:53 +0900 Subject: [PATCH 1/5] bugfixes --- compiler.cpp | 67 ++++++++++++++++++++++++++-------------------------- compiler.h | 6 ++--- main.cpp | 12 +++++----- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/compiler.cpp b/compiler.cpp index 9ac6f54..e768e75 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -4,7 +4,7 @@ #include #include #include -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN #include #endif using namespace cpi; @@ -76,11 +76,11 @@ Compiler::~Compiler() } -bool Compiler::compile(const QString &cmd, const QString &code) +bool Compiler::compile(const QString &cc, const QStringList &options, const QString &code) { _compileError.clear(); _sourceCode = code.trimmed(); - QString cccmd = cmd; + auto ccOptions = options; #ifdef Q_CC_MSVC QFile objtemp(QDir::tempPath() + QDir::separator() + "cpisource" + QString::number(QCoreApplication::applicationPid()) + ".obj"); @@ -89,8 +89,8 @@ bool Compiler::compile(const QString &cmd, const QString &code) temp.write(qPrintable(_sourceCode)); temp.close(); } - cccmd += " /Fo" + objtemp.fileName(); - cccmd += " " + temp.fileName(); + ccOptions << "/Fo" + objtemp.fileName(); + ccOptions << temp.fileName(); #endif if (isSetDebugOption()) { @@ -101,10 +101,10 @@ bool Compiler::compile(const QString &cmd, const QString &code) } } - //qDebug() << cccmd; + //qDebug() << cc << ccOptions; QProcess compileProc; - auto cmdlst = cccmd.split(" ", SkipEmptyParts); - compileProc.start(cmdlst[0], cmdlst.mid(1)); + compileProc.start(cc, ccOptions); + #ifndef Q_CC_MSVC compileProc.write(_sourceCode.toLocal8Bit()); compileProc.waitForBytesWritten(); @@ -123,38 +123,38 @@ bool Compiler::compile(const QString &cmd, const QString &code) } -int Compiler::compileAndExecute(const QString &cc, const QString &ccOptions, const QString &src) +int Compiler::compileAndExecute(const QString &cc, const QStringList &options, const QString &src) { - QString cmd = cc; - QString linkOpts; + QStringList ccOpts; + QStringList linkOpts; - for (auto &op : ccOptions.split(" ", SkipEmptyParts)) { + for (auto &op : options) { +#ifndef Q_CC_MSVC if (op.startsWith("-L", Qt::CaseInsensitive) || op.startsWith("-Wl,")) { - linkOpts += " "; - linkOpts += op; - } else if (op != "-c") { - cmd += " "; - cmd += op; + linkOpts << op; + continue; + } +#endif + if (op != "-c") { + ccOpts << op; + continue; } } QString ccopt = requiredOptions.value(QFileInfo(cc).fileName()); if (!ccopt.isEmpty()) { - cmd += " "; - cmd += ccopt; + ccOpts << ccopt; } #ifdef Q_CC_MSVC - cmd += " /Fe:"; - cmd += aoutName(); - cmd += " "; + ccOpts << "/Fe:" + aoutName(); #else - cmd += " -o "; - cmd += aoutName(); - cmd += " - "; // standard input + ccOpts << "-o"; + ccOpts << aoutName(); + ccOpts << "-"; // standard input #endif - cmd += linkOpts.trimmed(); + ccOpts << linkOpts; - bool cpl = compile(cmd, qPrintable(src)); + bool cpl = compile(cc, ccOpts, src); if (cpl) { // Executes the binary QProcess exe; @@ -173,7 +173,7 @@ int Compiler::compileAndExecute(const QString &cc, const QString &ccOptions, con } }; -#ifndef Q_OS_WINDOWS +#ifndef Q_OS_WIN QSocketNotifier notifier(fileno(stdin), QSocketNotifier::Read); QObject::connect(¬ifier, &QSocketNotifier::activated, readfunc); #endif @@ -183,7 +183,7 @@ int Compiler::compileAndExecute(const QString &cc, const QString &ccOptions, con if (!exeout.isEmpty()) { print() << exeout << flush; } -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN HANDLE h = GetStdHandle(STD_INPUT_HANDLE); if (WaitForSingleObject(h, 50) == WAIT_OBJECT_0) { readfunc(); @@ -201,8 +201,9 @@ int Compiler::compileAndExecute(const QString &cc, const QString &ccOptions, con int Compiler::compileAndExecute(const QString &src) { - auto optstr = cxxflags() + " " + ldflags(); - return compileAndExecute(cxx(), optstr, src); + auto opts = cxxflags().split(" ", SkipEmptyParts); + opts << ldflags().split(" ", SkipEmptyParts); + return compileAndExecute(cxx(), opts, src); } @@ -224,11 +225,11 @@ int Compiler::compileFileAndExecute(const QString &path) src += ts.readAll(); } - QString opts = cxxflags(); + auto opts = cxxflags().split(" ", SkipEmptyParts); const QRegularExpression re("//\\s*CompileOptions\\s*:([^\n]*)", QRegularExpression::CaseInsensitiveOption); auto match = re.match(src); if (match.hasMatch()) { - opts += match.captured(1); // compile options + opts << match.captured(1).split(" ", SkipEmptyParts); // compile options } const QRegularExpression reCxx("//\\s*CXX\\s*:([^\n]*)"); diff --git a/compiler.h b/compiler.h index dfb756a..e6eeeb5 100644 --- a/compiler.h +++ b/compiler.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include class Compiler { @@ -8,7 +8,7 @@ class Compiler { Compiler(); ~Compiler(); - int compileAndExecute(const QString &cc, const QString &ccOptions, const QString &src); + int compileAndExecute(const QString &cc, const QStringList &options, const QString &src); int compileAndExecute(const QString &src); int compileFileAndExecute(const QString &path); void printLastCompilationError() const; @@ -21,7 +21,7 @@ class Compiler { static QString ldflags(); private: - bool compile(const QString &cmd, const QString &code); + bool compile(const QString &cc, const QStringList &options, const QString &code); QString _sourceCode; QString _compileError; diff --git a/main.cpp b/main.cpp index a955d67..c9eb725 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,7 @@ #include #include #include -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN #include #else #include @@ -66,7 +66,7 @@ QString aoutName() static QString aout; if (aout.isEmpty()) { aout = QDir::tempPath() + QDir::separator(); -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN aout += ".cpiout" + QString::number(QCoreApplication::applicationPid()) + ".exe"; #else aout += ".cpi" + QString::number(QCoreApplication::applicationPid()) + ".out"; @@ -76,7 +76,7 @@ QString aoutName() } -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN static BOOL WINAPI signalHandler(DWORD ctrlType) { switch (ctrlType) { @@ -331,7 +331,7 @@ static int interpreter() }; print() << "cpi> " << flush; -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN HANDLE h = GetStdHandle(STD_INPUT_HANDLE); while (!end) { if (WaitForSingleObject(h, 50) == WAIT_OBJECT_0) { @@ -354,7 +354,7 @@ int main(int argv, char *argc[]) { QCoreApplication app(argv, argc); -#if (defined Q_OS_WINDOWS) || (defined Q_OS_DARWIN) +#if (defined Q_OS_WIN) || (defined Q_OS_DARWIN) conf = new QSettings(QSettings::IniFormat, QSettings::UserScope, "cpi/cpi"); #else conf = new QSettings(QSettings::NativeFormat, QSettings::UserScope, "cpi/cpi"); @@ -371,7 +371,7 @@ int main(int argv, char *argc[]) conf->sync(); } -#ifdef Q_OS_WINDOWS +#ifdef Q_OS_WIN SetConsoleCtrlHandler(signalHandler, TRUE); #else watchUnixSignal(SIGTERM); From 2dd523a350f49fcf728a2b1ce6fb75c58ef0bb02 Mon Sep 17 00:00:00 2001 From: AOYAMA Kazuharu Date: Tue, 22 Feb 2022 16:30:21 +0900 Subject: [PATCH 2/5] updatd --- .editorconfig | 6 ++- .github/workflows/actions.yml | 81 +++++++++++++++++++---------------- compiler.cpp | 52 ++++++++++++++-------- main.cpp | 63 +++++++++++++-------------- 4 files changed, 112 insertions(+), 90 deletions(-) diff --git a/.editorconfig b/.editorconfig index 539ac61..a7c6dfc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,8 +4,10 @@ root = true [*] +charset = utf-8 end_of_line = lf indent_style = space +trim_trailing_whitespace = true indent_size = 4 [*.{h,cpp}] @@ -20,7 +22,7 @@ trim_trailing_whitespace = true indent_style = tab [*.{html,htm}] -trim_trailing_whitespace = false +trim_trailing_whitespace = false insert_final_newline = false [*.ini] @@ -29,3 +31,5 @@ end_of_line = crlf [*.bat] end_of_line = crlf +[*.{yml,yaml}] +indent_size = 2 diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 7139517..0c37786 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -2,55 +2,60 @@ name: ActionsCI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: ci-macos: runs-on: macos-latest steps: - - uses: actions/checkout@main - - name: Homebrew - run: brew install qt6 - - name: build - run: | - qmake CONFIG+=release - make + - uses: actions/checkout@main + - name: Homebrew + run: brew install qt6 + - name: build + run: | + qmake CONFIG+=release + make + - name: tests + run: | + ./cpi tests/helloworld.cpp + ./cpi tests/sqrt.cpp 7 + ./cpi tests/fibonacci.cpp 10 ci-ubuntu-gcc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@main - - name: apt - run: | - sudo apt-get update -qq - sudo apt-get install -y --no-install-recommends g++ make qtbase5-dev qt5-default qt5-qmake - - name: build - run: | - qmake CONFIG+=release - make - - name: tests - run: | - ./cpi tests/helloworld.cpp - ./cpi tests/sqrt.cpp 7 - ./cpi tests/fibonacci.cpp 10 + - uses: actions/checkout@main + - name: apt + run: | + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends g++ make qtbase5-dev qt5-default qt5-qmake + - name: build + run: | + qmake CONFIG+=release + make + - name: tests + run: | + ./cpi tests/helloworld.cpp + ./cpi tests/sqrt.cpp 7 + ./cpi tests/fibonacci.cpp 10 ci-ubuntu-clang: runs-on: ubuntu-latest steps: - - uses: actions/checkout@main - - name: apt - run: | - sudo apt-get update -qq - sudo apt purge -y gcc g++ - sudo apt-get install -y --no-install-recommends clang make qtbase5-dev qt5-default qt5-qmake - - name: build - run: | - qmake -spec linux-clang CONFIG+=release - make - - name: tests - run: | - ./cpi tests/helloworld.cpp - ./cpi tests/sqrt.cpp 7 - ./cpi tests/fibonacci.cpp 10 + - uses: actions/checkout@main + - name: apt + run: | + sudo apt-get update -qq + sudo apt purge -y gcc g++ + sudo apt-get install -y --no-install-recommends clang make qtbase5-dev qt5-default qt5-qmake + - name: build + run: | + qmake -spec linux-clang CONFIG+=release + make + - name: tests + run: | + ./cpi tests/helloworld.cpp + ./cpi tests/sqrt.cpp 7 + ./cpi tests/fibonacci.cpp 10 diff --git a/compiler.cpp b/compiler.cpp index e768e75..3e736f9 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -23,33 +23,49 @@ const QMap requiredOptions = { }; +static QString searchPath(const QString &command) +{ + QString path; + QProcess which; + +#if defined(Q_OS_WIN) + which.start("where.exe", QStringList(command)); +#else + which.start("which", QStringList(command)); +#endif + which.waitForFinished(); + if (which.exitCode() == 0) { + path = QString::fromLocal8Bit(which.readAll()).split("\n", SkipEmptyParts).value(0).trimmed(); + } + return path; +}; + + QString Compiler::cxx() { - auto compiler = conf->value("CXX").toString().trimmed(); + QString compiler = conf->value("CXX").toString().trimmed(); if (compiler.isEmpty()) { #if defined(Q_OS_DARWIN) - compiler = "clang++"; + compiler = searchPath("clang++"); #elif defined(Q_CC_MSVC) - compiler = "cl.exe"; + compiler = searchPath("cl.exe"); #else - auto searchCommand = [](const QString &command) { - QProcess which; - which.start("which", QStringList(command)); - which.waitForFinished(); - return which.exitCode() == 0; - }; - - if (searchCommand("g++")) { - compiler = "g++"; - } else if (searchCommand("clang++")) { - compiler = "clang++"; - } else { - qCritical() << "Not found compiler"; - std::exit(1); + compiler = searchPath("g++"); + if (compiler.isEmpty()) { + compiler = searchPath("clang++"); } #endif + } else { + // check path + compiler = searchPath(compiler); } + + if (compiler.isEmpty()) { + qCritical() << "Compiler not found." << conf->value("CXX").toString().trimmed(); + std::exit(1); + } + return compiler; } @@ -101,7 +117,7 @@ bool Compiler::compile(const QString &cc, const QStringList &options, const QStr } } - //qDebug() << cc << ccOptions; + qDebug() << cc << ccOptions; QProcess compileProc; compileProc.start(cc, ccOptions); diff --git a/main.cpp b/main.cpp index c9eb725..9a59ec9 100644 --- a/main.cpp +++ b/main.cpp @@ -14,50 +14,47 @@ #endif using namespace cpi; -#define CPI_VERSION_STR "2.0.3" -#define CPI_VERSION_NUMBER 0x020003 +// Version +constexpr auto CPI_VERSION_STR = "2.0.4"; #ifdef Q_CC_MSVC -#define DEFAULT_CONFIG \ - "[General]\n" \ - "CXX=cl.exe\n" \ - "CXXFLAGS=\n" \ - "LDFLAGS=\n" \ - "COMMON_INCLUDES=\n" +constexpr auto DEFAULT_CONFIG = "[General]\n" + "CXX=cl.exe\n" + "CXXFLAGS=\n" + "LDFLAGS=\n" + "COMMON_INCLUDES=\n"; #else #if QT_VERSION < 0x060000 -#define DEFAULT_CONFIG \ - "[General]\n" \ - "### Example option for Qt5\n" \ - "#CXX=\n" \ - "#CXXFLAGS=-fPIC -pipe -std=c++14 -D_REENTRANT -I/usr/include/qt5\n" \ - "#LDFLAGS=-lQt5Core\n" \ - "#COMMON_INCLUDES=\n" \ - "\n" \ - "CXX=\n" \ - "CXXFLAGS=-fPIC -pipe -std=c++14 -D_REENTRANT\n" \ - "LDFLAGS=\n" \ - "COMMON_INCLUDES=\n" +constexpr auto DEFAULT_CONFIG = "[General]\n" + "### Example option for Qt5\n" + "#CXX=%1\n" + "#CXXFLAGS=-fPIC -pipe -std=c++14 -D_REENTRANT -I/usr/include/qt5\n" + "#LDFLAGS=-lQt5Core\n" + "#COMMON_INCLUDES=\n" + "\n" + "CXX=\n" + "CXXFLAGS=-fPIC -pipe -std=c++14 -D_REENTRANT\n" + "LDFLAGS=\n" + "COMMON_INCLUDES=\n"; #else -#define DEFAULT_CONFIG \ - "[General]\n" \ - "### Example option for Qt6\n" \ - "#CXX=\n" \ - "#CXXFLAGS=-fPIC -pipe -std=c++17 -D_REENTRANT -I/usr/include/qt6\n" \ - "#LDFLAGS=-lQt6Core\n" \ - "#COMMON_INCLUDES=\n" \ - "\n" \ - "CXX=\n" \ - "CXXFLAGS=-fPIC -pipe -std=c++17 -D_REENTRANT\n" \ - "LDFLAGS=\n" \ - "COMMON_INCLUDES=\n" +constexpr auto DEFAULT_CONFIG = "[General]\n" + "### Example option for Qt6\n" + "#CXX=\n" + "#CXXFLAGS=-fPIC -pipe -std=c++17 -D_REENTRANT -I/usr/include/qt6\n" + "#LDFLAGS=-lQt6Core\n" + "#COMMON_INCLUDES=\n" + "\n" + "CXX=\n" + "CXXFLAGS=-fPIC -pipe -std=c++17 -D_REENTRANT\n" + "LDFLAGS=\n" + "COMMON_INCLUDES=\n"; #endif #endif // Entered headers and code static QStringList headers, code; static int lastLineNumber = 0; // line number added recently -QSettings *conf; +QSettings *conf = nullptr; QStringList cppsArgs; From e989f7dccaf35e75b4d4f75afa6a17ee9b618cff Mon Sep 17 00:00:00 2001 From: AOYAMA Kazuharu Date: Tue, 22 Feb 2022 16:59:35 +0900 Subject: [PATCH 3/5] updated --- compiler.cpp | 8 ++++---- global.h | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler.cpp b/compiler.cpp index 3e736f9..51509d6 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -9,9 +9,6 @@ #endif using namespace cpi; -extern QSettings *conf; -extern QStringList cppsArgs; -extern QString aoutName(); const QMap requiredOptions = { {"gcc", "-xc"}, @@ -117,7 +114,7 @@ bool Compiler::compile(const QString &cc, const QStringList &options, const QStr } } - qDebug() << cc << ccOptions; + //qDebug() << cc << ccOptions; QProcess compileProc; compileProc.start(cc, ccOptions); @@ -205,6 +202,9 @@ int Compiler::compileAndExecute(const QString &cc, const QStringList &options, c readfunc(); } #endif + if (exe.state() != QProcess::Running) { + break; + } qApp->processEvents(); } print() << exe.readAll() << flush; diff --git a/global.h b/global.h index 46a6d3a..06783f5 100644 --- a/global.h +++ b/global.h @@ -15,3 +15,8 @@ const auto endl = Qt::endl; #endif } + + +extern QSettings *conf; +extern QStringList cppsArgs; +extern QString aoutName(); From 406fb242fc300232a5fe0b367e90b448c44643f8 Mon Sep 17 00:00:00 2001 From: AOYAMA Kazuharu Date: Tue, 22 Feb 2022 17:11:25 +0900 Subject: [PATCH 4/5] polish. --- compiler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler.cpp b/compiler.cpp index 51509d6..8477421 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -175,6 +175,7 @@ int Compiler::compileAndExecute(const QString &cc, const QStringList &options, c exe.start(aoutName(), cppsArgs); exe.waitForStarted(); +#ifndef Q_OS_WIN auto readfunc = [&]() { // read and write to the process std::string s; @@ -186,7 +187,6 @@ int Compiler::compileAndExecute(const QString &cc, const QStringList &options, c } }; -#ifndef Q_OS_WIN QSocketNotifier notifier(fileno(stdin), QSocketNotifier::Read); QObject::connect(¬ifier, &QSocketNotifier::activated, readfunc); #endif @@ -196,6 +196,7 @@ int Compiler::compileAndExecute(const QString &cc, const QStringList &options, c if (!exeout.isEmpty()) { print() << exeout << flush; } + #ifdef Q_OS_WIN HANDLE h = GetStdHandle(STD_INPUT_HANDLE); if (WaitForSingleObject(h, 50) == WAIT_OBJECT_0) { From 354f80ff4a6f850800716ce582781bc8783aee1d Mon Sep 17 00:00:00 2001 From: AOYAMA Kazuharu Date: Tue, 22 Feb 2022 17:14:21 +0900 Subject: [PATCH 5/5] revert. --- compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler.cpp b/compiler.cpp index 8477421..d66c5f2 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -175,7 +175,6 @@ int Compiler::compileAndExecute(const QString &cc, const QStringList &options, c exe.start(aoutName(), cppsArgs); exe.waitForStarted(); -#ifndef Q_OS_WIN auto readfunc = [&]() { // read and write to the process std::string s; @@ -187,6 +186,7 @@ int Compiler::compileAndExecute(const QString &cc, const QStringList &options, c } }; +#ifndef Q_OS_WIN QSocketNotifier notifier(fileno(stdin), QSocketNotifier::Read); QObject::connect(¬ifier, &QSocketNotifier::activated, readfunc); #endif