summary refs log tree commit diff stats
path: root/nim/nimrod.pas
blob: 8d7db04b2ca6000c075f761302730cc72ade654a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
//
//           The Nimrod Compiler
//        (c) Copyright 2009 Andreas Rumpf
//
//    See the file "copying.txt", included in this
//    distribution, for details about the copyright.
//
program nimrod;

{$include 'config.inc'}
{@ignore}
{$ifdef windows}
{$apptype console}
{$endif}
{@emit}

uses
  nsystem, ntime,
  charsets, sysutils, commands, scanner, condsyms, options, msgs, nversion,
  nimconf, ropes, extccomp, strutils, nos, platform, main, parseopt;

var
  arguments: string = ''; // the arguments to be passed to the program that
                          // should be run
  cmdLineInfo: TLineInfo;

procedure ProcessCmdLine(pass: TCmdLinePass; var command, filename: string);
var
  p: TOptParser;
  bracketLe: int;
  key, val: string;
begin
  p := parseopt.init();
  while true do begin
    parseopt.next(p);
    case p.kind of
      cmdEnd: break;
      cmdLongOption, cmdShortOption: begin
        // hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
        // we fix this here
        bracketLe := strutils.find(p.key, '[');
        if bracketLe >= strStart then begin
          key := ncopy(p.key, strStart, bracketLe-1);
          val := ncopy(p.key, bracketLe+1) +{&} ':' +{&} p.val;
          ProcessSwitch(key, val, pass, cmdLineInfo);
        end
        else
          ProcessSwitch(p.key, p.val, pass, cmdLineInfo);
      end;
      cmdArgument: begin  
        if command = '' then command := p.key
        else if filename = '' then begin
          filename := unixToNativePath(p.key);
          // BUGFIX for portable build scripts
          break
        end
      end
    end
  end;
  // collect the arguments:
  if pass = passCmd2 then begin
    arguments := getRestOfCommandLine(p);
    if not (optRun in gGlobalOptions) and (arguments <> '') then
      rawMessage(errArgsNeedRunOption);
  end
end;

{@ignore}
type
  TTime = int;
{@emit}

procedure HandleCmdLine;
var
  command, filename, prog: string;
  start: TTime;
begin
  {@emit start := getTime(); }
  if paramCount() = 0 then
    writeCommandLineUsage()
  else begin
    // Process command line arguments:
    command := '';
    filename := '';
    ProcessCmdLine(passCmd1, command, filename);
    if filename <> '' then options.projectPath := splitFile(filename).dir;
    nimconf.LoadConfig(filename); // load the right config file
    // now process command line arguments again, because some options in the
    // command line can overwite the config file's settings
    extccomp.initVars();

    command := '';
    filename := '';
    ProcessCmdLine(passCmd2, command, filename);
    MainCommand(command, filename);
  {@emit
    if gVerbosity >= 2 then echo(GC_getStatistics()); }
    if (gCmd <> cmdInterpret) and (msgs.gErrorCounter = 0) then begin
    {@ignore}
      rawMessage(hintSuccess);
    {@emit
      rawMessage(hintSuccessX, [toString(gLinesCompiled), 
                                toString(getTime() - start)]);
    }
    end;
    if optRun in gGlobalOptions then begin
      {$ifdef unix}
      prog := './' + quoteIfContainsWhite(changeFileExt(filename, ''));
      {$else}
      prog := quoteIfContainsWhite(changeFileExt(filename, ''));
      {$endif}
      execExternalProgram(prog +{&} ' ' +{&} arguments)
    end
  end
end;

begin
//{@emit
//  GC_disableMarkAndSweep();
//}
  cmdLineInfo := newLineInfo('command line', -1, -1);
  condsyms.InitDefines();
  HandleCmdLine();
  halt(options.gExitcode);
end.