/*
Parse a version number of the form major.minor.bugfix.prerlease

Part .bugfix and part .prerelease are optional.
Note that this is forwards compatible: the parsed version does not
have to exist as a constant.
*/
340093
func ParseVersion(version string) (ver Version, err error) {
	if version == "" {
		return
	}

	parts := strings.SplitN(version, ".", 4)
	if len(parts) < 2 || len(parts) > 4 {
		err = errors.New(fmt.Sprintf(
			"Version is not in form major.minor(.bugfix.prerelease) (got: %v)",
			version))
		return
	}

	var major, minor, bugfix, prerelease int
	if major, err = parse(parts[0], version, "major"); err != nil {
		return
	}
	if minor, err = parse(parts[1], version, "minor"); err != nil {
		return
	}

	if len(parts) > 2 {
		if bugfix, err = parse(parts[2], version, "bugfix"); err != nil {
			return
		}

		if len(parts) > 3 {
			if prerelease, err = parse(parts[3], version, "prerelease"); err != nil {
				return
			}
			if prerelease == 0 {
				err = errors.New(fmt.Sprintf(
					"Invalid value %v for prerelease; should be 1 or 2 (got: %v)",
					prerelease, version))
				return
			}
		}
	}

	return newVersion(major, minor, bugfix, prerelease), nil
}
389897
func NewPRVersion(s string) (PRVersion, error) {
	if len(s) == 0 {
		return PRVersion{}, errors.New("Prerelease is empty")
	}
	v := PRVersion{}
	if containsOnly(s, numbers) {
		if hasLeadingZeroes(s) {
			return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
		}
		num, err := strconv.ParseUint(s, 10, 64)

		// Might never be hit, but just in case
		if err != nil {
			return PRVersion{}, err
		}
		v.VersionNum = num
		v.IsNum = true
	} else if containsOnly(s, alphanum) {
		v.VersionStr = s
		v.IsNum = false
	} else {
		return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
	}
	return v, nil
}
491831
func parseKeyVersion(kid string) string {
	keyVersionParts := strings.Split(kid, "/")
	return keyVersionParts[len(keyVersionParts)-1]
}
218352
func Version() (major, minor, patch int) {
	if initVersionError != nil {
		return 0, 0, 0
	}
	var maj, min, pat C.int
	C.zmq_version(&maj, &min, &pat)
	return int(maj), int(min), int(pat)
}
1339296
func kubeadmVersion(info string) (string, error) {
	v, err := versionutil.ParseSemantic(info)
	if err != nil {
		return "", errors.Wrap(err, "kubeadm version error")
	}
	// There is no utility in versionutil to get the version without the metadata,
	// so this needs some manual formatting.
	// Discard offsets after a release label and keep the labels down to e.g. `alpha.0` instead of
	// including the offset e.g. `alpha.0.206`. This is done to comply with GCR image tags.
	pre := v.PreRelease()
	patch := v.Patch()
	if len(pre) > 0 {
		if patch > 0 {
			// If the patch version is more than zero, decrement it and remove the label.
			// this is done to comply with the latest stable patch release.
			patch = patch - 1
			pre = ""
		} else {
			split := strings.Split(pre, ".")
			if len(split) > 2 {
				pre = split[0] + "." + split[1] // Exclude the third element
			} else if len(split) < 2 {
				pre = split[0] + ".0" // Append .0 to a partial label
			}
			pre = "-" + pre
		}
	}
	vStr := fmt.Sprintf("v%d.%d.%d%s", v.Major(), v.Minor(), patch, pre)
	return vStr, nil
}
106997
func (parser *myParser) Parse(s string) error {
	typ := reflect.TypeOf(parser.ptr)
	val := reflect.ValueOf(parser.ptr)
	if typ.Kind() == reflect.Ptr {
		kind := reflect.Indirect(val).Type().Kind()
		if kind == reflect.Struct {
			typElem, valElem := typ.Elem(), val.Elem()
			numField := valElem.NumField()
			for i := 0; i < numField; i++ {
				_, valField := typElem.Field(i), valElem.Field(i)
				if valField.Kind() == reflect.Int &&
					valField.CanSet() {
					valField.SetInt(2)
				}
				if valField.Kind() == reflect.String &&
					valField.CanSet() {
					valField.SetString("B")
				}
			}
		}
	}
	return nil
}
949515
func (s VersionStr) MustParse() Version {
	ret, err := s.Parse()
	if err != nil {
		panic(err)
	}
	return ret
}
1061706
func ParseVersion(s string) (*Version, error) {
	parts := strings.Split(s, ".")
	if len(parts) != 2 {
		return &NullVersion, fmt.Errorf("incorrect number of version components, could not parse '%s'", s)
	}

	scalar, err := strconv.ParseUint(parts[0], 10, 64)
	if err != nil {
		return &NullVersion, fmt.Errorf("could not parse scalar component: '%s'", parts[0])
	}

	pid, err := strconv.ParseUint(parts[1], 10, 16)
	if err != nil {
		return &NullVersion, fmt.Errorf("could not parse pid component: '%s'", parts[1])
	}

	return &Version{scalar, uint16(pid)}, nil
}
783125
func GetVersion() (major, minor, micro int, err error) {
	out, err := exec.Command(iptablesPath, "--version").CombinedOutput()
	if err == nil {
		major, minor, micro = parseVersionNumbers(string(out))
	}
	return
}
636563
func GetVersionNumber() (int64, int) {
	ver := strings.Replace(GetVersionString(), "-", ".", -1)
	parts := strings.Split(ver, ".")
	multiplier := int64(100 * 100) // major, minor, patch
	version := int64(0)
	buildNum := int(0)
	for i, subVerString := range parts {
		if i == 3 {
			buildNum, _ = strconv.Atoi(subVerString)
			break // done
		}
		subVer, err := strconv.Atoi(subVerString)
		if err != nil {
			break // cannot parse
		}
		version += int64(subVer) * multiplier
		multiplier /= 100

	}
	return version, buildNum
}
1232854
func VERSION(v *Version) {
	v.Major = MAJOR_VERSION
	v.Minor = MINOR_VERSION
	v.Patch = PATCHLEVEL
}
592383
func MustParse(s string) Version {
	v, err := Parse(s)
	if err != nil {
		panic(`semver: Parse(` + s + `): ` + err.Error())
	}
	return v
}
402567
func (v Version) Validate() error {
	// Major, Minor, Patch already validated using uint64

	for _, pre := range v.Pre {
		if !pre.IsNum { //Numeric prerelease versions already uint64
			if len(pre.VersionStr) == 0 {
				return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
			}
			if !containsOnly(pre.VersionStr, alphanum) {
				return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
			}
		}
	}

	for _, build := range v.Build {
		if len(build) == 0 {
			return fmt.Errorf("Build meta data can not be empty %q", build)
		}
		if !containsOnly(build, alphanum) {
			return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
		}
	}

	return nil
}
138536
func GetVersion() (int, error) {
	output, err := cmd("", "--version")
	if err != nil {
		return -1, err
	}

	return parseVersion(output)
}
1341229
func CompareVersion(version interface{}) int {
	return compareVersionsWithSuffix(CurrentVersion.Number, CurrentVersion.PatchLevel, CurrentVersion.Suffix, version)
}
1283255
func ParseVersion(bts []byte) (major, minor int, ok bool) {
	switch {
	case bytes.Equal(bts, httpVersion11):
		return 1, 1, true
	case bytes.Equal(bts, httpVersion10):
		return 1, 0, true
	case len(bts) < 8:
		return
	case !bytes.Equal(bts[:5], httpVersionPrefix):
		return
	}

	bts = bts[5:]

	dot := bytes.IndexByte(bts, '.')
	if dot == -1 {
		return
	}
	major, ok = IntFromASCII(bts[:dot])
	if !ok {
		return
	}
	minor, ok = IntFromASCII(bts[dot+1:])
	if !ok {
		return
	}

	return major, minor, true
}
58929
func Parse(in string) (Release, error) {
	var rel Release
	parts := strings.Split(in, ".")
	if len(parts) != 3 {
		return rel, errors.New("release: invalid release " + in)
	}

	var err error
	rel.Year, err = strconv.Atoi(parts[0])
	if err != nil {
		return rel, err
	} else if rel.Year > 2038 || rel.Year < 2000 {
		return rel, errors.New("release: " + parts[0] + " is an invalid year (2000 >= year <= 2038)")
	}

	rel.Month, err = strconv.Atoi(parts[1])
	if err != nil {
		return rel, err
	} else if rel.Month < 1 || rel.Month > 12 {
		return rel, errors.New("release: " + parts[1] + " is an invalid month (1 >= month <= 12)")
	}

	parts = strings.SplitN(parts[2], "-", 2)
	rel.Iteration, err = strconv.Atoi(parts[0])
	if err != nil {
		return rel, err
	}

	if len(parts) == 2 {
		rel.Extra = parts[1]
	}

	return rel, nil
}