diff options
Diffstat (limited to 'plugins/warp/ui/shared/misc.cpp')
| -rw-r--r-- | plugins/warp/ui/shared/misc.cpp | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/plugins/warp/ui/shared/misc.cpp b/plugins/warp/ui/shared/misc.cpp index 71147079..bbe3ab24 100644 --- a/plugins/warp/ui/shared/misc.cpp +++ b/plugins/warp/ui/shared/misc.cpp @@ -8,6 +8,21 @@ #include "render.h" #include "theme.h" +TokenData::TokenData(const std::string &name) +{ + tokens.emplace_back(255, TextToken, name); +} + +TokenData::TokenData(const BinaryNinja::Type &type, const std::string& name) +{ + for (const auto &token: type.GetTokensBeforeName()) + tokens.emplace_back(token); + tokens.emplace_back(255, TextToken, " "); + tokens.emplace_back(255, TextToken, name); + for (const auto &token: type.GetTokensAfterName()) + tokens.emplace_back(token); +} + void TokenDataDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { painter->save(); @@ -23,7 +38,7 @@ void TokenDataDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt painter->translate(option.rect.topLeft()); - auto renderContext = RenderContext((QWidget *) option.widget); + auto renderContext = RenderContext(const_cast<QWidget *>(option.widget)); renderContext.init(*painter); HighlightTokenState highlightState; renderContext.drawDisassemblyLine(*painter, 5, 5, {tokenData.tokens.begin(), tokenData.tokens.end()}, @@ -35,7 +50,7 @@ void TokenDataDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt QSize TokenDataDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { auto tokenData = index.data(Qt::UserRole).value<TokenData>(); - auto renderContext = RenderContext((QWidget *) option.widget); + auto renderContext = RenderContext(const_cast<QWidget *>(option.widget)); QFontMetrics fontMetrics = QFontMetrics(renderContext.getFont()); QString line = ""; for (const auto &token: tokenData.tokens) @@ -79,3 +94,47 @@ bool GenericTextFilterModel::lessThan(const QModelIndex &sourceLeft, const QMode auto rightData = sourceRight.data().toString(); return QString::localeAwareCompare(leftData, rightData) < 0; } + +ParsedQuery::ParsedQuery(const QString &rawQuery) +{ + query = rawQuery; + qualifiers = {}; + + // Regex capturing: key, and value (bare, quoted and unquoted) + static QRegularExpression re(R"((^|\s)([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(?:\"([^\"]*)\"|'([^']*)'|(\S+)))", + QRegularExpression::CaseInsensitiveOption); + + // Collect matches to remove later (from end to start to keep indices stable) + struct Span + { + qsizetype start; + qsizetype length; + QString key; + QString value; + }; + QVector<Span> spans; + + auto it = re.globalMatch(rawQuery); + while (it.hasNext()) + { + const auto m = it.next(); + const QString key = m.captured(2).toLower(); + // Value can be in group 3 (double quotes), 4 (single quotes), or 5 (bare) + QString val = m.captured(3); + if (val.isNull() || val.isEmpty()) val = m.captured(4); + if (val.isNull() || val.isEmpty()) val = m.captured(5); + spans.push_back(Span{m.capturedStart(0), m.capturedLength(0), key, val}); + } + + // Keep only the last value per key (last occurrence wins, do not accumulate) + for (const auto &s: spans) + qualifiers[s.key] = s.value; + + // Remove matched spans from the text (replace with a single space to preserve boundaries) + std::sort(spans.begin(), spans.end(), [](const Span &a, const Span &b) { return a.start > b.start; }); + for (const auto &s: spans) + query.replace(s.start, s.length, QStringLiteral(" ")); + + // Normalize whitespace + query = query.simplified(); +} |
