{ This file is part of logfilter. Copyright (C) 2015 Andreas Schneider logfilter is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. logfilter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with logfilter. If not, see . } unit UApp; {$mode objfpc}{$H+} {.$define debugmatches} interface uses Classes, SysUtils, CustApp, math, RegExpr, UFilter, UWriter; type { TLogFilterApplication } TLogFilterApplication = class(TCustomApplication) protected FLineFilters: TLineFilters; FCurrentLineFilter: TLineFilter; FCommandMatcher: TRegExpr; FCommandFileName: String; FLogFileName: String; FWriter: TWriterList; procedure DoRun; override; procedure ProcessCommand(ACommand, AParams: String); procedure WriteContent(AContent: String; AFilters: TFilterList; AGroupRanges: TGroupRanges); public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; end; implementation { TLogFilterApplication } procedure TLogFilterApplication.DoRun; var commandFile: TextFile; logFile: TextFile; groupRanges: TGroupRanges; lineFilter: TLineFilter; line: String; begin if HasOption('h', 'help') or not HasOption('c', 'commandfile') then begin WriteHelp; Terminate; Exit; end; FCommandFileName := GetOptionValue('c', 'commandfile'); if not FileExists(FCommandFileName) then begin Writeln('Commandfile not found: ', FCommandFileName); ExitCode := 1; Terminate; Exit; end; AssignFile(commandFile, FCommandFileName); Reset(commandFile); // Parse command file first while not EOF(commandFile) do begin Readln(commandFile, line); if FCommandMatcher.Exec(line) then ProcessCommand(FCommandMatcher.Match[1], FCommandMatcher.Match[3]); end; CloseFile(commandFile); if HasOption('f', 'logfile') then FLogFileName := GetOptionValue('f', 'logfile'); if not FileExists(FLogFileName) then begin Writeln('Logfile not found: ', FLogFileName); ExitCode := 1; Terminate; Exit; end; FWriter.Add(TConsoleWriter.Create); AssignFile(logFile, FLogFileName); Reset(logFile); // Filter log while not EOF(logFile) do begin Readln(logFile, line); for lineFilter in FLineFilters do begin if lineFilter.Matches(line, groupRanges) then begin WriteContent(line, lineFilter.Filters, groupRanges); Break; end; end; end; CloseFile(logFile); // One run is enough. Terminate; end; procedure TLogFilterApplication.ProcessCommand(ACommand, AParams: String); var highlightFilter: THighlightFilter; begin case LowerCase(ACommand) of 'filter': begin FCurrentLineFilter := TLineFilter.Create(AParams); FLineFilters.Add(FCurrentLineFilter); end; 'highlight': begin highlightFilter := THighlightFilter.Create(AParams); FCurrentLineFilter.Filters.Add(highlightFilter); end; 'file': begin FLogFileName := AParams; end; end; end; procedure TLogFilterApplication.WriteContent(AContent: String; AFilters: TFilterList; AGroupRanges: TGroupRanges); var writer: TWriter; begin for writer in FWriter do writer.WriteContent(AContent, AFilters, AGroupRanges); end; constructor TLogFilterApplication.Create(TheOwner: TComponent); begin inherited Create(TheOwner); FLineFilters := TLineFilters.Create; FCommandMatcher := TRegExpr.Create('^(\w+)( (.*)|)$'); // 1 = command, 3 = OPTIONAL params FWriter := TWriterList.Create; end; destructor TLogFilterApplication.Destroy; begin FLineFilters.Free; FCommandMatcher.Free; FWriter.Free; inherited Destroy; end; procedure TLogFilterApplication.WriteHelp; begin Writeln('Usage: ', ExtractFileName(ExeName), ' [options]'); Writeln; Writeln('Options:'); Writeln(' -c --commandfile='); Writeln(' specifies the filename with filter commands'); Writeln(' -f --logfile='); Writeln(' specifies the logfile to be parsed'); Writeln(' -h --help'); Writeln(' show this help screen'); end; end.