summaryrefslogtreecommitdiffstats
path: root/src/cmd/internal/objabi/path.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:25:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:25:22 +0000
commitf6ad4dcef54c5ce997a4bad5a6d86de229015700 (patch)
tree7cfa4e31ace5c2bd95c72b154d15af494b2bcbef /src/cmd/internal/objabi/path.go
parentInitial commit. (diff)
downloadgolang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.tar.xz
golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.zip
Adding upstream version 1.22.1.upstream/1.22.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/internal/objabi/path.go')
-rw-r--r--src/cmd/internal/objabi/path.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/cmd/internal/objabi/path.go b/src/cmd/internal/objabi/path.go
new file mode 100644
index 0000000..30301b1
--- /dev/null
+++ b/src/cmd/internal/objabi/path.go
@@ -0,0 +1,78 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package objabi
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// PathToPrefix converts raw string to the prefix that will be used in the
+// symbol table. All control characters, space, '%' and '"', as well as
+// non-7-bit clean bytes turn into %xx. The period needs escaping only in the
+// last segment of the path, and it makes for happier users if we escape that as
+// little as possible.
+func PathToPrefix(s string) string {
+ slash := strings.LastIndex(s, "/")
+ // check for chars that need escaping
+ n := 0
+ for r := 0; r < len(s); r++ {
+ if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
+ n++
+ }
+ }
+
+ // quick exit
+ if n == 0 {
+ return s
+ }
+
+ // escape
+ const hex = "0123456789abcdef"
+ p := make([]byte, 0, len(s)+2*n)
+ for r := 0; r < len(s); r++ {
+ if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
+ p = append(p, '%', hex[c>>4], hex[c&0xF])
+ } else {
+ p = append(p, c)
+ }
+ }
+
+ return string(p)
+}
+
+// PrefixToPath is the inverse of PathToPrefix, replacing escape sequences with
+// the original character.
+func PrefixToPath(s string) (string, error) {
+ percent := strings.IndexByte(s, '%')
+ if percent == -1 {
+ return s, nil
+ }
+
+ p := make([]byte, 0, len(s))
+ for i := 0; i < len(s); {
+ if s[i] != '%' {
+ p = append(p, s[i])
+ i++
+ continue
+ }
+ if i+2 >= len(s) {
+ // Not enough characters remaining to be a valid escape
+ // sequence.
+ return "", fmt.Errorf("malformed prefix %q: escape sequence must contain two hex digits", s)
+ }
+
+ b, err := strconv.ParseUint(s[i+1:i+3], 16, 8)
+ if err != nil {
+ // Not a valid escape sequence.
+ return "", fmt.Errorf("malformed prefix %q: escape sequence %q must contain two hex digits", s, s[i:i+3])
+ }
+
+ p = append(p, byte(b))
+ i += 3
+ }
+ return string(p), nil
+}