Processing Command-Line Parameters |
This procedure processes command line parameters and sets compiler flags and data accordingly.
Procedure ProcessCompilerParameters; Function CommaIsIntegerNumericConstant (Var ChrPtr: PChar): Boolean; begin If ChrPtr [0] = ',' then Inc (ChrPtr); CommaIsIntegerNumericConstant := IsIntegerNumericConstant (ChrPtr); end; Function IsSegment (Var ChrPtr: PChar): Boolean; begin IsSegment := False; If CommaIsIntegerNumericConstant (ChrPtr) then begin If IntegerNumericConstantRec.WordH = $FFFF then If IntegerNumericConstantRec.WordL > $FFF0 then Exit; IntegerNumericConstant := (IntegerNumericConstant + $F) shr 4; IsSegment := IntegerNumericConstantRec.WordH = 0; end; end; Procedure AddNameToList (List, Name: PChar); begin If (List^ = #0) or (Name^ = #0) then StrCopy (List, Name) else If StrLen (List) + StrLen (Name) <= 126 then begin List := StrEnd (List); List^ := ';'; StrCopy (List + 1, Name); end; end; Procedure ProcessCommandLineCompilerDirectives (Var ChrPtr: PChar); Procedure ProcessSwitch (Switch: TCompilerSwitches); begin Inc (ChrPtr); With GlobalModuleData^ do begin Case ChrPtr [0] of '+': Include (CompilerSwitches, Switch); '-': Exclude (CompilerSwitches, Switch); else CmdErr := True; end; end; end; begin CmdErr := False; Repeat Inc (ChrPtr); Case Upcase (ChrPtr [0]) of 'A': ProcessSwitch (WordAlignment); 'B': ProcessSwitch (FullBooleanEval); 'D': ProcessSwitch (DebugInformation); 'E': ProcessSwitch (Emulation80x87); 'F': ProcessSwitch (ForceFarCalls); 'G': ProcessSwitch (Instructions80286); 'I': ProcessSwitch (IOErrorChecking); 'K': ProcessSwitch (CompilerDirective_K); 'L': ProcessSwitch (LocalDebugSymbols); 'M': begin CmdErr := True; Inc (ChrPtr); If CommaIsIntegerNumericConstant (ChrPtr) then If IntegerNumericConstantRec.WordH = 0 then begin IntegerNumericConstantRec.WordL := IntegerNumericConstantRec.WordL and $FFFE; If (IntegerNumericConstantRec.WordL >= $0400) and (IntegerNumericConstantRec.WordL <= $FFF0) then begin GlobalModuleData^.Stack := IntegerNumericConstantRec.WordL; If IsSegment (ChrPtr) then If IntegerNumericConstantRec.WordL <= $A000 then begin GlobalModuleData^.HeapMin := IntegerNumericConstantRec.WordL; If IsSegment (ChrPtr) then If IntegerNumericConstantRec.WordL >= ModuleHeapMin then If IntegerNumericConstantRec.WordL <= $A000 then begin GlobalModuleData^.HeapMax := IntegerNumericConstantRec.WordL; CmdErr := False; end; end; end; end; end; 'N': ProcessSwitch (Instructions80x87); 'O': ProcessSwitch (OverlaysAllowed); 'P': ProcessSwitch (OpenStringParams); 'Q': ProcessSwitch (OverflowChecking); 'R': ProcessSwitch (RangeChecking); 'S': ProcessSwitch (StackChecking); 'T': ProcessSwitch (TypedPointers); 'V': ProcessSwitch (StrictVarStrings); 'W': ProcessSwitch (CompilerDirective_W); 'X': ProcessSwitch (ExtendedSyntax); 'Y': ProcessSwitch (CompilerDirective_Y); else CmdErr := True; end; If CmdErr then Exit; Inc (ChrPtr); until ChrPtr [0] <> ','; end; begin ReadParameter; While TempStr [0] <> #0 do begin CmdErr := False; Case TempStr [0] of '/', '-': Case TempStr [1] of 'B': CompilerModeOptions := [cmoCreateExeFile, cmoCompileToDisk, cmoSearchForUnitSource]; 'D': AddNameToList (InitialConditionalDefines, TempStr + 2); 'E': StrCopy (EXE_TPU_Directory, TempStr + 2); 'F': begin CmdErr := True; CompilerModeOptions := [cmoCreateExeFile, cmoFindError]; Inc (TempStr, 2); If IsHexConstant (TempStr) then begin FindErrorAddress.Seg := IntegerNumericConstantRec.WordL; If TempStr [0] = ':' then begin Inc (TempStr); If IsHexConstant (TempStr) then begin CmdErr := False; FindErrorAddress.Ofs := IntegerNumericConstantRec.WordL; end; end; end; end; 'G': begin LinkerOptions := LinkerOptions - [MapFileWithSegments, MapFileWithPublics]; Case TempStr [2] of 'S': LinkerOptions := LinkerOptions + [MapFileWithSegments]; 'P': LinkerOptions := LinkerOptions + [MapFileWithPublics]; 'D': LinkerOptions := LinkerOptions + [MapFileWithSegments, MapFileWithPublics]; else CmdErr := True; end; end; 'I': AddNameToList (IncludeDirectories, TempStr + 2); 'L': LinkerOptions := LinkerOptions + [LinkBufferOnDisk]; 'M': CompilerModeOptions := [cmoCreateExeFile, cmoCompileToDisk, cmoSearchForUnitSource, cmoMakeModifiedUnitsOnly]; 'O': AddNameToList (ObjectsDirectories, TempStr + 2); 'Q': QuietCompile := True; 'T': AddNameToList (TPL_CFG_Directories, TempStr + 2); 'U': AddNameToList (UnitDirectories, TempStr + 2); 'V': LinkerOptions := LinkerOptions + [DebugInformationInExe]; '$': begin Inc (TempStr); ProcessCommandLineCompilerDirectives (TempStr); end; '#': else CmdErr := True; end; else StrCopy (MainFileName, TempStr); end; If CmdErr then begin Writeln ('Invalid command line option: "', TempStrBuff, '"'); Halt (1); end; ReadParameter; end; If MainFileName [0] = #0 then begin WriteSyntax; Halt (0); end; end; This procedure reads first configuration file stored in FileBuffer (CfgPtr points to it) and then command line parameters (CmdPtr) and stores the parameter in TempStr.
Procedure ReadParameter; Var Ch: Char; Function NextParameterChar: Char; begin If CfgPtr [0] <> #0 then NextParameterChar := CfgPtr [0] else NextParameterChar := CmdPtr [0]; end; Procedure IncParameterCharPtr; begin If CfgPtr [0] <> #0 then Inc (CfgPtr) else Inc (CmdPtr); end; Procedure StoreParameterChar (C: Char); begin If TempStrPtr - TempStr >= 127 then Exit; TempStrPtr^ := C; Inc (TempStrPtr); end; begin TempStrPtr := TempStr; Ch := NextParameterChar; While Ch <> #0 do begin If Ch > ' ' then begin IncParameterCharPtr; If Ch = '"' then Repeat Ch := NextParameterChar; If Ch <> #0 then begin IncParameterCharPtr; If Ch <> '"' then StoreParameterChar (Ch); end; until (Ch = '"') or (Ch = #0) else StoreParameterChar (UpCase (Ch)); If Ch = #0 then Break; Ch := NextParameterChar; If (Ch <= ' ') or (Ch = '/') then Break; end else begin IncParameterCharPtr; Ch := NextParameterChar; end; end; TempStrPtr^ := #0; end; This procedure checks and extracts directory for Turbo Pascal Library (TPL file) and Turbo Pascal configuration file (CFG).
Procedure Get_TPL_CFG_Directory; Var TempCmdStr: Pchar; N, I: Byte; begin TempCmdStr := CmdPtr; ReadParameter; If (TempStr [0] in ['/', '-']) and (TempStr [1] = 'T') then StrCopy (TPL_CFG_Directories, TempStr + 2) else begin CmdPtr := TempCmdStr; If Lo (DosVersion) > 3 then begin StrPCopy (TPL_CFG_Directories, ParamStr (0)); I := 0; For N := 0 to Length (ParamStr (0)) do If TPL_CFG_Directories [N] = '\' then I := N + 1; TPL_CFG_Directories [I] := #0; end; end; end; This procedure reads configuration file. This file is processed as initial command line parameters, i.e. all parameters specified in the command line override parameters in the configuration file. Procedure Read_TPC_CFG; Var CfgFile: File; begin StrCopy (TempStr, CfgFileName); FindFilePath (TempStr, Dir_TPL_CFG or Ext_Original); Assign (CfgFile, StrPas (TempStr)); {$I-} Reset (CfgFile, 1); If IOResult = 0 then begin BlockRead (CfgFile, FileBuffer, SizeOf (FileBuffer) - 2); Close (CfgFile); If IOResult = 0 then; end; {$I+} end; |