Merge branch 'master' into emoji

This commit is contained in:
Roy Qu 2024-02-21 11:14:15 +08:00
commit 6592b9cd73
63 changed files with 4510 additions and 2136 deletions

4
.gitattributes vendored
View File

@ -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

View File

@ -252,6 +252,7 @@ jobs:
rpm_opensuse:
name: RPM on openSUSE Tumbleweed
runs-on: ubuntu-latest
if: false
steps:
- uses: actions/checkout@v2

View File

@ -42,6 +42,12 @@ 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.
- 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
- Enhancement: New option for compiler set "Don't localize gcc output messages"
Red Panda C++ Version 2.25

View File

@ -17,7 +17,9 @@ APP_NAME = RedPandaCPP
APP_VERSION = 2.26
TEST_VERSION = beta1
# TEST_VERSION = beta2
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
} 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)

View File

@ -21,6 +21,7 @@
#include <QPalette>
#include <QStyleFactory>
#include <QJsonValue>
#include <QMessageBox>
#ifdef Q_OS_WINDOWS
# include <windows.h>
@ -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;
}
}

View File

@ -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;

View File

@ -26,7 +26,8 @@ namespace AddOn {
static QMap<QString, QMap<QString, lua_CFunction>> 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<QString> &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;

View File

@ -27,13 +27,17 @@ namespace AddOn {
// simple, stateless Lua executor
class SimpleExecutor {
protected:
SimpleExecutor(const QList<QString> &apis): mApis(apis) {}
SimpleExecutor(const QString &kind, int major, int minor, const QList<QString> &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;
};

View File

@ -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<lua_State *, LuaExtraState> RaiiLuaState::mExtraState;

View File

@ -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);

View File

@ -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","");

View File

@ -104,6 +104,7 @@ protected:
std::shared_ptr<Project> mProject;
bool mSetLANG;
PCppParser mParserForFile;
bool mForceEnglishOutput;
private:
bool mStop;

View File

@ -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<QString,QString>("Address","address"));
sl.append(QPair<QString,QString>("Hardware-assisted address (arm64 only)","hwaddress"));
sl.append(QPair<QString,QString>("Hwaddress","hwaddress"));
sl.append(QPair<QString,QString>("Thread","thread"));
sl.append(QPair<QString,QString>("Leak","leak"));
sl.append(QPair<QString,QString>("Undefined","undefined"));

View File

@ -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;
@ -4350,14 +4349,13 @@ 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();
QList<PStatement> statements=mParser->getListOfFunctions(mFilename,
s,
functionNamePos.line);
// qDebug()<<"finding function list:"<<s<<" - "<<statements.length();
foreach (const PStatement statement, statements) {
pMainWindow->functionTip()->addTip(
statement->command,
@ -4672,7 +4670,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);
}

View File

@ -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)
@ -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 {
@ -5875,7 +5879,7 @@ PStatement CppParser::doParseEvalTypeInfo(
} else if (token == ">") {
templateLevel--;
}
baseType += token;
templateParams += token;
}
syntaxer.next();
}
@ -6305,6 +6309,7 @@ int CppParser::indexOfNextPeriodOrSemicolon(int index, int endIndex)
case ';':
case ',':
case '}':
case ')':
return index;
case '(':
index = mTokenizer[index]->matchIndex+1;

View File

@ -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;i<dCharSeq.length();i++) {
if (*pChar!=dCharSeq[i]) {
ok=false;
break;
}
pChar++;
}
if (ok && *pChar=='\"') {
noEscape = false;
mCurrent = pChar;
}
}
break;
}
if (findDCharSeq) {
dCharSeq+=*mCurrent;
}
if (*mCurrent == 0)
break;
if ((*mCurrent == '"') && !noEscape)

View File

@ -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;
@ -3279,7 +3294,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();
@ -3554,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());
@ -3642,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()) {

View File

@ -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;

View File

@ -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());

View File

