@@ -3,88 +3,69 @@ package utils
33import (
44 "flag"
55 "fmt"
6− "io"
76 "os"
87 "runtime"
9− "syscall"
108)
119
12−type Red struct {
13− parent io.Writer
10+type Config struct {
11+ Code string
12+ Quiet bool
13+ Exp string
14+ Ps1, Ps2 string
15+ Args []string
16+ Interactive, OurInteractive bool
1417}
1518
16−func (r *Red) Write(p []byte) (n int, err error) {
17− r.parent.Write(([]byte("\033[31m")))
18− n, err = r.parent.Write(p)
19− r.parent.Write(([]byte("\033[0m")))
20− return n, err
21−}
19+func ParseFlags() *Config {
20+ config := &Config{}
2221
23−func DoCli(p PluginBase) {
24− var interactive, ourInteractive bool
25− var code string
26− var quiet bool
27− var exp string
28− var colorizeStderr bool
29− var ps1, ps2 string
22+ flag.StringVar(&config.Code, "c", "", "code to run")
23+ flag.StringVar(&config.Exp, "e", "", "expression to print")
3024
31− flag.StringVar(&code, "c", "", "code to run")
32− flag.StringVar(&exp, "e", "", "expression to print")
25+ flag.StringVar(&config.Ps1, "ps1", "--> ", "PS1")
26+ flag.StringVar(&config.Ps2, "ps2", "... ", "PS2")
3327
34− flag.StringVar(&ps1, "ps1", "--> ", "PS1")
35− flag.StringVar(&ps2, "ps2", "... ", "PS2")
28+ flag.BoolVar(&config.Interactive, "i", false, "interactive")
29+ flag.BoolVar(&config.OurInteractive, "I", false, "like -i, but never use language REPL")
30+ flag.BoolVar(&config.Quiet, "q", false, "quiet")
3631
37− flag.BoolVar(&interactive, "i", false, "interactive")
38− flag.BoolVar(&ourInteractive, "I", false, "like -i, but never use language REPL")
39− flag.BoolVar(&quiet, "q", false, "quiet")
32+ flag.Parse()
4033
41− flag.BoolVar(&colorizeStderr, "R", false, "color standard error red")
34+ config.Args = flag.Args()
35+ return config
36+}
4237
43− flag.Parse()
38+func DoCli(p PluginBase) {
4439
45− args := flag.Args()
40+ config := ParseFlags()
4641
4742 runtime.LockOSThread()
4843 p.Open()
49− lang := &Language{ptr: p, ps1: ps1}
44+ lang := &Language{ptr: p, ps1: config.Ps1}
5045
51− if !quiet {
46+ if !config.Quiet {
5247 fmt.Println(lang.Version())
5348 }
5449
55− if colorizeStderr {
56− var pipes [2]int
57− newStderr, err := syscall.Dup(2)
58− if err != nil {
59− panic(err)
60− }
61− syscall.Pipe(pipes[:])
62− syscall.Dup2(pipes[1], 2)
63− syscall.Close(pipes[1])
64− o := &Red{parent: os.NewFile(uintptr(newStderr), "o")}
65− i := os.NewFile(uintptr(pipes[0]), "i")
66− go io.Copy(o, i)
67− }
68−
69− if code != "" {
70− lang.Eval(code)
50+ if config.Code != "" {
51+ lang.Eval(config.Code)
7152 }
72− if exp != "" {
73− lang.EvalAndTryToPrint(exp)
53+ if config.Exp != "" {
54+ lang.EvalAndTryToPrint(config.Exp)
7455 }
75− if len(args) > 0 {
76− if _, err := os.Stat(args[0]); os.IsNotExist(err) {
77− fmt.Println("No such file:", args[0])
56+ if len(config.Args) > 0 {
57+ if _, err := os.Stat(config.Args[0]); os.IsNotExist(err) {
58+ fmt.Println("No such file:", config.Args[0])
7859 os.Exit(2)
7960 } else {
80− lang.EvalFile(args[0], args[1:])
61+ lang.EvalFile(config.Args[0], config.Args[1:])
8162 }
8263 }
8364
84− if interactive {
85− lang.SetPrompts(ps1, ps2)
65+ if config.Interactive {
66+ lang.SetPrompts(config.Ps1, config.Ps2)
8667 lang.REPL()
87− } else if ourInteractive {
68+ } else if config.OurInteractive {
8869 //LinenoiseSetCompleter(func(s string) []string {
8970 // return []string{s + "A", s + "B", s + "B"}
9071 //})