LexMPT.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // Scintilla source code edit control
  2. /** @file LexMPT.cxx
  3. ** Lexer for MPT specific files. Based on LexOthers.cxx
  4. ** LOT = the text log file created by the MPT application while running a test program
  5. ** Other MPT specific files to be added later.
  6. **/
  7. // Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>
  8. // The License.txt file describes the conditions under which this software may be distributed.
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <stdarg.h>
  13. #include <assert.h>
  14. #include <ctype.h>
  15. #include <string>
  16. #include "ILexer.h"
  17. #include "Scintilla.h"
  18. #include "SciLexer.h"
  19. #include "WordList.h"
  20. #include "LexAccessor.h"
  21. #include "Accessor.h"
  22. #include "StyleContext.h"
  23. #include "CharacterSet.h"
  24. #include "LexerModule.h"
  25. #ifdef SCI_NAMESPACE
  26. using namespace Scintilla;
  27. #endif
  28. static int GetLotLineState(std::string &line) {
  29. if (line.length()) {
  30. // Most of the time the first non-blank character in line determines that line's type
  31. // Now finds the first non-blank character
  32. unsigned i; // Declares counter here to make it persistent after the for loop
  33. for (i = 0; i < line.length(); ++i) {
  34. if (!(IsASCII(line[i]) && isspace(line[i])))
  35. break;
  36. }
  37. // Checks if it was a blank line
  38. if (i == line.length())
  39. return SCE_LOT_DEFAULT;
  40. switch (line[i]) {
  41. case '*': // Fail measurement
  42. return SCE_LOT_FAIL;
  43. case '+': // Header
  44. case '|': // Header
  45. return SCE_LOT_HEADER;
  46. case ':': // Set test limits
  47. return SCE_LOT_SET;
  48. case '-': // Section break
  49. return SCE_LOT_BREAK;
  50. default: // Any other line
  51. // Checks for message at the end of lot file
  52. if (line.find("PASSED") != std::string::npos) {
  53. return SCE_LOT_PASS;
  54. }
  55. else if (line.find("FAILED") != std::string::npos) {
  56. return SCE_LOT_FAIL;
  57. }
  58. else if (line.find("ABORTED") != std::string::npos) {
  59. return SCE_LOT_ABORT;
  60. }
  61. else {
  62. return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
  63. }
  64. }
  65. }
  66. else {
  67. return SCE_LOT_DEFAULT;
  68. }
  69. }
  70. static void ColourizeLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
  71. styler.StartAt(startPos);
  72. styler.StartSegment(startPos);
  73. bool atLineStart = true;// Arms the 'at line start' flag
  74. char chNext = styler.SafeGetCharAt(startPos);
  75. std::string line("");
  76. line.reserve(256); // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
  77. // Styles LOT document
  78. Sci_PositionU i; // Declared here because it's used after the for loop
  79. for (i = startPos; i < startPos + length; ++i) {
  80. char ch = chNext;
  81. chNext = styler.SafeGetCharAt(i + 1);
  82. line += ch;
  83. atLineStart = false;
  84. // LOT files are only used on the Win32 platform, thus EOL == CR+LF
  85. // Searches for the end of line
  86. if (ch == '\r' && chNext == '\n') {
  87. line += chNext; // Gets the '\n'
  88. ++i; // Advances past the '\n'
  89. chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line
  90. styler.ColourTo(i, GetLotLineState(line));
  91. line = "";
  92. atLineStart = true; // Arms flag for next line
  93. }
  94. }
  95. // Last line may not have a line ending
  96. if (!atLineStart) {
  97. styler.ColourTo(i - 1, GetLotLineState(line));
  98. }
  99. }
  100. // Folds an MPT LOT file: the blocks that can be folded are:
  101. // sections (headed by a set line)
  102. // passes (contiguous pass results within a section)
  103. // fails (contiguous fail results within a section)
  104. static void FoldLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
  105. bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0;
  106. Sci_PositionU endPos = startPos + length;
  107. int visibleChars = 0;
  108. Sci_Position lineCurrent = styler.GetLine(startPos);
  109. char chNext = styler.SafeGetCharAt(startPos);
  110. int style = SCE_LOT_DEFAULT;
  111. int styleNext = styler.StyleAt(startPos);
  112. int lev = SC_FOLDLEVELBASE;
  113. // Gets style of previous line if not at the beginning of the document
  114. if (startPos > 1)
  115. style = styler.StyleAt(startPos - 2);
  116. for (Sci_PositionU i = startPos; i < endPos; i++) {
  117. char ch = chNext;
  118. chNext = styler.SafeGetCharAt(i + 1);
  119. if (ch == '\r' && chNext == '\n') {
  120. // TO DO:
  121. // Should really get the state of the previous line from the styler
  122. int stylePrev = style;
  123. style = styleNext;
  124. styleNext = styler.StyleAt(i + 2);
  125. switch (style) {
  126. /*
  127. case SCE_LOT_SET:
  128. lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
  129. break;
  130. */
  131. case SCE_LOT_FAIL:
  132. /*
  133. if (stylePrev != SCE_LOT_FAIL)
  134. lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
  135. else
  136. lev = SC_FOLDLEVELBASE + 1;
  137. */
  138. lev = SC_FOLDLEVELBASE;
  139. break;
  140. default:
  141. if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
  142. lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
  143. else
  144. lev = SC_FOLDLEVELBASE + 1;
  145. if (visibleChars == 0 && foldCompact)
  146. lev |= SC_FOLDLEVELWHITEFLAG;
  147. break;
  148. }
  149. if (lev != styler.LevelAt(lineCurrent))
  150. styler.SetLevel(lineCurrent, lev);
  151. lineCurrent++;
  152. visibleChars = 0;
  153. }
  154. if (!isspacechar(ch))
  155. visibleChars++;
  156. }
  157. int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  158. styler.SetLevel(lineCurrent, lev | flagsNext);
  159. }
  160. static const char * const emptyWordListDesc[] = {
  161. 0
  162. };
  163. LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc);