9fans.net/go@v0.0.7/cmd/acme/internal/runes/runes.go (about) 1 // #include <u.h> 2 // #include <libc.h> 3 // #include <draw.h> 4 // #include <thread.h> 5 // #include <cursor.h> 6 // #include <mouse.h> 7 // #include <keyboard.h> 8 // #include <frame.h> 9 // #include <fcall.h> 10 // #include <regexp.h> 11 // #include <9pclient.h> 12 // #include <plumb.h> 13 // #include <libsec.h> 14 // #include "dat.h" 15 // #include "fns.h" 16 17 package runes 18 19 import ( 20 "path" 21 "strings" 22 "unicode/utf8" 23 ) 24 25 func Index(r, s []rune) int { 26 if len(s) == 0 { 27 return 0 28 } 29 c := s[0] 30 for i, ri := range r { 31 if len(r)-i < len(s) { 32 break 33 } 34 if ri == c && Equal(r[i:i+len(s)], s) { 35 return i 36 } 37 } 38 return -1 39 } 40 41 func IndexRune(rs []rune, c rune) int { 42 for i, r := range rs { 43 if r == c { 44 return i 45 } 46 } 47 return -1 48 } 49 50 func Compare(a, b []rune) int { 51 for i := 0; i < len(a) && i < len(b); i++ { 52 if a[i] != b[i] { 53 if a[i] < b[i] { 54 return -1 55 } 56 return +1 57 } 58 } 59 if len(a) < len(b) { 60 return -1 61 } 62 if len(a) > len(b) { 63 return +1 64 } 65 return 0 66 } 67 68 func Equal(s1, s2 []rune) bool { 69 if len(s1) != len(s2) { 70 return false 71 } 72 for i := 0; i < len(s1); i++ { 73 if s1[i] != s2[i] { 74 return false 75 } 76 } 77 return true 78 } 79 80 func Clone(r []rune) []rune { 81 s := make([]rune, len(r)) 82 copy(s, r) 83 return s 84 } 85 86 func IsAlphaNum(c rune) bool { 87 /* 88 * Hard to get absolutely right. Use what we know about ASCII 89 * and assume anything above the Latin control characters is 90 * potentially an alphanumeric. 91 */ 92 if c <= ' ' { 93 return false 94 } 95 if 0x7F <= c && c <= 0xA0 { 96 return false 97 } 98 if strings.ContainsRune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c) { 99 return false 100 } 101 return true 102 } 103 104 var isfilec_Lx = []rune(".-+/:@") 105 106 func IsFilename(r rune) bool { 107 if IsAlphaNum(r) { 108 return true 109 } 110 if IndexRune(isfilec_Lx, r) >= 0 { 111 return true 112 } 113 return false 114 } 115 116 func SkipBlank(r []rune) []rune { 117 for len(r) > 0 && (r[0] == ' ' || r[0] == '\t' || r[0] == '\n') { 118 r = r[1:] 119 } 120 return r 121 } 122 123 func SkipNonBlank(r []rune) []rune { 124 for len(r) > 0 && r[0] != ' ' && r[0] != '\t' && r[0] != '\n' { 125 r = r[1:] 126 } 127 return r 128 } 129 130 // Convert converts bytes in b to runes in r, 131 // returning the number of bytes processed from b, 132 // the number of runes written to r, 133 // and whether any null bytes were elided. 134 // If eof is true, then any partial runes at the end of b 135 // should be processed, and nb == len(b) at return. 136 // Otherwise, partial runes are left behind and 137 // nb may be up to utf8.UTFMax-1 bytes short of len(b). 138 func Convert(b []byte, r []rune, eof bool) (nb, nr int, nulls bool) { 139 b0 := b 140 for len(b) > 0 && (eof || len(b) >= utf8.UTFMax || utf8.FullRune(b)) { 141 rr, w := utf8.DecodeRune(b) 142 if rr == 0 { 143 nulls = true 144 } else { 145 r[nr] = rr 146 nr++ 147 } 148 b = b[w:] 149 } 150 nb = len(b0) - len(b) 151 return nb, nr, nulls 152 } 153 154 func CleanPath(r []rune) []rune { 155 return []rune(path.Clean(string(r))) 156 } 157 158 type Range struct { 159 Pos int 160 End int 161 } 162 163 func Rng(q0 int, q1 int) Range { 164 var r Range 165 r.Pos = q0 166 r.End = q1 167 return r 168 } 169 170 const Infinity = 0x7FFFFFFF 171 172 const RuneSize = 4 173 174 func IsAddr(r rune) bool { 175 if r != 0 && strings.ContainsRune("0123456789+-/$.#,;?", r) { 176 return true 177 } 178 return false 179 } 180 181 /* 182 * quite hard: could be almost anything but white space, but we are a little conservative, 183 * aiming for regular expressions of alphanumerics and no white space 184 */ 185 func IsRegx(r rune) bool { 186 if r == 0 { 187 return false 188 } 189 if IsAlphaNum(r) { 190 return true 191 } 192 if strings.ContainsRune("^+-.*?#,;[]()$", r) { 193 return true 194 } 195 return false 196 }