URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [strconv/] [atoi.go] - Rev 747
Compare with Previous | Blame | View Log
// 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 strconvimport "errors"// ErrRange indicates that a value is out of range for the target type.var ErrRange = errors.New("value out of range")// ErrSyntax indicates that a value does not have the right syntax for the target type.var ErrSyntax = errors.New("invalid syntax")// A NumError records a failed conversion.type NumError struct {Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)Num string // the inputErr error // the reason the conversion failed (ErrRange, ErrSyntax)}func (e *NumError) Error() string {return "strconv." + e.Func + ": " + `parsing "` + e.Num + `": ` + e.Err.Error()}func syntaxError(fn, str string) *NumError {return &NumError{fn, str, ErrSyntax}}func rangeError(fn, str string) *NumError {return &NumError{fn, str, ErrRange}}const intSize = 32 << uint(^uint(0)>>63)const IntSize = intSize // number of bits in int, uint (32 or 64)// Return the first number n such that n*base >= 1<<64.func cutoff64(base int) uint64 {if base < 2 {return 0}return (1<<64-1)/uint64(base) + 1}// ParseUint is like ParseInt but for unsigned numbers.func ParseUint(s string, b int, bitSize int) (n uint64, err error) {var cutoff, maxVal uint64if bitSize == 0 {bitSize = int(IntSize)}s0 := sswitch {case len(s) < 1:err = ErrSyntaxgoto Errorcase 2 <= b && b <= 36:// valid base; nothing to docase b == 0:// Look for octal, hex prefix.switch {case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):b = 16s = s[2:]if len(s) < 1 {err = ErrSyntaxgoto Error}case s[0] == '0':b = 8default:b = 10}default:err = errors.New("invalid base " + Itoa(b))goto Error}n = 0cutoff = cutoff64(b)maxVal = 1<<uint(bitSize) - 1for i := 0; i < len(s); i++ {var v byted := s[i]switch {case '0' <= d && d <= '9':v = d - '0'case 'a' <= d && d <= 'z':v = d - 'a' + 10case 'A' <= d && d <= 'Z':v = d - 'A' + 10default:n = 0err = ErrSyntaxgoto Error}if int(v) >= b {n = 0err = ErrSyntaxgoto Error}if n >= cutoff {// n*b overflowsn = 1<<64 - 1err = ErrRangegoto Error}n *= uint64(b)n1 := n + uint64(v)if n1 < n || n1 > maxVal {// n+v overflowsn = 1<<64 - 1err = ErrRangegoto Error}n = n1}return n, nilError:return n, &NumError{"ParseUint", s0, err}}// ParseInt interprets a string s in the given base (2 to 36) and// returns the corresponding value i. If base == 0, the base is// implied by the string's prefix: base 16 for "0x", base 8 for// "0", and base 10 otherwise.//// The bitSize argument specifies the integer type// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64// correspond to int, int8, int16, int32, and int64.//// The errors that ParseInt returns have concrete type *NumError// and include err.Num = s. If s is empty or contains invalid// digits, err.Error = ErrSyntax; if the value corresponding// to s cannot be represented by a signed integer of the// given size, err.Error = ErrRange.func ParseInt(s string, base int, bitSize int) (i int64, err error) {const fnParseInt = "ParseInt"if bitSize == 0 {bitSize = int(IntSize)}// Empty string bad.if len(s) == 0 {return 0, syntaxError(fnParseInt, s)}// Pick off leading sign.s0 := sneg := falseif s[0] == '+' {s = s[1:]} else if s[0] == '-' {neg = trues = s[1:]}// Convert unsigned and check range.var un uint64un, err = ParseUint(s, base, bitSize)if err != nil && err.(*NumError).Err != ErrRange {err.(*NumError).Func = fnParseInterr.(*NumError).Num = s0return 0, err}cutoff := uint64(1 << uint(bitSize-1))if !neg && un >= cutoff {return int64(cutoff - 1), rangeError(fnParseInt, s0)}if neg && un > cutoff {return -int64(cutoff), rangeError(fnParseInt, s0)}n := int64(un)if neg {n = -n}return n, nil}// Atoi is shorthand for ParseInt(s, 10, 0).func Atoi(s string) (i int, err error) {i64, err := ParseInt(s, 10, 0)return int(i64), err}
