From 423f87763eea8d3fc8a76ace05485b97d559ceeb Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Sat, 20 Jan 2024 21:09:43 +0800 Subject: [PATCH 01/16] fix case in json theme (#182) --- RedPandaIDE/themes/contrast.json | 2 +- RedPandaIDE/themes/dark.json | 2 +- RedPandaIDE/themes/default.json | 2 +- RedPandaIDE/themes/molo.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RedPandaIDE/themes/contrast.json b/RedPandaIDE/themes/contrast.json index 35a0ada8..a631b386 100644 --- a/RedPandaIDE/themes/contrast.json +++ b/RedPandaIDE/themes/contrast.json @@ -33,6 +33,6 @@ "PaletteTextDisabled":"#9DA9B5", "PaletteMid": "#FFFFFF", "PaletteLight": "#505050", - "PaletteMidLight": "#00ff00" + "PaletteMidlight": "#00ff00" } } diff --git a/RedPandaIDE/themes/dark.json b/RedPandaIDE/themes/dark.json index a1121153..97ab7142 100644 --- a/RedPandaIDE/themes/dark.json +++ b/RedPandaIDE/themes/dark.json @@ -33,6 +33,6 @@ "PaletteTextDisabled":"#9DA9B5", "PaletteMid": "#707070", "PaletteLight": "#505050", - "PaletteMidLight": "#00ff00" + "PaletteMidlight": "#00ff00" } } diff --git a/RedPandaIDE/themes/default.json b/RedPandaIDE/themes/default.json index 83dd4df8..4b782d23 100644 --- a/RedPandaIDE/themes/default.json +++ b/RedPandaIDE/themes/default.json @@ -21,7 +21,7 @@ "PaletteLink":"#0000ff", "PaletteLinkVisited":"#ff00ff", "PaletteLight": "#ffffff", - "PaletteMidLight": "#cacaca", + "PaletteMidlight": "#cacaca", "PaletteDark":"#9f9f9f", "PaletteMid": "#b8b8b8", "PaletteWindowDisabled":"#efefef", diff --git a/RedPandaIDE/themes/molo.json b/RedPandaIDE/themes/molo.json index ac18ec1e..731e34a8 100644 --- a/RedPandaIDE/themes/molo.json +++ b/RedPandaIDE/themes/molo.json @@ -33,6 +33,6 @@ "PaletteTextDisabled":"#9DA9B5", "PaletteMid": "#FFFFFF", "PaletteLight": "#505050", - "PaletteMidLight": "#00ff00" + "PaletteMidlight": "#00ff00" } } From e2a23ed4ee2827e3e3c88b31840900f03a2b2d06 Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Sun, 21 Jan 2024 18:02:51 +0800 Subject: [PATCH 02/16] add Lua api version check and type defs (#183) --- RedPandaIDE/addon/api.cpp | 160 +++- RedPandaIDE/addon/api.h | 1 + RedPandaIDE/addon/executor.cpp | 69 +- RedPandaIDE/addon/executor.h | 8 +- RedPandaIDE/addon/runtime.cpp | 40 +- RedPandaIDE/addon/runtime.h | 2 + RedPandaIDE/settings.cpp | 4 +- RedPandaIDE/themes/contrast.lua | 88 ++- RedPandaIDE/themes/dark.lua | 88 ++- RedPandaIDE/themes/default.lua | 84 +- RedPandaIDE/themes/molo.lua | 88 ++- RedPandaIDE/themes/random_light.lua | 196 +++-- RedPandaIDE/themes/system.lua | 116 +-- RedPandaIDE/translations/RedPandaIDE_pt_BR.ts | 4 + RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 4 + RedPandaIDE/translations/RedPandaIDE_zh_TW.ts | 4 + RedPandaIDE/utils.h | 4 + addon/compiler_hint/archlinux.tl | 313 ++++++++ addon/compiler_hint/windows_domain.tl | 430 +++++++++++ addon/defs/compiler_hint.d.tl | 107 +++ addon/defs/global_env.d.tl | 100 +++ addon/defs/theme.d.tl | 63 ++ addon/gen.sh | 29 + addon/theme/contrast.tl | 53 ++ addon/theme/dark.tl | 53 ++ addon/theme/default.tl | 51 ++ addon/theme/molo.tl | 53 ++ addon/theme/random_light.tl | 132 ++++ addon/theme/system.tl | 113 +++ docs/addon.md | 232 ++---- packages/archlinux/compiler_hint.lua | 538 +++++++------ packages/msys/domain/compiler_hint.lua | 728 ++++++++++-------- 32 files changed, 2886 insertions(+), 1069 deletions(-) create mode 100644 addon/compiler_hint/archlinux.tl create mode 100644 addon/compiler_hint/windows_domain.tl create mode 100644 addon/defs/compiler_hint.d.tl create mode 100644 addon/defs/global_env.d.tl create mode 100644 addon/defs/theme.d.tl create mode 100755 addon/gen.sh create mode 100644 addon/theme/contrast.tl create mode 100644 addon/theme/dark.tl create mode 100644 addon/theme/default.tl create mode 100644 addon/theme/molo.tl create mode 100644 addon/theme/random_light.tl create mode 100644 addon/theme/system.tl diff --git a/RedPandaIDE/addon/api.cpp b/RedPandaIDE/addon/api.cpp index 0d3ff398..8c253010 100644 --- a/RedPandaIDE/addon/api.cpp +++ b/RedPandaIDE/addon/api.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef Q_OS_WINDOWS # include @@ -51,11 +52,126 @@ using pIsWow64Process2_t = BOOL (WINAPI *)( ); #endif -// C_Debug.debug(string) -> () +static QString luaDump(const QJsonValue &value) { + if (value.isNull()) + return "nil"; + if (value.isBool()) + return value.toBool() ? "true" : "false"; + if (value.isDouble()) + return QString::number(value.toDouble()); + if (value.isString()) { + QString s = value.toString(); + s.replace('\\', "\\\\"); + s.replace('"', "\\\""); + s.replace('\n', "\\n"); + s.replace('\r', "\\r"); + s.replace('\t', "\\t"); + return '"' + s + '"'; + } + if (value.isArray()) { + QString s = "{"; + for (const QJsonValue &v : value.toArray()) + s += luaDump(v) + ','; + s += '}'; + return s; + } + if (value.isObject()) { + QJsonObject o = value.toObject(); + QString s = "{"; + for (const QString &k : o.keys()) + s += '[' + luaDump(k) + "]=" + luaDump(o[k]) + ','; + s += '}'; + return s; + } + return "nil"; +} + +static QString stringify(const QJsonValue &value) { + if (value.isString()) + return value.toString(); + if (value.isNull()) + return "[nil]"; + if (value.isBool()) + return value.toBool() ? "[true]" : "[false]"; + if (value.isDouble()) + return QString("[number %1]").arg(value.toDouble()); + if (value.isArray() || value.isObject()) + return QString("[table %1]").arg(luaDump(value)); + return "[unknown]"; +} + +/* https://stackoverflow.com/questions/15687223/explicit-call-to-destructor-before-longjmp-croak + * + * C++11 18.10/4: A setjmp/longjmp call pair has undefined behavior if + * replacing the setjmp and longjmp by catch and throw would invoke any + * non-trivial destructors for any automatic objects. + * + * Use impl function so the API boundary contains only POD types. + */ +void luaApiImpl_Debug_debug(lua_State *L) { + QString s = AddOn::RaiiLuaState::fetchString(L, 1); + int nArgs = lua_gettop(L); + for (int i = 2; i <= nArgs; ++i) { + QJsonValue arg; + try { + arg = AddOn::RaiiLuaState::fetch(L, i); + } catch (const AddOn::LuaError &e) { + QString reason = e.reason() + QString(" ('C_Debug.debug' argument #%1)").arg(i); + throw AddOn::LuaError(reason); + } + s = s.arg(stringify(arg)); + } + qDebug().noquote() << s; +} + +// C_Debug.debug(string, ...) -> () extern "C" int luaApi_Debug_debug(lua_State *L) noexcept { - QString info = AddOn::RaiiLuaState::fetchString(L, 1); - qDebug() << info; - return 0; + bool error = false; + try { + luaApiImpl_Debug_debug(L); + } catch (const AddOn::LuaError &e) { + error = true; + AddOn::RaiiLuaState::push(L, e.reason()); + } + if (error) { + lua_error(L); // longjmp, never returns + __builtin_unreachable(); + } else { + return 0; + } +} + +void luaApiImpl_Debug_messageBox(lua_State *L) { + QString s = AddOn::RaiiLuaState::fetchString(L, 1); + int nArgs = lua_gettop(L); + for (int i = 2; i <= nArgs; ++i) { + QJsonValue arg; + try { + arg = AddOn::RaiiLuaState::fetch(L, i); + } catch (const AddOn::LuaError &e) { + QString reason = e.reason() + QString(" ('C_Debug.messageBox' argument #%1)").arg(i); + throw AddOn::LuaError(reason); + } + s = s.arg(stringify(arg)); + } + QMessageBox::information(nullptr, "Debug", s); +} + +// C_Debug.messageBox(string, ...) -> () +extern "C" int luaApi_Debug_messageBox(lua_State *L) noexcept { + bool error = false; + try { + luaApiImpl_Debug_messageBox(L); + } catch (const AddOn::LuaError &e) { + error = true; + AddOn::RaiiLuaState::push(L, e.reason()); + } + if (error) { + lua_error(L); // longjmp, never returns + __builtin_unreachable(); + } else { + return 0; + } } // C_Desktop.desktopEnvironment() -> string @@ -262,9 +378,7 @@ extern "C" int luaApi_System_supportedAppArchList(lua_State *L) noexcept { } } - // workaround for Debian 10 Qt 5.11, better to be - // QStringList result{arches.begin(), arches.end()}; - QStringList result = arches.toList(); + QStringList result = arches.values(); AddOn::RaiiLuaState::push(L, result); return 1; #endif @@ -291,15 +405,37 @@ extern "C" int luaApi_System_readRegistry(lua_State *L) noexcept } #endif -// C_Util.format(string, ...) -> string -extern "C" int luaApi_Util_format(lua_State *L) noexcept +void luaApiImpl_Util_format(lua_State *L) { QString s = AddOn::RaiiLuaState::fetchString(L, 1); int nArgs = lua_gettop(L); for (int i = 2; i <= nArgs; ++i) { - QJsonValue arg = AddOn::RaiiLuaState::fetch(L, i); - s = s.arg(arg.toString()); + QJsonValue arg; + try { + arg = AddOn::RaiiLuaState::fetch(L, i); + } catch (const AddOn::LuaError &e) { + QString reason = e.reason() + QString(" ('C_Util.format' argument #%1)").arg(i); + throw AddOn::LuaError(reason); + } + s = s.arg(stringify(arg)); } AddOn::RaiiLuaState::push(L, s); - return 1; +} + +// C_Util.format(string, ...) -> string +extern "C" int luaApi_Util_format(lua_State *L) noexcept +{ + bool error = false; + try { + luaApiImpl_Util_format(L); + } catch (const AddOn::LuaError &e) { + error = true; + AddOn::RaiiLuaState::push(L, e.reason()); + } + if (error) { + lua_error(L); // longjmp, never returns + __builtin_unreachable(); + } else { + return 1; + } } diff --git a/RedPandaIDE/addon/api.h b/RedPandaIDE/addon/api.h index c147703c..6afd92e5 100644 --- a/RedPandaIDE/addon/api.h +++ b/RedPandaIDE/addon/api.h @@ -20,6 +20,7 @@ struct lua_State; extern "C" int luaApi_Debug_debug(lua_State *L) noexcept; +extern "C" int luaApi_Debug_messageBox(lua_State *L) noexcept; extern "C" int luaApi_Desktop_desktopEnvironment(lua_State *L) noexcept; extern "C" int luaApi_Desktop_language(lua_State *L) noexcept; diff --git a/RedPandaIDE/addon/executor.cpp b/RedPandaIDE/addon/executor.cpp index 0c941a79..08efb4eb 100644 --- a/RedPandaIDE/addon/executor.cpp +++ b/RedPandaIDE/addon/executor.cpp @@ -26,7 +26,8 @@ namespace AddOn { static QMap> apiGroups{ {"C_Debug", { - {"debug", &luaApi_Debug_debug}, // (string) -> () + {"debug", &luaApi_Debug_debug}, // (string, ...) -> () + {"messageBox", &luaApi_Debug_messageBox}, // (string, ...) -> () }}, {"C_Desktop", { @@ -80,7 +81,11 @@ extern "C" void luaHook_timeoutKiller(lua_State *L, lua_Debug *ar [[maybe_unused } }; -ThemeExecutor::ThemeExecutor() : SimpleExecutor({"C_Debug", "C_Desktop"}) {} +ThemeExecutor::ThemeExecutor() : SimpleExecutor( + "theme", 0, 1, + {"C_Debug", "C_Desktop", "C_Util"}) +{ +} QJsonObject ThemeExecutor::operator()(const QByteArray &script, const QString &name) { @@ -92,28 +97,74 @@ QJsonObject ThemeExecutor::operator()(const QByteArray &script, throw LuaError("Theme script must return an object."); } +SimpleExecutor::SimpleExecutor(const QString &kind, int major, int minor, const QList &apis) + : mKind(kind), mMajor(major), mMinor(minor), mApis(apis) +{ +} + +bool SimpleExecutor::apiVersionCheck(const QJsonObject &addonApi) { + const QString &addonKind = addonApi["kind"].toString(); + if (addonKind != mKind) + return false; + if (!addonApi.contains("major") || !addonApi.contains("minor")) + return false; + int addonMajor = addonApi["major"].toInt(); + int addonMinor = addonApi["minor"].toInt(); + if (mMajor == 0) + return addonMajor == mMajor && addonMinor == mMinor; + else + return addonMajor == mMajor && addonMinor <= mMinor; +} + QJsonValue SimpleExecutor::runScript(const QByteArray &script, const QString &name, std::chrono::microseconds timeLimit) { RaiiLuaState L(name, timeLimit); - L.openLibs(); - for (auto &api : mApis) - registerApiGroup(L, api); - int retLoad = L.loadBuffer(script, name); if (retLoad != 0) - throw LuaError(QString("Lua script load error: %1.").arg(L.popString())); + throw LuaError(QString("Lua load error: %1.").arg(L.popString())); L.setHook(&luaHook_timeoutKiller, LUA_MASKCOUNT, 1'000'000); // ~5ms on early 2020s desktop CPUs L.setTimeStart(); - int callResult = L.pCall(0, 1, 0); + int callResult = L.pCall(0, 0, 0); if (callResult != 0) { throw LuaError(QString("Lua error: %1.").arg(L.popString())); } + // call `apiVersion()` to check compatibility + int type = L.getGlobal("apiVersion"); + if (type != LUA_TFUNCTION) { + throw LuaError("Add-on interface error: `apiVersion` is not a function."); + } + callResult = L.pCall(0, 1, 0); + if (callResult != 0) { + throw LuaError(QString("Lua error: %1.").arg(L.popString())); + } + QJsonObject addonApi = L.popObject(); + if (!apiVersionCheck(addonApi)) { + throw LuaError(QString("Add-on interface error: API version incompatible with %1:%2.%3.") + .arg(mKind).arg(mMajor).arg(mMinor)); + } + + // inject APIs and call `main()` + L.openLibs(); + for (auto &api : mApis) + registerApiGroup(L, api); + type = L.getGlobal("main"); + if (type != LUA_TFUNCTION) { + throw LuaError("Add-on interface error: `main` is not a function."); + } + callResult = L.pCall(0, 1, 0); + if (callResult != 0) { + throw LuaError(QString("Lua error: %1.").arg(L.popString())); + } return L.fetch(1); } -CompilerHintExecutor::CompilerHintExecutor() : SimpleExecutor({"C_Debug", "C_Desktop", "C_FileSystem", "C_System", "C_Util"}) {} +CompilerHintExecutor::CompilerHintExecutor() : SimpleExecutor( + "compiler_hint", 0, 1, + {"C_Debug", "C_Desktop", "C_FileSystem", "C_System", "C_Util"}) +{ +} QJsonObject CompilerHintExecutor::operator()(const QByteArray &script) { using namespace std::chrono_literals; diff --git a/RedPandaIDE/addon/executor.h b/RedPandaIDE/addon/executor.h index 671305b6..4aca718b 100644 --- a/RedPandaIDE/addon/executor.h +++ b/RedPandaIDE/addon/executor.h @@ -27,13 +27,17 @@ namespace AddOn { // simple, stateless Lua executor class SimpleExecutor { protected: - SimpleExecutor(const QList &apis): mApis(apis) {} + SimpleExecutor(const QString &kind, int major, int minor, const QList &apis); + + bool apiVersionCheck(const QJsonObject &addonApi); - // run a Lua script and fetch its return value as type R QJsonValue runScript(const QByteArray &script, const QString &name, std::chrono::microseconds timeLimit); private: + QString mKind; + int mMajor; + int mMinor; QStringList mApis; }; diff --git a/RedPandaIDE/addon/runtime.cpp b/RedPandaIDE/addon/runtime.cpp index 752dbb59..2b374326 100644 --- a/RedPandaIDE/addon/runtime.cpp +++ b/RedPandaIDE/addon/runtime.cpp @@ -68,6 +68,11 @@ QString RaiiLuaState::fetchString(int index) return lua_tostring(mLua, index); } +QJsonObject RaiiLuaState::fetchObject(int index) +{ + return fetchTableImpl(mLua, index, 0).toObject(); +} + QJsonValue RaiiLuaState::fetch(int index) { return fetchValueImpl(mLua, index, 0); @@ -93,6 +98,11 @@ QString RaiiLuaState::fetchString(lua_State *L, int index) return lua_tostring(L, index); } +QJsonObject RaiiLuaState::fetchObject(lua_State *L, int index) +{ + return fetchTableImpl(L, index, 0).toObject(); +} + QJsonValue RaiiLuaState::fetch(lua_State *L, int index) { return fetchValueImpl(L, index, 0); @@ -112,6 +122,13 @@ QString RaiiLuaState::popString() return value; } +QJsonObject RaiiLuaState::popObject() +{ + QJsonObject value = fetchObject(-1); + lua_pop(mLua, 1); + return value; +} + QJsonValue RaiiLuaState::pop() { QJsonValue value = fetch(-1); @@ -191,6 +208,11 @@ int RaiiLuaState::pCall(int nargs, int nresults, int msgh) return lua_pcall(mLua, nargs, nresults, msgh); } +int RaiiLuaState::getGlobal(const QString &name) +{ + return lua_getglobal(mLua, name.toUtf8().constData()); +} + void RaiiLuaState::setGlobal(const QString &name) { return lua_setglobal(mLua, name.toUtf8().constData()); @@ -230,7 +252,16 @@ QJsonValue RaiiLuaState::fetchTableImpl(lua_State *L, int index, int depth) // here we take the fact that Lua iterates array part first bool processingArrayPart = true; while (lua_next(L, newIndex)) { - QJsonValue v = pop(L); + QJsonValue v; + try { + v = fetchValueImpl(L, -1, depth); + } catch (const LuaError &e) { + QString key = fetchString(L, -2); + QString reason = e.reason() + QString(" (at table key '%1')").arg(key); + lua_pop(L, 2); + throw LuaError(reason); + } + lua_pop(L, 1); if (processingArrayPart && lua_isinteger(L, -1) && fetchInteger(L, -1) == arrayPart.size() + 1) // we are still in array part arrayPart.push_back(v); @@ -275,8 +306,11 @@ QJsonValue RaiiLuaState::fetchValueImpl(lua_State *L, int index, int depth) return fetchString(L, index); else if (lua_istable(L, index)) return fetchTableImpl(L, index, depth + 1); - else - throw LuaError(QString("Lua type error: unknown type %1.").arg(lua_typename(L, index))); + else { + int type = lua_type(L, index); + const char *name = lua_typename(L, type); + throw LuaError(QString("Lua type error: unknown type %1.").arg(name)); + } } QHash RaiiLuaState::mExtraState; diff --git a/RedPandaIDE/addon/runtime.h b/RedPandaIDE/addon/runtime.h index 3eae0137..c5b2c8b3 100644 --- a/RedPandaIDE/addon/runtime.h +++ b/RedPandaIDE/addon/runtime.h @@ -68,6 +68,7 @@ public: static long long fetchInteger(lua_State *L, int index); static double fetchNumber(lua_State *L, int index); static QString fetchString(lua_State *L, int index); + static QJsonObject fetchObject(lua_State *L, int index); static QJsonValue fetch(lua_State *L, int index); bool popBoolean(); @@ -94,6 +95,7 @@ public: int loadBuffer(const QByteArray &buff, const QString &name); void openLibs(); int pCall(int nargs, int nresults, int msgh); + int getGlobal(const QString &name); void setGlobal(const QString &name); void setHook(lua_Hook f, int mask, int count); diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index da6a4f8b..92a6fffa 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -3279,7 +3279,9 @@ void Settings::CompilerSets::findSets() try { compilerHint = AddOn::CompilerHintExecutor{}(script); } catch (const AddOn::LuaError &e) { - qDebug() << "Error in compiler_hint.lua:" << e.reason(); + QMessageBox::critical(nullptr, + QObject::tr("Error executing platform compiler hint add-on"), + e.reason()); } if (!compilerHint.empty()) { QJsonArray compilerList = compilerHint["compilerList"].toArray(); diff --git a/RedPandaIDE/themes/contrast.lua b/RedPandaIDE/themes/contrast.lua index 3852ef13..dc02c16e 100644 --- a/RedPandaIDE/themes/contrast.lua +++ b/RedPandaIDE/themes/contrast.lua @@ -1,43 +1,53 @@ +function apiVersion() + return { + kind = "theme", + major = 0, + minor = 1, + } +end + local nameMap = { - en_US = "Contrast", - pt_BR = "Contraste", - zh_CN = "高对比度", - zh_TW = "高對比度" + en_US = "Contrast", + pt_BR = "Contraste", + zh_CN = "高对比度", + zh_TW = "高對比度", } -local lang = C_Desktop.language() +function main() + local lang = C_Desktop.language() -return { - ["name"] = nameMap[lang] or nameMap.en_US, - ["style"] = "RedPandaDarkFusion", - ["default scheme"] = "Twilight", - ["default iconset"] = "contrast", - ["palette"] = { - PaletteWindow = "#000000", - PaletteWindowText = "#FFFFFF", - PaletteBase = "#141414", - PaletteAlternateBase = "#191919", - PaletteButton = "#141414", - PaletteButtonDisabled = "#141414", - PaletteBrightText = "#ff0000", - PaletteText = "#FFFFFF", - PaletteButtonText = "#FFFFFF", - PaletteButtonTextDisabled = "#9DA9B5", - PaletteHighlight = "#aa1f75cc", - PaletteDark = "#232323", - PaletteHighlightedText = "#e7e7e7", - PaletteToolTipBase = "#66000000", - PaletteToolTipText = "#e7e7e7", - PaletteLink = "#007af4", - PaletteLinkVisited = "#a57aff", - PaletteWindowDisabled = "#0A0A0A", - PaletteWindowTextDisabled = "#9DA9B5", - PaletteHighlightDisabled = "#9DA9B5", - PaletteHighlightedTextDisabled = "#9DA9B5", - PaletteBaseDisabled = "#000000", - PaletteTextDisabled = "#9DA9B5", - PaletteMid = "#FFFFFF", - PaletteLight = "#505050", - PaletteMidLight = "#00ff00" - } -} + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaDarkFusion", + ["default scheme"] = "Twilight", + ["default iconset"] = "contrast", + ["palette"] = { + PaletteWindow = "#000000", + PaletteWindowText = "#FFFFFF", + PaletteBase = "#141414", + PaletteAlternateBase = "#191919", + PaletteButton = "#141414", + PaletteButtonDisabled = "#141414", + PaletteBrightText = "#ff0000", + PaletteText = "#FFFFFF", + PaletteButtonText = "#FFFFFF", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#0A0A0A", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#9DA9B5", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#000000", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#FFFFFF", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + }, + } +end diff --git a/RedPandaIDE/themes/dark.lua b/RedPandaIDE/themes/dark.lua index 3619a73c..73307fbc 100644 --- a/RedPandaIDE/themes/dark.lua +++ b/RedPandaIDE/themes/dark.lua @@ -1,43 +1,53 @@ +function apiVersion() + return { + kind = "theme", + major = 0, + minor = 1, + } +end + local nameMap = { - en_US = "Dark", - pt_BR = "Escura", - zh_CN = "深色", - zh_TW = "深色" + en_US = "Dark", + pt_BR = "Escura", + zh_CN = "深色", + zh_TW = "深色", } -local lang = C_Desktop.language() +function main() + local lang = C_Desktop.language() -return { - ["name"] = nameMap[lang] or nameMap.en_US, - ["style"] = "RedPandaDarkFusion", - ["default scheme"] = "VS Code", - ["default iconset"] = "contrast", - ["palette"] = { - PaletteWindow = "#19232D", - PaletteWindowText = "#E0E1E3", - PaletteBase = "#1E1E1E", - PaletteAlternateBase = "#303030", - PaletteButton = "#19232D", - PaletteButtonDisabled = "#19232D", - PaletteBrightText = "#ff0000", - PaletteText = "#e7e7e7", - PaletteButtonText = "#d3d3d3", - PaletteButtonTextDisabled = "#9DA9B5", - PaletteHighlight = "#aa1f75cc", - PaletteDark = "#232323", - PaletteHighlightedText = "#e7e7e7", - PaletteToolTipBase = "#66000000", - PaletteToolTipText = "#e7e7e7", - PaletteLink = "#007af4", - PaletteLinkVisited = "#a57aff", - PaletteWindowDisabled = "#333333", - PaletteWindowTextDisabled = "#9DA9B5", - PaletteHighlightDisabled = "#26486B", - PaletteHighlightedTextDisabled = "#9DA9B5", - PaletteBaseDisabled = "#19232D", - PaletteTextDisabled = "#9DA9B5", - PaletteMid = "#707070", - PaletteLight = "#505050", - PaletteMidLight = "#00ff00" - } -} + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaDarkFusion", + ["default scheme"] = "VS Code", + ["default iconset"] = "contrast", + ["palette"] = { + PaletteWindow = "#19232D", + PaletteWindowText = "#E0E1E3", + PaletteBase = "#1E1E1E", + PaletteAlternateBase = "#303030", + PaletteButton = "#19232D", + PaletteButtonDisabled = "#19232D", + PaletteBrightText = "#ff0000", + PaletteText = "#e7e7e7", + PaletteButtonText = "#d3d3d3", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#333333", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#26486B", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#19232D", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#707070", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + }, + } +end diff --git a/RedPandaIDE/themes/default.lua b/RedPandaIDE/themes/default.lua index 58452229..155735b9 100644 --- a/RedPandaIDE/themes/default.lua +++ b/RedPandaIDE/themes/default.lua @@ -1,41 +1,51 @@ +function apiVersion() + return { + kind = "theme", + major = 0, + minor = 1, + } +end + local nameMap = { - en_US = "Light", - pt_BR = "Clara", - zh_CN = "浅色", - zh_TW = "淺色" + en_US = "Light", + pt_BR = "Clara", + zh_CN = "浅色", + zh_TW = "淺色", } -local lang = C_Desktop.language() +function main() + local lang = C_Desktop.language() -return { - ["name"] = nameMap[lang] or nameMap.en_US, - ["style"] = "RedPandaLightFusion", - ["default scheme"] = "Intellij Classic", - ["default iconset"] = "newlook", - ["palette"] = { - PaletteWindow = "#efefef", - PaletteWindowText = "#000000", - PaletteBase = "#ffffff", - PaletteAlternateBase = "#f7f7f7", - PaletteToolTipBase = "#ffffdc", - PaletteToolTipText = "#000000", - PaletteText = "#000000", - PaletteButton = "#efefef", - PaletteButtonText = "#000000", - PaletteBrightText = "#ffffff", - PaletteLink = "#0000ff", - PaletteLinkVisited = "#ff00ff", - PaletteLight = "#ffffff", - PaletteMidLight = "#cacaca", - PaletteDark = "#9f9f9f", - PaletteMid = "#b8b8b8", - PaletteWindowDisabled = "#efefef", - PaletteWindowTextDisabled = "#bebebe", - PaletteBaseDisabled = "#efefef", - PaletteTextDisabled = "#bebebe", - PaletteButtonDisabled = "#efefef", - PaletteButtonTextDisabled = "#bebebe", - PaletteHighlight = "#dddddd", - PaletteHighlightedText = "#000000" - } -} + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaLightFusion", + ["default scheme"] = "Intellij Classic", + ["default iconset"] = "newlook", + ["palette"] = { + PaletteWindow = "#efefef", + PaletteWindowText = "#000000", + PaletteBase = "#ffffff", + PaletteAlternateBase = "#f7f7f7", + PaletteToolTipBase = "#ffffdc", + PaletteToolTipText = "#000000", + PaletteText = "#000000", + PaletteButton = "#efefef", + PaletteButtonText = "#000000", + PaletteBrightText = "#ffffff", + PaletteLink = "#0000ff", + PaletteLinkVisited = "#ff00ff", + PaletteLight = "#ffffff", + PaletteMidlight = "#cacaca", + PaletteDark = "#9f9f9f", + PaletteMid = "#b8b8b8", + PaletteWindowDisabled = "#efefef", + PaletteWindowTextDisabled = "#bebebe", + PaletteBaseDisabled = "#efefef", + PaletteTextDisabled = "#bebebe", + PaletteButtonDisabled = "#efefef", + PaletteButtonTextDisabled = "#bebebe", + PaletteHighlight = "#dddddd", + PaletteHighlightedText = "#000000", + }, + } +end diff --git a/RedPandaIDE/themes/molo.lua b/RedPandaIDE/themes/molo.lua index 9e5e0fef..3c31f23c 100644 --- a/RedPandaIDE/themes/molo.lua +++ b/RedPandaIDE/themes/molo.lua @@ -1,43 +1,53 @@ +function apiVersion() + return { + kind = "theme", + major = 0, + minor = 1, + } +end + local nameMap = { - en_US = "MoLo", - pt_BR = "Molo", - zh_CN = "墨落", - zh_TW = "墨落" + en_US = "MoLo", + pt_BR = "Molo", + zh_CN = "墨落", + zh_TW = "墨落", } -local lang = C_Desktop.language() +function main() + local lang = C_Desktop.language() -return { - ["name"] = nameMap[lang] or nameMap.en_US, - ["style"] = "RedPandaDarkFusion", - ["default scheme"] = "MoLo CodeBlack", - ["default iconset"] = "newlook", - ["palette"] = { - PaletteWindow = "#000000", - PaletteWindowText = "#FFFFFF", - PaletteBase = "#141414", - PaletteAlternateBase = "#191919", - PaletteButton = "#141414", - PaletteButtonDisabled = "#141414", - PaletteBrightText = "#ff0000", - PaletteText = "#FFFFFF", - PaletteButtonText = "#FFFFFF", - PaletteButtonTextDisabled = "#9DA9B5", - PaletteHighlight = "#aa1f75cc", - PaletteDark = "#232323", - PaletteHighlightedText = "#e7e7e7", - PaletteToolTipBase = "#66000000", - PaletteToolTipText = "#e7e7e7", - PaletteLink = "#007af4", - PaletteLinkVisited = "#a57aff", - PaletteWindowDisabled = "#0A0A0A", - PaletteWindowTextDisabled = "#9DA9B5", - PaletteHighlightDisabled = "#9DA9B5", - PaletteHighlightedTextDisabled = "#9DA9B5", - PaletteBaseDisabled = "#000000", - PaletteTextDisabled = "#9DA9B5", - PaletteMid = "#FFFFFF", - PaletteLight = "#505050", - PaletteMidLight = "#00ff00" - } -} + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaDarkFusion", + ["default scheme"] = "MoLo CodeBlack", + ["default iconset"] = "newlook", + ["palette"] = { + PaletteWindow = "#000000", + PaletteWindowText = "#FFFFFF", + PaletteBase = "#141414", + PaletteAlternateBase = "#191919", + PaletteButton = "#141414", + PaletteButtonDisabled = "#141414", + PaletteBrightText = "#ff0000", + PaletteText = "#FFFFFF", + PaletteButtonText = "#FFFFFF", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#0A0A0A", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#9DA9B5", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#000000", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#FFFFFF", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + }, + } +end diff --git a/RedPandaIDE/themes/random_light.lua b/RedPandaIDE/themes/random_light.lua index 34229dc7..1796d4f6 100644 --- a/RedPandaIDE/themes/random_light.lua +++ b/RedPandaIDE/themes/random_light.lua @@ -1,102 +1,132 @@ -function rgbFromString(color) - local r, g, b = color:match("#(%x%x)(%x%x)(%x%x)") - return {tonumber(r, 16) / 255, tonumber(g, 16) / 255, tonumber(b, 16) / 255} +function apiVersion() + return { + kind = "theme", + major = 0, + minor = 1, + } end -function rgbToString(rgb) - return string.format("#%02x%02x%02x", - math.floor(rgb[1] * 255), math.floor(rgb[2] * 255), math.floor(rgb[3] * 255) - ) + + + + + + + + + + + + +local function rgbFromString(color) + local r, g, b = color:match("#(%x%x)(%x%x)(%x%x)") + return { + r = tonumber(r, 16) / 255, + g = tonumber(g, 16) / 255, + b = tonumber(b, 16) / 255, + } end -function hsvToRgb(h, s, v) - local r, g, b - local i = math.floor(h * 6) - local f = h * 6 - i - local p = v * (1 - s) - local q = v * (1 - f * s) - local t = v * (1 - (1 - f) * s) - i = i % 6 - if i == 0 then - r, g, b = v, t, p - elseif i == 1 then - r, g, b = q, v, p - elseif i == 2 then - r, g, b = p, v, t - elseif i == 3 then - r, g, b = p, q, v - elseif i == 4 then - r, g, b = t, p, v - elseif i == 5 then - r, g, b = v, p, q - end - return {r, g, b} +local function rgbToString(rgb) + return string.format( + "#%02x%02x%02x", + math.floor(rgb.r * 255), + math.floor(rgb.g * 255), + math.floor(rgb.b * 255)) + end -function blend(lower, upper, alpha) - local r = (1 - alpha) * lower[1] + alpha * upper[1] - local g = (1 - alpha) * lower[2] + alpha * upper[2] - local b = (1 - alpha) * lower[3] + alpha * upper[3] - return {r, g, b} +local function hsvToRgb(hsv) + local r, g, b + local h, s, v = hsv.h, hsv.s, hsv.v + local i = math.floor(h * 6) + local f = h * 6 - i + local p = v * (1 - s) + local q = v * (1 - f * s) + local t = v * (1 - (1 - f) * s) + i = i % 6 + if i == 0 then + r, g, b = v, t, p + elseif i == 1 then + r, g, b = q, v, p + elseif i == 2 then + r, g, b = p, v, t + elseif i == 3 then + r, g, b = p, q, v + elseif i == 4 then + r, g, b = t, p, v + elseif i == 5 then + r, g, b = v, p, q + end + return { r = r, g = g, b = b } end -local hue = math.random() -local upperColor = hsvToRgb(hue, 0.6, 1) - -function transform(color) - local lowerColor = rgbFromString(color) - local blended = blend(lowerColor, upperColor, 0.1) - return rgbToString(blended) +local function blend(lower, upper, alpha) + local r = (1 - alpha) * lower.r + alpha * upper.r + local g = (1 - alpha) * lower.g + alpha * upper.g + local b = (1 - alpha) * lower.b + alpha * upper.b + return { r = r, g = g, b = b } end -function transformPalette(palette) - local transformed = {} - for key, value in pairs(palette) do - transformed[key] = transform(value) - end - return transformed +local function transform(color, upperColor) + local lowerColor = rgbFromString(color) + local blended = blend(lowerColor, upperColor, 0.1) + return rgbToString(blended) +end + +local function transformPalette(palette, upperColor) + local transformed = {} + for key, value in pairs(palette) do + transformed[key] = transform(value, upperColor) + end + return transformed end local originalPalette = { - PaletteWindow = "#efefef", - PaletteWindowText = "#000000", - PaletteBase = "#ffffff", - PaletteAlternateBase = "#f7f7f7", - PaletteToolTipBase = "#ffffdc", - PaletteToolTipText = "#000000", - PaletteText = "#000000", - PaletteButton = "#efefef", - PaletteButtonText = "#000000", - PaletteBrightText = "#ffffff", - PaletteLink = "#0000ff", - PaletteLinkVisited = "#ff00ff", - PaletteLight = "#ffffff", - PaletteMidLight = "#cacaca", - PaletteDark = "#9f9f9f", - PaletteMid = "#b8b8b8", - PaletteWindowDisabled = "#efefef", - PaletteWindowTextDisabled = "#bebebe", - PaletteBaseDisabled = "#efefef", - PaletteTextDisabled = "#bebebe", - PaletteButtonDisabled = "#efefef", - PaletteButtonTextDisabled = "#bebebe", - PaletteHighlight = "#dddddd", - PaletteHighlightedText = "#000000" + PaletteWindow = "#efefef", + PaletteWindowText = "#000000", + PaletteBase = "#ffffff", + PaletteAlternateBase = "#f7f7f7", + PaletteToolTipBase = "#ffffdc", + PaletteToolTipText = "#000000", + PaletteText = "#000000", + PaletteButton = "#efefef", + PaletteButtonText = "#000000", + PaletteBrightText = "#ffffff", + PaletteLink = "#0000ff", + PaletteLinkVisited = "#ff00ff", + PaletteLight = "#ffffff", + PaletteMidlight = "#cacaca", + PaletteDark = "#9f9f9f", + PaletteMid = "#b8b8b8", + PaletteWindowDisabled = "#efefef", + PaletteWindowTextDisabled = "#bebebe", + PaletteBaseDisabled = "#efefef", + PaletteTextDisabled = "#bebebe", + PaletteButtonDisabled = "#efefef", + PaletteButtonTextDisabled = "#bebebe", + PaletteHighlight = "#dddddd", + PaletteHighlightedText = "#000000", } local nameMap = { - en_US = "Random Light", - pt_BR = "Clara aleatória", - zh_CN = "随机浅色", - zh_TW = "隨機淺色" + en_US = "Random Light", + pt_BR = "Clara aleatória", + zh_CN = "随机浅色", + zh_TW = "隨機淺色", } -local lang = C_Desktop.language() +function main() + local hue = math.random() + local upperColor = hsvToRgb({ h = hue, s = 0.6, v = 1 }) -return { - ["name"] = nameMap[lang] or nameMap.en_US, - ["style"] = "RedPandaLightFusion", - ["default scheme"] = "Adaptive", - ["default iconset"] = "newlook", - ["palette"] = transformPalette(originalPalette) -} + local lang = C_Desktop.language() + + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaLightFusion", + ["default scheme"] = "Adaptive", + ["default iconset"] = "newlook", + ["palette"] = transformPalette(originalPalette, upperColor), + } +end diff --git a/RedPandaIDE/themes/system.lua b/RedPandaIDE/themes/system.lua index 2fd0173c..ea661869 100644 --- a/RedPandaIDE/themes/system.lua +++ b/RedPandaIDE/themes/system.lua @@ -1,26 +1,49 @@ -local desktopEnvironment = C_Desktop.desktopEnvironment() -local useSystemStyle = desktopEnvironment == "xdg" or desktopEnvironment == "macos" - -local systemAppMode = C_Desktop.systemAppMode() -local isDarkMode = systemAppMode == "dark" - -function getStyle() - if useSystemStyle then - return C_Desktop.systemStyle() - else - if isDarkMode then - return "RedPandaDarkFusion" - else - return "RedPandaLightFusion" - end - end +function apiVersion() + return { + kind = "theme", + major = 0, + minor = 1, + } end -function getPalette() - if useSystemStyle then - return {} - elseif isDarkMode then - return { -- palette from `dark.lua` +local nameMap = { + en_US = "System Style and Color", + pt_BR = "Estilo e Cor do Sistema", + zh_CN = "跟随系统样式和颜色", + zh_TW = "跟隨系統樣式和顏色", +} + +local nameMapNoStyle = { + en_US = "System Color", + pt_BR = "Cor do Sistema", + zh_CN = "跟随系统颜色", + zh_TW = "跟隨系統顏色", +} + +function main() + local desktopEnvironment = C_Desktop.desktopEnvironment() + local useSystemStyle = desktopEnvironment == "xdg" or desktopEnvironment == "macos" + + local systemAppMode = C_Desktop.systemAppMode() + local isDarkMode = systemAppMode == "dark" + + local function getStyle() + if useSystemStyle then + return C_Desktop.systemStyle() + else + if isDarkMode then + return "RedPandaDarkFusion" + else + return "RedPandaLightFusion" + end + end + end + + local function getPalette() + if useSystemStyle then + return {} + elseif isDarkMode then + return { PaletteWindow = "#19232D", PaletteWindowText = "#E0E1E3", PaletteBase = "#1E1E1E", @@ -46,10 +69,10 @@ function getPalette() PaletteTextDisabled = "#9DA9B5", PaletteMid = "#707070", PaletteLight = "#505050", - PaletteMidLight = "#00ff00" - } - else - return { -- palette from `default.lua` + PaletteMidlight = "#00ff00", + } + else + return { PaletteWindow = "#efefef", PaletteWindowText = "#000000", PaletteBase = "#ffffff", @@ -63,7 +86,7 @@ function getPalette() PaletteLink = "#0000ff", PaletteLinkVisited = "#ff00ff", PaletteLight = "#ffffff", - PaletteMidLight = "#cacaca", + PaletteMidlight = "#cacaca", PaletteDark = "#9f9f9f", PaletteMid = "#b8b8b8", PaletteWindowDisabled = "#efefef", @@ -73,31 +96,18 @@ function getPalette() PaletteButtonDisabled = "#efefef", PaletteButtonTextDisabled = "#bebebe", PaletteHighlight = "#dddddd", - PaletteHighlightedText = "#000000" - } - end + PaletteHighlightedText = "#000000", + } + end + end + + local lang = C_Desktop.language() + + return { + ["name"] = useSystemStyle and (nameMap[lang] or nameMap.en_US) or (nameMapNoStyle[lang] or nameMapNoStyle.en_US), + ["style"] = getStyle(), + ["default scheme"] = "Adaptive", + ["default iconset"] = "newlook", + ["palette"] = getPalette(), + } end - -local nameMap = { - en_US = "System Style and Color", - pt_BR = "Estilo e Cor do Sistema", - zh_CN = "跟随系统样式和颜色", - zh_TW = "跟隨系統樣式和顏色" -} - -local nameMapNoStyle = { - en_US = "System Color", - pt_BR = "Cor do Sistema", - zh_CN = "跟随系统颜色", - zh_TW = "跟隨系統顏色" -} - -local lang = C_Desktop.language() - -return { - ["name"] = useSystemStyle and (nameMap[lang] or nameMap.en_US) or (nameMapNoStyle[lang] or nameMapNoStyle.en_US), - ["style"] = getStyle(), - ["default scheme"] = "Adaptive", - ["default iconset"] = "newlook", - ["palette"] = getPalette() -} diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index c4a20cce..b59607d6 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -7110,6 +7110,10 @@ Failed to detect terminal arguments pattern for “%1”. + + Error executing platform compiler hint add-on + + RegisterModel diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index 300038ea..783ab04d 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -9679,6 +9679,10 @@ p, li { white-space: pre-wrap; } Failed to detect terminal arguments pattern for “%1”. 无法检测适用于 “%1” 的终端参数模式。 + + Error executing platform compiler hint add-on + 执行平台编译器提示附加组件错误 + RegisterModel diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index c1d05c7b..ab815827 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -6622,6 +6622,10 @@ Failed to detect terminal arguments pattern for “%1”. + + Error executing platform compiler hint add-on + + RegisterModel diff --git a/RedPandaIDE/utils.h b/RedPandaIDE/utils.h index 80f51d06..bd13564c 100644 --- a/RedPandaIDE/utils.h +++ b/RedPandaIDE/utils.h @@ -176,4 +176,8 @@ QString defaultShell(); QString appArch(); QString osArch(); +#ifdef _MSC_VER +#define __builtin_unreachable() (__assume(0)) +#endif + #endif // UTILS_H diff --git a/addon/compiler_hint/archlinux.tl b/addon/compiler_hint/archlinux.tl new file mode 100644 index 00000000..94518103 --- /dev/null +++ b/addon/compiler_hint/archlinux.tl @@ -0,0 +1,313 @@ +global function apiVersion(): ApiVersion + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end + +local nameMap: {string:{string:string}} = { + systemGcc = { + en_US = "System GCC", + pt_BR = "GCC do sistema", + zh_CN = "系统 GCC", + zh_TW = "系統 GCC", + }, + systemClang = { + en_US = "System Clang", + pt_BR = "Clang do sistema", + zh_CN = "系统 Clang", + zh_TW = "系統 Clang", + }, + multilibGcc = { + en_US = "Multilib GCC", + pt_BR = "GCC multilib", + zh_CN = "Multilib GCC", + zh_TW = "Multilib GCC", + }, + multilibClang = { + en_US = "Multilib Clang", + pt_BR = "Clang multilib", + zh_CN = "Multilib Clang", + zh_TW = "Multilib Clang", + }, + crossGcc = { + en_US = "Cross GCC", + pt_BR = "GCC cruzado", + zh_CN = "交叉编译 GCC", + zh_TW = "交叉編譯 GCC", + }, + mingwGcc = { + en_US = "MinGW GCC", + pt_BR = "GCC MinGW", + zh_CN = "MinGW GCC", + zh_TW = "MinGW GCC", + }, + mingwClang = { + en_US = "MinGW Clang", + pt_BR = "Clang MinGW", + zh_CN = "MinGW Clang", + zh_TW = "MinGW Clang", + }, + release = { + en_US = ", release", + pt_BR = ", lançamento", + zh_CN = ",发布", + zh_TW = ",發佈", + }, + debug = { + en_US = ", debug", + pt_BR = ", depuração", + zh_CN = ",调试", + zh_TW = ",偵錯", + }, + debugWithAsan = { + en_US = ", debug with ASan", + pt_BR = ", depuração com ASan", + zh_CN = ",ASan 调试", + zh_TW = ",ASan 偵錯", + }, +} + +local function mergeCompilerSet(compilerSet: CompilerHint.CompilerSet, other: CompilerHint.CompilerSet) + local c = compilerSet as {string:any} + local o = other as {string:any} + for k, v in pairs(o) do + c[k] = v + end +end + +local record Config + isMultilib: boolean | nil + isMingw: boolean | nil + isClang: boolean | nil + customCompileParams: {string} | nil + customLinkParams: {string} | nil + triplet: string | nil +end + +local function generateConfig( + name: string, lang: string, + cCompiler: string, cxxCompiler: string, + config: Config +): CompilerHint.CompilerSet, CompilerHint.CompilerSet, CompilerHint.CompilerSet + local commonOptions: CompilerHint.CompilerSet = { + cCompiler = cCompiler, + cxxCompiler = cxxCompiler, + debugger = "/usr/bin/gdb", + debugServer = "/usr/bin/gdbserver", + make = "/usr/bin/make", + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = config.isMingw and ".exe" or "", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + binDirs = {"/usr/bin"}, + } + if config.isMultilib then + commonOptions.ccCmdOptPointerSize = "32" + end + if config.isMingw then + commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = name .. (nameMap.release[lang] or nameMap.release.en_US), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +global function main(): CompilerHint + local arch = C_System.osArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + + local compilerList = {} + + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemClang[lang] or nameMap.systemClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + {isClang = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + -- with lib32-gcc-libs installed, system GCC and Clang can target 32-bit + if arch == "x86_64" and C_FileSystem.isExecutable("/usr/lib32/libstdc++.so") then + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {isMultilib = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + {isClang = true, isMultilib = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + end + + -- cross GCC + if ( + arch == "x86_64" and + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/qemu-aarch64") and + C_FileSystem.isExecutable("/usr/bin/aarch64-linux-gnu-gcc") + ) then + local release, _, _ = generateConfig( + (nameMap.crossGcc[lang] or nameMap.crossGcc.en_US) .. " aarch64", lang, + "/usr/bin/aarch64-linux-gnu-gcc", "/usr/bin/aarch64-linux-gnu-g++", + {} + ) + table.insert(compilerList, release) + end + + -- with wine or WSL init registered in binfmt_misc, Windows binaries can run seamlessly + if ( + arch == "x86_64" and ( + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop") + ) + ) then + if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/x86_64-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/x86_64-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", lang, + "/usr/bin/x86_64-w64-mingw32-gcc", "/usr/bin/x86_64-w64-mingw32-g++", + { + isMingw = true, + triplet = "x86_64-w64-mingw32", + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + end + + -- system Clang can target Windows + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, _, _ = generateConfig( + (nameMap.mingwClang[lang] or nameMap.mingwClang.en_US) .. " x86_64", lang, + "/usr/bin/clang", "/usr/bin/clang++", + { + isClang = true, + isMingw = true, + triplet = "x86_64-w64-mingw32", + customCompileParams = {"-target", "x86_64-w64-mingw32"}, + customLinkParams = { + "-target", "x86_64-w64-mingw32", + extraObjects.utf8init, extraObjects.utf8manifest, + "-lstdc++", "-lwinpthread", + }, + } + ) + table.insert(compilerList, release) + end + end + + if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/i686-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/i686-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", lang, + "/usr/bin/i686-w64-mingw32-gcc", "/usr/bin/i686-w64-mingw32-g++", + { + isMingw = true, + triplet = "i686-w64-mingw32", + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + end + + -- system Clang can target Windows + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, _, _ = generateConfig( + (nameMap.mingwClang[lang] or nameMap.mingwClang.en_US) .. " i686", lang, + "/usr/bin/clang", "/usr/bin/clang++", + { + isClang = true, + isMingw = true, + triplet = "i686-w64-mingw32", + customCompileParams = {"-target", "i686-w64-mingw32"}, + customLinkParams = { + "-target", "i686-w64-mingw32", + extraObjects.utf8init, extraObjects.utf8manifest, + "-lstdc++", "-lwinpthread", + }, + } + ) + table.insert(compilerList, release) + end + end + end + + local result = { + compilerList = compilerList, + noSearch = { + "/usr/bin", + "/opt/cuda/bin", + "/usr/lib/ccache/bin", + }, + preferCompiler = 3, -- System GCC Debug with ASan + } + + return result + +end diff --git a/addon/compiler_hint/windows_domain.tl b/addon/compiler_hint/windows_domain.tl new file mode 100644 index 00000000..9c818414 --- /dev/null +++ b/addon/compiler_hint/windows_domain.tl @@ -0,0 +1,430 @@ +global function apiVersion(): ApiVersion + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end + +local gnuArchMap: {string:string} = { + i386 = "i686", + x86_64 = "x86_64", + arm = "armv7", + arm64 = "aarch64", +} + +local profileNameMap: {string:{string:string}} = { + release = { + en_US = "release", + pt_BR = "lançamento", + zh_CN = "发布", + zh_TW = "發佈", + }, + debug = { + en_US = "debug", + pt_BR = "depuração", + zh_CN = "调试", + zh_TW = "偵錯", + }, + debugWithAsan = { + en_US = "debug with ASan", + pt_BR = "depuração com ASan", + zh_CN = "ASan 调试", + zh_TW = "ASan 偵錯", + }, +} + +local function nameGeneratorMingwGcc(lang: string, arch: string, profile: string, isUtf8: boolean): string + local template: {string:string} = { + en_US = "MinGW GCC %1 in %2, %3", + pt_BR = "GCC MinGW %1 em %2, %3", + zh_CN = "%2 MinGW GCC %1,%3", + zh_TW = "%2 MinGW GCC %1,%3", + } + local systemCodePage: {string:string} = { + en_US = "system code page", + pt_Br = "página de código do sistema", + zh_CN = "系统代码页", + zh_TW = "系統代碼頁", + } + return C_Util.format( + template[lang] or template.en_US, + gnuArchMap[arch], + isUtf8 and "UTF-8" or systemCodePage[lang] or systemCodePage.en_US, + profileNameMap[profile][lang] or profileNameMap[profile].en_US + ) +end + +local function nameGeneratorClang(lang: string, arch: string, profile: string, isMingw: boolean): string + local template: {string:string} = { + en_US = "%1 Clang %2, %3", + pt_BR = "Clang %2 %1, %3", + zh_CN = "%1 Clang %2,%3", + zh_TW = "%1 Clang %2,%3", + } + local msvcCompatible: {string:string} = { + en_US = "MSVC-compatible", + pt_BR = "compatível com MSVC", + zh_CN = "兼容 MSVC 的", + zh_TW = "相容 MSVC 的", + } + return C_Util.format( + template[lang] or template.en_US, + isMingw and "LLVM-MinGW" or msvcCompatible[lang] or msvcCompatible.en_US, + gnuArchMap[arch], + profileNameMap[profile][lang] or profileNameMap[profile].en_US + ) +end + +local function mergeCompilerSet(compilerSet: CompilerHint.CompilerSet, other: CompilerHint.CompilerSet) + local c = compilerSet as {string:any} + local o = other as {string:any} + for k, v in pairs(o) do + c[k] = v + end +end + +local record Programs + cCompiler: string + cxxCompiler: string + make: string + debugger: string + debugServer: string + resourceCompiler: string + binDirs: {string} + libDirs: {string} | nil +end + +local record Config + arch: string + isAnsi: boolean | nil + isClang: boolean | nil + customCompileParams: {string} | nil + customLinkParams: {string} | nil +end + +local function generateConfig( + nameGen: (function (arch: string, profile: string): string), + programs: Programs, + config: Config +): CompilerHint.CompilerSet, CompilerHint.CompilerSet, CompilerHint.CompilerSet + local commonOptions : CompilerHint.CompilerSet = { + cCompiler = programs.cCompiler, + cxxCompiler = programs.cxxCompiler, + debugger = programs.debugger, + debugServer = programs.debugServer, + make = programs.make, + resourceCompiler = programs.resourceCompiler, + binDirs = programs.binDirs, + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = ".exe", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + } + if programs.libDirs then + commonOptions.libDirs = programs.libDirs + end + if config.isAnsi then + commonOptions.execCharset = "SYSTEM" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release: CompilerHint.CompilerSet = { + name = nameGen(config.arch, "release"), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_: CompilerHint.CompilerSet = { + name = nameGen(config.arch, "debug"), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan: CompilerHint.CompilerSet = { + name = nameGen(config.arch, "debugWithAsan"), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +global function main(): CompilerHint + local appArch = C_System.appArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + local supportedAppArches = C_System.supportedAppArchList() + + local compilerList = {} + local noSearch = {} + local preferCompiler = 0 + + local function checkAndAddMingw(arch: string) + local binDir: string + local libDir: string + local excludeBinDir: string + if arch == "i386" then + binDir = libexecDir .. "/mingw32/bin" -- must match case because Windows filesystem can be case sensitive + libDir = libexecDir .. "/mingw32/i686-w64-mingw32/lib" + excludeBinDir = libexecDir .. "/MinGW32/bin" -- workaround for path check + elseif arch == "x86_64" then + binDir = libexecDir .. "/mingw64/bin" + libDir = libexecDir .. "/mingw64/x86_64-w64-mingw32/lib" + excludeBinDir = libexecDir .. "/MinGW64/bin" + else + return + end + + if not C_FileSystem.isExecutable(binDir .. "/gcc.exe") then + return + end + + local programs: Programs = { + cCompiler = binDir .. "/gcc.exe", + cxxCompiler = binDir .. "/g++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/gdb.exe", + debugServer = binDir .. "/gdbserver.exe", + resourceCompiler = binDir .. "/windres.exe", + binDirs = {binDir}, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + + local release, debug_, debugWithAsan = generateConfig( + function (arch_: string, profile: string): string + return nameGeneratorMingwGcc(lang, arch_, profile, true) + end, + programs, + { + arch = arch, + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if preferCompiler == 0 then + preferCompiler = 2 + end + + release, debug_, debugWithAsan = generateConfig( + function (arch_: string, profile: string): string + return nameGeneratorMingwGcc(lang, arch_, profile, false) + end, + programs, + { + arch = arch, + isAnsi = true, + } + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + + table.insert(noSearch, excludeBinDir) + end + + local function checkAndAddClang() + if not C_FileSystem.isExecutable(libexecDir .. "/llvm-mingw/bin/clang.exe") then + return + end + + local binDir = libexecDir .. "/llvm-mingw/bin" + local appTriplet = gnuArchMap[appArch] .. "-w64-mingw32" + do + -- appArch is always debuggable + local libDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/lib" + local programs: Programs = { + cCompiler = binDir .. "/" .. appTriplet .. "-clang.exe", + cxxCompiler = binDir .. "/" .. appTriplet .. "-clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", + binDirs = {binDir}, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + local release, debug_, debugWithAsan = generateConfig( + function (arch_: string, profile: string): string + return nameGeneratorClang(lang, arch_, profile, true) + end, + programs, + { + arch = appArch, + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + isClang = true, + } + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if appArch ~= "arm64" then + table.insert(compilerList, debugWithAsan) + if preferCompiler == 0 then + preferCompiler = 3 + end + else + if preferCompiler == 0 then + preferCompiler = 2 + end + end + end + + for _, foreignArch in ipairs(supportedAppArches) do + if foreignArch ~= appArch then + local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" + local libDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/lib" + local programs: Programs = { + cCompiler = binDir .. "/" .. foreignTriplet .. "-clang.exe", + cxxCompiler = binDir .. "/" .. foreignTriplet .. "-clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", + binDirs = {binDir}, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + local release, _, _ = generateConfig( + function (arch_: string, profile: string): string + return nameGeneratorClang(lang, arch_, profile, true) + end, + programs, + { + arch = foreignArch, + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + isClang = true, + } + ) + table.insert(compilerList, release) + end + end + + table.insert(noSearch, binDir) + + local llvmOrgPath = C_System.readRegistry([[Software\LLVM\LLVM]], "") or C_System.readRegistry([[Software\Wow6432Node\LLVM\LLVM]], "") + if not llvmOrgPath then + return + end + local llvmOrgBinDir = llvmOrgPath .. "/bin" + + do + local msvcTriplet = gnuArchMap[appArch] .. "-pc-windows-msvc" + local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" + local programs: Programs = { + cCompiler = llvmOrgBinDir .. "/clang.exe", + cxxCompiler = llvmOrgBinDir .. "/clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", + binDirs = {llvmOrgBinDir}, + libDirs = {libDir}, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + local release, debug_, _ = generateConfig( + function (arch: string, profile: string): string + return nameGeneratorClang(lang, arch, profile, false) + end, + programs, + { + arch = appArch, + customCompileParams = { + "-target", msvcTriplet, + "-fms-extensions", + "-fms-compatibility", + "-fdelayed-template-parsing", + }, + customLinkParams = { + "-target", msvcTriplet, + extraObjects.utf8init, extraObjects.utf8manifest, + }, + isClang = true, + } + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + end + + for _, foreignArch in ipairs(supportedAppArches) do + if foreignArch ~= appArch then + local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" + local msvcTriplet = gnuArchMap[foreignArch] .. "-pc-windows-msvc" + local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" + local programs: Programs = { + cCompiler = llvmOrgBinDir .. "/clang.exe", + cxxCompiler = llvmOrgBinDir .. "/clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", + binDirs = {llvmOrgBinDir}, + libDirs = {libDir}, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + local release, _, _ = generateConfig( + function (arch: string, profile: string): string + return nameGeneratorClang(lang, arch, profile, false) + end, + programs, + { + arch = foreignArch, + customCompileParams = { + "-target", msvcTriplet, + "-fms-extensions", + "-fms-compatibility", + "-fdelayed-template-parsing", + }, + customLinkParams = { + "-target", msvcTriplet, + extraObjects.utf8init, extraObjects.utf8manifest, + }, + isClang = true, + } + ) + table.insert(compilerList, release) + end + end + table.insert(noSearch, llvmOrgBinDir) + end + + if appArch == "x86_64" then + checkAndAddMingw("x86_64") + checkAndAddClang() + elseif appArch == "arm64" then + checkAndAddClang() + else + checkAndAddMingw("i386") + checkAndAddClang() + end + + local result = { + compilerList = compilerList, + noSearch = noSearch, + preferCompiler = preferCompiler, + } + + return result +end diff --git a/addon/defs/compiler_hint.d.tl b/addon/defs/compiler_hint.d.tl new file mode 100644 index 00000000..09102e0b --- /dev/null +++ b/addon/defs/compiler_hint.d.tl @@ -0,0 +1,107 @@ +local env = require("defs.global_env") + +global C_Debug = env.C_Debug +global C_Desktop = env.C_Desktop +global C_FileSystem = env.C_FileSystem +global C_System = env.C_System +global C_Util = env.C_Util + +global record CompilerHint + -- found compiler sets + compilerList: {CompilerSet} + + -- do not search in these directories anymore + noSearch: {string} + + -- prefer compiler set index (in Lua, 1-based) in compilerList + -- 0 for no preference + preferCompiler: integer + + record CompilerSet + name: string + + -- internal + + -- e.g. "x86_64-linux-gnu", "x86_64-w64-mingw32" + dumpMachine: string + -- e.g. "13.2.1", "17.0.6" + version: string + -- e.g. "TDM-GCC", "MinGW" + type: string + -- e.g. "x86_64", "aarch64" + target: string + compilerType: CompilerType + + -- general + + staticLink: boolean + -- automatically sets useCustomCompileParams + customCompileParams: {string} + -- automatically sets useCustomLinkParams + customLinkParams: {string} + -- automatically sets autoAddCharsetParams + execCharset: string + + -- setting: code generation + + ccCmdOptOptimize: string + ccCmdOptStd: string + cCmdOptStd: string + ccCmdOptInstruction: string + ccCmdOptPointerSize: string + ccCmdOptDebugInfo: string + ccCmdOptProfileInfo: string + ccCmdOptSyntaxOnly: string + + -- setting: warnings + + ccCmdOptInhibitAllWarning: string + ccCmdOptWarningAll: string + ccCmdOptWarningExtra: string + ccCmdOptCheckIsoConformance: string + ccCmdOptWarningAsError: string + ccCmdOptAbortOnError: string + ccCmdOptStackProtector: string + ccCmdOptAddressSanitizer: string + + -- setting: linker + + ccCmdOptUsePipe: string + linkCmdOptNoLinkStdlib: string + linkCmdOptNoConsole: string + linkCmdOptStripExe: string + + -- directory + + binDirs: {string} + cIncludeDirs: {string} + cxxIncludeDirs: {string} + libDirs: {string} + defaultLibDirs: {string} + defaultCIncludeDirs: {string} + defaultCxxIncludeDirs: {string} + + -- program + + cCompiler: string + cxxCompiler: string + make: string + debugger: string + debugServer: string + resourceCompiler: string + + -- output + + preprocessingSuffix: string + compilationProperSuffix: string + assemblingSuffix: string + executableSuffix: string + compilationStage: integer + + enum CompilerType + "GCC" + "GCC_UTF8" + "Clang" + end + end +end diff --git a/addon/defs/global_env.d.tl b/addon/defs/global_env.d.tl new file mode 100644 index 00000000..aa47edff --- /dev/null +++ b/addon/defs/global_env.d.tl @@ -0,0 +1,100 @@ +global record ApiVersion + kind: Kind + major: integer + minor: integer + + enum Kind + "theme" + "compiler_hint" + end +end + +local record env + record C_Debug + -- print message to console, with Qt-style string format + debug: function (format: string, ...: any): nil + + -- show message box, with Qt-style string format + messageBox: function (format: string, ...: any): nil + end + + record C_Desktop + -- return desktoop environment name + desktopEnvironment: function (): DesktopEnvironment + + -- return language code, e.g. "en_US", "zh_CN" + language: function (): string + + -- return available Qt styles, e.g. {"breeze", "fusion", "windows"} + qtStyleList: function (): {string} + + -- return system app mode, light or dark + systemAppMode: function (): AppMode + + -- return default Qt style, e.g. "fusion" + systemStyle: function (): string + + enum DesktopEnvironment + "windows" -- Windows Win32 + "macos" -- macOS + "xdg" -- XDG-compliant desktop environment (e.g. GNOME, KDE Plasma) + "unknown" -- other desktops or non-desktop environments (e.g. Windows UWP, Android) + end + + enum AppMode + "light" + "dark" + end + end + + record C_FileSystem + -- return whether the path exists + exists: function (path: string): boolean + + -- return whether the path is executable + isExecutable: function (path: string): boolean + end + + record C_System + -- returns the architecture of Red Panda C++, name following `QSysInfo` + -- e.g. "i386", "x86_64", "arm", "arm64", "riscv64", "loongarch64" + -- though unsupported, MSVC arm64ec is handled correctly (returns "arm64ec") + appArch: function (): string + + -- returns the directory of Red Panda C++ + -- e.g. "/usr/bin", "C:/Program Files/RedPanda-Cpp", "C:/Users/中文/AppData/Local/RedPanda-CPP" + appDir: function (): string + + -- returns the libexec directory of Red Panda C++ + -- e.g. "/usr/libexec/RedPandaCPP", "C:/Program Files/RedPanda-Cpp" + appLibexecDir: function (): string + + -- returns the resource directory of Red Panda C++ + -- e.g. "/usr/share/RedPandaCPP", "C:/Program Files/RedPanda-Cpp" + appResourceDir: function (): string + + -- returns the architecture of the OS, name following `QSysInfo` + -- e.g. "i386", "x86_64", "arm", "arm64" + -- Windows arm64 is handled correctly even if Red Panda C++ runs under emulation + osArch: function (): string + + -- returns supported application architectures by OS, name following `QSysInfo` + -- e.g. {"i386", "x86_64", "arm64"} + -- Windows 10 1709 or later: accurate result + -- Legacy Windows: hardcoded result, i.e. "i386" is always included even though WoW64 is not available + -- macOS: accurate result supposed, but not tested + -- Linux: osArch + appArch + QEMU user mode emulation, no multilib detection + -- other (BSD): osArch + appArch, no multilib detection + supportedAppArchList: function (): {string} + + -- read `subKey\name` from HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE in order (Windows only) + readRegistry: function (subKey: string, name: string): string | nil + end + + record C_Util + -- Qt-style string format, replace %1, %2, etc. with arguments + format: function (format: string, ...: any): string + end +end + +return env diff --git a/addon/defs/theme.d.tl b/addon/defs/theme.d.tl new file mode 100644 index 00000000..0dca7fe6 --- /dev/null +++ b/addon/defs/theme.d.tl @@ -0,0 +1,63 @@ +local env = require("defs.global_env") + +global C_Debug = env.C_Debug +global C_Desktop = env.C_Desktop +global C_Util = env.C_Util + +global record Theme + name: string + style: string + ["default scheme"]: string + ["default iconset"]: BuiltInIconSet + palette: Palette + + enum BuiltInIconSet + "newlook" + "contrast" + "bluesky" + end + + record Palette + PaletteWindow: string | nil + PaletteWindowText: string | nil + PaletteBase: string | nil + PaletteAlternateBase: string | nil + PaletteToolTipBase: string | nil + PaletteToolTipText: string | nil + PaletteText: string | nil + PaletteButton: string | nil + PaletteButtonText: string | nil + PaletteBrightText: string | nil + PaletteHighlight: string | nil + PaletteHighlightedText: string | nil + PaletteLink: string | nil + PaletteLinkVisited: string | nil + + PaletteLight: string | nil + PaletteMidlight: string | nil + PaletteDark: string | nil + PaletteMid: string | nil + PaletteShadow: string | nil + + PaletteWindowDisabled: string | nil + PaletteWindowTextDisabled: string | nil + PaletteBaseDisabled: string | nil + PaletteAlternateBaseDisabled: string | nil + PaletteToolTipBaseDisabled: string | nil + PaletteToolTipTextDisabled: string | nil + PaletteTextDisabled: string | nil + PaletteButtonDisabled: string | nil + PaletteButtonTextDisabled: string | nil + PaletteBrightTextDisabled: string | nil + PaletteHighlightDisabled: string | nil + PaletteHighlightedTextDisabled: string | nil + PaletteLinkDisabled: string | nil + PaletteLinkVisitedDisabled: string | nil + + PaletteLightDisabled: string | nil + PaletteMidlightDisabled: string | nil + PaletteDarkDisabled: string | nil + PaletteMidDisabled: string | nil + PaletteShadowDisabled: string | nil + end +end diff --git a/addon/gen.sh b/addon/gen.sh new file mode 100755 index 00000000..2e19e91b --- /dev/null +++ b/addon/gen.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euo pipefail + +function gen-theme() { + local file="$1" + local bn="$(basename $file)" + local out="RedPandaIDE/themes/${bn%.tl}.lua" + echo -e "\033[1;33mChecking $file\033[0m" + tl check --include-dir addon --global-env-def defs/theme --quiet "$file" + echo -e "\033[1;32mCompiling $file\033[0m" + tl gen --include-dir addon --global-env-def defs/theme --gen-compat off --gen-target 5.4 -o "$out" "$file" +} + +for file in addon/theme/*.tl; do + gen-theme "$file" +done + +function gen-compiler-hint() { + local file="$1" + local out="$2" + echo -e "\033[1;33mChecking $file\033[0m" + tl check --include-dir addon --global-env-def defs/compiler_hint --quiet "$file" + echo -e "\033[1;32mCompiling $file\033[0m" + tl gen --include-dir addon --global-env-def defs/compiler_hint --gen-compat off --gen-target 5.4 -o "$out" "$file" +} + +gen-compiler-hint addon/compiler_hint/windows_domain.tl packages/msys/domain/compiler_hint.lua +gen-compiler-hint addon/compiler_hint/archlinux.tl packages/archlinux/compiler_hint.lua diff --git a/addon/theme/contrast.tl b/addon/theme/contrast.tl new file mode 100644 index 00000000..4b8a0efe --- /dev/null +++ b/addon/theme/contrast.tl @@ -0,0 +1,53 @@ +global function apiVersion(): ApiVersion + return { + kind = "theme", + major = 0, + minor = 1, + } +end + +local nameMap: {string:string} = { + en_US = "Contrast", + pt_BR = "Contraste", + zh_CN = "高对比度", + zh_TW = "高對比度", +} + +global function main(): Theme + local lang = C_Desktop.language() + + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaDarkFusion", + ["default scheme"] = "Twilight", + ["default iconset"] = "contrast", + ["palette"] = { + PaletteWindow = "#000000", + PaletteWindowText = "#FFFFFF", + PaletteBase = "#141414", + PaletteAlternateBase = "#191919", + PaletteButton = "#141414", + PaletteButtonDisabled = "#141414", + PaletteBrightText = "#ff0000", + PaletteText = "#FFFFFF", + PaletteButtonText = "#FFFFFF", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#0A0A0A", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#9DA9B5", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#000000", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#FFFFFF", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + }, + } +end diff --git a/addon/theme/dark.tl b/addon/theme/dark.tl new file mode 100644 index 00000000..ae097861 --- /dev/null +++ b/addon/theme/dark.tl @@ -0,0 +1,53 @@ +global function apiVersion(): ApiVersion + return { + kind = "theme", + major = 0, + minor = 1, + } +end + +local nameMap: {string:string} = { + en_US = "Dark", + pt_BR = "Escura", + zh_CN = "深色", + zh_TW = "深色", +} + +global function main(): Theme + local lang = C_Desktop.language() + + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaDarkFusion", + ["default scheme"] = "VS Code", + ["default iconset"] = "contrast", + ["palette"] = { + PaletteWindow = "#19232D", + PaletteWindowText = "#E0E1E3", + PaletteBase = "#1E1E1E", + PaletteAlternateBase = "#303030", + PaletteButton = "#19232D", + PaletteButtonDisabled = "#19232D", + PaletteBrightText = "#ff0000", + PaletteText = "#e7e7e7", + PaletteButtonText = "#d3d3d3", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#333333", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#26486B", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#19232D", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#707070", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + }, + } +end diff --git a/addon/theme/default.tl b/addon/theme/default.tl new file mode 100644 index 00000000..3605bd57 --- /dev/null +++ b/addon/theme/default.tl @@ -0,0 +1,51 @@ +global function apiVersion(): ApiVersion + return { + kind = "theme", + major = 0, + minor = 1, + } +end + +local nameMap: {string:string} = { + en_US = "Light", + pt_BR = "Clara", + zh_CN = "浅色", + zh_TW = "淺色", +} + +global function main(): Theme + local lang = C_Desktop.language() + + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaLightFusion", + ["default scheme"] = "Intellij Classic", + ["default iconset"] = "newlook", + ["palette"] = { + PaletteWindow = "#efefef", + PaletteWindowText = "#000000", + PaletteBase = "#ffffff", + PaletteAlternateBase = "#f7f7f7", + PaletteToolTipBase = "#ffffdc", + PaletteToolTipText = "#000000", + PaletteText = "#000000", + PaletteButton = "#efefef", + PaletteButtonText = "#000000", + PaletteBrightText = "#ffffff", + PaletteLink = "#0000ff", + PaletteLinkVisited = "#ff00ff", + PaletteLight = "#ffffff", + PaletteMidlight = "#cacaca", + PaletteDark = "#9f9f9f", + PaletteMid = "#b8b8b8", + PaletteWindowDisabled = "#efefef", + PaletteWindowTextDisabled = "#bebebe", + PaletteBaseDisabled = "#efefef", + PaletteTextDisabled = "#bebebe", + PaletteButtonDisabled = "#efefef", + PaletteButtonTextDisabled = "#bebebe", + PaletteHighlight = "#dddddd", + PaletteHighlightedText = "#000000", + }, + } +end diff --git a/addon/theme/molo.tl b/addon/theme/molo.tl new file mode 100644 index 00000000..f09f68cc --- /dev/null +++ b/addon/theme/molo.tl @@ -0,0 +1,53 @@ +global function apiVersion(): ApiVersion + return { + kind = "theme", + major = 0, + minor = 1, + } +end + +local nameMap: {string:string} = { + en_US = "MoLo", + pt_BR = "Molo", + zh_CN = "墨落", + zh_TW = "墨落", +} + +global function main(): Theme + local lang = C_Desktop.language() + + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaDarkFusion", + ["default scheme"] = "MoLo CodeBlack", + ["default iconset"] = "newlook", + ["palette"] = { + PaletteWindow = "#000000", + PaletteWindowText = "#FFFFFF", + PaletteBase = "#141414", + PaletteAlternateBase = "#191919", + PaletteButton = "#141414", + PaletteButtonDisabled = "#141414", + PaletteBrightText = "#ff0000", + PaletteText = "#FFFFFF", + PaletteButtonText = "#FFFFFF", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#0A0A0A", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#9DA9B5", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#000000", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#FFFFFF", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + }, + } +end diff --git a/addon/theme/random_light.tl b/addon/theme/random_light.tl new file mode 100644 index 00000000..517a365f --- /dev/null +++ b/addon/theme/random_light.tl @@ -0,0 +1,132 @@ +global function apiVersion(): ApiVersion + return { + kind = "theme", + major = 0, + minor = 1, + } +end + +local record Rgb + r: number + g: number + b: number +end + +local record Hsv + h: number + s: number + v: number +end + +local function rgbFromString(color: string): Rgb + local r, g, b = color:match("#(%x%x)(%x%x)(%x%x)") + return { + r = tonumber(r, 16) / 255, + g = tonumber(g, 16) / 255, + b = tonumber(b, 16) / 255, + } +end + +local function rgbToString(rgb: Rgb): string + return string.format( + "#%02x%02x%02x", + math.floor(rgb.r * 255), + math.floor(rgb.g * 255), + math.floor(rgb.b * 255) + ) +end + +local function hsvToRgb(hsv: Hsv): Rgb + local r, g, b: number, number, number + local h, s, v = hsv.h, hsv.s, hsv.v + local i = math.floor(h * 6) + local f = h * 6 - i + local p = v * (1 - s) + local q = v * (1 - f * s) + local t = v * (1 - (1 - f) * s) + i = i % 6 + if i == 0 then + r, g, b = v, t, p + elseif i == 1 then + r, g, b = q, v, p + elseif i == 2 then + r, g, b = p, v, t + elseif i == 3 then + r, g, b = p, q, v + elseif i == 4 then + r, g, b = t, p, v + elseif i == 5 then + r, g, b = v, p, q + end + return {r = r, g = g, b = b} +end + +local function blend(lower: Rgb, upper: Rgb, alpha: number): Rgb + local r = (1 - alpha) * lower.r + alpha * upper.r + local g = (1 - alpha) * lower.g + alpha * upper.g + local b = (1 - alpha) * lower.b + alpha * upper.b + return {r = r, g = g, b = b} +end + +local function transform(color: string, upperColor: Rgb): string + local lowerColor = rgbFromString(color) + local blended = blend(lowerColor, upperColor, 0.1) + return rgbToString(blended) +end + +local function transformPalette(palette: Theme.Palette, upperColor: Rgb): Theme.Palette + local transformed = {} + for key, value in pairs(palette as {string:string}) do + transformed[key] = transform(value, upperColor) + end + return transformed as Theme.Palette +end + +local originalPalette: Theme.Palette = { + PaletteWindow = "#efefef", + PaletteWindowText = "#000000", + PaletteBase = "#ffffff", + PaletteAlternateBase = "#f7f7f7", + PaletteToolTipBase = "#ffffdc", + PaletteToolTipText = "#000000", + PaletteText = "#000000", + PaletteButton = "#efefef", + PaletteButtonText = "#000000", + PaletteBrightText = "#ffffff", + PaletteLink = "#0000ff", + PaletteLinkVisited = "#ff00ff", + PaletteLight = "#ffffff", + PaletteMidlight = "#cacaca", + PaletteDark = "#9f9f9f", + PaletteMid = "#b8b8b8", + PaletteWindowDisabled = "#efefef", + PaletteWindowTextDisabled = "#bebebe", + PaletteBaseDisabled = "#efefef", + PaletteTextDisabled = "#bebebe", + PaletteButtonDisabled = "#efefef", + PaletteButtonTextDisabled = "#bebebe", + PaletteHighlight = "#dddddd", + PaletteHighlightedText = "#000000", +} + +local nameMap: {string:string} = { + en_US = "Random Light", + pt_BR = "Clara aleatória", + zh_CN = "随机浅色", + zh_TW = "隨機淺色", +} + +global function main(): Theme + local hue = math.random() + local upperColor = hsvToRgb({h = hue, s = 0.6, v = 1}) + + local lang = C_Desktop.language() + + return { + ["name"] = nameMap[lang] or nameMap.en_US, + ["style"] = "RedPandaLightFusion", + ["default scheme"] = "Adaptive", + ["default iconset"] = "newlook", + ["palette"] = transformPalette(originalPalette, upperColor), + } +end diff --git a/addon/theme/system.tl b/addon/theme/system.tl new file mode 100644 index 00000000..aecacdd3 --- /dev/null +++ b/addon/theme/system.tl @@ -0,0 +1,113 @@ +global function apiVersion(): ApiVersion + return { + kind = "theme", + major = 0, + minor = 1, + } +end + +local nameMap: {string:string} = { + en_US = "System Style and Color", + pt_BR = "Estilo e Cor do Sistema", + zh_CN = "跟随系统样式和颜色", + zh_TW = "跟隨系統樣式和顏色", +} + +local nameMapNoStyle: {string:string} = { + en_US = "System Color", + pt_BR = "Cor do Sistema", + zh_CN = "跟随系统颜色", + zh_TW = "跟隨系統顏色", +} + +global function main(): Theme + local desktopEnvironment = C_Desktop.desktopEnvironment() + local useSystemStyle = desktopEnvironment == "xdg" or desktopEnvironment == "macos" + + local systemAppMode = C_Desktop.systemAppMode() + local isDarkMode = systemAppMode == "dark" + + local function getStyle(): string + if useSystemStyle then + return C_Desktop.systemStyle() + else + if isDarkMode then + return "RedPandaDarkFusion" + else + return "RedPandaLightFusion" + end + end + end + + local function getPalette(): Theme.Palette + if useSystemStyle then + return {} + elseif isDarkMode then + return { -- palette from `dark.lua` + PaletteWindow = "#19232D", + PaletteWindowText = "#E0E1E3", + PaletteBase = "#1E1E1E", + PaletteAlternateBase = "#303030", + PaletteButton = "#19232D", + PaletteButtonDisabled = "#19232D", + PaletteBrightText = "#ff0000", + PaletteText = "#e7e7e7", + PaletteButtonText = "#d3d3d3", + PaletteButtonTextDisabled = "#9DA9B5", + PaletteHighlight = "#aa1f75cc", + PaletteDark = "#232323", + PaletteHighlightedText = "#e7e7e7", + PaletteToolTipBase = "#66000000", + PaletteToolTipText = "#e7e7e7", + PaletteLink = "#007af4", + PaletteLinkVisited = "#a57aff", + PaletteWindowDisabled = "#333333", + PaletteWindowTextDisabled = "#9DA9B5", + PaletteHighlightDisabled = "#26486B", + PaletteHighlightedTextDisabled = "#9DA9B5", + PaletteBaseDisabled = "#19232D", + PaletteTextDisabled = "#9DA9B5", + PaletteMid = "#707070", + PaletteLight = "#505050", + PaletteMidlight = "#00ff00", + } + else + return { -- palette from `default.lua` + PaletteWindow = "#efefef", + PaletteWindowText = "#000000", + PaletteBase = "#ffffff", + PaletteAlternateBase = "#f7f7f7", + PaletteToolTipBase = "#ffffdc", + PaletteToolTipText = "#000000", + PaletteText = "#000000", + PaletteButton = "#efefef", + PaletteButtonText = "#000000", + PaletteBrightText = "#ffffff", + PaletteLink = "#0000ff", + PaletteLinkVisited = "#ff00ff", + PaletteLight = "#ffffff", + PaletteMidlight = "#cacaca", + PaletteDark = "#9f9f9f", + PaletteMid = "#b8b8b8", + PaletteWindowDisabled = "#efefef", + PaletteWindowTextDisabled = "#bebebe", + PaletteBaseDisabled = "#efefef", + PaletteTextDisabled = "#bebebe", + PaletteButtonDisabled = "#efefef", + PaletteButtonTextDisabled = "#bebebe", + PaletteHighlight = "#dddddd", + PaletteHighlightedText = "#000000", + } + end + end + + local lang = C_Desktop.language() + + return { + ["name"] = useSystemStyle and (nameMap[lang] or nameMap.en_US) or (nameMapNoStyle[lang] or nameMapNoStyle.en_US), + ["style"] = getStyle(), + ["default scheme"] = "Adaptive", + ["default iconset"] = "newlook", + ["palette"] = getPalette() + } +end diff --git a/docs/addon.md b/docs/addon.md index 88c72552..7e69702d 100644 --- a/docs/addon.md +++ b/docs/addon.md @@ -14,28 +14,81 @@ - Red Panda C++ APIs exposed to add-on are organized by groups. - Each group is a Lua table. - Each API is a function in the table. - - Available API groups vary by add-on type. -- Localization is handled by add-on. e.g. - ```lua - local lang = C_Desktop.language() - local localizedName = { - en_US = "System", - pt_BR = "Sistema", - zh_CN = "系统", - zh_TW = "系統", - } - return { - name = localizedName[lang] or localizedName.en_US, - -- ... - } - ``` + - Available API groups vary by add-on kind. + - See [`env.d.tl`](../addon/defs/global_env.d.tl) for API definitions. +- Add-on can be executed only if the API version is compatible. +- Localization is handled by add-on. + +### API Version Check + +Add-on must implement `apiVersion` that takes no argument and returns `ApiVersion` ([`env.d.tl`](../addon/defs/global_env.d.tl)). + +Before execution, Red Panda C++ will call `apiVersion()` _without injecting any API group_[^1] to check whether the add-on is compatible with current Red Panda C++ (host). + +[^1]: Thus do not call any API (incl. Lua standard library) in `apiVersion` and file scope. + +Add-on is compatible with host if and only if: +``` +(add-on kind = host kind) ∧ ( + ((add-on major = host major = 0) ∧ (add-on minor = host minor)) ∨ + ((add-on major = host major ≥ 1) ∧ (add-on minor ≤ host minor)) +) +``` + +That is to say: +- API version is kind-specific. +- For a given kind, API major reported by add-on must be equal to host major. + - API major = 0 means unstable, minor updates may break backward compatibility. + - API major ≥ 1 means stable, minor updates keep backward compatibility. + +### Types + +Types in Red Panda C++ add-on interface are defined in [Teal](https://github.com/teal-language/tl) language, a typed dialect of Lua. + +To make use of the type definitions, add-on can be written in Teal. To check and compile Teal add-on: +```bash +tl check --include-dir /path/to/RedPanda-CPP/addon --global-env-def defs/theme addon.tl +tl gen --include-dir /path/to/RedPanda-CPP/addon --global-env-def defs/theme --gen-compat off --gen-target 5.4 addon.tl +``` + +### Localization + +Example: + +```lua +local lang = C_Desktop.language() +-- note: explicitly declare as `{string:string}` for Teal +local localizedName = { + en_US = "System", + pt_BR = "Sistema", + zh_CN = "系统", + zh_TW = "系統", +} +return { + name = localizedName[lang] or localizedName.en_US, + -- ... +} +``` ## Simple Add-on -A simple add-on is a Lua script that returns a single value. +A simple add-on is a Lua script with a `main` function returning single value. + +### Theme Add-on + +Current API version: `theme:0.1`. + +Available API groups: +- `C_Debug` +- `C_Desktop` +- `C_Util` + +`main` function takes no argument and returns `Theme` ([`theme.d.tl`](../addon/defs/theme.d.tl)). ### Compiler Hint Add-on +Current API version: `compiler_hint:0.1`. + If `$appLibexecDir/compiler_hint.lua` exists, it will be executed as compiler hint add-on when searching for compiler. Available API groups: @@ -45,149 +98,4 @@ Available API groups: - `C_System` - `C_Util` -Return value schema: -```typescript -{ - // found compiler sets - compilerList: [compilerSet], - - // do not search in these directories anymore - noSearch: [string], - - // prefer compiler set index (in Lua, 1-based) in compilerList - // 0 for no preference - preferCompiler: number, -} -``` - -`compilerSet` schema: -```typescript -{ - name: string, - - // internal - dumpMachine: string, // e.g. "x86_64-linux-gnu", "x86_64-w64-mingw32" - version: string, // e.g. "13.2.1", "17.0.6" - type: string, // e.g. "TDM-GCC", "MinGW" - target: string, // e.g. "x86_64", "aarch64" - compilerType: string, // "GCC" or "Clang" - - // general - staticLink: boolean, - customCompileParams: [string], // automatically sets useCustomCompileParams - customLinkParams: [string], // automatically sets useCustomLinkParams - execCharset: string, // automatically sets autoAddCharsetParams - - // setting - // - code generation - ccCmdOptOptimize: string, - ccCmdOptStd: string, - cCmdOptStd: string, - ccCmdOptInstruction: string, - ccCmdOptPointerSize: string, - ccCmdOptDebugInfo: string, - ccCmdOptProfileInfo: string, - ccCmdOptSyntaxOnly: string, - // - warnings - ccCmdOptInhibitAllWarning: string, - ccCmdOptWarningAll: string, - ccCmdOptWarningExtra: string, - ccCmdOptCheckIsoConformance: string, - ccCmdOptWarningAsError: string, - ccCmdOptAbortOnError: string, - ccCmdOptStackProtector: string, - ccCmdOptAddressSanitizer: string, - // - linker - ccCmdOptUsePipe: string, - linkCmdOptNoLinkStdlib: string, - linkCmdOptNoConsole: string, - linkCmdOptStripExe: string, - - // directory - binDirs: [string], - cIncludeDirs: [string], - cxxIncludeDirs: [string], - libDirs: [string], - defaultLibDirs: [string], - defaultCIncludeDirs: [string], - defaultCxxIncludeDirs: [string], - - // program - cCompiler: string, - cxxCompiler: string, - make: string, - debugger: string, - debugServer: string, - resourceCompiler: string, - - // output - preprocessingSuffix: string, - compilationProperSuffix: string, - assemblingSuffix: string, - executableSuffix: string, - compilationStage: number, -} -``` - -## API Groups - -### `C_Debug` - -`C_Debug` is available to all add-on types. - -- `C_Debug.debug`: `(message: string) -> ()`, print message to console (via `qDebug()`). - -### `C_Desktop` - -- `C_Desktop.desktopEnvironment`: `() -> string`, return desktop environment name. - - `windows`: Windows (Win32 only) - - `macos`: macOS - - `xdg`: XDG-compliant desktop environment (e.g. GNOME, KDE Plasma) - - `unknown`: other desktops or non-desktop environments (e.g. Windows UWP, Android) -- `C_Desktop.language`: `() -> string`, return language code. - - e.g. `en_US`, `zh_CN` -- `C_Desktop.qtStyleList`: `() -> [string]`, return available Qt styles. - - e.g. `{"breeze", "fusion", "windows"}` -- `C_Desktop.systemAppMode`: `() -> string`, return system app mode. - - `light`: light mode - - `dark`: dark mode -- `C_Desktop.systemStyle`: `() -> string`, return default Qt style. - - e.g. `fusion` - -### `C_FileSystem` - -- `C_FileSystem.exists`: `(path: string) -> boolean`, return whether the path exists. -- `C_FileSystem.isExecutable`: `(path: string) -> boolean`, return whether the path is executable. - -### `C_System` - -- `C_System.appArch`: `() -> string`, return the architecture of Red Panda C++, name following `QSysInfo`. - - e.g. `i386`, `x86_64`, `arm`, `arm64`, `riscv64`, `loongarch64` - - Though unsupprted, MSVC arm64ec is handled correctly (returns `arm64ec`) -- `C_System.appDir`: `() -> string`, return the directory of Red Panda C++. - - e.g. `/usr/bin`, `C:/Program Files/RedPanda-Cpp` -- `C_System.appLibexecDir`: `() -> string`, return the libexec directory of Red Panda C++. - - e.g. `/usr/libexec/RedPandaCPP`, `C:/Program Files/RedPanda-Cpp` -- `C_System.appResourceDir`: `() -> string`, return the resource directory of Red Panda C++. - - e.g. `/usr/share/RedPandaCPP`, `C:/Program Files/RedPanda-Cpp` -- `C_System.osArch`: `() -> string`, return the architecture of the OS, name following `QSysInfo`. - - e.g. `i386`, `x86_64`, `arm`, `arm64` - - Windows arm64 is handled correctly even if Red Panda C++ runs under emulation -- `C_System.supportedAppArchList`: `() -> [string]`, return supported application architectures by OS, name following `QSysInfo`. - - e.g. `{"i386", "x86_64", "arm64"}` - - Windows 10 1709 or later: accurate result - - Legacy Windows: hardcoded - - `{"i386", "x86_64"}` for x86_64 even though WoW64 is not available - - macOS: accurate result supposed, but not tested - - Linux: osArch + appArch + QEMU user mode emulation - - No multilib detection. It’s packager’s responsibility to detect multilib support in `compiler_hint.lua` - - other (BSD): osArch + appArch (no multilib) - -Windows specific: - -- `C_System.readRegistry`: `(subKey: string, name: string) -> string | nil`, read `subKey\name` from `HKEY_CURRENT_USER` and `HKEY_LOCAL_MACHINE` in order. - - `name` can be empty string for default value - -### `C_Util` - -- `C_Util.format`: `(format: string, ...) -> string`, Qt-style string format, replace `%1`, `%2`, etc. with arguments. +`main` function takes no argument and returns `CompilerHint` ([`compiler_hint.d.tl`](../addon/defs/compiler_hint.d.tl)). diff --git a/packages/archlinux/compiler_hint.lua b/packages/archlinux/compiler_hint.lua index 3e7a0071..5d509fe3 100644 --- a/packages/archlinux/compiler_hint.lua +++ b/packages/archlinux/compiler_hint.lua @@ -1,271 +1,313 @@ -local arch = C_System.osArch() -local libexecDir = C_System.appLibexecDir() -local lang = C_Desktop.language() +function apiVersion() + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end local nameMap = { - systemGcc = { - en_US = "System GCC", - pt_BR = "GCC do sistema", - zh_CN = "系统 GCC", - zh_TW = "系統 GCC", - }, - systemClang = { - en_US = "System Clang", - pt_BR = "Clang do sistema", - zh_CN = "系统 Clang", - zh_TW = "系統 Clang", - }, - multilibGcc = { - en_US = "Multilib GCC", - pt_BR = "GCC multilib", - zh_CN = "Multilib GCC", - zh_TW = "Multilib GCC", - }, - multilibClang = { - en_US = "Multilib Clang", - pt_BR = "Clang multilib", - zh_CN = "Multilib Clang", - zh_TW = "Multilib Clang", - }, - crossGcc = { - en_US = "Cross GCC", - pt_BR = "GCC cruzado", - zh_CN = "交叉编译 GCC", - zh_TW = "交叉編譯 GCC", - }, - mingwGcc = { - en_US = "MinGW GCC", - pt_BR = "GCC MinGW", - zh_CN = "MinGW GCC", - zh_TW = "MinGW GCC", - }, - mingwClang = { - en_US = "MinGW Clang", - pt_BR = "Clang MinGW", - zh_CN = "MinGW Clang", - zh_TW = "MinGW Clang", - }, - release = { - en_US = ", release", - pt_BR = ", lançamento", - zh_CN = ",发布", - zh_TW = ",發佈", - }, - debug = { - en_US = ", debug", - pt_BR = ", depuração", - zh_CN = ",调试", - zh_TW = ",偵錯", - }, - debugWithAsan = { - en_US = ", debug with ASan", - pt_BR = ", depuração com ASan", - zh_CN = ",ASan 调试", - zh_TW = ",ASan 偵錯", - }, + systemGcc = { + en_US = "System GCC", + pt_BR = "GCC do sistema", + zh_CN = "系统 GCC", + zh_TW = "系統 GCC", + }, + systemClang = { + en_US = "System Clang", + pt_BR = "Clang do sistema", + zh_CN = "系统 Clang", + zh_TW = "系統 Clang", + }, + multilibGcc = { + en_US = "Multilib GCC", + pt_BR = "GCC multilib", + zh_CN = "Multilib GCC", + zh_TW = "Multilib GCC", + }, + multilibClang = { + en_US = "Multilib Clang", + pt_BR = "Clang multilib", + zh_CN = "Multilib Clang", + zh_TW = "Multilib Clang", + }, + crossGcc = { + en_US = "Cross GCC", + pt_BR = "GCC cruzado", + zh_CN = "交叉编译 GCC", + zh_TW = "交叉編譯 GCC", + }, + mingwGcc = { + en_US = "MinGW GCC", + pt_BR = "GCC MinGW", + zh_CN = "MinGW GCC", + zh_TW = "MinGW GCC", + }, + mingwClang = { + en_US = "MinGW Clang", + pt_BR = "Clang MinGW", + zh_CN = "MinGW Clang", + zh_TW = "MinGW Clang", + }, + release = { + en_US = ", release", + pt_BR = ", lançamento", + zh_CN = ",发布", + zh_TW = ",發佈", + }, + debug = { + en_US = ", debug", + pt_BR = ", depuração", + zh_CN = ",调试", + zh_TW = ",偵錯", + }, + debugWithAsan = { + en_US = ", debug with ASan", + pt_BR = ", depuração com ASan", + zh_CN = ",ASan 调试", + zh_TW = ",ASan 偵錯", + }, } -function generateConfig(name, cCompiler, cxxCompiler, config) - local commonOptions = { - cCompiler = cCompiler, - cxxCompiler = cxxCompiler, - debugger = "/usr/bin/gdb", - debugServer = "/usr/bin/gdbserver", - make = "/usr/bin/make", - compilerType = config.isClang and "Clang" or "GCC_UTF8", - preprocessingSuffix = ".i", - compilationProperSuffix = ".s", - assemblingSuffix = ".o", - executableSuffix = config.isMingw and ".exe" or "", - compilationStage = 3, - ccCmdOptUsePipe = "on", - ccCmdOptWarningAll = "on", - ccCmdOptWarningExtra = "on", - ccCmdOptCheckIsoConformance = "on", - binDirs = {"/usr/bin"}, - } - if config.isMultilib then - commonOptions.ccCmdOptPointerSize = "32" - end - if config.isMingw then - commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" - end - if config.customCompileParams then - commonOptions.customCompileParams = config.customCompileParams - end - if config.customLinkParams then - commonOptions.customLinkParams = config.customLinkParams - end - local release = { - name = name .. (nameMap.release[lang] or nameMap.release.en_US), - staticLink = true, - linkCmdOptStripExe = "on", - ccCmdOptOptimize = "2", - } - local debug = { - name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), - ccCmdOptDebugInfo = "on", - } - local debugWithAsan = { - name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), - ccCmdOptDebugInfo = "on", - ccCmdOptAddressSanitizer = "address", - } - for k, v in pairs(commonOptions) do - release[k] = v - debug[k] = v - debugWithAsan[k] = v - end - return release, debug, debugWithAsan +local function mergeCompilerSet(compilerSet, other) + local c = compilerSet + local o = other + for k, v in pairs(o) do + c[k] = v + end end -local compilerList = {} -do - local release, debug, debugWithAsan = generateConfig( - nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, - "/usr/bin/gcc", "/usr/bin/g++", - {} - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - table.insert(compilerList, debugWithAsan) + + + + + + + + +local function generateConfig( + name, lang, + cCompiler, cxxCompiler, + config) + + local commonOptions = { + cCompiler = cCompiler, + cxxCompiler = cxxCompiler, + debugger = "/usr/bin/gdb", + debugServer = "/usr/bin/gdbserver", + make = "/usr/bin/make", + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = config.isMingw and ".exe" or "", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + binDirs = { "/usr/bin" }, + } + if config.isMultilib then + commonOptions.ccCmdOptPointerSize = "32" + end + if config.isMingw then + commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = name .. (nameMap.release[lang] or nameMap.release.en_US), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan end -if C_FileSystem.isExecutable("/usr/bin/clang") then - local release, debug, debugWithAsan = generateConfig( - nameMap.systemClang[lang] or nameMap.systemClang.en_US, - "/usr/bin/clang", "/usr/bin/clang++", - {isClang = true} - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - table.insert(compilerList, debugWithAsan) -end +function main() + local arch = C_System.osArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() --- with lib32-gcc-libs installed, system GCC and Clang can target 32-bit -if arch == "x86_64" and C_FileSystem.isExecutable("/usr/lib32/libstdc++.so") then - local release, debug, debugWithAsan = generateConfig( - nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, - "/usr/bin/gcc", "/usr/bin/g++", - {isMultilib = true} - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - table.insert(compilerList, debugWithAsan) - if C_FileSystem.isExecutable("/usr/bin/clang") then - local release, debug, debugWithAsan = generateConfig( - nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, - "/usr/bin/clang", "/usr/bin/clang++", - {isClang = true, isMultilib = true} - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - table.insert(compilerList, debugWithAsan) - end -end + local compilerList = {} --- cross GCC -if ( - arch == "x86_64" and - C_FileSystem.exists("/proc/sys/fs/binfmt_misc/qemu-aarch64") and - C_FileSystem.isExecutable("/usr/bin/aarch64-linux-gnu-gcc") -) then - local release, debug, debugWithAsan = generateConfig( - (nameMap.crossGcc[lang] or nameMap.crossGcc.en_US) .. " aarch64", - "/usr/bin/aarch64-linux-gnu-gcc", "/usr/bin/aarch64-linux-gnu-g++", - {} - ) - table.insert(compilerList, release) -end + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {}) --- with wine or WSL init registered in binfmt_misc, Windows binaries can run seamlessly -if ( - arch == "x86_64" and ( - C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or - C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop") - ) -) then - if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then - local extraObjects = { + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemClang[lang] or nameMap.systemClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + { isClang = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + + if arch == "x86_64" and C_FileSystem.isExecutable("/usr/lib32/libstdc++.so") then + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + { isMultilib = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + { isClang = true, isMultilib = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + end + + + if ( + arch == "x86_64" and + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/qemu-aarch64") and + C_FileSystem.isExecutable("/usr/bin/aarch64-linux-gnu-gcc")) then + + local release, _, _ = generateConfig( + (nameMap.crossGcc[lang] or nameMap.crossGcc.en_US) .. " aarch64", lang, + "/usr/bin/aarch64-linux-gnu-gcc", "/usr/bin/aarch64-linux-gnu-g++", + {}) + + table.insert(compilerList, release) + end + + + if ( + arch == "x86_64" and ( + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop"))) then + + + if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then + local extraObjects = { utf8init = libexecDir .. "/x86_64-w64-mingw32/utf8init.o", utf8manifest = libexecDir .. "/x86_64-w64-mingw32/utf8manifest.o", - } - local release, debug, debugWithAsan = generateConfig( - (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", lang, "/usr/bin/x86_64-w64-mingw32-gcc", "/usr/bin/x86_64-w64-mingw32-g++", { - isMingw = true, - triplet = "x86_64-w64-mingw32", - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, - } - ) - table.insert(compilerList, release) - -- system Clang can target Windows - if C_FileSystem.isExecutable("/usr/bin/clang") then - local release, debug, debugWithAsan = generateConfig( - (nameMap.mingwClang[lang] or nameMap.mingwClang.en_US) .. " x86_64", - "/usr/bin/clang", "/usr/bin/clang++", - { - isClang = true, - isMingw = true, - triplet = "x86_64-w64-mingw32", - customCompileParams = {"-target", "x86_64-w64-mingw32"}, - customLinkParams = { - "-target", "x86_64-w64-mingw32", - extraObjects.utf8init, extraObjects.utf8manifest, - "-lstdc++", "-lwinpthread", - }, - } - ) + isMingw = true, + triplet = "x86_64-w64-mingw32", + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + table.insert(compilerList, release) - end - end - if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then - local extraObjects = { + end + + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, _, _ = generateConfig( + (nameMap.mingwClang[lang] or nameMap.mingwClang.en_US) .. " x86_64", lang, + "/usr/bin/clang", "/usr/bin/clang++", + { + isClang = true, + isMingw = true, + triplet = "x86_64-w64-mingw32", + customCompileParams = { "-target", "x86_64-w64-mingw32" }, + customLinkParams = { + "-target", "x86_64-w64-mingw32", + extraObjects.utf8init, extraObjects.utf8manifest, + "-lstdc++", "-lwinpthread", + }, + }) + + table.insert(compilerList, release) + end + end + + if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then + local extraObjects = { utf8init = libexecDir .. "/i686-w64-mingw32/utf8init.o", utf8manifest = libexecDir .. "/i686-w64-mingw32/utf8manifest.o", - } - local release, debug, debugWithAsan = generateConfig( - (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", lang, "/usr/bin/i686-w64-mingw32-gcc", "/usr/bin/i686-w64-mingw32-g++", { - isMingw = true, - triplet = "i686-w64-mingw32", - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, - } - ) - table.insert(compilerList, release) - -- system Clang can target Windows - if C_FileSystem.isExecutable("/usr/bin/clang") then - local release, debug, debugWithAsan = generateConfig( - (nameMap.mingwClang[lang] or nameMap.mingwClang.en_US) .. " i686", - "/usr/bin/clang", "/usr/bin/clang++", - { - isClang = true, - isMingw = true, - triplet = "i686-w64-mingw32", - customCompileParams = {"-target", "i686-w64-mingw32"}, - customLinkParams = { - "-target", "i686-w64-mingw32", - extraObjects.utf8init, extraObjects.utf8manifest, - "-lstdc++", "-lwinpthread", - }, - } - ) + isMingw = true, + triplet = "i686-w64-mingw32", + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + table.insert(compilerList, release) - end - end + end + + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, _, _ = generateConfig( + (nameMap.mingwClang[lang] or nameMap.mingwClang.en_US) .. " i686", lang, + "/usr/bin/clang", "/usr/bin/clang++", + { + isClang = true, + isMingw = true, + triplet = "i686-w64-mingw32", + customCompileParams = { "-target", "i686-w64-mingw32" }, + customLinkParams = { + "-target", "i686-w64-mingw32", + extraObjects.utf8init, extraObjects.utf8manifest, + "-lstdc++", "-lwinpthread", + }, + }) + + table.insert(compilerList, release) + end + end + end + + local result = { + compilerList = compilerList, + noSearch = { + "/usr/bin", + "/opt/cuda/bin", + "/usr/lib/ccache/bin", + }, + preferCompiler = 3, + } + + return result + end - -local result = { - compilerList = compilerList, - noSearch = { - "/usr/bin", - "/opt/cuda/bin", - "/usr/lib/ccache/bin", - }, - preferCompiler = 3, -- System GCC Debug with ASan -} - -return result diff --git a/packages/msys/domain/compiler_hint.lua b/packages/msys/domain/compiler_hint.lua index c5532b79..2fc454a3 100644 --- a/packages/msys/domain/compiler_hint.lua +++ b/packages/msys/domain/compiler_hint.lua @@ -1,386 +1,430 @@ -local arch = C_System.osArch() -local appArch = C_System.appArch() -local libexecDir = C_System.appLibexecDir() -local lang = C_Desktop.language() -local supportedAppArches = C_System.supportedAppArchList() +function apiVersion() + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end local gnuArchMap = { - i386 = "i686", - x86_64 = "x86_64", - arm = "armv7", - arm64 = "aarch64", + i386 = "i686", + x86_64 = "x86_64", + arm = "armv7", + arm64 = "aarch64", } local profileNameMap = { - release = { - en_US = "release", - pt_BR = "lançamento", - zh_CN = "发布", - zh_TW = "發佈", - }, - debug = { - en_US = "debug", - pt_BR = "depuração", - zh_CN = "调试", - zh_TW = "偵錯", - }, - debugWithAsan = { - en_US = "debug with ASan", - pt_BR = "depuração com ASan", - zh_CN = "ASan 调试", - zh_TW = "ASan 偵錯", - }, + release = { + en_US = "release", + pt_BR = "lançamento", + zh_CN = "发布", + zh_TW = "發佈", + }, + debug = { + en_US = "debug", + pt_BR = "depuração", + zh_CN = "调试", + zh_TW = "偵錯", + }, + debugWithAsan = { + en_US = "debug with ASan", + pt_BR = "depuração com ASan", + zh_CN = "ASan 调试", + zh_TW = "ASan 偵錯", + }, } -local nameGenerator = { - mingwGcc = function (lang, arch, profile, isUtf8) - local template = { - en_US = "MinGW GCC %1 in %2, %3", - pt_BR = "GCC MinGW %1 em %2, %3", - zh_CN = "%2 MinGW GCC %1,%3", - zh_TW = "%2 MinGW GCC %1,%3", - } - local systemCodePage = { - en_US = "system code page", - pt_Br = "página de código do sistema", - zh_CN = "系统代码页", - zh_TW = "系統代碼頁", - } - return C_Util.format( - template[lang] or template.en_US, - gnuArchMap[arch], - isUtf8 and "UTF-8" or systemCodePage[lang] or systemCodePage.en_US, - profileNameMap[profile][lang] or profileNameMap[profile].en_US - ) - end, - clang = function (lang, arch, profile, isMingw) - local template = { - en_US = "%1 Clang %2, %3", - pt_BR = "Clang %2 %1, %3", - zh_CN = "%1 Clang %2,%3", - zh_CN = "%1 Clang %2,%3", - } - local msvcCompatible = { - en_US = "MSVC-compatible", - pt_BR = "compatível com MSVC", - zh_CN = "兼容 MSVC 的", - zh_TW = "相容 MSVC 的", - } - return C_Util.format( - template[lang] or template.en_US, - isMingw and "LLVM-MinGW" or msvcCompatible[lang] or msvcCompatible.en_US, - gnuArchMap[arch], - profileNameMap[profile][lang] or profileNameMap[profile].en_US - ) - end, -} +local function nameGeneratorMingwGcc(lang, arch, profile, isUtf8) + local template = { + en_US = "MinGW GCC %1 in %2, %3", + pt_BR = "GCC MinGW %1 em %2, %3", + zh_CN = "%2 MinGW GCC %1,%3", + zh_TW = "%2 MinGW GCC %1,%3", + } + local systemCodePage = { + en_US = "system code page", + pt_Br = "página de código do sistema", + zh_CN = "系统代码页", + zh_TW = "系統代碼頁", + } + return C_Util.format( + template[lang] or template.en_US, + gnuArchMap[arch], + isUtf8 and "UTF-8" or systemCodePage[lang] or systemCodePage.en_US, + profileNameMap[profile][lang] or profileNameMap[profile].en_US) -function generateConfig(nameGen, programs, config) - local commonOptions = { - cCompiler = programs.cCompiler, - cxxCompiler = programs.cxxCompiler, - debugger = programs.debugger, - debugServer = programs.debugServer, - make = programs.make, - resourceCompiler = programs.resourceCompiler, - binDirs = programs.binDirs, - compilerType = config.isClang and "Clang" or "GCC_UTF8", - preprocessingSuffix = ".i", - compilationProperSuffix = ".s", - assemblingSuffix = ".o", - executableSuffix = ".exe", - compilationStage = 3, - ccCmdOptUsePipe = "on", - ccCmdOptWarningAll = "on", - ccCmdOptWarningExtra = "on", - ccCmdOptCheckIsoConformance = "on", - } - if programs.libDirs then - commonOptions.libDirs = programs.libDirs - end - if config.isAnsi then - commonOptions.execCharset = "SYSTEM" - end - if config.customCompileParams then - commonOptions.customCompileParams = config.customCompileParams - end - if config.customLinkParams then - commonOptions.customLinkParams = config.customLinkParams - end - local release = { - name = nameGen(config.arch, "release"), - staticLink = true, - linkCmdOptStripExe = "on", - ccCmdOptOptimize = "2", - } - local debug = { - name = nameGen(config.arch, "debug"), - ccCmdOptDebugInfo = "on", - } - local debugWithAsan = { - name = nameGen(config.arch, "debugWithAsan"), - ccCmdOptDebugInfo = "on", - ccCmdOptAddressSanitizer = "address", - } - for k, v in pairs(commonOptions) do - release[k] = v - debug[k] = v - debugWithAsan[k] = v - end - return release, debug, debugWithAsan end -function contains(t, v) - for _, vv in ipairs(t) do - if vv == v then - return true - end - end - return false +local function nameGeneratorClang(lang, arch, profile, isMingw) + local template = { + en_US = "%1 Clang %2, %3", + pt_BR = "Clang %2 %1, %3", + zh_CN = "%1 Clang %2,%3", + zh_TW = "%1 Clang %2,%3", + } + local msvcCompatible = { + en_US = "MSVC-compatible", + pt_BR = "compatível com MSVC", + zh_CN = "兼容 MSVC 的", + zh_TW = "相容 MSVC 的", + } + return C_Util.format( + template[lang] or template.en_US, + isMingw and "LLVM-MinGW" or msvcCompatible[lang] or msvcCompatible.en_US, + gnuArchMap[arch], + profileNameMap[profile][lang] or profileNameMap[profile].en_US) + end -local compilerList = {} -local noSearch = {} -local preferCompiler = 0 - -function checkAndAddMingw(arch) - local binDir - local libDir - local excludeBinDir - if arch == "i386" then - binDir = libexecDir .. "/mingw32/bin" -- must match case because Windows filesystem can be case sensitive - libDir = libexecDir .. "/mingw32/i686-w64-mingw32/lib" - excludeBinDir = libexecDir .. "/MinGW32/bin" -- workaround for path check - elseif arch == "x86_64" then - binDir = libexecDir .. "/mingw64/bin" - libDir = libexecDir .. "/mingw64/x86_64-w64-mingw32/lib" - excludeBinDir = libexecDir .. "/MinGW64/bin" - else - return - end - - if not C_FileSystem.isExecutable(binDir .. "/gcc.exe") then - return - end - - local programs = { - cCompiler = binDir .. "/gcc.exe", - cxxCompiler = binDir .. "/g++.exe", - make = binDir .. "/mingw32-make.exe", - debugger = binDir .. "/gdb.exe", - debugServer = binDir .. "/gdbserver.exe", - resourceCompiler = binDir .. "/windres.exe", - binDirs = {binDir}, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } - - local release, debug, debugWithAsan = generateConfig( - function (arch, profile) return nameGenerator.mingwGcc(lang, arch, profile, true) end, - programs, - { - arch = arch, - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, - } - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - if preferCompiler == 0 then - preferCompiler = 2 - end - - release, debug, debugWithAsan = generateConfig( - function (arch, profile) return nameGenerator.mingwGcc(lang, arch, profile, false) end, - programs, - { - arch = arch, - isAnsi = true, - } - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - - table.insert(noSearch, excludeBinDir) +local function mergeCompilerSet(compilerSet, other) + local c = compilerSet + local o = other + for k, v in pairs(o) do + c[k] = v + end end -function checkAndAddClang() - if not C_FileSystem.isExecutable(libexecDir .. "/llvm-mingw/bin/clang.exe") then - return - end - -- appArch is always debuggable - local appTriplet = gnuArchMap[appArch] .. "-w64-mingw32" - local binDir = libexecDir .. "/llvm-mingw/bin" - local libDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/lib" - local programs = { - cCompiler = binDir .. "/" .. appTriplet .. "-clang.exe", - cxxCompiler = binDir .. "/" .. appTriplet .. "-clang++.exe", - make = binDir .. "/mingw32-make.exe", - debugger = binDir .. "/lldb-mi.exe", - debugServer = binDir .. "/lldb-server.exe", - resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", - binDirs = {binDir}, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } - local release, debug, debugWithAsan = generateConfig( - function (arch, profile) return nameGenerator.clang(lang, arch, profile, true) end, - programs, - { + + + + + + + + + + + + + + + + + + +local function generateConfig( + nameGen, + programs, + config) + + local commonOptions = { + cCompiler = programs.cCompiler, + cxxCompiler = programs.cxxCompiler, + debugger = programs.debugger, + debugServer = programs.debugServer, + make = programs.make, + resourceCompiler = programs.resourceCompiler, + binDirs = programs.binDirs, + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = ".exe", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + } + if programs.libDirs then + commonOptions.libDirs = programs.libDirs + end + if config.isAnsi then + commonOptions.execCharset = "SYSTEM" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = nameGen(config.arch, "release"), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = nameGen(config.arch, "debug"), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = nameGen(config.arch, "debugWithAsan"), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +function main() + local appArch = C_System.appArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + local supportedAppArches = C_System.supportedAppArchList() + + local compilerList = {} + local noSearch = {} + local preferCompiler = 0 + + local function checkAndAddMingw(arch) + local binDir + local libDir + local excludeBinDir + if arch == "i386" then + binDir = libexecDir .. "/mingw32/bin" + libDir = libexecDir .. "/mingw32/i686-w64-mingw32/lib" + excludeBinDir = libexecDir .. "/MinGW32/bin" + elseif arch == "x86_64" then + binDir = libexecDir .. "/mingw64/bin" + libDir = libexecDir .. "/mingw64/x86_64-w64-mingw32/lib" + excludeBinDir = libexecDir .. "/MinGW64/bin" + else + return + end + + if not C_FileSystem.isExecutable(binDir .. "/gcc.exe") then + return + end + + local programs = { + cCompiler = binDir .. "/gcc.exe", + cxxCompiler = binDir .. "/g++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/gdb.exe", + debugServer = binDir .. "/gdbserver.exe", + resourceCompiler = binDir .. "/windres.exe", + binDirs = { binDir }, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + + local release, debug_, debugWithAsan = generateConfig( + function(arch_, profile) + return nameGeneratorMingwGcc(lang, arch_, profile, true) + end, + programs, + { + arch = arch, + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if preferCompiler == 0 then + preferCompiler = 2 + end + + release, debug_, debugWithAsan = generateConfig( + function(arch_, profile) + return nameGeneratorMingwGcc(lang, arch_, profile, false) + end, + programs, + { + arch = arch, + isAnsi = true, + }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + + table.insert(noSearch, excludeBinDir) + end + + local function checkAndAddClang() + if not C_FileSystem.isExecutable(libexecDir .. "/llvm-mingw/bin/clang.exe") then + return + end + + local binDir = libexecDir .. "/llvm-mingw/bin" + local appTriplet = gnuArchMap[appArch] .. "-w64-mingw32" + do + + local libDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/lib" + local programs = { + cCompiler = binDir .. "/" .. appTriplet .. "-clang.exe", + cxxCompiler = binDir .. "/" .. appTriplet .. "-clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", + binDirs = { binDir }, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + local release, debug_, debugWithAsan = generateConfig( + function(arch_, profile) + return nameGeneratorClang(lang, arch_, profile, true) + end, + programs, + { arch = appArch, - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, isClang = true, - } - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) - if appArch ~= "arm64" then - table.insert(compilerList, debugWithAsan) - if preferCompiler == 0 then - preferCompiler = 3 - end - else - if preferCompiler == 0 then - preferCompiler = 2 - end - end + }) - for _, foreignArch in ipairs(supportedAppArches) do - if foreignArch ~= appArch then + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if appArch ~= "arm64" then + table.insert(compilerList, debugWithAsan) + if preferCompiler == 0 then + preferCompiler = 3 + end + else + if preferCompiler == 0 then + preferCompiler = 2 + end + end + end + + for _, foreignArch in ipairs(supportedAppArches) do + if foreignArch ~= appArch then local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" local libDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/lib" local programs = { - cCompiler = binDir .. "/" .. foreignTriplet .. "-clang.exe", - cxxCompiler = binDir .. "/" .. foreignTriplet .. "-clang++.exe", - make = binDir .. "/mingw32-make.exe", - debugger = binDir .. "/lldb-mi.exe", - debugServer = binDir .. "/lldb-server.exe", - resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", - binDirs = {binDir}, + cCompiler = binDir .. "/" .. foreignTriplet .. "-clang.exe", + cxxCompiler = binDir .. "/" .. foreignTriplet .. "-clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", + binDirs = { binDir }, } local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", } - local release, debug, debugWithAsan = generateConfig( - function (arch, profile) return nameGenerator.clang(lang, arch, profile, true) end, - programs, - { - arch = foreignArch, - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, - isClang = true, - } - ) + local release, _, _ = generateConfig( + function(arch_, profile) + return nameGeneratorClang(lang, arch_, profile, true) + end, + programs, + { + arch = foreignArch, + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + isClang = true, + }) + table.insert(compilerList, release) - end - end + end + end - table.insert(noSearch, binDir) + table.insert(noSearch, binDir) - local llvmOrgPath = C_System.readRegistry([[Software\LLVM\LLVM]], "") or C_System.readRegistry([[Software\Wow6432Node\LLVM\LLVM]], "") - if not llvmOrgPath then - return - end + local llvmOrgPath = C_System.readRegistry([[Software\LLVM\LLVM]], "") or C_System.readRegistry([[Software\Wow6432Node\LLVM\LLVM]], "") + if not llvmOrgPath then + return + end + local llvmOrgBinDir = llvmOrgPath .. "/bin" - local llvmOrgBinDir = llvmOrgPath .. "/bin" - local msvcTriplet = gnuArchMap[appArch] .. "-pc-windows-msvc" - local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" - local programs = { - cCompiler = llvmOrgBinDir .. "/clang.exe", - cxxCompiler = llvmOrgBinDir .. "/clang++.exe", - make = binDir .. "/mingw32-make.exe", - debugger = binDir .. "/lldb-mi.exe", - debugServer = binDir .. "/lldb-server.exe", - resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", - binDirs = {llvmOrgBinDir}, - libDirs = {libDir}, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } - local release, debug, debugWithAsan = generateConfig( - function (arch, profile) return nameGenerator.clang(lang, arch, profile, false) end, - programs, - { + do + local msvcTriplet = gnuArchMap[appArch] .. "-pc-windows-msvc" + local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" + local programs = { + cCompiler = llvmOrgBinDir .. "/clang.exe", + cxxCompiler = llvmOrgBinDir .. "/clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", + binDirs = { llvmOrgBinDir }, + libDirs = { libDir }, + } + local extraObjects = { + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", + } + local release, debug_, _ = generateConfig( + function(arch, profile) + return nameGeneratorClang(lang, arch, profile, false) + end, + programs, + { arch = appArch, customCompileParams = { - "-target", msvcTriplet, - "-fms-extensions", - "-fms-compatibility", - "-fdelayed-template-parsing", + "-target", msvcTriplet, + "-fms-extensions", + "-fms-compatibility", + "-fdelayed-template-parsing", }, customLinkParams = { - "-target", msvcTriplet, - extraObjects.utf8init, extraObjects.utf8manifest, + "-target", msvcTriplet, + extraObjects.utf8init, extraObjects.utf8manifest, }, isClang = true, - } - ) - table.insert(compilerList, release) - table.insert(compilerList, debug) + }) - for _, foreignArch in ipairs(supportedAppArches) do - if foreignArch ~= appArch then + table.insert(compilerList, release) + table.insert(compilerList, debug_) + end + + for _, foreignArch in ipairs(supportedAppArches) do + if foreignArch ~= appArch then local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" local msvcTriplet = gnuArchMap[foreignArch] .. "-pc-windows-msvc" local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" local programs = { - cCompiler = llvmOrgBinDir .. "/clang.exe", - cxxCompiler = llvmOrgBinDir .. "/clang++.exe", - make = binDir .. "/mingw32-make.exe", - debugger = binDir .. "/lldb-mi.exe", - debugServer = binDir .. "/lldb-server.exe", - resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", - binDirs = {llvmOrgBinDir}, - libDirs = {libDir}, + cCompiler = llvmOrgBinDir .. "/clang.exe", + cxxCompiler = llvmOrgBinDir .. "/clang++.exe", + make = binDir .. "/mingw32-make.exe", + debugger = binDir .. "/lldb-mi.exe", + debugServer = binDir .. "/lldb-server.exe", + resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", + binDirs = { llvmOrgBinDir }, + libDirs = { libDir }, } local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", + utf8init = libDir .. "/utf8init.o", + utf8manifest = libDir .. "/utf8manifest.o", } - local release, debug, debugWithAsan = generateConfig( - function (arch, profile) return nameGenerator.clang(lang, arch, profile, false) end, - programs, - { - arch = foreignArch, - customCompileParams = { - "-target", msvcTriplet, - "-fms-extensions", - "-fms-compatibility", - "-fdelayed-template-parsing", - }, - customLinkParams = { - "-target", msvcTriplet, - extraObjects.utf8init, extraObjects.utf8manifest, - }, - isClang = true, - } - ) + local release, _, _ = generateConfig( + function(arch, profile) + return nameGeneratorClang(lang, arch, profile, false) + end, + programs, + { + arch = foreignArch, + customCompileParams = { + "-target", msvcTriplet, + "-fms-extensions", + "-fms-compatibility", + "-fdelayed-template-parsing", + }, + customLinkParams = { + "-target", msvcTriplet, + extraObjects.utf8init, extraObjects.utf8manifest, + }, + isClang = true, + }) + table.insert(compilerList, release) - end - end - table.insert(noSearch, llvmOrgBinDir) + end + end + table.insert(noSearch, llvmOrgBinDir) + end + + if appArch == "x86_64" then + checkAndAddMingw("x86_64") + checkAndAddClang() + elseif appArch == "arm64" then + checkAndAddClang() + else + checkAndAddMingw("i386") + checkAndAddClang() + end + + local result = { + compilerList = compilerList, + noSearch = noSearch, + preferCompiler = preferCompiler, + } + + return result end - -if appArch == "x86_64" then - checkAndAddMingw("x86_64") - checkAndAddClang() -elseif appArch == "arm64" then - checkAndAddClang() -else - checkAndAddMingw("i386") - checkAndAddClang() -end - -local result = { - compilerList = compilerList, - noSearch = noSearch, - preferCompiler = preferCompiler, -} - -return result From 613b2a5cffd763a8ceba12bea731c5ec70a2d425 Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Mon, 19 Feb 2024 17:18:34 +0800 Subject: [PATCH 03/16] Update Windows on Arm build script (#185) * update woa build script: move out llvm libs preparation * update woa compiler hint: remove armv7; simplify UTF-8 objects * update woa build script: merge system and user installer * update woa: fix gcc utf8 --- addon/compiler_hint/windows_domain.tl | 109 ++++++------- packages/msys/domain/build.sh | 60 ++------ packages/msys/domain/compiler_hint.lua | 105 ++++++------- packages/msys/domain/lang.nsh | 4 +- packages/msys/domain/main.nsi | 205 ++++++++++--------------- 5 files changed, 194 insertions(+), 289 deletions(-) diff --git a/addon/compiler_hint/windows_domain.tl b/addon/compiler_hint/windows_domain.tl index 9c818414..7ebdcfbc 100644 --- a/addon/compiler_hint/windows_domain.tl +++ b/addon/compiler_hint/windows_domain.tl @@ -9,7 +9,6 @@ end local gnuArchMap: {string:string} = { i386 = "i686", x86_64 = "x86_64", - arm = "armv7", arm64 = "aarch64", } @@ -199,39 +198,42 @@ global function main(): CompilerHint resourceCompiler = binDir .. "/windres.exe", binDirs = {binDir}, } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } - local release, debug_, debugWithAsan = generateConfig( - function (arch_: string, profile: string): string - return nameGeneratorMingwGcc(lang, arch_, profile, true) - end, - programs, - { - arch = arch, - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, - } - ) - table.insert(compilerList, release) - table.insert(compilerList, debug_) - if preferCompiler == 0 then - preferCompiler = 2 + if C_FileSystem.exists(libDir .. "/libutf8.a") then + local release, debug_, _ = generateConfig( + function (arch_: string, profile: string): string + return nameGeneratorMingwGcc(lang, arch_, profile, true) + end, + programs, + { + arch = arch, + customLinkParams = {"-Wl,--whole-archive", "-lutf8", "-Wl,--no-whole-archive"}, + } + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if preferCompiler == 0 then + preferCompiler = 2 + end end - release, debug_, debugWithAsan = generateConfig( - function (arch_: string, profile: string): string - return nameGeneratorMingwGcc(lang, arch_, profile, false) - end, - programs, - { - arch = arch, - isAnsi = true, - } - ) - table.insert(compilerList, release) - table.insert(compilerList, debug_) + do + local release, debug_, _ = generateConfig( + function (arch_: string, profile: string): string + return nameGeneratorMingwGcc(lang, arch_, profile, false) + end, + programs, + { + arch = arch, + isAnsi = true, + } + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if preferCompiler == 0 then + preferCompiler = 2 + end + end table.insert(noSearch, excludeBinDir) end @@ -243,9 +245,9 @@ global function main(): CompilerHint local binDir = libexecDir .. "/llvm-mingw/bin" local appTriplet = gnuArchMap[appArch] .. "-w64-mingw32" + local appDllDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/bin" do -- appArch is always debuggable - local libDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/lib" local programs: Programs = { cCompiler = binDir .. "/" .. appTriplet .. "-clang.exe", cxxCompiler = binDir .. "/" .. appTriplet .. "-clang++.exe", @@ -253,11 +255,7 @@ global function main(): CompilerHint debugger = binDir .. "/lldb-mi.exe", debugServer = binDir .. "/lldb-server.exe", resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", - binDirs = {binDir}, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", + binDirs = {binDir, appDllDir}, } local release, debug_, debugWithAsan = generateConfig( function (arch_: string, profile: string): string @@ -266,7 +264,7 @@ global function main(): CompilerHint programs, { arch = appArch, - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + customLinkParams = {"-Wl,utf8init.o", "-Wl,utf8manifest.o"}, isClang = true, } ) @@ -285,9 +283,10 @@ global function main(): CompilerHint end for _, foreignArch in ipairs(supportedAppArches) do - if foreignArch ~= appArch then - local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" - local libDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/lib" + local gnuArch = gnuArchMap[foreignArch] + if foreignArch ~= appArch and gnuArch ~= nil then + local foreignTriplet = gnuArch .. "-w64-mingw32" + local foreignDllDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/bin" local programs: Programs = { cCompiler = binDir .. "/" .. foreignTriplet .. "-clang.exe", cxxCompiler = binDir .. "/" .. foreignTriplet .. "-clang++.exe", @@ -295,11 +294,7 @@ global function main(): CompilerHint debugger = binDir .. "/lldb-mi.exe", debugServer = binDir .. "/lldb-server.exe", resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", - binDirs = {binDir}, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", + binDirs = {binDir, foreignDllDir}, } local release, _, _ = generateConfig( function (arch_: string, profile: string): string @@ -308,7 +303,7 @@ global function main(): CompilerHint programs, { arch = foreignArch, - customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + customLinkParams = {"-Wl,utf8init.o", "-Wl,utf8manifest.o"}, isClang = true, } ) @@ -337,10 +332,6 @@ global function main(): CompilerHint binDirs = {llvmOrgBinDir}, libDirs = {libDir}, } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } local release, debug_, _ = generateConfig( function (arch: string, profile: string): string return nameGeneratorClang(lang, arch, profile, false) @@ -356,7 +347,7 @@ global function main(): CompilerHint }, customLinkParams = { "-target", msvcTriplet, - extraObjects.utf8init, extraObjects.utf8manifest, + "-Wl,utf8init.o", "-Wl,utf8manifest.o", }, isClang = true, } @@ -366,8 +357,9 @@ global function main(): CompilerHint end for _, foreignArch in ipairs(supportedAppArches) do - if foreignArch ~= appArch then - local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" + local gnuArch = gnuArchMap[foreignArch] + if foreignArch ~= appArch and gnuArch ~= nil then + local foreignTriplet = gnuArch .. "-w64-mingw32" local msvcTriplet = gnuArchMap[foreignArch] .. "-pc-windows-msvc" local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" local programs: Programs = { @@ -380,10 +372,6 @@ global function main(): CompilerHint binDirs = {llvmOrgBinDir}, libDirs = {libDir}, } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } local release, _, _ = generateConfig( function (arch: string, profile: string): string return nameGeneratorClang(lang, arch, profile, false) @@ -399,7 +387,7 @@ global function main(): CompilerHint }, customLinkParams = { "-target", msvcTriplet, - extraObjects.utf8init, extraObjects.utf8manifest, + "-Wl,utf8init.o", "-Wl,utf8manifest.o", }, isClang = true, } @@ -412,9 +400,12 @@ global function main(): CompilerHint if appArch == "x86_64" then checkAndAddMingw("x86_64") + checkAndAddMingw("i386") checkAndAddClang() elseif appArch == "arm64" then checkAndAddClang() + checkAndAddMingw("x86_64") + checkAndAddMingw("i386") else checkAndAddMingw("i386") checkAndAddClang() diff --git a/packages/msys/domain/build.sh b/packages/msys/domain/build.sh index 59f57d8e..cf649515 100644 --- a/packages/msys/domain/build.sh +++ b/packages/msys/domain/build.sh @@ -26,7 +26,7 @@ set -euxo pipefail GCC_VERSION="13.2.0" MINGW_VERSION="rt_v11-rev1" -LLVM_MINGW_TAG="20231128" +REDPANDA_LLVM_VERSION="17-r0" WINDOWS_TERMINAL_VERSION="1.18.3181.0" _QMAKE="$MINGW_PREFIX/qt5-static/bin/qmake" @@ -43,10 +43,9 @@ _MINGW64_ARCHIVE="x86_64-$GCC_VERSION-release-posix-seh-ucrt-$MINGW_VERSION.7z" _MINGW64_URL="https://github.com/niXman/mingw-builds-binaries/releases/download/$GCC_VERSION-$MINGW_VERSION/$_MINGW64_ARCHIVE" _LLVM_DIR="llvm-mingw" -_LLVM_ARCHES=("x86_64" "i686" "aarch64" "armv7") -_LLVM_ORIGINAL_DIR="llvm-mingw-$LLVM_MINGW_TAG-ucrt-$_NATIVE_ARCH" -_LLVM_ARCHIVE="$_LLVM_ORIGINAL_DIR.zip" -_LLVM_URL="https://github.com/mstorsjo/llvm-mingw/releases/download/$LLVM_MINGW_TAG/$_LLVM_ARCHIVE" +_LLVM_ARCHES=("x86_64" "i686" "aarch64") +_LLVM_ARCHIVE="$_LLVM_DIR-$REDPANDA_LLVM_VERSION-$_NATIVE_ARCH.7z" +_LLVM_URL="https://github.com/redpanda-cpp/toolchain-win32-llvm/releases/download/$REDPANDA_LLVM_VERSION/$_LLVM_ARCHIVE" _WINDOWS_TERMINAL_DIR="terminal-${WINDOWS_TERMINAL_VERSION}" _WINDOWS_TERMINAL_ARCHIVE="Microsoft.WindowsTerminal_${WINDOWS_TERMINAL_VERSION}_$_DISPLAY_ARCH.zip" @@ -103,7 +102,7 @@ function check-deps() { $MINGW_PACKAGE_PREFIX-{$compiler,make,qt5-static} mingw-w64-i686-nsis ) - [[ _7Z_REPACK -eq 1 ]] || deps+=("$MINGW_PACKAGE_PREFIX-7zip") + [[ _7Z_REPACK -eq 1 ]] && deps+=("$MINGW_PACKAGE_PREFIX-7zip") for dep in "${deps[@]}"; do pacman -Q "$dep" >/dev/null 2>&1 || ( echo "Missing dependency: $dep" @@ -113,7 +112,10 @@ function check-deps() { } function prepare-dirs() { - [[ $_CLEAN -eq 1 ]] && rm -rf "$_BUILDDIR" "$_PKGDIR" || true + if [[ $_CLEAN -eq 1 ]]; then + [[ -d "$_BUILDDIR" ]] && rm -rf "$_BUILDDIR" + [[ -d "$_PKGDIR" ]] && rm -rf "$_PKGDIR" + fi mkdir -p "$_ASSETSDIR" "$_BUILDDIR" "$_PKGDIR" "$_DISTDIR" } @@ -144,37 +146,7 @@ function prepare-mingw() { { gcc -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o "$mingw_lib_dir/utf8init.o" "$_SRCDIR/platform/windows/utf8/utf8init.cpp" windres -O coff -o "$mingw_lib_dir/utf8manifest.o" "$_SRCDIR/platform/windows/utf8/utf8manifest.rc" - } - export PATH="$old_path" - fi -} - -function prepare-llvm-mingw() { - local llvm_dir="$_BUILDDIR/$_LLVM_DIR" - if [[ ! -d "$llvm_dir" ]]; then - bsdtar -C "$_BUILDDIR" -xf "$_ASSETSDIR/$_LLVM_ARCHIVE" - mv "$_BUILDDIR/$_LLVM_ORIGINAL_DIR" "$llvm_dir" - local old_path="$PATH" - export PATH="$llvm_dir/bin:$PATH" - for arch in "${_LLVM_ARCHES[@]}"; do - local triplet="$arch-w64-mingw32" - local lib_dir="$llvm_dir/$triplet/lib" - $triplet-clang -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o "$lib_dir/utf8init.o" "$_SRCDIR/platform/windows/utf8/utf8init.cpp" - $triplet-windres -O coff -o "$lib_dir/utf8manifest.o" "$_SRCDIR/platform/windows/utf8/utf8manifest.rc" - - local msvc_triplet="$arch-pc-windows-msvc" - local lib_dir="$llvm_dir/$msvc_triplet/lib" - mkdir -p "$lib_dir" - $triplet-clang -target $msvc_triplet -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o "$lib_dir/utf8init.o" "$_SRCDIR/platform/windows/utf8/utf8init.cpp" - $triplet-windres -O coff -o "$lib_dir/utf8manifest.o" "$_SRCDIR/platform/windows/utf8/utf8manifest.rc" - done - { - local triplet="x86_64-w64-mingw32" - local msvc_triplet="arm64ec-pc-windows-msvc" - local lib_dir="$llvm_dir/$msvc_triplet/lib" - mkdir -p "$lib_dir" - $triplet-clang -target $msvc_triplet -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o "$lib_dir/utf8init.o" "$_SRCDIR/platform/windows/utf8/utf8init.cpp" - $triplet-windres -O coff -o "$lib_dir/utf8manifest.o" "$_SRCDIR/platform/windows/utf8/utf8manifest.rc" + ar rcs "$mingw_lib_dir/libutf8.a" "$mingw_lib_dir/utf8init.o" "$mingw_lib_dir/utf8manifest.o" } export PATH="$old_path" fi @@ -210,17 +182,15 @@ function build() { if [[ $_NATIVE_ARCH == x86_64 ]]; then [[ -d "$_PKGDIR/mingw64" ]] || cp -r "mingw64" "$_PKGDIR" fi - [[ -d "$_PKGDIR/llvm-mingw" ]] || cp -r "llvm-mingw" "$_PKGDIR" + [[ -d "$_PKGDIR/llvm-mingw" ]] || bsdtar -C "$_PKGDIR" -xf "$_ASSETSDIR/$_LLVM_ARCHIVE" popd } function package() { pushd "$_PKGDIR" - "$_NSIS" -DVERSION="$_REDPANDA_VERSION" -DARCH="$_DISPLAY_ARCH" main.nsi & - "$_NSIS" -DVERSION="$_REDPANDA_VERSION" -DARCH="$_DISPLAY_ARCH" -DUSER_MODE main.nsi & - wait + "$_NSIS" -DVERSION="$_REDPANDA_VERSION" -DARCH="$_DISPLAY_ARCH" main.nsi if [[ _7Z_REPACK -eq 1 ]]; then - 7z x "redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH-user.exe" -o"RedPanda-CPP" -xr'!$PLUGINSDIR' -x"!uninstall.exe" + 7z x "redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH.exe" -o"RedPanda-CPP" -xr'!$PLUGINSDIR' -x"!uninstall.exe" 7z a -t7z -mx=9 -ms=on -mqs=on -mf=BCJ2 -m0="LZMA2:d=128m:fb=273:c=2g" "redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH.7z" "RedPanda-CPP" rm -rf "RedPanda-CPP" fi @@ -228,8 +198,7 @@ function package() { } function dist() { - cp "$_PKGDIR/redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH-system.exe" "$_DISTDIR" - cp "$_PKGDIR/redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH-user.exe" "$_DISTDIR" + cp "$_PKGDIR/redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH.exe" "$_DISTDIR" [[ _7Z_REPACK -eq 1 ]] && cp "$_PKGDIR/redpanda-cpp-$_REDPANDA_VERSION-$_DISPLAY_ARCH.7z" "$_DISTDIR" } @@ -238,7 +207,6 @@ prepare-dirs download-assets [[ $_NATIVE_ARCH == i686 ]] && prepare-mingw 32 [[ $_NATIVE_ARCH == x86_64 ]] && prepare-mingw 64 -prepare-llvm-mingw prepare-openconsole prepare-src trap restore-src EXIT INT TERM diff --git a/packages/msys/domain/compiler_hint.lua b/packages/msys/domain/compiler_hint.lua index 2fc454a3..85bdca84 100644 --- a/packages/msys/domain/compiler_hint.lua +++ b/packages/msys/domain/compiler_hint.lua @@ -9,7 +9,6 @@ end local gnuArchMap = { i386 = "i686", x86_64 = "x86_64", - arm = "armv7", arm64 = "aarch64", } @@ -199,39 +198,42 @@ function main() resourceCompiler = binDir .. "/windres.exe", binDirs = { binDir }, } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } - local release, debug_, debugWithAsan = generateConfig( - function(arch_, profile) - return nameGeneratorMingwGcc(lang, arch_, profile, true) - end, - programs, - { - arch = arch, - customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, - }) + if C_FileSystem.exists(libDir .. "/libutf8.a") then + local release, debug_, _ = generateConfig( + function(arch_, profile) + return nameGeneratorMingwGcc(lang, arch_, profile, true) + end, + programs, + { + arch = arch, + customLinkParams = { "-Wl,--whole-archive", "-lutf8", "-Wl,--no-whole-archive" }, + }) - table.insert(compilerList, release) - table.insert(compilerList, debug_) - if preferCompiler == 0 then - preferCompiler = 2 + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if preferCompiler == 0 then + preferCompiler = 2 + end end - release, debug_, debugWithAsan = generateConfig( - function(arch_, profile) - return nameGeneratorMingwGcc(lang, arch_, profile, false) - end, - programs, - { - arch = arch, - isAnsi = true, - }) + do + local release, debug_, _ = generateConfig( + function(arch_, profile) + return nameGeneratorMingwGcc(lang, arch_, profile, false) + end, + programs, + { + arch = arch, + isAnsi = true, + }) - table.insert(compilerList, release) - table.insert(compilerList, debug_) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + if preferCompiler == 0 then + preferCompiler = 2 + end + end table.insert(noSearch, excludeBinDir) end @@ -243,9 +245,9 @@ function main() local binDir = libexecDir .. "/llvm-mingw/bin" local appTriplet = gnuArchMap[appArch] .. "-w64-mingw32" + local appDllDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/bin" do - local libDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/lib" local programs = { cCompiler = binDir .. "/" .. appTriplet .. "-clang.exe", cxxCompiler = binDir .. "/" .. appTriplet .. "-clang++.exe", @@ -253,11 +255,7 @@ function main() debugger = binDir .. "/lldb-mi.exe", debugServer = binDir .. "/lldb-server.exe", resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe", - binDirs = { binDir }, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", + binDirs = { binDir, appDllDir }, } local release, debug_, debugWithAsan = generateConfig( function(arch_, profile) @@ -266,7 +264,7 @@ function main() programs, { arch = appArch, - customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + customLinkParams = { "-Wl,utf8init.o", "-Wl,utf8manifest.o" }, isClang = true, }) @@ -285,9 +283,10 @@ function main() end for _, foreignArch in ipairs(supportedAppArches) do - if foreignArch ~= appArch then - local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" - local libDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/lib" + local gnuArch = gnuArchMap[foreignArch] + if foreignArch ~= appArch and gnuArch ~= nil then + local foreignTriplet = gnuArch .. "-w64-mingw32" + local foreignDllDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/bin" local programs = { cCompiler = binDir .. "/" .. foreignTriplet .. "-clang.exe", cxxCompiler = binDir .. "/" .. foreignTriplet .. "-clang++.exe", @@ -295,11 +294,7 @@ function main() debugger = binDir .. "/lldb-mi.exe", debugServer = binDir .. "/lldb-server.exe", resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe", - binDirs = { binDir }, - } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", + binDirs = { binDir, foreignDllDir }, } local release, _, _ = generateConfig( function(arch_, profile) @@ -308,7 +303,7 @@ function main() programs, { arch = foreignArch, - customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + customLinkParams = { "-Wl,utf8init.o", "-Wl,utf8manifest.o" }, isClang = true, }) @@ -337,10 +332,6 @@ function main() binDirs = { llvmOrgBinDir }, libDirs = { libDir }, } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } local release, debug_, _ = generateConfig( function(arch, profile) return nameGeneratorClang(lang, arch, profile, false) @@ -356,7 +347,7 @@ function main() }, customLinkParams = { "-target", msvcTriplet, - extraObjects.utf8init, extraObjects.utf8manifest, + "-Wl,utf8init.o", "-Wl,utf8manifest.o", }, isClang = true, }) @@ -366,8 +357,9 @@ function main() end for _, foreignArch in ipairs(supportedAppArches) do - if foreignArch ~= appArch then - local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32" + local gnuArch = gnuArchMap[foreignArch] + if foreignArch ~= appArch and gnuArch ~= nil then + local foreignTriplet = gnuArch .. "-w64-mingw32" local msvcTriplet = gnuArchMap[foreignArch] .. "-pc-windows-msvc" local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib" local programs = { @@ -380,10 +372,6 @@ function main() binDirs = { llvmOrgBinDir }, libDirs = { libDir }, } - local extraObjects = { - utf8init = libDir .. "/utf8init.o", - utf8manifest = libDir .. "/utf8manifest.o", - } local release, _, _ = generateConfig( function(arch, profile) return nameGeneratorClang(lang, arch, profile, false) @@ -399,7 +387,7 @@ function main() }, customLinkParams = { "-target", msvcTriplet, - extraObjects.utf8init, extraObjects.utf8manifest, + "-Wl,utf8init.o", "-Wl,utf8manifest.o", }, isClang = true, }) @@ -412,9 +400,12 @@ function main() if appArch == "x86_64" then checkAndAddMingw("x86_64") + checkAndAddMingw("i386") checkAndAddClang() elseif appArch == "arm64" then checkAndAddClang() + checkAndAddMingw("x86_64") + checkAndAddMingw("i386") else checkAndAddMingw("i386") checkAndAddClang() diff --git a/packages/msys/domain/lang.nsh b/packages/msys/domain/lang.nsh index b718b1c5..83524342 100644 --- a/packages/msys/domain/lang.nsh +++ b/packages/msys/domain/lang.nsh @@ -16,7 +16,7 @@ LangString MessageSectionAssocs 1033 "Use Red Panda C++ as the default applicati LangString MessageSectionShortcuts 1033 "Create shortcuts to Red Panda C++ in various folders." LangString MessageSectionConfig 1033 "Remove all leftover configuration files from previous installs." LangString MessageUninstallText 1033 "This program will uninstall Red Panda C++, continue?" -LangString MessageUninstallExisting 1033 "Red Panda C++ is already installed.$\n$\nClick OK to remove the previous version or Cancel to cancel the installation." +LangString MessageUninstallingExisting 1033 "Removing previous installation." LangString MessageRemoveConfig 1033 "Do you want to remove all the remaining configuration files?" LangString SectionMainName 1033 "Program files (required)" LangString SectionOpenConsoleName 1033 "OpenConsole.exe terminal emulator" @@ -49,7 +49,7 @@ LangString MessageSectionAssocs 2052 "使用小熊猫 C++ 打开这些文件。" LangString MessageSectionShortcuts 2052 "开始菜单和快捷方式。" LangString MessageSectionConfig 2052 "删除之前安装遗留的所有配置文件。" LangString MessageUninstallText 2052 "将要删除小熊猫 C++,是否继续?" -LangString MessageUninstallExisting 2052 "本机上已经安装了旧版本小熊猫 C++。 $\n$\n点击“确定”以将其删除并继续,或者“取消”中止安装。" +LangString MessageUninstallingExisting 2052 "正在删除之前的安装。" LangString MessageRemoveConfig 2052 "你想要删除所有的配置文件吗?" LangString SectionMainName 2052 "程序文件(必需)" LangString SectionOpenConsoleName 2052 "OpenConsole.exe 终端模拟器" diff --git a/packages/msys/domain/main.nsi b/packages/msys/domain/main.nsi index 400ca71f..0bddc4e4 100644 --- a/packages/msys/domain/main.nsi +++ b/packages/msys/domain/main.nsi @@ -7,16 +7,24 @@ SetCompressorDictSize 128 SetDatablockOptimize on Unicode True -!ifdef USER_MODE - !define MODE "user" -!else - !define MODE "system" +!define FINALNAME "redpanda-cpp-${VERSION}-${ARCH}.exe" +!define DISPLAY_NAME "Red Panda C++ ${VERSION} (${ARCH})" + +!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" +!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}" +!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser" +!define MULTIUSER_INSTALLMODE_INSTDIR "RedPanda-CPP" +!define MULTIUSER_EXECUTIONLEVEL Highest +!define MULTIUSER_MUI +!define MULTIUSER_INSTALLMODE_COMMANDLINE + +!if "${ARCH}" != "x86" + !define MULTIUSER_USE_PROGRAMFILES64 !endif -!define FINALNAME "redpanda-cpp-${VERSION}-${ARCH}-${MODE}.exe" -!define DISPLAY_NAME "Red Panda C++ ${VERSION} (${ARCH} ${MODE})" !include "x64.nsh" !include "WinVer.nsh" +!include "MultiUser.nsh" !include "MUI2.nsh" !include "lang.nsh" @@ -31,18 +39,6 @@ Caption "${DISPLAY_NAME}" LicenseData "LICENSE" -!ifdef USER_MODE - RequestExecutionLevel user - InstallDir "$LOCALAPPDATA\RedPanda-CPP" -!else - RequestExecutionLevel admin - !if "${ARCH}" == "x86" - InstallDir "$PROGRAMFILES\RedPanda-CPP" - !else - InstallDir "$PROGRAMFILES64\RedPanda-CPP" - !endif -!endif - #################################################################### # Interface Settings @@ -56,15 +52,6 @@ ManifestDPIAware true InstType "Full" ;1 InstType "Minimal" ;2 -## Remember the installer language -!ifdef USER_MODE - !define MUI_LANGDLL_REGISTRY_ROOT "HKCU" -!else - !define MUI_LANGDLL_REGISTRY_ROOT "HKLM" -!endif -!define MUI_LANGDLL_REGISTRY_KEY "Software\RedPanda-C++" -!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" - #################################################################### # Pages @@ -77,6 +64,7 @@ InstType "Minimal" ;2 !define MUI_COMPONENTSPAGE_SMALLDESC !insertmacro MUI_PAGE_LICENSE "LICENSE" +!insertmacro MULTIUSER_PAGE_INSTALLMODE !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES @@ -90,6 +78,16 @@ InstType "Minimal" ;2 !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "SimpChinese" +Section "" SecUninstallPrevious + SetRegView 32 + Call UninstallExisting + SetRegView 64 + Call UninstallExisting +!if "${ARCH}" == "x86" + SetRegView 32 +!endif +SectionEnd + #################################################################### # Files, by option section @@ -100,21 +98,13 @@ Section "$(SectionMainName)" SectionMain ; Allways create an uninstaller WriteUninstaller "$INSTDIR\uninstall.exe" -!ifdef USER_MODE - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "DisplayName" "Red Panda C++" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "InstallLocation" "$INSTDIR" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "UninstallString" "$INSTDIR\uninstall.exe" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "DisplayVersion" "${VERSION}" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "DisplayIcon" "$INSTDIR\RedPandaIDE.exe" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "Publisher" "Roy Qu (royqh1979@gmail.com)" -!else - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "DisplayName" "Red Panda C++" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "InstallLocation" "$INSTDIR" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "UninstallString" "$INSTDIR\uninstall.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "DisplayVersion" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "DisplayIcon" "$INSTDIR\RedPandaIDE.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "Publisher" "Roy Qu (royqh1979@gmail.com)" -!endif + WriteRegStr ShCtx "${UNINSTKEY}" "DisplayName" "Red Panda C++" + WriteRegStr ShCtx "${UNINSTKEY}" "InstallLocation" "$INSTDIR" + WriteRegStr ShCtx "${UNINSTKEY}" "UninstallString" "$INSTDIR\uninstall.exe" + WriteRegStr ShCtx "${UNINSTKEY}" "DisplayVersion" "${VERSION}" + WriteRegStr ShCtx "${UNINSTKEY}" "DisplayIcon" "$INSTDIR\RedPandaIDE.exe" + WriteRegStr ShCtx "${UNINSTKEY}" "Publisher" "Roy Qu (royqh1979@gmail.com)" + WriteRegStr ShCtx "${UNINSTKEY}" $MultiUser.InstallMode 1 ; Write required files File "RedPandaIDE.exe" @@ -167,80 +157,80 @@ SectionGroup "$(SectionAssocsName)" SectionAssocs SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".dev" "" "DevCpp.dev" - WriteRegStr HKCR "DevCpp.dev" "" "Dev-C++ Project File" - WriteRegStr HKCR "DevCpp.dev\DefaultIcon" "" '$0,3' - WriteRegStr HKCR "DevCpp.dev\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.dev" "" "DevCpp.dev" + WriteRegStr ShCtx "Software\Classes\DevCpp.dev" "" "Dev-C++ Project File" + WriteRegStr ShCtx "Software\Classes\DevCpp.dev\DefaultIcon" "" '$0,3' + WriteRegStr ShCtx "Software\Classes\DevCpp.dev\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .c $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".c" "" "DevCpp.c" - WriteRegStr HKCR "DevCpp.c" "" "C Source File" - WriteRegStr HKCR "DevCpp.c\DefaultIcon" "" '$0,4' - WriteRegStr HKCR "DevCpp.c\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.c" "" "DevCpp.c" + WriteRegStr ShCtx "Software\Classes\DevCpp.c" "" "C Source File" + WriteRegStr ShCtx "Software\Classes\DevCpp.c\DefaultIcon" "" '$0,4' + WriteRegStr ShCtx "Software\Classes\DevCpp.c\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .cpp $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".cpp" "" "DevCpp.cpp" - WriteRegStr HKCR "DevCpp.cpp" "" "C++ Source File" - WriteRegStr HKCR "DevCpp.cpp\DefaultIcon" "" '$0,5' - WriteRegStr HKCR "DevCpp.cpp\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.cpp" "" "DevCpp.cpp" + WriteRegStr ShCtx "Software\Classes\DevCpp.cpp" "" "C++ Source File" + WriteRegStr ShCtx "Software\Classes\DevCpp.cpp\DefaultIcon" "" '$0,5' + WriteRegStr ShCtx "Software\Classes\DevCpp.cpp\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .cxx $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".cxx" "" "DevCpp.cxx" - WriteRegStr HKCR "DevCpp.cxx" "" "C++ Source File" - WriteRegStr HKCR "DevCpp.cxx\DefaultIcon" "" '$0,5' - WriteRegStr HKCR "DevCpp.cxx\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.cxx" "" "DevCpp.cxx" + WriteRegStr ShCtx "Software\Classes\DevCpp.cxx" "" "C++ Source File" + WriteRegStr ShCtx "Software\Classes\DevCpp.cxx\DefaultIcon" "" '$0,5' + WriteRegStr ShCtx "Software\Classes\DevCpp.cxx\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .cc $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".cc" "" "DevCpp.cc" - WriteRegStr HKCR "DevCpp.cc" "" "C++ Source File" - WriteRegStr HKCR "DevCpp.cc\DefaultIcon" "" '$0,5' - WriteRegStr HKCR "DevCpp.cc\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.cc" "" "DevCpp.cc" + WriteRegStr ShCtx "Software\Classes\DevCpp.cc" "" "C++ Source File" + WriteRegStr ShCtx "Software\Classes\DevCpp.cc\DefaultIcon" "" '$0,5' + WriteRegStr ShCtx "Software\Classes\DevCpp.cc\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .hxx $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".hxx" "" "DevCpp.hxx" - WriteRegStr HKCR "DevCpp.hxx" "" "C++ Header File" - WriteRegStr HKCR "DevCpp.hxx\DefaultIcon" "" '$0,7' - WriteRegStr HKCR "DevCpp.hxx\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.hxx" "" "DevCpp.hxx" + WriteRegStr ShCtx "Software\Classes\DevCpp.hxx" "" "C++ Header File" + WriteRegStr ShCtx "Software\Classes\DevCpp.hxx\DefaultIcon" "" '$0,7' + WriteRegStr ShCtx "Software\Classes\DevCpp.hxx\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .h $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".h" "" "DevCpp.h" - WriteRegStr HKCR "DevCpp.h" "" "C Header File" - WriteRegStr HKCR "DevCpp.h\DefaultIcon" "" '$0,6' - WriteRegStr HKCR "DevCpp.h\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.h" "" "DevCpp.h" + WriteRegStr ShCtx "Software\Classes\DevCpp.h" "" "C Header File" + WriteRegStr ShCtx "Software\Classes\DevCpp.h\DefaultIcon" "" '$0,6' + WriteRegStr ShCtx "Software\Classes\DevCpp.h\Shell\Open\Command" "" '$0 "%1"' SectionEnd Section "$(SectionAssocExtNameBegin) .hpp $(SectionAssocExtNameEnd)" SectionIn 1 StrCpy $0 $INSTDIR\RedPandaIDE.exe - WriteRegStr HKCR ".hpp" "" "DevCpp.hpp" - WriteRegStr HKCR "DevCpp.hpp" "" "C++ Header File" - WriteRegStr HKCR "DevCpp.hpp\DefaultIcon" "" '$0,7' - WriteRegStr HKCR "DevCpp.hpp\Shell\Open\Command" "" '$0 "%1"' + WriteRegStr ShCtx "Software\Classes\.hpp" "" "DevCpp.hpp" + WriteRegStr ShCtx "Software\Classes\DevCpp.hpp" "" "C++ Header File" + WriteRegStr ShCtx "Software\Classes\DevCpp.hpp\DefaultIcon" "" '$0,7' + WriteRegStr ShCtx "Software\Classes\DevCpp.hpp\Shell\Open\Command" "" '$0 "%1"' SectionEnd SectionGroupEnd @@ -264,11 +254,9 @@ SectionGroup "$(SectionShortcutsName)" SectionShortcuts SectionEnd SectionGroupEnd -!ifdef USER_MODE Section "$(SectionConfigName)" SectionConfig RMDir /r "$APPDATA\RedPandaIDE" SectionEnd -!endif #################################################################### @@ -284,23 +272,17 @@ SectionEnd !insertmacro MUI_DESCRIPTION_TEXT ${SectionLlvm} "$(MessageSectionLlvm)" !insertmacro MUI_DESCRIPTION_TEXT ${SectionShortcuts} "$(MessageSectionShortcuts)" !insertmacro MUI_DESCRIPTION_TEXT ${SectionAssocs} "$(MessageSectionAssocs)" -!ifdef USER_MODE !insertmacro MUI_DESCRIPTION_TEXT ${SectionConfig} "$(MessageSectionConfig)" -!endif !insertmacro MUI_FUNCTION_DESCRIPTION_END #################################################################### # Functions, utilities Function .onInit + !insertmacro MULTIUSER_INIT !insertmacro MUI_LANGDLL_DISPLAY !if "${ARCH}" != "x86" SetRegView 64 -!endif -!ifdef USER_MODE - SetShellVarContext current -!else - SetShellVarContext all !endif ${IfNot} ${AtLeastBuild} 17763 ; OpenConsole.exe requires Windows 10 v1809 ConPTY !if "${ARCH}" == "x86" @@ -343,14 +325,6 @@ Function myGuiInit Abort ${EndIf} !endif - - SetRegView 32 - Call UninstallExisting - SetRegView 64 - Call UninstallExisting -!if "${ARCH}" == "x86" - SetRegView 32 -!endif FunctionEnd Function .onSelChange @@ -363,32 +337,21 @@ Function .onSelChange FunctionEnd Function un.onInit + !insertmacro MULTIUSER_UNINIT !insertmacro MUI_UNGETLANGUAGE !if "${ARCH}" != "x86" SetRegView 64 !endif -!ifdef USER_MODE - SetShellVarContext current -!else - SetShellVarContext all -!endif FunctionEnd Function UninstallExisting -!ifdef USER_MODE - ReadRegStr $R0 HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "UninstallString" -!else - ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" "UninstallString" -!endif + ReadRegStr $R0 ShCtx "${UNINSTKEY}" "UninstallString" ${If} $R0 != "" GetFullPathName $R1 "$R0\.." ; remove \uninstall.exe - MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ - "$(MessageUninstallExisting)" \ - IDOK uninst - Abort - uninst: - ClearErrors - ExecWait '"$R0" /S _?=$R1' + DetailPrint "$(MessageUninstallingExisting)" + ExecWait '"$R0" /S _?=$R1' + Delete $R0 + RMDir $R1 ${EndIf} FunctionEnd @@ -412,14 +375,14 @@ Section "Uninstall" Delete "$QUICKLAUNCH\$(MessageAppName).lnk" Delete "$DESKTOP\$(MessageAppName).lnk" - DeleteRegKey HKCR "DevCpp.dev" - DeleteRegKey HKCR "DevCpp.c" - DeleteRegKey HKCR "DevCpp.cpp" - DeleteRegKey HKCR "DevCpp.cxx" - DeleteRegKey HKCR "DevCpp.cc" - DeleteRegKey HKCR "DevCpp.h" - DeleteRegKey HKCR "DevCpp.hpp" - DeleteRegKey HKCR "DevCpp.hxx" + DeleteRegKey ShCtx "Software\Classes\DevCpp.dev" + DeleteRegKey ShCtx "Software\Classes\DevCpp.c" + DeleteRegKey ShCtx "Software\Classes\DevCpp.cpp" + DeleteRegKey ShCtx "Software\Classes\DevCpp.cxx" + DeleteRegKey ShCtx "Software\Classes\DevCpp.cc" + DeleteRegKey ShCtx "Software\Classes\DevCpp.h" + DeleteRegKey ShCtx "Software\Classes\DevCpp.hpp" + DeleteRegKey ShCtx "Software\Classes\DevCpp.hxx" Delete "$INSTDIR\NEWS.md" Delete "$INSTDIR\RedPandaIDE.exe" @@ -440,17 +403,9 @@ Section "Uninstall" RMDir "$INSTDIR" ; Remove registry keys -!ifdef USER_MODE - DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" - DeleteRegKey HKCU "Software\RedPanda-C++" -!else - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RedPanda-C++" - DeleteRegKey HKLM "Software\RedPanda-C++" -!endif + DeleteRegKey ShCtx "${UNINSTKEY}" -!ifdef USER_MODE MessageBox MB_YESNO "$(MessageRemoveConfig)" /SD IDNO IDNO SkipRemoveConfig RMDir /r "$APPDATA\RedPandaIDE" SkipRemoveConfig: -!endif SectionEnd From b4cfc7b98d62edf862ac9d512f34b2a369a29222 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Mon, 19 Feb 2024 17:56:15 +0800 Subject: [PATCH 04/16] fix: Can't correctly suggest a variable defined by a typedef-ed type. --- RedPandaIDE/RedPandaIDE.pro | 2 +- RedPandaIDE/parser/cppparser.cpp | 2 +- Red_Panda_CPP.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 10c2b038..7867df35 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -17,7 +17,7 @@ APP_NAME = RedPandaCPP APP_VERSION = 2.26 -TEST_VERSION = beta1 +TEST_VERSION = beta2 contains(QMAKE_HOST.arch, x86_64):{ DEFINES += ARCH_X86_64=1 } else: { diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 964d44eb..14d1c2ce 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -5875,7 +5875,7 @@ PStatement CppParser::doParseEvalTypeInfo( } else if (token == ">") { templateLevel--; } - baseType += token; + templateParams += token; } syntaxer.next(); } diff --git a/Red_Panda_CPP.pro b/Red_Panda_CPP.pro index 6b5b6549..84d36729 100644 --- a/Red_Panda_CPP.pro +++ b/Red_Panda_CPP.pro @@ -23,7 +23,7 @@ APP_NAME = RedPandaCPP APP_VERSION = 2.26 -TEST_VERSION = beta1 +TEST_VERSION = beta2 win32: { SUBDIRS += \ From 53be5a9f3d11fa8214a36ed5b3cad2ff928eff7b Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Mon, 19 Feb 2024 18:24:29 +0800 Subject: [PATCH 05/16] Add MinGW support to deb amd64 (#187) * update git attributes * add mingw support to debian package * fix build deps --- .gitattributes | 4 + addon/compiler_hint/debian.tl | 246 ++++++++++++++++++++++++++++++ addon/gen.sh | 1 + packages/debian/01-in-docker.sh | 3 +- packages/debian/builddeb.sh | 1 + packages/debian/compiler_hint.lua | 246 ++++++++++++++++++++++++++++++ packages/debian/control | 10 +- packages/debian/rules | 29 ++++ 8 files changed, 538 insertions(+), 2 deletions(-) create mode 100644 addon/compiler_hint/debian.tl create mode 100644 packages/debian/compiler_hint.lua diff --git a/.gitattributes b/.gitattributes index e7898d5a..a44d14b3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -27,3 +27,7 @@ /platform/linux/templates/*/*.template eol=lf /platform/linux/templates/*/*.fs eol=lf /platform/linux/templates/*/*.vs eol=lf + +# generated files +compiler_hint.lua eol=lf +/RedPandaIDE/themes/*.lua eol=lf diff --git a/addon/compiler_hint/debian.tl b/addon/compiler_hint/debian.tl new file mode 100644 index 00000000..75bf7bd1 --- /dev/null +++ b/addon/compiler_hint/debian.tl @@ -0,0 +1,246 @@ +global function apiVersion(): ApiVersion + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end + +local nameMap: {string:{string:string}} = { + systemGcc = { + en_US = "System GCC", + pt_BR = "GCC do sistema", + zh_CN = "系统 GCC", + zh_TW = "系統 GCC", + }, + systemClang = { + en_US = "System Clang", + pt_BR = "Clang do sistema", + zh_CN = "系统 Clang", + zh_TW = "系統 Clang", + }, + multilibGcc = { + en_US = "Multilib GCC", + pt_BR = "GCC multilib", + zh_CN = "Multilib GCC", + zh_TW = "Multilib GCC", + }, + multilibClang = { + en_US = "Multilib Clang", + pt_BR = "Clang multilib", + zh_CN = "Multilib Clang", + zh_TW = "Multilib Clang", + }, + mingwGcc = { + en_US = "MinGW GCC", + pt_BR = "GCC MinGW", + zh_CN = "MinGW GCC", + zh_TW = "MinGW GCC", + }, + release = { + en_US = ", release", + pt_BR = ", lançamento", + zh_CN = ",发布", + zh_TW = ",發佈", + }, + debug = { + en_US = ", debug", + pt_BR = ", depuração", + zh_CN = ",调试", + zh_TW = ",偵錯", + }, + debugWithAsan = { + en_US = ", debug with ASan", + pt_BR = ", depuração com ASan", + zh_CN = ",ASan 调试", + zh_TW = ",ASan 偵錯", + }, +} + +local function mergeCompilerSet(compilerSet: CompilerHint.CompilerSet, other: CompilerHint.CompilerSet) + local c = compilerSet as {string:any} + local o = other as {string:any} + for k, v in pairs(o) do + c[k] = v + end +end + +local record Config + isMultilib: boolean | nil + isMingw: boolean | nil + isClang: boolean | nil + customCompileParams: {string} | nil + customLinkParams: {string} | nil + triplet: string | nil +end + +local function generateConfig( + name: string, lang: string, + cCompiler: string, cxxCompiler: string, + config: Config +): CompilerHint.CompilerSet, CompilerHint.CompilerSet, CompilerHint.CompilerSet + local commonOptions: CompilerHint.CompilerSet = { + cCompiler = cCompiler, + cxxCompiler = cxxCompiler, + debugger = "/usr/bin/gdb", + debugServer = "/usr/bin/gdbserver", + make = "/usr/bin/make", + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = config.isMingw and ".exe" or "", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + binDirs = {"/usr/bin"}, + } + if config.isMultilib then + commonOptions.ccCmdOptPointerSize = "32" + end + if config.isMingw then + commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = name .. (nameMap.release[lang] or nameMap.release.en_US), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +global function main(): CompilerHint + local arch = C_System.osArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + + local compilerList = {} + + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemClang[lang] or nameMap.systemClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + {isClang = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + -- TODO: better to check 32-bit libstdc++.a (lib32stdc++-dev), but its path is not fixed + if arch == "x86_64" and C_FileSystem.exists("/usr/lib32/libc.a") then + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {isMultilib = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + {isClang = true, isMultilib = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + end + + -- with wine or WSL init registered in binfmt_misc, Windows binaries can run seamlessly + if ( + arch == "x86_64" and ( + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop") + ) + ) then + if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/x86_64-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/x86_64-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", lang, + "/usr/bin/x86_64-w64-mingw32-gcc", "/usr/bin/x86_64-w64-mingw32-g++", + { + isMingw = true, + triplet = "x86_64-w64-mingw32", + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + end + end + + if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/i686-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/i686-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", lang, + "/usr/bin/i686-w64-mingw32-gcc", "/usr/bin/i686-w64-mingw32-g++", + { + isMingw = true, + triplet = "i686-w64-mingw32", + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + end + end + end + + local result = { + compilerList = compilerList, + noSearch = { + "/usr/bin", + "/usr/lib/ccache", + }, + preferCompiler = 3, -- System GCC Debug with ASan + } + + return result + +end diff --git a/addon/gen.sh b/addon/gen.sh index 2e19e91b..04d7a556 100755 --- a/addon/gen.sh +++ b/addon/gen.sh @@ -27,3 +27,4 @@ function gen-compiler-hint() { gen-compiler-hint addon/compiler_hint/windows_domain.tl packages/msys/domain/compiler_hint.lua gen-compiler-hint addon/compiler_hint/archlinux.tl packages/archlinux/compiler_hint.lua +gen-compiler-hint addon/compiler_hint/debian.tl packages/debian/compiler_hint.lua diff --git a/packages/debian/01-in-docker.sh b/packages/debian/01-in-docker.sh index 08c1b7d0..13fa054a 100755 --- a/packages/debian/01-in-docker.sh +++ b/packages/debian/01-in-docker.sh @@ -32,7 +32,7 @@ fi export DEBIAN_FRONTEND=noninteractive apt update apt install -y --no-install-recommends \ - build-essential debhelper \ + build-essential debhelper g++-mingw-w64 \ libqt5svg5-dev qtbase5-dev qtbase5-dev-tools qttools5-dev-tools # prepare source @@ -51,6 +51,7 @@ cp Red_Panda_CPP.pro $TMP_FOLDER # build cd $TMP_FOLDER +sed -i '/CONFIG += ENABLE_LUA_ADDON/ { s/^#\s*// }' RedPandaIDE/RedPandaIDE.pro dpkg-buildpackage -us -uc -j$JOBS # copy back to host diff --git a/packages/debian/builddeb.sh b/packages/debian/builddeb.sh index 3e29a2c1..4f862b6b 100755 --- a/packages/debian/builddeb.sh +++ b/packages/debian/builddeb.sh @@ -18,4 +18,5 @@ cp -r platform $TMP_FOLDER cp Red_Panda_CPP.pro $TMP_FOLDER cd $TMP_FOLDER +sed -i '/CONFIG += ENABLE_LUA_ADDON/ { s/^#\s*// }' RedPandaIDE/RedPandaIDE.pro dpkg-buildpackage -us -uc diff --git a/packages/debian/compiler_hint.lua b/packages/debian/compiler_hint.lua new file mode 100644 index 00000000..e8c7f13a --- /dev/null +++ b/packages/debian/compiler_hint.lua @@ -0,0 +1,246 @@ +function apiVersion() + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end + +local nameMap = { + systemGcc = { + en_US = "System GCC", + pt_BR = "GCC do sistema", + zh_CN = "系统 GCC", + zh_TW = "系統 GCC", + }, + systemClang = { + en_US = "System Clang", + pt_BR = "Clang do sistema", + zh_CN = "系统 Clang", + zh_TW = "系統 Clang", + }, + multilibGcc = { + en_US = "Multilib GCC", + pt_BR = "GCC multilib", + zh_CN = "Multilib GCC", + zh_TW = "Multilib GCC", + }, + multilibClang = { + en_US = "Multilib Clang", + pt_BR = "Clang multilib", + zh_CN = "Multilib Clang", + zh_TW = "Multilib Clang", + }, + mingwGcc = { + en_US = "MinGW GCC", + pt_BR = "GCC MinGW", + zh_CN = "MinGW GCC", + zh_TW = "MinGW GCC", + }, + release = { + en_US = ", release", + pt_BR = ", lançamento", + zh_CN = ",发布", + zh_TW = ",發佈", + }, + debug = { + en_US = ", debug", + pt_BR = ", depuração", + zh_CN = ",调试", + zh_TW = ",偵錯", + }, + debugWithAsan = { + en_US = ", debug with ASan", + pt_BR = ", depuração com ASan", + zh_CN = ",ASan 调试", + zh_TW = ",ASan 偵錯", + }, +} + +local function mergeCompilerSet(compilerSet, other) + local c = compilerSet + local o = other + for k, v in pairs(o) do + c[k] = v + end +end + + + + + + + + + + +local function generateConfig( + name, lang, + cCompiler, cxxCompiler, + config) + + local commonOptions = { + cCompiler = cCompiler, + cxxCompiler = cxxCompiler, + debugger = "/usr/bin/gdb", + debugServer = "/usr/bin/gdbserver", + make = "/usr/bin/make", + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = config.isMingw and ".exe" or "", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + binDirs = { "/usr/bin" }, + } + if config.isMultilib then + commonOptions.ccCmdOptPointerSize = "32" + end + if config.isMingw then + commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = name .. (nameMap.release[lang] or nameMap.release.en_US), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +function main() + local arch = C_System.osArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + + local compilerList = {} + + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {}) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemClang[lang] or nameMap.systemClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + { isClang = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + + if arch == "x86_64" and C_FileSystem.exists("/usr/lib32/libc.a") then + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + { isMultilib = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + { isClang = true, isMultilib = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + end + + + if ( + arch == "x86_64" and ( + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop"))) then + + + if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/x86_64-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/x86_64-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", lang, + "/usr/bin/x86_64-w64-mingw32-gcc", "/usr/bin/x86_64-w64-mingw32-g++", + { + isMingw = true, + triplet = "x86_64-w64-mingw32", + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + + table.insert(compilerList, release) + end + end + + if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/i686-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/i686-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", lang, + "/usr/bin/i686-w64-mingw32-gcc", "/usr/bin/i686-w64-mingw32-g++", + { + isMingw = true, + triplet = "i686-w64-mingw32", + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + + table.insert(compilerList, release) + end + end + end + + local result = { + compilerList = compilerList, + noSearch = { + "/usr/bin", + "/usr/lib/ccache", + }, + preferCompiler = 3, + } + + return result + +end diff --git a/packages/debian/control b/packages/debian/control index 38d117a3..b742463e 100644 --- a/packages/debian/control +++ b/packages/debian/control @@ -6,7 +6,8 @@ Build-Depends: debhelper (>= 12~), qtbase5-dev, qtbase5-dev-tools, qttools5-dev-tools, - libqt5svg5-dev + libqt5svg5-dev, + g++-mingw-w64 [amd64] Standards-Version: 4.3.0 Homepage: https://github.com/royqh1979/RedPanda-CPP @@ -19,6 +20,13 @@ Depends: ${shlibs:Depends}, make, gdb, gdbserver +Recommends: qterminal | deepin-terminal | konsole | gnome-terminal | terminator | lxterminal | mate-terminal | terminology | xfce4-terminal | alacritty | cool-retro-term | kitty | sakura | termit | tilix +Suggests: clang, + gcc-multilib [amd64], + g++-multilib [amd64], + gcc-mingw-w64 [amd64], + g++-mingw-w64 [amd64], + wine [amd64] Description: A lightweight but powerful C/C++ IDE Red Panda C++ (Old name Red Panda Dev-C++ 7) is a full featured C/C++ IDE. It's the succesor of Red Panda Dev-C++ 6, which is developed by Delphi 7 and diff --git a/packages/debian/rules b/packages/debian/rules index d292cde0..acc5757b 100755 --- a/packages/debian/rules +++ b/packages/debian/rules @@ -6,3 +6,32 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: dh ${@} --buildsystem qmake + +ifeq ($(DEB_HOST_ARCH), amd64) + +MINGW_UTF8_OBJS = x86_64-w64-mingw32/utf8init.o i686-w64-mingw32/utf8init.o x86_64-w64-mingw32/utf8manifest.o i686-w64-mingw32/utf8manifest.o + +execute_after_dh_auto_build: $(MINGW_UTF8_OBJS) + +x86_64-w64-mingw32/utf8init.o: platform/windows/utf8/utf8init.cpp + mkdir -p $(dir $@) + x86_64-w64-mingw32-g++ -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o $@ $< + +x86_64-w64-mingw32/utf8manifest.o: platform/windows/utf8/utf8manifest.rc + mkdir -p $(dir $@) + x86_64-w64-mingw32-windres -O coff -o $@ $< + +i686-w64-mingw32/utf8init.o: platform/windows/utf8/utf8init.cpp + mkdir -p $(dir $@) + i686-w64-mingw32-g++ -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o $@ $< + +i686-w64-mingw32/utf8manifest.o: platform/windows/utf8/utf8manifest.rc + mkdir -p $(dir $@) + i686-w64-mingw32-windres -O coff -o $@ $< + +execute_after_dh_install: + dh_install debian/compiler_hint.lua usr/libexec/RedPandaCPP + dh_install x86_64-w64-mingw32/* usr/libexec/RedPandaCPP/x86_64-w64-mingw32 + dh_install i686-w64-mingw32/* usr/libexec/RedPandaCPP/i686-w64-mingw32 + +endif From f0c01e03aafa49d940fc4a85db0a971d193982d6 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 10:31:12 +0800 Subject: [PATCH 06/16] - Fix: Can't goto definition/declaration into files that not saved. --- NEWS.md | 1 + RedPandaIDE/editor.cpp | 5 +++-- libs/qsynedit/qsynedit/syntaxer/cpp.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9df7e5e2..907a508d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -42,6 +42,7 @@ Red Panda C++ Version 2.26 - Enhancement: add qmake variable to control preference of UTF-8 compatible OpenConsole.exe on Windows. - Enhancement: add Windows arm64 package. - Fix: Force to use debug server when debugging with lldb-mi to fix input/output on Windows. + - Fix: Can't goto definition/declaration into files that not saved. Red Panda C++ Version 2.25 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index c35bb347..683878c2 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -1373,7 +1373,6 @@ void Editor::mouseReleaseEvent(QMouseEvent *event) QString filename = mParser->getHeaderFileName(mFilename,s); pMainWindow->openFile(filename); return; - } else if (mParser->enabled()) { gotoDefinition(p); return; @@ -4674,7 +4673,9 @@ void Editor::gotoDefinition(const QSynedit::BufferCoord &pos) filename = statement->definitionFileName; line = statement->definitionLine; } - Editor *e = pMainWindow->openFile(filename); + Editor *e = pMainWindow->editorList()->getOpenedEditorByFilename(filename); + if (!e) + e = pMainWindow->openFile(filename); if (e) { e->setCaretPositionAndActivate(line,1); } diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.h b/libs/qsynedit/qsynedit/syntaxer/cpp.h index 1dba1fb7..48430541 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.h +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.h @@ -50,7 +50,7 @@ class CppSyntaxer: public Syntaxer rsDocstring, rsStringEscapeSeq, rsRawString, rsSpace,rsRawStringNotEscaping,rsRawStringEnd,rsChar, - rsDefineIdentifier, rsDefineRemaining + rsDefineIdentifier, rsDefineRemaining, }; public: From d8e4c4d76b1f0a0c45628e01d721843b5ed3cd1a Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 12:34:02 +0800 Subject: [PATCH 07/16] - Fix: Expression that starts with full scoped variables might be treated as var definition. --- NEWS.md | 1 + RedPandaIDE/parser/cppparser.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 907a508d..5e3b35d1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -43,6 +43,7 @@ Red Panda C++ Version 2.26 - Enhancement: add Windows arm64 package. - Fix: Force to use debug server when debugging with lldb-mi to fix input/output on Windows. - Fix: Can't goto definition/declaration into files that not saved. + - Fix: Expression that starts with full scoped variables might be treated as var definition. Red Panda C++ Version 2.25 diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 14d1c2ce..c933d689 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -2340,6 +2340,10 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType) mIndex++; } else { QString s = mTokenizer[mIndex]->text; + if (!isWordChar(s.front())) { + mIndex = indexOfNextPeriodOrSemicolon(mIndex); + return; + } if (sName.endsWith("::")) { sName+=s; } else { @@ -4444,7 +4448,7 @@ void CppParser::internalParse(const QString &fileName) if (mTokenizer.tokenCount() == 0) return; #ifdef QT_DEBUG -// mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName))); + mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName))); #endif #ifdef QT_DEBUG mLastIndex = -1; @@ -6305,6 +6309,7 @@ int CppParser::indexOfNextPeriodOrSemicolon(int index, int endIndex) case ';': case ',': case '}': + case ')': return index; case '(': index = mTokenizer[index]->matchIndex+1; From 0faea6ac693f3d038b37133164a9e4283f13ab05 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 12:51:01 +0800 Subject: [PATCH 08/16] - Enhancement: Don't auto-indent in raw string. --- NEWS.md | 1 + libs/qsynedit/qsynedit/formatter/cppformatter.cpp | 2 ++ libs/qsynedit/qsynedit/syntaxer/cpp.h | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 5e3b35d1..4c674ec0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -44,6 +44,7 @@ Red Panda C++ Version 2.26 - Fix: Force to use debug server when debugging with lldb-mi to fix input/output on Windows. - Fix: Can't goto definition/declaration into files that not saved. - Fix: Expression that starts with full scoped variables might be treated as var definition. + - Enhancement: Don't auto-indent in raw string. Red Panda C++ Version 2.25 diff --git a/libs/qsynedit/qsynedit/formatter/cppformatter.cpp b/libs/qsynedit/qsynedit/formatter/cppformatter.cpp index 41fa8e2a..3ad02e2e 100644 --- a/libs/qsynedit/qsynedit/formatter/cppformatter.cpp +++ b/libs/qsynedit/qsynedit/formatter/cppformatter.cpp @@ -40,6 +40,8 @@ namespace QSynedit { if (editor->syntaxer()->language() != ProgrammingLanguage::CPP) return indentSpaces; SyntaxState rangePreceeding = editor->document()->getSyntaxState(startLine-1); + if (rangePreceeding.state == CppSyntaxer::RangeState::rsRawStringNotEscaping) + return 0; if (addIndent) { // QString trimmedS = s.trimmed(); QString trimmedLineText = lineText.trimmed(); diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.h b/libs/qsynedit/qsynedit/syntaxer/cpp.h index 48430541..2c7509ad 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.h +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.h @@ -23,6 +23,7 @@ namespace QSynedit { class CppSyntaxer: public Syntaxer { +public: enum class TokenId { Comment, Directive, @@ -53,7 +54,6 @@ class CppSyntaxer: public Syntaxer rsDefineIdentifier, rsDefineRemaining, }; -public: explicit CppSyntaxer(); CppSyntaxer(const CppSyntaxer&)=delete; CppSyntaxer operator=(const CppSyntaxer&)=delete; From 625475fabd9a8ff65b341d064cb75304014457f0 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 12:55:27 +0800 Subject: [PATCH 09/16] - Reduce sanitizer option length --- RedPandaIDE/compiler/compilerinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RedPandaIDE/compiler/compilerinfo.cpp b/RedPandaIDE/compiler/compilerinfo.cpp index ff4ea55c..d327c603 100644 --- a/RedPandaIDE/compiler/compilerinfo.cpp +++ b/RedPandaIDE/compiler/compilerinfo.cpp @@ -179,7 +179,7 @@ void CompilerInfo::prepareCompilerOptions() addOption(CC_CMD_OPT_STACK_PROTECTOR , QObject::tr("Check for stack smashing attacks (-fstack-protector)"), groupName, false, false, true, "-fstack-protector", CompilerOptionType::Choice, sl); sl.clear(); sl.append(QPair("Address","address")); - sl.append(QPair("Hardware-assisted address (arm64 only)","hwaddress")); + sl.append(QPair("Hwaddress","hwaddress")); sl.append(QPair("Thread","thread")); sl.append(QPair("Leak","leak")); sl.append(QPair("Undefined","undefined")); From 2c26f9aaa1aff6e15950067cc1b111b37270c28d Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 13:12:46 +0800 Subject: [PATCH 10/16] Use git info to generate version number --- RedPandaIDE/RedPandaIDE.pro | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 7867df35..328ed9e1 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -17,7 +17,9 @@ APP_NAME = RedPandaCPP APP_VERSION = 2.26 -TEST_VERSION = beta2 +# TEST_VERSION = beta2 +TEST_VERSION = $$system(git rev-list HEAD --count) + contains(QMAKE_HOST.arch, x86_64):{ DEFINES += ARCH_X86_64=1 } else: { @@ -57,7 +59,7 @@ DEFINES += APP_NAME=\\\"$${APP_NAME}\\\" isEmpty(TEST_VERSION) { DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}\\\" } else { - DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}-$${TEST_VERSION}\\\" + DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}.$${TEST_VERSION}\\\" } win32 { _WINDOWS_PREFER_OPENCONSOLE = $$(WINDOWS_PREFER_OPENCONSOLE) From 20339b3e9a32264e86e7c176859dce27cda82f9a Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 14:45:12 +0800 Subject: [PATCH 11/16] - Fix: Function list is not correctly retrived for full-scoped functions --- NEWS.md | 1 + RedPandaIDE/RedPandaIDE.pro | 2 +- RedPandaIDE/editor.cpp | 2 +- RedPandaIDE/parser/cppparser.cpp | 2 +- Red_Panda_CPP.pro | 2 -- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4c674ec0..cfe3460f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -45,6 +45,7 @@ Red Panda C++ Version 2.26 - Fix: Can't goto definition/declaration into files that not saved. - Fix: Expression that starts with full scoped variables might be treated as var definition. - Enhancement: Don't auto-indent in raw string. + - Fix: Function list is not correctly retrived for full-scoped functions. Red Panda C++ Version 2.25 diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 328ed9e1..ee02c1ac 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -18,7 +18,7 @@ APP_NAME = RedPandaCPP APP_VERSION = 2.26 # TEST_VERSION = beta2 -TEST_VERSION = $$system(git rev-list HEAD --count) +system(git rev-list HEAD --count): TEST_VERSION = $$system(git rev-list HEAD --count) contains(QMAKE_HOST.arch, x86_64):{ DEFINES += ARCH_X86_64=1 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 683878c2..cdd654ab 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -4358,7 +4358,7 @@ void Editor::updateFunctionTip(bool showTip) QList statements=mParser->getListOfFunctions(mFilename, s, functionNamePos.line); - +// qDebug()<<"finding function list:"<functionTip()->addTip( statement->command, diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index c933d689..f56c2389 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -435,7 +435,7 @@ PStatement CppParser::doFindStatementOf(const QString &fileName, } } if (!isSTLContainerFunctions) - typeStatement = doFindTypeDefinitionOf(fileName,statement->type, parentScopeType); + typeStatement = doFindTypeDefinitionOf(fileName,statement->type, statement->parentScope.lock()); //it's stl smart pointer if ((typeStatement) diff --git a/Red_Panda_CPP.pro b/Red_Panda_CPP.pro index 84d36729..47212503 100644 --- a/Red_Panda_CPP.pro +++ b/Red_Panda_CPP.pro @@ -23,8 +23,6 @@ APP_NAME = RedPandaCPP APP_VERSION = 2.26 -TEST_VERSION = beta2 - win32: { SUBDIRS += \ redpanda-win-git-askpass From 522722c41865c11c0a255e5cb119d9e66cbd5ad0 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 17:25:37 +0800 Subject: [PATCH 12/16] - Enhancement: Improved Raw string support --- NEWS.md | 1 + RedPandaIDE/editor.cpp | 1 - RedPandaIDE/parser/cpptokenizer.cpp | 26 +++++++++++++++++++++++-- libs/qsynedit/qsynedit/syntaxer/cpp.cpp | 24 +++++++++++++++++++---- libs/qsynedit/qsynedit/syntaxer/cpp.h | 2 ++ 5 files changed, 47 insertions(+), 7 deletions(-) diff --git a/NEWS.md b/NEWS.md index cfe3460f..82eb9bad 100644 --- a/NEWS.md +++ b/NEWS.md @@ -46,6 +46,7 @@ Red Panda C++ Version 2.26 - Fix: Expression that starts with full scoped variables might be treated as var definition. - Enhancement: Don't auto-indent in raw string. - Fix: Function list is not correctly retrived for full-scoped functions. + - Enhancement: Improved Raw string support Red Panda C++ Version 2.25 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index cdd654ab..a41b74c4 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -4351,7 +4351,6 @@ void Editor::updateFunctionTip(bool showTip) // Don't bother scanning the database when there's no identifier to scan for // Only do the cumbersome list filling when showing a new tooltip... - if (s != pMainWindow->functionTip()->functionFullName() && !mParser->parsing()) { pMainWindow->functionTip()->clearTips(); diff --git a/RedPandaIDE/parser/cpptokenizer.cpp b/RedPandaIDE/parser/cpptokenizer.cpp index d8e4edd7..a5130d9c 100644 --- a/RedPandaIDE/parser/cpptokenizer.cpp +++ b/RedPandaIDE/parser/cpptokenizer.cpp @@ -748,16 +748,38 @@ void CppTokenizer::skipRawString() { mCurrent++; //skip R bool noEscape = false; + bool findDCharSeq = true; + QString dCharSeq; while(true) { mCurrent++; switch(mCurrent->unicode()) { case '(': - noEscape = true; + if (findDCharSeq) { + noEscape = true; + findDCharSeq = false; + } break; case ')': - noEscape = false; + if (noEscape) { + bool ok=true; + QChar* pChar=mCurrent+1; + for (int i=0;i127)) { mRange.state = RangeState::rsUnknown; mRun+=1; return; @@ -974,14 +979,25 @@ void CppSyntaxer::procRawString() case '\t': return; case '(': - if (mRange.state==RangeState::rsRawString) + if (mRange.state==RangeState::rsRawString) { mRange.state = RangeState::rsRawStringNotEscaping; + mRawStringInitialDCharSeq += "\""; + } break; case ')': - if (mRange.state == RangeState::rsRawStringNotEscaping) - mRange.state = RangeState::rsRawStringEnd; + qDebug()<=mLineSize && mRange.state != RangeState::rsRawStringNotEscaping) diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.h b/libs/qsynedit/qsynedit/syntaxer/cpp.h index 2c7509ad..4f5021cf 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.h +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.h @@ -159,6 +159,8 @@ private: int mLeftBraces; int mRightBraces; + QString mRawStringInitialDCharSeq; + QSet mCustomTypeKeywords; PTokenAttribute mPreprocessorAttribute; From f9d821271278f7e065a4f004cfa25285a84d6bd3 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 20 Feb 2024 21:47:12 +0800 Subject: [PATCH 13/16] - Enhancement: New option for compiler set "Don't localize gcc output messages" --- NEWS.md | 1 + RedPandaIDE/compiler/compiler.cpp | 12 +- RedPandaIDE/compiler/compiler.h | 1 + RedPandaIDE/parser/cppparser.cpp | 2 +- RedPandaIDE/settings.cpp | 17 + RedPandaIDE/settings.h | 4 + .../compilersetoptionwidget.cpp | 3 + .../settingsdialog/compilersetoptionwidget.ui | 27 +- RedPandaIDE/translations/RedPandaIDE_pt_BR.ts | 16 +- RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 1693 +++++++++-------- RedPandaIDE/translations/RedPandaIDE_zh_TW.ts | 12 +- libs/qsynedit/qsynedit/syntaxer/cpp.cpp | 3 - 12 files changed, 927 insertions(+), 864 deletions(-) diff --git a/NEWS.md b/NEWS.md index 82eb9bad..6b722e30 100644 --- a/NEWS.md +++ b/NEWS.md @@ -47,6 +47,7 @@ Red Panda C++ Version 2.26 - Enhancement: Don't auto-indent in raw string. - Fix: Function list is not correctly retrived for full-scoped functions. - Enhancement: Improved Raw string support + - Enhancement: New option for compiler set "Don't localize gcc output messages" Red Panda C++ Version 2.25 diff --git a/RedPandaIDE/compiler/compiler.cpp b/RedPandaIDE/compiler/compiler.cpp index fd6d87c4..85596a06 100644 --- a/RedPandaIDE/compiler/compiler.cpp +++ b/RedPandaIDE/compiler/compiler.cpp @@ -37,10 +37,11 @@ #define COMPILE_PROCESS_END "---//END//----" Compiler::Compiler(const QString &filename, bool onlyCheckSyntax): - QThread(), - mOnlyCheckSyntax(onlyCheckSyntax), - mFilename(filename), - mRebuild(false), + QThread{}, + mOnlyCheckSyntax{onlyCheckSyntax}, + mFilename{filename}, + mRebuild{false}, + mForceEnglishOutput{false}, mParserForFile() { getParserForFile(filename); @@ -685,7 +686,8 @@ void Compiler::runCommand(const QString &cmd, const QString &arguments, const Q } env.insert("PATH",path); } - //env.insert("LANG","en"); + if (compilerSet() && compilerSet()->forceEnglishOutput()) + env.insert("LANG","en"); env.insert("LDFLAGS","-Wl,--stack,12582912"); env.insert("CFLAGS",""); env.insert("CXXFLAGS",""); diff --git a/RedPandaIDE/compiler/compiler.h b/RedPandaIDE/compiler/compiler.h index eec997ab..7949fb6e 100644 --- a/RedPandaIDE/compiler/compiler.h +++ b/RedPandaIDE/compiler/compiler.h @@ -104,6 +104,7 @@ protected: std::shared_ptr mProject; bool mSetLANG; PCppParser mParserForFile; + bool mForceEnglishOutput; private: bool mStop; diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index f56c2389..56f25778 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -4448,7 +4448,7 @@ void CppParser::internalParse(const QString &fileName) if (mTokenizer.tokenCount() == 0) return; #ifdef QT_DEBUG - mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName))); +// mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName))); #endif #ifdef QT_DEBUG mLastIndex = -1; diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 92a6fffa..acf6d434 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -1680,6 +1680,7 @@ Settings::CompilerSet::CompilerSet(): mExecCharset{ENCODING_SYSTEM_DEFAULT}, mStaticLink{false}, mPersistInAutoFind{false}, + mForceEnglishOutput{false}, mPreprocessingSuffix{DEFAULT_PREPROCESSING_SUFFIX}, mCompilationProperSuffix{DEFAULT_COMPILATION_SUFFIX}, mAssemblingSuffix{DEFAULT_ASSEMBLING_SUFFIX}, @@ -1695,6 +1696,7 @@ Settings::CompilerSet::CompilerSet(const QString& compilerFolder, const QString& mExecCharset{ENCODING_SYSTEM_DEFAULT}, mStaticLink{true}, mPersistInAutoFind{false}, + mForceEnglishOutput{false}, mPreprocessingSuffix{DEFAULT_PREPROCESSING_SUFFIX}, mCompilationProperSuffix{DEFAULT_COMPILATION_SUFFIX}, mAssemblingSuffix{DEFAULT_ASSEMBLING_SUFFIX}, @@ -1753,6 +1755,7 @@ Settings::CompilerSet::CompilerSet(const Settings::CompilerSet &set): mTarget{set.mTarget}, mCompilerType{set.mCompilerType}, + mUseCustomCompileParams{set.mUseCustomCompileParams}, mUseCustomLinkParams{set.mUseCustomLinkParams}, mCustomCompileParams{set.mCustomCompileParams}, @@ -1761,6 +1764,7 @@ Settings::CompilerSet::CompilerSet(const Settings::CompilerSet &set): mExecCharset{set.mExecCharset}, mStaticLink{set.mStaticLink}, mPersistInAutoFind{set.mPersistInAutoFind}, + mForceEnglishOutput{set.mForceEnglishOutput}, mPreprocessingSuffix{set.mPreprocessingSuffix}, mCompilationProperSuffix{set.mCompilationProperSuffix}, @@ -1804,6 +1808,7 @@ Settings::CompilerSet::CompilerSet(const QJsonObject &set) : mExecCharset{}, // handle later mStaticLink{set["staticLink"].toBool()}, mPersistInAutoFind{false}, + mForceEnglishOutput{false}, mPreprocessingSuffix{set["preprocessingSuffix"].toString()}, mCompilationProperSuffix{set["compilationProperSuffix"].toString()}, @@ -2907,6 +2912,16 @@ QByteArray Settings::CompilerSet::getCompilerOutput(const QString &binDir, const return result.trimmed(); } +bool Settings::CompilerSet::forceEnglishOutput() const +{ + return mForceEnglishOutput; +} + +void Settings::CompilerSet::setForceEnglishOutput(bool newForceEnglishOutput) +{ + mForceEnglishOutput = newForceEnglishOutput; +} + bool Settings::CompilerSet::persistInAutoFind() const { return mPersistInAutoFind; @@ -3556,6 +3571,7 @@ void Settings::CompilerSets::saveSet(int index) mSettings->mSettings.setValue("StaticLink", pSet->staticLink()); mSettings->mSettings.setValue("ExecCharset", pSet->execCharset()); mSettings->mSettings.setValue("PersistInAutoFind", pSet->persistInAutoFind()); + mSettings->mSettings.setValue("forceEnglishOutput", pSet->forceEnglishOutput()); mSettings->mSettings.setValue("preprocessingSuffix", pSet->preprocessingSuffix()); mSettings->mSettings.setValue("compilationProperSuffix", pSet->compilationProperSuffix()); @@ -3644,6 +3660,7 @@ Settings::PCompilerSet Settings::CompilerSets::loadSet(int index) pSet->setAutoAddCharsetParams(mSettings->mSettings.value("AddCharset", true).toBool()); pSet->setStaticLink(mSettings->mSettings.value("StaticLink", false).toBool()); pSet->setPersistInAutoFind(mSettings->mSettings.value("PersistInAutoFind", false).toBool()); + pSet->setForceEnglishOutput(mSettings->mSettings.value("forceEnglishOutput", false).toBool()); pSet->setExecCharset(mSettings->mSettings.value("ExecCharset", ENCODING_SYSTEM_DEFAULT).toString()); if (pSet->execCharset().isEmpty()) { diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index 19759e1d..ddb91f83 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -1472,6 +1472,9 @@ public: bool persistInAutoFind() const; void setPersistInAutoFind(bool newPersistInAutoFind); + bool forceEnglishOutput() const; + void setForceEnglishOutput(bool newForceEnglishOutput); + private: void setGCCProperties(const QString& binDir, const QString& c_prog); void setDirectories(const QString& binDir); @@ -1523,6 +1526,7 @@ public: QString mExecCharset; bool mStaticLink; bool mPersistInAutoFind; + bool mForceEnglishOutput; QString mPreprocessingSuffix; QString mCompilationProperSuffix; diff --git a/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp b/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp index fec1982b..774bb74f 100644 --- a/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp +++ b/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp @@ -96,6 +96,7 @@ static void loadCompilerSetSettings(Settings::PCompilerSet pSet, Ui::CompilerSet ui->chkAutoAddCharset->setChecked(pSet->autoAddCharsetParams()); ui->chkStaticLink->setChecked(pSet->staticLink()); ui->chkPersistInAutoFind->setChecked(pSet->persistInAutoFind()); + ui->chkForceEnglishOutput->setChecked(pSet->forceEnglishOutput()); //rest tabs in the options widget ui->optionTabs->resetUI(pSet,pSet->compileOptions()); @@ -242,6 +243,8 @@ void CompilerSetOptionWidget::saveCurrentCompilerSet() pSet->setAutoAddCharsetParams(ui->chkAutoAddCharset->isChecked()); pSet->setStaticLink(ui->chkStaticLink->isChecked()); pSet->setPersistInAutoFind(ui->chkPersistInAutoFind->isChecked()); + pSet->setForceEnglishOutput(ui->chkForceEnglishOutput->isChecked()); + pSet->setCCompiler(ui->txtCCompiler->text().trimmed()); pSet->setCppCompiler(ui->txtCppCompiler->text().trimmed()); diff --git a/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui b/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui index 6836a211..78ec48f0 100644 --- a/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui +++ b/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui @@ -85,7 +85,7 @@ - 4 + 0 false @@ -146,6 +146,20 @@ + + + + Don't localize compiler output messages + + + + + + + Survive auto-finds + + + @@ -166,13 +180,6 @@ - - - - Survive auto-finds - - - @@ -497,8 +504,6 @@ 1 - - - + diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index b59607d6..c4f29434 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -13,7 +13,7 @@ Based on Qt %1 (%2) rodando em %3 - Com base em Qt %1 (%2) executado em %3 + Com base em Qt %1 (%2) executado em %3 Build time: %1 %2 @@ -21,7 +21,7 @@ Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) - Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) + Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) <html><head/><body><p>Homepage: <a href="Homepage: https://sourceforge.net/projects/dev-cpp-2020/">https://sourceforge.net/projects/dev-cpp-2020/</a></p></body></html> @@ -75,6 +75,14 @@ Legacy Microsoft Visual C++ Microsoft Visual C++ Legado + + Based on Qt %1 (%2) running on %3 + + + + Copyright(C) 2021-2024 瞿华(royqh1979@gmail.com) + Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) {2021-2024 ?} {1979@?} + AppTheme @@ -815,6 +823,10 @@ Survive auto-finds + + Don't localize compiler output messages + + CppRefacter diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index 783ab04d..a4b058df 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -72,8 +72,12 @@ p, li { white-space: pre-wrap; } + Copyright(C) 2021-2024 瞿华(royqh1979@gmail.com) + Copyright(C) 2021-2024 瞿华(royqh1979@gmail.com) + + Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) - Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) + Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) @@ -125,32 +129,37 @@ p, li { white-space: pre-wrap; } 版本: + Next Generation Microsoft Visual C++ 下一代 Microsoft Visual C++ + Microsoft Visual C++ 2022 Microsoft Visual C++ 2022 + Microsoft Visual C++ 2019 Microsoft Visual C++ 2019 + Microsoft Visual C++ 2017 Microsoft Visual C++ 2017 + Legacy Microsoft Visual C++ 旧版 Microsoft Visual C++ - + Non-GCC Compiler 非GCC编译器 - + Website: <a href="%1">%1</a> 网址:<a href="%1">%1</a> @@ -158,17 +167,17 @@ p, li { white-space: pre-wrap; } AppTheme - + Theme file '%1' doesn't exist! 主题文件"%1"不存在! - + Error in json file '%1':%2 : %3 JSON文件'%1':%2中存在错误:%3 - + Can't open the theme file '%1' for read. 无法读取主题文件"%1"! @@ -208,17 +217,17 @@ p, li { white-space: pre-wrap; } BacktraceModel - + Function 函数 - + Filename 文件名 - + Line @@ -264,17 +273,17 @@ p, li { white-space: pre-wrap; } BreakpointModel - + Filename 文件名 - + Line - + Condition 条件 @@ -557,77 +566,77 @@ p, li { white-space: pre-wrap; } Compiler - + Clean before rebuild failed. 重编译前的清理准备工作失败! - + - Command: %1 %2 - 命令: %1 %2 - + - Command: %1 %2 > "%3" - 命令: %1 %2 > "%3" - + Compile Result: 编译结果: - + - Errors: %1 - 错误数: %1 - + - Warnings: %1 - 警告数: %1 - + - Output Filename: %1 - 输出文件名: %1 - + - Output Size: %1 - 输出文件大小: %1 - + - Compilation Time: %1 secs - 编译时间: %1 秒 - + [Error] [错误] - + [Warning] [警告] - + [Info] [信息] - + [Note] [说明] - + Can't open file "%1" for write! 无法写入文件“%1”。 - + The compiler process for '%1' failed to start. 无法启动编译器进程'%1'。 @@ -636,27 +645,27 @@ p, li { white-space: pre-wrap; } 无法启动编译进程。 - + The compiler process crashed after starting successfully. 编译进程启动后崩溃。 - + The last waitFor...() function timed out. waitFor()函数等待超时。 - + An error occurred when attempting to write to the compiler process. 在向编译进程输入内容时出错。 - + An error occurred when attempting to read from the compiler process. 在从编译进程读取内容时出错。 - + An unknown error occurred. 发生了未知错误。 @@ -803,12 +812,12 @@ p, li { white-space: pre-wrap; } 当变量占用栈空间大于此值时报错 - - - - - - + + + + + + ... ... @@ -818,12 +827,12 @@ p, li { white-space: pre-wrap; } 基本选项 - + Add the following arguments when calling the compiler 编译时加入下列选项: - + Add the following arguments when calling the linker 链接时加入下列选项 @@ -873,7 +882,12 @@ p, li { white-space: pre-wrap; } 用静态链接方式链接库文件 - + + Don't localize compiler output messages + 强制编译器使用英语输出信息 + + + Binary suffix 二进制文件类型 @@ -886,17 +900,17 @@ p, li { white-space: pre-wrap; } MB - + Settings 编译/链接选项 - + Directories 文件夹 - + Programs 程序 @@ -905,22 +919,22 @@ p, li { white-space: pre-wrap; } 汇编器(NASM) - + Output 输出 - + Compilation Stages 编译阶段 - + Stop after the preprocessing stage 在完成预处理后停止编译 - + Stop after the compilation proper stage 在生成汇编代码后停止。 @@ -929,12 +943,12 @@ p, li { white-space: pre-wrap; } 在完成汇编后停止。 - + Link and generate the executable 链接得到可执行文件。 - + Preprocessing output suffix 预处理输出后缀 @@ -943,12 +957,12 @@ p, li { white-space: pre-wrap; } 编译输出后缀 - + Compiling output suffix 编译(汇编代码)输出后缀 - + Executable suffix 可执行文件后缀 @@ -957,37 +971,37 @@ p, li { white-space: pre-wrap; } 选项 - + gdb gdb - + gdb server gdb server - + Resource Compiler(windres) 资源编辑器(winres) - + C++ Compiler(g++) C++编译器(g++) - + Choose C++ Compiler 选择C++编译器 - + Choose C Compiler 选择C编译器 - + C Compiler(gcc) C编译器(gcc) @@ -1000,22 +1014,22 @@ p, li { white-space: pre-wrap; } 性能分析器(gprof) - + make - + Choose make 选择make - + Choose Debugger 选择调试器 - + Choose Resource Compiler 选择资源编译器 @@ -1024,12 +1038,12 @@ p, li { white-space: pre-wrap; } 选择性能分析器 - + Confirm 确认 - + Red Panda C++ will clear previously found compiler list and search for compilers in the following locations:<br /> '%1'<br /> '%2'<br />Do you really want to continue? 小熊猫C++ 将会清除以前搜索到的编译器配置列表,然后在下列文件夹中搜索编译器:<br/> '%1'<br/> '%2'<br />你确定要继续吗? @@ -1044,95 +1058,95 @@ p, li { white-space: pre-wrap; } UTF-8 - + Red Panda C++ will clear previously found compiler list and search for compilers in the the PATH. <br />Do you really want to continue? 小熊猫C++ 将会清除以前搜索到的编译器配置列表,然后在PATH路径中搜索gcc编译器.<br />你确定要继续吗? - + Searching for compilers... 正在搜索编译器…… - + Abort 中止 - + Searching... 正在查找... - - + + Failed 失败 - - + + Can't find any compiler. 找不到编译器 - - + + Compiler Set Name 编译器配置名称 - + Name 名称 - + Compiler Set Folder 编译器所在文件夹 - + New name 新名称 - + Locate C Compiler 定位C编译器 - - - - - - + + + + + + Executable files (*.exe) 可执行文件 (*.exe) - + Locate C++ Compiler 定位C++编译器 - + Locate Make 定位make程序 - + Locate GDB 定位gdb程序 - + Locate GDB Server 定位gdb server程序 - + Locate windres 定位windres程序 @@ -1145,6 +1159,7 @@ p, li { white-space: pre-wrap; } 定位nasm程序 + Survive auto-finds 自动搜索时保留此项 @@ -1409,12 +1424,12 @@ p, li { white-space: pre-wrap; } 调试器路径"%1"中包含非ASCII字符(如,中文字符) - + This prevents it from executing. 这会导致调试器无法启动。 - + Debugger not exists 找不到调试器 @@ -1423,57 +1438,57 @@ p, li { white-space: pre-wrap; } 找不到调试器程序"%1" - + Can''t find debugger (gdb) in : "%1" 找不到gdb程序“%1” - + Please check the "program" page of compiler settings. 请检查编译器设置中的“程序”页。 - + GDB Server path error gdb server路径错误 - + GDB Server's path "%1" contains non-ascii characters. gdb server的路径"%1"包含中文或者全角字符 - + GDB Server not exists 找不到gdb server - + Can''t find gdb server in : "%1" 无法在"%1"找到gdb server - + Execute to evaluate 执行以求值 - + Save file '%1' failed. 保存文件'%1'失败。 - + Can't open file '%1' for write. 无法写入文件'%1'. - + Error in json file '%1':%2 : %3 JSON文件'%1':%2中存在错误:%3 - + Can't open file '%1' for read. 无法读取文件'%1'. @@ -1482,22 +1497,22 @@ p, li { white-space: pre-wrap; } 不在当前语境中 - + Compile 编译 - + Source file is more recent than executable. 源文件比程序文件新。 - + Recompile? 重新编译? - + Signal "%1" Received: 收到信号"%1": @@ -1520,10 +1535,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Error 错误 @@ -1572,44 +1587,44 @@ p, li { white-space: pre-wrap; } 文件%1已经被打开! - + The text to be copied exceeds count limit! 要复制的内容超过了行数限制! - + The text to be copied exceeds character limit! 要复制的内容超过了字符数限制! - + The text to be cut exceeds count limit! 要剪切的内容超过了行数限制! - + The text to be cut exceeds character limit! 要剪切的内容超过了字符数限制! - + hex: %1 16进制: %1 - + dec: %1 十进制: %1 - + Print Document 打印文档 - - - + + + Ctrl+click for more info Ctrl+单击以获取更多信息 @@ -3061,45 +3076,45 @@ p, li { white-space: pre-wrap; } - 编译器配置: %1 - - + + Can't delete the old executable file "%1". 无法删除旧的可执行文件"%1". - + GNU Assembler GNU汇编 - + Can't find the compiler for file %1 Can't the compiler for file %1 找不到适合文件%1的编译器 - + The Compiler '%1' doesn't exists! 编译器程序"%1"不存在! - + Please check the "program" page of compiler settings. 请检查编译器设置中的“程序”页。 - + Processing %1 source file: 正在处理%1源程序文件: - + %1 Compiler: %2 %1编译器: %2 - + Command: %1 %2 命令: %1 %2 @@ -4457,18 +4472,18 @@ p, li { white-space: pre-wrap; } MainWindow - + Red Panda C++ 小熊猫C++ - - - - - + + + + + Issues 编译器 @@ -4542,7 +4557,7 @@ p, li { white-space: pre-wrap; } - + Debug Console 调试主控台 @@ -4618,7 +4633,7 @@ p, li { white-space: pre-wrap; } 工具栏2 - + New 新建 @@ -4751,9 +4766,9 @@ p, li { white-space: pre-wrap; } - - - + + + Copy 复制 @@ -4764,7 +4779,7 @@ p, li { white-space: pre-wrap; } - + Paste 粘贴 @@ -4775,8 +4790,8 @@ p, li { white-space: pre-wrap; } - - + + Select All 选择全部 @@ -4900,38 +4915,38 @@ p, li { white-space: pre-wrap; } - - + + New Problem Set 新建试题集 - + Add Problem 添加试题 - + Remove Problem 删除试题 - - + + Save Problem Set 保存试题集 - - + + Load Problem Set 载入试题集 @@ -4979,29 +4994,29 @@ p, li { white-space: pre-wrap; } - + Remove Problem Case Remove Problem Set - 删除试题案例 + 删除试题案例 - + Open Anwser Source File 打开答案源代码文件 - + Run All Cases Run Current Case 运行所有案例 - + Problem Cases Validation Options 测试案例验证选项 @@ -5061,15 +5076,15 @@ p, li { white-space: pre-wrap; } - - + + Import FPS Problem Set 导入FPS试题集 - - + + Export FPS Problem Set 导出FPS试题集 @@ -5320,7 +5335,7 @@ p, li { white-space: pre-wrap; } - + Clear all breakpoints 删除所有断点 @@ -5684,7 +5699,7 @@ p, li { white-space: pre-wrap; } 保存为模板... - + New File 新建文件 @@ -5725,7 +5740,7 @@ p, li { white-space: pre-wrap; } - + Rename Symbol 重命名符号 @@ -5746,13 +5761,13 @@ p, li { white-space: pre-wrap; } - + Export As RTF 导出为RTF - + Export As HTML 导出为HTML @@ -6021,42 +6036,42 @@ p, li { white-space: pre-wrap; } 运行参数... - + File Encoding 文件编码 - + Recent Files 文件历史 - - - - - - + + + + + + Debugging 正在调试 - - - - - - + + + + + + Running 正在运行 - - - - - - + + + + + + Compiling 正在编译 @@ -6070,17 +6085,17 @@ p, li { white-space: pre-wrap; } 行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5 - + Read Only 只读 - + Insert 插入 - + Overwrite 覆写 @@ -6097,7 +6112,7 @@ p, li { white-space: pre-wrap; } 确认 - + Source file is not compiled. 源文件尚未编译。 @@ -6114,39 +6129,39 @@ p, li { white-space: pre-wrap; } 重新编译? - - - - + + + + Wrong Compiler Settings 错误的编译器设置 - - - - + + + + Compiler is set not to generate executable. 编译器被设置为不生成可执行文件。 - - + + We need the executabe to run problem case. 我们需要可执行文件来运行试题案例。 - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 @@ -6167,33 +6182,33 @@ p, li { white-space: pre-wrap; } 项目尚未构建。是否构建? - + Host applcation missing 宿主程序不存在 - + DLL project needs a host application to run. 动态链接库(DLL)需要一个宿主程序来运行。 - + But it's missing. 但它不存在。 - + Host application not exists 宿主程序不存在 - + Host application file '%1' doesn't exist. 宿主程序'%1'不存在。 - - + + Please correct this before start debugging 请在调试前改正设置。 @@ -6202,8 +6217,8 @@ p, li { white-space: pre-wrap; } 重新编译? - - + + Save last open info error 保存上次打开信息失败 @@ -6212,37 +6227,37 @@ p, li { white-space: pre-wrap; } 无法删除旧上次打开信息文件'%1' - + Can't save last open info file '%1' 无法保存上次打开信息文件'%1' - + Load last open info error 载入上次打开信息失败 - + Can't load last open info file '%1' 无法载入上次打开信息文件'%1' - + Open Source File 打开源代码文件 - - - + + + Correct compile settings for debug 纠正调试用编译设置 - - + + The generated executable won't have debug symbol infos, and can't be debugged. 生成的可执行文件中会缺少调试符号信息,因此无法编译。 @@ -6251,81 +6266,81 @@ p, li { white-space: pre-wrap; } 如果你正在使用Release版的编译器设置集,请在工具栏中将其改为Debug版本。 - - - + + + Or you can manually change the following settings in the options dialog's compiler set page: 您也可以手动在选项对话框的编译器设置页中修正下列选项: - - - + + + - Turned on the "Generate debug info (-g3)" option. - 打开“生成调试信息(-g3)"选项. - - - + + + - Turned off the "Strip executable (-s)" option. - 关闭"剥除附加信息(-s)"选项. - - - + + + - Turned off the "Optimization level (-O)" option or set it to "Debug (-Og)". - 关闭"优化级别(-O)选项,或将其设置为"调试(-Og)"级别. - - - - + + + + You should recompile after change the compiler set or it's settings. 在更换编译器设置集或修改其设置后,需要重新编译. - - - + + + Do you want to mannually change the compiler set settings now? 您现在就要手动修改编译器设置集的设置吗? - - + + Batch Set Cases 批量设置案例 - + Show detail debug logs 显示详细调试器日志 - + Copy all 全部复制 - + Go to Line 跳转到行 - + Line - + Template Exists 模板已存在 - + Template %1 already exists. Do you want to overwrite? 模板%1已存在。是否覆盖? @@ -6333,25 +6348,25 @@ p, li { white-space: pre-wrap; } - - - + + + Clear 清除 - + Export 导出 - + Insert Snippet 插入代码段 - - + + Problem Set %1 试题集%1 @@ -6380,56 +6395,56 @@ p, li { white-space: pre-wrap; } 项目已经被修改过,是否需要重新构建? - + Auto Save Error 自动保存出错 - + Auto save "%1" to "%2" failed:%3 自动保存"%1"到"%2"失败:%3 - + Properties... 试题属性... - + Set Problem Set Name 设置试题集名称 - + Problem Set Name: 试题集名称: - + Remove 删除 - + Remove All Bookmarks 删除全部书签 - + Modify Description 修改描述 - - - + + + Bookmark Description 书签描述 - - - + + + Description: 描述: @@ -6438,70 +6453,70 @@ p, li { white-space: pre-wrap; } 在调试主控台中显示调试器输出 - + Remove this search 清除这次搜索 - + Clear all searches 删除所有搜索 - + Breakpoint condition... 断点条件... - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Remove All Breakpoints Remove all breakpoints 删除所有断点 - + Line: %1 Col: %2 Sel:%3 Lines: %4 行: %1 列: %2 选中:%3 总行数: %4 - + Remove Breakpoint 删除当前断点 - + Rename File 重命名文件 - - + + Add Folder 添加文件夹 - - + + New folder 新文件夹 - + Folder name: 文件夹: - + Rename Folder 重命名 @@ -6514,22 +6529,22 @@ p, li { white-space: pre-wrap; } 要现在去修改设置吗? - + Rename Problem Set 修改试题集名称 - + Can't open last open information file '%1' for write! 无法写入配置文件'%1'。 - + Rename Problem 修改试题名称 - + Line: %1 Col: %2 Lines: %3 行: %1 列: %2 总行数: %3 @@ -6554,12 +6569,12 @@ p, li { white-space: pre-wrap; } 是否现在去改正? - + Missing Project Files 项目文件缺失 - + The following files is missing, can't build the project: 下列项目文件缺失,无法构建项目: @@ -6576,202 +6591,202 @@ p, li { white-space: pre-wrap; } 请取消该设置,重新编译然后重新启动调试。 - + Goto Url 跳转到试题网址 - + Add Problem Case 添加试题案例 - + Run Current Case 运行当前案例 - + Remove Folder 删除文件夹 - + Switch to normal view 切换为普通视图 - + Switch to custom view 切换为自定义视图 - + Sort By Type 按类型排序 - + Sort alphabetically 按名称排序 - + Show inherited members 显示继承的成员 - + Goto declaration 跳转到声明处 - + Goto definition 跳转到定义处 - + In current file 仅当前文件 - + In current project 整个项目 - - + + New Folder 新建文件夹 - + Rename 重命名 - - - - - + + + + + Delete 删除 - + Open in Editor 在编辑器中打开 - + Open in External Program 使用外部程序打开 - + Open in Terminal 在终端中打开 - + Open in Windows Explorer 在文件资源管理器中打开 - + Character sets 字符集 - + Convert to %1 转换为%1编码 - + Newline 换行符 - + %1 files autosaved 已自动保存%1个文件 - + Set answer to... 设置答案源代码... - + select other file... 选择其他文件... - + Select Answer Source File 选择答案源代码文件 - + Watchpoint hitted 变量断点被触发 - + Value of "%1" has changed: "%1"的值发生了变化: - + New value: %1 新值: %1 - + Project folder removed. 项目文件夹被删除 - + Folder for project '%1' was removed. 项目"%1"的文件夹已被外部程序删除. - + It will be closed. 项目将被关闭. - + Save settings failed! 保存设置失败 - + Folder Not Empty 文件夹非空 - + The project folder is not empty, existing files may be overwritten. 项目文件夹不是空的,已有的文件可能会被覆盖。 - + Do you want to proceed? 您确定要继续吗? - + Watchpoint variable name 被监控的变量 - + Stop execution when the following variable is modified (it must be visible from the currect scope): 当下面的变量被修改时暂停执行(该变量必须可以从当前程序处访问): @@ -6780,17 +6795,17 @@ p, li { white-space: pre-wrap; } 中止 - + FPS Problem Set Files (*.fps;*.xml) FPS试题集文件(*.fps;*.xml) - + FPS Problem Set Files (*.fps) FPS试题集文件(*.fps) - + Export Error 导出时出错 @@ -6800,7 +6815,7 @@ p, li { white-space: pre-wrap; } C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + New Folder %1 新建文件夹%1 @@ -6813,13 +6828,13 @@ p, li { white-space: pre-wrap; } 无标题%1 - - + + Do you really want to delete %1? 你真的要删除%1吗? - + Do you really want to delete %1 files? 你真的要删除%1个文件吗? @@ -6832,7 +6847,7 @@ p, li { white-space: pre-wrap; } 变量"%1"有改动: - + Old value: %1 旧值: %1 @@ -6841,63 +6856,63 @@ p, li { white-space: pre-wrap; } 新值: %1 - + Save project 保存项目 - + The project '%1' has modifications. 项目'%1'有改动。 - - + + Do you want to save it? 需要保存吗? - - + + File Changed 文件已发生变化 - - - + + + New Project File? 新建项目文件? - - - + + + Do you want to add the new file to the project? 您是否要将新建的文件加入项目? - - - - - + + + + + Save Error 保存失败 - + Change Project Compiler Set 改变项目编译器配置集 - + Change the project's compiler set will lose all custom compiler set options. 改变项目的编译器配置集会导致所有的自定义编译器选项被重置。 - - + + Do you really want to do that? 你真的想要那么做吗? @@ -6906,12 +6921,12 @@ p, li { white-space: pre-wrap; } 批量设置案例 - + Choose input files 选择输入数据文件 - + Input data files (*.in) 输入数据文件 (*.in) @@ -6920,78 +6935,78 @@ p, li { white-space: pre-wrap; } 无标题%1 - + Modify Watch 修改监视表达式 - + Watch Expression 监视表达式 - + Do you really want to clear all breakpoints in this file? 您真的要清除该文件的所有断点吗? - + New project 新建项目 - + Close %1 and start new project? 关闭'%1'以打开新项目? - + Folder not exist 文件夹不存在 - + Folder '%1' doesn't exist. Create it now? 文件夹'%1'不存在。是否创建? - + Can't create folder 无法创建文件夹 - + Failed to create folder '%1'. 创建文件夹'%1'失败。 - + Save new project as - + Folder %1 is not empty. 文件夹%1不是空的。 - + Do you really want to delete it? 你真的要删除它吗? - + Change working folder 改变工作文件夹 - + File '%1' is not in the current working folder. File '%1' is not in the current working folder 文件'%1'不在当前工作文件夹中。 - + Do you want to change working folder to '%1'? 是否将工作文件夹改设为'%1'? @@ -7000,28 +7015,28 @@ p, li { white-space: pre-wrap; } 正在删除试题... - + Can't Commit 无法提交 - + Git needs user info to commit. Git需要用信息进行提交。 - + Choose Input Data File 选择输入数据文件 - - + + All files (*.*) 所有文件 (*.*) - + Choose Expected Output Data File Choose Expected Input Data File 选择期望输出文件 @@ -7033,59 +7048,59 @@ p, li { white-space: pre-wrap; } - + Choose Working Folder 选择工作文件夹 - - + + Header Exists 头文件已存在 - - + + Header file "%1" already exists! 头文件"%1"已存在! - + Source Exists 源文件已存在! - + Source file "%1" already exists! 源文件"%1"已存在! - + Can't commit! 无法提交! - + The following files are in conflicting: 下列文件处于冲突状态,请解决后重新添加和提交: - + Commit Message 提交信息 - + Commit Message: 提交信息: - + Commit Failed 提交失败 - + Commit message shouldn't be empty! 提交信息不能为空! @@ -7094,22 +7109,22 @@ p, li { white-space: pre-wrap; } 小熊猫Dev-C++项目文件 (*.dev) - + New project fail 新建项目失败 - + Can't assign project template 无法使用模板创建项目 - + Remove file 删除文件 - + Remove the file from disk? 同时从硬盘上删除文件? @@ -7118,27 +7133,27 @@ p, li { white-space: pre-wrap; } 无标题 - + New Project File Name 新的项目文件名 - + File Name: 文件名: - + File Already Exists! 文件已存在! - + File '%1' already exists! 文件'%1'已经存在! - + Add to project 添加到项目 @@ -7155,12 +7170,12 @@ p, li { white-space: pre-wrap; } 请在工具栏中选择Debug编译器配置集,或者在“编译器配置集”设置的“编译/链接选项”页中<b>启用</b>“生成调试信息(-g3)”、<b>禁用</b>“剥除附件信息(-3)”。 - + C/C++ Source Files (*.c *.cpp *.cc *.cxx) C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + This operation will remove all cases for the current problem. 本操作会删除此试题的所有案例。 @@ -7169,7 +7184,7 @@ p, li { white-space: pre-wrap; } 调试失败 - + The executable doesn't have symbol table, and can't be debugged. 可执行文件中没有符号表信息,无法调试。 @@ -7194,122 +7209,123 @@ p, li { white-space: pre-wrap; } 您也可以删除所有断点,打开“CPU信息窗口”,然后调试汇编代码。 - + Failed to generate the executable. 未能生成可执行文件。 - + Please check detail info in "Tools Output" panel. 请查看“工具输出”面板中的详细信息。 - + Red Panda C++ project file (*.dev) 小熊猫C++项目文件(*.dev) - + Rename Error 重命名出错 - + Symbol '%1' is defined in system header. 符号'%1'在系统头文件中定义,无法修改。 - + New Name 新名称 - - - - + + + + Replace Error 替换出错 - + Can't open file '%1' for replace! 无法打开文件'%1'进行替换! - + Contents has changed since last search! 内容和上次查找时不一致。 - + Rich Text Format Files (*.rtf) RTF格式文件 (*.rtf) - + HTML Files (*.html) HTML文件 (*.html) - + The current problem set is not empty. 当前的试题集不是空的。 - + Problem %1 试题%1 - - + + Problem Set Files (*.pbs) 试题集文件 (*.pbs) - - + + Load Error 载入失败 - - + + Problem Case %1 试题案例%1 - - - - - - - - - - - - - - + + + + + + + + + + + + + + Error 错误 - + Recent Projects 项目历史 - + + Load Theme Error 载入主题失败 - - + + Clear History 清除历史 @@ -7318,8 +7334,8 @@ p, li { white-space: pre-wrap; } 编译生成的可执行文件中没有符号表,无法被调试。 - - + + Version Control 版本控制 @@ -7328,61 +7344,61 @@ p, li { white-space: pre-wrap; } 请在工具栏中选用Debug编译器配置集,或者在选项对话框的编辑器配置集页中勾选“生成调试信息(-g3)"选项。 - + File '%1' was changed. 磁盘文件'%1'已被修改。 - + Reload its content from disk? 是否重新读取它的内容? - + File '%1' was removed. 磁盘文件'%1'已被删除。 - + Keep it open? 是否保持它在小熊猫C++中打开的编辑窗口? - + Open 打开 - - + + Compile Failed 编译失败 - + Run Failed 运行失败 - - - - + + + + Confirm Convertion 确认转换 - + Exact 完全一致 - + Ignore leading/trailing spaces 忽略行首/行尾空格 - + Ignore spaces 忽略多余空格 @@ -7391,43 +7407,43 @@ p, li { white-space: pre-wrap; } 行: %1 列: %2 (%3个字符) 总行数: %4 - - - + + + If you are using the Release compiler set, please use choose the Debug version from toolbar. 如果你正在使用Release版的编译器设置集,请在工具栏中将其改为Debug版本。 - - - - + + + + The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue? 当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗? - + New Watch Expression 新监视表达式 - + Enter Watch Expression (it is recommended to use 'this->' for class members): 输入监视表达式 - + Parsing file %1 of %2: "%3" (%1/%2)正在解析文件"%3" - - + + Done parsing %1 files in %2 seconds 完成%1个文件的解析,用时%2秒 - + (%1 files per second) (每秒%1个文件) @@ -7435,17 +7451,17 @@ p, li { white-space: pre-wrap; } MemoryModel - + addr: %1 地址: %1 - + dec: %1 十进制: %1 - + oct: %1 八进制: %1 @@ -7454,12 +7470,12 @@ p, li { white-space: pre-wrap; } 16进制: %1 - + bin: %1 二进制: %1 - + ascii: '%1' ASCII字符: '%1' @@ -7624,13 +7640,13 @@ p, li { white-space: pre-wrap; } 项目%1 - - + + Default 默认 - + Choose directory 选择文件夹 @@ -7886,105 +7902,105 @@ p, li { white-space: pre-wrap; } 您确定要继续吗? - + Error Load File 载入文件错误 - - + + Error 错误 - + Can't create folder %1 无法创建文件夹%1 - + Warning 警告 - - + + Can't save file %1 无法保存文件%1 - + File Exists 文件已存在 - + File '%1' is already in the project 文件'%1'已在项目中 - + Project Updated 项目已升级 - + Your project was succesfully updated to a newer file format! 已成功将项目升级到新的格式 - + If something has gone wrong, we kept a backup-file: '%1'... 旧项目文件备份在'%1'。 - + Headers 头文件 - + Sources 源文件 - + Others 其他文件 - + Settings need update 设置需要更新 - + The compiler settings format of Red Panda C++ has changed. The compiler settings format of Dev-C++ has changed. 小熊猫C++的编译器设置格式已发生改变。 - + Please update your settings at Project >> Project Options >> Compiler and save your project. 请在项目 >> 项目属性 >> 编译器设置中修改您的设置并保存您的项目 - + Compiler not found 未找到编译器 - + The compiler set you have selected for this project, no longer exists. 您为该项目设置的编译器不存在。 - + It will be substituted by the global compiler set. 它将会被全局编译器设置代替。 - + Developed using the Red Panda C++ IDE Developed using the Red Panda Dev-C++ IDE 使用小熊猫C++编辑器开发 @@ -8199,33 +8215,33 @@ p, li { white-space: pre-wrap; } UTF-8 - - + + Wrong Compiler Type 错误的编译器类型 - + Compiler %1 can't compile a microcontroller project. 编译器"%1"无法编译嵌入式项目。 - + Compiler %1 can only compile microcontroller project. 编译器"%1"只能编译嵌入式项目 - + Change Project Compiler Set 改变项目编译器配置集 - + Change the project's compiler set will lose all custom compiler set options. 改变项目的编译器配置集会导致所有的自定义编译器选项被重置。 - + Do you really want to do that? 你真的想要那么做吗? @@ -8450,42 +8466,42 @@ p, li { white-space: pre-wrap; } 输出文件: - + %1 files [ %2 sources, %3 headers, %4 resources, %5 other files ] 共%1个文件[%2个源程序文件,%3个头文件,%4个资源文件,%5个其他文件] - + Can't remove old icon file 无法删除旧图标文件 - + Can't remove old icon file '%1' 无法删除旧图标文件'%1' - + Select icon file 选择图标文件 - + Image Files (*.ico *.png *.jpg) 图像文件 (*.ico *.png *.jpg) - + ANSI ANSI - + UTF-8 UTF-8 - + UTF-8 BOM UTF-8 BOM @@ -8536,32 +8552,32 @@ p, li { white-space: pre-wrap; } ProjectModel - + File exists 文件已存在 - + File '%1' already exists. Delete it now? 文件'%1'已存在。是否删除? - + Remove failed 删除失败 - + Failed to remove file '%1' 无法删除文件'%1' - + Rename failed 改名失败 - + Failed to rename file '%1' to '%2' 无法将文件'%1'改名为'%2' @@ -8810,7 +8826,7 @@ p, li { white-space: pre-wrap; } QApplication - + Error 错误 @@ -8832,13 +8848,13 @@ p, li { white-space: pre-wrap; } QObject - + Save 保存 - + Save changes to %1? 将修改保存到"%1"? @@ -8910,7 +8926,7 @@ p, li { white-space: pre-wrap; } 无法写入配置文件夹"%1" - + Can't load autolink settings 无法载入自动链接设置 @@ -8972,7 +8988,7 @@ p, li { white-space: pre-wrap; } - + Code Generation 代码生成 @@ -9000,7 +9016,7 @@ p, li { white-space: pre-wrap; } 使用下列指针大小编译(-mx) - + Processor (-m) 处理器类型(-m) @@ -9018,7 +9034,7 @@ p, li { white-space: pre-wrap; } 生成调试信息(-g3) - + Would you like Red Panda C++ to search for compilers in PATH? 您同意小熊猫C++在PATH路径中寻找gcc编译器吗? @@ -9056,7 +9072,7 @@ p, li { white-space: pre-wrap; } 检查栈溢出(stack smashing)错误 (-fstack-protector) - + Enable Sanitizer (-fsanitize=) 启用地址消毒(-fsanitize=) @@ -9081,82 +9097,82 @@ p, li { white-space: pre-wrap; } 检查是否严格遵守ISO C/C++标准 - + Language standard (--std) C语言标准(--std) - + Memory model (--model) 内存模型(--model) - + Use external stack 使用外部栈空间 - + Use movc instead of movx to read from external ram 使用movc代替movx访问外部RAM - + Replaces lcall/ljmp with acall/ajmp 用acall/ajmp代替lcall/ljmp - + Don't memcpy initialized xram from code Don't memcpy initialized xram from code - + Don't generate startup code 无main函数时不生成起始代码(用于edsim51模拟器) - + MCU Specification 微处理器参数 - + Internal ram size 内部RAM大小 - + External ram start location 外部RAM起始地址 - + External ram size 外部RAM大小 - + Stack pointer initial value 栈指针寄存器初始地址 - + External stack start location 外部栈空间起始地址 - + Direct data start location 内部数据区起始地址 - + Code segment location 代码段起始地址 - + Code segment size 代码段大小 @@ -9180,7 +9196,7 @@ p, li { white-space: pre-wrap; } 遇到第一个错误后立即中止编译(-Wfatal-errors) - + Linker 链接器 @@ -9189,17 +9205,17 @@ p, li { white-space: pre-wrap; } 链接Objective-C程序 (-lobjc) - + Do not use standard system libraries (-nostdlib) 不使用标准库和系统启动文件(-nostdlib) - + Do not create a console window (-mwindows) 不产生控制台窗口(-mwindows) - + Strip executable (-s) 剥除附加信息(-s) @@ -9220,7 +9236,7 @@ p, li { white-space: pre-wrap; } 仅预处理(-E) - + Use pipes instead of temporary files during compilation (-pipe) 编译时使用管道而不是临时文件(-pipe) @@ -9229,7 +9245,7 @@ p, li { white-space: pre-wrap; } 只生成汇编代码(-S) - + Confirm 确认 @@ -9250,13 +9266,13 @@ p, li { white-space: pre-wrap; } 如果仍然保留这些设置,可能会导致编译错误。<br /><br />请选择“是”,除非您清楚的知道选择“否”的后果, - - + + Compiler set not configuared. 未配置编译器设置。 - + Would you like Red Panda C++ to search for compilers in the following locations: <BR />'%1'<BR />'%2'? 您需要小熊猫C++在下列位置搜索编译器吗:<br />%1<br />%2 @@ -9281,12 +9297,12 @@ p, li { white-space: pre-wrap; } C++包含文件 - + Remove 删除 - + Do you really want to remove "%1"? 您确定要删除"%1"吗? @@ -9307,22 +9323,22 @@ p, li { white-space: pre-wrap; } 下标"%1"越界 - + bytes 字节 - + KB KB - + MB MB - + GB GB @@ -9612,12 +9628,12 @@ p, li { white-space: pre-wrap; } 无标题 - + constructor 构造函数 - + destructor 析构函数 @@ -9625,7 +9641,7 @@ p, li { white-space: pre-wrap; } - + Can't open file '%1' for read. @@ -9680,6 +9696,7 @@ p, li { white-space: pre-wrap; } 无法检测适用于 “%1” 的终端参数模式。 + Error executing platform compiler hint add-on 执行平台编译器提示附加组件错误 @@ -9687,31 +9704,31 @@ p, li { white-space: pre-wrap; } RegisterModel - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + 64-bit 64位 @@ -9719,30 +9736,6 @@ p, li { white-space: pre-wrap; } Accumulator 累加器 - - - - - - - - - - - - - - - - - - General purpose - 通用 - - - Instruction Pointer - 指令 - @@ -9752,19 +9745,28 @@ p, li { white-space: pre-wrap; } - - - - + + + + + + + + + General purpose + 通用 + + + Instruction Pointer + 指令 + + - 32-bit - 32位 - - + @@ -9776,16 +9778,16 @@ p, li { white-space: pre-wrap; } - + 32-bit + 32位 + + - lower 16 bits of %1 - %1的低16位 - - + @@ -9797,29 +9799,44 @@ p, li { white-space: pre-wrap; } - + lower 16 bits of %1 + %1的低16位 + + - lower 8 bits of %1 - %1的低8位 - - + - 8 high bits of lower 16 bits of %1 - %1的低16位数据中的高8位 - - + + lower 8 bits of %1 + %1的低8位 + + + + + + + 8 high bits of lower 16 bits of %1 + %1的低16位数据中的高8位 + + + + + + + + 16-bit 16位 @@ -9832,159 +9849,10 @@ p, li { white-space: pre-wrap; } 媒体 - - - - - - - - - - - - - 128-bit - 128位 - - - - Floating-point control - 浮点运算控制 - - - - - Accumulator for operands and results data - 操作数和结果的累加器 - - - - - Pointer to data in the DS segment - 指向DS段中数据的指针 - - - - - Counter for string and loop operations - 字符串和循环操作计数器 - - - - - I/O pointer - I/O指针 - - - - - Source index for string operations; Pointer to data in the segment pointed to by the DS register - 字符串操作来源下标;指向DS段中数据的指针 - - - - - Destination index for string operations; Pointer to data (or destination) in the segment pointed to by the ES register - 字符串操作目的下标;指向ES段中数据(或目标)的指针 - - - - - Stack pointer (in the SS segment) - 栈指针(在SS段中) - - - - - Pointer to data on the stack (in the SS segment) - 指向(SS段中)栈内数据的指针 - - - - - Instruction pointer - 指令指针 - - - - - Flags - 标志 - - - - Code segment selector - 代码段选择器 - - - - Data segment selector - 数据段选择器 - - - - - - Extra data segment selector - 额外的数据段选择器 - - - - Stack segment selector - 栈段选择器 - - - - - - - - - - - Floating-point data - 浮点运算数据 - - - - Floating-point status - 浮点运算状态 - - - - Floating-point tag word - 浮点运算标签word - - - - Floating-point operation - 浮点运算操作 - - - - Floating-point last instruction segment - 浮点运算上次指令段 - - - - Floating-point last instruction offset - 浮点运算上次指令位移 - - - - Floating-point last operand segment - 浮点运算上次操作数段 - - - - Floating-point last operand offset - 浮点运算上次操作数位移 - - + @@ -9996,25 +9864,174 @@ p, li { white-space: pre-wrap; } - + 128-bit + 128位 + + + + Floating-point control + 浮点运算控制 + + + + + Accumulator for operands and results data + 操作数和结果的累加器 + + + + + Pointer to data in the DS segment + 指向DS段中数据的指针 + + + + + Counter for string and loop operations + 字符串和循环操作计数器 + + + + + I/O pointer + I/O指针 + + + + + Source index for string operations; Pointer to data in the segment pointed to by the DS register + 字符串操作来源下标;指向DS段中数据的指针 + + + + + Destination index for string operations; Pointer to data (or destination) in the segment pointed to by the ES register + 字符串操作目的下标;指向ES段中数据(或目标)的指针 + + + + + Stack pointer (in the SS segment) + 栈指针(在SS段中) + + + + + Pointer to data on the stack (in the SS segment) + 指向(SS段中)栈内数据的指针 + + + + + Instruction pointer + 指令指针 + + + + + Flags + 标志 + + + + Code segment selector + 代码段选择器 + + + + Data segment selector + 数据段选择器 + + + + + + Extra data segment selector + 额外的数据段选择器 + + + + Stack segment selector + 栈段选择器 + + + + + + + + + + + Floating-point data + 浮点运算数据 + + + + Floating-point status + 浮点运算状态 + + + + Floating-point tag word + 浮点运算标签word + + + + Floating-point operation + 浮点运算操作 + + + + Floating-point last instruction segment + 浮点运算上次指令段 + + + + Floating-point last instruction offset + 浮点运算上次指令位移 + + + + Floating-point last operand segment + 浮点运算上次操作数段 + + + + Floating-point last operand offset + 浮点运算上次操作数位移 + + + + + + + + + + + + + + 256-bit 256位 - + SSE status and control SSE状态和控制 - + Register 寄存器 - + Value @@ -10643,12 +10660,12 @@ p, li { white-space: pre-wrap; } Settings - + Error 错误 - + Can't find terminal program! 找不到合适的终端程序! @@ -10845,18 +10862,18 @@ p, li { white-space: pre-wrap; } 性能 - - - - + + + + - + Compiler Set 编译器配置集 - - + + Compiler @@ -10868,13 +10885,13 @@ p, li { white-space: pre-wrap; } 自动链接 - + - + General 通用 @@ -10944,15 +10961,15 @@ p, li { white-space: pre-wrap; } 杂项 - - + + Program Runner 程序运行 - + Problem Set 试题集 @@ -11006,73 +11023,73 @@ p, li { white-space: pre-wrap; } Git - + Project Options 项目选项 - - - - - - - - - - - - + + + + + + + + + + + + Project 项目 - + Files 文件 - + Custom Compile options 自定义编译选项 - + Directories 文件夹 - + Precompiled Header 预编译头文件 - + Makefile Makefile - + Output 输出 - + DLL host DLL宿主 - + Version info 版本信息 - + Save Changes 保存修改 - + There are changes in the settings, do you want to save them before swtich to other page? 本页中有尚未保存的设置修改,是否保存后再切换到其他页? @@ -11492,14 +11509,14 @@ p, li { white-space: pre-wrap; } JSON文件'%1':%2中存在错误:%3 - - + + Execute to evaluate 执行以求值 - - + + Not Valid 在当前作用域中无效 @@ -11508,17 +11525,17 @@ p, li { white-space: pre-wrap; } 无法读取文件'%1'. - + Expression 表达式 - + Type 类型 - + Value diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index ab815827..b861fc7c 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -19,10 +19,6 @@ Build time: %1 %2 - - Copyright(C) 2021-2022 瞿华(royqh1979@gmail.com) - - <html><head/><body><p>Homepage: <a href="Homepage: https://sourceforge.net/projects/dev-cpp-2020/">https://sourceforge.net/projects/dev-cpp-2020/</a></p></body></html> @@ -71,6 +67,10 @@ Legacy Microsoft Visual C++ 舊版 Microsoft Visual C++ + + Copyright(C) 2021-2024 瞿华(royqh1979@gmail.com) + + AppTheme @@ -704,6 +704,10 @@ Survive auto-finds + + Don't localize compiler output messages + + CppRefacter diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp index 7849eced..e3323468 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp @@ -985,9 +985,6 @@ void CppSyntaxer::procRawString() } break; case ')': - qDebug()< Date: Wed, 21 Feb 2024 09:44:51 +0800 Subject: [PATCH 14/16] disable openSUSE CI build (#191) --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 418ced0b..dff87b81 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -252,6 +252,7 @@ jobs: rpm_opensuse: name: RPM on openSUSE Tumbleweed runs-on: ubuntu-latest + if: false steps: - uses: actions/checkout@v2 From e49f815119a042ab1ac560c50b368c79fa6a40b1 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Wed, 21 Feb 2024 09:58:18 +0800 Subject: [PATCH 15/16] Improve raw string syntax color --- libs/qsynedit/qsynedit/syntaxer/cpp.cpp | 21 +++++++++++++-------- libs/qsynedit/qsynedit/syntaxer/cpp.h | 2 -- libs/qsynedit/qsynedit/syntaxer/syntaxer.h | 10 +++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp index e3323468..b8c86d29 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp @@ -963,8 +963,9 @@ void CppSyntaxer::procQuestion() void CppSyntaxer::procRawString() { mTokenId = TokenId::RawString; + QString rawStringInitialDCharSeq; if (mRange.state == RangeState::rsRawString) - mRawStringInitialDCharSeq=""; + mRange.extraData = std::make_shared(""); while (mRun(rawStringInitialDCharSeq); } break; case ')': - if (mRange.state == RangeState::rsRawStringNotEscaping - && mLine.mid(mRun+1,mRawStringInitialDCharSeq.length()) == mRawStringInitialDCharSeq) { - mRun = mRun+1+mRawStringInitialDCharSeq.length(); - mRange.state = RangeState::rsUnknown; - return; + if (mRange.state == RangeState::rsRawStringNotEscaping) { + rawStringInitialDCharSeq = mRange.extraData->toString(); + if ( mLine.mid(mRun+1,rawStringInitialDCharSeq.length()) == rawStringInitialDCharSeq) { + mRun = mRun+1+rawStringInitialDCharSeq.length(); + mRange.state = RangeState::rsUnknown; + mRange.extraData = nullptr; + return; + } } break; } if (mRange.state == RangeState::rsRawString) - mRawStringInitialDCharSeq += mLine[mRun]; + rawStringInitialDCharSeq += mLine[mRun]; mRun+=1; } if (mRun>=mLineSize && mRange.state != RangeState::rsRawStringNotEscaping) diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.h b/libs/qsynedit/qsynedit/syntaxer/cpp.h index 4f5021cf..2c7509ad 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.h +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.h @@ -159,8 +159,6 @@ private: int mLeftBraces; int mRightBraces; - QString mRawStringInitialDCharSeq; - QSet mCustomTypeKeywords; PTokenAttribute mPreprocessorAttribute; diff --git a/libs/qsynedit/qsynedit/syntaxer/syntaxer.h b/libs/qsynedit/qsynedit/syntaxer/syntaxer.h index 5d39ee6b..96a708a2 100644 --- a/libs/qsynedit/qsynedit/syntaxer/syntaxer.h +++ b/libs/qsynedit/qsynedit/syntaxer/syntaxer.h @@ -54,15 +54,11 @@ struct SyntaxState { int parenthesisLevel; // current parenthesis embedding level (needed by rainbow color) // int leftBraces; // unpairing left braces in the current line ( needed by block folding) // int rightBraces; // unparing right braces in the current line (needed by block folding) - QVector indents; + QVector indents; // indents stack (needed by auto indent) IndentInfo lastUnindent; -// QVector indents; // indents stack (needed by auto indent) -// int firstIndentThisLine; /* index of first indent that appended to the indents -// * stack at this line ( need by auto indent) */ -// QVector matchingIndents; /* the indent matched ( and removed ) -// but not started at this line -// (need by auto indent) */ bool hasTrailingSpaces; + std::shared_ptr extraData; + bool operator==(const SyntaxState& s2); IndentInfo getLastIndent(); IndentType getLastIndentType(); From 15c5956e1e69b3b79177a1f3c79e8090e7889cf9 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Wed, 21 Feb 2024 10:01:15 +0800 Subject: [PATCH 16/16] minor change --- libs/qsynedit/qsynedit/syntaxer/cpp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp index b8c86d29..76620cb8 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp @@ -970,7 +970,8 @@ void CppSyntaxer::procRawString() if (mRange.state!=RangeState::rsRawStringNotEscaping && (mLine[mRun]=='"' || mLine[mRun].isSpace() - || mLine[mRun].unicode()>127)) { + || mLine[mRun].unicode()>127 + || mLine[mRun].unicode()<=32)) { mRange.state = RangeState::rsUnknown; mRun+=1; return;