Browse Source

Start work on splitting large Compiler.Compile.pas unit into smaller ones.

Martijn Laan 1 year ago
parent
commit
c8170bf58e
3 changed files with 324 additions and 301 deletions
  1. 2 0
      Projects/ISCmplr.dpr
  2. 2 301
      Projects/Src/Compiler.SetupCompiler.pas
  3. 320 0
      Projects/Src/Compiler.StringLists.pas

+ 2 - 0
Projects/ISCmplr.dpr

@@ -15,7 +15,9 @@ uses
   Shared.CompilerInt in 'Src\Shared.CompilerInt.pas',
   Shared.CompilerInt in 'Src\Shared.CompilerInt.pas',
   Shared.PreprocInt in 'Src\Shared.PreprocInt.pas',
   Shared.PreprocInt in 'Src\Shared.PreprocInt.pas',
   Compiler.Compile in 'Src\Compiler.Compile.pas',
   Compiler.Compile in 'Src\Compiler.Compile.pas',
+  Compiler.SetupCompiler in 'Src\Compiler.SetupCompiler.pas',
   Compiler.Messages in 'Src\Compiler.Messages.pas',
   Compiler.Messages in 'Src\Compiler.Messages.pas',
+  Compiler.StringLists in 'Src\Compiler.StringLists.pas',
   Shared.Struct in 'Src\Shared.Struct.pas',
   Shared.Struct in 'Src\Shared.Struct.pas',
   Shared.ScriptFunc in 'Src\Shared.ScriptFunc.pas',
   Shared.ScriptFunc in 'Src\Shared.ScriptFunc.pas',
   Compiler.ScriptFunc in 'Src\Compiler.ScriptFunc.pas',
   Compiler.ScriptFunc in 'Src\Compiler.ScriptFunc.pas',

+ 2 - 301
Projects/Src/Compiler.Compile.pas → Projects/Src/Compiler.SetupCompiler.pas

