* @brief Parses 'pass grep' raw output into (entry, matches) pairs. * * pass grep emits ANSI blue color (\x1B[94m) at the start of each entry * header line. This is checked before stripping ANSI so headers are detected * reliably regardless of locale. */
| 569 | * reliably regardless of locale. |
| 570 | */ |
| 571 | auto parseGrepOutput(const QString &rawOut) |
| 572 | -> QList<QPair<QString, QStringList>> { |
| 573 | static const QRegularExpression ansi( |
| 574 | QStringLiteral(R"(\x1B\[[0-9;]*[a-zA-Z])")); |
| 575 | QList<QPair<QString, QStringList>> results; |
| 576 | QString currentEntry; |
| 577 | QStringList currentMatches; |
| 578 | for (const QString &rawLine : rawOut.split('\n')) { |
| 579 | QString line = rawLine; |
| 580 | line.remove('\r'); |
| 581 | line.remove(ansi); |
| 582 | line = line.trimmed(); |
| 583 | const bool isHeader = isGrepHeaderLine(rawLine, line); |
| 584 | if (isHeader) { |
| 585 | if (!currentEntry.isEmpty() && !currentMatches.isEmpty()) |
| 586 | results.append({currentEntry, currentMatches}); |
| 587 | currentEntry = line.endsWith(':') ? line.chopped(1) : line; |
| 588 | currentMatches.clear(); |
| 589 | } else if (!currentEntry.isEmpty()) { |
| 590 | if (!line.isEmpty()) |
| 591 | currentMatches << line; |
| 592 | } |
| 593 | } |
| 594 | if (!currentEntry.isEmpty() && !currentMatches.isEmpty()) |
| 595 | results.append({currentEntry, currentMatches}); |
| 596 | return results; |
| 597 | } |
| 598 | |
| 599 | /** |
| 600 | * @brief Pass::processFinished reemits specific signal based on what process |
no test coverage detected