-
Notifications
You must be signed in to change notification settings - Fork 0
/
compile.go
99 lines (93 loc) · 1.91 KB
/
compile.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"os"
"io"
"bufio"
"fmt"
"path"
"exec"
"runtime"
)
func compile(source io.ReadSeeker, targetname string) os.Error {
O, err := getArchSym()
if err != nil {
return err
}
gc := O + "g"
gl := O + "l"
tempobj := path.Join(os.TempDir(), targetname+"."+O)
_, err = source.Seek(0, 0)
if err != nil {
return err
}
bufsource := bufio.NewReader(source)
var insource io.Reader = bufsource
if line, err := bufsource.ReadString('\n'); err != nil && err != os.EOF ||
len(line) < 2 || line[:2] != "#!" {
_, err := source.Seek(0, 0)
if err != nil {
return err
}
insource = source
}
err = run(gc, []string{gc, "-o", tempobj, "/dev/stdin"}, insource)
if err != nil {
return err
}
err = run(gl, []string{gl, "-o", path.Join(storedir, targetname),
tempobj},
nil)
return err
}
func getArchSym() (sym string, err os.Error) {
archsyms := map[string]string{
"arm": "5",
"amd64": "6",
"i386": "8",
}
if sym, ok := archsyms[runtime.GOARCH]; ok {
return sym, nil
}
return "", os.ErrorString("Unrecognized architecture")
}
func run(name string, argv []string, stdin io.Reader) os.Error {
executable, err := exec.LookPath(name)
if err != nil {
return err
}
var sin int
if stdin == nil {
sin = exec.PassThrough
} else {
sin = exec.Pipe
}
proc, err := exec.Run(executable, argv, os.Environ(), "", sin,
exec.PassThrough, exec.PassThrough)
if err != nil {
return err
}
defer proc.Close()
if stdin != nil {
if _, err := io.Copy(proc.Stdin, stdin); err != nil {
return err
}
if err := proc.Stdin.Close(); err != nil {
return err
}
}
wm, err := proc.Wait(0)
for err == os.EINTR {
wm, err = proc.Wait(0)
}
if err != nil {
return err
}
if wm.Exited() {
if es := wm.ExitStatus(); es != 0 {
return os.ErrorString(fmt.Sprintf("%s returned status %d", name,
es))
}
return nil
}
return os.ErrorString("Something wierd happend with wait()")
}