From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libgo/go/strconv/atoi.go | 202 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 libgo/go/strconv/atoi.go (limited to 'libgo/go/strconv/atoi.go') diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go new file mode 100644 index 000000000..f7b845672 --- /dev/null +++ b/libgo/go/strconv/atoi.go @@ -0,0 +1,202 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strconv + +import "os" + +type NumError struct { + Num string + Error os.Error +} + +func (e *NumError) String() string { return `parsing "` + e.Num + `": ` + e.Error.String() } + + +func computeIntsize() uint { + siz := uint(8) + for 1<= 1<<64. +func cutoff64(base int) uint64 { + if base < 2 { + return 0 + } + return (1<<64-1)/uint64(base) + 1 +} + +// Btoui64 interprets a string s in an arbitrary base b (2 to 36) +// and returns the corresponding value n. If b == 0, the base +// is taken from the string prefix: base 16 for "0x", base 8 for "0", +// and base 10 otherwise. +// +// The errors that Btoui64 returns have concrete type *NumError +// and include err.Num = s. If s is empty or contains invalid +// digits, err.Error = os.EINVAL; if the value corresponding +// to s cannot be represented by a uint64, err.Error = os.ERANGE. +func Btoui64(s string, b int) (n uint64, err os.Error) { + s0 := s + switch { + case len(s) < 1: + err = os.EINVAL + goto Error + + case 2 <= b && b <= 36: + // valid base; nothing to do + + case b == 0: + // Look for octal, hex prefix. + switch { + case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'): + b = 16 + s = s[2:] + if len(s) < 1 { + err = os.EINVAL + goto Error + } + case s[0] == '0': + b = 8 + default: + b = 10 + } + + default: + err = os.ErrorString("invalid base " + Itoa(b)) + goto Error + } + + n = 0 + cutoff := cutoff64(b) + + for i := 0; i < len(s); i++ { + var v byte + d := s[i] + switch { + case '0' <= d && d <= '9': + v = d - '0' + case 'a' <= d && d <= 'z': + v = d - 'a' + 10 + case 'A' <= d && d <= 'Z': + v = d - 'A' + 10 + default: + n = 0 + err = os.EINVAL + goto Error + } + if int(v) >= b { + n = 0 + err = os.EINVAL + goto Error + } + + if n >= cutoff { + // n*b overflows + n = 1<<64 - 1 + err = os.ERANGE + goto Error + } + n *= uint64(b) + + n1 := n + uint64(v) + if n1 < n { + // n+v overflows + n = 1<<64 - 1 + err = os.ERANGE + goto Error + } + n = n1 + } + + return n, nil + +Error: + return n, &NumError{s0, err} +} + +// Atoui64 interprets a string s as a decimal number and +// returns the corresponding value n. +// +// Atoui64 returns err == os.EINVAL if s is empty or contains invalid digits. +// It returns err == os.ERANGE if s cannot be represented by a uint64. +func Atoui64(s string) (n uint64, err os.Error) { + return Btoui64(s, 10) +} + +// Btoi64 is like Btoui64 but allows signed numbers and +// returns its result in an int64. +func Btoi64(s string, base int) (i int64, err os.Error) { + // Empty string bad. + if len(s) == 0 { + return 0, &NumError{s, os.EINVAL} + } + + // Pick off leading sign. + s0 := s + neg := false + if s[0] == '+' { + s = s[1:] + } else if s[0] == '-' { + neg = true + s = s[1:] + } + + // Convert unsigned and check range. + var un uint64 + un, err = Btoui64(s, base) + if err != nil && err.(*NumError).Error != os.ERANGE { + err.(*NumError).Num = s0 + return 0, err + } + if !neg && un >= 1<<63 { + return 1<<63 - 1, &NumError{s0, os.ERANGE} + } + if neg && un > 1<<63 { + return -1 << 63, &NumError{s0, os.ERANGE} + } + n := int64(un) + if neg { + n = -n + } + return n, nil +} + +// Atoi64 is like Atoui64 but allows signed numbers and +// returns its result in an int64. +func Atoi64(s string) (i int64, err os.Error) { return Btoi64(s, 10) } + + +// Atoui is like Atoui64 but returns its result as a uint. +func Atoui(s string) (i uint, err os.Error) { + i1, e1 := Atoui64(s) + if e1 != nil && e1.(*NumError).Error != os.ERANGE { + return 0, e1 + } + i = uint(i1) + if uint64(i) != i1 { + return ^uint(0), &NumError{s, os.ERANGE} + } + return i, nil +} + +// Atoi is like Atoi64 but returns its result as an int. +func Atoi(s string) (i int, err os.Error) { + i1, e1 := Atoi64(s) + if e1 != nil && e1.(*NumError).Error != os.ERANGE { + return 0, e1 + } + i = int(i1) + if int64(i) != i1 { + if i1 < 0 { + return -1 << (IntSize - 1), &NumError{s, os.ERANGE} + } + return 1<<(IntSize-1) - 1, &NumError{s, os.ERANGE} + } + return i, nil +} -- cgit v1.2.3