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