aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/syntax-highlighting/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/syntax-highlighting/src')
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp14
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp438
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt27
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp50
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h13
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp102
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp17
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp9
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp107
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definition.h28
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp18
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp33
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp39
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp31
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h34
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp191
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository.h10
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp295
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h74
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp56
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/theme.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp21
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h33
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h2
31 files changed, 1096 insertions, 571 deletions
diff --git a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
index a009c4f259..749123aa54 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
@@ -30,10 +30,11 @@ static void applyHighlighter(Highlighter &highlighter,
const QCommandLineOption &outputName,
const Ts &...highlightParams)
{
- if (parser.isSet(outputName))
+ if (parser.isSet(outputName)) {
highlighter.setOutputFile(parser.value(outputName));
- else
+ } else {
highlighter.setOutputFile(stdout);
+ }
if (fromFileName) {
highlighter.highlightFile(inFileName, highlightParams...);
@@ -126,8 +127,9 @@ int main(int argc, char **argv)
}
if (parser.isSet(listThemes)) {
- for (const auto &theme : repo.themes())
+ for (const auto &theme : repo.themes()) {
std::cout << qPrintable(theme.name()) << std::endl;
+ }
return 0;
}
@@ -158,9 +160,10 @@ int main(int argc, char **argv)
if (!def.isValid()) {
/* see if it's a extension instead */
def = repo.definitionForFileName(QLatin1String("f.") + syntax);
- if (!def.isValid())
+ if (!def.isValid()) {
/* see if it's a filename instead */
def = repo.definitionForFileName(syntax);
+ }
}
}
} else if (fromFileName) {
@@ -177,8 +180,9 @@ int main(int argc, char **argv)
QString outputFormat = parser.value(outputFormatOption);
if (0 == outputFormat.compare(QLatin1String("html"), Qt::CaseInsensitive)) {
QString title;
- if (parser.isSet(titleOption))
+ if (parser.isSet(titleOption)) {
title = parser.value(titleOption);
+ }
HtmlHighlighter highlighter;
highlighter.setDefinition(def);
diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt
index 508cd276cc..4a84696ad9 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt
@@ -28,7 +28,8 @@ elseif(CMAKE_CROSSCOMPILING)
else()
# host build
add_executable(katehighlightingindexer katehighlightingindexer.cpp ../lib/worddelimiters.cpp)
- if(Qt5XmlPatterns_FOUND)
+ ecm_mark_nongui_executable(katehighlightingindexer)
+ if(Qt5XmlPatterns_FOUND AND NOT ECM_ENABLE_SANITIZERS)
target_link_libraries(katehighlightingindexer Qt5::XmlPatterns)
else()
target_link_libraries(katehighlightingindexer Qt5::Core)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
index 86b3a38b12..4de51ba7c8 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
@@ -31,7 +31,8 @@ using KSyntaxHighlighting::Xml::attrToBool;
class HlFilesChecker
{
public:
- void setDefinition(const QStringRef &verStr, const QString &filename, const QString &name)
+ template<typename T>
+ void setDefinition(const T &verStr, const QString &filename, const QString &name)
{
m_currentDefinition = &*m_definitions.insert(name, Definition{});
m_currentDefinition->languageName = name;
@@ -93,6 +94,12 @@ public:
continue;
}
+ auto markAsUsedContext = [](ContextName &ContextName) {
+ if (!ContextName.stay && ContextName.context) {
+ ContextName.context->isOnlyIncluded = false;
+ }
+ };
+
QMutableMapIterator<QString, Context> contextIt(contexts);
while (contextIt.hasNext()) {
contextIt.next();
@@ -100,12 +107,21 @@ public:
resolveContextName(definition, context, context.lineEndContext, context.line);
resolveContextName(definition, context, context.lineEmptyContext, context.line);
resolveContextName(definition, context, context.fallthroughContext, context.line);
+ markAsUsedContext(context.lineEndContext);
+ markAsUsedContext(context.lineEmptyContext);
+ markAsUsedContext(context.fallthroughContext);
for (auto &rule : context.rules) {
+ rule.parentContext = &context;
resolveContextName(definition, context, rule.context, rule.line);
+ if (rule.type != Context::Rule::Type::IncludeRules) {
+ markAsUsedContext(rule.context);
+ }
}
}
- definition.firstContext = &*definition.contexts.find(definition.firstContextName);
+ auto *firstContext = &*definition.contexts.find(definition.firstContextName);
+ firstContext->isOnlyIncluded = false;
+ definition.firstContext = firstContext;
}
resolveIncludeRules();
@@ -118,6 +134,7 @@ public:
const auto usedContexts = extractUsedContexts();
QMap<const Definition *, const Definition *> maxVersionByDefinitions;
+ QMap<const Context::Rule *, IncludedRuleUnreachableBy> unreachableIncludedRules;
QMapIterator<QString, Definition> def(m_definitions);
while (def.hasNext()) {
@@ -135,14 +152,7 @@ public:
QSet<const Keywords *> referencedKeywords;
QSet<ItemDatas::Style> usedAttributeNames;
success = checkKeywordsList(definition, referencedKeywords) && success;
- success = checkContexts(definition, referencedKeywords, usedAttributeNames, usedContexts) && success;
-
- // search for non-existing or unreferenced keyword lists.
- for (const auto &keywords : definition.keywordsList) {
- if (!referencedKeywords.contains(&keywords)) {
- qWarning() << filename << "line" << keywords.line << "unused keyword:" << keywords.name;
- }
- }
+ success = checkContexts(definition, referencedKeywords, usedAttributeNames, usedContexts, unreachableIncludedRules) && success;
// search for non-existing itemDatas.
const auto invalidNames = usedAttributeNames - definition.itemDatas.styleNames;
@@ -159,6 +169,56 @@ public:
}
}
+ QMutableMapIterator<const Context::Rule *, IncludedRuleUnreachableBy> unreachableIncludedRuleIt(unreachableIncludedRules);
+ while (unreachableIncludedRuleIt.hasNext()) {
+ unreachableIncludedRuleIt.next();
+ IncludedRuleUnreachableBy &unreachableRulesBy = unreachableIncludedRuleIt.value();
+ if (unreachableRulesBy.alwaysUnreachable) {
+ auto *rule = unreachableIncludedRuleIt.key();
+
+ if (!rule->parentContext->isOnlyIncluded) {
+ continue;
+ }
+
+ // remove duplicates rules
+ QSet<const Context::Rule *> rules;
+ auto &unreachableBy = unreachableRulesBy.unreachableBy;
+ unreachableBy.erase(std::remove_if(unreachableBy.begin(),
+ unreachableBy.end(),
+ [&](const RuleAndInclude &ruleAndInclude) {
+ if (rules.contains(ruleAndInclude.rule)) {
+ return true;
+ }
+ rules.insert(ruleAndInclude.rule);
+ return false;
+ }),
+ unreachableBy.end());
+
+ QString message;
+ message.reserve(128);
+ for (auto &ruleAndInclude : std::as_const(unreachableBy)) {
+ message += QStringLiteral("line ");
+ message += QString::number(ruleAndInclude.rule->line);
+ message += QStringLiteral(" [");
+ message += ruleAndInclude.rule->parentContext->name;
+ if (rule->filename != ruleAndInclude.rule->filename) {
+ message += QStringLiteral(" (");
+ message += ruleAndInclude.rule->filename;
+ message += QLatin1Char(')');
+ }
+ if (ruleAndInclude.includeRules) {
+ message += QStringLiteral(" via line ");
+ message += QString::number(ruleAndInclude.includeRules->line);
+ }
+ message += QStringLiteral("], ");
+ }
+ message.chop(2);
+
+ qWarning() << rule->filename << "line" << rule->line << "no IncludeRule can reach this rule, hidden by" << message;
+ success = false;
+ }
+ }
+
return success;
}
@@ -176,7 +236,7 @@ private:
int popCount = 0;
bool stay = false;
- const Context *context = nullptr;
+ Context *context = nullptr;
};
struct Parser {
@@ -185,12 +245,13 @@ private:
QXmlStreamAttribute &attr;
bool success;
- //! Read a string type attribute, \c sucess = \c false when \p str is not empty
+ //! Read a string type attribute, \c success = \c false when \p str is not empty
//! \return \c true when attr.name() == attrName, otherwise false
bool extractString(QString &str, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
str = attr.value().toString();
if (str.isEmpty()) {
@@ -201,24 +262,26 @@ private:
return true;
}
- //! Read a bool type attribute, \c sucess = \c false when \p xmlBool is not \c XmlBool::Unspecified.
+ //! Read a bool type attribute, \c success = \c false when \p xmlBool is not \c XmlBool::Unspecified.
//! \return \c true when attr.name() == attrName, otherwise false
bool extractXmlBool(XmlBool &xmlBool, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
xmlBool = attr.value().isNull() ? XmlBool::Unspecified : attrToBool(attr.value()) ? XmlBool::True : XmlBool::False;
return true;
}
- //! Read a positive integer type attribute, \c sucess = \c false when \p positive is already greater than or equal to 0
+ //! Read a positive integer type attribute, \c success = \c false when \p positive is already greater than or equal to 0
//! \return \c true when attr.name() == attrName, otherwise false
bool extractPositive(int &positive, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
bool ok = true;
positive = attr.value().toInt(&ok);
@@ -231,12 +294,13 @@ private:
return true;
}
- //! Read a color, \c sucess = \c false when \p color is already greater than or equal to 0
+ //! Read a color, \c success = \c false when \p color is already greater than or equal to 0
//! \return \c true when attr.name() == attrName, otherwise false
bool checkColor(const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
const auto value = attr.value().toString();
if (value.isEmpty() /*|| QColor(value).isValid()*/) {
@@ -247,16 +311,17 @@ private:
return true;
}
- //! Read a QChar, \c sucess = \c false when \p c is not \c '\0' or does not have one char
+ //! Read a QChar, \c success = \c false when \p c is not \c '\0' or does not have one char
//! \return \c true when attr.name() == attrName, otherwise false
bool extractChar(QChar &c, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
- if (attr.value().size() == 1)
+ if (attr.value().size() == 1) {
c = attr.value()[0];
- else {
+ } else {
c = QLatin1Char('_');
qWarning() << filename << "line" << xml.lineNumber() << attrName << "must contain exactly one char:" << attr.value();
success = false;
@@ -268,8 +333,9 @@ private:
//! \return parsing status when \p isExtracted is \c true, otherwise \c false
bool checkIfExtracted(bool isExtracted)
{
- if (isExtracted)
+ if (isExtracted) {
return success;
+ }
qWarning() << filename << "line" << xml.lineNumber() << "unknown attribute:" << attr.name();
return false;
@@ -284,7 +350,7 @@ private:
friend uint qHash(const Item &item, uint seed = 0)
{
- return qHash(item.content, seed);
+ return uint(qHash(item.content, seed));
}
friend bool operator==(const Item &item0, const Item &item1)
@@ -400,18 +466,19 @@ private:
QString additionalDeliminator;
QString weakDeliminator;
- // rules included by IncludeRules
+ // rules included by IncludeRules (without IncludeRule)
QVector<const Rule *> includedRules;
// IncludeRules included by IncludeRules
QSet<const Rule *> includedIncludeRules;
+ Context const *parentContext = nullptr;
+
QString filename;
bool parseElement(const QString &filename, QXmlStreamReader &xml)
{
this->filename = filename;
-
line = xml.lineNumber();
using Pair = QPair<QString, Type>;
@@ -579,6 +646,8 @@ private:
};
int line;
+ // becomes false when a context refers to it
+ bool isOnlyIncluded = true;
QString name;
QString attribute;
ContextName lineEndContext;
@@ -650,7 +719,7 @@ private:
friend uint qHash(const Style &style, uint seed = 0)
{
- return qHash(style.name, seed);
+ return uint(qHash(style.name, seed));
}
friend bool operator==(const Style &style0, const Style &style1)
@@ -723,8 +792,9 @@ private:
{
Context context;
m_success = context.parseElement(m_currentDefinition->filename, xml) && m_success;
- if (m_currentDefinition->firstContextName.isEmpty())
+ if (m_currentDefinition->firstContextName.isEmpty()) {
m_currentDefinition->firstContextName = context.name;
+ }
if (m_currentDefinition->contexts.contains(context.name)) {
qWarning() << m_currentDefinition->filename << "line" << xml.lineNumber() << "duplicate context:" << context.name;
m_success = false;
@@ -784,6 +854,7 @@ private:
m_success = false;
continue;
}
+
if (rule.context.popCount) {
qWarning() << definition.filename << "line" << rule.line << "IncludeRules with #pop prefix";
m_success = false;
@@ -794,6 +865,8 @@ private:
continue;
}
+ // resolve includedRules and includedIncludeRules
+
usedContexts.clear();
usedContexts.insert(rule.context.context);
contexts.clear();
@@ -866,11 +939,27 @@ private:
return usedContexts;
}
+ struct RuleAndInclude {
+ const Context::Rule *rule;
+ const Context::Rule *includeRules;
+
+ explicit operator bool() const
+ {
+ return rule;
+ }
+ };
+
+ struct IncludedRuleUnreachableBy {
+ QVector<RuleAndInclude> unreachableBy;
+ bool alwaysUnreachable = true;
+ };
+
//! Check contexts and rules
bool checkContexts(const Definition &definition,
QSet<const Keywords *> &referencedKeywords,
QSet<ItemDatas::Style> &usedAttributeNames,
- const QSet<const Context *> &usedContexts) const
+ const QSet<const Context *> &usedContexts,
+ QMap<const Context::Rule *, IncludedRuleUnreachableBy> &unreachableIncludedRules) const
{
bool success = true;
@@ -892,16 +981,18 @@ private:
success = false;
}
- if (!context.attribute.isEmpty())
+ if (!context.attribute.isEmpty()) {
usedAttributeNames.insert({context.attribute, context.line});
+ }
success = checkfallthrough(definition, context) && success;
- success = checkUreachableRules(definition.filename, context) && success;
+ success = checkUreachableRules(definition.filename, context, unreachableIncludedRules) && success;
success = suggestRuleMerger(definition.filename, context) && success;
for (const auto &rule : context.rules) {
- if (!rule.attribute.isEmpty())
+ if (!rule.attribute.isEmpty()) {
usedAttributeNames.insert({rule.attribute, rule.line});
+ }
success = checkLookAhead(rule) && success;
success = checkStringDetect(rule) && success;
success = checkAnyChar(rule) && success;
@@ -954,9 +1045,14 @@ private:
return false;
}
+#define REG_ESCAPE_CHAR R"(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4}))"
+#define REG_CHAR "(?:" REG_ESCAPE_CHAR "|\\[(?:" REG_ESCAPE_CHAR "|.)\\]|[^[.^])"
+
// is RangeDetect
- static const QRegularExpression isRange(QStringLiteral(
- R"(^(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4})|[^[.]|\[[^].\\]\])(?:\.|\[^\1\])\*[?*]?\1$)"));
+ static const QRegularExpression isRange(QStringLiteral("^\\^?" REG_CHAR "(?:"
+ "\\.\\*[?*]?" REG_CHAR "|"
+ "\\[\\^(" REG_ESCAPE_CHAR "|.)\\]\\*[?*]?\\1"
+ ")$"));
if (( rule.lookAhead == XmlBool::True
|| rule.minimal == XmlBool::True
|| rule.string.contains(QStringLiteral(".*?"))
@@ -967,11 +1063,21 @@ private:
return false;
}
+ // is LineContinue
+ static const QRegularExpression isLineContinue(QStringLiteral("^\\^?" REG_CHAR "\\$$"));
+ if (reg.contains(isLineContinue)) {
+ auto extra = (reg[0] == QLatin1Char('^')) ? "with column=\"0\"" : "";
+ qWarning() << filename << "line" << rule.line << "RegExpr should be replaced by LineContinue:" << rule.string << extra;
+ return false;
+ }
+
// replace \c, \xhhh, \x{hhh...}, \0dd, \o{ddd}, \uhhhh, with _
- static const QRegularExpression sanitize1(
- QStringLiteral(R"(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4}))"));
+ static const QRegularExpression sanitize1(QStringLiteral(REG_ESCAPE_CHAR));
reg.replace(sanitize1, QStringLiteral("_"));
+#undef REG_CHAR
+#undef REG_ESCAPE_CHAR
+
// use minimal or lazy operator
static const QRegularExpression isMinimal(QStringLiteral(
R"([.][*+][^][?+*()|$]*$)"));
@@ -1008,8 +1114,9 @@ private:
char const *extraMsg = rule.string.contains(QLatin1Char('^')) ? "+ column=\"0\" or firstNonSpace=\"1\"" : "";
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by StringDetect / Detect2Chars / DetectChar" << extraMsg
<< ":" << rule.string;
- if (len != reg.size())
+ if (len != reg.size()) {
qWarning() << rule.filename << "line" << rule.line << "insensitive=\"1\" missing:" << rule.string;
+ }
return false;
}
@@ -1019,8 +1126,8 @@ private:
// (^sas*) -> ok
// (^sa|s*) -> ko
// (^(sa|s*)) -> ok
- auto first = qAsConst(reg).begin();
- auto last = qAsConst(reg).end();
+ auto first = std::as_const(reg).begin();
+ auto last = std::as_const(reg).end();
int depth = 0;
while (QLatin1Char('(') == *first) {
@@ -1066,8 +1173,8 @@ private:
// add ^ with column=0
if (rule.column == 0 && !rule.isDotRegex) {
bool hasStartOfLine = false;
- auto first = qAsConst(reg).begin();
- auto last = qAsConst(reg).end();
+ auto first = std::as_const(reg).begin();
+ auto last = std::as_const(reg).end();
for (; first != last; ++first) {
if (*first == QLatin1Char('^')) {
hasStartOfLine = true;
@@ -1306,8 +1413,9 @@ private:
//! Search for additionalDeliminator/weakDeliminator which has no effect.
bool checkDelimiters(const Definition &definition, const Context::Rule &rule) const
{
- if (rule.additionalDeliminator.isEmpty() && rule.weakDeliminator.isEmpty())
+ if (rule.additionalDeliminator.isEmpty() && rule.weakDeliminator.isEmpty()) {
return true;
+ }
bool success = true;
@@ -1472,16 +1580,39 @@ private:
//! - StringDetect, WordDetect, RegExpr with as prefix Detect2Chars or other strings
//! - duplicate rule (Int, Float, keyword with same String, etc)
//! - Rule hidden by a dot regex
- bool checkUreachableRules(const QString &filename, const Context &context) const
+ bool checkUreachableRules(const QString &filename,
+ const Context &context,
+ QMap<const Context::Rule *, IncludedRuleUnreachableBy> &unreachableIncludedRules) const
{
- struct RuleAndInclude {
- const Context::Rule *rule;
- const Context::Rule *includeRules;
+ if (context.isOnlyIncluded) {
+ return true;
+ }
- explicit operator bool() const
+ struct Rule4 {
+ RuleAndInclude setRule(const Context::Rule &rule, const Context::Rule *includeRules = nullptr)
{
- return rule;
+ auto set = [&](RuleAndInclude &ruleAndInclude) {
+ auto old = ruleAndInclude;
+ ruleAndInclude = {&rule, includeRules};
+ return old;
+ };
+
+ if (rule.firstNonSpace == XmlBool::True) {
+ return set(firstNonSpace);
+ } else if (rule.column == 0) {
+ return set(column0);
+ } else if (rule.column > 0) {
+ return set(columnGreaterThan0[rule.column]);
+ } else {
+ return set(normal);
+ }
}
+
+ private:
+ RuleAndInclude normal;
+ RuleAndInclude column0;
+ QMap<int, RuleAndInclude> columnGreaterThan0;
+ RuleAndInclude firstNonSpace;
};
// Associate QChar with RuleAndInclude
@@ -1489,8 +1620,9 @@ private:
/// Search RuleAndInclude associated with @p c.
RuleAndInclude find(QChar c) const
{
- if (c.unicode() < 128)
+ if (c.unicode() < 128) {
return m_asciiMap[c.unicode()];
+ }
auto it = m_utf8Map.find(c);
return it == m_utf8Map.end() ? RuleAndInclude{nullptr, nullptr} : it.value();
}
@@ -1517,10 +1649,11 @@ private:
/// Associates @p c with a rule.
void append(QChar c, const Context::Rule &rule, const Context::Rule *includeRule = nullptr)
{
- if (c.unicode() < 128)
+ if (c.unicode() < 128) {
m_asciiMap[c.unicode()] = {&rule, includeRule};
- else
+ } else {
m_utf8Map[c] = {&rule, includeRule};
+ }
}
/// Associates each character of @p s with a rule.
@@ -1549,13 +1682,15 @@ private:
// Char4Tables::char is always added.
CharTableArray(Char4Tables &tables, const Context::Rule &rule)
{
- if (rule.firstNonSpace == XmlBool::True)
+ if (rule.firstNonSpace == XmlBool::True) {
appendTable(tables.charsFirstNonSpace);
+ }
- if (rule.column == 0)
+ if (rule.column == 0) {
appendTable(tables.charsColumn0);
- else if (rule.column > 0)
+ } else if (rule.column > 0) {
appendTable(tables.charsColumnGreaterThan0[rule.column]);
+ }
appendTable(tables.chars);
}
@@ -1572,8 +1707,9 @@ private:
RuleAndInclude find(QChar c) const
{
for (int i = 0; i < m_size; ++i) {
- if (auto ruleAndInclude = m_charTables[i]->find(c))
+ if (auto ruleAndInclude = m_charTables[i]->find(c)) {
return ruleAndInclude;
+ }
}
return RuleAndInclude{nullptr, nullptr};
}
@@ -1621,9 +1757,19 @@ private:
int m_size = 0;
};
+ struct ObservableRule {
+ const Context::Rule *rule;
+ const Context::Rule *includeRules;
+
+ bool hasResolvedIncludeRules() const
+ {
+ return rule == includeRules;
+ }
+ };
+
// Iterates over all the rules, including those in includedRules
struct RuleIterator {
- RuleIterator(const QVector<Context::Rule> &rules, const Context::Rule &endRule)
+ RuleIterator(const QVector<ObservableRule> &rules, const ObservableRule &endRule)
: m_end(&endRule - rules.data())
, m_rules(rules)
{
@@ -1635,7 +1781,7 @@ private:
// if in includedRules
if (m_includedRules) {
++m_i2;
- if (m_i2 != m_rules[m_i].includedRules.size()) {
+ if (m_i2 != m_includedRules->size()) {
return (*m_includedRules)[m_i2];
}
++m_i;
@@ -1643,10 +1789,10 @@ private:
}
// if is a includedRules
- while (m_i < m_end && m_rules[m_i].type == Context::Rule::Type::IncludeRules) {
- if (m_rules[m_i].includedRules.size()) {
+ while (m_i < m_end && m_rules[m_i].rule->type == Context::Rule::Type::IncludeRules) {
+ if (!m_rules[m_i].includeRules && m_rules[m_i].rule->includedRules.size()) {
m_i2 = 0;
- m_includedRules = &m_rules[m_i].includedRules;
+ m_includedRules = &m_rules[m_i].rule->includedRules;
return (*m_includedRules)[m_i2];
}
++m_i;
@@ -1654,7 +1800,7 @@ private:
if (m_i < m_end) {
++m_i;
- return &m_rules[m_i - 1];
+ return m_rules[m_i - 1].rule;
}
return nullptr;
@@ -1663,14 +1809,14 @@ private:
/// \return current IncludeRules or nullptr
const Context::Rule *currentIncludeRules() const
{
- return m_includedRules ? &m_rules[m_i] : nullptr;
+ return m_includedRules ? m_rules[m_i].rule : m_rules[m_i].includeRules;
}
private:
int m_i = 0;
int m_i2;
int m_end;
- const QVector<Context::Rule> &m_rules;
+ const QVector<ObservableRule> &m_rules;
const QVector<const Context::Rule *> *m_includedRules = nullptr;
};
@@ -1680,20 +1826,24 @@ private:
void append(const Context::Rule &rule, const Context::Rule *includedRule)
{
auto array = extractDotRegexes(rule);
- if (array[0])
+ if (array[0]) {
*array[0] = {&rule, includedRule};
- if (array[1])
+ }
+ if (array[1]) {
*array[1] = {&rule, includedRule};
+ }
}
/// Search dot regex which hides @p rule
RuleAndInclude find(const Context::Rule &rule)
{
auto array = extractDotRegexes(rule);
- if (array[0])
+ if (array[0]) {
return *array[0];
- if (array[1])
+ }
+ if (array[1]) {
return *array[1];
+ }
return RuleAndInclude{};
}
@@ -1707,13 +1857,15 @@ private:
if (rule.firstNonSpace != XmlBool::True && rule.column == -1) {
ret[0] = &dotRegex;
} else {
- if (rule.firstNonSpace == XmlBool::True)
+ if (rule.firstNonSpace == XmlBool::True) {
ret[0] = &dotRegexFirstNonSpace;
+ }
- if (rule.column == 0)
+ if (rule.column == 0) {
ret[1] = &dotRegexColumn0;
- else if (rule.column > 0)
+ } else if (rule.column > 0) {
ret[1] = &dotRegexColumnGreaterThan0[rule.column];
+ }
}
return ret;
@@ -1734,23 +1886,44 @@ private:
// characters of LineContinue
Char4Tables lineContinueChars;
- RuleAndInclude intRule{};
- RuleAndInclude floatRule{};
- RuleAndInclude hlCCharRule{};
- RuleAndInclude hlCOctRule{};
- RuleAndInclude hlCHexRule{};
- RuleAndInclude hlCStringCharRule{};
+ Rule4 intRule{};
+ Rule4 floatRule{};
+ Rule4 hlCCharRule{};
+ Rule4 hlCOctRule{};
+ Rule4 hlCHexRule{};
+ Rule4 hlCStringCharRule{};
+ Rule4 detectIdentifierRule{};
// Contains includedRules and included includedRules
QMap<Context const*, RuleAndInclude> includeContexts;
DotRegex dotRegex;
+ QVector<ObservableRule> observedRules;
+ observedRules.reserve(context.rules.size());
for (const Context::Rule &rule : context.rules) {
+ const Context::Rule *includeRule = nullptr;
+ if (rule.type == Context::Rule::Type::IncludeRules) {
+ auto *context = rule.context.context;
+ if (context && context->isOnlyIncluded) {
+ includeRule = &rule;
+ }
+ }
+
+ observedRules.push_back({&rule, includeRule});
+ if (includeRule) {
+ for (const Context::Rule *rule2 : rule.includedRules) {
+ observedRules.push_back({rule2, includeRule});
+ }
+ }
+ }
+
+ for (auto &observedRule : observedRules) {
+ const Context::Rule &rule = *observedRule.rule;
bool isUnreachable = false;
QVector<RuleAndInclude> unreachableBy;
- // declare rule as unreacheable if ruleAndInclude is not empty
+ // declare rule as unreachable if ruleAndInclude is not empty
auto updateUnreachable1 = [&](RuleAndInclude ruleAndInclude) {
if (ruleAndInclude) {
isUnreachable = true;
@@ -1758,7 +1931,7 @@ private:
}
};
- // declare rule as unreacheable if ruleAndIncludes is not empty
+ // declare rule as unreachable if ruleAndIncludes is not empty
auto updateUnreachable2 = [&](const QVector<RuleAndInclude> &ruleAndIncludes) {
if (!ruleAndIncludes.isEmpty()) {
isUnreachable = true;
@@ -1810,43 +1983,42 @@ private:
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCChar:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('\'')));
- updateUnreachable1(hlCCharRule);
- hlCCharRule = {&rule, nullptr};
+ updateUnreachable1(hlCCharRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCHex:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('0')));
- updateUnreachable1(hlCHexRule);
- hlCHexRule = {&rule, nullptr};
+ updateUnreachable1(hlCHexRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCOct:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('0')));
- updateUnreachable1(hlCOctRule);
- hlCOctRule = {&rule, nullptr};
+ updateUnreachable1(hlCOctRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCStringChar:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('\\')));
- updateUnreachable1(hlCStringCharRule);
- hlCStringCharRule = {&rule, nullptr};
+ updateUnreachable1(hlCStringCharRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::Int:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789")));
- updateUnreachable1(intRule);
- intRule = {&rule, nullptr};
+ updateUnreachable1(intRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::Float:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789.")));
- updateUnreachable1(floatRule);
- floatRule = {&rule, nullptr};
+ updateUnreachable1(floatRule.setRule(rule));
+ break;
+
+ // check if hidden by another DetectIdentifier rule
+ case Context::Rule::Type::DetectIdentifier:
+ updateUnreachable1(detectIdentifierRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar or another LineContinue
@@ -1865,10 +2037,11 @@ private:
case Context::Rule::Type::RangeDetect:
updateUnreachable1(CharTableArray(detectChars, rule).find(rule.char0));
if (!isUnreachable) {
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type == rule.type && isCompatible(rule2) && rule.char0 == rule2.char0 && rule.char1 == rule2.char1) {
updateUnreachable1({&rule2, ruleIterator.currentIncludeRules()});
@@ -1884,10 +2057,11 @@ private:
}
// check that `rule` does not have another RegExpr as a prefix
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type == Context::Rule::Type::RegExpr && isCompatible(rule2) && rule.insensitive == rule2.insensitive
&& rule.dynamic == rule2.dynamic && rule.string.startsWith(rule2.string)) {
@@ -1902,10 +2076,11 @@ private:
case Context::Rule::Type::StringDetect: {
// check that dynamic `rule` does not have another dynamic StringDetect as a prefix
if (rule.type == Context::Rule::Type::StringDetect && rule.dynamic == XmlBool::True) {
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type != Context::Rule::Type::StringDetect || rule2.dynamic != XmlBool::True || !isCompatible(rule2)) {
@@ -1963,10 +2138,11 @@ private:
// combination of uppercase and lowercase
RuleAndInclude detect2CharsInsensitives[]{{}, {}, {}, {}};
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
const bool isSensitive = (rule2.insensitive == XmlBool::True);
const auto caseSensitivity = isSensitive ? Qt::CaseInsensitive : Qt::CaseSensitive;
@@ -2030,10 +2206,11 @@ private:
// check if hidden by another keyword rule
case Context::Rule::Type::keyword: {
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type == Context::Rule::Type::keyword && isCompatible(rule2) && rule.string == rule2.string) {
updateUnreachable1({&rule2, ruleIterator.currentIncludeRules()});
@@ -2049,6 +2226,10 @@ private:
// <includedRules .../> <- reference a <DetectChar char="{" /> who will be added
// <DetectChar char="{" /> <- hidden by previous rule
case Context::Rule::Type::IncludeRules:
+ if (observedRule.includeRules && !observedRule.hasResolvedIncludeRules()) {
+ break;
+ }
+
if (auto &ruleAndInclude = includeContexts[rule.context.context]) {
updateUnreachable1(ruleAndInclude);
}
@@ -2060,6 +2241,10 @@ private:
includeContexts.insert(rulePtr->context.context, RuleAndInclude{rulePtr, &rule});
}
+ if (observedRule.includeRules) {
+ break;
+ }
+
for (const auto *rulePtr : rule.includedRules) {
const auto &rule2 = *rulePtr;
switch (rule2.type) {
@@ -2087,27 +2272,27 @@ private:
}
case Context::Rule::Type::HlCChar:
- hlCCharRule = {&rule2, &rule};
+ hlCCharRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCHex:
- hlCHexRule = {&rule2, &rule};
+ hlCHexRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCOct:
- hlCOctRule = {&rule2, &rule};
+ hlCOctRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCStringChar:
- hlCStringCharRule = {&rule2, &rule};
+ hlCStringCharRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::Int:
- intRule = {&rule2, &rule};
+ intRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::Float:
- floatRule = {&rule2, &rule};
+ floatRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::LineContinue: {
@@ -2136,12 +2321,18 @@ private:
}
break;
- case Context::Rule::Type::DetectIdentifier:
case Context::Rule::Type::Unknown:
break;
}
- if (isUnreachable) {
+ if (observedRule.includeRules && !observedRule.hasResolvedIncludeRules()) {
+ auto &unreachableIncludedRule = unreachableIncludedRules[&rule];
+ if (isUnreachable && unreachableIncludedRule.alwaysUnreachable) {
+ unreachableIncludedRule.unreachableBy.append(unreachableBy);
+ } else {
+ unreachableIncludedRule.alwaysUnreachable = false;
+ }
+ } else if (isUnreachable) {
success = false;
QString message;
message.reserve(128);
@@ -2165,7 +2356,7 @@ private:
message += QStringLiteral(", ");
}
message.chop(2);
- qWarning() << filename << "line" << rule.line << "unreachable element by" << message;
+ qWarning() << filename << "line" << rule.line << "unreachable rule by" << message;
}
}
@@ -2179,8 +2370,9 @@ private:
{
bool success = true;
- if (context.rules.isEmpty())
+ if (context.rules.isEmpty()) {
return success;
+ }
auto it = context.rules.begin();
const auto end = context.rules.end() - 1;
@@ -2249,7 +2441,7 @@ private:
//! - "#pop!Comment" -> "Comment"
//! - "##ISO C++" -> ""
//! - "Comment##ISO C++"-> "Comment" in ISO C++
- void resolveContextName(Definition &definition, const Context &context, ContextName &contextName, int line)
+ void resolveContextName(Definition &definition, Context &context, ContextName &contextName, int line)
{
QString name = contextName.name;
if (name.isEmpty()) {
@@ -2281,8 +2473,9 @@ private:
const int idx = name.indexOf(QStringLiteral("##"));
if (idx == -1) {
auto it = definition.contexts.find(name);
- if (it != definition.contexts.end())
+ if (it != definition.contexts.end()) {
contextName.context = &*it;
+ }
} else {
auto defName = name.mid(idx + 2);
auto listName = name.left(idx);
@@ -2392,14 +2585,16 @@ int main(int argc, char *argv[])
QCoreApplication app(argc, argv);
// ensure enough arguments are passed
- if (app.arguments().size() < 3)
+ if (app.arguments().size() < 3) {
return 1;
+ }
#ifdef QT_XMLPATTERNS_LIB
// open schema
QXmlSchema schema;
- if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2))))
+ if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2)))) {
return 2;
+ }
#endif
const QString hlFilenamesListing = app.arguments().value(3);
@@ -2422,7 +2617,7 @@ int main(int argc, char *argv[])
HlFilesChecker filesChecker;
QVariantMap hls;
int anyError = 0;
- for (const QString &hlFilename : qAsConst(hlFilenames)) {
+ for (const QString &hlFilename : std::as_const(hlFilenames)) {
QFile hlFile(hlFilename);
if (!hlFile.open(QIODevice::ReadOnly)) {
qWarning("Failed to open %s", qPrintable(hlFilename));
@@ -2456,7 +2651,7 @@ int main(int argc, char *argv[])
QVariantMap hl;
// transfer text attributes
- for (const QString &attribute : qAsConst(textAttributes)) {
+ for (const QString &attribute : std::as_const(textAttributes)) {
hl[attribute] = xml.attributes().value(attribute).toString();
}
@@ -2489,17 +2684,20 @@ int main(int argc, char *argv[])
filesChecker.resolveContexts();
- if (!filesChecker.check())
+ if (!filesChecker.check()) {
anyError = 7;
+ }
// bail out if any problem was seen
- if (anyError)
+ if (anyError) {
return anyError;
+ }
// create outfile, after all has worked!
QFile outFile(app.arguments().at(1));
- if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return 9;
+ }
// write out json
outFile.write(QCborValue::fromVariant(QVariant(hls)).toCbor());
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
index 722f92742b..43a60cc19b 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
@@ -1,6 +1,8 @@
+add_library(KF5SyntaxHighlighting)
+
ecm_create_qm_loader(syntax_highlighting_QM_LOADER syntaxhighlighting5_qt)
-set(syntax_highlighting_srcs
+target_sources(KF5SyntaxHighlighting PRIVATE
abstracthighlighter.cpp
context.cpp
contextswitch.cpp
@@ -20,8 +22,9 @@ set(syntax_highlighting_srcs
themedata.cpp
worddelimiters.cpp
${syntax_highlighting_QM_LOADER}
+ $<TARGET_OBJECTS:SyntaxHighlightingData>
)
-ecm_qt_declare_logging_category(syntax_highlighting_srcs
+ecm_qt_declare_logging_category(KF5SyntaxHighlighting
HEADER ksyntaxhighlighting_logging.h
IDENTIFIER KSyntaxHighlighting::Log
CATEGORY_NAME kf.syntaxhighlighting
@@ -30,16 +33,27 @@ ecm_qt_declare_logging_category(syntax_highlighting_srcs
EXPORT KSYNTAXHIGHLIGHTING
)
-add_library(KF5SyntaxHighlighting ${syntax_highlighting_srcs} $<TARGET_OBJECTS:SyntaxHighlightingData>)
-generate_export_header(KF5SyntaxHighlighting BASE_NAME KSyntaxHighlighting)
+ecm_generate_export_header(KF5SyntaxHighlighting
+ BASE_NAME KSyntaxHighlighting
+ GROUP_BASE_NAME KF
+ VERSION ${KF_VERSION}
+ DEPRECATED_BASE_VERSION 0
+ DEPRECATION_VERSIONS 5.87
+ EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
+)
set_target_properties(KF5SyntaxHighlighting PROPERTIES
- VERSION ${SyntaxHighlighting_VERSION_STRING}
+ VERSION ${SyntaxHighlighting_VERSION}
SOVERSION ${SyntaxHighlighting_SOVERSION}
EXPORT_NAME SyntaxHighlighting
)
target_include_directories(KF5SyntaxHighlighting INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/KSyntaxHighlighting;${KDE_INSTALL_INCLUDEDIR_KF5}>")
target_include_directories(KF5SyntaxHighlighting PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR};>")
-target_link_libraries(KF5SyntaxHighlighting LINK_PUBLIC Qt5::Gui LINK_PRIVATE Qt5::Network)
+target_link_libraries(KF5SyntaxHighlighting
+ PUBLIC
+ Qt5::Gui
+ PRIVATE
+ Qt5::Network
+)
ecm_generate_headers(SyntaxHighlighting_HEADERS
HEADER_NAMES
@@ -52,6 +66,7 @@ ecm_generate_headers(SyntaxHighlighting_HEADERS
State
SyntaxHighlighter
Theme
+ WildcardMatcher
REQUIRED_HEADERS SyntaxHighlighting_HEADERS
)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
index 2ad9d371f9..d6f8cad0c7 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
@@ -36,11 +36,13 @@ void AbstractHighlighterPrivate::ensureDefinitionLoaded()
defData = DefinitionData::get(m_definition);
}
- if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty()))
+ if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty())) {
qCCritical(Log) << "Repository got deleted while a highlighter is still active!";
+ }
- if (m_definition.isValid())
+ if (m_definition.isValid()) {
defData->load();
+ }
}
AbstractHighlighter::AbstractHighlighter()
@@ -85,7 +87,7 @@ void AbstractHighlighter::setTheme(const Theme &theme)
* Returns the index of the first non-space character. If the line is empty,
* or only contains white spaces, text.size() is returned.
*/
-static inline int firstNonSpaceChar(const QString &text)
+static inline int firstNonSpaceChar(QStringView text)
{
for (int i = 0; i < text.length(); ++i) {
if (!text[i].isSpace()) {
@@ -95,8 +97,15 @@ static inline int firstNonSpaceChar(const QString &text)
return text.size();
}
+#if KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(5, 87)
State AbstractHighlighter::highlightLine(const QString &text, const State &state)
{
+ return highlightLine(QStringView(text), state);
+}
+#endif
+
+State AbstractHighlighter::highlightLine(QStringView text, const State &state)
+{
Q_D(AbstractHighlighter);
// verify definition, deal with no highlighting being enabled
@@ -145,8 +154,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* skipping empty lines after a line continuation character (see bug 405903)
*/
} else if (!stateData->topContext()->lineEndContext().isStay()
- && !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
+ && !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
+ }
// guard against endless loops
++endlessLoopingCounter;
@@ -160,7 +170,8 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
return newState;
}
- int offset = 0, beginOffset = 0;
+ int offset = 0;
+ int beginOffset = 0;
bool lineContinuation = false;
/**
@@ -247,8 +258,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
skipOffsets.clear();
}
const auto currentSkipOffset = skipOffsets.value(rule.get());
- if (currentSkipOffset < 0 || currentSkipOffset > offset)
+ if (currentSkipOffset < 0 || currentSkipOffset > offset) {
continue;
+ }
const auto newResult = rule->doMatch(text, offset, stateData->topCaptures());
newOffset = newResult.offset();
@@ -265,8 +277,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
}
}
- if (newOffset <= offset)
+ if (newOffset <= offset) {
continue;
+ }
/**
* apply folding.
@@ -274,12 +287,14 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* - rule with endRegion + beginRegion: in endRegion, the length is 0
* - rule with lookAhead: length is 0
*/
- if (rule->endRegion().isValid() && rule->beginRegion().isValid())
+ if (rule->endRegion().isValid() && rule->beginRegion().isValid()) {
applyFolding(offset, 0, rule->endRegion());
- else if (rule->endRegion().isValid())
+ } else if (rule->endRegion().isValid()) {
applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->endRegion());
- if (rule->beginRegion().isValid())
+ }
+ if (rule->beginRegion().isValid()) {
applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->beginRegion());
+ }
if (rule->isLookAhead()) {
Q_ASSERT(!rule->context().isStay());
@@ -290,12 +305,14 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
d->switchContext(stateData, rule->context(), newResult.captures());
newFormat = rule->attributeFormat().isValid() ? &rule->attributeFormat() : &stateData->topContext()->attributeFormat();
- if (newOffset == text.size() && std::dynamic_pointer_cast<LineContinue>(rule))
+ if (newOffset == text.size() && std::dynamic_pointer_cast<LineContinue>(rule)) {
lineContinuation = true;
+ }
break;
}
- if (isLookAhead)
+ if (isLookAhead) {
continue;
+ }
if (newOffset <= offset) { // no matching rule
if (stateData->topContext()->fallthrough()) {
@@ -316,8 +333,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* on format change, apply the last one and switch to new one
*/
if (newFormat != currentFormat && newFormat->id() != currentFormat->id()) {
- if (offset > 0)
+ if (offset > 0) {
applyFormat(beginOffset, offset - beginOffset, *currentFormat);
+ }
beginOffset = offset;
currentFormat = newFormat;
}
@@ -333,8 +351,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
/**
* apply format for remaining text, if any
*/
- if (beginOffset < offset)
+ if (beginOffset < offset) {
applyFormat(beginOffset, text.size() - beginOffset, *currentFormat);
+ }
/**
* handle line end context switches
@@ -344,8 +363,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
{
int endlessLoopingCounter = 0;
while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) {
- if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
+ if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
+ }
// guard against endless loops
++endlessLoopingCounter;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h
index 5e85873ce0..49cfbf2530 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h
@@ -108,6 +108,15 @@ protected:
AbstractHighlighter();
AbstractHighlighter(AbstractHighlighterPrivate *dd);
+#if KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(5, 87)
+ /**
+ * @copydoc highlightLine(QStringView,const State&)
+ * @deprecated since 5.87, use highlightLine(QStringView, const State&) instead.
+ */
+ // no deprecation warning, as removal of this will automatically "port" the using code
+ State highlightLine(const QString &text, const State &state);
+#endif
+
// TODO KF6: add an optional void* context argument that is passed through
// to the applyX() calls, so highlighters dealing with some form of line object
// (such as QSyntaxHighlighter or KTextEditor) can avoid some ugly hacks to have
@@ -120,14 +129,14 @@ protected:
* @param state The highlighting state handle returned by the call
* to highlightLine() for the previous line. For the very first line,
* just pass a default constructed State().
- * @returns The state of the highlighing engine after processing the
+ * @returns The state of the highlighting engine after processing the
* given line. This needs to passed into highlightLine() for the
* next line. You can store the state for efficient partial
* re-highlighting for example during editing.
*
* @see applyFormat(), applyFolding()
*/
- State highlightLine(const QString &text, const State &state);
+ State highlightLine(QStringView text, const State &state);
/**
* Reimplement this to apply formats to your output. The provided @p format
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
index 9ff012e1d7..8ae47d80eb 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
@@ -33,10 +33,6 @@ struct CieLab {
double b;
};
-#ifndef M_PI
-constexpr double M_PI = 3.14159265358979323846;
-#endif
-
// clang-format off
// xterm color reference
// constexpr Rgb888 xterm256Colors[] {
@@ -388,10 +384,11 @@ CieLab rgbToLab(QRgb rgb)
// Perform the inverse gamma companding for a sRGB color
// http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
auto inverseGammaCompanding = [](int c) {
- if (c <= 10)
+ if (c <= 10) {
return c / (255.0 * 12.92);
- else
+ } else {
return std::pow((c / 255.0 + 0.055) / 1.055, 2.4);
+ }
};
const double r = inverseGammaCompanding(qRed(rgb));
@@ -404,10 +401,11 @@ CieLab rgbToLab(QRgb rgb)
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
auto f = [](double t) {
- if (t > 216.0 / 24389.0)
+ if (t > 216.0 / 24389.0) {
return std::cbrt(t);
- else
+ } else {
return t * (24389.0 / (27.0 * 116.0)) + 4.0 / 29.0;
+ }
};
const double f_x = f(x / illuminant_D65[0]);
@@ -440,8 +438,9 @@ inline double pow2(double x)
inline double computeHPrime(double a_prime, double b)
{
- if (std::abs(a_prime) < epsilon && std::abs(b) < epsilon)
+ if (std::abs(a_prime) < epsilon && std::abs(b) < epsilon) {
return 0.0;
+ }
const double value = std::atan2(b, a_prime) * 180.0 / M_PI;
return (value < 0.0) ? value + 360.0 : value;
@@ -449,34 +448,38 @@ inline double computeHPrime(double a_prime, double b)
inline double computeDeltaHPrime(double C1_prime, double C2_prime, double h1_prime, double h2_prime)
{
- if (C1_prime * C2_prime < epsilon)
+ if (C1_prime * C2_prime < epsilon) {
return 0.0;
+ }
const double diff = h2_prime - h1_prime;
- if (std::abs(diff) <= 180.0)
+ if (std::abs(diff) <= 180.0) {
return diff;
- else if (diff > 180.0)
+ } else if (diff > 180.0) {
return diff - 360.0;
- else
+ } else {
return diff + 360.0;
+ }
}
inline double computeHPrimeBar(double C1_prime, double C2_prime, double h1_prime, double h2_prime)
{
const double sum = h1_prime + h2_prime;
- if (C1_prime * C2_prime < epsilon)
+ if (C1_prime * C2_prime < epsilon) {
return sum;
+ }
const double dist = std::abs(h1_prime - h2_prime);
- if (dist <= 180.0)
+ if (dist <= 180.0) {
return 0.5 * sum;
- else if (sum < 360.0)
+ } else if (sum < 360.0) {
return 0.5 * (sum + 360.0);
- else
+ } else {
return 0.5 * (sum - 360.0);
+ }
}
/// Calculate the perceptual color difference based on CIEDE2000.
@@ -702,7 +705,7 @@ struct GraphLine {
const int n2 = offset - labelLineLength;
labelLineLength += n2 + 1;
fillLine(labelLine, n2);
- labelLine += graphLine.rightRef(graphLine.size() - ps1);
+ labelLine += QStringView(graphLine).right(graphLine.size() - ps1);
}
}
@@ -781,8 +784,9 @@ public:
state = highlightLine(currentLine, state);
if (hasSeparator) {
- if (!firstLine)
+ if (!firstLine) {
out << QStringLiteral("\x1b[0m────────────────────────────────────────────────────\x1b[K\n");
+ }
firstLine = false;
}
@@ -793,14 +797,15 @@ public:
for (const auto &fragment : m_highlightedFragments) {
auto const &ansiStyle = ansiStyles[fragment.formatId];
- out << ansiStyle.first << currentLine.midRef(fragment.offset, fragment.length) << ansiStyle.second;
+ out << ansiStyle.first << QStringView(currentLine).mid(fragment.offset, fragment.length) << ansiStyle.second;
}
out << QStringLiteral("\x1b[K\n");
if (hasFormatOrContextTrace && !m_highlightedFragments.empty()) {
- if (m_hasContextTrace || m_hasStackSizeTrace)
+ if (m_hasContextTrace || m_hasStackSizeTrace) {
appendContextNames(oldState, currentLine);
+ }
printFormats(out, infoStyle, ansiStyles);
out << resetBgColor;
@@ -817,8 +822,9 @@ public:
void applyFolding(int offset, int /*length*/, FoldingRegion region) override
{
- if (!m_hasRegionTrace)
+ if (!m_hasRegionTrace) {
return;
+ }
const auto id = region.id();
@@ -829,8 +835,9 @@ public:
auto &previousRegion = m_regions[m_regions.size() - 2];
if (previousRegion.state == Region::State::Close && previousRegion.offset == offset) {
std::swap(previousRegion, m_regions.back());
- if (previousRegion.bindIndex != -1)
+ if (previousRegion.bindIndex != -1) {
m_regions[previousRegion.bindIndex].bindIndex = m_regions.size() - 1;
+ }
}
}
++m_regionDepth;
@@ -840,10 +847,11 @@ public:
auto eit = m_regions.rend();
for (int depth = 0; it != eit; ++it) {
if (it->regionId == id && it->bindIndex < 0) {
- if (it->state == Region::State::Close)
+ if (it->state == Region::State::Close) {
++depth;
- else if (--depth < 0)
+ } else if (--depth < 0) {
break;
+ }
}
}
@@ -868,8 +876,9 @@ private:
void initRegionStyles(const std::vector<QPair<QString, QString>> &ansiStyles)
{
m_regionStyles.resize(ansiStyles.size());
- for (std::size_t i = 0; i < m_regionStyles.size(); ++i)
+ for (std::size_t i = 0; i < m_regionStyles.size(); ++i) {
m_regionStyles[i] = ansiStyles[i].first;
+ }
std::sort(m_regionStyles.begin(), m_regionStyles.end());
m_regionStyles.erase(std::unique(m_regionStyles.begin(), m_regionStyles.end()), m_regionStyles.end());
@@ -1216,7 +1225,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
}
// initialize ansiStyles
- for (auto &&definition : qAsConst(definitions)) {
+ for (auto &&definition : std::as_const(definitions)) {
const auto formats = definition.formats();
for (auto &&format : formats) {
const auto id = format.id();
@@ -1236,20 +1245,26 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
const bool hasUnderline = format.isUnderline(theme);
const bool hasStrikeThrough = format.isStrikeThrough(theme);
- if (hasFg)
+ if (hasFg) {
buffer.appendForeground(format.textColor(theme).rgb(), is256Colors, colorCache);
- else
+ } else {
buffer.append(foregroundDefaultColor);
- if (hasBg)
+ }
+ if (hasBg) {
buffer.appendBackground(format.backgroundColor(theme).rgb(), is256Colors, colorCache);
- if (hasBold)
+ }
+ if (hasBold) {
buffer.append(QLatin1String("1;"));
- if (hasItalic)
+ }
+ if (hasItalic) {
buffer.append(QLatin1String("3;"));
- if (hasUnderline)
+ }
+ if (hasUnderline) {
buffer.append(QLatin1String("4;"));
- if (hasStrikeThrough)
+ }
+ if (hasStrikeThrough) {
buffer.append(QLatin1String("9;"));
+ }
// if there is ANSI style
if (buffer.latin1().size() > 2) {
@@ -1266,14 +1281,18 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
d->ansiStyles[id].second = buffer.latin1();
} else if (hasEffect) {
buffer.append(QLatin1String("\x1b["));
- if (hasBold)
+ if (hasBold) {
buffer.append(QLatin1String("21;"));
- if (hasItalic)
+ }
+ if (hasItalic) {
buffer.append(QLatin1String("23;"));
- if (hasUnderline)
+ }
+ if (hasUnderline) {
buffer.append(QLatin1String("24;"));
- if (hasStrikeThrough)
+ }
+ if (hasStrikeThrough) {
buffer.append(QLatin1String("29;"));
+ }
buffer.setFinalStyle();
d->ansiStyles[id].second = buffer.latin1();
}
@@ -1301,10 +1320,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
d->currentLine = in.readLine();
state = highlightLine(d->currentLine, state);
- if (useEditorBackground)
+ if (useEditorBackground) {
d->out << QStringLiteral("\x1b[K\n");
- else
+ } else {
d->out << QLatin1Char('\n');
+ }
}
} else {
AnsiBuffer buffer;
@@ -1328,5 +1348,5 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
void AnsiHighlighter::applyFormat(int offset, int length, const Format &format)
{
auto const &ansiStyle = d->ansiStyles[format.id()];
- d->out << ansiStyle.first << d->currentLine.midRef(offset, length) << ansiStyle.second;
+ d->out << ansiStyle.first << QStringView(d->currentLine).mid(offset, length) << ansiStyle.second;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp
index f980ea5be8..724f37a03f 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp
@@ -30,8 +30,9 @@ void Context::setDefinition(const DefinitionRef &def)
bool Context::indentationBasedFoldingEnabled() const
{
- if (m_noIndentationBasedFolding)
+ if (m_noIndentationBasedFolding) {
return false;
+ }
return m_def.definition().indentationBasedFoldingEnabled();
}
@@ -56,8 +57,9 @@ void Context::load(QXmlStreamReader &reader)
auto rule = Rule::create(reader.name());
if (rule) {
rule->setDefinition(m_def.definition());
- if (rule->load(reader))
+ if (rule->load(reader)) {
m_rules.push_back(std::move(rule));
+ }
} else {
reader.skipCurrentElement();
}
@@ -79,8 +81,9 @@ void Context::resolveContexts()
m_lineEndContext.resolve(def);
m_lineEmptyContext.resolve(def);
m_fallthroughContext.resolve(def);
- for (const auto &rule : m_rules)
+ for (const auto &rule : m_rules) {
rule->resolveContext();
+ }
}
Context::ResolveState Context::resolveState()
@@ -100,8 +103,9 @@ Context::ResolveState Context::resolveState()
void Context::resolveIncludes()
{
- if (resolveState() == Resolved)
+ if (resolveState() == Resolved) {
return;
+ }
if (resolveState() == Resolving) {
qCWarning(Log) << "Cyclic dependency!";
return;
@@ -129,10 +133,11 @@ void Context::resolveIncludes()
}
auto defData = DefinitionData::get(def);
defData->load();
- if (inc->contextName().isEmpty())
+ if (inc->contextName().isEmpty()) {
context = defData->initialContext();
- else
+ } else {
context = defData->contextByName(inc->contextName());
+ }
}
if (!context) {
qCWarning(Log) << "Unable to resolve include rule for definition" << inc->contextName() << "##" << inc->definitionName() << "in"
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp
index 7ccd73ee9b..e829af463a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp
@@ -29,8 +29,9 @@ Context *ContextSwitch::context() const
void ContextSwitch::parse(QStringView contextInstr)
{
- if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay"))
+ if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay")) {
return;
+ }
if (contextInstr.startsWith(QLatin1String("#pop!"))) {
++m_popCount;
@@ -60,13 +61,15 @@ void ContextSwitch::resolve(const Definition &def)
d = DefinitionData::get(def)->repo->definitionForName(m_defName);
auto data = DefinitionData::get(d);
data->load();
- if (m_contextName.isEmpty())
+ if (m_contextName.isEmpty()) {
m_context = data->initialContext();
+ }
}
if (!m_contextName.isEmpty()) {
m_context = DefinitionData::get(d)->contextByName(m_contextName);
- if (!m_context)
+ if (!m_context) {
qCWarning(Log) << "cannot find context" << m_contextName << "in" << def.name();
+ }
}
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
index 7434e745b2..068907a4e2 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
@@ -52,29 +52,20 @@ DefinitionData *DefinitionData::get(const Definition &def)
Definition::Definition()
: d(new DefinitionData)
{
-}
-
-Definition::Definition(const Definition &other)
- : d(other.d)
-{
d->q = *this;
}
+Definition::Definition(Definition &&other) noexcept = default;
+Definition::Definition(const Definition &) = default;
+Definition::~Definition() = default;
+Definition &Definition::operator=(Definition &&other) noexcept = default;
+Definition &Definition::operator=(const Definition &) = default;
+
Definition::Definition(std::shared_ptr<DefinitionData> &&dd)
: d(std::move(dd))
{
}
-Definition::~Definition()
-{
-}
-
-Definition &Definition::operator=(const Definition &rhs)
-{
- d = rhs.d;
- return *this;
-}
-
bool Definition::operator==(const Definition &other) const
{
return d->fileName == other.d->fileName;
@@ -223,8 +214,9 @@ bool Definition::setKeywordList(const QString &name, const QStringList &content)
if (list) {
list->setKeywordList(content);
return true;
- } else
+ } else {
return false;
+ }
}
QVector<Format> Definition::formats() const
@@ -251,7 +243,7 @@ QVector<Definition> Definition::includedDefinitions() const
// Iterate all context rules to find associated Definitions. This will
// automatically catch other Definitions referenced with IncludeRuldes or ContextSwitch.
const auto definition = queue.takeLast();
- for (const auto &context : qAsConst(definition.d->contexts)) {
+ for (const auto &context : std::as_const(definition.d->contexts)) {
// handle context switch attributes of this context itself
for (const auto switchContext :
{context->lineEndContext().context(), context->lineEmptyContext().context(), context->fallthroughContext().context()}) {
@@ -321,8 +313,9 @@ Context *DefinitionData::initialContext() const
Context *DefinitionData::contextByName(const QString &wantedName) const
{
for (const auto context : contexts) {
- if (context->name() == wantedName)
+ if (context->name() == wantedName) {
return context;
+ }
}
return nullptr;
}
@@ -336,8 +329,9 @@ KeywordList *DefinitionData::keywordList(const QString &wantedName)
Format DefinitionData::formatByName(const QString &wantedName) const
{
const auto it = formats.constFind(wantedName);
- if (it != formats.constEnd())
+ if (it != formats.constEnd()) {
return it.value();
+ }
return Format();
}
@@ -349,24 +343,29 @@ bool DefinitionData::isLoaded() const
bool DefinitionData::load(OnlyKeywords onlyKeywords)
{
- if (fileName.isEmpty())
+ if (fileName.isEmpty()) {
return false;
+ }
- if (isLoaded())
+ if (isLoaded()) {
return true;
+ }
- if (bool(onlyKeywords) && keywordIsLoaded)
+ if (bool(onlyKeywords) && keywordIsLoaded) {
return true;
+ }
QFile file(fileName);
- if (!file.open(QFile::ReadOnly))
+ if (!file.open(QFile::ReadOnly)) {
return false;
+ }
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
const auto token = reader.readNext();
- if (token != QXmlStreamReader::StartElement)
+ if (token != QXmlStreamReader::StartElement) {
continue;
+ }
if (reader.name() == QLatin1String("highlighting")) {
loadHighlighting(reader, onlyKeywords);
@@ -375,21 +374,22 @@ bool DefinitionData::load(OnlyKeywords onlyKeywords)
}
}
- else if (reader.name() == QLatin1String("general"))
+ else if (reader.name() == QLatin1String("general")) {
loadGeneral(reader);
+ }
}
for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
it->setCaseSensitivity(caseSensitive);
}
- for (const auto context : qAsConst(contexts)) {
+ for (const auto context : std::as_const(contexts)) {
context->resolveContexts();
context->resolveIncludes();
context->resolveAttributeFormat();
}
- for (const auto context : qAsConst(contexts)) {
+ for (const auto context : std::as_const(contexts)) {
for (const auto &rule : context->rules()) {
rule->resolvePostProcessing();
}
@@ -427,14 +427,16 @@ bool DefinitionData::loadMetaData(const QString &definitionFileName)
fileName = definitionFileName;
QFile file(definitionFileName);
- if (!file.open(QFile::ReadOnly))
+ if (!file.open(QFile::ReadOnly)) {
return false;
+ }
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
const auto token = reader.readNext();
- if (token != QXmlStreamReader::StartElement)
+ if (token != QXmlStreamReader::StartElement) {
continue;
+ }
if (reader.name() == QLatin1String("language")) {
return loadLanguage(reader);
}
@@ -457,11 +459,13 @@ bool DefinitionData::loadMetaData(const QString &file, const QCborMap &obj)
fileName = file;
const auto exts = obj.value(QLatin1String("extensions")).toString();
- for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
extensions.push_back(ext);
+ }
const auto mts = obj.value(QLatin1String("mimetype")).toString();
- for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
+ }
return true;
}
@@ -471,8 +475,9 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
Q_ASSERT(reader.name() == QLatin1String("language"));
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
- if (!checkKateVersion(reader.attributes().value(QLatin1String("kateversion"))))
+ if (!checkKateVersion(reader.attributes().value(QLatin1String("kateversion")))) {
return false;
+ }
name = reader.attributes().value(QLatin1String("name")).toString();
section = reader.attributes().value(QLatin1String("section")).toString();
@@ -485,13 +490,16 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
author = reader.attributes().value(QLatin1String("author")).toString();
license = reader.attributes().value(QLatin1String("license")).toString();
const auto exts = reader.attributes().value(QLatin1String("extensions")).toString();
- for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
extensions.push_back(ext);
+ }
const auto mts = reader.attributes().value(QLatin1String("mimetype")).toString();
- for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
- if (reader.attributes().hasAttribute(QLatin1String("casesensitive")))
+ }
+ if (reader.attributes().hasAttribute(QLatin1String("casesensitive"))) {
caseSensitive = Xml::attrToBool(reader.attributes().value(QLatin1String("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ }
return true;
}
@@ -618,8 +626,9 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
++elementRefCounter;
if (reader.name() == QLatin1String("keywords")) {
- if (reader.attributes().hasAttribute(QLatin1String("casesensitive")))
+ if (reader.attributes().hasAttribute(QLatin1String("casesensitive"))) {
caseSensitive = Xml::attrToBool(reader.attributes().value(QLatin1String("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ }
// adapt wordDelimiters
wordDelimiters.append(reader.attributes().value(QLatin1String("additionalDeliminator")));
@@ -628,14 +637,15 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
// adapt WordWrapDelimiters
auto wordWrapDeliminatorAttr = reader.attributes().value(
QLatin1String("wordWrapDeliminator"));
- if (wordWrapDeliminatorAttr.isEmpty())
+ if (wordWrapDeliminatorAttr.isEmpty()) {
wordWrapDelimiters = wordDelimiters;
- else {
+ } else {
wordWrapDelimiters.append(wordWrapDeliminatorAttr);
}
} else if (reader.name() == QLatin1String("folding")) {
- if (reader.attributes().hasAttribute(QLatin1String("indentationsensitive")))
+ if (reader.attributes().hasAttribute(QLatin1String("indentationsensitive"))) {
indentationBasedFolding = Xml::attrToBool(reader.attributes().value(QLatin1String("indentationsensitive")));
+ }
} else if (reader.name() == QLatin1String("emptyLines")) {
loadFoldingIgnoreList(reader);
} else if (reader.name() == QLatin1String("comments")) {
@@ -649,8 +659,9 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -688,8 +699,9 @@ void DefinitionData::loadComments(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -719,8 +731,9 @@ void DefinitionData::loadFoldingIgnoreList(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -754,8 +767,9 @@ void DefinitionData::loadSpellchecking(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -798,10 +812,6 @@ DefinitionRef::DefinitionRef(const Definition &def)
{
}
-DefinitionRef::~DefinitionRef()
-{
-}
-
DefinitionRef &DefinitionRef::operator=(const Definition &def)
{
d = def.d;
@@ -810,8 +820,9 @@ DefinitionRef &DefinitionRef::operator=(const Definition &def)
Definition DefinitionRef::definition() const
{
- if (!d.expired())
+ if (!d.expired()) {
return Definition(d.lock());
+ }
return Definition();
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h
index 8226fbdd24..05757ea52a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h
@@ -13,6 +13,7 @@
#include <QPair>
#include <QVector>
#include <memory>
+#include <qobjectdefs.h>
QT_BEGIN_NAMESPACE
class QChar;
@@ -74,7 +75,7 @@ enum class CommentPosition {
* singleLineCommentMarker() and multiLineCommentMarker() provide comment
* markers that can be used for commenting/uncommenting code. Similarly,
* formats() returns a list of Format items defined by this Definition (which
- * equal the itemDatas of a highlighing definition file). includedDefinitions()
+ * equal the itemDatas of a highlighting definition file). includedDefinitions()
* returns a list of all included Definition%s referenced by this Definition via
* the rule IncludeRules, which is useful for displaying all Format items for
* color configuration in the user interface.
@@ -84,6 +85,13 @@ enum class CommentPosition {
*/
class KSYNTAXHIGHLIGHTING_EXPORT Definition
{
+ Q_GADGET
+ Q_PROPERTY(QString name READ name)
+ Q_PROPERTY(QString translatedName READ translatedName)
+ Q_PROPERTY(QString section READ section)
+ Q_PROPERTY(QString translatedSection READ translatedSection)
+ Q_PROPERTY(QString author READ author)
+ Q_PROPERTY(QString license READ license)
public:
/**
* Default constructor, creating an empty (invalid) Definition instance.
@@ -94,6 +102,14 @@ public:
Definition();
/**
+ * Move constructor.
+ * This definition takes the Definition data from @p other.
+ * @note @p other may only be assigned to or destroyed afterwards.
+ * @since 5.86
+ */
+ Definition(Definition &&other) noexcept;
+
+ /**
* Copy constructor.
* Both this definition as well as @p other share the Definition data.
*/
@@ -105,7 +121,15 @@ public:
~Definition();
/**
- * Assignment operator.
+ * Move assignment operator.
+ * This definition takes the Definition data from @p other.
+ * @note @p other may only be assigned to or destroyed afterwards.
+ * @since 5.86
+ */
+ Definition &operator=(Definition &&other) noexcept;
+
+ /**
+ * Copy assignment operator.
* Both this definition as well as @p rhs share the Definition data.
*/
Definition &operator=(const Definition &rhs);
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp
index 3dff1dd436..b16139b731 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp
@@ -51,24 +51,27 @@ void DefinitionDownloaderPrivate::definitionListDownloadFinished(QNetworkReply *
while (!parser.atEnd()) {
switch (parser.readNext()) {
case QXmlStreamReader::StartElement:
- if (parser.name() == QLatin1String("Definition"))
+ if (parser.name() == QLatin1String("Definition")) {
updateDefinition(parser);
+ }
break;
default:
break;
}
}
- if (pendingDownloads == 0)
+ if (pendingDownloads == 0) {
Q_EMIT q->informationMessage(QObject::tr("All syntax definitions are up-to-date."));
+ }
checkDone();
}
void DefinitionDownloaderPrivate::updateDefinition(QXmlStreamReader &parser)
{
const auto name = parser.attributes().value(QLatin1String("name"));
- if (name.isEmpty())
+ if (name.isEmpty()) {
return;
+ }
auto localDef = repo->definitionForName(name.toString());
if (!localDef.isValid()) {
@@ -86,11 +89,13 @@ void DefinitionDownloaderPrivate::updateDefinition(QXmlStreamReader &parser)
void DefinitionDownloaderPrivate::downloadDefinition(const QUrl &downloadUrl)
{
- if (!downloadUrl.isValid())
+ if (!downloadUrl.isValid()) {
return;
+ }
auto url = downloadUrl;
- if (url.scheme() == QLatin1String("http"))
+ if (url.scheme() == QLatin1String("http")) {
url.setScheme(QStringLiteral("https"));
+ }
QNetworkRequest req(url);
auto reply = nam->get(req);
@@ -133,8 +138,9 @@ void DefinitionDownloaderPrivate::downloadDefinitionFinished(QNetworkReply *repl
void DefinitionDownloaderPrivate::checkDone()
{
if (pendingDownloads == 0) {
- if (needsReload)
+ if (needsReload) {
repo->reload();
+ }
Q_EMIT QTimer::singleShot(0, q, &DefinitionDownloader::done);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h
index 25a1a749e4..285fec3e20 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h
@@ -13,7 +13,6 @@ namespace KSyntaxHighlighting
{
class Definition;
class DefinitionData;
-class DefinitionPrivate;
/** Weak reference for Definition instances.
*
@@ -21,6 +20,8 @@ class DefinitionPrivate;
* in objects hold directly or indirectly by Definition
* to avoid reference count loops and thus memory leaks.
*
+ * This class follows the rule of zero. It is implicitly movable and copyable.
+ *
* @internal
*/
class DefinitionRef
@@ -28,7 +29,6 @@ class DefinitionRef
public:
DefinitionRef();
explicit DefinitionRef(const Definition &def);
- ~DefinitionRef();
DefinitionRef &operator=(const Definition &def);
Definition definition() const;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
index d459ee36d8..bcc64c3c2b 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
@@ -21,8 +21,9 @@ using namespace KSyntaxHighlighting;
static Theme::TextStyle stringToDefaultFormat(QStringView str)
{
- if (!str.startsWith(QLatin1String("ds")))
+ if (!str.startsWith(QLatin1String("ds"))) {
return Theme::Normal;
+ }
static const auto idx = Theme::staticMetaObject.indexOfEnumerator("TextStyle");
Q_ASSERT(idx >= 0);
@@ -30,8 +31,9 @@ static Theme::TextStyle stringToDefaultFormat(QStringView str)
bool ok = false;
const auto value = metaEnum.keyToValue(str.mid(2).toLatin1().constData(), &ok);
- if (!ok || value < 0)
+ if (!ok || value < 0) {
return Theme::Normal;
+ }
return static_cast<Theme::TextStyle>(value);
}
@@ -44,8 +46,9 @@ FormatPrivate *FormatPrivate::detachAndGet(Format &format)
TextStyleData FormatPrivate::styleOverride(const Theme &theme) const
{
const auto themeData = ThemeData::get(theme);
- if (themeData)
+ if (themeData) {
return themeData->textStyleOverride(definition.definition().name(), name);
+ }
return TextStyleData();
}
@@ -113,16 +116,18 @@ bool Format::hasTextColor(const Theme &theme) const
QColor Format::textColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.textColor)
+ if (overrideStyle.textColor) {
return overrideStyle.textColor;
+ }
return d->style.textColor ? QColor::fromRgba(d->style.textColor) : QColor::fromRgba(theme.textColor(d->defaultStyle));
}
QColor Format::selectedTextColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.selectedTextColor)
+ if (overrideStyle.selectedTextColor) {
return overrideStyle.selectedTextColor;
+ }
return d->style.selectedTextColor ? QColor::fromRgba(d->style.selectedTextColor) : QColor::fromRgba(theme.selectedTextColor(d->defaultStyle));
}
@@ -136,8 +141,9 @@ bool Format::hasBackgroundColor(const Theme &theme) const
QColor Format::backgroundColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.backgroundColor)
+ if (overrideStyle.backgroundColor) {
return overrideStyle.backgroundColor;
+ }
// use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
return d->style.backgroundColor ? QColor::fromRgba(d->style.backgroundColor) : QColor::fromRgba(theme.backgroundColor(d->defaultStyle));
@@ -146,8 +152,9 @@ QColor Format::backgroundColor(const Theme &theme) const
QColor Format::selectedBackgroundColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.selectedBackgroundColor)
+ if (overrideStyle.selectedBackgroundColor) {
return overrideStyle.selectedBackgroundColor;
+ }
// use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
return d->style.selectedBackgroundColor ? QColor::fromRgba(d->style.selectedBackgroundColor)
@@ -157,32 +164,36 @@ QColor Format::selectedBackgroundColor(const Theme &theme) const
bool Format::isBold(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasBold)
+ if (overrideStyle.hasBold) {
return overrideStyle.bold;
+ }
return d->style.hasBold ? d->style.bold : theme.isBold(d->defaultStyle);
}
bool Format::isItalic(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasItalic)
+ if (overrideStyle.hasItalic) {
return overrideStyle.italic;
+ }
return d->style.hasItalic ? d->style.italic : theme.isItalic(d->defaultStyle);
}
bool Format::isUnderline(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasUnderline)
+ if (overrideStyle.hasUnderline) {
return overrideStyle.underline;
+ }
return d->style.hasUnderline ? d->style.underline : theme.isUnderline(d->defaultStyle);
}
bool Format::isStrikeThrough(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasStrikeThrough)
+ if (overrideStyle.hasStrikeThrough) {
return overrideStyle.strikeThrough;
+ }
return d->style.hasStrikeThrough ? d->style.strikeThrough : theme.isStrikeThrough(d->defaultStyle);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp
index 5ba421d0e1..688a42d45c 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp
@@ -70,10 +70,11 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
return;
}
- if (title.isEmpty())
+ if (title.isEmpty()) {
highlightData(&f, fi.fileName());
- else
+ } else {
highlightData(&f, title);
+ }
}
/**
@@ -87,8 +88,9 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
*/
static QString toHtmlRgbaString(const QColor &color)
{
- if (color.alpha() == 0xFF)
+ if (color.alpha() == 0xFF) {
return color.name();
+ }
QString rgba = QStringLiteral("rgba(");
rgba.append(QString::number(color.red()));
@@ -111,10 +113,11 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
}
QString htmlTitle;
- if (title.isEmpty())
+ if (title.isEmpty()) {
htmlTitle = QStringLiteral("Kate Syntax Highlighter");
- else
+ } else {
htmlTitle = title.toHtmlEscaped();
+ }
State state;
*d->out << "<!DOCTYPE html>\n";
@@ -125,8 +128,9 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
<< ")\"/>\n";
*d->out << "</head><body";
*d->out << " style=\"background-color:" << toHtmlRgbaString(QColor::fromRgba(theme().editorColor(Theme::BackgroundColor)));
- if (theme().textColor(Theme::Normal))
+ if (theme().textColor(Theme::Normal)) {
*d->out << ";color:" << toHtmlRgbaString(QColor::fromRgba(theme().textColor(Theme::Normal)));
+ }
*d->out << "\"><pre>\n";
QTextStream in(dev);
@@ -148,27 +152,34 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
void HtmlHighlighter::applyFormat(int offset, int length, const Format &format)
{
- if (length == 0)
+ if (length == 0) {
return;
+ }
// collect potential output, cheaper than thinking about "is there any?"
QVarLengthArray<QString, 16> formatOutput;
- if (format.hasTextColor(theme()))
+ if (format.hasTextColor(theme())) {
formatOutput << QStringLiteral("color:") << toHtmlRgbaString(format.textColor(theme())) << QStringLiteral(";");
- if (format.hasBackgroundColor(theme()))
+ }
+ if (format.hasBackgroundColor(theme())) {
formatOutput << QStringLiteral("background-color:") << toHtmlRgbaString(format.backgroundColor(theme())) << QStringLiteral(";");
- if (format.isBold(theme()))
+ }
+ if (format.isBold(theme())) {
formatOutput << QStringLiteral("font-weight:bold;");
- if (format.isItalic(theme()))
+ }
+ if (format.isItalic(theme())) {
formatOutput << QStringLiteral("font-style:italic;");
- if (format.isUnderline(theme()))
+ }
+ if (format.isUnderline(theme())) {
formatOutput << QStringLiteral("text-decoration:underline;");
- if (format.isStrikeThrough(theme()))
+ }
+ if (format.isStrikeThrough(theme())) {
formatOutput << QStringLiteral("text-decoration:line-through;");
+ }
if (!formatOutput.isEmpty()) {
*d->out << "<span style=\"";
- for (const auto &out : qAsConst(formatOutput)) {
+ for (const auto &out : std::as_const(formatOutput)) {
*d->out << out;
}
*d->out << "\">";
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
index b13e30607b..3a7514897a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
@@ -16,6 +16,27 @@
using namespace KSyntaxHighlighting;
+namespace
+{
+struct KeywordComparator {
+ Qt::CaseSensitivity caseSensitive;
+
+ bool operator()(QStringView a, QStringView b) const
+ {
+ if (a.size() < b.size()) {
+ return true;
+ }
+
+ if (a.size() > b.size()) {
+ return false;
+ }
+
+ return a.compare(b, caseSensitive) < 0;
+ }
+};
+
+}
+
bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) const
{
/**
@@ -26,9 +47,7 @@ bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) c
/**
* search with right predicate
*/
- return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), QStringView(str), [caseSensitive](QStringView a, QStringView b) {
- return a.compare(b, caseSensitive) < 0;
- });
+ return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), QStringView(str), KeywordComparator{caseSensitive});
}
void KeywordList::load(QXmlStreamReader &reader)
@@ -85,16 +104,14 @@ void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive
* fill vector with refs to keywords
*/
vectorToSort.reserve(m_keywords.size());
- for (const auto &keyword : qAsConst(m_keywords)) {
+ for (const auto &keyword : std::as_const(m_keywords)) {
vectorToSort.push_back(keyword);
}
/**
* sort with right predicate
*/
- std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive](QStringView a, QStringView b) {
- return a.compare(b, caseSensitive) < 0;
- });
+ std::sort(vectorToSort.begin(), vectorToSort.end(), KeywordComparator{caseSensitive});
}
void KeywordList::resolveIncludeKeywords(DefinitionData &def)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h b/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h
deleted file mode 100644
index a39adb5ed6..0000000000
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <QtGlobal>
-
-#if defined(KSYNTAXHIGHLIGHTING_LIBRARY)
-# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
-#else
-# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT
-#endif
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
index 1e3191a7bc..f3b36df459 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
@@ -11,7 +11,7 @@
#include "repository_p.h"
#include "theme.h"
#include "themedata_p.h"
-#include "wildcardmatcher_p.h"
+#include "wildcardmatcher.h"
#include <QCborMap>
#include <QCborValue>
@@ -19,15 +19,75 @@
#include <QFile>
#include <QFileInfo>
#include <QPalette>
+#include <QString>
+#include <QStringView>
#ifndef NO_STANDARD_PATHS
#include <QStandardPaths>
#endif
+#include <algorithm>
+#include <iterator>
#include <limits>
using namespace KSyntaxHighlighting;
+namespace
+{
+QString fileNameFromFilePath(const QString &filePath)
+{
+ return QFileInfo{filePath}.fileName();
+}
+
+auto anyWildcardMatches(QStringView str)
+{
+ return [str](const Definition &def) {
+ const auto strings = def.extensions();
+ return std::any_of(strings.cbegin(), strings.cend(), [str](QStringView wildcard) {
+ return WildcardMatcher::exactMatch(str, wildcard);
+ });
+ };
+}
+
+auto anyMimeTypeEquals(QStringView mimeTypeName)
+{
+ return [mimeTypeName](const Definition &def) {
+ const auto strings = def.mimeTypes();
+ return std::any_of(strings.cbegin(), strings.cend(), [mimeTypeName](QStringView name) {
+ return mimeTypeName == name;
+ });
+ };
+}
+
+// The two function templates below take defs - a map sorted by highlighting name - to be deterministic and independent of translations.
+
+template<typename UnaryPredicate>
+Definition findHighestPriorityDefinitionIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
+{
+ const Definition *match = nullptr;
+ auto matchPriority = std::numeric_limits<int>::lowest();
+ for (const Definition &def : defs) {
+ const auto defPriority = def.priority();
+ if (defPriority > matchPriority && predicate(def)) {
+ match = &def;
+ matchPriority = defPriority;
+ }
+ }
+ return match == nullptr ? Definition{} : *match;
+}
+
+template<typename UnaryPredicate>
+QVector<Definition> findDefinitionsIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
+{
+ QVector<Definition> matches;
+ std::copy_if(defs.cbegin(), defs.cend(), std::back_inserter(matches), predicate);
+ std::stable_sort(matches.begin(), matches.end(), [](const Definition &lhs, const Definition &rhs) {
+ return lhs.priority() > rhs.priority();
+ });
+ return matches;
+}
+} // unnamed namespace
+
static void initResource()
{
#ifdef HAS_SYNTAX_RESOURCE
@@ -52,8 +112,9 @@ Repository::~Repository()
{
// reset repo so we can detect in still alive definition instances
// that the repo was deleted
- for (const auto &def : qAsConst(d->m_sortedDefs))
+ for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->repo = nullptr;
+ }
}
Definition Repository::definitionForName(const QString &defName) const
@@ -61,58 +122,24 @@ Definition Repository::definitionForName(const QString &defName) const
return d->m_defs.value(defName);
}
-static void sortDefinitions(QVector<Definition> &definitions)
-{
- std::stable_sort(definitions.begin(), definitions.end(), [](const Definition &lhs, const Definition &rhs) {
- return lhs.priority() > rhs.priority();
- });
-}
-
Definition Repository::definitionForFileName(const QString &fileName) const
{
- return definitionsForFileName(fileName).value(0);
+ return findHighestPriorityDefinitionIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const
{
- QFileInfo fi(fileName);
- const auto name = fi.fileName();
-
- // use d->m_defs, sorted map by highlighting name, to be deterministic and independent of translations
- QVector<Definition> candidates;
- for (const Definition &def : qAsConst(d->m_defs)) {
- for (const auto &pattern : def.extensions()) {
- if (WildcardMatcher::exactMatch(name, pattern)) {
- candidates.push_back(def);
- break;
- }
- }
- }
-
- sortDefinitions(candidates);
- return candidates;
+ return findDefinitionsIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
Definition Repository::definitionForMimeType(const QString &mimeType) const
{
- return definitionsForMimeType(mimeType).value(0);
+ return findHighestPriorityDefinitionIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
{
- // use d->m_defs, sorted map by highlighting name, to be deterministic and independent of translations
- QVector<Definition> candidates;
- for (const Definition &def : qAsConst(d->m_defs)) {
- for (const auto &matchType : def.mimeTypes()) {
- if (mimeType == matchType) {
- candidates.push_back(def);
- break;
- }
- }
- }
-
- sortDefinitions(candidates);
- return candidates;
+ return findDefinitionsIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitions() const
@@ -127,7 +154,7 @@ QVector<Theme> Repository::themes() const
Theme Repository::theme(const QString &themeName) const
{
- for (const auto &theme : qAsConst(d->m_themes)) {
+ for (const auto &theme : std::as_const(d->m_themes)) {
if (theme.name() == themeName) {
return theme;
}
@@ -138,14 +165,15 @@ Theme Repository::theme(const QString &themeName) const
Theme Repository::defaultTheme(Repository::DefaultTheme t) const
{
- if (t == DarkTheme)
+ if (t == DarkTheme) {
return theme(QLatin1String("Breeze Dark"));
+ }
return theme(QLatin1String("Breeze Light"));
}
Theme Repository::defaultTheme(Repository::DefaultTheme t)
{
- return qAsConst(*this).defaultTheme(t);
+ return std::as_const(*this).defaultTheme(t);
}
Theme Repository::themeForPalette(const QPalette &palette) const
@@ -164,7 +192,7 @@ Theme Repository::themeForPalette(const QPalette &palette) const
if (!matchingThemes.empty()) {
// if there's multiple, search for one with a matching highlight color
const auto highlight = palette.color(QPalette::Highlight);
- for (const auto &theme : qAsConst(matchingThemes)) {
+ for (const auto &theme : std::as_const(matchingThemes)) {
auto selection = theme.editorColor(KSyntaxHighlighting::Theme::EditorColorRole::TextSelection);
if (selection == highlight.rgb()) {
return theme;
@@ -179,7 +207,7 @@ Theme Repository::themeForPalette(const QPalette &palette) const
Theme Repository::themeForPalette(const QPalette &palette)
{
- return qAsConst(*this).themeForPalette(palette);
+ return std::as_const(*this).themeForPalette(palette);
}
void RepositoryPrivate::load(Repository *repo)
@@ -189,29 +217,39 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
- for (const auto &dir :
- QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/syntax"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
+ QStringLiteral("org.kde.syntax-highlighting/syntax"),
+ QStandardPaths::LocateDirectory)) {
loadSyntaxFolder(repo, dir);
+ }
// backward compatibility with Kate
- for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory))
+ for (const auto &dir :
+ QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory)) {
loadSyntaxFolder(repo, dir);
+ }
#endif
- // default resources are always used
- loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
+ // default resources are always used, this is the one location that has a index cbor file
+ loadSyntaxFolderFromIndex(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
+
+ // extra resources provided by 3rdparty libraries/applications
+ loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax-addons"));
// user given extra paths
- for (const auto &path : qAsConst(m_customSearchPaths))
+ for (const auto &path : std::as_const(m_customSearchPaths)) {
loadSyntaxFolder(repo, path + QStringLiteral("/syntax"));
+ }
m_sortedDefs.reserve(m_defs.size());
- for (auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it)
+ for (auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it) {
m_sortedDefs.push_back(it.value());
+ }
std::sort(m_sortedDefs.begin(), m_sortedDefs.end(), [](const Definition &left, const Definition &right) {
auto comparison = left.translatedSection().compare(right.translatedSection(), Qt::CaseInsensitive);
- if (comparison == 0)
+ if (comparison == 0) {
comparison = left.translatedName().compare(right.translatedName(), Qt::CaseInsensitive);
+ }
return comparison < 0;
});
@@ -219,54 +257,60 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
- for (const auto &dir :
- QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
+ QStringLiteral("org.kde.syntax-highlighting/themes"),
+ QStandardPaths::LocateDirectory)) {
loadThemeFolder(dir);
+ }
#endif
// default resources are always used
loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes"));
+ // extra resources provided by 3rdparty libraries/applications
+ loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes-addons"));
+
// user given extra paths
- for (const auto &path : qAsConst(m_customSearchPaths))
+ for (const auto &path : std::as_const(m_customSearchPaths)) {
loadThemeFolder(path + QStringLiteral("/themes"));
+ }
}
void RepositoryPrivate::loadSyntaxFolder(Repository *repo, const QString &path)
{
- if (loadSyntaxFolderFromIndex(repo, path))
- return;
-
QDirIterator it(path, QStringList() << QLatin1String("*.xml"), QDir::Files);
while (it.hasNext()) {
Definition def;
auto defData = DefinitionData::get(def);
defData->repo = repo;
- if (defData->loadMetaData(it.next()))
+ if (defData->loadMetaData(it.next())) {
addDefinition(def);
+ }
}
}
-bool RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path)
+void RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path)
{
QFile indexFile(path + QLatin1String("/index.katesyntax"));
- if (!indexFile.open(QFile::ReadOnly))
- return false;
+ if (!indexFile.open(QFile::ReadOnly)) {
+ return;
+ }
const auto indexDoc(QCborValue::fromCbor(indexFile.readAll()));
const auto index = indexDoc.toMap();
for (auto it = index.begin(); it != index.end(); ++it) {
- if (!it.value().isMap())
+ if (!it.value().isMap()) {
continue;
+ }
const auto fileName = QString(path + QLatin1Char('/') + it.key().toString());
const auto defMap = it.value().toMap();
Definition def;
auto defData = DefinitionData::get(def);
defData->repo = repo;
- if (defData->loadMetaData(fileName, defMap))
+ if (defData->loadMetaData(fileName, defMap)) {
addDefinition(def);
+ }
}
- return true;
}
void RepositoryPrivate::addDefinition(const Definition &def)
@@ -277,8 +321,9 @@ void RepositoryPrivate::addDefinition(const Definition &def)
return;
}
- if (it.value().version() >= def.version())
+ if (it.value().version() >= def.version()) {
return;
+ }
m_defs.insert(def.name(), def);
}
@@ -287,8 +332,9 @@ void RepositoryPrivate::loadThemeFolder(const QString &path)
QDirIterator it(path, QStringList() << QLatin1String("*.theme"), QDir::Files);
while (it.hasNext()) {
auto themeData = std::unique_ptr<ThemeData>(new ThemeData);
- if (themeData->load(it.next()))
+ if (themeData->load(it.next())) {
addTheme(Theme(themeData.release()));
+ }
}
}
@@ -307,15 +353,17 @@ void RepositoryPrivate::addTheme(const Theme &theme)
m_themes.insert(it, theme);
return;
}
- if (themeRevision(*it) < themeRevision(theme))
+ if (themeRevision(*it) < themeRevision(theme)) {
*it = theme;
+ }
}
quint16 RepositoryPrivate::foldingRegionId(const QString &defName, const QString &foldName)
{
const auto it = m_foldingRegionIds.constFind(qMakePair(defName, foldName));
- if (it != m_foldingRegionIds.constEnd())
+ if (it != m_foldingRegionIds.constEnd()) {
return it.value();
+ }
m_foldingRegionIds.insert(qMakePair(defName, foldName), ++m_foldingRegionId);
return m_foldingRegionId;
}
@@ -329,8 +377,9 @@ quint16 RepositoryPrivate::nextFormatId()
void Repository::reload()
{
qCDebug(Log) << "Reloading syntax definitions!";
- for (const auto &def : qAsConst(d->m_sortedDefs))
+ for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->clear();
+ }
d->m_defs.clear();
d->m_sortedDefs.clear();
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
index 323407f008..9e19ecda56 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
@@ -86,6 +86,11 @@ class Theme;
* The internal resource path is ":/org.kde.syntax-highlighting/syntax".
* This path should never be touched by other applications.
*
+ * -# Then, all custom files compiled into resources are loaded.
+ * The resource path is ":/org.kde.syntax-highlighting/syntax-addons".
+ * This path can be used by other libraries/applications to bundle specialized definitions.
+ * Per default this path isn't used by the framework itself.
+ *
* -# Finally, the search path can be extended by calling addCustomSearchPath().
* A custom search path can either be a path on disk or again a path to
* a Qt resource.
@@ -102,6 +107,11 @@ class Theme;
* The internal resource path is ":/org.kde.syntax-highlighting/themes".
* This path should never be touched by other applications.
*
+ * -# Then, all custom files compiled into resources are loaded.
+ * The resource path is ":/org.kde.syntax-highlighting/themes-addons".
+ * This path can be used by other libraries/applications to bundle specialized themes.
+ * Per default this path isn't used by the framework itself.
+ *
* -# Finally, all Theme%s located in the paths added addCustomSearchPath()
* are loaded.
*
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h
index 447cfae699..abc992358d 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h
@@ -29,7 +29,7 @@ public:
void load(Repository *repo);
void loadSyntaxFolder(Repository *repo, const QString &path);
- bool loadSyntaxFolderFromIndex(Repository *repo, const QString &path);
+ void loadSyntaxFolderFromIndex(Repository *repo, const QString &path);
void addDefinition(const Definition &def);
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
index c8d3fa0e63..f4e88b719a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
@@ -34,10 +34,11 @@ static bool isHexChar(QChar c)
return isDigit(c) || (c <= QLatin1Char('f') && QLatin1Char('a') <= c) || (c <= QLatin1Char('F') && QLatin1Char('A') <= c);
}
-static int matchEscapedChar(const QString &text, int offset)
+static int matchEscapedChar(QStringView text, int offset)
{
- if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2)
+ if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2) {
return offset;
+ }
const auto c = text.at(offset + 1);
switch (c.unicode()) {
@@ -59,8 +60,9 @@ static int matchEscapedChar(const QString &text, int offset)
// hex encoded character
case 'x':
if (offset + 2 < text.size() && isHexChar(text.at(offset + 2))) {
- if (offset + 3 < text.size() && isHexChar(text.at(offset + 3)))
+ if (offset + 3 < text.size() && isHexChar(text.at(offset + 3))) {
return offset + 4;
+ }
return offset + 3;
}
return offset;
@@ -75,8 +77,9 @@ static int matchEscapedChar(const QString &text, int offset)
case '6':
case '7':
if (offset + 2 < text.size() && isOctalChar(text.at(offset + 2))) {
- if (offset + 3 < text.size() && isOctalChar(text.at(offset + 3)))
+ if (offset + 3 < text.size() && isOctalChar(text.at(offset + 3))) {
return offset + 4;
+ }
return offset + 3;
}
return offset + 2;
@@ -116,26 +119,31 @@ bool Rule::load(QXmlStreamReader &reader)
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
m_attribute = reader.attributes().value(QLatin1String("attribute")).toString();
- if (reader.name() != QLatin1String("IncludeRules")) // IncludeRules uses this with a different semantic
+ if (reader.name() != QLatin1String("IncludeRules")) { // IncludeRules uses this with a different semantic
m_context.parse(reader.attributes().value(QLatin1String("context")));
+ }
m_firstNonSpace = Xml::attrToBool(reader.attributes().value(QLatin1String("firstNonSpace")));
m_lookAhead = Xml::attrToBool(reader.attributes().value(QLatin1String("lookAhead")));
bool colOk = false;
m_column = reader.attributes().value(QLatin1String("column")).toInt(&colOk);
- if (!colOk)
+ if (!colOk) {
m_column = -1;
+ }
auto regionName = reader.attributes().value(QLatin1String("beginRegion"));
- if (!regionName.isEmpty())
+ if (!regionName.isEmpty()) {
m_beginRegion = FoldingRegion(FoldingRegion::Begin, DefinitionData::get(m_def.definition())->foldingRegionId(regionName.toString()));
+ }
regionName = reader.attributes().value(QLatin1String("endRegion"));
- if (!regionName.isEmpty())
+ if (!regionName.isEmpty()) {
m_endRegion = FoldingRegion(FoldingRegion::End, DefinitionData::get(m_def.definition())->foldingRegionId(regionName.toString()));
+ }
auto result = doLoad(reader);
- if (m_lookAhead && m_context.isStay())
+ if (m_lookAhead && m_context.isStay()) {
result = false;
+ }
// be done with this rule, skip all subelements, e.g. no longer supported sub-rules
reader.skipCurrentElement();
@@ -184,42 +192,60 @@ void Rule::loadAdditionalWordDelimiters(QXmlStreamReader &reader)
Rule::Ptr Rule::create(QStringView name)
{
- if (name == QLatin1String("AnyChar"))
+ if (name == QLatin1String("AnyChar")) {
return std::make_shared<AnyChar>();
- if (name == QLatin1String("DetectChar"))
+ }
+ if (name == QLatin1String("DetectChar")) {
return std::make_shared<DetectChar>();
- if (name == QLatin1String("Detect2Chars"))
+ }
+ if (name == QLatin1String("Detect2Chars")) {
return std::make_shared<Detect2Char>();
- if (name == QLatin1String("DetectIdentifier"))
+ }
+ if (name == QLatin1String("DetectIdentifier")) {
return std::make_shared<DetectIdentifier>();
- if (name == QLatin1String("DetectSpaces"))
+ }
+ if (name == QLatin1String("DetectSpaces")) {
return std::make_shared<DetectSpaces>();
- if (name == QLatin1String("Float"))
+ }
+ if (name == QLatin1String("Float")) {
return std::make_shared<Float>();
- if (name == QLatin1String("Int"))
+ }
+ if (name == QLatin1String("Int")) {
return std::make_shared<Int>();
- if (name == QLatin1String("HlCChar"))
+ }
+ if (name == QLatin1String("HlCChar")) {
return std::make_shared<HlCChar>();
- if (name == QLatin1String("HlCHex"))
+ }
+ if (name == QLatin1String("HlCHex")) {
return std::make_shared<HlCHex>();
- if (name == QLatin1String("HlCOct"))
+ }
+ if (name == QLatin1String("HlCOct")) {
return std::make_shared<HlCOct>();
- if (name == QLatin1String("HlCStringChar"))
+ }
+ if (name == QLatin1String("HlCStringChar")) {
return std::make_shared<HlCStringChar>();
- if (name == QLatin1String("IncludeRules"))
+ }
+ if (name == QLatin1String("IncludeRules")) {
return std::make_shared<IncludeRules>();
- if (name == QLatin1String("keyword"))
+ }
+ if (name == QLatin1String("keyword")) {
return std::make_shared<KeywordListRule>();
- if (name == QLatin1String("LineContinue"))
+ }
+ if (name == QLatin1String("LineContinue")) {
return std::make_shared<LineContinue>();
- if (name == QLatin1String("RangeDetect"))
+ }
+ if (name == QLatin1String("RangeDetect")) {
return std::make_shared<RangeDetect>();
- if (name == QLatin1String("RegExpr"))
+ }
+ if (name == QLatin1String("RegExpr")) {
return std::make_shared<RegExpr>();
- if (name == QLatin1String("StringDetect"))
+ }
+ if (name == QLatin1String("StringDetect")) {
return std::make_shared<StringDetect>();
- if (name == QLatin1String("WordDetect"))
+ }
+ if (name == QLatin1String("WordDetect")) {
return std::make_shared<WordDetect>();
+ }
qCWarning(Log) << "Unknown rule type:" << name;
return Ptr(nullptr);
@@ -233,23 +259,26 @@ bool Rule::isWordDelimiter(QChar c) const
bool AnyChar::doLoad(QXmlStreamReader &reader)
{
m_chars = reader.attributes().value(QLatin1String("String")).toString();
- if (m_chars.size() == 1)
+ if (m_chars.size() == 1) {
qCDebug(Log) << "AnyChar rule with just one char: use DetectChar instead.";
+ }
return !m_chars.isEmpty();
}
-MatchResult AnyChar::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult AnyChar::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (m_chars.contains(text.at(offset)))
+ if (m_chars.contains(text.at(offset))) {
return offset + 1;
+ }
return offset;
}
bool DetectChar::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("char"));
- if (s.isEmpty())
+ if (s.isEmpty()) {
return false;
+ }
m_char = s.at(0);
m_dynamic = Xml::attrToBool(reader.attributes().value(QLatin1String("dynamic")));
if (m_dynamic) {
@@ -258,18 +287,21 @@ bool DetectChar::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult DetectChar::doMatch(const QString &text, int offset, const QStringList &captures) const
+MatchResult DetectChar::doMatch(QStringView text, int offset, const QStringList &captures) const
{
if (m_dynamic) {
- if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty())
+ if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) {
return offset;
- if (text.at(offset) == captures.at(m_captureIndex).at(0))
+ }
+ if (text.at(offset) == captures.at(m_captureIndex).at(0)) {
return offset + 1;
+ }
return offset;
}
- if (text.at(offset) == m_char)
+ if (text.at(offset) == m_char) {
return offset + 1;
+ }
return offset;
}
@@ -277,40 +309,46 @@ bool Detect2Char::doLoad(QXmlStreamReader &reader)
{
const auto s1 = reader.attributes().value(QLatin1String("char"));
const auto s2 = reader.attributes().value(QLatin1String("char1"));
- if (s1.isEmpty() || s2.isEmpty())
+ if (s1.isEmpty() || s2.isEmpty()) {
return false;
+ }
m_char1 = s1.at(0);
m_char2 = s2.at(0);
return true;
}
-MatchResult Detect2Char::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult Detect2Char::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() - offset < 2)
+ if (text.size() - offset < 2) {
return offset;
- if (text.at(offset) == m_char1 && text.at(offset + 1) == m_char2)
+ }
+ if (text.at(offset) == m_char1 && text.at(offset + 1) == m_char2) {
return offset + 2;
+ }
return offset;
}
-MatchResult DetectIdentifier::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult DetectIdentifier::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_'))
+ if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_')) {
return offset;
+ }
for (int i = offset + 1; i < text.size(); ++i) {
const auto c = text.at(i);
- if (!c.isLetterOrNumber() && c != QLatin1Char('_'))
+ if (!c.isLetterOrNumber() && c != QLatin1Char('_')) {
return i;
+ }
}
return text.size();
}
-MatchResult DetectSpaces::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult DetectSpaces::doMatch(QStringView text, int offset, const QStringList &) const
{
- while (offset < text.size() && text.at(offset).isSpace())
+ while (offset < text.size() && text.at(offset).isSpace()) {
++offset;
+ }
return offset;
}
@@ -320,63 +358,76 @@ bool Float::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult Float::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult Float::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
auto newOffset = offset;
- while (newOffset < text.size() && isDigit(text.at(newOffset)))
+ while (newOffset < text.size() && isDigit(text.at(newOffset))) {
++newOffset;
+ }
- if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.'))
+ if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.')) {
return offset;
+ }
++newOffset;
- while (newOffset < text.size() && isDigit(text.at(newOffset)))
+ while (newOffset < text.size() && isDigit(text.at(newOffset))) {
++newOffset;
+ }
- if (newOffset == offset + 1) // we only found a decimal point
+ if (newOffset == offset + 1) { // we only found a decimal point
return offset;
+ }
auto expOffset = newOffset;
- if (expOffset >= text.size() || (text.at(expOffset) != QLatin1Char('e') && text.at(expOffset) != QLatin1Char('E')))
+ if (expOffset >= text.size() || (text.at(expOffset) != QLatin1Char('e') && text.at(expOffset) != QLatin1Char('E'))) {
return newOffset;
+ }
++expOffset;
- if (expOffset < text.size() && (text.at(expOffset) == QLatin1Char('+') || text.at(expOffset) == QLatin1Char('-')))
+ if (expOffset < text.size() && (text.at(expOffset) == QLatin1Char('+') || text.at(expOffset) == QLatin1Char('-'))) {
++expOffset;
+ }
bool foundExpDigit = false;
while (expOffset < text.size() && isDigit(text.at(expOffset))) {
++expOffset;
foundExpDigit = true;
}
- if (!foundExpDigit)
+ if (!foundExpDigit) {
return newOffset;
+ }
return expOffset;
}
-MatchResult HlCChar::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCChar::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() < offset + 3)
+ if (text.size() < offset + 3) {
return offset;
+ }
- if (text.at(offset) != QLatin1Char('\'') || text.at(offset + 1) == QLatin1Char('\''))
+ if (text.at(offset) != QLatin1Char('\'') || text.at(offset + 1) == QLatin1Char('\'')) {
return offset;
+ }
auto newOffset = matchEscapedChar(text, offset + 1);
if (newOffset == offset + 1) {
- if (text.at(newOffset) == QLatin1Char('\\'))
+ if (text.at(newOffset) == QLatin1Char('\\')) {
return offset;
- else
+ } else {
++newOffset;
+ }
}
- if (newOffset >= text.size())
+ if (newOffset >= text.size()) {
return offset;
+ }
- if (text.at(newOffset) == QLatin1Char('\''))
+ if (text.at(newOffset) == QLatin1Char('\'')) {
return newOffset + 1;
+ }
return offset;
}
@@ -387,23 +438,28 @@ bool HlCHex::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult HlCHex::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCHex::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
- if (text.size() < offset + 3)
+ if (text.size() < offset + 3) {
return offset;
+ }
- if (text.at(offset) != QLatin1Char('0') || (text.at(offset + 1) != QLatin1Char('x') && text.at(offset + 1) != QLatin1Char('X')))
+ if (text.at(offset) != QLatin1Char('0') || (text.at(offset + 1) != QLatin1Char('x') && text.at(offset + 1) != QLatin1Char('X'))) {
return offset;
+ }
- if (!isHexChar(text.at(offset + 2)))
+ if (!isHexChar(text.at(offset + 2))) {
return offset;
+ }
offset += 3;
- while (offset < text.size() && isHexChar(text.at(offset)))
+ while (offset < text.size() && isHexChar(text.at(offset))) {
++offset;
+ }
// TODO Kate matches U/L suffix, QtC does not?
@@ -416,28 +472,33 @@ bool HlCOct::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult HlCOct::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCOct::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
- if (text.size() < offset + 2)
+ if (text.size() < offset + 2) {
return offset;
+ }
- if (text.at(offset) != QLatin1Char('0'))
+ if (text.at(offset) != QLatin1Char('0')) {
return offset;
+ }
- if (!isOctalChar(text.at(offset + 1)))
+ if (!isOctalChar(text.at(offset + 1))) {
return offset;
+ }
offset += 2;
- while (offset < text.size() && isOctalChar(text.at(offset)))
+ while (offset < text.size() && isOctalChar(text.at(offset))) {
++offset;
+ }
return offset;
}
-MatchResult HlCStringChar::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCStringChar::doMatch(QStringView text, int offset, const QStringList &) const
{
return matchEscapedChar(text, offset);
}
@@ -461,17 +522,19 @@ bool IncludeRules::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("context"));
const auto split = s.split(QString::fromLatin1("##"), Qt::KeepEmptyParts);
- if (split.isEmpty())
+ if (split.isEmpty()) {
return false;
+ }
m_contextName = split.at(0).toString();
- if (split.size() > 1)
+ if (split.size() > 1) {
m_defName = split.at(1).toString();
+ }
m_includeAttribute = Xml::attrToBool(reader.attributes().value(QLatin1String("includeAttrib")));
return !m_contextName.isEmpty() || !m_defName.isEmpty();
}
-MatchResult IncludeRules::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult IncludeRules::doMatch(QStringView text, int offset, const QStringList &) const
{
Q_UNUSED(text);
qCWarning(Log) << "Unresolved include rule for" << m_contextName << "##" << m_defName;
@@ -484,13 +547,15 @@ bool Int::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult Int::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult Int::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
- while (offset < text.size() && isDigit(text.at(offset)))
+ while (offset < text.size() && isDigit(text.at(offset))) {
++offset;
+ }
return offset;
}
@@ -522,21 +587,24 @@ bool KeywordListRule::doLoad(QXmlStreamReader &reader)
return !m_keywordList->isEmpty();
}
-MatchResult KeywordListRule::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult KeywordListRule::doMatch(QStringView text, int offset, const QStringList &) const
{
auto newOffset = offset;
- while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset)))
+ while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset))) {
++newOffset;
- if (newOffset == offset)
+ }
+ if (newOffset == offset) {
return offset;
+ }
if (m_hasCaseSensitivityOverride) {
- if (m_keywordList->contains(QStringView(text).mid(offset, newOffset - offset),
- m_caseSensitivityOverride))
+ if (m_keywordList->contains(text.mid(offset, newOffset - offset), m_caseSensitivityOverride)) {
return newOffset;
+ }
} else {
- if (m_keywordList->contains(QStringView(text).mid(offset, newOffset - offset)))
+ if (m_keywordList->contains(text.mid(offset, newOffset - offset))) {
return newOffset;
+ }
}
// we don't match, but we can skip until newOffset as we can't start a keyword in-between
@@ -546,17 +614,19 @@ MatchResult KeywordListRule::doMatch(const QString &text, int offset, const QStr
bool LineContinue::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("char"));
- if (s.isEmpty())
+ if (s.isEmpty()) {
m_char = QLatin1Char('\\');
- else
+ } else {
m_char = s.at(0);
+ }
return true;
}
-MatchResult LineContinue::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult LineContinue::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset == text.size() - 1 && text.at(offset) == m_char)
+ if (offset == text.size() - 1 && text.at(offset) == m_char) {
return offset + 1;
+ }
return offset;
}
@@ -564,24 +634,28 @@ bool RangeDetect::doLoad(QXmlStreamReader &reader)
{
const auto s1 = reader.attributes().value(QLatin1String("char"));
const auto s2 = reader.attributes().value(QLatin1String("char1"));
- if (s1.isEmpty() || s2.isEmpty())
+ if (s1.isEmpty() || s2.isEmpty()) {
return false;
+ }
m_begin = s1.at(0);
m_end = s2.at(0);
return true;
}
-MatchResult RangeDetect::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult RangeDetect::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() - offset < 2)
+ if (text.size() - offset < 2) {
return offset;
- if (text.at(offset) != m_begin)
+ }
+ if (text.at(offset) != m_begin) {
return offset;
+ }
auto newOffset = offset + 1;
while (newOffset < text.size()) {
- if (text.at(newOffset) == m_end)
+ if (text.at(newOffset) == m_end) {
return newOffset + 1;
+ }
++newOffset;
}
return offset;
@@ -596,7 +670,9 @@ bool RegExpr::doLoad(QXmlStreamReader &reader)
m_regexp.setPatternOptions((isMinimal ? QRegularExpression::InvertedGreedinessOption : QRegularExpression::NoPatternOption)
| (isCaseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption)
// DontCaptureOption is removed by resolvePostProcessing() when necessary
- | QRegularExpression::DontCaptureOption);
+ | QRegularExpression::DontCaptureOption
+ // ensure Unicode support is enabled
+ | QRegularExpression::UseUnicodePropertiesOption);
m_dynamic = Xml::attrToBool(reader.attributes().value(QLatin1String("dynamic")));
@@ -605,8 +681,9 @@ bool RegExpr::doLoad(QXmlStreamReader &reader)
void KSyntaxHighlighting::RegExpr::resolvePostProcessing()
{
- if (m_isResolved)
+ if (m_isResolved) {
return;
+ }
m_isResolved = true;
bool hasCapture = false;
@@ -641,7 +718,7 @@ void KSyntaxHighlighting::RegExpr::resolvePostProcessing()
}
}
-MatchResult RegExpr::doMatch(const QString &text, int offset, const QStringList &captures) const
+MatchResult RegExpr::doMatch(QStringView text, int offset, const QStringList &captures) const
{
/**
* for dynamic case: create new pattern with right instantiation
@@ -651,7 +728,11 @@ MatchResult RegExpr::doMatch(const QString &text, int offset, const QStringList
/**
* match the pattern
*/
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
+ const auto result = regexp.match(text.toString(), offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption);
+#else
const auto result = regexp.match(text, offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption);
+#endif
if (result.capturedStart() == offset) {
/**
* we only need to compute the captured texts if we have real capture groups
@@ -683,16 +764,16 @@ bool StringDetect::doLoad(QXmlStreamReader &reader)
return !m_string.isEmpty();
}
-MatchResult StringDetect::doMatch(const QString &text, int offset, const QStringList &captures) const
+MatchResult StringDetect::doMatch(QStringView text, int offset, const QStringList &captures) const
{
/**
* for dynamic case: create new pattern with right instantiation
*/
const auto &pattern = m_dynamic ? replaceCaptures(m_string, captures, false) : m_string;
- if (offset + pattern.size() <= text.size()
- && QStringView(text).mid(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0)
+ if (offset + pattern.size() <= text.size() && text.mid(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0) {
return offset + pattern.size();
+ }
return offset;
}
@@ -704,23 +785,27 @@ bool WordDetect::doLoad(QXmlStreamReader &reader)
return !m_word.isEmpty();
}
-MatchResult WordDetect::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult WordDetect::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() - offset < m_word.size())
+ if (text.size() - offset < m_word.size()) {
return offset;
+ }
/**
* detect delimiter characters on the inner and outer boundaries of the string
* NOTE: m_word isn't empty
*/
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)) && !isWordDelimiter(text.at(offset)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1)) && !isWordDelimiter(text.at(offset))) {
return offset;
+ }
- if (QStringView(text).mid(offset, m_word.size()).compare(m_word, m_caseSensitivity) != 0)
+ if (text.mid(offset, m_word.size()).compare(m_word, m_caseSensitivity) != 0) {
return offset;
+ }
- if (text.size() == offset + m_word.size() || isWordDelimiter(text.at(offset + m_word.size())) || isWordDelimiter(text.at(offset + m_word.size() - 1)))
+ if (text.size() == offset + m_word.size() || isWordDelimiter(text.at(offset + m_word.size())) || isWordDelimiter(text.at(offset + m_word.size() - 1))) {
return offset + m_word.size();
+ }
return offset;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h
index 22c786eaa2..374eb87dfa 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h
@@ -87,7 +87,7 @@ public:
{
}
- virtual MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const = 0;
+ virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const = 0;
static Rule::Ptr create(QStringView name);
@@ -121,58 +121,58 @@ protected:
bool m_dynamic = false;
};
-class AnyChar : public Rule
+class AnyChar final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QString m_chars;
};
-class DetectChar : public Rule
+class DetectChar final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QChar m_char;
int m_captureIndex = 0;
};
-class Detect2Char : public Rule
+class Detect2Char final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QChar m_char1;
QChar m_char2;
};
-class DetectIdentifier : public Rule
+class DetectIdentifier final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class DetectSpaces : public Rule
+class DetectSpaces final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class Float : public Rule
+class Float final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class IncludeRules : public Rule
+class IncludeRules final : public Rule
{
public:
QString contextName() const;
@@ -181,7 +181,7 @@ public:
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QString m_contextName;
@@ -189,44 +189,44 @@ private:
bool m_includeAttribute;
};
-class Int : public Rule
+class Int final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
};
-class HlCChar : public Rule
+class HlCChar final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class HlCHex : public Rule
+class HlCHex final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class HlCOct : public Rule
+class HlCOct final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class HlCStringChar : public Rule
+class HlCStringChar final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class KeywordListRule : public Rule
+class KeywordListRule final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
KeywordList *m_keywordList;
@@ -234,55 +234,55 @@ private:
Qt::CaseSensitivity m_caseSensitivityOverride;
};
-class LineContinue : public Rule
+class LineContinue final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QChar m_char;
};
-class RangeDetect : public Rule
+class RangeDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QChar m_begin;
QChar m_end;
};
-class RegExpr : public Rule
+class RegExpr final : public Rule
{
protected:
void resolvePostProcessing() override;
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QRegularExpression m_regexp;
bool m_isResolved = false;
};
-class StringDetect : public Rule
+class StringDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QString m_string;
Qt::CaseSensitivity m_caseSensitivity;
};
-class WordDetect : public Rule
+class WordDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QString m_word;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp
index f9b4f4b4ab..ea21fef215 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp
@@ -104,7 +104,8 @@ bool State::operator!=(const State &other) const
bool State::indentationBasedFoldingEnabled() const
{
- if (!d || d->m_contextStack.isEmpty())
+ if (!d || d->m_contextStack.isEmpty()) {
return false;
+ }
return d->m_contextStack.last().first->indentationBasedFoldingEnabled();
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
index d0c4ee98ae..41551e96da 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
@@ -37,11 +37,13 @@ public:
FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock &startBlock)
{
const auto data = dynamic_cast<TextBlockUserData *>(startBlock.userData());
- if (!data)
+ if (!data) {
return FoldingRegion();
+ }
for (int i = data->foldingRegions.size() - 1; i >= 0; --i) {
- if (data->foldingRegions.at(i).type() == FoldingRegion::Begin)
+ if (data->foldingRegions.at(i).type() == FoldingRegion::Begin) {
return data->foldingRegions.at(i);
+ }
}
return FoldingRegion();
}
@@ -68,8 +70,9 @@ void SyntaxHighlighter::setDefinition(const Definition &def)
{
const auto needsRehighlight = definition() != def;
AbstractHighlighter::setDefinition(def);
- if (needsRehighlight)
+ if (needsRehighlight) {
rehighlight();
+ }
}
bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const
@@ -86,17 +89,21 @@ QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock)
while (block.isValid()) {
block = block.next();
const auto data = dynamic_cast<TextBlockUserData *>(block.userData());
- if (!data)
+ if (!data) {
continue;
+ }
for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) {
- if ((*it).id() != region.id())
+ if ((*it).id() != region.id()) {
continue;
- if ((*it).type() == FoldingRegion::End)
+ }
+ if ((*it).type() == FoldingRegion::End) {
--depth;
- else if ((*it).type() == FoldingRegion::Begin)
+ } else if ((*it).type() == FoldingRegion::Begin) {
++depth;
- if (depth == 0)
+ }
+ if (depth == 0) {
return block;
+ }
}
}
@@ -111,8 +118,9 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
if (currentBlock().position() > 0) {
const auto prevBlock = currentBlock().previous();
const auto prevData = dynamic_cast<TextBlockUserData *>(prevBlock.userData());
- if (prevData)
+ if (prevData) {
state = prevData->state;
+ }
}
d->foldingRegions.clear();
state = highlightLine(text, state);
@@ -126,35 +134,43 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
return;
}
- if (data->state == state && data->foldingRegions == d->foldingRegions) // we ended up in the same state, so we are done here
+ if (data->state == state && data->foldingRegions == d->foldingRegions) { // we ended up in the same state, so we are done here
return;
+ }
data->state = state;
data->foldingRegions = d->foldingRegions;
const auto nextBlock = currentBlock().next();
- if (nextBlock.isValid())
+ if (nextBlock.isValid()) {
QMetaObject::invokeMethod(this, "rehighlightBlock", Qt::QueuedConnection, Q_ARG(QTextBlock, nextBlock));
+ }
}
void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
{
- if (length == 0)
+ if (length == 0) {
return;
+ }
QTextCharFormat tf;
// always set the foreground color to avoid palette issues
tf.setForeground(format.textColor(theme()));
- if (format.hasBackgroundColor(theme()))
+ if (format.hasBackgroundColor(theme())) {
tf.setBackground(format.backgroundColor(theme()));
- if (format.isBold(theme()))
+ }
+ if (format.isBold(theme())) {
tf.setFontWeight(QFont::Bold);
- if (format.isItalic(theme()))
+ }
+ if (format.isItalic(theme())) {
tf.setFontItalic(true);
- if (format.isUnderline(theme()))
+ }
+ if (format.isUnderline(theme())) {
tf.setFontUnderline(true);
- if (format.isStrikeThrough(theme()))
+ }
+ if (format.isStrikeThrough(theme())) {
tf.setFontStrikeOut(true);
+ }
QSyntaxHighlighter::setFormat(offset, length, tf);
}
@@ -165,13 +181,15 @@ void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion regio
Q_UNUSED(length);
Q_D(SyntaxHighlighter);
- if (region.type() == FoldingRegion::Begin)
+ if (region.type() == FoldingRegion::Begin) {
d->foldingRegions.push_back(region);
+ }
if (region.type() == FoldingRegion::End) {
for (int i = d->foldingRegions.size() - 1; i >= 0; --i) {
- if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin)
+ if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin) {
continue;
+ }
d->foldingRegions.remove(i);
return;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h
index 076e8d0318..37f9de1694 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h
@@ -64,6 +64,8 @@ class RepositoryPrivate;
class KSYNTAXHIGHLIGHTING_EXPORT Theme
{
Q_GADGET
+ Q_PROPERTY(QString name READ name)
+ Q_PROPERTY(QString translatedName READ translatedName)
public:
// TODO KF6:
// - make TextStyle an enum class
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp
index 2919a31a6e..f9c386bc2a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp
@@ -160,8 +160,9 @@ bool ThemeData::load(const QString &filePath)
for (auto it = customStyles.begin(); it != customStyles.end(); ++it) {
const auto obj = it.value().toObject();
auto &overrideStyle = m_textStyleOverrides[it.key()];
- for (auto it2 = obj.begin(); it2 != obj.end(); ++it2)
+ for (auto it2 = obj.begin(); it2 != obj.end(); ++it2) {
overrideStyle.insert(it2.key(), readThemeData(it2.value().toObject()));
+ }
}
return true;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp
index 82d3e4ea80..98daff19d6 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp
@@ -4,14 +4,16 @@
SPDX-License-Identifier: MIT
*/
-#include "wildcardmatcher_p.h"
+#include "wildcardmatcher.h"
using namespace KSyntaxHighlighting;
#include <QChar>
-#include <QString>
+#include <QStringView>
-static bool exactMatch(const QString &candidate, const QString &wildcard, int candidatePosFromRight, int wildcardPosFromRight, bool caseSensitive = true)
+namespace
+{
+bool wildcardMatch(QStringView candidate, QStringView wildcard, int candidatePosFromRight, int wildcardPosFromRight)
{
for (; wildcardPosFromRight >= 0; wildcardPosFromRight--) {
const auto ch = wildcard.at(wildcardPosFromRight).unicode();
@@ -27,7 +29,7 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
// Eat all we can and go back as far as we have to
for (int j = -1; j <= candidatePosFromRight; j++) {
- if (exactMatch(candidate, wildcard, j, wildcardPosFromRight - 1)) {
+ if (wildcardMatch(candidate, wildcard, j, wildcardPosFromRight - 1)) {
return true;
}
}
@@ -47,18 +49,19 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
}
const auto candidateCh = candidate.at(candidatePosFromRight).unicode();
- const auto match = caseSensitive ? (candidateCh == ch) : (QChar::toLower(candidateCh) == QChar::toLower(ch));
- if (match) {
+ if (candidateCh == ch) {
candidatePosFromRight--;
} else {
return false;
}
}
}
- return true;
+ return candidatePosFromRight == -1;
}
-bool WildcardMatcher::exactMatch(const QString &candidate, const QString &wildcard, bool caseSensitive)
+} // unnamed namespace
+
+bool WildcardMatcher::exactMatch(QStringView candidate, QStringView wildcard)
{
- return ::exactMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1, caseSensitive);
+ return ::wildcardMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h
new file mode 100644
index 0000000000..4042de3788
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h
@@ -0,0 +1,33 @@
+/*
+ SPDX-FileCopyrightText: 2007 Sebastian Pipping <webmaster@hartwork.org>
+
+ SPDX-License-Identifier: MIT
+*/
+
+#ifndef KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
+#define KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
+
+#include "ksyntaxhighlighting_export.h"
+
+#include <QStringView>
+
+namespace KSyntaxHighlighting
+{
+namespace WildcardMatcher
+{
+/**
+ * Matches a string against a given wildcard case-sensitively.
+ * The wildcard supports '*' (".*" in regex) and '?' ("." in regex), not more.
+ *
+ * @param candidate Text to match
+ * @param wildcard Wildcard to use
+ * @return True for an exact match, false otherwise
+ *
+ * @since 5.86
+ */
+KSYNTAXHIGHLIGHTING_EXPORT bool exactMatch(QStringView candidate, QStringView wildcard);
+}
+
+}
+
+#endif // KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp
index 634eeb70bb..f9079ea1f3 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp
@@ -11,15 +11,17 @@ using namespace KSyntaxHighlighting;
WordDelimiters::WordDelimiters()
: asciiDelimiters{}
{
- for (const char *p = "\t !%&()*+,-./:;<=>?[\\]^{|}~"; *p; ++p)
+ for (const char *p = "\t !%&()*+,-./:;<=>?[\\]^{|}~"; *p; ++p) {
// int(*p) fix -Wchar-subscripts
asciiDelimiters[int(*p)] = true;
+ }
}
bool WordDelimiters::contains(QChar c) const
{
- if (c.unicode() < 128)
+ if (c.unicode() < 128) {
return asciiDelimiters[c.unicode()];
+ }
// perf tells contains is MUCH faster than binary search here, very short array
return notAsciiDelimiters.contains(c);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h
index 3fa5db10a4..c1afaaa6bb 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h
@@ -12,7 +12,7 @@
namespace KSyntaxHighlighting
{
/**
- * Repesents a list of character that separates 2 words.
+ * Represents a list of character that separates 2 words.
*
* Default delimiters are .():!+*,-<=>%&/;?[]^{|}~\, space (' ') and tabulator ('\t').
*
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h
index 5aae9eebb5..2e1dd25cc8 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h
@@ -17,7 +17,7 @@ namespace Xml
/** Parse a xs:boolean attribute. */
inline bool attrToBool(QStringView str)
{
- return str == QLatin1String("1") || str.compare(QString("true"), Qt::CaseInsensitive) == 0;
+ return str == QStringLiteral("1") || str.compare(QStringLiteral("true"), Qt::CaseInsensitive) == 0;
}
}