summary refs log tree commit diff stats
path: root/nim/commands.pas
diff options
context:
space:
mode:
Diffstat (limited to 'nim/commands.pas')
-rw-r--r--nim/commands.pas971
1 files changed, 512 insertions, 459 deletions
diff --git a/nim/commands.pas b/nim/commands.pas
index 8a4435eb0..fde2d26c7 100644
--- a/nim/commands.pas
+++ b/nim/commands.pas
@@ -1,61 +1,61 @@
-//
-//
-//           The Nimrod Compiler
-//        (c) Copyright 2008 Andreas Rumpf
-//
-//    See the file "copying.txt", included in this
-//    distribution, for details about the copyright.
-//
-
-unit commands;
-
-// This module handles the parsing of command line arguments.
-
-interface
-
-{$include 'config.inc'}
-
-uses
-  nsystem, charsets, nos, msgs, options, nversion, condsyms, strutils, extccomp, 
-  platform, lists, wordrecg;
-
-procedure writeCommandLineUsage;
-
-type
-  TCmdLinePass = (
-    passCmd1,                // first pass over the command line
-    passCmd2,                // second pass over the command line
-    passPP                   // preprocessor called ProcessCommand()
-  );
-
-procedure ProcessCommand(const switch: string; pass: TCmdLinePass);
-procedure processSwitch(const switch, arg: string; pass: TCmdlinePass;
-                        const info: TLineInfo);
-
-implementation
-
-{@ignore}
-const
-{$ifdef fpc}
-  compileDate = {$I %date%};
-{$else}
-  compileDate = '2009-0-0';
-{$endif}
-{@emit}
-
-const
-  HelpMessage = 'Nimrod Compiler Version $1 (' +{&}
-    compileDate +{&} ') [$2: $3]' +{&} nl +{&}
-    'Copyright (c) 2004-2009 by Andreas Rumpf' +{&} nl;
-
-const
-  Usage = ''
-//[[[cog
-//from string import replace
-//def f(x): return "+{&} '" + replace(x, "'", "''")[:-1] + "' +{&} nl"
-//for line in open("data/basicopt.txt").readlines():
-//  cog.outl(f(line))
-//]]]
+//

+//

+//           The Nimrod Compiler

+//        (c) Copyright 2008 Andreas Rumpf

+//

+//    See the file "copying.txt", included in this

+//    distribution, for details about the copyright.

+//

+

+unit commands;

+

+// This module handles the parsing of command line arguments.

+

+interface

+

+{$include 'config.inc'}

+

+uses

+  nsystem, charsets, nos, msgs, options, nversion, condsyms, strutils, extccomp, 

+  platform, lists, wordrecg;

+

+procedure writeCommandLineUsage;

+

+type

+  TCmdLinePass = (

+    passCmd1,                // first pass over the command line

+    passCmd2,                // second pass over the command line

+    passPP                   // preprocessor called ProcessCommand()

+  );

+

+procedure ProcessCommand(const switch: string; pass: TCmdLinePass);

+procedure processSwitch(const switch, arg: string; pass: TCmdlinePass;

+                        const info: TLineInfo);

+

+implementation

+

+{@ignore}

+const

+{$ifdef fpc}

+  compileDate = {$I %date%};

+{$else}

+  compileDate = '2009-0-0';

+{$endif}

+{@emit}

+

+const

+  HelpMessage = 'Nimrod Compiler Version $1 (' +{&}

+    compileDate +{&} ') [$2: $3]' +{&} nl +{&}

+    'Copyright (c) 2004-2009 by Andreas Rumpf' +{&} nl;

+

+const

+  Usage = ''

+//[[[cog

+//from string import replace

+//def f(x): return "+{&} '" + replace(x, "'", "''")[:-1] + "' +{&} nl"

+//for line in open("data/basicopt.txt").readlines():

+//  cog.outl(f(line))

+//]]]

 +{&} 'Usage::' +{&} nl
 +{&} '  nimrod command [options] inputfile [arguments]' +{&} nl
 +{&} 'Command::' +{&} nl
@@ -88,14 +88,14 @@ const
 +{&} '  -r, --run                 run the compiled program with given arguments' +{&} nl
 +{&} '  --advanced                show advanced command line switches' +{&} nl
 +{&} '  -h, --help                show this help' +{&} nl
-//[[[end]]]
-  ;
-
-  AdvancedUsage = ''
-//[[[cog
-//for line in open("data/advopt.txt").readlines():
-//  cog.outl(f(line))
-//]]]
+//[[[end]]]

