213 lines
7.0 KiB
ObjectPascal
213 lines
7.0 KiB
ObjectPascal
{**************************************************************************************************}
|
|
{ }
|
|
{ Delphi language Preprocessor (dpp32) }
|
|
{ }
|
|
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
|
|
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
|
|
{ License at http://www.mozilla.org/MPL/ }
|
|
{ }
|
|
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
|
|
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
|
|
{ and limitations under the License. }
|
|
{ }
|
|
{ The Original Code is Main.pas }
|
|
{ }
|
|
{ The Initial Developer of the Original Code is Andreas Hausladen }
|
|
{ Portions created by these individuals are Copyright (C) of these individuals. }
|
|
{ }
|
|
{ You may retrieve the latest version of this file at the Projects home page, located at }
|
|
{ http://www.sourceforge.net/projects/dpp32 }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
|
|
{ program arguments:
|
|
-dppCompile preprocess files and compile them with dcc/dcc32
|
|
-dppCaseInsensitive macros are case insensitive
|
|
-dppConditional macros are replaced for conditions that are true
|
|
}
|
|
unit Main;
|
|
interface
|
|
uses
|
|
{$ifdef MSWINDOWS}
|
|
Windows,
|
|
{$endif}
|
|
{$ifdef LINUX}
|
|
Libc,
|
|
{$endif}
|
|
SysUtils, Classes, dpp_PreProcess, dpp_Utils;
|
|
|
|
function EntryPoint: Integer;
|
|
|
|
implementation
|
|
const
|
|
{$ifdef MSWINDOWS}
|
|
dcc = 'dcc32.exe';
|
|
{$endif}
|
|
{$ifdef LINUX}
|
|
dcc = 'dcc';
|
|
{$endif}
|
|
|
|
var
|
|
PreProcessor: TPreProcessor;
|
|
Filename: string;
|
|
|
|
{$ifdef MSWINDOWS}
|
|
function ExecuteConsole(const Cmd: string): Integer;
|
|
var
|
|
ProcessInfo: TProcessInformation;
|
|
StartInfo: TStartupInfo;
|
|
begin
|
|
AllocConsole;
|
|
StartInfo.cb := SizeOf(StartInfo);
|
|
GetStartupInfo(StartInfo);
|
|
StartInfo.dwFlags := STARTF_USESTDHANDLES;
|
|
StartInfo.hStdOutput := GetStdHandle(STD_OUTPUT_HANDLE);
|
|
StartInfo.hStdError := GetStdHandle(STD_ERROR_HANDLE);
|
|
StartInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
|
|
if CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, StartInfo, ProcessInfo) then
|
|
begin
|
|
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
|
|
GetExitCodeProcess(ProcessInfo.hProcess, Cardinal(Result));
|
|
CloseHandle(ProcessInfo.hThread);
|
|
CloseHandle(ProcessInfo.hProcess);
|
|
end
|
|
else
|
|
RaiseLastOSError;
|
|
end;
|
|
{$endif}
|
|
{$ifdef LINUX}
|
|
function ExecuteConsole(const Cmd: string): Integer;
|
|
begin
|
|
Result := Libc.system(PChar(Cmd));
|
|
end;
|
|
{$endif}
|
|
function GetDccArgs: string;
|
|
var
|
|
i: Integer;
|
|
s: String;
|
|
begin
|
|
Result := '';
|
|
for i := 1 to ParamCount do
|
|
begin
|
|
s := ParamStr(i);
|
|
if SameText(s, '-dppCompile') or
|
|
SameText(s, '-dppCaseInsensitive') or
|
|
SameText(s, '-dppConditional') then
|
|
Continue;
|
|
if Pos(' ', s) > 0 then s := '"' + s + '"';
|
|
Result := Result + ' ' + s;
|
|
end;
|
|
Delete(Result, 1, 1);
|
|
end;
|
|
|
|
procedure SetPreProcessorParam(S: string);
|
|
var ps: Integer;
|
|
begin
|
|
// remove ""
|
|
ps := Pos('"', s);
|
|
while ps > 0 do
|
|
begin
|
|
Delete(S, ps, 1);
|
|
ps := Pos('"', S);
|
|
end;
|
|
|
|
if SameText(S, '-dppCompile') then // Preprocessor command switch
|
|
PreProcessor.CompilePrepare := True
|
|
else if SameText(S, '-dppCaseInsensitive') then // Preprocessor command switch
|
|
PreProcessor.CaseSensitive := False
|
|
else if SameText(S, '-dppConditional') then // Preprocessor command switch
|
|
PreProcessor.ConditionalParse := True
|
|
else if StartsText('-U', S) then
|
|
PreProcessor.UnitPaths := PreProcessor.UnitPaths + Copy(s, 3, MaxInt)
|
|
else if StartsText('-I', S) then
|
|
PreProcessor.IncludePaths := PreProcessor.IncludePaths + Copy(s, 3, MaxInt)
|
|
else if StartsText('-D', S) then // conditionals
|
|
PreProcessor.Conditionals.Add(Copy(s, 3, MaxInt))
|
|
else if (s[1] <> '-') and (FileExistsX(S)) then
|
|
Filename := S;
|
|
end;
|
|
|
|
procedure LoadConfigFile(const ConfigFile: string);
|
|
var
|
|
List: TStrings;
|
|
i: Integer;
|
|
begin
|
|
List := TStringList.Create;
|
|
try
|
|
List.LoadFromFile(ConfigFile);
|
|
for i := 0 to List.Count - 1 do
|
|
SetPreProcessorParam(List[i]);
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
function EntryPoint: Integer;
|
|
var
|
|
i: Integer;
|
|
ConfigFile: string;
|
|
begin
|
|
try
|
|
PreProcessor := TPreProcessor.Create(TNoVirtualFileSys.Create);
|
|
try
|
|
PreProcessor.CompilePrepare := False;
|
|
|
|
// Config file and Arguments
|
|
ConfigFile := IncludeTrailingPathDelimiter(GetCurrentDir) + ChangeFileExt(dcc, '.cfg');
|
|
if not FileExistsX(ConfigFile) then
|
|
ConfigFile := ExtractFilePath(ParamStr(0)) + ChangeFileExt(dcc, '.cfg');
|
|
|
|
if FileExistsX(ConfigFile) then
|
|
LoadConfigFile(ConfigFile);
|
|
|
|
for i := 1 to ParamCount do
|
|
SetPreProcessorParam(ParamStr(i));
|
|
|
|
|
|
// file not found -> let dcc32 handle this
|
|
if not FileExistsX(Filename) then
|
|
begin
|
|
Result := ExecuteConsole(dcc + ' ' + GetDccArgs);
|
|
Exit;
|
|
end;
|
|
|
|
// proceed
|
|
WriteLn('Delphi language Preprocessor Version ' + PreProcessorVersion);
|
|
WriteLn('Copyright (c) 2003 Andreas Hausladen');
|
|
|
|
// SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
|
|
try
|
|
if PreProcessor.BeginPreProcessing(Filename) then
|
|
begin
|
|
try
|
|
if PreProcessor.CompilePrepare then
|
|
begin
|
|
WriteLn;
|
|
Result := ExecuteConsole(dcc + ' -DPREPROCESSOR ' + GetDccArgs)
|
|
end
|
|
else
|
|
Result := 0;
|
|
finally
|
|
PreProcessor.EndPreProcessing;
|
|
end;
|
|
end
|
|
else
|
|
Result := 1;
|
|
finally
|
|
// SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS);
|
|
end;
|
|
finally
|
|
PreProcessor.Free;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
WriteLn(ErrOutput, E.Message);
|
|
Result := 1;
|
|
end;
|
|
end;
|
|
// if Result <> 0 then ReadLn;
|
|
end;
|
|
|
|
end.
|