OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [strconv/] [atoi.go] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package strconv
6
 
7
import "errors"
8
 
9
// ErrRange indicates that a value is out of range for the target type.
10
var ErrRange = errors.New("value out of range")
11
 
12
// ErrSyntax indicates that a value does not have the right syntax for the target type.
13
var ErrSyntax = errors.New("invalid syntax")
14
 
15
// A NumError records a failed conversion.
16
type NumError struct {
17
        Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
18
        Num  string // the input
19
        Err  error  // the reason the conversion failed (ErrRange, ErrSyntax)
20
}
21
 
22
func (e *NumError) Error() string {
23
        return "strconv." + e.Func + ": " + `parsing "` + e.Num + `": ` + e.Err.Error()
24
}
25
 
26
func syntaxError(fn, str string) *NumError {
27
        return &NumError{fn, str, ErrSyntax}
28
}
29
 
30
func rangeError(fn, str string) *NumError {
31
        return &NumError{fn, str, ErrRange}
32
}
33
 
34
const intSize = 32 << uint(^uint(0)>>63)
35
 
36
const IntSize = intSize // number of bits in int, uint (32 or 64)
37
 
38
// Return the first number n such that n*base >= 1<<64.
39
func cutoff64(base int) uint64 {
40
        if base < 2 {
41
                return 0
42
        }
43
        return (1<<64-1)/uint64(base) + 1
44
}
45
 
46
// ParseUint is like ParseInt but for unsigned numbers.
47
func ParseUint(s string, b int, bitSize int) (n uint64, err error) {
48
        var cutoff, maxVal uint64
49
 
50
        if bitSize == 0 {
51
                bitSize = int(IntSize)
52
        }
53
 
54
        s0 := s
55
        switch {
56
        case len(s) < 1:
57
                err = ErrSyntax
58
                goto Error
59
 
60
        case 2 <= b && b <= 36:
61
                // valid base; nothing to do
62
 
63
        case b == 0:
64
                // Look for octal, hex prefix.
65
                switch {
66
                case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
67
                        b = 16
68
                        s = s[2:]
69
                        if len(s) < 1 {
70
                                err = ErrSyntax
71
                                goto Error
72
                        }
73
                case s[0] == '0':
74
                        b = 8
75
                default:
76
                        b = 10
77
                }
78
 
79
        default:
80
                err = errors.New("invalid base " + Itoa(b))
81
                goto Error
82
        }
83
 
84
        n = 0
85
        cutoff = cutoff64(b)
86
        maxVal = 1<
87
 
88
        for i := 0; i < len(s); i++ {
89
                var v byte
90
                d := s[i]
91
                switch {
92
                case '0' <= d && d <= '9':
93
                        v = d - '0'
94
                case 'a' <= d && d <= 'z':
95
                        v = d - 'a' + 10
96
                case 'A' <= d && d <= 'Z':
97
                        v = d - 'A' + 10
98
                default:
99
                        n = 0
100
                        err = ErrSyntax
101
                        goto Error
102
                }
103
                if int(v) >= b {
104
                        n = 0
105
                        err = ErrSyntax
106
                        goto Error
107
                }
108
 
109
                if n >= cutoff {
110
                        // n*b overflows
111
                        n = 1<<64 - 1
112
                        err = ErrRange
113
                        goto Error
114
                }
115
                n *= uint64(b)
116
 
117
                n1 := n + uint64(v)
118
                if n1 < n || n1 > maxVal {
119
                        // n+v overflows
120
                        n = 1<<64 - 1
121
                        err = ErrRange
122
                        goto Error
123
                }
124
                n = n1
125
        }
126
 
127
        return n, nil
128
 
129
Error:
130
        return n, &NumError{"ParseUint", s0, err}
131
}
132
 
133
// ParseInt interprets a string s in the given base (2 to 36) and
134
// returns the corresponding value i.  If base == 0, the base is
135
// implied by the string's prefix: base 16 for "0x", base 8 for
136
// "0", and base 10 otherwise.
137
//
138
// The bitSize argument specifies the integer type
139
// that the result must fit into.  Bit sizes 0, 8, 16, 32, and 64
140
// correspond to int, int8, int16, int32, and int64.
141
//
142
// The errors that ParseInt returns have concrete type *NumError
143
// and include err.Num = s.  If s is empty or contains invalid
144
// digits, err.Error = ErrSyntax; if the value corresponding
145
// to s cannot be represented by a signed integer of the
146
// given size, err.Error = ErrRange.
147
func ParseInt(s string, base int, bitSize int) (i int64, err error) {
148
        const fnParseInt = "ParseInt"
149
 
150
        if bitSize == 0 {
151
                bitSize = int(IntSize)
152
        }
153
 
154
        // Empty string bad.
155
        if len(s) == 0 {
156
                return 0, syntaxError(fnParseInt, s)
157
        }
158
 
159
        // Pick off leading sign.
160
        s0 := s
161
        neg := false
162
        if s[0] == '+' {
163
                s = s[1:]
164
        } else if s[0] == '-' {
165
                neg = true
166
                s = s[1:]
167
        }
168
 
169
        // Convert unsigned and check range.
170
        var un uint64
171
        un, err = ParseUint(s, base, bitSize)
172
        if err != nil && err.(*NumError).Err != ErrRange {
173
                err.(*NumError).Func = fnParseInt
174
                err.(*NumError).Num = s0
175
                return 0, err
176
        }
177
        cutoff := uint64(1 << uint(bitSize-1))
178
        if !neg && un >= cutoff {
179
                return int64(cutoff - 1), rangeError(fnParseInt, s0)
180
        }
181
        if neg && un > cutoff {
182
                return -int64(cutoff), rangeError(fnParseInt, s0)
183
        }
184
        n := int64(un)
185
        if neg {
186
                n = -n
187
        }
188
        return n, nil
189
}
190
 
191
// Atoi is shorthand for ParseInt(s, 10, 0).
192
func Atoi(s string) (i int, err error) {
193
        i64, err := ParseInt(s, 10, 0)
194
        return int(i64), err
195
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.