path.go raw

   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 "strings"
   8  
   9  // PathToPrefix converts raw string to the prefix that will be used in the
  10  // symbol table. All control characters, space, '%' and '"', as well as
  11  // non-7-bit clean bytes turn into %xx. The period needs escaping only in the
  12  // last segment of the path, and it makes for happier users if we escape that as
  13  // little as possible.
  14  func PathToPrefix(s string) string {
  15  	slash := strings.LastIndex(s, "/")
  16  	// check for chars that need escaping
  17  	n := 0
  18  	for r := 0; r < len(s); r++ {
  19  		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
  20  			n++
  21  		}
  22  	}
  23  
  24  	// quick exit
  25  	if n == 0 {
  26  		return s
  27  	}
  28  
  29  	// escape
  30  	const hex = "0123456789abcdef"
  31  	p := make([]byte, 0, len(s)+2*n)
  32  	for r := 0; r < len(s); r++ {
  33  		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
  34  			p = append(p, '%', hex[c>>4], hex[c&0xF])
  35  		} else {
  36  			p = append(p, c)
  37  		}
  38  	}
  39  
  40  	return string(p)
  41  }
  42