123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718 |
- #
- #
- # The Nim Compiler
- # (c) Copyright 2015 Andreas Rumpf
- #
- # See the file "copying.txt", included in this
- # distribution, for details about the copyright.
- #
- # This module handles the parsing of command line arguments.
- # We do this here before the 'import' statement so 'defined' does not get
- # confused with 'TGCMode.gcGenerational' etc.
- template bootSwitch(name, expr, userString) =
- # Helper to build boot constants, for debugging you can 'echo' the else part.
- const name = if expr: " " & userString else: ""
- bootSwitch(usedRelease, defined(release), "-d:release")
- bootSwitch(usedGnuReadline, defined(useLinenoise), "-d:useLinenoise")
- bootSwitch(usedNoCaas, defined(noCaas), "-d:noCaas")
- bootSwitch(usedBoehm, defined(boehmgc), "--gc:boehm")
- bootSwitch(usedMarkAndSweep, defined(gcmarkandsweep), "--gc:markAndSweep")
- bootSwitch(usedGenerational, defined(gcgenerational), "--gc:generational")
- bootSwitch(usedGoGC, defined(gogc), "--gc:go")
- bootSwitch(usedNoGC, defined(nogc), "--gc:none")
- import
- os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
- wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils
- # but some have deps to imported modules. Yay.
- bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
- bootSwitch(usedAvoidTimeMachine, noTimeMachine, "-d:avoidTimeMachine")
- bootSwitch(usedNativeStacktrace,
- defined(nativeStackTrace) and nativeStackTraceSupported,
- "-d:nativeStackTrace")
- bootSwitch(usedFFI, hasFFI, "-d:useFFI")
- proc writeCommandLineUsage*()
- type
- TCmdLinePass* = enum
- passCmd1, # first pass over the command line
- passCmd2, # second pass over the command line
- passPP # preprocessor called processCommand()
- proc processCommand*(switch: string, pass: TCmdLinePass)
- proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
- config: ConfigRef = nil)
- # implementation
- const
- HelpMessage = "Nim Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" &
- "Copyright (c) 2006-" & CompileDate.substr(0, 3) & " by Andreas Rumpf\n"
- const
- Usage = slurp"../doc/basicopt.txt".replace("//", "")
- AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "")
- proc getCommandLineDesc(): string =
- result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name,
- CPU[platform.hostCPU].name]) & Usage
- proc helpOnError(pass: TCmdLinePass) =
- if pass == passCmd1:
- msgWriteln(getCommandLineDesc(), {msgStdout})
- msgQuit(0)
- proc writeAdvancedUsage(pass: TCmdLinePass) =
- if pass == passCmd1:
- msgWriteln(`%`(HelpMessage, [VersionAsString,
- platform.OS[platform.hostOS].name,
- CPU[platform.hostCPU].name]) & AdvancedUsage,
- {msgStdout})
- msgQuit(0)
- proc writeVersionInfo(pass: TCmdLinePass) =
- if pass == passCmd1:
- msgWriteln(`%`(HelpMessage, [VersionAsString,
- platform.OS[platform.hostOS].name,
- CPU[platform.hostCPU].name]),
- {msgStdout})
- const gitHash = gorge("git log -n 1 --format=%H").strip
- when gitHash.len == 40:
- msgWriteln("git hash: " & gitHash, {msgStdout})
- msgWriteln("active boot switches:" & usedRelease & usedAvoidTimeMachine &
- usedTinyC & usedGnuReadline & usedNativeStacktrace & usedNoCaas &
- usedFFI & usedBoehm & usedMarkAndSweep & usedGenerational & usedGoGC & usedNoGC,
- {msgStdout})
- msgQuit(0)
- var
- helpWritten: bool
- proc writeCommandLineUsage() =
- if not helpWritten:
- msgWriteln(getCommandLineDesc(), {msgStdout})
- helpWritten = true
- proc addPrefix(switch: string): string =
- if len(switch) == 1: result = "-" & switch
- else: result = "--" & switch
- proc invalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) =
- if switch == " ": localError(info, errInvalidCmdLineOption, "-")
- else: localError(info, errInvalidCmdLineOption, addPrefix(switch))
- proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass,
- info: TLineInfo) =
- cmd = ""
- var i = 0
- if i < len(switch) and switch[i] == '-': inc(i)
- if i < len(switch) and switch[i] == '-': inc(i)
- while i < len(switch):
- case switch[i]
- of 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': add(cmd, switch[i])
- else: break
- inc(i)
- if i >= len(switch): arg = ""
- elif switch[i] in {':', '=', '['}: arg = substr(switch, i + 1)
- else: invalidCmdLineOption(pass, switch, info)
- proc processOnOffSwitch(op: TOptions, arg: string, pass: TCmdLinePass,
- info: TLineInfo) =
- case arg.normalize
- of "on": gOptions = gOptions + op
- of "off": gOptions = gOptions - op
- else: localError(info, errOnOrOffExpectedButXFound, arg)
- proc processOnOffSwitchOrList(op: TOptions, arg: string, pass: TCmdLinePass,
- info: TLineInfo): bool =
- result = false
- case arg.normalize
- of "on": gOptions = gOptions + op
- of "off": gOptions = gOptions - op
- else:
- if arg == "list":
- result = true
- else:
- localError(info, errOnOffOrListExpectedButXFound, arg)
- proc processOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdLinePass,
- info: TLineInfo) =
- case arg.normalize
- of "on": gGlobalOptions = gGlobalOptions + op
- of "off": gGlobalOptions = gGlobalOptions - op
- else: localError(info, errOnOrOffExpectedButXFound, arg)
- proc expectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
- if arg == "": localError(info, errCmdLineArgExpected, addPrefix(switch))
- proc expectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
- if arg != "": localError(info, errCmdLineNoArgExpected, addPrefix(switch))
- var
- enableNotes: TNoteKinds
- disableNotes: TNoteKinds
- proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
- info: TLineInfo; orig: string) =
- var id = "" # arg = "X]:on|off"
- var i = 0
- var n = hintMin
- while i < len(arg) and (arg[i] != ']'):
- add(id, arg[i])
- inc(i)
- if i < len(arg) and (arg[i] == ']'): inc(i)
- else: invalidCmdLineOption(pass, orig, info)
- if i < len(arg) and (arg[i] in {':', '='}): inc(i)
- else: invalidCmdLineOption(pass, orig, info)
- if state == wHint:
- var x = findStr(msgs.HintsToStr, id)
- if x >= 0: n = TNoteKind(x + ord(hintMin))
- else: localError(info, "unknown hint: " & id)
- else:
- var x = findStr(msgs.WarningsToStr, id)
- if x >= 0: n = TNoteKind(x + ord(warnMin))
- else: localError(info, "unknown warning: " & id)
- case substr(arg, i).normalize
- of "on":
- incl(gNotes, n)
- incl(gMainPackageNotes, n)
- incl(enableNotes, n)
- of "off":
- excl(gNotes, n)
- excl(gMainPackageNotes, n)
- incl(disableNotes, n)
- excl(ForeignPackageNotes, n)
- else: localError(info, errOnOrOffExpectedButXFound, arg)
- proc processCompile(filename: string) =
- var found = findFile(filename)
- if found == "": found = filename
- extccomp.addExternalFileToCompile(found)
- proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
- case switch.normalize
- of "gc":
- case arg.normalize
- of "boehm": result = gSelectedGC == gcBoehm
- of "refc": result = gSelectedGC == gcRefc
- of "v2": result = gSelectedGC == gcV2
- of "markandsweep": result = gSelectedGC == gcMarkAndSweep
- of "generational": result = gSelectedGC == gcGenerational
- of "go": result = gSelectedGC == gcGo
- of "none": result = gSelectedGC == gcNone
- of "stack", "regions": result = gSelectedGC == gcRegions
- else: localError(info, errNoneBoehmRefcExpectedButXFound, arg)
- of "opt":
- case arg.normalize
- of "speed": result = contains(gOptions, optOptimizeSpeed)
- of "size": result = contains(gOptions, optOptimizeSize)
- of "none": result = gOptions * {optOptimizeSpeed, optOptimizeSize} == {}
- else: localError(info, errNoneSpeedOrSizeExpectedButXFound, arg)
- of "verbosity": result = $gVerbosity == arg
- of "app":
- case arg.normalize
- of "gui": result = contains(gGlobalOptions, optGenGuiApp)
- of "console": result = not contains(gGlobalOptions, optGenGuiApp)
- of "lib": result = contains(gGlobalOptions, optGenDynLib) and
- not contains(gGlobalOptions, optGenGuiApp)
- of "staticlib": result = contains(gGlobalOptions, optGenStaticLib) and
- not contains(gGlobalOptions, optGenGuiApp)
- else: localError(info, errGuiConsoleOrLibExpectedButXFound, arg)
- of "dynliboverride":
- result = isDynlibOverride(arg)
- else: invalidCmdLineOption(passCmd1, switch, info)
- proc testCompileOption*(switch: string, info: TLineInfo): bool =
- case switch.normalize
- of "debuginfo": result = contains(gGlobalOptions, optCDebug)
- of "compileonly", "c": result = contains(gGlobalOptions, optCompileOnly)
- of "nolinking": result = contains(gGlobalOptions, optNoLinking)
- of "nomain": result = contains(gGlobalOptions, optNoMain)
- of "forcebuild", "f": result = contains(gGlobalOptions, optForceFullMake)
- of "warnings", "w": result = contains(gOptions, optWarns)
- of "hints": result = contains(gOptions, optHints)
- of "threadanalysis": result = contains(gGlobalOptions, optThreadAnalysis)
- of "stacktrace": result = contains(gOptions, optStackTrace)
- of "linetrace": result = contains(gOptions, optLineTrace)
- of "debugger": result = contains(gOptions, optEndb)
- of "profiler": result = contains(gOptions, optProfiler)
- of "memtracker": result = contains(gOptions, optMemTracker)
- of "checks", "x": result = gOptions * ChecksOptions == ChecksOptions
- of "floatchecks":
- result = gOptions * {optNaNCheck, optInfCheck} == {optNaNCheck, optInfCheck}
- of "infchecks": result = contains(gOptions, optInfCheck)
- of "nanchecks": result = contains(gOptions, optNaNCheck)
- of "nilchecks": result = contains(gOptions, optNilCheck)
- of "objchecks": result = contains(gOptions, optObjCheck)
- of "fieldchecks": result = contains(gOptions, optFieldCheck)
- of "rangechecks": result = contains(gOptions, optRangeCheck)
- of "boundchecks": result = contains(gOptions, optBoundsCheck)
- of "overflowchecks": result = contains(gOptions, optOverflowCheck)
- of "linedir": result = contains(gOptions, optLineDir)
- of "assertions", "a": result = contains(gOptions, optAssert)
- of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim)
- of "run", "r": result = contains(gGlobalOptions, optRun)
- of "symbolfiles": result = contains(gGlobalOptions, optSymbolFiles)
- of "genscript": result = contains(gGlobalOptions, optGenScript)
- of "threads": result = contains(gGlobalOptions, optThreads)
- of "taintmode": result = contains(gGlobalOptions, optTaintMode)
- of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
- of "implicitstatic": result = contains(gOptions, optImplicitStatic)
- of "patterns": result = contains(gOptions, optPatterns)
- of "experimental": result = gExperimentalMode
- of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
- else: invalidCmdLineOption(passCmd1, switch, info)
- proc processPath(path: string, info: TLineInfo,
- notRelativeToProj = false): string =
- let p = if notRelativeToProj or os.isAbsolute(path) or
- '$' in path:
- path
- else:
- options.gProjectPath / path
- try:
- result = pathSubs(p, info.toFullPath().splitFile().dir)
- except ValueError:
- localError(info, "invalid path: " & p)
- result = p
- proc processCfgPath(path: string, info: TLineInfo): string =
- let path = if path[0] == '"': strutils.unescape(path) else: path
- let basedir = info.toFullPath().splitFile().dir
- let p = if os.isAbsolute(path) or '$' in path:
- path
- else:
- basedir / path
- try:
- result = pathSubs(p, basedir)
- except ValueError:
- localError(info, "invalid path: " & p)
- result = p
- proc trackDirty(arg: string, info: TLineInfo) =
- var a = arg.split(',')
- if a.len != 4: localError(info, errTokenExpected,
- "DIRTY_BUFFER,ORIGINAL_FILE,LINE,COLUMN")
- var line, column: int
- if parseUtils.parseInt(a[2], line) <= 0:
- localError(info, errInvalidNumber, a[1])
- if parseUtils.parseInt(a[3], column) <= 0:
- localError(info, errInvalidNumber, a[2])
- let dirtyOriginalIdx = a[1].fileInfoIdx
- if dirtyOriginalIdx >= 0:
- msgs.setDirtyFile(dirtyOriginalIdx, a[0])
- gTrackPos = newLineInfo(dirtyOriginalIdx, line, column)
- proc track(arg: string, info: TLineInfo) =
- var a = arg.split(',')
- if a.len != 3: localError(info, errTokenExpected, "FILE,LINE,COLUMN")
- var line, column: int
- if parseUtils.parseInt(a[1], line) <= 0:
- localError(info, errInvalidNumber, a[1])
- if parseUtils.parseInt(a[2], column) <= 0:
- localError(info, errInvalidNumber, a[2])
- gTrackPos = newLineInfo(a[0], line, column)
- proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
- if pass in {passCmd2, passPP}:
- expectArg(switch, arg, pass, info)
- options.inclDynlibOverride(arg)
- proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
- config: ConfigRef = nil) =
- var
- theOS: TSystemOS
- cpu: TSystemCPU
- key, val: string
- case switch.normalize
- of "path", "p":
- expectArg(switch, arg, pass, info)
- addPath(if pass == passPP: processCfgPath(arg, info) else: processPath(arg, info), info)
- of "nimblepath", "babelpath":
- # keep the old name for compat
- if pass in {passCmd2, passPP} and not options.gNoNimblePath:
- expectArg(switch, arg, pass, info)
- let path = processPath(arg, info, notRelativeToProj=true)
- nimblePath(path, info)
- of "nonimblepath", "nobabelpath":
- expectNoArg(switch, arg, pass, info)
- disableNimblePath()
- of "excludepath":
- expectArg(switch, arg, pass, info)
- let path = processPath(arg, info)
- options.searchPaths.keepItIf( cmpPaths(it, path) != 0 )
- options.lazyPaths.keepItIf( cmpPaths(it, path) != 0 )
- if (len(path) > 0) and (path[len(path) - 1] == DirSep):
- let strippedPath = path[0 .. (len(path) - 2)]
- options.searchPaths.keepItIf( cmpPaths(it, strippedPath) != 0 )
- options.lazyPaths.keepItIf( cmpPaths(it, strippedPath) != 0 )
- of "nimcache":
- expectArg(switch, arg, pass, info)
- options.nimcacheDir = processPath(arg, info, true)
- of "out", "o":
- expectArg(switch, arg, pass, info)
- options.outFile = arg
- of "docseesrcurl":
- expectArg(switch, arg, pass, info)
- options.docSeeSrcUrl = arg
- of "mainmodule", "m":
- discard "allow for backwards compatibility, but don't do anything"
- of "define", "d":
- expectArg(switch, arg, pass, info)
- if {':', '='} in arg:
- splitSwitch(arg, key, val, pass, info)
- defineSymbol(key, val)
- else:
- defineSymbol(arg)
- of "undef", "u":
- expectArg(switch, arg, pass, info)
- undefSymbol(arg)
- of "symbol":
- expectArg(switch, arg, pass, info)
- # deprecated, do nothing
- of "compile":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: processCompile(arg)
- of "link":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: addExternalFileToLink(arg)
- of "debuginfo":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optCDebug)
- of "embedsrc":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optEmbedOrigSrc)
- of "compileonly", "c":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optCompileOnly)
- of "nolinking":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optNoLinking)
- of "nomain":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optNoMain)
- of "forcebuild", "f":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optForceFullMake)
- of "project":
- expectNoArg(switch, arg, pass, info)
- gWholeProject = true
- of "gc":
- expectArg(switch, arg, pass, info)
- case arg.normalize
- of "boehm":
- gSelectedGC = gcBoehm
- defineSymbol("boehmgc")
- of "refc":
- gSelectedGC = gcRefc
- of "v2":
- gSelectedGC = gcV2
- of "markandsweep":
- gSelectedGC = gcMarkAndSweep
- defineSymbol("gcmarkandsweep")
- of "generational":
- gSelectedGC = gcGenerational
- defineSymbol("gcgenerational")
- of "go":
- gSelectedGC = gcGo
- defineSymbol("gogc")
- of "none":
- gSelectedGC = gcNone
- defineSymbol("nogc")
- of "stack", "regions":
- gSelectedGC= gcRegions
- defineSymbol("gcregions")
- else: localError(info, errNoneBoehmRefcExpectedButXFound, arg)
- of "warnings", "w":
- if processOnOffSwitchOrList({optWarns}, arg, pass, info): listWarnings()
- of "warning": processSpecificNote(arg, wWarning, pass, info, switch)
- of "hint": processSpecificNote(arg, wHint, pass, info, switch)
- of "hints":
- if processOnOffSwitchOrList({optHints}, arg, pass, info): listHints()
- of "threadanalysis": processOnOffSwitchG({optThreadAnalysis}, arg, pass, info)
- of "stacktrace": processOnOffSwitch({optStackTrace}, arg, pass, info)
- of "excessivestacktrace": processOnOffSwitchG({optExcessiveStackTrace}, arg, pass, info)
- of "linetrace": processOnOffSwitch({optLineTrace}, arg, pass, info)
- of "debugger":
- case arg.normalize
- of "on", "endb":
- gOptions.incl optEndb
- defineSymbol("endb")
- of "off":
- gOptions.excl optEndb
- undefSymbol("endb")
- of "native", "gdb":
- incl(gGlobalOptions, optCDebug)
- gOptions = gOptions + {optLineDir} - {optEndb}
- defineSymbol("nimTypeNames", nil) # type names are used in gdb pretty printing
- undefSymbol("endb")
- else:
- localError(info, "expected endb|gdb but found " & arg)
- of "profiler":
- processOnOffSwitch({optProfiler}, arg, pass, info)
- if optProfiler in gOptions: defineSymbol("profiler")
- else: undefSymbol("profiler")
- of "memtracker":
- processOnOffSwitch({optMemTracker}, arg, pass, info)
- if optMemTracker in gOptions: defineSymbol("memtracker")
- else: undefSymbol("memtracker")
- of "checks", "x": processOnOffSwitch(ChecksOptions, arg, pass, info)
- of "floatchecks":
- processOnOffSwitch({optNaNCheck, optInfCheck}, arg, pass, info)
- of "infchecks": processOnOffSwitch({optInfCheck}, arg, pass, info)
- of "nanchecks": processOnOffSwitch({optNaNCheck}, arg, pass, info)
- of "nilchecks": processOnOffSwitch({optNilCheck}, arg, pass, info)
- of "objchecks": processOnOffSwitch({optObjCheck}, arg, pass, info)
- of "fieldchecks": processOnOffSwitch({optFieldCheck}, arg, pass, info)
- of "rangechecks": processOnOffSwitch({optRangeCheck}, arg, pass, info)
- of "boundchecks": processOnOffSwitch({optBoundsCheck}, arg, pass, info)
- of "overflowchecks": processOnOffSwitch({optOverflowCheck}, arg, pass, info)
- of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info)
- of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info)
- of "deadcodeelim": processOnOffSwitchG({optDeadCodeElim}, arg, pass, info)
- of "threads":
- processOnOffSwitchG({optThreads}, arg, pass, info)
- #if optThreads in gGlobalOptions: incl(gNotes, warnGcUnsafe)
- of "tlsemulation": processOnOffSwitchG({optTlsEmulation}, arg, pass, info)
- of "taintmode": processOnOffSwitchG({optTaintMode}, arg, pass, info)
- of "implicitstatic":
- processOnOffSwitch({optImplicitStatic}, arg, pass, info)
- of "patterns":
- processOnOffSwitch({optPatterns}, arg, pass, info)
- of "opt":
- expectArg(switch, arg, pass, info)
- case arg.normalize
- of "speed":
- incl(gOptions, optOptimizeSpeed)
- excl(gOptions, optOptimizeSize)
- of "size":
- excl(gOptions, optOptimizeSpeed)
- incl(gOptions, optOptimizeSize)
- of "none":
- excl(gOptions, optOptimizeSpeed)
- excl(gOptions, optOptimizeSize)
- else: localError(info, errNoneSpeedOrSizeExpectedButXFound, arg)
- of "app":
- expectArg(switch, arg, pass, info)
- case arg.normalize
- of "gui":
- incl(gGlobalOptions, optGenGuiApp)
- defineSymbol("executable")
- defineSymbol("guiapp")
- of "console":
- excl(gGlobalOptions, optGenGuiApp)
- defineSymbol("executable")
- defineSymbol("consoleapp")
- of "lib":
- incl(gGlobalOptions, optGenDynLib)
- excl(gGlobalOptions, optGenGuiApp)
- defineSymbol("library")
- defineSymbol("dll")
- of "staticlib":
- incl(gGlobalOptions, optGenStaticLib)
- excl(gGlobalOptions, optGenGuiApp)
- defineSymbol("library")
- defineSymbol("staticlib")
- else: localError(info, errGuiConsoleOrLibExpectedButXFound, arg)
- of "passc", "t":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: extccomp.addCompileOptionCmd(arg)
- of "passl", "l":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: extccomp.addLinkOptionCmd(arg)
- of "cincludes":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: cIncludes.add arg.processPath(info)
- of "clibdir":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: cLibs.add arg.processPath(info)
- of "clib":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: cLinkedLibs.add arg.processPath(info)
- of "header":
- if config != nil: config.headerFile = arg
- incl(gGlobalOptions, optGenIndex)
- of "index":
- processOnOffSwitchG({optGenIndex}, arg, pass, info)
- of "import":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: implicitImports.add arg
- of "include":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd2, passPP}: implicitIncludes.add arg
- of "listcmd":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optListCmd)
- of "genmapping":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optGenMapping)
- of "os":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd1, passPP}:
- theOS = platform.nameToOS(arg)
- if theOS == osNone: localError(info, errUnknownOS, arg)
- elif theOS != platform.hostOS:
- setTarget(theOS, targetCPU)
- of "cpu":
- expectArg(switch, arg, pass, info)
- if pass in {passCmd1, passPP}:
- cpu = platform.nameToCPU(arg)
- if cpu == cpuNone: localError(info, errUnknownCPU, arg)
- elif cpu != platform.hostCPU:
- setTarget(targetOS, cpu)
- of "run", "r":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optRun)
- of "verbosity":
- expectArg(switch, arg, pass, info)
- gVerbosity = parseInt(arg)
- gNotes = NotesVerbosity[gVerbosity]
- incl(gNotes, enableNotes)
- excl(gNotes, disableNotes)
- gMainPackageNotes = gNotes
- of "parallelbuild":
- expectArg(switch, arg, pass, info)
- gNumberOfProcessors = parseInt(arg)
- of "version", "v":
- expectNoArg(switch, arg, pass, info)
- writeVersionInfo(pass)
- of "advanced":
- expectNoArg(switch, arg, pass, info)
- writeAdvancedUsage(pass)
- of "help", "h":
- expectNoArg(switch, arg, pass, info)
- helpOnError(pass)
- of "symbolfiles":
- processOnOffSwitchG({optSymbolFiles}, arg, pass, info)
- of "skipcfg":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optSkipConfigFile)
- of "skipprojcfg":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optSkipProjConfigFile)
- of "skipusercfg":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optSkipUserConfigFile)
- of "skipparentcfg":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optSkipParentConfigFiles)
- of "genscript":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optGenScript)
- of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info)
- of "lib":
- expectArg(switch, arg, pass, info)
- libpath = processPath(arg, info, notRelativeToProj=true)
- of "putenv":
- expectArg(switch, arg, pass, info)
- splitSwitch(arg, key, val, pass, info)
- os.putEnv(key, val)
- of "cc":
- expectArg(switch, arg, pass, info)
- setCC(arg)
- of "track":
- expectArg(switch, arg, pass, info)
- track(arg, info)
- of "trackdirty":
- expectArg(switch, arg, pass, info)
- trackDirty(arg, info)
- of "suggest":
- expectNoArg(switch, arg, pass, info)
- gIdeCmd = ideSug
- of "def":
- expectNoArg(switch, arg, pass, info)
- gIdeCmd = ideDef
- of "eval":
- expectArg(switch, arg, pass, info)
- gEvalExpr = arg
- of "context":
- expectNoArg(switch, arg, pass, info)
- gIdeCmd = ideCon
- of "usages":
- expectNoArg(switch, arg, pass, info)
- gIdeCmd = ideUse
- of "stdout":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optStdout)
- of "listfullpaths":
- expectNoArg(switch, arg, pass, info)
- gListFullPaths = true
- of "dynliboverride":
- dynlibOverride(switch, arg, pass, info)
- of "cs":
- # only supported for compatibility. Does nothing.
- expectArg(switch, arg, pass, info)
- of "experimental":
- expectNoArg(switch, arg, pass, info)
- gExperimentalMode = true
- of "nocppexceptions":
- expectNoArg(switch, arg, pass, info)
- incl(gGlobalOptions, optNoCppExceptions)
- defineSymbol("noCppExceptions")
- of "cppdefine":
- expectArg(switch, arg, pass, info)
- if config != nil:
- config.cppDefine(arg)
- of "newruntime":
- expectNoArg(switch, arg, pass, info)
- newDestructors = true
- defineSymbol("nimNewRuntime")
- else:
- if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
- else: invalidCmdLineOption(pass, switch, info)
- proc processCommand(switch: string, pass: TCmdLinePass) =
- var cmd, arg: string
- splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
- processSwitch(cmd, arg, pass, gCmdLineInfo)
- var
- arguments* = ""
- # the arguments to be passed to the program that
- # should be run
- proc processSwitch*(pass: TCmdLinePass; p: OptParser) =
- # hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
- # we fix this here
- var bracketLe = strutils.find(p.key, '[')
- if bracketLe >= 0:
- var key = substr(p.key, 0, bracketLe - 1)
- var val = substr(p.key, bracketLe + 1) & ':' & p.val
- processSwitch(key, val, pass, gCmdLineInfo)
- else:
- processSwitch(p.key, p.val, pass, gCmdLineInfo)
- proc processArgument*(pass: TCmdLinePass; p: OptParser;
- argsCount: var int): bool =
- if argsCount == 0:
- # nim filename.nims is the same as "nim e filename.nims":
- if p.key.endswith(".nims"):
- options.command = "e"
- options.gProjectName = unixToNativePath(p.key)
- arguments = cmdLineRest(p)
- result = true
- elif pass != passCmd2:
- options.command = p.key
- else:
- if pass == passCmd1: options.commandArgs.add p.key
- if argsCount == 1:
- # support UNIX style filenames everywhere for portable build scripts:
- options.gProjectName = unixToNativePath(p.key)
- arguments = cmdLineRest(p)
- result = true
- inc argsCount
|