gorgeimpl.nim 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2017 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Module that implements ``gorge`` for the compiler as well as
  10. ## the scriptable import mechanism.
  11. import msgs, securehash, os, osproc, streams, strutils, options
  12. proc readOutput(p: Process): (string, int) =
  13. result[0] = ""
  14. var output = p.outputStream
  15. while not output.atEnd:
  16. result[0].add(output.readLine)
  17. result[0].add("\n")
  18. if result[0].len > 0:
  19. result[0].setLen(result[0].len - "\n".len)
  20. result[1] = p.waitForExit
  21. proc opGorge*(cmd, input, cache: string, info: TLineInfo): (string, int) =
  22. let workingDir = parentDir(info.toFullPath)
  23. if cache.len > 0:# and optForceFullMake notin gGlobalOptions:
  24. let h = secureHash(cmd & "\t" & input & "\t" & cache)
  25. let filename = options.toGeneratedFile("gorge_" & $h, "txt")
  26. var f: File
  27. if open(f, filename):
  28. result = (f.readAll, 0)
  29. f.close
  30. return
  31. var readSuccessful = false
  32. try:
  33. var p = startProcess(cmd, workingDir,
  34. options={poEvalCommand, poStderrToStdout})
  35. if input.len != 0:
  36. p.inputStream.write(input)
  37. p.inputStream.close()
  38. result = p.readOutput
  39. readSuccessful = true
  40. # only cache successful runs:
  41. if result[1] == 0:
  42. writeFile(filename, result[0])
  43. except IOError, OSError:
  44. if not readSuccessful: result = ("", -1)
  45. else:
  46. try:
  47. var p = startProcess(cmd, workingDir,
  48. options={poEvalCommand, poStderrToStdout})
  49. if input.len != 0:
  50. p.inputStream.write(input)
  51. p.inputStream.close()
  52. result = p.readOutput
  53. except IOError, OSError:
  54. result = ("", -1)
  55. proc scriptableImport*(pkg, subdir: string; info: TLineInfo): string =
  56. var cmd = getConfigVar("resolver.exe")
  57. if cmd.len == 0: cmd = "nimresolve"
  58. else: cmd = quoteShell(cmd)
  59. cmd.add " --source:"
  60. cmd.add quoteShell(info.toFullPath())
  61. cmd.add " --stdlib:"
  62. cmd.add quoteShell(options.libpath)
  63. cmd.add " --project:"
  64. cmd.add quoteShell(gProjectFull)
  65. if subdir.len != 0:
  66. cmd.add " --subdir:"
  67. cmd.add quoteShell(subdir)
  68. if options.gNoNimblePath:
  69. cmd.add " --nonimblepath"
  70. cmd.add ' '
  71. cmd.add quoteShell(pkg)
  72. let (res, exitCode) = opGorge(cmd, "", cmd, info)
  73. if exitCode == 0:
  74. result = res.strip()
  75. elif res.len > 0:
  76. localError(info, res)
  77. else:
  78. localError(info, "cannot resolve: " & (pkg / subdir))