.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.1.1 / printf / printf.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.1.1/printf/printf.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.1.1/printf/printf.go
new file mode 100644 (file)
index 0000000..754db9b
--- /dev/null
@@ -0,0 +1,197 @@
+// Package printf implements a parser for fmt.Printf-style format
+// strings.
+//
+// It parses verbs according to the following syntax:
+//     Numeric -> '0'-'9'
+//     Letter -> 'a'-'z' | 'A'-'Z'
+//     Index -> '[' Numeric+ ']'
+//     Star -> '*'
+//     Star -> Index '*'
+//
+//     Precision -> Numeric+ | Star
+//     Width -> Numeric+ | Star
+//
+//     WidthAndPrecision -> Width '.' Precision
+//     WidthAndPrecision -> Width '.'
+//     WidthAndPrecision -> Width
+//     WidthAndPrecision -> '.' Precision
+//     WidthAndPrecision -> '.'
+//
+//     Flag -> '+' | '-' | '#' | ' ' | '0'
+//     Verb -> Letter | '%'
+//
+//     Input -> '%' [ Flag+ ] [ WidthAndPrecision ] [ Index ] Verb
+package printf
+
+import (
+       "errors"
+       "regexp"
+       "strconv"
+       "strings"
+)
+
+// ErrInvalid is returned for invalid format strings or verbs.
+var ErrInvalid = errors.New("invalid format string")
+
+type Verb struct {
+       Letter rune
+       Flags  string
+
+       Width     Argument
+       Precision Argument
+       // Which value in the argument list the verb uses.
+       // -1 denotes the next argument,
+       // values > 0 denote explicit arguments.
+       // The value 0 denotes that no argument is consumed. This is the case for %%.
+       Value int
+
+       Raw string
+}
+
+// Argument is an implicit or explicit width or precision.
+type Argument interface {
+       isArgument()
+}
+
+// The Default value, when no width or precision is provided.
+type Default struct{}
+
+// Zero is the implicit zero value.
+// This value may only appear for precisions in format strings like %6.f
+type Zero struct{}
+
+// Star is a * value, which may either refer to the next argument (Index == -1) or an explicit argument.
+type Star struct{ Index int }
+
+// A Literal value, such as 6 in %6d.
+type Literal int
+
+func (Default) isArgument() {}
+func (Zero) isArgument()    {}
+func (Star) isArgument()    {}
+func (Literal) isArgument() {}
+
+// Parse parses f and returns a list of actions.
+// An action may either be a literal string, or a Verb.
+func Parse(f string) ([]interface{}, error) {
+       var out []interface{}
+       for len(f) > 0 {
+               if f[0] == '%' {
+                       v, n, err := ParseVerb(f)
+                       if err != nil {
+                               return nil, err
+                       }
+                       f = f[n:]
+                       out = append(out, v)
+               } else {
+                       n := strings.IndexByte(f, '%')
+                       if n > -1 {
+                               out = append(out, f[:n])
+                               f = f[n:]
+                       } else {
+                               out = append(out, f)
+                               f = ""
+                       }
+               }
+       }
+
+       return out, nil
+}
+
+func atoi(s string) int {
+       n, _ := strconv.Atoi(s)
+       return n
+}
+
+// ParseVerb parses the verb at the beginning of f.
+// It returns the verb, how much of the input was consumed, and an error, if any.
+func ParseVerb(f string) (Verb, int, error) {
+       if len(f) < 2 {
+               return Verb{}, 0, ErrInvalid
+       }
+       const (
+               flags = 1
+
+               width      = 2
+               widthStar  = 3
+               widthIndex = 5
+
+               dot       = 6
+               prec      = 7
+               precStar  = 8
+               precIndex = 10
+
+               verbIndex = 11
+               verb      = 12
+       )
+
+       m := re.FindStringSubmatch(f)
+       if m == nil {
+               return Verb{}, 0, ErrInvalid
+       }
+
+       v := Verb{
+               Letter: []rune(m[verb])[0],
+               Flags:  m[flags],
+               Raw:    m[0],
+       }
+
+       if m[width] != "" {
+               // Literal width
+               v.Width = Literal(atoi(m[width]))
+       } else if m[widthStar] != "" {
+               // Star width
+               if m[widthIndex] != "" {
+                       v.Width = Star{atoi(m[widthIndex])}
+               } else {
+                       v.Width = Star{-1}
+               }
+       } else {
+               // Default width
+               v.Width = Default{}
+       }
+
+       if m[dot] == "" {
+               // default precision
+               v.Precision = Default{}
+       } else {
+               if m[prec] != "" {
+                       // Literal precision
+                       v.Precision = Literal(atoi(m[prec]))
+               } else if m[precStar] != "" {
+                       // Star precision
+                       if m[precIndex] != "" {
+                               v.Precision = Star{atoi(m[precIndex])}
+                       } else {
+                               v.Precision = Star{-1}
+                       }
+               } else {
+                       // Zero precision
+                       v.Precision = Zero{}
+               }
+       }
+
+       if m[verb] == "%" {
+               v.Value = 0
+       } else if m[verbIndex] != "" {
+               v.Value = atoi(m[verbIndex])
+       } else {
+               v.Value = -1
+       }
+
+       return v, len(m[0]), nil
+}
+
+const (
+       flags             = `([+#0 -]*)`
+       verb              = `([a-zA-Z%])`
+       index             = `(?:\[([0-9]+)\])`
+       star              = `((` + index + `)?\*)`
+       width1            = `([0-9]+)`
+       width2            = star
+       width             = `(?:` + width1 + `|` + width2 + `)`
+       precision         = width
+       widthAndPrecision = `(?:(?:` + width + `)?(?:(\.)(?:` + precision + `)?)?)`
+)
+
+var re = regexp.MustCompile(`^%` + flags + widthAndPrecision + `?` + index + `?` + verb)