forked from jmhodges/jsonpp
/
jsonpp.go
102 lines (85 loc) · 1.86 KB
/
jsonpp.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
100
101
102
package main
import (
"bytes"
"bufio"
"flag"
"fmt"
"json"
"os"
)
var newline = []uint8("\n")
func main() {
bufIn := bufio.NewReader(fileFromArguments())
lastLine := []uint8("")
// One meg is good enough for anybody
arr := make([]byte, 0, 1024*1024)
buf := bytes.NewBuffer(arr)
lineNum := int64(1)
for {
line, isPrefix, err := bufIn.ReadLine()
if err != nil && err != os.EOF {
genericError(err)
}
lastLine = append(lastLine, line...)
if !isPrefix && len(lastLine) != 0 {
indentAndPrint(buf, lastLine, lineNum)
lineNum += 1
lastLine = []uint8("")
}
if err == os.EOF {
os.Exit(0)
}
}
}
func indentAndPrint(buf *bytes.Buffer, js []uint8, lineNum int64) {
jsErr := json.Indent(buf, js, "", " ")
if (jsErr != nil) {
malformedJson(jsErr, js, lineNum)
}
os.Stdout.Write(buf.Bytes())
os.Stdout.Write(newline)
buf.Reset()
}
func malformedJson(jsErr os.Error, js []uint8, lineNum int64) {
os.Stdout.Sync()
synErr, isSynError := (jsErr).(*json.SyntaxError)
fmt.Fprintf(os.Stderr, "ERROR: Broken json on line %d: %s\n", lineNum, jsErr)
if (isSynError) {
prefix := ""
suffix := ""
begin := 0
if synErr.Offset > 15 {
begin = int(synErr.Offset - 15)
prefix = "..."
}
end := begin + 30
if end > len(js) {
end = len(js)
} else {
suffix = "..."
}
fmt.Fprintf(os.Stderr, " Context: %s%s%s\n", prefix, js[begin:end], suffix)
}
os.Exit(1)
}
func fileFromArguments() *os.File {
flag.Parse()
args := flag.Args()
if len(args) > 1 {
msg := fmt.Sprintf("only specify 0 or 1 files in the arguments, not %d\n", len(args))
genericError(os.NewError(msg))
}
if len(args) == 0 {
return os.Stdin
}
file, err := os.OpenFile(args[0], os.O_RDONLY, 0)
if err != nil {
genericError(err)
}
return file
}
func genericError(err os.Error) {
os.Stdout.Sync()
fmt.Fprintf(os.Stderr, "ERROR: %s", err)
os.Exit(2)
}