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