@ -85,7 +85,7 @@
<item>
<widget class="QTabWidget" name="settingTabs">
<property name="currentIndex">
<number>4</number>
<number>0</number>
</property>
<property name="movable">
<bool>false</bool>
@ -146,6 +146,20 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkForceEnglishOutput">
<property name="text">
<string>Don't localize compiler output messages</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkPersistInAutoFind">
<property name="text">
<string>Survive auto-finds</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkUseCustomCompilerParams">
<property name="text">
@ -166,13 +180,6 @@
<item>
<widget class="QPlainTextEdit" name="txtCustomLinkParams"/>
</item>
<item>
<widget class="QCheckBox" name="chkPersistInAutoFind">
<property name="text">
<string>Survive auto-finds</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabSettings">
@ -497,8 +504,6 @@
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>
</resources>
<resources/>
<connections/>
</ui>

View File

@ -33,6 +33,6 @@
"PaletteTextDisabled":"#9DA9B5",
"PaletteMid": "#FFFFFF",
"PaletteLight": "#505050",
"PaletteMidLight": "#00ff00"
"PaletteMidlight": "#00ff00"
}
}

View File

@ -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

View File

@ -33,6 +33,6 @@
"PaletteTextDisabled":"#9DA9B5",
"PaletteMid": "#707070",
"PaletteLight": "#505050",
"PaletteMidLight": "#00ff00"
"PaletteMidlight": "#00ff00"
}
}

View File

@ -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

View File

@ -21,7 +21,7 @@
"PaletteLink":"#0000ff",
"PaletteLinkVisited":"#ff00ff",
"PaletteLight": "#ffffff",
"PaletteMidLight": "#cacaca",
"PaletteMidlight": "#cacaca",
"PaletteDark":"#9f9f9f",
"PaletteMid": "#b8b8b8",
"PaletteWindowDisabled":"#efefef",

View File

@ -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

View File

@ -33,6 +33,6 @@
"PaletteTextDisabled":"#9DA9B5",
"PaletteMid": "#FFFFFF",
"PaletteLight": "#505050",
"PaletteMidLight": "#00ff00"
"PaletteMidlight": "#00ff00"
}
}

View File

@ -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

View File

@ -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

View File

@ -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()
}

View File

@ -13,7 +13,7 @@
</message>
<message>
<source>Based on Qt %1 (%2) rodando em %3</source>
<translation>Com base em Qt %1 (%2) executado em %3</translation>
<translation type="vanished">Com base em Qt %1 (%2) executado em %3</translation>
</message>
<message>
<source>Build time: %1 %2</source>
@ -21,7 +21,7 @@
</message>
<message>
<source>Copyright(C) 2021-2022 (royqh1979@gmail.com)</source>
<translation>Copyright(C) 2021-2022 (royqh1979@gmail.com)</translation>
<translation type="vanished">Copyright(C) 2021-2022 (royqh1979@gmail.com)</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Homepage: &lt;a href=&quot;Homepage: https://sourceforge.net/projects/dev-cpp-2020/&quot;&gt;https://sourceforge.net/projects/dev-cpp-2020/&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@ -75,6 +75,14 @@
<source>Legacy Microsoft Visual C++</source>
<translation>Microsoft Visual C++ Legado</translation>
</message>
<message>
<source>Based on Qt %1 (%2) running on %3</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copyright(C) 2021-2024 (royqh1979@gmail.com)</source>
<translation type="unfinished">Copyright(C) 2021-2022 (royqh1979@gmail.com) {2021-2024 ?} {1979@?}</translation>
</message>
</context>
<context>
<name>AppTheme</name>
@ -815,6 +823,10 @@
<source>Survive auto-finds</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Don&apos;t localize compiler output messages</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CppRefacter</name>
@ -7110,6 +7122,10 @@
<source>Failed to detect terminal arguments pattern for %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error executing platform compiler hint add-on</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RegisterModel</name>

File diff suppressed because it is too large Load Diff

View File

@ -19,10 +19,6 @@
<source>Build time: %1 %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copyright(C) 2021-2022 (royqh1979@gmail.com)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Homepage: &lt;a href=&quot;Homepage: https://sourceforge.net/projects/dev-cpp-2020/&quot;&gt;https://sourceforge.net/projects/dev-cpp-2020/&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
@ -71,6 +67,10 @@
<source>Legacy Microsoft Visual C++</source>
<translation> Microsoft Visual C++</translation>
</message>
<message>
<source>Copyright(C) 2021-2024 (royqh1979@gmail.com)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AppTheme</name>
@ -704,6 +704,10 @@
<source>Survive auto-finds</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Don&apos;t localize compiler output messages</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CppRefacter</name>
@ -6622,6 +6626,10 @@
<source>Failed to detect terminal arguments pattern for %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error executing platform compiler hint add-on</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RegisterModel</name>

