-
Notifications
You must be signed in to change notification settings - Fork 29
/
gow_misc.go
118 lines (99 loc) · 2.48 KB
/
gow_misc.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"os"
"path/filepath"
"regexp"
"strings"
"syscall"
"github.com/mitranim/gg"
)
const (
// These names reflect standard naming and meaning.
// See our re-interpretation below.
ASCII_END_OF_TEXT = 3 // ^C
ASCII_FILE_SEPARATOR = 28 // ^\
ASCII_DEVICE_CONTROL_2 = 18 // ^R
ASCII_DEVICE_CONTROL_4 = 20 // ^T
ASCII_UNIT_SEPARATOR = 31 // ^- or ^?
ASCII_DELETE = 127
// These names reflect our re-interpretation of standard codes.
CODE_INTERRUPT = ASCII_END_OF_TEXT
CODE_QUIT = ASCII_FILE_SEPARATOR
CODE_RESTART = ASCII_DEVICE_CONTROL_2
CODE_STOP = ASCII_DEVICE_CONTROL_4
CODE_PRINT_COMMAND = ASCII_UNIT_SEPARATOR
)
var (
FD_TERM = syscall.Stdin
KILL_SIGS = []syscall.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM}
KILL_SIGS_OS = gg.Map(KILL_SIGS, toOsSignal[syscall.Signal])
RE_WORD = regexp.MustCompile(`^\w+$`)
PATH_SEP = string([]rune{os.PathSeparator})
REP_SINGLE_MULTI = strings.NewReplacer(
`\r\n`, gg.Newline,
`\r`, gg.Newline,
`\n`, gg.Newline,
)
)
/*
Making `.main` private reduces the chance of accidental cyclic walking by
reflection tools such as pretty printers.
*/
type Mained struct{ main *Main }
func (self *Mained) Init(val *Main) { self.main = val }
func (self *Mained) Main() *Main { return self.main }
/*
Implemented by `notify.EventInfo`.
Path must be an absolute filesystem path.
*/
type FsEvent interface{ Path() string }
// Implemented by `WatchNotify`.
type Watcher interface {
Init(*Main)
Deinit()
Run()
}
func commaSplit(val string) []string {
if len(val) == 0 {
return nil
}
return strings.Split(val, `,`)
}
func cleanExtension(val string) string {
ext := filepath.Ext(val)
if len(ext) > 0 && ext[0] == '.' {
return ext[1:]
}
return ext
}
func validateExtension(val string) {
if !RE_WORD.MatchString(val) {
panic(gg.Errf(`invalid extension %q`, val))
}
}
func toAbsPath(val string) string {
if !filepath.IsAbs(val) {
val = filepath.Join(cwd, val)
}
return filepath.Clean(val)
}
func toDirPath(val string) string {
if val == `` || strings.HasSuffix(val, PATH_SEP) {
return val
}
return val + PATH_SEP
}
func toAbsDirPath(val string) string { return toDirPath(toAbsPath(val)) }
func toOsSignal[A os.Signal](src A) os.Signal { return src }
func recLog() {
val := recover()
if val != nil {
log.Println(val)
}
}
func withNewline[A ~string](val A) A {
if gg.HasNewlineSuffix(val) {
return val
}
return val + A(gg.Newline)
}