Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 143 additions & 32 deletions jcl/source/common/JclCompilerUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -135,6 +143,7 @@ TJclDCC32 = class(TJclBorlandCommandLineTool)
FOnEnvironmentVariables: TJclStringsGetterFunction;
FSupportsNoConfig: Boolean;
FSupportsPlatform: Boolean;
FIgnoreConfigFiles: Boolean;
FDCCVersion: Single;
protected
procedure AddProjectOptions(const ProjectFileName, DCPPath: string);
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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 ''';
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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 := '';
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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 := '';
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;

Expand Down
26 changes: 25 additions & 1 deletion jcl/source/common/JclIDEUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down