+  ;

+

+  AdvancedUsage = ''

+//[[[cog

+//for line in open("data/advopt.txt").readlines():

+//  cog.outl(f(line))

+//]]]

 +{&} 'Advanced commands::' +{&} nl
 +{&} '  pas                       convert a Pascal file to Nimrod syntax' +{&} nl
 +{&} '  pretty                    pretty print the inputfile' +{&} nl
@@ -125,401 +125,454 @@ const
 +{&} '  --checkpoints:on|off      turn on|off checkpoints; for debugging Nimrod' +{&} nl
 +{&} '  --skip_cfg                do not read the general configuration file' +{&} nl
 +{&} '  --skip_proj_cfg           do not read the project''s configuration file' +{&} nl
++{&} '  --gc:refc|boehm           use Nimrod''s native GC|Boehm GC' +{&} nl
 +{&} '  --index:FILE              use FILE to generate a documenation index file' +{&} nl
 +{&} '  --putenv:key=value        set an environment variable' +{&} nl
 +{&} '  --list_cmd                list the commands used to execute external programs' +{&} nl
 +{&} '  --verbosity:0|1|2|3       set Nimrod''s verbosity level (0 is default)' +{&} nl
 +{&} '  -v, --version             show detailed version information' +{&} nl
-//[[[end]]]
-  ;
-
-function getCommandLineDesc: string;
-begin
-  result := format(HelpMessage, [VersionAsString, 
-    platform.os[platform.hostOS].name, cpu[platform.hostCPU].name]) +{&} Usage
-end;
-
-var
-  helpWritten: boolean;  // BUGFIX 19
-  versionWritten: boolean;
-  advHelpWritten: boolean;
-
-procedure HelpOnError(pass: TCmdLinePass);
-begin
-  if (pass = passCmd1) and not helpWritten then begin
-    // BUGFIX 19
-    MessageOut(getCommandLineDesc());
-    helpWritten := true
-  end
-end;
-
-procedure writeAdvancedUsage(pass: TCmdLinePass);
-begin
-  if (pass = passCmd1) and not advHelpWritten then begin
-    // BUGFIX 19
-    MessageOut(format(HelpMessage, [VersionAsString, 
-                                    platform.os[platform.hostOS].name,
-                                    cpu[platform.hostCPU].name]) +{&}
-                                    AdvancedUsage);
-    advHelpWritten := true;
-    helpWritten := true;
-    halt(0);
-  end
-end;
-
-procedure writeVersionInfo(pass: TCmdLinePass);
-begin
-  if (pass = passCmd1) and not versionWritten then begin
-    versionWritten := true;
-    helpWritten := true;
-    messageOut(format(HelpMessage, [VersionAsString, 
-                                    platform.os[platform.hostOS].name,
-                                    cpu[platform.hostCPU].name]))
-  end
-end;
-
-procedure writeCommandLineUsage;
-begin
-  if not helpWritten then begin
-    messageOut(getCommandLineDesc());
-    helpWritten := true
-  end
-end;
-
-procedure InvalidCmdLineOption(pass: TCmdLinePass; const switch: string;
-                               const info: TLineInfo);
-begin
-  liMessage(info, errInvalidCmdLineOption, switch)
-end;
-
-procedure splitSwitch(const switch: string; out cmd, arg: string;
-                      pass: TCmdLinePass; const info: TLineInfo);
-var
-  i: int;
-begin
-  cmd := '';
-  i := strStart;
-  if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i);
-  if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i);
-  while i < length(switch) + strStart do begin
-    case switch[i] of
-      'a'..'z', 'A'..'Z', '0'..'9', '_', '.':
-        addChar(cmd, switch[i]);
-      else break;
-    end;
-    inc(i);
-  end;
-  if i >= length(switch) + strStart then
-    arg := ''
-  else if switch[i] in [':', '=', '['] then
-    arg := ncopy(switch, i + 1)
-  else
-    InvalidCmdLineOption(pass, switch, info)
-end;
-
-procedure ProcessOnOffSwitch(const op: TOptions; const arg: string;
-                             pass: TCmdlinePass; const info: TLineInfo);
-begin
-  case whichKeyword(arg) of
-    wOn:  gOptions := gOptions + op;
-    wOff: gOptions := gOptions - op;
-    else  liMessage(info, errOnOrOffExpectedButXFound, arg)
-  end
-end;
-
-procedure ProcessOnOffSwitchG(const op: TGlobalOptions; const arg: string;
-                              pass: TCmdlinePass; const info: TLineInfo);
-begin
-  case whichKeyword(arg) of
-    wOn:  gGlobalOptions := gGlobalOptions + op;
-    wOff: gGlobalOptions := gGlobalOptions - op;
-    else  liMessage(info, errOnOrOffExpectedButXFound, arg)
-  end
-end;
-
-procedure ExpectArg(const switch, arg: string; pass: TCmdLinePass;
-                    const info: TLineInfo);
-begin
-  if (arg = '') then
-    liMessage(info, errCmdLineArgExpected, switch)
-end;
-
-procedure ProcessSpecificNote(const arg: string; state: TSpecialWord;
-                              pass: TCmdlinePass; const info: TLineInfo);
-var
-  i, x: int;
-  n: TNoteKind;
-  id: string;
-begin
-  id := '';
-  // arg = "X]:on|off"
-  i := strStart;
-  n := hintMin;
-  while (i < length(arg)+strStart) and (arg[i] <> ']') do begin
-    addChar(id, arg[i]);
-    inc(i)
-  end;
-  if (i < length(arg)+strStart) and (arg[i] = ']') then
-    inc(i)
-  else
-    InvalidCmdLineOption(pass, arg, info);
-  if (i < length(arg)+strStart) and (arg[i] in [':', '=']) then
-    inc(i)
-  else
-    InvalidCmdLineOption(pass, arg, info);
-  if state = wHint then begin
-    x := findStr(msgs.HintsToStr, id);
-    if x >= 0 then
-      n := TNoteKind(x + ord(hintMin))
-    else
-      InvalidCmdLineOption(pass, arg, info)
-  end
-  else begin
-    x := findStr(msgs.WarningsToStr, id);
-    if x >= 0 then
-      n := TNoteKind(x + ord(warnMin))
-    else
-      InvalidCmdLineOption(pass, arg, info)
-  end;
-  case whichKeyword(ncopy(arg, i)) of
-    wOn: include(gNotes, n);
-    wOff: exclude(gNotes, n);
-    else liMessage(info, errOnOrOffExpectedButXFound, arg)
-  end
-end;
-
-function processPath(const path: string): string;
-begin
-  result := UnixToNativePath(format(path,
-    ['nimrod', getPrefixDir(), 'lib', libpath]))
-end;
-
-procedure processCompile(const filename: string);
-var
-  found, trunc, ext: string;
-begin
-  found := findFile(filename);
-  if found = '' then found := filename;
-  splitFilename(found, trunc, ext);
-  extccomp.addExternalFileToCompile(trunc);
-  extccomp.addFileToLink(completeCFilePath(trunc, false));
-end;
-
-procedure processSwitch(const switch, arg: string; pass: TCmdlinePass;
-                        const info: TLineInfo);
-var
-  theOS: TSystemOS;
-  cpu: TSystemCPU;
-  key, val, path: string;
-begin
-  case whichKeyword(switch) of
-    wPath, wP: begin
-      expectArg(switch, arg, pass, info);
-      path := processPath(arg);
-      {@discard} lists.IncludeStr(options.searchPaths, path)
-    end;
-    wOut, wO: begin
-      expectArg(switch, arg, pass, info);
-      options.outFile := arg;
-    end;
-    wDefine, wD: begin
-      expectArg(switch, arg, pass, info);
-      DefineSymbol(arg)
-    end;
-    wUndef, wU: begin
-      expectArg(switch, arg, pass, info);
-      UndefSymbol(arg)
-    end;
-    wCompile: begin
-      expectArg(switch, arg, pass, info);
-      if pass in {@set}[passCmd2, passPP] then
-        processCompile(arg);
-    end;
-    wLink: begin
-      expectArg(switch, arg, pass, info);
-      if pass in {@set}[passCmd2, passPP] then
-        addFileToLink(arg);
-    end;
-    wDebuginfo: include(gGlobalOptions, optCDebug);
-    wCompileOnly, wC: include(gGlobalOptions, optCompileOnly);
-    wNoLinking: include(gGlobalOptions, optNoLinking);
-    wForceBuild, wF: include(gGlobalOptions, optForceFullMake);
-    wGC: begin
-      case whichKeyword(arg) of
-        wBoehm: begin
-          include(gGlobalOptions, optBoehmGC);
-          exclude(gGlobalOptions, optRefcGC);
-          DefineSymbol('boehmgc');
-        end;
-        wRefc: begin
-          exclude(gGlobalOptions, optBoehmGC);
-          include(gGlobalOptions, optRefcGC)
-        end;
-        wNone: begin
-          exclude(gGlobalOptions, optRefcGC);
-          exclude(gGlobalOptions, optBoehmGC);
-          defineSymbol('nogc');
-        end
-        else
-          liMessage(info, errNoneBoehmRefcExpectedButXFound, arg)
-      end
-    end;
-    wWarnings, wW: ProcessOnOffSwitch({@set}[optWarns], arg, pass, info);
-    wWarning: ProcessSpecificNote(arg, wWarning, pass, info);
-    wHint: ProcessSpecificNote(arg, wHint, pass, info);
-    wHints: ProcessOnOffSwitch({@set}[optHints], arg, pass, info);
-    wCheckpoints: ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info);
-    wStackTrace: ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info);
-    wLineTrace: ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info);
-    wDebugger: begin
-      ProcessOnOffSwitch({@set}[optEndb], arg, pass, info);
-      if optEndb in gOptions then
-        DefineSymbol('endb')
-      else
-        UndefSymbol('endb')
-    end;
-    wProfiler: begin
-      ProcessOnOffSwitch({@set}[optProfiler], arg, pass, info);
-      if optProfiler in gOptions then DefineSymbol('profiler')
-      else UndefSymbol('profiler')
-    end;
-    wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info);
-    wObjChecks: ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info);
-    wFieldChecks: ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info);
-    wRangeChecks: ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info);
-    wBoundChecks: ProcessOnOffSwitch({@set}[optBoundsCheck], arg, pass, info);
-    wOverflowChecks: ProcessOnOffSwitch({@set}[optOverflowCheck], arg, pass, info);
-    wLineDir: ProcessOnOffSwitch({@set}[optLineDir], arg, pass, info);
-    wAssertions, wA: ProcessOnOffSwitch({@set}[optAssert], arg, pass, info);
-    wDeadCodeElim: ProcessOnOffSwitchG({@set}[optDeadCodeElim], arg, pass, info);
-    wOpt: begin
-      case whichKeyword(arg) of
-        wSpeed: begin
-          include(gOptions, optOptimizeSpeed);
-          exclude(gOptions, optOptimizeSize)
-        end;
-        wSize: begin
-          exclude(gOptions, optOptimizeSpeed);
-          include(gOptions, optOptimizeSize)
-        end;
-        wNone: begin
-          exclude(gOptions, optOptimizeSpeed);
-          exclude(gOptions, optOptimizeSize)
-        end
-        else
-          liMessage(info, errNoneSpeedOrSizeExpectedButXFound, arg)
-      end
-    end;
-    wApp: begin
-      case whichKeyword(arg) of
-        wGui: begin
-          include(gGlobalOptions, optGenGuiApp);
-          defineSymbol('guiapp')
-        end;
-        wConsole:
-          exclude(gGlobalOptions, optGenGuiApp);
-        wLib: begin
-          include(gGlobalOptions, optGenDynLib);
-          exclude(gGlobalOptions, optGenGuiApp);
-          defineSymbol('library')
-        end;
-        else
-          liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg)
-      end
-    end;
-    wListDef: begin
-      if pass in {@set}[passCmd2, passPP] then
-        condsyms.listSymbols();
-    end;
-    wPassC, wT: begin
-      expectArg(switch, arg, pass, info);
-      if pass in {@set}[passCmd2, passPP] then
-        extccomp.addCompileOption(arg)
-    end;
-    wPassL, wL: begin
-      expectArg(switch, arg, pass, info);
-      if pass in {@set}[passCmd2, passPP] then
-        extccomp.addLinkOption(arg)
-    end;
-    wIndex: begin
-      expectArg(switch, arg, pass, info);
-      if pass in {@set}[passCmd2, passPP] then
-        gIndexFile := arg
-    end;
-    wImport: begin
-      expectArg(switch, arg, pass, info);
-      options.addImplicitMod(arg);
-    end;
-    wListCmd: include(gGlobalOptions, optListCmd);
-    wGenMapping: include(gGlobalOptions, optGenMapping);
-    wOS: begin
-      if (pass = passCmd1) then begin
-        theOS := platform.NameToOS(arg);
-        if theOS = osNone then
-          liMessage(info, errUnknownOS, arg);
-        if theOS <> platform.hostOS then begin
-          setTarget(theOS, targetCPU);
-          include(gGlobalOptions, optCompileOnly);
-          condsyms.InitDefines()
-        end
-      end
-    end;
-    wCPU: begin
-      if (pass = passCmd1) then begin
-        cpu := platform.NameToCPU(arg);
-        if cpu = cpuNone then
-          liMessage(info, errUnknownCPU, arg);
-        if cpu <> platform.hostCPU then begin
-          setTarget(targetOS, cpu);
-          include(gGlobalOptions, optCompileOnly);
-          condsyms.InitDefines()
-        end
-      end
-    end;
-    wRun, wR: include(gGlobalOptions, optRun);
-    wVerbosity: begin
-      expectArg(switch, arg, pass, info);
-      gVerbosity := parseInt(arg);
-    end;
-    wVersion, wV: writeVersionInfo(pass);
-    wAdvanced: writeAdvancedUsage(pass);
-    wHelp, wH: helpOnError(pass);
-    wSymbolFiles: ProcessOnOffSwitchG({@set}[optSymbolFiles], arg, pass, info);
-    wSkipCfg: include(gGlobalOptions, optSkipConfigFile);
-    wSkipProjCfg: include(gGlobalOptions, optSkipProjConfigFile);
-    wGenScript: include(gGlobalOptions, optGenScript);
-    wLib: begin
-      expectArg(switch, arg, pass, info);
-      libpath := processPath(arg)
-    end;
-    wPutEnv: begin
-      expectArg(switch, arg, pass, info);
-      splitSwitch(arg, key, val, pass, info);
-      nos.putEnv(key, val);
-    end;
-    wCC: begin
-      expectArg(switch, arg, pass, info);
-      setCC(arg)
-    end;
-    wMaxErr: begin
-      expectArg(switch, arg, pass, info);
-      gErrorMax := parseInt(arg);
-    end;
-    else if strutils.find(switch, '.') >= strStart then
-      options.setConfigVar(switch, arg)
-    else
-      InvalidCmdLineOption(pass, switch, info)
-  end
-end;
-
-procedure ProcessCommand(const switch: string; pass: TCmdLinePass);
-var
-  cmd, arg: string;
-  info: TLineInfo;
-begin
-  info := newLineInfo('command line', 1, 1);
-  splitSwitch(switch, cmd, arg, pass, info);
-  ProcessSwitch(cmd, arg, pass, info)
-end;
-
-end.
+//[[[end]]]

