github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/buildutil/tags.go (about) 1 // Copyright 2015 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 buildutil 6 7 // This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go. 8 9 import "fmt" 10 11 const TagsFlagDoc = "a list of `build tags` to consider satisfied during the build. " + 12 "For more information about build tags, see the description of " + 13 "build constraints in the documentation for the go/build package" 14 15 // TagsFlag is an implementation of the flag.Value and flag.Getter interfaces that parses 16 // a flag value in the same manner as go build's -tags flag and 17 // populates a []string slice. 18 // 19 // See $GOROOT/src/go/build/doc.go for description of build tags. 20 // See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag. 21 // 22 // Example: 23 // flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) 24 type TagsFlag []string 25 26 func (v *TagsFlag) Set(s string) error { 27 var err error 28 *v, err = splitQuotedFields(s) 29 if *v == nil { 30 *v = []string{} 31 } 32 return err 33 } 34 35 func (v *TagsFlag) Get() interface{} { return *v } 36 37 func splitQuotedFields(s string) ([]string, error) { 38 // Split fields allowing '' or "" around elements. 39 // Quotes further inside the string do not count. 40 var f []string 41 for len(s) > 0 { 42 for len(s) > 0 && isSpaceByte(s[0]) { 43 s = s[1:] 44 } 45 if len(s) == 0 { 46 break 47 } 48 // Accepted quoted string. No unescaping inside. 49 if s[0] == '"' || s[0] == '\'' { 50 quote := s[0] 51 s = s[1:] 52 i := 0 53 for i < len(s) && s[i] != quote { 54 i++ 55 } 56 if i >= len(s) { 57 return nil, fmt.Errorf("unterminated %c string", quote) 58 } 59 f = append(f, s[:i]) 60 s = s[i+1:] 61 continue 62 } 63 i := 0 64 for i < len(s) && !isSpaceByte(s[i]) { 65 i++ 66 } 67 f = append(f, s[:i]) 68 s = s[i:] 69 } 70 return f, nil 71 } 72 73 func (v *TagsFlag) String() string { 74 return "<tagsFlag>" 75 } 76 77 func isSpaceByte(c byte) bool { 78 return c == ' ' || c == '\t' || c == '\n' || c == '\r' 79 }