github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/internal/output.go (about) 1 package internal 2 3 import ( 4 "bytes" 5 "errors" 6 "go/format" 7 "go/scanner" 8 "io" 9 "reflect" 10 "strings" 11 "unicode" 12 ) 13 14 // Identifier turns a C style type or field name into an exportable Go equivalent. 15 func Identifier(str string) string { 16 prev := rune(-1) 17 return strings.Map(func(r rune) rune { 18 // See https://golang.org/ref/spec#Identifiers 19 switch { 20 case unicode.IsLetter(r): 21 if prev == -1 { 22 r = unicode.ToUpper(r) 23 } 24 25 case r == '_': 26 switch { 27 // The previous rune was deleted, or we are at the 28 // beginning of the string. 29 case prev == -1: 30 fallthrough 31 32 // The previous rune is a lower case letter or a digit. 33 case unicode.IsDigit(prev) || (unicode.IsLetter(prev) && unicode.IsLower(prev)): 34 // delete the current rune, and force the 35 // next character to be uppercased. 36 r = -1 37 } 38 39 case unicode.IsDigit(r): 40 41 default: 42 // Delete the current rune. prev is unchanged. 43 return -1 44 } 45 46 prev = r 47 return r 48 }, str) 49 } 50 51 // WriteFormatted outputs a formatted src into out. 52 // 53 // If formatting fails it returns an informative error message. 54 func WriteFormatted(src []byte, out io.Writer) error { 55 formatted, err := format.Source(src) 56 if err == nil { 57 _, err = out.Write(formatted) 58 return err 59 } 60 61 var el scanner.ErrorList 62 if !errors.As(err, &el) { 63 return err 64 } 65 66 var nel scanner.ErrorList 67 for _, err := range el { 68 if !err.Pos.IsValid() { 69 nel = append(nel, err) 70 continue 71 } 72 73 buf := src[err.Pos.Offset:] 74 nl := bytes.IndexRune(buf, '\n') 75 if nl == -1 { 76 nel = append(nel, err) 77 continue 78 } 79 80 err.Msg += ": " + string(buf[:nl]) 81 nel = append(nel, err) 82 } 83 84 return nel 85 } 86 87 // GoTypeName is like %T, but elides the package name. 88 // 89 // Pointers to a type are peeled off. 90 func GoTypeName(t any) string { 91 rT := reflect.TypeOf(t) 92 for rT.Kind() == reflect.Pointer { 93 rT = rT.Elem() 94 } 95 // Doesn't return the correct Name for generic types due to https://github.com/golang/go/issues/55924 96 return rT.Name() 97 }