github.com/bir3/gocompiler@v0.9.2202/src/cmd/internal/objabi/path.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package objabi 6 7 import ( 8 "fmt" 9 "strconv" 10 "strings" 11 ) 12 13 // PathToPrefix converts raw string to the prefix that will be used in the 14 // symbol table. All control characters, space, '%' and '"', as well as 15 // non-7-bit clean bytes turn into %xx. The period needs escaping only in the 16 // last segment of the path, and it makes for happier users if we escape that as 17 // little as possible. 18 func PathToPrefix(s string) string { 19 slash := strings.LastIndex(s, "/") 20 // check for chars that need escaping 21 n := 0 22 for r := 0; r < len(s); r++ { 23 if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { 24 n++ 25 } 26 } 27 28 // quick exit 29 if n == 0 { 30 return s 31 } 32 33 // escape 34 const hex = "0123456789abcdef" 35 p := make([]byte, 0, len(s)+2*n) 36 for r := 0; r < len(s); r++ { 37 if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { 38 p = append(p, '%', hex[c>>4], hex[c&0xF]) 39 } else { 40 p = append(p, c) 41 } 42 } 43 44 return string(p) 45 } 46 47 // PrefixToPath is the inverse of PathToPrefix, replacing escape sequences with 48 // the original character. 49 func PrefixToPath(s string) (string, error) { 50 percent := strings.IndexByte(s, '%') 51 if percent == -1 { 52 return s, nil 53 } 54 55 p := make([]byte, 0, len(s)) 56 for i := 0; i < len(s); { 57 if s[i] != '%' { 58 p = append(p, s[i]) 59 i++ 60 continue 61 } 62 if i+2 >= len(s) { 63 // Not enough characters remaining to be a valid escape 64 // sequence. 65 return "", fmt.Errorf("malformed prefix %q: escape sequence must contain two hex digits", s) 66 } 67 68 b, err := strconv.ParseUint(s[i+1:i+3], 16, 8) 69 if err != nil { 70 // Not a valid escape sequence. 71 return "", fmt.Errorf("malformed prefix %q: escape sequence %q must contain two hex digits", s, s[i:i+3]) 72 } 73 74 p = append(p, byte(b)) 75 i += 3 76 } 77 return string(p), nil 78 }