-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
97 lines (79 loc) · 1.81 KB
/
main.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
// Copyright (c) 2013 Ostap Cherkashin, Julius Chrobak. You can use this source code
// under the terms of the MIT License found in the LICENSE file.
package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"strings"
)
const usage = `comp [-f <files>] <expr>
examples
cat file.json | comp -f @json '[ i | i <- in, i.name =~ \"hello\" ]'
comp -f file1.json,file2.csv '[ {i, j} | i <- file1, j <- file2, i.id == j.id ]'
flags
`
func openFiles(files string) (map[string]io.Reader, error) {
res := make(map[string]io.Reader)
if files != "" {
for _, f := range strings.Split(files, ",") {
if f[0] == '@' {
f = fmt.Sprintf("in.%v", f[1:])
res[f] = os.Stdin
} else {
r, err := os.Open(f)
if err != nil {
return nil, err
}
res[f] = r
}
}
}
return res, nil
}
func Run(expr string, inputs map[string]io.Reader, output io.Writer) error {
store := Store{make(map[string]Type), make(map[string]Value)}
for k, v := range inputs {
if err := store.Add(k, v); err != nil {
return err
}
}
decls := store.Decls()
prg, rt, err := Compile(expr, decls)
if err != nil {
return err
}
res := prg.Run(new(Stack))
if res != nil {
if err := res.Quote(output, rt); err != nil {
return err
}
fmt.Printf("\n")
}
return nil
}
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, usage)
flag.PrintDefaults()
}
files := flag.String("f", "", "comma separated list of files (@json @csv @txt @xml for stdin types)")
flag.Parse()
args := flag.Args()
if len(args) != 1 {
flag.Usage()
return
}
inputs, err := openFiles(*files)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
if err := Run(args[0], inputs, os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
}
func init() {
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
}