unit TestDbgConfig; {$mode objfpc}{$H+} (* fpclist.txt contains lines of format: [Name] exe=/path/fpc.exe symbols=none,gs,gw,gwset,gw3 optional gdblist.txt contains lines of format: [Name] exe=/path/fpc.exe version=070201 symbols=none,gs,gw,gwset,gw3 *) interface uses Classes, SysUtils, LazStringUtils; var AppDir, ConfDir: String; type TSymbolType = (stNone, stStabs, stDwarf, stDwarfSet, stDwarf3, stDwarf4); TSymbolTypes = set of TSymbolType; TCpuBitType = (cpu32, cpu64); TCpuBitTypes = set of TCpuBitType; const SymbolTypeNames: Array [TSymbolType] of String = ('No_Dbg', 'Stabs', 'Dwarf', 'Dwarf+Sets', 'Dwarf3', 'Dwarf4'); SymbolTypeSwitches: Array [TSymbolType] of String = ('', '-gs', '-gw', '-gw -godwarfsets', '-gw3', '-gw4'); CpuBitNames: Array [TCpuBitType] of String = ('32Bit', '64Bit'); stDwarf2 = [stDwarf, stDwarfSet]; stDwarf3Up = [stDwarf3, stDwarf4]; type TExternalExeInfo = record Name: string; Version: Integer; ExeName: string; SymbolTypes: TSymbolTypes; CpuBitTypes: TCpuBitTypes; ExtraOpts: string; CustomFlags, _CustomFlags: string; end; type { TBaseList } TBaseList = class private FList: array of TExternalExeInfo; function GetCpuBitTypes(Index: Integer): TCpuBitTypes; function GetExeName(Index: Integer): string; function GetExtraOpts(Index: Integer): string; function GetFullInfo(Index: Integer): TExternalExeInfo; function GetName(Index: Integer): string; function GetSymbolTypes(Index: Integer): TSymbolTypes; function GetVersion(Index: Integer): Integer; protected function AddName(const AName: string): Integer; procedure SetAttribute(AIndex: Integer; const AAttr, AValue: string); virtual; public procedure Add(Name, Exe: string; Opts: String = ''); procedure Add(Info: TExternalExeInfo); procedure LoadFromFile(const AFileName: string); function Count: Integer; property Name[Index: Integer]: string read GetName; property Version[Index: Integer]: Integer read GetVersion; property ExeName[Index: Integer]: string read GetExeName; property SymbolTypes[Index: Integer]: TSymbolTypes read GetSymbolTypes; property CpuBitTypes[Index: Integer]: TCpuBitTypes read GetCpuBitTypes; property ExtraOpts[Index: Integer]: string read GetExtraOpts; property FullInfo[Index: Integer]: TExternalExeInfo read GetFullInfo; end; function LoadConfig(FileName: String): TBaseList; implementation function StrToSymbolTypes(s: string): TSymbolTypes; var s2: string; begin Result := []; while (s <> '') do begin while (s <> '') and (s[1] in [' ', ',', #9, #10, #13]) do delete(s,1, 1); s2 := ''; while (s <> '') and not (s[1] in [' ', ',', #9, #10, #13]) do begin s2 := s2 + s[1]; delete(s,1, 1); end; if s2 = 'none' then Result := Result + [stNone]; if s2 = 'gs' then Result := Result + [stStabs]; if s2 = 'gw' then Result := Result + [stDwarf]; if s2 = 'gwset' then Result := Result + [stDwarfSet]; if s2 = 'gw3' then Result := Result + [stDwarf3]; if s2 = 'gw4' then Result := Result + [stDwarf4]; end; end; function StrToCpuBitTypes(s: string): TCpuBitTypes; var s2: string; begin Result := []; while (s <> '') do begin while (s <> '') and (s[1] in [' ', ',', #9, #10, #13]) do delete(s,1, 1); s2 := ''; while (s <> '') and not (s[1] in [' ', ',', #9, #10, #13]) do begin s2 := s2 + s[1]; delete(s,1, 1); end; if s2 = '32' then Result := Result + [cpu32]; if s2 = '64' then Result := Result + [cpu64]; end; end; { TBaseList } function TBaseList.GetExeName(Index: Integer): string; begin Result := FList[Index].ExeName; end; function TBaseList.GetCpuBitTypes(Index: Integer): TCpuBitTypes; begin Result := FList[Index].CpuBitTypes; end; function TBaseList.GetExtraOpts(Index: Integer): string; begin Result := FList[Index].ExtraOpts; end; function TBaseList.GetFullInfo(Index: Integer): TExternalExeInfo; begin Result := FList[Index]; end; function TBaseList.GetName(Index: Integer): string; begin Result := FList[Index].Name; end; function TBaseList.GetSymbolTypes(Index: Integer): TSymbolTypes; begin Result := FList[Index].SymbolTypes; end; function TBaseList.GetVersion(Index: Integer): Integer; begin Result := FList[Index].Version; end; function TBaseList.AddName(const AName: string): Integer; begin Result := length(FList); SetLength(FList, Result + 1); FList[Result].Name := AName; FList[Result].Version := -1; FList[Result].ExeName := ''; FList[Result].SymbolTypes := []; FList[Result].CpuBitTypes := [low(TCpuBitType)..high(TCpuBitType)]; // default: all FList[Result].ExtraOpts := ''; end; procedure TBaseList.SetAttribute(AIndex: Integer; const AAttr, AValue: string); begin case StringCase(AAttr, ['exe', 'symbols', 'opts', 'vers', 'version', 'bittype', 'bits', 'flags'], True, False) of 0: begin // exe FList[AIndex].ExeName := AValue; end; 1: begin // symbols FList[AIndex].SymbolTypes := StrToSymbolTypes(AValue); end; 2: begin //opts FList[AIndex].ExtraOpts := AValue; end; 3,4: begin FList[AIndex].Version := StrToIntDef(AValue,-1); end; 5,6: begin FList[AIndex].CpuBitTypes := StrToCpuBitTypes(AValue); end; 7: begin // flags FList[AIndex].CustomFlags := AValue; // each flag enclosed by , / ,flag1,flag2, FList[AIndex]._CustomFlags := ','+StringReplace(lowercase(AValue), ' ', '', [rfReplaceAll])+','; end; end; end; procedure TBaseList.Add(Name, Exe: string; Opts: String); var i: LongInt; begin i := AddName(Name); FList[i].ExeName := Exe; FList[i].SymbolTypes := [low(TSymbolTypes)..high(TSymbolTypes)]; FList[i].ExtraOpts := Opts; end; procedure TBaseList.Add(Info: TExternalExeInfo); var i: Integer; begin i := AddName(''); FList[i] := Info; end; procedure TBaseList.LoadFromFile(const AFileName: string); var txt: TStringList; s: string; i, j, k: Integer; begin txt := TStringList.Create; txt.LoadFromFile(AFileName); j := -1; for i := 0 to txt.Count - 1 do begin s := txt[i]; if Trim(s) = '' then continue; if copy(s, 1, 1) = '[' then begin j := AddName(GetPart(['['], [']'], s)); continue; end; if j < 0 then continue; k := pos('=', s); SetAttribute(j, copy(s, 1, k-1), copy(s, k + 1, length(s))); end; txt.Free; end; function TBaseList.Count: Integer; begin Result := length(FList); end; function LoadConfig(FileName: String): TBaseList; begin Result := TBaseList.Create; if FileExists(FileName) then Result.LoadFromFile(FileName); end; end.