main.mx raw
1 package main
2
3 import (
4 "os"
5 )
6
7 func readFile(path string) (data []byte, err error) {
8 f, err := os.Open(path)
9 if err != nil { return }
10 info, err := f.Stat()
11 if err != nil {
12 f.Close()
13 return
14 }
15 sz := int32(info.Size())
16 if sz == 0 { sz = 4096 }
17 buf := []byte{:0:sz + 1}
18 for {
19 if len(buf) >= cap(buf) {
20 nb := []byte{:len(buf):len(buf) * 2}
21 copy(nb, buf)
22 buf = nb
23 }
24 n, rerr := f.Read(buf[len(buf):cap(buf)])
25 buf = buf[:len(buf)+n]
26 if rerr != nil { break }
27 }
28 f.Close()
29 data = buf
30 return
31 }
32
33 func writeFile(path string, data []byte) (err error) {
34 f, err := os.Create(path)
35 if err != nil { return }
36 _, err = f.Write(data)
37 cerr := f.Close()
38 if err == nil { err = cerr }
39 return
40 }
41
42 func main() {
43 args := os.Args
44 if len(args) == 0 {
45 args = argsFromCmdline()
46 }
47 if len(args) < 2 {
48 os.Stderr().Write([]byte("usage: moxiefmt [-w] file.mx ...\n"))
49 os.Exit(1)
50 }
51
52 write := false
53 files := []string{:0:len(args)}
54 for i := int32(1); i < int32(len(args)); i++ {
55 a := args[i]
56 if a == "-w" {
57 write = true
58 } else {
59 files = append(files, a)
60 }
61 }
62
63 if len(files) == 0 {
64 os.Stderr().Write([]byte("no files specified\n"))
65 os.Exit(1)
66 }
67
68 exitCode := int32(0)
69 for i := int32(0); i < int32(len(files)); i++ {
70 ok, err := processFile(files[i], write)
71 if err != nil {
72 os.Stderr().Write([]byte("moxiefmt: " | files[i] | ": " | err.Error() | "\n"))
73 exitCode = 1
74 }
75 if !ok { exitCode = 1 }
76 }
77 os.Exit(exitCode)
78 }
79
80 func argsFromCmdline() []string {
81 data, err := readFile("/proc/self/cmdline")
82 if err != nil { return nil }
83 args := []string{:0:8}
84 start := int32(0)
85 for i := int32(0); i < int32(len(data)); i++ {
86 if data[i] == 0 {
87 if i > start {
88 args = append(args, string(data[start:i]))
89 }
90 start = i + 1
91 }
92 }
93 if start < int32(len(data)) {
94 args = append(args, string(data[start:]))
95 }
96 return args
97 }
98
99 func processFile(path string, write bool) (ok bool, err error) {
100 src, err := readFile(path)
101 if err != nil { return }
102
103 out, errs := formatSource(string(src))
104 reportErrors(path, errs)
105 ok = len(errs) == 0
106
107 if write {
108 err = writeFile(path, []byte(out))
109 } else {
110 _, err = os.Stdout().Write([]byte(out))
111 }
112 return
113 }
114