0

I have many dfms. I am using delete unwanted properties exe from this site Delphi DFM properties remover, to remove deleted properties which are no longer required. Following code works fine except for some properties like if I want to delete property with name Prop then it deletes another property with name SecondProp along with Prop. mPropList contains each property on new line like Prop1 Prop2 SecondProp Propn

I doubt following code:

 if StrIPos(mPropList.Lines[K] + ' =', S) = 0 then
      begin
        LResult.Add(LSource[J]);
        continue;
      end;

How to skip SecondProp in such case?

I tried this

if mPropList.Lines[K] = S then
      begin
        LResult.Add(LSource[J]);
        continue;
      end;

To match exact strings, but it didn't work.

This is delete button code

procedure TfrmDeleteProp_MainForm.Button2Click(Sender: TObject);
var
      LFile, LSource, LResult: TStringList;
      I, J, K, Processed, WasError, Removed: Integer;
      SkipPropData: Boolean;
      FLOpt: TFileListOptions;
      S: String;
begin
      LFile := TStringList.Create;
      LSource := TStringList.Create;
      LResult := TStringList.Create;
  try
    if chbxSubFolders.Checked then
      FLOpt := [flFullNames, flRecursive]
    else
      FLOpt := [flFullNames];

    if not AdvBuildFileList(IncludeTrailingBackslash(edPath.Text) + '*.DFM', faAnyFile, LFile, FLOpt) then
    begin
      MessageBox(Handle,
        'Invalid path specified. Can not process.',
        'Warning',
        MB_OK or MB_ICONEXCLAMATION);
      exit;
    end;

    Processed := 0;
    WasError := 0;

    for I := 0 to LFile.Count - 1 do
    begin
      LSource.LoadFromFile(LFile[I]);
      Removed := 0;

      for K := 0 to mPropList.Lines.Count - 1 do
      begin
        if K > 0 then
          LSource.Assign(LResult);

        if Trim(mPropList.Lines[K]) = '' then
          continue;

        LResult.Clear;
        SkipPropData := False;

        for J := 0 to LSource.Count - 1 do
        begin
          S := Trim(LSource[J]);

          if SkipPropData then
          begin
            if (S > '') and (S[Length(S)] in [')', '}']) then
              SkipPropData := False;
            continue;
          end;

          if StrIPos(mPropList.Lines[K] + ' =', S) = 0 then
          begin
            LResult.Add(LSource[J]);
            continue;
          end;

          if (S > '') and (S[Length(S)] in ['(', '{']) then
            SkipPropData := True;

          Removed := Removed + 1;
        end;
      end;

      if Removed > 0 then
      begin
        if RenameFile(LFile[I], ChangeFileExt(LFile[I], '.BAK')) then
        begin
          LResult.SaveToFile(LFile[I]);
          Processed := Processed + 1;
        end else
        begin
          MessageBox(Handle,
            PChar('Can not create back up copy for file: ' + LFile[I] + #13#10'File is not processed.'),
            'Warning',
            MB_OK or MB_ICONEXCLAMATION);
          WasError := WasError + 1;
        end;
      end;
    end;

    MessageBox(Handle,
      PChar(Format('Total files found: %d'#13#10'Properties were removed from: %d'#13#10'Error files: %d',
        [LFile.Count, Processed, WasError])),
      'Statistics',
      MB_OK or MB_ICONINFORMATION);
  finally
    LFile.Free;
    LSource.Free;
    LResult.Free;
  end;
end;
User421
  • 25
  • 8
  • Check that the strings match exactly, not just that the property name contains the input...? – underscore_d Jun 19 '20 at 14:12
  • Show what you tried and explain how it didn't work, please. – underscore_d Jun 19 '20 at 14:16
  • @underscore_d I have added my trial code – User421 Jun 19 '20 at 14:26
  • Right, so your `mPropList.Lines` each contain something like `Prop = foo` or `SecondProp = bar`. Does the property name always start the line? And what is `LResult`? The lines that should be kept? Then you don't want to add to that if the strings match, but if they _don't_. Putting these together, you want to do `LResult.Add()` only if `StrIPos(...) <> 1`, don't you? That way, you add lines that don't contain the property (`0`, i.e. `<1`) and those that contain it as a substring but not at the beginning (`>1`). – underscore_d Jun 19 '20 at 14:54
  • MPropList.Lines contains only property name and not value because values can be different, eg. Prop on first line , secondProp on second and so on. – User421 Jun 19 '20 at 16:17
  • so did you try comparing StrIPos() to <>1 ? – underscore_d Jun 19 '20 at 16:52
  • @underscore_d yes, it worked! Thank you – User421 Jun 22 '20 at 13:32
  • Great! You're welcome. I posted it as an answer with a slightly better explanation. Accepting/upvoting would be welcomed ;-) – underscore_d Jun 22 '20 at 14:49

1 Answers1

1

We established that:

  • Your mPropList.Lines each contain something like Prop =[...] or SecondProp =[...], and the property name always starts the line.
  • LResult holds the lines that should be kept. So, you don't want to add to that if the strings match, but you do if they don't.

Putting these together, you want to do LResult.Add() only if StrIPos(...) <> 1. That way, you add

  • lines that don't contain the property name (StrIPos() == 0, i.e. < 1) and
  • lines that contain it as a substring but not at the start, i.e. only within another property name (StrIPos > 1).

The fixed code will thus look like:

if StrIPos(mPropList.Lines[K] + ' =', S) <> 1 then
  begin
    LResult.Add(LSource[J]);
    continue;
  end;
underscore_d
  • 6,309
  • 3
  • 38
  • 64