123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package internal
- import (
- "bytes"
- "errors"
- "go/format"
- "go/scanner"
- "io"
- "strings"
- "unicode"
- )
- // Identifier turns a C style type or field name into an exportable Go equivalent.
- func Identifier(str string) string {
- prev := rune(-1)
- return strings.Map(func(r rune) rune {
- // See https://golang.org/ref/spec#Identifiers
- switch {
- case unicode.IsLetter(r):
- if prev == -1 {
- r = unicode.ToUpper(r)
- }
- case r == '_':
- switch {
- // The previous rune was deleted, or we are at the
- // beginning of the string.
- case prev == -1:
- fallthrough
- // The previous rune is a lower case letter or a digit.
- case unicode.IsDigit(prev) || (unicode.IsLetter(prev) && unicode.IsLower(prev)):
- // delete the current rune, and force the
- // next character to be uppercased.
- r = -1
- }
- case unicode.IsDigit(r):
- default:
- // Delete the current rune. prev is unchanged.
- return -1
- }
- prev = r
- return r
- }, str)
- }
- // WriteFormatted outputs a formatted src into out.
- //
- // If formatting fails it returns an informative error message.
- func WriteFormatted(src []byte, out io.Writer) error {
- formatted, err := format.Source(src)
- if err == nil {
- _, err = out.Write(formatted)
- return err
- }
- var el scanner.ErrorList
- if !errors.As(err, &el) {
- return err
- }
- var nel scanner.ErrorList
- for _, err := range el {
- if !err.Pos.IsValid() {
- nel = append(nel, err)
- continue
- }
- buf := src[err.Pos.Offset:]
- nl := bytes.IndexRune(buf, '\n')
- if nl == -1 {
- nel = append(nel, err)
- continue
- }
- err.Msg += ": " + string(buf[:nl])
- nel = append(nel, err)
- }
- return nel
- }
|