+  ;

+

+function getCommandLineDesc: string;

+begin

+  result := format(HelpMessage, [VersionAsString, 

+    platform.os[platform.hostOS].name, cpu[platform.hostCPU].name]) +{&} Usage

+end;

+

+var

+  helpWritten: boolean;  // BUGFIX 19

+  versionWritten: boolean;

+  advHelpWritten: boolean;

+

+procedure HelpOnError(pass: TCmdLinePass);

+begin

+  if (pass = passCmd1) and not helpWritten then begin

+    // BUGFIX 19

+    MessageOut(getCommandLineDesc());

+    helpWritten := true

+  end

+end;

+

+procedure writeAdvancedUsage(pass: TCmdLinePass);

+begin

+  if (pass = passCmd1) and not advHelpWritten then begin

+    // BUGFIX 19

+    MessageOut(format(HelpMessage, [VersionAsString, 

+                                    platform.os[platform.hostOS].name,

+                                    cpu[platform.hostCPU].name]) +{&}

+                                    AdvancedUsage);

+    advHelpWritten := true;

+    helpWritten := true;

+    halt(0);

+  end

+end;

+

+procedure writeVersionInfo(pass: TCmdLinePass);

+begin

+  if (pass = passCmd1) and not versionWritten then begin

+    versionWritten := true;

