diff --git a/UApp.pas b/UApp.pas index 2161d96..3640c54 100644 --- a/UApp.pas +++ b/UApp.pas @@ -25,7 +25,7 @@ unit UApp; interface uses - Classes, SysUtils, CustApp, RegExpr, + Classes, SysUtils, CustApp, RegExpr, Math, UFilter, UWriter; type @@ -105,6 +105,9 @@ begin FWriter.Add(TConsoleWriter.Create); + if HasOption('html') then + FWriter.Add(THTMLWriter.Create(GetOptionValue('html'))); + AssignFile(logFile, FLogFileName); Reset(logFile); @@ -153,10 +156,73 @@ end; procedure TLogFilterApplication.WriteContent(AContent: String; AFilters: TFilterList; AGroupRanges: TGroupRanges); var + i: Integer; + matchPos, offset: Integer; + highlights: THighlights; + highlight: THighlight; + group: Byte; writer: TWriter; begin + + highlights := THighlights.Create; + + offset := 0; + + for i := 0 to AFilters.Count - 1 do + begin + if AFilters[i].Expression.Exec(AContent) then + begin + repeat + // We need these values anyway. + matchPos := AFilters[i].Expression.MatchPos[0]; + offset := AFilters[i].Expression.MatchLen[0]; + + group := AFilters[i].Group; + if group < Length(AGroupRanges) then + begin + if (matchPos + offset < AGroupRanges[group].StartIdx) or + (matchPos > AGroupRanges[group].EndIdx) then + continue; //Pointless; nothing we can do here + + highlight.Start := Max(AGroupRanges[group].StartIdx, matchPos); + highlight.Length := Min(AGroupRanges[group].EndIdx - highlight.Start, + highlight.Start + offset - matchPos); + + {$ifdef debugmatches} + writeln(' Highlight: ', highlight.Start, ', ', highlight.Length); + writeln(' MatchPos: ', matchPos, ', StartIdx: ', AGroupRanges[group].StartIdx); + writeln(' Offset: ', offset, ', EndIdx: ', AGroupRanges[group].EndIdx); + {$endif} + end else + begin + highlight.Start := matchPos; + highlight.Length := offset; + end; + + highlight.FGColor := AFilters[i].FGColor; + highlight.BGColor := AFilters[i].BGColor; + highlights.Add(highlight); + until not AFilters[i].Expression.ExecNext; + end; + end; + + highlights.Sort(@CompareHighlights); + + // Sanitize highlights + for i := 0 to highlights.Count - 2 do + begin + if (highlights[i].Start + highlights[i].Length) > highlights[i+1].Start then + begin + highlight := highlights[i]; + highlight.Length := highlights[i+1].Start - highlights[i].Start; + highlights[i] := highlight; + end; + end; + for writer in FWriter do - writer.WriteContent(AContent, AFilters, AGroupRanges); + writer.WriteContent(AContent, highlights); + + highlights.Free; end; constructor TLogFilterApplication.Create(TheOwner: TComponent); diff --git a/UWriter.pas b/UWriter.pas index 8c1cb14..c59b850 100644 --- a/UWriter.pas +++ b/UWriter.pas @@ -5,13 +5,13 @@ unit UWriter; interface uses - Classes, SysUtils, UFilter, Math, crt, fgl; + Classes, SysUtils, UFilter, crt, fgl; type TWriter = class public - procedure WriteContent(AContent: String; AFilters: TFilterList; - AGroupRanges: TGroupRanges); virtual; abstract; + procedure WriteContent(AContent: String; + AHighlights: THighlights); virtual; abstract; end; TWriterList = specialize TFPGObjectList; @@ -19,80 +19,64 @@ type TConsoleWriter = class(TWriter) public - procedure WriteContent(AContent: String; AFilters: TFilterList; - AGroupRanges: TGroupRanges); override; + procedure WriteContent(AContent: String; + AHighlights: THighlights); override; + end; + + { THTMLWriter } + + THTMLWriter = class(TWriter) + protected + FFileStream: TFileStream; + procedure WriteLine(AContent: String); + public + constructor Create(AFileName: String); + destructor Destroy; override; + procedure WriteContent(AContent: String; + AHighlights: THighlights); override; end; implementation +{ THTMLWriter } + +procedure THTMLWriter.WriteLine(AContent: String); +begin + AContent := AContent + LineEnding; + FFileStream.Write(AContent[1], Length(AContent)); +end; + +constructor THTMLWriter.Create(AFileName: String); +begin + FFileStream := TFileStream.Create(AFileName, fmCreate); + WriteLine(''); + WriteLine(''); +end; + +destructor THTMLWriter.Destroy; +begin + WriteLine(''); + WriteLine(''); + FFileStream.Free; + inherited Destroy; +end; + +procedure THTMLWriter.WriteContent(AContent: String; AHighlights: THighlights); +begin + +end; + { TConsoleWriter } -procedure TConsoleWriter.WriteContent(AContent: String; AFilters: TFilterList; - AGroupRanges: TGroupRanges); +procedure TConsoleWriter.WriteContent(AContent: String; AHighlights: THighlights + ); var - i: Integer; matchPos, offset, lastPos: Integer; - highlights: THighlights; highlight: THighlight; - group: Byte; begin - highlights := THighlights.Create; - - offset := 0; lastPos := 1; - for i := 0 to AFilters.Count - 1 do - begin - if AFilters[i].Expression.Exec(AContent) then - begin - repeat - // We need these values anyway. - matchPos := AFilters[i].Expression.MatchPos[0]; - offset := AFilters[i].Expression.MatchLen[0]; - - group := AFilters[i].Group; - if group < Length(AGroupRanges) then - begin - if (matchPos + offset < AGroupRanges[group].StartIdx) or - (matchPos > AGroupRanges[group].EndIdx) then - continue; //Pointless; nothing we can do here - - highlight.Start := Max(AGroupRanges[group].StartIdx, matchPos); - highlight.Length := Min(AGroupRanges[group].EndIdx - highlight.Start, - highlight.Start + offset - matchPos); - - {$ifdef debugmatches} - writeln(' Highlight: ', highlight.Start, ', ', highlight.Length); - writeln(' MatchPos: ', matchPos, ', StartIdx: ', AGroupRanges[group].StartIdx); - writeln(' Offset: ', offset, ', EndIdx: ', AGroupRanges[group].EndIdx); - {$endif} - end else - begin - highlight.Start := matchPos; - highlight.Length := offset; - end; - - highlight.FGColor := AFilters[i].FGColor; - highlight.BGColor := AFilters[i].BGColor; - highlights.Add(highlight); - until not AFilters[i].Expression.ExecNext; - end; - end; - - highlights.Sort(@CompareHighlights); - - // Sanitize highlights - for i := 0 to highlights.Count - 2 do - begin - if (highlights[i].Start + highlights[i].Length) > highlights[i+1].Start then - begin - highlight := highlights[i]; - highlight.Length := highlights[i+1].Start - highlights[i].Start; - highlights[i] := highlight; - end; - end; - - for highlight in highlights do + for highlight in AHighlights do begin matchPos := highlight.Start; offset := highlight.Length; @@ -107,8 +91,6 @@ begin end; writeln(Copy(AContent, lastPos, Length(AContent))); - - highlights.Free; end; end.