github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/pkg/parsers/parsers.go (about) 1 // Package parsers provides helper functions to parse and validate different type 2 // of string. It can be hosts, unix addresses, tcp addresses, filters, kernel 3 // operating system versions. 4 package parsers // import "github.com/Prakhar-Agarwal-byte/moby/pkg/parsers" 5 6 import ( 7 "fmt" 8 "strconv" 9 "strings" 10 ) 11 12 // ParseKeyValueOpt parses and validates the specified string as a key/value 13 // pair (key=value). 14 func ParseKeyValueOpt(opt string) (key string, value string, err error) { 15 k, v, ok := strings.Cut(opt, "=") 16 if !ok { 17 return "", "", fmt.Errorf("unable to parse key/value option: %s", opt) 18 } 19 return strings.TrimSpace(k), strings.TrimSpace(v), nil 20 } 21 22 // ParseUintListMaximum parses and validates the specified string as the value 23 // found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be 24 // one of the formats below. Note that duplicates are actually allowed in the 25 // input string. It returns a `map[int]bool` with available elements from `val` 26 // set to `true`. Values larger than `maximum` cause an error if max is non zero, 27 // in order to stop the map becoming excessively large. 28 // Supported formats: 29 // 30 // 7 31 // 1-6 32 // 0,3-4,7,8-10 33 // 0-0,0,1-7 34 // 03,1-3 <- this is gonna get parsed as [1,2,3] 35 // 3,2,1 36 // 0-2,3,1 37 func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) { 38 return parseUintList(val, maximum) 39 } 40 41 // ParseUintList parses and validates the specified string as the value 42 // found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be 43 // one of the formats below. Note that duplicates are actually allowed in the 44 // input string. It returns a `map[int]bool` with available elements from `val` 45 // set to `true`. 46 // Supported formats: 47 // 48 // 7 49 // 1-6 50 // 0,3-4,7,8-10 51 // 0-0,0,1-7 52 // 03,1-3 <- this is gonna get parsed as [1,2,3] 53 // 3,2,1 54 // 0-2,3,1 55 func ParseUintList(val string) (map[int]bool, error) { 56 return parseUintList(val, 0) 57 } 58 59 func parseUintList(val string, maximum int) (map[int]bool, error) { 60 if val == "" { 61 return map[int]bool{}, nil 62 } 63 64 availableInts := make(map[int]bool) 65 split := strings.Split(val, ",") 66 errInvalidFormat := fmt.Errorf("invalid format: %s", val) 67 68 for _, r := range split { 69 if !strings.Contains(r, "-") { 70 v, err := strconv.Atoi(r) 71 if err != nil { 72 return nil, errInvalidFormat 73 } 74 if maximum != 0 && v > maximum { 75 return nil, fmt.Errorf("value of out range, maximum is %d", maximum) 76 } 77 availableInts[v] = true 78 } else { 79 minS, maxS, _ := strings.Cut(r, "-") 80 min, err := strconv.Atoi(minS) 81 if err != nil { 82 return nil, errInvalidFormat 83 } 84 max, err := strconv.Atoi(maxS) 85 if err != nil { 86 return nil, errInvalidFormat 87 } 88 if max < min { 89 return nil, errInvalidFormat 90 } 91 if maximum != 0 && max > maximum { 92 return nil, fmt.Errorf("value of out range, maximum is %d", maximum) 93 } 94 for i := min; i <= max; i++ { 95 availableInts[i] = true 96 } 97 } 98 } 99 return availableInts, nil 100 }