| 18 | } |
| 19 | |
| 20 | QList<FormattedText> CodeFormatHandler::parseText(const FormattedText &input) |
| 21 | { |
| 22 | const QString escape = "\x1b["; |
| 23 | const QChar semicolon = ';'; |
| 24 | const QChar colorTerminator = 'm'; |
| 25 | const QChar eraseToEol = 'K'; |
| 26 | |
| 27 | QList<FormattedText> outputData; |
| 28 | QTextCharFormat charFormat = previousFormatClosed ? input.format : previousFormat; |
| 29 | QString strippedText; |
| 30 | if (pendingText.isEmpty()) { |
| 31 | strippedText = input.text; |
| 32 | } else { |
| 33 | strippedText = pendingText.append(input.text); |
| 34 | pendingText.clear(); |
| 35 | } |
| 36 | |
| 37 | while (!strippedText.isEmpty()) { |
| 38 | QTC_ASSERT(pendingText.isEmpty(), break); |
| 39 | if (waitingForTerminator) { |
| 40 | // We ignore all escape codes taking string arguments. |
| 41 | QString terminator = "\x1b\\"; |
| 42 | int terminatorPos = strippedText.indexOf(terminator); |
| 43 | if (terminatorPos == -1 && !alternateTerminator.isEmpty()) { |
| 44 | terminator = alternateTerminator; |
| 45 | terminatorPos = strippedText.indexOf(terminator); |
| 46 | } |
| 47 | if (terminatorPos == -1) { |
| 48 | pendingText = strippedText; |
| 49 | break; |
| 50 | } |
| 51 | waitingForTerminator = false; |
| 52 | alternateTerminator.clear(); |
| 53 | strippedText.remove(0, terminatorPos + terminator.length()); |
| 54 | if (strippedText.isEmpty()) |
| 55 | break; |
| 56 | } |
| 57 | const int escapePos = strippedText.indexOf(escape.at(0)); |
| 58 | if (escapePos < 0) { |
| 59 | outputData << FormattedText(strippedText, charFormat); |
| 60 | break; |
| 61 | } else if (escapePos != 0) { |
| 62 | outputData << FormattedText(strippedText.left(escapePos), charFormat); |
| 63 | strippedText.remove(0, escapePos); |
| 64 | } |
| 65 | QTC_ASSERT(strippedText.at(0) == escape.at(0), break); |
| 66 | |
| 67 | while (!strippedText.isEmpty() && escape.at(0) == strippedText.at(0)) { |
| 68 | if (escape.startsWith(strippedText)) { |
| 69 | // control secquence is not complete |
| 70 | pendingText += strippedText; |
| 71 | strippedText.clear(); |
| 72 | break; |
| 73 | } |
| 74 | if (!strippedText.startsWith(escape)) { |
| 75 | switch (strippedText.at(1).toLatin1()) { |
| 76 | case '\\': // Unexpected terminator sequence. |
| 77 | QTC_CHECK(false); |