strings.go raw
1 package ini
2
3 import (
4 "strings"
5 )
6
7 func trimProfileComment(s string) string {
8 r, _, _ := strings.Cut(s, "#")
9 r, _, _ = strings.Cut(r, ";")
10 return r
11 }
12
13 func trimPropertyComment(s string) string {
14 r, _, _ := strings.Cut(s, " #")
15 r, _, _ = strings.Cut(r, " ;")
16 r, _, _ = strings.Cut(r, "\t#")
17 r, _, _ = strings.Cut(r, "\t;")
18 return r
19 }
20
21 // assumes no surrounding comment
22 func splitProperty(s string) (string, string, bool) {
23 equalsi := strings.Index(s, "=")
24 coloni := strings.Index(s, ":") // LEGACY: also supported for property assignment
25 sep := "="
26 if equalsi == -1 || coloni != -1 && coloni < equalsi {
27 sep = ":"
28 }
29
30 k, v, ok := strings.Cut(s, sep)
31 if !ok {
32 return "", "", false
33 }
34 return strings.TrimSpace(k), strings.TrimSpace(v), true
35 }
36
37 // assumes no surrounding comment, whitespace, or profile brackets
38 func splitProfile(s string) (string, string) {
39 var first int
40 for i, r := range s {
41 if isLineSpace(r) {
42 if first == 0 {
43 first = i
44 }
45 } else {
46 if first != 0 {
47 return s[:first], s[i:]
48 }
49 }
50 }
51 if first == 0 {
52 return "", s // type component is effectively blank
53 }
54 return "", ""
55 }
56
57 func isLineSpace(r rune) bool {
58 return r == ' ' || r == '\t'
59 }
60
61 func unquote(s string) string {
62 if isSingleQuoted(s) || isDoubleQuoted(s) {
63 return s[1 : len(s)-1]
64 }
65 return s
66 }
67
68 // applies various legacy conversions to property values:
69 // - remote wrapping single/doublequotes
70 func legacyStrconv(s string) string {
71 s = unquote(s)
72 return s
73 }
74
75 func isSingleQuoted(s string) bool {
76 return hasAffixes(s, "'", "'")
77 }
78
79 func isDoubleQuoted(s string) bool {
80 return hasAffixes(s, `"`, `"`)
81 }
82
83 func isBracketed(s string) bool {
84 return hasAffixes(s, "[", "]")
85 }
86
87 func hasAffixes(s, left, right string) bool {
88 return strings.HasPrefix(s, left) && strings.HasSuffix(s, right)
89 }
90