@@ -1,4 +1,4 @@
-unit Compiler.Compile;
+unit Compiler.SetupCompiler;
 
 
 {
 {
   Inno Setup
   Inno Setup
@@ -37,7 +37,7 @@ uses
 {$IFDEF STATICPREPROC}
 {$IFDEF STATICPREPROC}
   ISPP.Preprocess,
   ISPP.Preprocess,
 {$ENDIF}
 {$ENDIF}
-  Compiler.ScriptCompiler, SimpleExpression, Shared.SetupTypes;
+  Compiler.StringLists, Compiler.ScriptCompiler, SimpleExpression, Shared.SetupTypes;
 
 
 type
 type
   TParamInfo = record
   TParamInfo = record
@@ -81,78 +81,6 @@ type
     Mask: DWORD;
     Mask: DWORD;
   end;
   end;
 
 
-  TLowFragList = class(TList)
-  protected
-    procedure Grow; override;
-  end;
-
-  TLowFragStringList = class
-  private
-    FInternalList: TLowFragList;
-    function Get(Index: Integer): String;
-    function GetCount: Integer;
-    procedure Put(Index: Integer; const Value: String);
-  public
-    constructor Create;
-    destructor Destroy; override;
-    function Add(const S: String): Integer;
-    procedure Clear;
-    property Count: Integer read GetCount;
-    property Strings[Index: Integer]: String read Get write Put; default;
-  end;
-
-  THashStringItem = record
-    Hash: Longint;
-    Str: String;
-  end;
-
-const
-  MaxHashStringItemListSize = MaxInt div 16;
-
-type
-  PHashStringItemList = ^THashStringItemList;
-  THashStringItemList = array[0..MaxHashStringItemListSize-1] of THashStringItem;
-  THashStringList = class
-  private
-    FCapacity: Integer;
-    FCount: Integer;
-    FIgnoreDuplicates: Boolean;
-    FList: PHashStringItemList;
-    procedure Grow;
-  public
-    destructor Destroy; override;
-    function Add(const S: String): Integer;
-    function CaseInsensitiveIndexOf(const S: String): Integer;
-    procedure Clear;
-    function Get(Index: Integer): String;
-    property Count: Integer read FCount;
-    property IgnoreDuplicates: Boolean read FIgnoreDuplicates write FIgnoreDuplicates;
-    property Strings[Index: Integer]: String read Get; default;
-  end;
-
-  PScriptFileLine = ^TScriptFileLine;
-  TScriptFileLine = record
-    LineFilename: String;
-    LineNumber: Integer;
-    LineText: String;
-  end;
-
-  TScriptFileLines = class
-  private
-    FLines: TLowFragList;
-    function Get(Index: Integer): PScriptFileLine;
-    function GetCount: Integer;
-    function GetText: String;
-  public
-    constructor Create;
-    destructor Destroy; override;
-    procedure Add(const LineFilename: String; const LineNumber: Integer;
-      const LineText: String);
-    property Count: Integer read GetCount;
-    property Lines[Index: Integer]: PScriptFileLine read Get; default;
-    property Text: String read GetText;
-  end;
-
   TCheckOrInstallKind = (cikCheck, cikDirectiveCheck, cikInstall);
   TCheckOrInstallKind = (cikCheck, cikDirectiveCheck, cikInstall);
 
 
   TSetupCompiler = class
   TSetupCompiler = class
@@ -812,233 +740,6 @@ begin
   end;
   end;
 end;
 end;
 
 
-{ TLowFragList }
-
-procedure TLowFragList.Grow;
-var
-  Delta: Integer;
-begin
-  { Delphi 2's TList.Grow induces memory fragmentation big time. This is the
-    Grow code from Delphi 3 and later. }
-  if Capacity > 64 then Delta := Capacity div 4 else
-    if Capacity > 8 then Delta := 16 else
-      Delta := 4;
-  SetCapacity(Capacity + Delta);
-end;
-
-{ TLowFragStringList }
-
-constructor TLowFragStringList.Create;
-begin
-  inherited;
-  FInternalList := TLowFragList.Create;
-end;
-
-destructor TLowFragStringList.Destroy;
-begin
-  if Assigned(FInternalList) then begin
-    Clear;
-    FInternalList.Free;
-  end;
-  inherited;
-end;
-
-function TLowFragStringList.Add(const S: String): Integer;
-var
-  P: Pointer;
-begin
-  FInternalList.Expand;
-  P := nil;
-  String(P) := S;  { bump the ref count }
-  Result := FInternalList.Add(P);
-end;
-
-procedure TLowFragStringList.Clear;
-begin
-  if FInternalList.Count <> 0 then
-    Finalize(String(FInternalList.List[0]), FInternalList.Count);
-  FInternalList.Clear;
-end;
-
-function TLowFragStringList.Get(Index: Integer): String;
-begin
-  Result := String(FInternalList[Index]);
-end;
-
-function TLowFragStringList.GetCount: Integer;
-begin
-  Result := FInternalList.Count;
-end;
-
-procedure TLowFragStringList.Put(Index: Integer; const Value: String);
-begin
-  if (Index < 0) or (Index >= FInternalList.Count) then
-    raise EListError.CreateFmt('List index out of bounds (%d)', [Index]);
-  String(FInternalList.List[Index]) := Value;
-end;
-
-{ THashStringList }
-
-destructor THashStringList.Destroy;
-begin
-  Clear;
-  inherited;
-end;
-
-function THashStringList.Add(const S: String): Integer;
-var
-  LS: String;
-begin
-  if FIgnoreDuplicates and (CaseInsensitiveIndexOf(S) <> -1) then begin
-    Result := -1;
-    Exit;
-  end;
-
-  Result := FCount;
-  if Result = FCapacity then
-    Grow;
-  LS := PathLowercase(S);
-  Pointer(FList[Result].Str) := nil;  { since Grow doesn't zero init }
-  FList[Result].Str := S;
-  FList[Result].Hash := GetCRC32(Pointer(LS)^, Length(LS)*SizeOf(LS[1]));
-  Inc(FCount);
-end;
-
-procedure THashStringList.Clear;
-begin
-  if FCount > 0 then
-    Finalize(FList[0], FCount);
-  FCount := 0;
-  FCapacity := 0;
-  ReallocMem(FList, 0);
-end;
-
-function THashStringList.Get(Index: Integer): String;
-begin
-  if (Index < 0) or (Index >= FCount) then
-    raise EStringListError.CreateFmt('THashStringList: Index %d is out of bounds',
-      [Index]);
-  Result := FList[Index].Str;
-end;
-
-procedure THashStringList.Grow;
-var
-  Delta, NewCapacity: Integer;
-begin
-  if FCapacity > 64 then Delta := FCapacity div 4 else
-    if FCapacity > 8 then Delta := 16 else
-      Delta := 4;
-  NewCapacity := FCapacity + Delta;
-  if NewCapacity > MaxHashStringItemListSize then
-    raise EStringListError.Create('THashStringList: Exceeded maximum list size');
-  ReallocMem(FList, NewCapacity * SizeOf(FList[0]));
-  FCapacity := NewCapacity;
-end;
-
-function THashStringList.CaseInsensitiveIndexOf(const S: String): Integer;
-var
-  LS: String;
-  Hash: Longint;
-  I: Integer;
-begin
-  LS := PathLowercase(S);
-  Hash := GetCRC32(Pointer(LS)^, Length(LS)*SizeOf(LS[1]));
-  for I := 0 to FCount-1 do
-    if (FList[I].Hash = Hash) and (PathLowercase(FList[I].Str) = LS) then begin
-      Result := I;
-      Exit;
-    end;
-  Result := -1;
-end;
-
-{ TScriptFileLines }
-
-constructor TScriptFileLines.Create;
-begin
-  inherited;
-  FLines := TLowFragList.Create;
-end;
-
-destructor TScriptFileLines.Destroy;
-var
-  I: Integer;
-begin
-  if Assigned(FLines) then begin
-    for I := FLines.Count-1 downto 0 do
-      Dispose(PScriptFileLine(FLines[I]));
-    FLines.Free;
-  end;
-  inherited;
-end;
-
-procedure TScriptFileLines.Add(const LineFilename: String;
-  const LineNumber: Integer; const LineText: String);
-var
-  L, PrevLine: PScriptFileLine;
-begin
-  FLines.Expand;
-  New(L);
-  try
-    { Memory usage optimization: If LineFilename is equal to the previous
-      line's LineFilename, then make this line's LineFilename reference the
-      same string (i.e. just increment its refcount). }
-    PrevLine := nil;
-    if (LineFilename <> '') and (FLines.Count > 0) then
-      PrevLine := PScriptFileLine(FLines[FLines.Count-1]);
-    if Assigned(PrevLine) and (PrevLine.LineFilename = LineFilename) then
-      L.LineFilename := PrevLine.LineFilename
-    else
-      L.LineFilename := LineFilename;
-    L.LineNumber := LineNumber;
-    L.LineText := LineText;
-  except
-    Dispose(L);
-    raise;
-  end;
-  FLines.Add(L);
-end;
-
-function TScriptFileLines.Get(Index: Integer): PScriptFileLine;
-begin
-  Result := PScriptFileLine(FLines[Index]);
-end;
-
-function TScriptFileLines.GetCount: Integer;
-begin
-  Result := FLines.Count;
-end;
-
-function TScriptFileLines.GetText: String;
-var
-  I, L, Size, Count: Integer;
-  P: PChar;
-  S, LB: string;
-begin
-  Count := GetCount;
-  Size := 0;
-  LB := sLineBreak;
-  for I := 0 to Count-1 do
-    Inc(Size, Length(Get(I).LineText) + Length(LB));
-  Dec(Size, Length(LB));
-  SetString(Result, nil, Size);
-  P := Pointer(Result);
-  for I := 0 to Count-1 do begin
-    S := Get(I).LineText;
-    L := Length(S);
-    if L <> 0 then begin
-      System.Move(Pointer(S)^, P^, L * SizeOf(Char));
-      Inc(P, L);
-    end;
-    if I < Count-1 then begin
-      L := Length(LB);
-      if L <> 0 then begin
-        System.Move(Pointer(LB)^, P^, L * SizeOf(Char));
-        Inc(P, L);
-      end;
-    end;
-  end;
-end;
-
 { Built-in preprocessor }
 { Built-in preprocessor }
 
 
 type
 type

+ 320 - 0
Projects/Src/Compiler.StringLists.pas

@@ -0,0 +1,320 @@
+unit Compiler.StringLists;
+
+{
+  Inno Setup
+  Copyright (C) 1997-2024 Jordan Russell
+  Portions by Martijn Laan
+  For conditions of distribution and use, see LICENSE.TXT.
+}
+
+interface
+
+uses
+  Classes;
+
+type
+  TLowFragList = class(TList)
+  protected
+    procedure Grow; override;
+  end;
+
+  TLowFragStringList = class
+  private
+    FInternalList: TLowFragList;
+    function Get(Index: Integer): String;
+    function GetCount: Integer;
+    procedure Put(Index: Integer; const Value: String);
+  public
+    constructor Create;
+    destructor Destroy; override;
+    function Add(const S: String): Integer;
+    procedure Clear;
+    property Count: Integer read GetCount;
+    property Strings[Index: Integer]: String read Get write Put; default;
+  end;
+
+  THashStringItem = record
+    Hash: Longint;
+    Str: String;
+  end;
+
+const
+  MaxHashStringItemListSize = MaxInt div 16;
+
+type
+  PHashStringItemList = ^THashStringItemList;
+  THashStringItemList = array[0..MaxHashStringItemListSize-1] of THashStringItem;
+  THashStringList = class
+  private
+    FCapacity: Integer;
+    FCount: Integer;
+    FIgnoreDuplicates: Boolean;
+    FList: PHashStringItemList;
+    procedure Grow;
+  public
+    destructor Destroy; override;
+    function Add(const S: String): Integer;
+    function CaseInsensitiveIndexOf(const S: String): Integer;
+    procedure Clear;
+    function Get(Index: Integer): String;
+    property Count: Integer read FCount;
+    property IgnoreDuplicates: Boolean read FIgnoreDuplicates write FIgnoreDuplicates;
+    property Strings[Index: Integer]: String read Get; default;
+  end;
+
+  PScriptFileLine = ^TScriptFileLine;
+  TScriptFileLine = record
+    LineFilename: String;
+    LineNumber: Integer;
+    LineText: String;
+  end;
+
+  TScriptFileLines = class
+  private
+    FLines: TLowFragList;
+    function Get(Index: Integer): PScriptFileLine;
+    function GetCount: Integer;
+    function GetText: String;
+  public
+    constructor Create;
+    destructor Destroy; override;
+    procedure Add(const LineFilename: String; const LineNumber: Integer;
+      const LineText: String);
+    property Count: Integer read GetCount;
+    property Lines[Index: Integer]: PScriptFileLine read Get; default;
+    property Text: String read GetText;
+  end;
+
+implementation
+
+uses
+  PathFunc, Compression.Base;
+
+{ TLowFragList }
+
+procedure TLowFragList.Grow;
+var
+  Delta: Integer;
+begin
+  { Delphi 2's TList.Grow induces memory fragmentation big time. This is the
+    Grow code from Delphi 3 and later. }
+  if Capacity > 64 then Delta := Capacity div 4 else
+    if Capacity > 8 then Delta := 16 else
+      Delta := 4;
+  SetCapacity(Capacity + Delta);
+end;
+
+{ TLowFragStringList }
+
+constructor TLowFragStringList.Create;
+begin
+  inherited;
+  FInternalList := TLowFragList.Create;
+end;
+
+destructor TLowFragStringList.Destroy;
+begin
+  if Assigned(FInternalList) then begin
+    Clear;
+    FInternalList.Free;
+  end;
+  inherited;
+end;
+
+function TLowFragStringList.Add(const S: String): Integer;
+var
+  P: Pointer;
+begin
+  FInternalList.Expand;
+  P := nil;
+  String(P) := S;  { bump the ref count }
+  Result := FInternalList.Add(P);
+end;
+
+procedure TLowFragStringList.Clear;
+begin
+  if FInternalList.Count <> 0 then
+    Finalize(String(FInternalList.List[0]), FInternalList.Count);
+  FInternalList.Clear;
+end;
+
+function TLowFragStringList.Get(Index: Integer): String;
+begin
+  Result := String(FInternalList[Index]);
+end;
+
+function TLowFragStringList.GetCount: Integer;
+begin
+  Result := FInternalList.Count;
+end;
+
+procedure TLowFragStringList.Put(Index: Integer; const Value: String);
+begin
+  if (Index < 0) or (Index >= FInternalList.Count) then
+    raise EListError.CreateFmt('List index out of bounds (%d)', [Index]);
+  String(FInternalList.List[Index]) := Value;
+end;
+
+{ THashStringList }
+
+destructor THashStringList.Destroy;
+begin
+  Clear;
+  inherited;
+end;
+
+function THashStringList.Add(const S: String): Integer;
+var
+  LS: String;
+begin
+  if FIgnoreDuplicates and (CaseInsensitiveIndexOf(S) <> -1) then begin
+    Result := -1;
+    Exit;
+  end;
+
+  Result := FCount;
+  if Result = FCapacity then
+    Grow;
+  LS := PathLowercase(S);
+  Pointer(FList[Result].Str) := nil;  { since Grow doesn't zero init }
+  FList[Result].Str := S;
+  FList[Result].Hash := GetCRC32(Pointer(LS)^, Length(LS)*SizeOf(LS[1]));
+  Inc(FCount);
+end;
+
+procedure THashStringList.Clear;
+begin
+  if FCount > 0 then
+    Finalize(FList[0], FCount);
+  FCount := 0;
+  FCapacity := 0;
+  ReallocMem(FList, 0);
+end;
+
+function THashStringList.Get(Index: Integer): String;
+begin
+  if (Index < 0) or (Index >= FCount) then
+    raise EStringListError.CreateFmt('THashStringList: Index %d is out of bounds',
+      [Index]);
+  Result := FList[Index].Str;
+end;
+
+procedure THashStringList.Grow;
+var
+  Delta, NewCapacity: Integer;
+begin
+  if FCapacity > 64 then Delta := FCapacity div 4 else
+    if FCapacity > 8 then Delta := 16 else
+      Delta := 4;
+  NewCapacity := FCapacity + Delta;
+  if NewCapacity > MaxHashStringItemListSize then
+    raise EStringListError.Create('THashStringList: Exceeded maximum list size');
+  ReallocMem(FList, NewCapacity * SizeOf(FList[0]));
+  FCapacity := NewCapacity;
+end;
+
+function THashStringList.CaseInsensitiveIndexOf(const S: String): Integer;
+var
+  LS: String;
+  Hash: Longint;
+  I: Integer;
+begin
+  LS := PathLowercase(S);
+  Hash := GetCRC32(Pointer(LS)^, Length(LS)*SizeOf(LS[1]));
+  for I := 0 to FCount-1 do
+    if (FList[I].Hash = Hash) and (PathLowercase(FList[I].Str) = LS) then begin
+      Result := I;
+      Exit;
+    end;
+  Result := -1;
+end;
+
+{ TScriptFileLines }
+
+constructor TScriptFileLines.Create;
+begin
+  inherited;
+  FLines := TLowFragList.Create;
+end;
+
+destructor TScriptFileLines.Destroy;
+var
+  I: Integer;
+begin
+  if Assigned(FLines) then begin
+    for I := FLines.Count-1 downto 0 do
+      Dispose(PScriptFileLine(FLines[I]));
+    FLines.Free;
+  end;
+  inherited;
+end;
+
+procedure TScriptFileLines.Add(const LineFilename: String;
+  const LineNumber: Integer; const LineText: String);
+var
+  L, PrevLine: PScriptFileLine;
+begin
+  FLines.Expand;
+  New(L);
+  try
+    { Memory usage optimization: If LineFilename is equal to the previous
+      line's LineFilename, then make this line's LineFilename reference the
+      same string (i.e. just increment its refcount). }
+    PrevLine := nil;
+    if (LineFilename <> '') and (FLines.Count > 0) then
+      PrevLine := PScriptFileLine(FLines[FLines.Count-1]);
+    if Assigned(PrevLine) and (PrevLine.LineFilename = LineFilename) then
+      L.LineFilename := PrevLine.LineFilename
+    else
+      L.LineFilename := LineFilename;
+    L.LineNumber := LineNumber;
+    L.LineText := LineText;
+  except
+    Dispose(L);
+    raise;
+  end;
+  FLines.Add(L);
+end;
+
+function TScriptFileLines.Get(Index: Integer): PScriptFileLine;
+begin
+  Result := PScriptFileLine(FLines[Index]);
+end;
+
+function TScriptFileLines.GetCount: Integer;
+begin
+  Result := FLines.Count;
+end;
+
+function TScriptFileLines.GetText: String;
+var
+  I, L, Size, Count: Integer;
+  P: PChar;
+  S, LB: string;
+begin
+  Count := GetCount;
+  Size := 0;
+  LB := sLineBreak;
+  for I := 0 to Count-1 do
+    Inc(Size, Length(Get(I).LineText) + Length(LB));
+  Dec(Size, Length(LB));
+  SetString(Result, nil, Size);
+  P := Pointer(Result);
+  for I := 0 to Count-1 do begin
+    S := Get(I).LineText;
+    L := Length(S);
+    if L <> 0 then begin
+      System.Move(Pointer(S)^, P^, L * SizeOf(Char));
+      Inc(P, L);
+    end;
+    if I < Count-1 then begin
+      L := Length(LB);
+      if L <> 0 then begin
+        System.Move(Pointer(LB)^, P^, L * SizeOf(Char));
+        Inc(P, L);
+      end;
+    end;
+  end;
+end;
+
+end.