diff --git a/Source/CoverageConfiguration.pas b/Source/CoverageConfiguration.pas index c9a84a6..667325e 100644 --- a/Source/CoverageConfiguration.pas +++ b/Source/CoverageConfiguration.pas @@ -59,7 +59,9 @@ TCoverageConfiguration = class(TInterfacedObject, ICoverageConfiguration) procedure ParseSwitch(var AParameter: Integer); procedure ParseBooleanSwitches; function GetCurrentConfig(const Project: IXMLNode): string; + function GetBasePropertyGroupNode(const Project: IXMLNode): IXMLNode; function GetExeOutputFromDProj(const Project: IXMLNode; const ProjectName: TFileName): string; + function GetSourceDirsFromDProj(const Project: IXMLNode): string; procedure ParseDProj(const DProjFilename: TFileName); function IsPathInExclusionList(const APath: TFileName): Boolean; procedure ExcludeSourcePaths; @@ -896,13 +898,45 @@ function TCoverageConfiguration.GetCurrentConfig(const Project: IXMLNode): strin end; end; +function TCoverageConfiguration.GetBasePropertyGroupNode(const Project: IXMLNode): IXMLNode; +var + GroupIndex: Integer; +begin + Assert(Assigned(Project)); + for GroupIndex := 0 to Project.ChildNodes.Count - 1 do + begin + Result := Project.ChildNodes.Get(GroupIndex); + if (Result.LocalName = 'PropertyGroup') + and Result.HasAttribute('Condition') + and ( + (Result.Attributes['Condition'] = '''$(Base)''!=''''') + or (Result.Attributes['Condition'] = '''$(Basis)''!=''''') + ) then + Exit; + end; + Result := nil; +end; + +function TCoverageConfiguration.GetSourceDirsFromDProj(const Project: IXMLNode): string; +var + Node: IXMLNode; +begin + Result := ''; + Assert(Assigned(Project)); + + Node := GetBasePropertyGroupNode(Project); + if Node = nil then Exit; + Node := Node.ChildNodes.FindNode('DCC_UnitSearchPath'); + if Node = nil then Exit; + Result := StringReplace(Node.Text, '$(DCC_UnitSearchPath)', '', [rfReplaceAll, rfIgnoreCase]); +end; + function TCoverageConfiguration.GetExeOutputFromDProj(const Project: IXMLNode; const ProjectName: TFileName): string; var CurrentConfig: string; CurrentPlatform: string; DCC_ExeOutputNode: IXMLNode; DCC_ExeOutput: string; - GroupIndex: Integer; Node: IXMLNode; begin Result := ''; @@ -915,15 +949,8 @@ function TCoverageConfiguration.GetExeOutputFromDProj(const Project: IXMLNode; c CurrentPlatform := 'Win32'; {$ENDIF} - for GroupIndex := 0 to Project.ChildNodes.Count - 1 do - begin - Node := Project.ChildNodes.Get(GroupIndex); - if (Node.LocalName = 'PropertyGroup') - and Node.HasAttribute('Condition') - and ( - (Node.Attributes['Condition'] = '''$(Base)''!=''''') - or (Node.Attributes['Condition'] = '''$(Basis)''!=''''') - ) then + Node := GetBasePropertyGroupNode(Project); + if Node <> nil then begin if CurrentConfig <> '' then begin @@ -939,7 +966,6 @@ function TCoverageConfiguration.GetExeOutputFromDProj(const Project: IXMLNode; c Result := ChangeFileExt(ProjectName, '.exe'); end; end; - end; end; procedure TCoverageConfiguration.ParseDProj(const DProjFilename: TFileName); @@ -948,7 +974,7 @@ procedure TCoverageConfiguration.ParseDProj(const DProjFilename: TFileName); ItemGroup: IXMLNode; Node: IXMLNode; Project: IXMLNode; - Unitname: string; + Unitname, Path, SearchPaths: string; I: Integer; RootPath: TFileName; SourcePath: TFileName; @@ -969,6 +995,18 @@ procedure TCoverageConfiguration.ParseDProj(const DProjFilename: TFileName); FMapFileName := ChangeFileExt(FExeFileName, '.map'); end; + SearchPaths := GetSourceDirsFromDProj(Project); + if SearchPaths <> '' then + begin + for Path in SearchPaths.Split([';']) do + if Path <> '' then + begin + SourcePath := TPath.GetFullPath(TPath.Combine(RootPath, Path)); + if FSourcePathLst.IndexOf(SourcePath) = -1 then + FSourcePathLst.Add(SourcePath); + end; + end; + ItemGroup := Project.ChildNodes.FindNode('ItemGroup'); if ItemGroup <> nil then begin diff --git a/Test/CoverageConfigurationTest.pas b/Test/CoverageConfigurationTest.pas index 8914c41..e1e1160 100644 --- a/Test/CoverageConfigurationTest.pas +++ b/Test/CoverageConfigurationTest.pas @@ -1470,6 +1470,7 @@ procedure TCoverageConfigurationTest.TestDProj; LCoverageConfiguration : ICoverageConfiguration; I : Integer; ExpectedExeName : TFileName; + ExpectedSourcePath : TFileName; PlatformName : string; begin LExeName := RandomFileName(); @@ -1483,6 +1484,7 @@ procedure TCoverageConfigurationTest.TestDProj; LDProj.Add(''); LDProj.Add(''); LDProj.Add('..\build\$(PLATFORM)'); + LDProj.Add('..\src\;$(DCC_UnitSearchPath)'); LDProj.Add(''); LTotalUnitList := TStringList.Create; @@ -1516,6 +1518,8 @@ procedure TCoverageConfigurationTest.TestDProj; ExpectedExeName := TPath.GetDirectoryName(GetCurrentDir()) + '\build\' + PlatformName + '\' + LExeName; CheckEquals(ChangeFileExt(ExpectedExeName, '.exe'), LCoverageConfiguration.ExeFileName, 'Incorrect executable listed'); CheckEquals(ChangeFileExt(ExpectedExeName, '.map'), LCoverageConfiguration.MapFileName, 'Incorrect map file name'); + ExpectedSourcePath := TPath.GetFullPath(TPath.Combine(TPath.GetDirectoryName(LDProjName), '..\src\')); + CheckTrue(LCoverageConfiguration.SourcePaths.IndexOf(ExpectedSourcePath) <> -1, 'Incorrect SourcePaths'); for I := 0 to Pred(LTotalUnitList.Count) do CheckNotEquals(-1, LCoverageConfiguration.Units.IndexOf(LTotalUnitList[I]), 'Missing unit name');