package main import ( "bytes" "path/filepath" "strings" ) func splitSpaces(s string) []string { var r []string tokStart := -1 for i, ch := range s { if ch == ' ' || ch == '\t' { if tokStart >= 0 { r = append(r, s[tokStart:i]) tokStart = -1 } } else { if tokStart < 0 { tokStart = i } } } if tokStart >= 0 { r = append(r, s[tokStart:]) } Log("splitSpace(%q)=%q", s, r) return r } func splitSpacesBytes(s []byte) (r [][]byte) { tokStart := -1 for i, ch := range s { if ch == ' ' || ch == '\t' { if tokStart >= 0 { r = append(r, s[tokStart:i]) tokStart = -1 } } else { if tokStart < 0 { tokStart = i } } } if tokStart >= 0 { r = append(r, s[tokStart:]) } Log("splitSpace(%q)=%q", s, r) return r } func matchPattern(pat, str string) bool { i := strings.IndexByte(pat, '%') if i < 0 { return pat == str } return strings.HasPrefix(str, pat[:i]) && strings.HasSuffix(str, pat[i+1:]) } func matchPatternBytes(pat, str []byte) bool { i := bytes.IndexByte(pat, '%') if i < 0 { return bytes.Equal(pat, str) } return bytes.HasPrefix(str, pat[:i]) && bytes.HasSuffix(str, pat[i+1:]) } func substPattern(pat, repl, str string) string { ps := strings.SplitN(pat, "%", 2) if len(ps) != 2 { if str == pat { return repl } return str } in := str trimed := str if ps[0] != "" { trimed = strings.TrimPrefix(in, ps[0]) if trimed == in { return str } } in = trimed if ps[1] != "" { trimed = strings.TrimSuffix(in, ps[1]) if trimed == in { return str } } rs := strings.SplitN(repl, "%", 2) if len(rs) != 2 { return repl } return rs[0] + trimed + rs[1] } func substPatternBytes(pat, repl, str []byte) []byte { ps := bytes.SplitN(pat, []byte{'%'}, 2) if len(ps) != 2 { if bytes.Equal(str, pat) { return repl } return str } in := str trimed := str if len(ps[0]) != 0 { trimed = bytes.TrimPrefix(in, ps[0]) if bytes.Equal(trimed, in) { return str } } in = trimed if len(ps[1]) != 0 { trimed = bytes.TrimSuffix(in, ps[1]) if bytes.Equal(trimed, in) { return str } } rs := bytes.SplitN(repl, []byte{'%'}, 2) if len(rs) != 2 { return repl } r := make([]byte, 0, len(rs[0])+len(trimed)+len(rs[1])+1) r = append(r, rs[0]...) r = append(r, trimed...) r = append(r, rs[1]...) return r } func substRef(pat, repl, str string) string { if strings.IndexByte(pat, '%') >= 0 && strings.IndexByte(repl, '%') >= 0 { return substPattern(pat, repl, str) } str = strings.TrimSuffix(str, pat) return str + repl } func stripExt(s string) string { suf := filepath.Ext(s) return s[:len(s)-len(suf)] } func trimLeftSpace(s string) string { for i, ch := range s { if ch != ' ' && ch != '\t' { return s[i:] } } return "" } func trimLeftSpaceBytes(s []byte) []byte { for i, ch := range s { if ch != ' ' && ch != '\t' { return s[i:] } } return nil }