cmdlinehelper.nim 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2018 Nim contributors
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Helpers for binaries that use compiler passes, e.g.: nim, nimsuggest, nimfix
  10. import
  11. options, idents, nimconf, extccomp, commands, msgs,
  12. lineinfos, modulegraphs, condsyms, os, pathutils, parseopt
  13. from strutils import normalize
  14. proc prependCurDir*(f: AbsoluteFile): AbsoluteFile =
  15. when defined(unix):
  16. if os.isAbsolute(f.string): result = f
  17. else: result = AbsoluteFile("./" & f.string)
  18. else:
  19. result = f
  20. proc addCmdPrefix*(result: var string, kind: CmdLineKind) =
  21. # consider moving this to std/parseopt
  22. case kind
  23. of cmdLongOption: result.add "--"
  24. of cmdShortOption: result.add "-"
  25. of cmdArgument, cmdEnd: discard
  26. type
  27. NimProg* = ref object
  28. suggestMode*: bool
  29. supportsStdinFile*: bool
  30. processCmdLine*: proc(pass: TCmdLinePass, cmd: string; config: ConfigRef)
  31. proc initDefinesProg*(self: NimProg, conf: ConfigRef, name: string) =
  32. condsyms.initDefines(conf.symbols)
  33. defineSymbol conf.symbols, name
  34. proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
  35. self.processCmdLine(passCmd1, "", conf)
  36. if conf.projectIsCmd and conf.projectName in ["-", ""]:
  37. handleCmdInput(conf)
  38. elif self.supportsStdinFile and conf.projectName == "-":
  39. handleStdinInput(conf)
  40. elif conf.projectName != "":
  41. try:
  42. conf.projectFull = canonicalizePath(conf, AbsoluteFile conf.projectName)
  43. except OSError:
  44. conf.projectFull = AbsoluteFile conf.projectName
  45. let p = splitFile(conf.projectFull)
  46. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  47. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  48. conf.projectName = p.name
  49. else:
  50. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile getCurrentDir())
  51. proc loadConfigsAndProcessCmdLine*(self: NimProg, cache: IdentCache; conf: ConfigRef;
  52. graph: ModuleGraph): bool =
  53. if self.suggestMode:
  54. conf.command = "nimsuggest"
  55. if conf.command == "e":
  56. incl(conf.globalOptions, optWasNimscript)
  57. loadConfigs(DefaultConfig, cache, conf, graph.idgen) # load all config files
  58. if not self.suggestMode:
  59. let scriptFile = conf.projectFull.changeFileExt("nims")
  60. # 'nim foo.nims' means to just run the NimScript file and do nothing more:
  61. if fileExists(scriptFile) and scriptFile == conf.projectFull:
  62. if conf.command == "":
  63. conf.command = "e"
  64. return false
  65. elif conf.command.normalize == "e":
  66. return false
  67. # now process command line arguments again, because some options in the
  68. # command line can overwrite the config file's settings
  69. extccomp.initVars(conf)
  70. self.processCmdLine(passCmd2, "", conf)
  71. if conf.command == "":
  72. rawMessage(conf, errGenerated, "command missing")
  73. graph.suggestMode = self.suggestMode
  74. return true
  75. proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef; graph: ModuleGraph): bool =
  76. ## Alias for loadConfigsAndProcessCmdLine, here for backwards compatibility
  77. loadConfigsAndProcessCmdLine(self, cache, conf, graph)