gorgeimpl.nim 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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.
  10. import msgs, std / sha1, os, osproc, streams, strutils, options,
  11. lineinfos, pathutils
  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; conf: ConfigRef): (string, int) =
  22. let workingDir = parentDir(toFullPath(conf, info))
  23. if cache.len > 0:
  24. let h = secureHash(cmd & "\t" & input & "\t" & cache)
  25. let filename = toGeneratedFile(conf, AbsoluteFile("gorge_" & $h), "txt").string
  26. var f: File
  27. if optForceFullMake notin conf.globalOptions and 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)