+    helpWritten := true;

+    messageOut(format(HelpMessage, [VersionAsString, 

+                                    platform.os[platform.hostOS].name,

+                                    cpu[platform.hostCPU].name]))

+  end

+end;

+

+procedure writeCommandLineUsage;

+begin

+  if not helpWritten then begin

+    messageOut(getCommandLineDesc());

+    helpWritten := true

+  end

+end;

+

+procedure InvalidCmdLineOption(pass: TCmdLinePass; const switch: string;

+                               const info: TLineInfo);

+begin

+  liMessage(info, errInvalidCmdLineOption, switch)

+end;

+

+procedure splitSwitch(const switch: string; out cmd, arg: string;

+                      pass: TCmdLinePass; const info: TLineInfo);

+var

+  i: int;

+begin

+  cmd := '';

+  i := strStart;

+  if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i);

+  if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i);

+  while i < length(switch) + strStart do begin

+    case switch[i] of

+      'a'..'z', 'A'..'Z', '0'..'9', '_', '.':

+        addChar(cmd, switch[i]);

+      else break;

+    end;

+    inc(i);

+  end;

+  if i >= length(switch) + strStart then

+    arg := ''

+  else if switch[i] in [':', '=', '['] then

+    arg := ncopy(switch, i + 1)

+  else

