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 10## Module that implements ``gorge`` for the compiler. 11 12import msgs, std / sha1, os, osproc, streams, options, 13 lineinfos, pathutils 14 15proc readOutput(p: Process): (string, int) = 16 result[0] = "" 17 var output = p.outputStream 18 while not output.atEnd: 19 result[0].add(output.readLine) 20 result[0].add("\n") 21 if result[0].len > 0: 22 result[0].setLen(result[0].len - "\n".len) 23 result[1] = p.waitForExit 24 25proc opGorge*(cmd, input, cache: string, info: TLineInfo; conf: ConfigRef): (string, int) = 26 let workingDir = parentDir(toFullPath(conf, info)) 27 if cache.len > 0: 28 let h = secureHash(cmd & "\t" & input & "\t" & cache) 29 let filename = toGeneratedFile(conf, AbsoluteFile("gorge_" & $h), "txt").string 30 var f: File 31 if optForceFullMake notin conf.globalOptions and open(f, filename): 32 result = (f.readAll, 0) 33 f.close 34 return 35 var readSuccessful = false 36 try: 37 var p = startProcess(cmd, workingDir, 38 options={poEvalCommand, poStdErrToStdOut}) 39 if input.len != 0: 40 p.inputStream.write(input) 41 p.inputStream.close() 42 result = p.readOutput 43 p.close() 44 readSuccessful = true 45 # only cache successful runs: 46 if result[1] == 0: 47 writeFile(filename, result[0]) 48 except IOError, OSError: 49 if not readSuccessful: result = ("", -1) 50 else: 51 try: 52 var p = startProcess(cmd, workingDir, 53 options={poEvalCommand, poStdErrToStdOut}) 54 if input.len != 0: 55 p.inputStream.write(input) 56 p.inputStream.close() 57 result = p.readOutput 58 p.close() 59 except IOError, OSError: 60 result = ("", -1) 61