strings_flag.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. package main
  5. import "fmt"
  6. type stringsFlag []string
  7. func (v *stringsFlag) Set(s string) error {
  8. var err error
  9. *v, err = splitQuotedFields(s)
  10. if *v == nil {
  11. *v = []string{}
  12. }
  13. return err
  14. }
  15. func isSpaceByte(c byte) bool {
  16. return c == ' ' || c == '\t' || c == '\n' || c == '\r'
  17. }
  18. func splitQuotedFields(s string) ([]string, error) {
  19. // Split fields allowing '' or "" around elements.
  20. // Quotes further inside the string do not count.
  21. var f []string
  22. for len(s) > 0 {
  23. for len(s) > 0 && isSpaceByte(s[0]) {
  24. s = s[1:]
  25. }
  26. if len(s) == 0 {
  27. break
  28. }
  29. // Accepted quoted string. No unescaping inside.
  30. if s[0] == '"' || s[0] == '\'' {
  31. quote := s[0]
  32. s = s[1:]
  33. i := 0
  34. for i < len(s) && s[i] != quote {
  35. i++
  36. }
  37. if i >= len(s) {
  38. return nil, fmt.Errorf("unterminated %c string", quote)
  39. }
  40. f = append(f, s[:i])
  41. s = s[i+1:]
  42. continue
  43. }
  44. i := 0
  45. for i < len(s) && !isSpaceByte(s[i]) {
  46. i++
  47. }
  48. f = append(f, s[:i])
  49. s = s[i:]
  50. }
  51. return f, nil
  52. }
  53. func (v *stringsFlag) String() string {
  54. return "<stringsFlag>"
  55. }