+    InvalidCmdLineOption(pass, switch, info)

+end;

+

+procedure ProcessOnOffSwitch(const op: TOptions; const arg: string;

+                             pass: TCmdlinePass; const info: TLineInfo);

+begin

+  case whichKeyword(arg) of

+    wOn:  gOptions := gOptions + op;

+    wOff: gOptions := gOptions - op;

+    else  liMessage(info, errOnOrOffExpectedButXFound, arg)

+  end

+end;

+

+procedure ProcessOnOffSwitchG(const op: TGlobalOptions; const arg: string;

+                              pass: TCmdlinePass; const info: TLineInfo);

+begin

+  case whichKeyword(arg) of

+    wOn:  gGlobalOptions := gGlobalOptions + op;

+    wOff: gGlobalOptions := gGlobalOptions - op;

+    else  liMessage(info, errOnOrOffExpectedButXFound, arg)

+  end

+end;

+

+procedure ExpectArg(const switch, arg: string; pass: TCmdLinePass;

+                    const info: TLineInfo);

+begin

+  if (arg = '') then

+    liMessage(info, errCmdLineArgExpected, switch)

+end;

+

+procedure ExpectNoArg(const switch, arg: string; pass: TCmdLinePass;

+                      const info: TLineInfo);

+begin

+  if (arg <> '') then