View File

@ -176,4 +176,8 @@ QString defaultShell();
QString appArch();
QString osArch();
#ifdef _MSC_VER
#define __builtin_unreachable() (__assume(0))
#endif
#endif // UTILS_H

View File

@ -23,8 +23,6 @@ APP_NAME = RedPandaCPP
APP_VERSION = 2.26
TEST_VERSION = beta1
win32: {
SUBDIRS += \
redpanda-win-git-askpass

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,421 @@
global function apiVersion(): ApiVersion
return {
kind = "compiler_hint",
major = 0,
minor = 1,
}
end
local gnuArchMap: {string:string} = {
i386 = "i686",
x86_64 = "x86_64",
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},
}
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
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
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"
local appDllDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/bin"
do
-- appArch is always debuggable
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, appDllDir},
}
local release, debug_, debugWithAsan = generateConfig(
function (arch_: string, profile: string): string
return nameGeneratorClang(lang, arch_, profile, true)
end,
programs,
{
arch = appArch,
customLinkParams = {"-Wl,utf8init.o", "-Wl,utf8manifest.o"},
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
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",
make = binDir .. "/mingw32-make.exe",
debugger = binDir .. "/lldb-mi.exe",
debugServer = binDir .. "/lldb-server.exe",
resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe",
binDirs = {binDir, foreignDllDir},
}
local release, _, _ = generateConfig(
function (arch_: string, profile: string): string
return nameGeneratorClang(lang, arch_, profile, true)
end,
programs,
{
arch = foreignArch,
customLinkParams = {"-Wl,utf8init.o", "-Wl,utf8manifest.o"},
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 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,
"-Wl,utf8init.o", "-Wl,utf8manifest.o",
},
isClang = true,
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug_)
end
for _, foreignArch in ipairs(supportedAppArches) do
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 = {
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 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,
"-Wl,utf8init.o", "-Wl,utf8manifest.o",
},
isClang = true,
}
)
table.insert(compilerList, release)
end
end
table.insert(noSearch, llvmOrgBinDir)
end
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()
end
local result = {
compilerList = compilerList,
noSearch = noSearch,
preferCompiler = preferCompiler,
}
return result
end

View File

@ -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

100
addon/defs/global_env.d.tl Normal file
View File

@ -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

63
addon/defs/theme.d.tl Normal file
View File

@ -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

30
addon/gen.sh Executable file
View File

@ -0,0 +1,30 @@
#!/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
gen-compiler-hint addon/compiler_hint/debian.tl packages/debian/compiler_hint.lua

53
addon/theme/contrast.tl Normal file
View File

@ -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

53
addon/theme/dark.tl Normal file
View File

@ -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

51
addon/theme/default.tl Normal file
View File

@ -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

53
addon/theme/molo.tl Normal file
View File

@ -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

132
addon/theme/random_light.tl Normal file
View File

@ -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

113
addon/theme/system.tl Normal file
View File

@ -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

View File

@ -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. Its packagers 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)).

View File

@ -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();

View File

