// SPDX-License-Identifier: LGPL-3.0-linking-exception unit TextLine; {$mode objfpc}{$H+} interface uses Classes, SysUtils, ReleaserTypes; type { TTextLine } TTextLine = class(TReleaserObject) private FFilename, FTextLine: String; FTextLineStart, FTextLineEnd: integer; FVersion: TVersion; FText: string; FChanged: boolean; public constructor Create(AParameters: TStringList; ALogicDir: string); override; destructor Destroy; override; procedure Save; override; function GetLineForVersion(AVersion: TVersion): string; procedure GetVersions({%H-}AVersionList: TStringList); override; procedure CheckVersion(AVersion: TVersion); override; procedure UpdateVersion(AVersion: TVersion); override; end; implementation { TTextLine } constructor TTextLine.Create(AParameters: TStringList; ALogicDir: string); var str: TStringStream; stream: TFileStream; begin inherited Create(AParameters, ALogicDir); ExpectParamCount(2); FFilename := ExpandFileName(ReplaceVariables(Param[0])); FTextLine := Param[1]; FTextLineStart:= 0; FTextLineEnd:= 0; stream := nil; str := nil; try stream := TFileStream.Create(FFilename, fmOpenRead); str := TStringStream.Create(''); if str.CopyFrom(stream, stream.Size)<>stream.Size then raise exception.Create('Unable to read file'); FText := str.DataString; finally str.Free; stream.Free; end; end; destructor TTextLine.Destroy; begin inherited Destroy; end; procedure TTextLine.Save; var stream: TFileStream; begin if FChanged then begin writeln('Updating text file "',ExtractFileName(FFilename),'"'); stream := TFileStream.Create(FFilename, fmCreate); try if FText <> '' then stream.WriteBuffer(FText[1], length(FText)); finally stream.Free; end; end; end; function TTextLine.GetLineForVersion(AVersion: TVersion): string; begin result := ReplaceVariables(FTextLine, AVersion); end; procedure TTextLine.GetVersions(AVersionList: TStringList); begin //nothing end; procedure TTextLine.CheckVersion(AVersion: TVersion); var i, start: Integer; expectLine: string; procedure TryLine(AEnd: integer); var curLine: String; begin if AEnd > start then begin curLine := copy(FText, start, AEnd-start); if curLine = expectLine then begin FTextLineStart:= start; FTextLineEnd:= AEnd; FVersion := AVersion; end; end; start := AEnd+1; end; begin inherited CheckVersion(AVersion); if FTextLineEnd > FTextLineStart then exit; expectLine := GetLineForVersion(AVersion); i := 1; start := 1; while (i < length(FText)) and (FTextLineEnd <= FTextLineStart) do begin if FText[i] in[#13,#10] then TryLine(i); inc(i); end; if (FTextLineEnd <= FTextLineStart) then TryLine(i); if FTextLineEnd > FTextLineStart then writeln('Text file "',ExtractFileName(FFilename),'" line found') else writeln('Text file "',ExtractFileName(FFilename),'" line not found'); end; procedure TTextLine.UpdateVersion(AVersion: TVersion); var newLine: String; begin if AVersion = FVersion then exit; newLine := GetLineForVersion(AVersion); if FTextLineEnd > FTextLineStart then begin delete(FText, FTextLineStart, FTextLineEnd-FTextLineStart); insert(newLine, FText, FTextLineStart); FTextLineEnd:= FTextLineStart+length(newLine); FChanged:= true; end else writeln('Please add manually a line "',newLine,'" in "',ExtractFileName(FFilename),'"'); end; end.