+    liMessage(info, errCmdLineNoArgExpected, switch)

+end;

+

+procedure ProcessSpecificNote(const arg: string; state: TSpecialWord;

+                              pass: TCmdlinePass; const info: TLineInfo);

+var

+  i, x: int;

+  n: TNoteKind;

+  id: string;

+begin

+  id := '';

+  // arg = "X]:on|off"

+  i := strStart;

+  n := hintMin;

+  while (i < length(arg)+strStart) and (arg[i] <> ']') do begin

+    addChar(id, arg[i]);

+    inc(i)

+  end;

+  if (i < length(arg)+strStart) and (arg[i] = ']') then

+    inc(i)

+  else

+    InvalidCmdLineOption(pass, arg, info);

+  if (i < length(arg)+strStart) and (arg[i] in [':', '=']) then

+    inc(i)

+  else

+    InvalidCmdLineOption(pass, arg, info);

+  if state = wHint then begin

+    x := findStr(msgs.HintsToStr, id);

+    if x >= 0 then

+      n := TNoteKind(x + ord(hintMin))

+    else

+      InvalidCmdLineOption(pass, arg, info)

+  end

+  else begin

+    x := findStr(msgs.WarningsToStr, id);

+    if x >= 0 then

+      n := TNoteKind(x + ord(warnMin))

+    else

+      InvalidCmdLineOption(pass, arg, info)

+  end;

+  case whichKeyword(ncopy(arg, i)) of

+    wOn: include(gNotes, n);

+    wOff: exclude(gNotes, n);

+    else liMessage(info, errOnOrOffExpectedButXFound, arg)

+  end

+end;

+

+function processPath(const path: string): string;

+begin

+  result := UnixToNativePath(format(path,

+    ['nimrod', getPrefixDir(), 'lib', libpath]))

+end;

+

+procedure processCompile(const filename: string);

+var

+  found, trunc, ext: string;

+begin

+  found := findFile(filename);

+  if found = '' then found := filename;

+  splitFilename(found, trunc, ext);

+  extccomp.addExternalFileToCompile(trunc);

+  extccomp.addFileToLink(completeCFilePath(trunc, false));

+end;

+

+procedure processSwitch(const switch, arg: string; pass: TCmdlinePass;

+                        const info: TLineInfo);

+var

+  theOS: TSystemOS;

+  cpu: TSystemCPU;

