Press enter to see results or esc to cancel.

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] &lt;&gt; ',';
  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;