Insert a line to a text file/template in Inno Setup before a specific line if doesn't exist yet

How can I add a line to a file/template before a specific other line, if it doesn't exist?

For example for the following JS file, I have to make sure that there's dependencies.push(...) line between the ABOVE THIS LINE and BELOW THIS LINE comment-lines. If the dependencies.push(...) is not present, I have to add it before the BELOW THIS LINE comment-line:

(function(ng) {
    var dependencies = [];

    /*DO NOT MODIFY ABOVE THIS LINE!*/

    dependencies.push("mxdfNewTransaction.controller.mxdfNewTransactionCtrl");

    /*DO NOT MODIFY BELOW THIS LINE!*/

    ng.module('prismApp.customizations', dependencies, null);
})(angular);

I have to also do the same thing with a similar HTML template file.

Thanks for your help.

Upvotes: 2

Views: 1415

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202272

You have to parse the file line-by-line to find the spot to insert your code.

Something like this:

function AddLineToTemplate(
  FileName: string; StartLine, EndLine, AddLine: string): Boolean;
var
  Lines: TArrayOfString;
  Count, I, I2: Integer;
  Line: string;
  State: Integer;
begin
  Result := True;

  if not LoadStringsFromFile(FileName, Lines) then
  begin
    Log(Format('Error reading %s', [FileName]));
    Result := False;
  end
    else
  begin
    State := 0;
    
    Count := GetArrayLength(Lines);
    for I := 0 to Count - 1 do
    begin
      Line := Trim(Lines[I]);
      if (CompareText(Line, StartLine) = 0) then
      begin
        State := 1;
        Log(Format('Start line found at %d', [I]));
      end
        else
      if (State = 1) and (CompareText(Line, AddLine) = 0) then
      begin
        Log(Format('Line already present at %d', [I]));
        State := 2;
        break;
      end
        else
      if (State = 1) and (CompareText(Line, EndLine) = 0) then
      begin
        Log(Format('End line found at %d, inserting', [I]));
        SetArrayLength(Lines, Count + 1);
        for I2 := Count - 1 downto I do
          Lines[I2 + 1] := Lines[I2];
        Lines[I] := AddLine;
        State := 2;

        if not SaveStringsToFile(FileName, Lines, False) then
        begin
          Log(Format('Error writing %s', [FileName]));
          Result := False;
        end
          else
        begin
          Log(Format('Modifications saved to %s', [FileName]));
        end;

        break;
      end;
    end;

    if Result and (State <> 2) then
    begin
      Log(Format('Spot to insert line was not found in %s', [FileName]));
      Result := False;
    end;
  end;
end;

You can use it like this:

if AddLineToTemplate(
     'C:\path\to\customizations.js',
     '/*DO NOT MODIFY ABOVE THIS LINE!*/',
     '/*DO NOT MODIFY BELOW THIS LINE!*/', 
     '    dependencies.push("mxdfNewTransaction.controller.mxdfNewTransactionCtrl");') then
begin
  Log('Success');
end
  else
begin
  Log('Failure');
end;

Beware of the LoadStringsFromFile and SaveStringsToFile limitations, when working with Unicode files. See Inno Setup Reading file in Ansi and Unicode encoding.

Upvotes: 1

Related Questions