+  key, val, path: string;

+begin

+  case whichKeyword(switch) of

+    wPath, wP: begin

+      expectArg(switch, arg, pass, info);

+      path := processPath(arg);

+      {@discard} lists.IncludeStr(options.searchPaths, path)

+    end;

+    wOut, wO: begin

+      expectArg(switch, arg, pass, info);

+      options.outFile := arg;

+    end;

+    wDefine, wD: begin

+      expectArg(switch, arg, pass, info);

+      DefineSymbol(arg)

+    end;

+    wUndef, wU: begin

+      expectArg(switch, arg, pass, info);

+      UndefSymbol(arg)

+    end;

+    wCompile: begin

+      expectArg(switch, arg, pass, info);

+      if pass in {@set}[passCmd2, passPP] then

+        processCompile(arg);

+    end;

+    wLink: begin

+      expectArg(switch, arg, pass, info);

+      if pass in {@set}[passCmd2, passPP] then

+        addFileToLink(arg);

+    end;

+    wDebuginfo: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optCDebug);

+    end;

+    wCompileOnly, wC: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optCompileOnly);

+    end;

+    wNoLinking: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optNoLinking);

+    end;

+    wForceBuild, wF: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optForceFullMake);

+    end;

+    wGC: begin

+      expectArg(switch, arg, pass, info);

+      case whichKeyword(arg) of

+        wBoehm: begin

+          include(gGlobalOptions, optBoehmGC);

+          exclude(gGlobalOptions, optRefcGC);

+          DefineSymbol('boehmgc');

+        end;

+        wRefc: begin

+          exclude(gGlobalOptions, optBoehmGC);

+          include(gGlobalOptions, optRefcGC)

+        end;

+        wNone: begin

+          exclude(gGlobalOptions, optRefcGC);

+          exclude(gGlobalOptions, optBoehmGC);

+          defineSymbol('nogc');

+        end

+        else

+          liMessage(info, errNoneBoehmRefcExpectedButXFound, arg)

+      end

+    end;

+    wWarnings, wW: ProcessOnOffSwitch({@set}[optWarns], arg, pass, info);

+    wWarning: ProcessSpecificNote(arg, wWarning, pass, info);

+    wHint: ProcessSpecificNote(arg, wHint, pass, info);

+    wHints: ProcessOnOffSwitch({@set}[optHints], arg, pass, info);

+    wCheckpoints: ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info);

+    wStackTrace: ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info);

+    wLineTrace: ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info);

+    wDebugger: begin

+      ProcessOnOffSwitch({@set}[optEndb], arg, pass, info);

+      if optEndb in gOptions then

+        DefineSymbol('endb')

+      else

+        UndefSymbol('endb')

+    end;

+    wProfiler: begin

+      ProcessOnOffSwitch({@set}[optProfiler], arg, pass, info);

+      if optProfiler in gOptions then DefineSymbol('profiler')

+      else UndefSymbol('profiler')

+    end;

+    wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info);

+    wObjChecks: ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info);

+    wFieldChecks: ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info);

+    wRangeChecks: ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info);

+    wBoundChecks: ProcessOnOffSwitch({@set}[optBoundsCheck], arg, pass, info);

+    wOverflowChecks: ProcessOnOffSwitch({@set}[optOverflowCheck], arg, pass, info);

+    wLineDir: ProcessOnOffSwitch({@set}[optLineDir], arg, pass, info);

+    wAssertions, wA: ProcessOnOffSwitch({@set}[optAssert], arg, pass, info);

+    wDeadCodeElim: ProcessOnOffSwitchG({@set}[optDeadCodeElim], arg, pass, info);

+    wOpt: begin

+      expectArg(switch, arg, pass, info);

+      case whichKeyword(arg) of

+        wSpeed: begin

+          include(gOptions, optOptimizeSpeed);

+          exclude(gOptions, optOptimizeSize)

+        end;

+        wSize: begin

+          exclude(gOptions, optOptimizeSpeed);

+          include(gOptions, optOptimizeSize)

+        end;

+        wNone: begin

+          exclude(gOptions, optOptimizeSpeed);

+          exclude(gOptions, optOptimizeSize)

+        end

+        else

+          liMessage(info, errNoneSpeedOrSizeExpectedButXFound, arg)

+      end

+    end;

+    wApp: begin

+      expectArg(switch, arg, pass, info);

+      case whichKeyword(arg) of

+        wGui: begin

