diff --git a/jcl/source/common/JclCompilerUtils.pas b/jcl/source/common/JclCompilerUtils.pas index 2f9c052f78..1c4a8bcb90 100644 --- a/jcl/source/common/JclCompilerUtils.pas +++ b/jcl/source/common/JclCompilerUtils.pas @@ -59,6 +59,8 @@ EJclCompilerUtilsException = class(EJclError); TJclCompilerSettingsFormat = (csfDOF, csfBDSProj, csfMsBuild); + + TJclOnBeforeRunCommandLineTool = procedure (var ExeName, CommandLine:string; var DoExecute:Boolean) of object; TJclBorlandCommandLineTool = class; TJclBorlandCommandLineToolEvent = procedure(Sender:TJclBorlandCommandLineTool) of object; @@ -72,11 +74,16 @@ TJclBorlandCommandLineTool = class(TInterfacedObject, IJclCommandLineTool) FOutput: string; FOnAfterExecute: TJclBorlandCommandLineToolEvent; FOnBeforeExecute: TJclBorlandCommandLineToolEvent; + FOnBeforeRun: TJclOnBeforeRunCommandLineTool; procedure OemTextHandler(const Text: string); protected procedure CheckOutputValid; function GetFileName: string; function InternalExecute(const CommandLine: string): Boolean; + + function InternalNeedToUseOem: Boolean; + function InternalAnsiToOemIfNeeded(const aText: string): string; + function InternalOemToAnsiIfNeeded(const aText: string): string; public constructor Create(const ABinDirectory: string; ALongPathBug: Boolean; ACompilerSettingsFormat: TJclCompilerSettingsFormat); @@ -100,6 +107,7 @@ TJclBorlandCommandLineTool = class(TInterfacedObject, IJclCommandLineTool) property FileName: string read GetFileName; property OnAfterExecute: TJclBorlandCommandLineToolEvent read FOnAfterExecute write FOnAfterExecute; property OnBeforeExecute: TJclBorlandCommandLineToolEvent read FOnBeforeExecute write FOnBeforeExecute; + property OnBeforeRun: TJclOnBeforeRunCommandLineTool read FOnBeforeRun write FOnBeforeRun; end; TJclBCC32 = class(TJclBorlandCommandLineTool) @@ -135,6 +143,7 @@ TJclDCC32 = class(TJclBorlandCommandLineTool) FOnEnvironmentVariables: TJclStringsGetterFunction; FSupportsNoConfig: Boolean; FSupportsPlatform: Boolean; + FIgnoreConfigFiles: Boolean; FDCCVersion: Single; protected procedure AddProjectOptions(const ProjectFileName, DCPPath: string); @@ -151,11 +160,9 @@ TJclDCC32 = class(TJclBorlandCommandLineTool) function MakeProject(const ProjectName, OutputDir, DcpSearchPath: string; ExtraOptions: string = ''; ADebug: Boolean = False): Boolean; procedure SetDefaultOptions(ADebug: Boolean); virtual; - function AddBDSProjOptions(const ProjectFileName: string; var ProjectOptions: TProjectOptions): Boolean; - function AddDOFOptions(const ProjectFileName: string; var ProjectOptions: TProjectOptions): Boolean; - function AddDProjOptions(const ProjectFileName: string; var ProjectOptions: TProjectOptions): Boolean; property CppSearchPath: string read FCppSearchPath; property DCPSearchPath: string read FDCPSearchPath; + property IgnoreConfigFiles: Boolean read FIgnoreConfigFiles write FIgnoreConfigFiles; property LibrarySearchPath: string read FLibrarySearchPath; property LibraryDebugSearchPath: string read FLibraryDebugSearchPath; property OnEnvironmentVariables: TJclStringsGetterFunction read FOnEnvironmentVariables write FOnEnvironmentVariables; @@ -176,6 +183,26 @@ TJclDCCOSX32 = class(TJclDCC32) function GetExeName: string; override; end; + TJclProjectOptionsReader = class + private + FDcc32: TJclDCC32; + public + function AddBDSProjOptions(const ProjectFileName: string; var ProjectOptions: + TProjectOptions): Boolean; + function AddDOFOptions(const ProjectFileName: string; var ProjectOptions: + TProjectOptions): Boolean; + function AddDProjOptions(const ProjectFileName: string; var ProjectOptions: + TProjectOptions): Boolean; + + function LoadProjOptionsFromDProjFile(const OptionsFileName: string; var + ProjectOptions: TProjectOptions): Boolean; + + function ReadOptions(const ProjectFileName: string; var ProjectOptions: + TProjectOptions): Boolean; + + constructor Create(const aDcc32: TJclDCC32); virtual; + end; + {$IFDEF MSWINDOWS} TJclDCCIL = class(TJclDCC32) private @@ -301,14 +328,21 @@ implementation BDSProjDirectoriesNodeName = 'Directories'; // DProj options + DProjProjectExtensionsNodeName = 'ProjectExtensions'; DProjPersonalityNodeName = 'Borland.Personality'; DProjDelphiPersonalityValue = 'Delphi.Personality'; DProjDelphiDotNetPersonalityValue = 'DelphiDotNet.Personality'; + DProjPropertyGroupNodeName = 'PropertyGroup'; + DProjConditionValueName = 'Condition'; DProjUsePackageNodeName = 'DCC_UsePackage'; DProjDcuOutputDirNodeName = 'DCC_DcuOutput'; DProjUnitSearchPathNodeName = 'DCC_UnitSearchPath'; DProjDefineNodeName = 'DCC_Define'; DProjNamespaceNodeName = 'DCC_Namespace'; + DProjConfigurationNodeName = 'Configuration'; + DProjPlatformNodeName = 'Platform'; + DProjProjectVersionNodeName = 'ProjectVersion'; + DProjConfigNodeName = 'Config'; DelphiLibSuffixOption = '{$LIBSUFFIX '''; DelphiDescriptionOption = '{$DESCRIPTION '''; @@ -775,12 +809,35 @@ function TJclBorlandCommandLineTool.GetOutputCallback: TTextHandler; Result := FOutputCallback; end; +function TJclBorlandCommandLineTool.InternalAnsiToOemIfNeeded(const aText: string): string; +begin + if InternalNeedToUseOem then + Result := StrAnsiToOem(AnsiString(aText)) + else + Result := aText; +end; + function TJclBorlandCommandLineTool.InternalExecute( const CommandLine: string): Boolean; var LaunchCommand: string; + tmpDoExecute: Boolean; + tmpFileName, tmpCommandLine: string; begin - LaunchCommand := Format('%s %s', [FileName, StrAnsiToOem(AnsiString(CommandLine))]); + tmpDoExecute := True; + tmpFileName := FileName; + tmpCommandLine := CommandLine; + if Assigned(FOnBeforeRun) then + FOnBeforeRun(tmpFileName, tmpCommandLine, tmpDoExecute); + + if not tmpDoExecute then + begin + Result := False; + exit; + end; + + tmpCommandLine := InternalAnsiToOemIfNeeded(tmpCommandLine); + LaunchCommand := Format('%s %s', [tmpFileName, tmpCommandLine]); if Assigned(FOutputCallback) then begin OemTextHandler(LaunchCommand); @@ -790,30 +847,48 @@ function TJclBorlandCommandLineTool.InternalExecute( begin Result := JclSysUtils.Execute(LaunchCommand, FOutput) = 0; {$IFDEF MSWINDOWS} - FOutput := string(StrOemToAnsi(AnsiString(FOutput))); + FOutput := InternalOemToAnsiIfNeeded(FOutput); {$ENDIF MSWINDOWS} end; end; -procedure TJclBorlandCommandLineTool.OemTextHandler(const Text: string); -var - AnsiText: string; +function TJclBorlandCommandLineTool.InternalNeedToUseOem: Boolean; begin - if Assigned(FOutputCallback) then + { TODO : Probably D2007 also may have MsBuild format } + result := CompilerSettingsFormat <> csfMsBuild; +end; + +function TJclBorlandCommandLineTool.InternalOemToAnsiIfNeeded(const aText: string): string; +begin + {$IFDEF MSWINDOWS} + if InternalNeedToUseOem then begin - {$IFDEF MSWINDOWS} // Text is OEM under Windows // Code below seems to crash older compilers at times, so we only do // the casts when it's absolutely necessary, that is when compiling // with a unicode compiler. {$IFDEF UNICODE} - AnsiText := string(StrOemToAnsi(AnsiString(Text))); + Result := string(StrOemToAnsi(AnsiString(aText))); {$ELSE} - AnsiText := StrOemToAnsi(Text); + Result := StrOemToAnsi(aText); {$ENDIF UNICODE} - {$ELSE ~MSWINDOWS} - AnsiText := Text; - {$ENDIF ~MSWINDOWS} + end + else + begin + Result := aText; + end; + {$ELSE ~MSWINDOWS} + Result := aText; + {$ENDIF ~MSWINDOWS} +end; + +procedure TJclBorlandCommandLineTool.OemTextHandler(const Text: string); +var + AnsiText: string; +begin + if Assigned(FOutputCallback) then + begin + AnsiText := InternalOemToAnsiIfNeeded(Text); FOutputCallback(AnsiText); end; end; @@ -847,27 +922,38 @@ class function TJclBCC64.GetPlatform: string; Result := BDSPlatformWin64; end; -//=== { TJclDCC32 } ============================================================ +//=== { TJclProjectOptionsReader } ============================================================ + +function TJclProjectOptionsReader.AddDProjOptions(const ProjectFileName: string; + var ProjectOptions: TProjectOptions): Boolean; +var + DProjFileName: string; +begin + DProjFileName := ChangeFileExt(ProjectFileName, SourceExtensionDProject); + Result := FileExists(DProjFileName) and (FDcc32.CompilerSettingsFormat = csfMsBuild); + if Result then + Result := LoadProjOptionsFromDProjFile(DProjFileName, ProjectOptions); +end; -function TJclDCC32.AddDProjOptions(const ProjectFileName: string; var ProjectOptions: TProjectOptions): Boolean; +function TJclProjectOptionsReader.LoadProjOptionsFromDProjFile(const OptionsFileName: + string; var ProjectOptions: TProjectOptions): Boolean; var DProjFileName, PersonalityName: string; MsBuildOptions: TJclMsBuildParser; ProjectExtensionsNode, PersonalityNode: TJclSimpleXMLElem; begin - DProjFileName := ChangeFileExt(ProjectFileName, SourceExtensionDProject); - Result := FileExists(DProjFileName) and (CompilerSettingsFormat = csfMsBuild); - if Result then - begin - MsBuildOptions := TJclMsBuildParser.Create(DProjFileName); + //Version := ''; + Result := FileExists(OptionsFileName); + MsBuildOptions := TJclMsBuildParser.Create(OptionsFileName); try MsBuildOptions.Init; - if SupportsPlatform then - MsBuildOptions.Properties.GlobalProperties.Values['Platform'] := GetPlatform; + if FDcc32.SupportsPlatform then + MsBuildOptions.Properties.GlobalProperties.Values['Platform'] := FDcc32.GetPlatform; - if Assigned(FOnEnvironmentVariables) then - MsBuildOptions.Properties.EnvironmentProperties.Assign(FOnEnvironmentVariables); + if Assigned(FDcc32.OnEnvironmentVariables) then + MsBuildOptions.Properties.EnvironmentProperties.Assign(FDcc32.OnEnvironmentVariables); + // active configuration is used here MsBuildOptions.Parse; PersonalityName := ''; @@ -891,10 +977,12 @@ function TJclDCC32.AddDProjOptions(const ProjectFileName: string; var ProjectOpt finally MsBuildOptions.Free; end; - end; + end; -function TJclDCC32.AddBDSProjOptions(const ProjectFileName: string; var ProjectOptions: TProjectOptions): Boolean; + +function TJclProjectOptionsReader.AddBDSProjOptions(const ProjectFileName: + string; var ProjectOptions: TProjectOptions): Boolean; var BDSProjFileName, PersonalityName: string; OptionsXmlFile: TJclSimpleXML; @@ -971,7 +1059,8 @@ function TJclDCC32.AddBDSProjOptions(const ProjectFileName: string; var ProjectO end; end; -function TJclDCC32.AddDOFOptions(const ProjectFileName: string; var ProjectOptions: TProjectOptions): Boolean; +function TJclProjectOptionsReader.AddDOFOptions(const ProjectFileName: string; + var ProjectOptions: TProjectOptions): Boolean; var DOFFileName: string; OptionsFile: TIniFile; @@ -994,9 +1083,24 @@ function TJclDCC32.AddDOFOptions(const ProjectFileName: string; var ProjectOptio end; end; + +constructor TJclProjectOptionsReader.Create(const aDcc32: TJclDCC32); +begin + FDcc32 := aDcc32; +end; + +function TJclProjectOptionsReader.ReadOptions(const ProjectFileName: string; + var ProjectOptions: TProjectOptions): Boolean; +begin + Result := AddDProjOptions(ProjectFileName, ProjectOptions) or + AddBDSProjOptions(ProjectFileName, ProjectOptions) or + AddDOFOptions(ProjectFileName, ProjectOptions); +end; + procedure TJclDCC32.AddProjectOptions(const ProjectFileName, DCPPath: string); var ProjectOptions: TProjectOptions; + tmpOptionsReader: TJclProjectOptionsReader; begin ProjectOptions.UsePackages := False; ProjectOptions.UnitOutputDir := ''; @@ -1006,9 +1110,12 @@ procedure TJclDCC32.AddProjectOptions(const ProjectFileName, DCPPath: string); ProjectOptions.Conditionals := ''; ProjectOptions.Namespace := ''; - if AddDProjOptions(ProjectFileName, ProjectOptions) or - AddBDSProjOptions(ProjectFileName, ProjectOptions) or - AddDOFOptions(ProjectFileName, ProjectOptions) then + if FIgnoreConfigFiles then + exit; + + tmpOptionsReader := TJclProjectOptionsReader.Create(self); + try + if tmpOptionsReader.ReadOptions(ProjectFileName, ProjectOptions) then begin if ProjectOptions.UnitOutputDir <> '' then begin @@ -1034,6 +1141,9 @@ procedure TJclDCC32.AddProjectOptions(const ProjectFileName, DCPPath: string); if ProjectOptions.Namespace <> '' then Options.Add('-ns' + ProjectOptions.Namespace); end; + finally + tmpOptionsReader.Free; + end; end; function TJclDCC32.Compile(const ProjectFileName: string): Boolean; @@ -1056,6 +1166,7 @@ constructor TJclDCC32.Create(const ABinDirectory: string; ALongPathBug: Boolean; FLibrarySearchPath := ALibrarySearchPath; FLibraryDebugSearchPath := ALibraryDebugSearchPath; FCppSearchPath := ACppSearchPath; + FIgnoreConfigFiles := False; SetDefaultOptions(False); // in case $(DELPHI)\bin\dcc32.cfg (replace as appropriate) is invalid end; diff --git a/jcl/source/common/JclIDEUtils.pas b/jcl/source/common/JclIDEUtils.pas index 7dd241275b..4d5ae2701b 100644 --- a/jcl/source/common/JclIDEUtils.pas +++ b/jcl/source/common/JclIDEUtils.pas @@ -246,6 +246,7 @@ TJclBorRADToolIdePackages = class(TJclBorRADToolInstallationObject) function GetPackageFileNames(Index: Integer): string; function GetIDEPackageFileNames(Index: Integer): string; function GetExpertFileNames(Index: Integer): string; + procedure SetPackageDisabledEnabled(aIndex: integer; aEnabled: Boolean); protected function PackageEntryToFileName(const Entry: string): string; procedure ReadPackages; @@ -268,7 +269,7 @@ TJclBorRADToolIdePackages = class(TJclBorRADToolInstallationObject) property PackageFileNames[Index: Integer]: string read GetPackageFileNames; property IDEPackageFileNames[Index: Integer]: string read GetIDEPackageFileNames; property ExpertFileNames[Index: Integer]: string read GetExpertFileNames; - property PackageDisabled[Index: Integer]: Boolean read GetPackageDisabled; + property PackageDisabled[Index: Integer]: Boolean read GetPackageDisabled write SetPackageDisabledEnabled; end; TJclBorRADToolPalette = class(TJclBorRADToolInstallationObject) @@ -1408,6 +1409,29 @@ function TJclBorRADToolIdePackages.RemovePackage(const FileName: string): Boolea end; end; +procedure TJclBorRADToolIdePackages.SetPackageDisabledEnabled(aIndex: integer; aEnabled: Boolean); +const + cNonExistingValue = '?;)'; +var + tmpPackageName: string; + tmpPackageData: string; +begin + tmpPackageName := FKnownPackages.Names[aIndex]; + tmpPackageData := Installation.ConfigData.ReadString(KnownPackagesKeyName, tmpPackageName, cNonExistingValue); + if tmpPackageData<>cNonExistingValue then + begin + if aEnabled then + begin + Installation.ConfigData.WriteString(DisabledPackagesKeyName, tmpPackageName, tmpPackageData); + end + else + begin + Installation.ConfigData.DeleteKey(DisabledPackagesKeyName, tmpPackageName); + end; + ReadPackages; + end; +end; + function TJclBorRADToolIdePackages.RemoveIDEPackage(const FileName: string): Boolean; var I: Integer;