@ -963,8 +963,15 @@ void CppSyntaxer::procQuestion()
void CppSyntaxer::procRawString()
{
mTokenId = TokenId::RawString;
QString rawStringInitialDCharSeq;
if (mRange.state == RangeState::rsRawString)
mRange.extraData = std::make_shared<QVariant>("");
while (mRun<mLineSize) {
if (mRange.state!=RangeState::rsRawStringNotEscaping && (mLine[mRun]=='"')) {
if (mRange.state!=RangeState::rsRawStringNotEscaping &&
(mLine[mRun]=='"'
|| mLine[mRun].isSpace()
|| mLine[mRun].unicode()>127
|| mLine[mRun].unicode()<=32)) {
mRange.state = RangeState::rsUnknown;
mRun+=1;
return;
@ -974,14 +981,26 @@ void CppSyntaxer::procRawString()
case '\t':
return;
case '(':
if (mRange.state==RangeState::rsRawString)
if (mRange.state==RangeState::rsRawString) {
mRange.state = RangeState::rsRawStringNotEscaping;
rawStringInitialDCharSeq += "\"";
mRange.extraData = std::make_shared<QVariant>(rawStringInitialDCharSeq);
}
break;
case ')':
if (mRange.state == RangeState::rsRawStringNotEscaping)
mRange.state = RangeState::rsRawStringEnd;
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)
rawStringInitialDCharSeq += mLine[mRun];
mRun+=1;
}
if (mRun>=mLineSize && mRange.state != RangeState::rsRawStringNotEscaping)

View File

@ -23,6 +23,7 @@ namespace QSynedit {
class CppSyntaxer: public Syntaxer
{
public:
enum class TokenId {
Comment,
Directive,
@ -50,10 +51,9 @@ class CppSyntaxer: public Syntaxer
rsDocstring,
rsStringEscapeSeq,
rsRawString, rsSpace,rsRawStringNotEscaping,rsRawStringEnd,rsChar,
rsDefineIdentifier, rsDefineRemaining
rsDefineIdentifier, rsDefineRemaining,
};
public:
explicit CppSyntaxer();
CppSyntaxer(const CppSyntaxer&)=delete;
CppSyntaxer operator=(const CppSyntaxer&)=delete;

View File

@ -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<IndentInfo> indents;
QVector<IndentInfo> indents; // indents stack (needed by auto indent)
IndentInfo lastUnindent;
// QVector<int> 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<int> matchingIndents; /* the indent matched ( and removed )
// but not started at this line
// (need by auto indent) */
bool hasTrailingSpaces;
std::shared_ptr<QVariant> extraData;
bool operator==(const SyntaxState& s2);
IndentInfo getLastIndent();
IndentType getLastIndentType();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,386 +1,421 @@
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",
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
local function mergeCompilerSet(compilerSet, other)
local c = compilerSet
local o = other
for k, v in pairs(o) do
c[k] = v
end
end
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,
{
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 },
}
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 = {extraObjects.utf8init, extraObjects.utf8manifest},
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug)
if preferCompiler == 0 then
preferCompiler = 2
end
customLinkParams = { "-Wl,--whole-archive", "-lutf8", "-Wl,--no-whole-archive" },
})
release, debug, debugWithAsan = generateConfig(
function (arch, profile) return nameGenerator.mingwGcc(lang, arch, profile, false) end,
programs,
{
table.insert(compilerList, release)
table.insert(compilerList, debug_)
if preferCompiler == 0 then
preferCompiler = 2
end
end
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(noSearch, excludeBinDir)
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,
{
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
table.insert(compilerList, release)
table.insert(compilerList, debug_)
if preferCompiler == 0 then
preferCompiler = 2
end
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"
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"
local appDllDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/bin"
do
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, appDllDir },
}
local release, debug_, debugWithAsan = generateConfig(
function(arch_, profile)
return nameGeneratorClang(lang, arch_, profile, true)
end,
programs,
{
arch = appArch,
customLinkParams = { "-Wl,utf8init.o", "-Wl,utf8manifest.o" },
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
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",
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, foreignDllDir },
}
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,
{
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 = { "-Wl,utf8init.o", "-Wl,utf8manifest.o" },
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 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,
"-Wl,utf8init.o", "-Wl,utf8manifest.o",
},
isClang = true,
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug)
})
for _, foreignArch in ipairs(supportedAppArches) do
if foreignArch ~= appArch then
local foreignTriplet = gnuArchMap[foreignArch] .. "-w64-mingw32"
table.insert(compilerList, release)
table.insert(compilerList, debug_)
end
for _, foreignArch in ipairs(supportedAppArches) do
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 = {
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",
}
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,
"-Wl,utf8init.o", "-Wl,utf8manifest.o",
},
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")
checkAndAddMingw("i386")
checkAndAddClang()
elseif appArch == "arm64" then
checkAndAddClang()
checkAndAddMingw("x86_64")
checkAndAddMingw("i386")
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

View File

@ -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 终端模拟器"

View File

@ -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