+          include(gGlobalOptions, optGenGuiApp);

+          defineSymbol('guiapp')

+        end;

+        wConsole:

+          exclude(gGlobalOptions, optGenGuiApp);

+        wLib: begin

+          include(gGlobalOptions, optGenDynLib);

+          exclude(gGlobalOptions, optGenGuiApp);

+          defineSymbol('library')

+        end;

+        else

+          liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg)

+      end

+    end;

+    wListDef: begin

+      expectNoArg(switch, arg, pass, info);

+      if pass in {@set}[passCmd2, passPP] then

+        condsyms.listSymbols();

+    end;

+    wPassC, wT: begin

+      expectArg(switch, arg, pass, info);

+      if pass in {@set}[passCmd2, passPP] then

+        extccomp.addCompileOption(arg)

+    end;

+    wPassL, wL: begin

+      expectArg(switch, arg, pass, info);

+      if pass in {@set}[passCmd2, passPP] then

+        extccomp.addLinkOption(arg)

+    end;

+    wIndex: begin

+      expectArg(switch, arg, pass, info);

+      if pass in {@set}[passCmd2, passPP] then

+        gIndexFile := arg

+    end;

+    wImport: begin

+      expectArg(switch, arg, pass, info);

+      options.addImplicitMod(arg);

+    end;

+    wListCmd: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optListCmd);

+    end;

+    wGenMapping: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optGenMapping);

+    end;

+    wOS: begin

+      expectArg(switch, arg, pass, info);

+      if (pass = passCmd1) then begin

+        theOS := platform.NameToOS(arg);

+        if theOS = osNone then

+          liMessage(info, errUnknownOS, arg);

+        if theOS <> platform.hostOS then begin

+          setTarget(theOS, targetCPU);

+          include(gGlobalOptions, optCompileOnly);

+          condsyms.InitDefines()

+        end

+      end

+    end;

+    wCPU: begin

+      expectArg(switch, arg, pass, info);

+      if (pass = passCmd1) then begin

+        cpu := platform.NameToCPU(arg);

+        if cpu = cpuNone then

+          liMessage(info, errUnknownCPU, arg);

+        if cpu <> platform.hostCPU then begin

+          setTarget(targetOS, cpu);

+          include(gGlobalOptions, optCompileOnly);

+          condsyms.InitDefines()

+        end

+      end

+    end;

+    wRun, wR: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optRun);

+    end;

+    wVerbosity: begin

+      expectArg(switch, arg, pass, info);

+      gVerbosity := parseInt(arg);

+    end;

+    wVersion, wV: begin

+      expectNoArg(switch, arg, pass, info);

+      writeVersionInfo(pass);

+    end;

+    wAdvanced: begin

+      expectNoArg(switch, arg, pass, info);

+      writeAdvancedUsage(pass);

+    end;

+    wHelp, wH: begin

+      expectNoArg(switch, arg, pass, info);

+      helpOnError(pass);

+    end;

+    wSymbolFiles: ProcessOnOffSwitchG({@set}[optSymbolFiles], arg, pass, info);

+    wSkipCfg: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optSkipConfigFile);

+    end;

+    wSkipProjCfg: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optSkipProjConfigFile);

+    end;

+    wGenScript: begin

+      expectNoArg(switch, arg, pass, info);

+      include(gGlobalOptions, optGenScript);

+    end;

+    wLib: begin

+      expectArg(switch, arg, pass, info);

+      libpath := processPath(arg)

+    end;

+    wPutEnv: begin

+      expectArg(switch, arg, pass, info);

+      splitSwitch(arg, key, val, pass, info);

+      nos.putEnv(key, val);

+    end;

+    wCC: begin

+      expectArg(switch, arg, pass, info);

+      setCC(arg)

+    end;

+    wMaxErr: begin

+      expectArg(switch, arg, pass, info);

+      gErrorMax := parseInt(arg);

+    end;

+    else if strutils.find(switch, '.') >= strStart then

+      options.setConfigVar(switch, arg)

+    else

+      InvalidCmdLineOption(pass, switch, info)

+  end

+end;

+

+procedure ProcessCommand(const switch: string; pass: TCmdLinePass);

+var

+  cmd, arg: string;

+  info: TLineInfo;

+begin

+  info := newLineInfo('command line', 1, 1);

+  splitSwitch(switch, cmd, arg, pass, info);

+  ProcessSwitch(cmd, arg, pass, info)

+end;

+

+end.