aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp')
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp107
1 files changed, 58 insertions, 49 deletions
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
index 31678018f9f..e9bea02d1c7 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
@@ -5,6 +5,7 @@
*/
#include "ansihighlighter.h"
+#include "abstracthighlighter_p.h"
#include "context_p.h"
#include "definition.h"
#include "definition_p.h"
@@ -18,6 +19,7 @@
#include <QFile>
#include <QFileInfo>
#include <QHash>
+#include <QIODevice>
#include <QTextStream>
#include <cmath>
@@ -783,7 +785,7 @@ GraphLine &lineAtOffset(std::vector<GraphLine> &graphLines, int offset)
}
// disable bold, italic and underline on |
-const QLatin1String graphSymbol("\x1b[21;23;24m|");
+const QLatin1String graphSymbol("\x1b[22;23;24m|");
// reverse video
const QLatin1String nameStyle("\x1b[7m");
@@ -793,8 +795,8 @@ const QLatin1String nameStyle("\x1b[7m");
class DebugSyntaxHighlighter : public KSyntaxHighlighting::AbstractHighlighter
{
public:
- using TraceOption = KSyntaxHighlighting::AnsiHighlighter::TraceOption;
- using TraceOptions = KSyntaxHighlighting::AnsiHighlighter::TraceOptions;
+ using Option = KSyntaxHighlighting::AnsiHighlighter::Option;
+ using Options = KSyntaxHighlighting::AnsiHighlighter::Options;
void setDefinition(const KSyntaxHighlighting::Definition &def) override
{
@@ -815,14 +817,14 @@ public:
QLatin1String infoStyle,
QLatin1String editorBackground,
const std::vector<QPair<QString, QString>> &ansiStyles,
- TraceOptions traceOptions)
+ Options options)
{
initRegionStyles(ansiStyles);
- m_hasFormatTrace = traceOptions.testFlag(TraceOption::Format);
- m_hasRegionTrace = traceOptions.testFlag(TraceOption::Region);
- m_hasStackSizeTrace = traceOptions.testFlag(TraceOption::StackSize);
- m_hasContextTrace = traceOptions.testFlag(TraceOption::Context);
+ m_hasFormatTrace = options.testFlag(Option::TraceFormat);
+ m_hasRegionTrace = options.testFlag(Option::TraceRegion);
+ m_hasStackSizeTrace = options.testFlag(Option::TraceStackSize);
+ m_hasContextTrace = options.testFlag(Option::TraceContext);
const bool hasFormatOrContextTrace = m_hasFormatTrace || m_hasContextTrace || m_hasStackSizeTrace;
const bool hasSeparator = hasFormatOrContextTrace && m_hasRegionTrace;
@@ -831,6 +833,7 @@ public:
bool firstLine = true;
State state;
QString currentLine;
+ const bool isUnbuffered = options.testFlag(Option::Unbuffered);
while (in.readLineInto(&currentLine)) {
auto oldState = state;
state = highlightLine(currentLine, state);
@@ -864,6 +867,10 @@ public:
}
m_highlightedFragments.clear();
+
+ if (isUnbuffered) {
+ out.flush();
+ }
}
}
@@ -970,12 +977,14 @@ private:
QString label;
if (m_hasStackSizeTrace) {
- label += QLatin1Char('(') % QString::number(stateData->size()) % QLatin1Char(')');
+ // first state is empty
+ int stateSize = stateData ? stateData->size() : 0;
+ label = QLatin1Char('(') % QString::number(stateSize) % QLatin1Char(')');
}
if (m_hasContextTrace) {
// first state is empty
- if (stateData->isEmpty()) {
+ if (!stateData) {
return label + QStringLiteral("[???]");
}
@@ -1138,7 +1147,7 @@ private:
QString name;
int offset;
int length;
- quint16 formatId;
+ int formatId;
};
struct ContextCaptureHighlighter : KSyntaxHighlighting::AbstractHighlighter {
@@ -1168,7 +1177,7 @@ private:
int depth;
int offset;
int bindIndex;
- quint16 regionId;
+ int regionId;
State state;
};
@@ -1190,7 +1199,7 @@ private:
};
} // anonymous namespace
-class KSyntaxHighlighting::AnsiHighlighterPrivate
+class KSyntaxHighlighting::AnsiHighlighterPrivate : public AbstractHighlighterPrivate
{
public:
QTextStream out;
@@ -1201,7 +1210,7 @@ public:
};
AnsiHighlighter::AnsiHighlighter()
- : d(new AnsiHighlighterPrivate())
+ : AbstractHighlighter(new AnsiHighlighterPrivate())
{
}
@@ -1209,6 +1218,7 @@ AnsiHighlighter::~AnsiHighlighter() = default;
void AnsiHighlighter::setOutputFile(const QString &fileName)
{
+ Q_D(AnsiHighlighter);
if (d->file.isOpen()) {
d->file.close();
}
@@ -1218,21 +1228,16 @@ void AnsiHighlighter::setOutputFile(const QString &fileName)
return;
}
d->out.setDevice(&d->file);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- d->out.setCodec("UTF-8");
-#endif
}
void AnsiHighlighter::setOutputFile(FILE *fileHandle)
{
+ Q_D(AnsiHighlighter);
d->file.open(fileHandle, QIODevice::WriteOnly);
d->out.setDevice(&d->file);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- d->out.setCodec("UTF-8");
-#endif
}
-void AnsiHighlighter::highlightFile(const QString &fileName, AnsiFormat format, bool useEditorBackground, TraceOptions traceOptions)
+void AnsiHighlighter::highlightFile(const QString &fileName, AnsiFormat format, Options options)
{
QFileInfo fi(fileName);
QFile f(fileName);
@@ -1241,19 +1246,21 @@ void AnsiHighlighter::highlightFile(const QString &fileName, AnsiFormat format,
return;
}
- highlightData(&f, format, useEditorBackground, traceOptions);
+ highlightData(&f, format, options);
}
-void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useEditorBackground, TraceOptions traceOptions)
+void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, Options options)
{
+ Q_D(AnsiHighlighter);
+
if (!d->out.device()) {
qCWarning(Log) << "No output stream defined!";
return;
}
const auto is256Colors = (format == AnsiFormat::XTerm256Color);
- const auto theme = this->theme();
- const auto definition = this->definition();
+ const auto &theme = d->m_theme;
+ const auto &definition = d->m_definition;
auto definitions = definition.includedDefinitions();
definitions.append(definition);
@@ -1265,6 +1272,8 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
QLatin1String foregroundDefaultColor;
QLatin1String backgroundDefaultColor;
+ const bool useEditorBackground = options.testFlag(Option::UseEditorBackground);
+
// https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
if (useEditorBackground) {
@@ -1277,23 +1286,19 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
backgroundDefaultColor = backgroundColorBuffer.latin1().mid(2);
}
- // ansiStyles must not be empty for applyFormat to work even with a definition without any context
- if (d->ansiStyles.empty()) {
- d->ansiStyles.resize(32);
- } else {
- d->ansiStyles[0].first.clear();
- d->ansiStyles[0].second.clear();
+ int maxId = 0;
+ for (const auto &definition : std::as_const(definitions)) {
+ for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
+ maxId = qMax(maxId, format.id());
+ }
}
+ d->ansiStyles.clear();
+ // ansiStyles must not be empty for applyFormat to work even with a definition without any context
+ d->ansiStyles.resize(maxId + 1);
// initialize ansiStyles
- for (auto &&definition : std::as_const(definitions)) {
- for (auto &&format : std::as_const(DefinitionData::get(definition)->formats)) {
- const auto id = format.id();
- if (id >= d->ansiStyles.size()) {
- // better than id + 1 to avoid successive allocations
- d->ansiStyles.resize(id * 2);
- }
-
+ for (const auto &definition : std::as_const(definitions)) {
+ for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
AnsiBuffer buffer;
buffer.append(QLatin1String("\x1b["));
@@ -1329,7 +1334,8 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
// if there is ANSI style
if (buffer.latin1().size() > 2) {
buffer.setFinalStyle();
- d->ansiStyles[id].first = buffer.latin1();
+ auto &style = d->ansiStyles[format.id()];
+ style.first = buffer.latin1();
if (useEditorBackground) {
buffer.clear();
@@ -1338,11 +1344,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
buffer.append(hasEffect ? QLatin1String("\x1b[0;") : QLatin1String("\x1b["));
buffer.append(backgroundDefaultColor);
buffer.setFinalStyle();
- d->ansiStyles[id].second = buffer.latin1();
+ style.second = buffer.latin1();
} else if (hasEffect) {
buffer.append(QLatin1String("\x1b["));
if (hasBold) {
- buffer.append(QLatin1String("21;"));
+ buffer.append(QLatin1String("22;"));
}
if (hasItalic) {
buffer.append(QLatin1String("23;"));
@@ -1354,10 +1360,10 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
buffer.append(QLatin1String("29;"));
}
buffer.setFinalStyle();
- d->ansiStyles[id].second = buffer.latin1();
+ style.second = buffer.latin1();
}
} else {
- d->ansiStyles[id].second = QStringLiteral("\x1b[0m");
+ style.second = QStringLiteral("\x1b[0m");
}
}
}
@@ -1370,13 +1376,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
}
QTextStream in(dev);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- in.setCodec("UTF-8");
-#endif
- if (!traceOptions) {
+ if (!options.testAnyFlag(Option::TraceAll)) {
State state;
QString currentLine;
+ const bool isUnbuffered = options.testFlag(Option::Unbuffered);
while (in.readLineInto(&currentLine)) {
d->currentLine = currentLine;
state = highlightLine(d->currentLine, state);
@@ -1386,6 +1390,10 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
} else {
d->out << QLatin1Char('\n');
}
+
+ if (isUnbuffered) {
+ d->out.flush();
+ }
}
} else {
AnsiBuffer buffer;
@@ -1394,7 +1402,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
buffer.setFinalStyle();
DebugSyntaxHighlighter debugHighlighter;
debugHighlighter.setDefinition(definition);
- debugHighlighter.highlightData(in, d->out, buffer.latin1(), backgroundDefaultColor, d->ansiStyles, traceOptions);
+ debugHighlighter.highlightData(in, d->out, buffer.latin1(), backgroundDefaultColor, d->ansiStyles, options);
}
if (useEditorBackground) {
@@ -1408,6 +1416,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
void AnsiHighlighter::applyFormat(int offset, int length, const Format &format)
{
+ Q_D(AnsiHighlighter);
auto const &ansiStyle = d->ansiStyles[format.id()];
d->out << ansiStyle.first << d->currentLine.mid(offset, length) << ansiStyle.second;
}