193 lines
5.2 KiB
C++
193 lines
5.2 KiB
C++
|
// Scintilla source code edit control
|
||
|
/** @file LexMPT.cxx
|
||
|
** Lexer for MPT specific files. Based on LexOthers.cxx
|
||
|
** LOT = the text log file created by the MPT application while running a test program
|
||
|
** Other MPT specific files to be added later.
|
||
|
**/
|
||
|
// Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>
|
||
|
// The License.txt file describes the conditions under which this software may be distributed.
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <assert.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
#include <string>
|
||
|
#include <string_view>
|
||
|
|
||
|
#include "ILexer.h"
|
||
|
#include "Scintilla.h"
|
||
|
#include "SciLexer.h"
|
||
|
|
||
|
#include "WordList.h"
|
||
|
#include "LexAccessor.h"
|
||
|
#include "Accessor.h"
|
||
|
#include "StyleContext.h"
|
||
|
#include "CharacterSet.h"
|
||
|
#include "LexerModule.h"
|
||
|
|
||
|
using namespace Lexilla;
|
||
|
|
||
|
static int GetLotLineState(std::string &line) {
|
||
|
if (line.length()) {
|
||
|
// Most of the time the first non-blank character in line determines that line's type
|
||
|
// Now finds the first non-blank character
|
||
|
unsigned i; // Declares counter here to make it persistent after the for loop
|
||
|
for (i = 0; i < line.length(); ++i) {
|
||
|
if (!(IsASCII(line[i]) && isspace(line[i])))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Checks if it was a blank line
|
||
|
if (i == line.length())
|
||
|
return SCE_LOT_DEFAULT;
|
||
|
|
||
|
switch (line[i]) {
|
||
|
case '*': // Fail measurement
|
||
|
return SCE_LOT_FAIL;
|
||
|
|
||
|
case '+': // Header
|
||
|
case '|': // Header
|
||
|
return SCE_LOT_HEADER;
|
||
|
|
||
|
case ':': // Set test limits
|
||
|
return SCE_LOT_SET;
|
||
|
|
||
|
case '-': // Section break
|
||
|
return SCE_LOT_BREAK;
|
||
|
|
||
|
default: // Any other line
|
||
|
// Checks for message at the end of lot file
|
||
|
if (line.find("PASSED") != std::string::npos) {
|
||
|
return SCE_LOT_PASS;
|
||
|
}
|
||
|
else if (line.find("FAILED") != std::string::npos) {
|
||
|
return SCE_LOT_FAIL;
|
||
|
}
|
||
|
else if (line.find("ABORTED") != std::string::npos) {
|
||
|
return SCE_LOT_ABORT;
|
||
|
}
|
||
|
else {
|
||
|
return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
return SCE_LOT_DEFAULT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ColourizeLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||
|
styler.StartAt(startPos);
|
||
|
styler.StartSegment(startPos);
|
||
|
bool atLineStart = true;// Arms the 'at line start' flag
|
||
|
char chNext = styler.SafeGetCharAt(startPos);
|
||
|
std::string line("");
|
||
|
line.reserve(256); // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
|
||
|
|
||
|
// Styles LOT document
|
||
|
Sci_PositionU i; // Declared here because it's used after the for loop
|
||
|
for (i = startPos; i < startPos + length; ++i) {
|
||
|
char ch = chNext;
|
||
|
chNext = styler.SafeGetCharAt(i + 1);
|
||
|
line += ch;
|
||
|
atLineStart = false;
|
||
|
|
||
|
// LOT files are only used on the Win32 platform, thus EOL == CR+LF
|
||
|
// Searches for the end of line
|
||
|
if (ch == '\r' && chNext == '\n') {
|
||
|
line += chNext; // Gets the '\n'
|
||
|
++i; // Advances past the '\n'
|
||
|
chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line
|
||
|
styler.ColourTo(i, GetLotLineState(line));
|
||
|
line = "";
|
||
|
atLineStart = true; // Arms flag for next line
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Last line may not have a line ending
|
||
|
if (!atLineStart) {
|
||
|
styler.ColourTo(i - 1, GetLotLineState(line));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Folds an MPT LOT file: the blocks that can be folded are:
|
||
|
// sections (headed by a set line)
|
||
|
// passes (contiguous pass results within a section)
|
||
|
// fails (contiguous fail results within a section)
|
||
|
static void FoldLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||
|
bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0;
|
||
|
Sci_PositionU endPos = startPos + length;
|
||
|
int visibleChars = 0;
|
||
|
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||
|
|
||
|
char chNext = styler.SafeGetCharAt(startPos);
|
||
|
int style = SCE_LOT_DEFAULT;
|
||
|
int styleNext = styler.StyleAt(startPos);
|
||
|
int lev = SC_FOLDLEVELBASE;
|
||
|
|
||
|
// Gets style of previous line if not at the beginning of the document
|
||
|
if (startPos > 1)
|
||
|
style = styler.StyleAt(startPos - 2);
|
||
|
|
||
|
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||
|
char ch = chNext;
|
||
|
chNext = styler.SafeGetCharAt(i + 1);
|
||
|
|
||
|
if (ch == '\r' && chNext == '\n') {
|
||
|
// TO DO:
|
||
|
// Should really get the state of the previous line from the styler
|
||
|
int stylePrev = style;
|
||
|
style = styleNext;
|
||
|
styleNext = styler.StyleAt(i + 2);
|
||
|
|
||
|
switch (style) {
|
||
|
/*
|
||
|
case SCE_LOT_SET:
|
||
|
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
|
||
|
break;
|
||
|
*/
|
||
|
case SCE_LOT_FAIL:
|
||
|
/*
|
||
|
if (stylePrev != SCE_LOT_FAIL)
|
||
|
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
|
||
|
else
|
||
|
lev = SC_FOLDLEVELBASE + 1;
|
||
|
*/
|
||
|
lev = SC_FOLDLEVELBASE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
|
||
|
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
|
||
|
else
|
||
|
lev = SC_FOLDLEVELBASE + 1;
|
||
|
|
||
|
if (visibleChars == 0 && foldCompact)
|
||
|
lev |= SC_FOLDLEVELWHITEFLAG;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (lev != styler.LevelAt(lineCurrent))
|
||
|
styler.SetLevel(lineCurrent, lev);
|
||
|
|
||
|
lineCurrent++;
|
||
|
visibleChars = 0;
|
||
|
}
|
||
|
|
||
|
if (!isspacechar(ch))
|
||
|
visibleChars++;
|
||
|
}
|
||
|
|
||
|
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
|
||
|
styler.SetLevel(lineCurrent, lev | flagsNext);
|
||
|
}
|
||
|
|
||
|
static const char * const emptyWordListDesc[] = {
|
||
|
0
|
||
|
};
|
||
|
|
||
|
LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc);
|