github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/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 // 24 // flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) 25 type TagsFlag []string 26 27 func (v *TagsFlag) Set(s string) error { 28 var err error 29 *v, err = splitQuotedFields(s) 30 if *v == nil { 31 *v = []string{} 32 } 33 return err 34 } 35 36 func (v *TagsFlag) Get() interface{} { return *v } 37 38 func splitQuotedFields(s string) ([]string, error) { 39 // Split fields allowing '' or "" around elements. 40 // Quotes further inside the string do not count. 41 var f []string 42 for len(s) > 0 { 43 for len(s) > 0 && isSpaceByte(s[0]) { 44 s = s[1:] 45 } 46 if len(s) == 0 { 47 break 48 } 49 // Accepted quoted string. No unescaping inside. 50 if s[0] == '"' || s[0] == '\'' { 51 quote := s[0] 52 s = s[1:] 53 i := 0 54 for i < len(s) && s[i] != quote { 55 i++ 56 } 57 if i >= len(s) { 58 return nil, fmt.Errorf("unterminated %c string", quote) 59 } 60 f = append(f, s[:i]) 61 s = s[i+1:] 62 continue 63 } 64 i := 0 65 for i < len(s) && !isSpaceByte(s[i]) { 66 i++ 67 } 68 f = append(f, s[:i]) 69 s = s[i:] 70 } 71 return f, nil 72 } 73 74 func (v *TagsFlag) String() string { 75 return "<tagsFlag>" 76 } 77 78 func isSpaceByte(c byte) bool { 79 return c == ' ' || c == '\t' || c == '\n' || c == '\r' 80 }