2018-11-11 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / strconv / atoi_test.go
blobe2f505a66516c8019acf90608e7bd159cccd8210
1 // 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.
5 package strconv_test
7 import (
8 "errors"
9 "fmt"
10 "reflect"
11 . "strconv"
12 "testing"
15 type parseUint64Test struct {
16 in string
17 out uint64
18 err error
21 var parseUint64Tests = []parseUint64Test{
22 {"", 0, ErrSyntax},
23 {"0", 0, nil},
24 {"1", 1, nil},
25 {"12345", 12345, nil},
26 {"012345", 12345, nil},
27 {"12345x", 0, ErrSyntax},
28 {"98765432100", 98765432100, nil},
29 {"18446744073709551615", 1<<64 - 1, nil},
30 {"18446744073709551616", 1<<64 - 1, ErrRange},
31 {"18446744073709551620", 1<<64 - 1, ErrRange},
34 type parseUint64BaseTest struct {
35 in string
36 base int
37 out uint64
38 err error
41 var parseUint64BaseTests = []parseUint64BaseTest{
42 {"", 0, 0, ErrSyntax},
43 {"0", 0, 0, nil},
44 {"0x", 0, 0, ErrSyntax},
45 {"0X", 0, 0, ErrSyntax},
46 {"1", 0, 1, nil},
47 {"12345", 0, 12345, nil},
48 {"012345", 0, 012345, nil},
49 {"0x12345", 0, 0x12345, nil},
50 {"0X12345", 0, 0x12345, nil},
51 {"12345x", 0, 0, ErrSyntax},
52 {"0xabcdefg123", 0, 0, ErrSyntax},
53 {"123456789abc", 0, 0, ErrSyntax},
54 {"98765432100", 0, 98765432100, nil},
55 {"18446744073709551615", 0, 1<<64 - 1, nil},
56 {"18446744073709551616", 0, 1<<64 - 1, ErrRange},
57 {"18446744073709551620", 0, 1<<64 - 1, ErrRange},
58 {"0xFFFFFFFFFFFFFFFF", 0, 1<<64 - 1, nil},
59 {"0x10000000000000000", 0, 1<<64 - 1, ErrRange},
60 {"01777777777777777777777", 0, 1<<64 - 1, nil},
61 {"01777777777777777777778", 0, 0, ErrSyntax},
62 {"02000000000000000000000", 0, 1<<64 - 1, ErrRange},
63 {"0200000000000000000000", 0, 1 << 61, nil},
66 type parseInt64Test struct {
67 in string
68 out int64
69 err error
72 var parseInt64Tests = []parseInt64Test{
73 {"", 0, ErrSyntax},
74 {"0", 0, nil},
75 {"-0", 0, nil},
76 {"1", 1, nil},
77 {"-1", -1, nil},
78 {"12345", 12345, nil},
79 {"-12345", -12345, nil},
80 {"012345", 12345, nil},
81 {"-012345", -12345, nil},
82 {"98765432100", 98765432100, nil},
83 {"-98765432100", -98765432100, nil},
84 {"9223372036854775807", 1<<63 - 1, nil},
85 {"-9223372036854775807", -(1<<63 - 1), nil},
86 {"9223372036854775808", 1<<63 - 1, ErrRange},
87 {"-9223372036854775808", -1 << 63, nil},
88 {"9223372036854775809", 1<<63 - 1, ErrRange},
89 {"-9223372036854775809", -1 << 63, ErrRange},
92 type parseInt64BaseTest struct {
93 in string
94 base int
95 out int64
96 err error
99 var parseInt64BaseTests = []parseInt64BaseTest{
100 {"", 0, 0, ErrSyntax},
101 {"0", 0, 0, nil},
102 {"-0", 0, 0, nil},
103 {"1", 0, 1, nil},
104 {"-1", 0, -1, nil},
105 {"12345", 0, 12345, nil},
106 {"-12345", 0, -12345, nil},
107 {"012345", 0, 012345, nil},
108 {"-012345", 0, -012345, nil},
109 {"0x12345", 0, 0x12345, nil},
110 {"-0X12345", 0, -0x12345, nil},
111 {"12345x", 0, 0, ErrSyntax},
112 {"-12345x", 0, 0, ErrSyntax},
113 {"98765432100", 0, 98765432100, nil},
114 {"-98765432100", 0, -98765432100, nil},
115 {"9223372036854775807", 0, 1<<63 - 1, nil},
116 {"-9223372036854775807", 0, -(1<<63 - 1), nil},
117 {"9223372036854775808", 0, 1<<63 - 1, ErrRange},
118 {"-9223372036854775808", 0, -1 << 63, nil},
119 {"9223372036854775809", 0, 1<<63 - 1, ErrRange},
120 {"-9223372036854775809", 0, -1 << 63, ErrRange},
122 // other bases
123 {"g", 17, 16, nil},
124 {"10", 25, 25, nil},
125 {"holycow", 35, (((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, nil},
126 {"holycow", 36, (((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, nil},
128 // base 2
129 {"0", 2, 0, nil},
130 {"-1", 2, -1, nil},
131 {"1010", 2, 10, nil},
132 {"1000000000000000", 2, 1 << 15, nil},
133 {"111111111111111111111111111111111111111111111111111111111111111", 2, 1<<63 - 1, nil},
134 {"1000000000000000000000000000000000000000000000000000000000000000", 2, 1<<63 - 1, ErrRange},
135 {"-1000000000000000000000000000000000000000000000000000000000000000", 2, -1 << 63, nil},
136 {"-1000000000000000000000000000000000000000000000000000000000000001", 2, -1 << 63, ErrRange},
138 // base 8
139 {"-10", 8, -8, nil},
140 {"57635436545", 8, 057635436545, nil},
141 {"100000000", 8, 1 << 24, nil},
143 // base 16
144 {"10", 16, 16, nil},
145 {"-123456789abcdef", 16, -0x123456789abcdef, nil},
146 {"7fffffffffffffff", 16, 1<<63 - 1, nil},
149 type parseUint32Test struct {
150 in string
151 out uint32
152 err error
155 var parseUint32Tests = []parseUint32Test{
156 {"", 0, ErrSyntax},
157 {"0", 0, nil},
158 {"1", 1, nil},
159 {"12345", 12345, nil},
160 {"012345", 12345, nil},
161 {"12345x", 0, ErrSyntax},
162 {"987654321", 987654321, nil},
163 {"4294967295", 1<<32 - 1, nil},
164 {"4294967296", 1<<32 - 1, ErrRange},
167 type parseInt32Test struct {
168 in string
169 out int32
170 err error
173 var parseInt32Tests = []parseInt32Test{
174 {"", 0, ErrSyntax},
175 {"0", 0, nil},
176 {"-0", 0, nil},
177 {"1", 1, nil},
178 {"-1", -1, nil},
179 {"12345", 12345, nil},
180 {"-12345", -12345, nil},
181 {"012345", 12345, nil},
182 {"-012345", -12345, nil},
183 {"12345x", 0, ErrSyntax},
184 {"-12345x", 0, ErrSyntax},
185 {"987654321", 987654321, nil},
186 {"-987654321", -987654321, nil},
187 {"2147483647", 1<<31 - 1, nil},
188 {"-2147483647", -(1<<31 - 1), nil},
189 {"2147483648", 1<<31 - 1, ErrRange},
190 {"-2147483648", -1 << 31, nil},
191 {"2147483649", 1<<31 - 1, ErrRange},
192 {"-2147483649", -1 << 31, ErrRange},
195 type numErrorTest struct {
196 num, want string
199 var numErrorTests = []numErrorTest{
200 {"0", `strconv.ParseFloat: parsing "0": failed`},
201 {"`", "strconv.ParseFloat: parsing \"`\": failed"},
202 {"1\x00.2", `strconv.ParseFloat: parsing "1\x00.2": failed`},
205 func init() {
206 // The parse routines return NumErrors wrapping
207 // the error and the string. Convert the tables above.
208 for i := range parseUint64Tests {
209 test := &parseUint64Tests[i]
210 if test.err != nil {
211 test.err = &NumError{"ParseUint", test.in, test.err}
214 for i := range parseUint64BaseTests {
215 test := &parseUint64BaseTests[i]
216 if test.err != nil {
217 test.err = &NumError{"ParseUint", test.in, test.err}
220 for i := range parseInt64Tests {
221 test := &parseInt64Tests[i]
222 if test.err != nil {
223 test.err = &NumError{"ParseInt", test.in, test.err}
226 for i := range parseInt64BaseTests {
227 test := &parseInt64BaseTests[i]
228 if test.err != nil {
229 test.err = &NumError{"ParseInt", test.in, test.err}
232 for i := range parseUint32Tests {
233 test := &parseUint32Tests[i]
234 if test.err != nil {
235 test.err = &NumError{"ParseUint", test.in, test.err}
238 for i := range parseInt32Tests {
239 test := &parseInt32Tests[i]
240 if test.err != nil {
241 test.err = &NumError{"ParseInt", test.in, test.err}
246 func TestParseUint32(t *testing.T) {
247 for i := range parseUint32Tests {
248 test := &parseUint32Tests[i]
249 out, err := ParseUint(test.in, 10, 32)
250 if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
251 t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v",
252 test.in, out, err, test.out, test.err)
257 func TestParseUint64(t *testing.T) {
258 for i := range parseUint64Tests {
259 test := &parseUint64Tests[i]
260 out, err := ParseUint(test.in, 10, 64)
261 if test.out != out || !reflect.DeepEqual(test.err, err) {
262 t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v",
263 test.in, out, err, test.out, test.err)
268 func TestParseUint64Base(t *testing.T) {
269 for i := range parseUint64BaseTests {
270 test := &parseUint64BaseTests[i]
271 out, err := ParseUint(test.in, test.base, 64)
272 if test.out != out || !reflect.DeepEqual(test.err, err) {
273 t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v",
274 test.in, test.base, out, err, test.out, test.err)
279 func TestParseInt32(t *testing.T) {
280 for i := range parseInt32Tests {
281 test := &parseInt32Tests[i]
282 out, err := ParseInt(test.in, 10, 32)
283 if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
284 t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v",
285 test.in, out, err, test.out, test.err)
290 func TestParseInt64(t *testing.T) {
291 for i := range parseInt64Tests {
292 test := &parseInt64Tests[i]
293 out, err := ParseInt(test.in, 10, 64)
294 if test.out != out || !reflect.DeepEqual(test.err, err) {
295 t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v",
296 test.in, out, err, test.out, test.err)
301 func TestParseInt64Base(t *testing.T) {
302 for i := range parseInt64BaseTests {
303 test := &parseInt64BaseTests[i]
304 out, err := ParseInt(test.in, test.base, 64)
305 if test.out != out || !reflect.DeepEqual(test.err, err) {
306 t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v",
307 test.in, test.base, out, err, test.out, test.err)
312 func TestParseUint(t *testing.T) {
313 switch IntSize {
314 case 32:
315 for i := range parseUint32Tests {
316 test := &parseUint32Tests[i]
317 out, err := ParseUint(test.in, 10, 0)
318 if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
319 t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
320 test.in, out, err, test.out, test.err)
323 case 64:
324 for i := range parseUint64Tests {
325 test := &parseUint64Tests[i]
326 out, err := ParseUint(test.in, 10, 0)
327 if test.out != out || !reflect.DeepEqual(test.err, err) {
328 t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
329 test.in, out, err, test.out, test.err)
335 func TestParseInt(t *testing.T) {
336 switch IntSize {
337 case 32:
338 for i := range parseInt32Tests {
339 test := &parseInt32Tests[i]
340 out, err := ParseInt(test.in, 10, 0)
341 if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
342 t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
343 test.in, out, err, test.out, test.err)
346 case 64:
347 for i := range parseInt64Tests {
348 test := &parseInt64Tests[i]
349 out, err := ParseInt(test.in, 10, 0)
350 if test.out != out || !reflect.DeepEqual(test.err, err) {
351 t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
352 test.in, out, err, test.out, test.err)
358 func TestAtoi(t *testing.T) {
359 switch IntSize {
360 case 32:
361 for i := range parseInt32Tests {
362 test := &parseInt32Tests[i]
363 out, err := Atoi(test.in)
364 var testErr error
365 if test.err != nil {
366 testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
368 if int(test.out) != out || !reflect.DeepEqual(testErr, err) {
369 t.Errorf("Atoi(%q) = %v, %v want %v, %v",
370 test.in, out, err, test.out, testErr)
373 case 64:
374 for i := range parseInt64Tests {
375 test := &parseInt64Tests[i]
376 out, err := Atoi(test.in)
377 var testErr error
378 if test.err != nil {
379 testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
381 if test.out != int64(out) || !reflect.DeepEqual(testErr, err) {
382 t.Errorf("Atoi(%q) = %v, %v want %v, %v",
383 test.in, out, err, test.out, testErr)
389 func bitSizeErrStub(name string, bitSize int) error {
390 return BitSizeError(name, "0", bitSize)
393 func baseErrStub(name string, base int) error {
394 return BaseError(name, "0", base)
397 func noErrStub(name string, arg int) error {
398 return nil
401 type parseErrorTest struct {
402 arg int
403 errStub func(name string, arg int) error
406 var parseBitSizeTests = []parseErrorTest{
407 {-1, bitSizeErrStub},
408 {0, noErrStub},
409 {64, noErrStub},
410 {65, bitSizeErrStub},
413 var parseBaseTests = []parseErrorTest{
414 {-1, baseErrStub},
415 {0, noErrStub},
416 {1, baseErrStub},
417 {2, noErrStub},
418 {36, noErrStub},
419 {37, baseErrStub},
422 func TestParseIntBitSize(t *testing.T) {
423 for i := range parseBitSizeTests {
424 test := &parseBitSizeTests[i]
425 testErr := test.errStub("ParseInt", test.arg)
426 _, err := ParseInt("0", 0, test.arg)
427 if !reflect.DeepEqual(testErr, err) {
428 t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v",
429 test.arg, err, testErr)
434 func TestParseUintBitSize(t *testing.T) {
435 for i := range parseBitSizeTests {
436 test := &parseBitSizeTests[i]
437 testErr := test.errStub("ParseUint", test.arg)
438 _, err := ParseUint("0", 0, test.arg)
439 if !reflect.DeepEqual(testErr, err) {
440 t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v",
441 test.arg, err, testErr)
446 func TestParseIntBase(t *testing.T) {
447 for i := range parseBaseTests {
448 test := &parseBaseTests[i]
449 testErr := test.errStub("ParseInt", test.arg)
450 _, err := ParseInt("0", test.arg, 0)
451 if !reflect.DeepEqual(testErr, err) {
452 t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v",
453 test.arg, err, testErr)
458 func TestParseUintBase(t *testing.T) {
459 for i := range parseBaseTests {
460 test := &parseBaseTests[i]
461 testErr := test.errStub("ParseUint", test.arg)
462 _, err := ParseUint("0", test.arg, 0)
463 if !reflect.DeepEqual(testErr, err) {
464 t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v",
465 test.arg, err, testErr)
470 func TestNumError(t *testing.T) {
471 for _, test := range numErrorTests {
472 err := &NumError{
473 Func: "ParseFloat",
474 Num: test.num,
475 Err: errors.New("failed"),
477 if got := err.Error(); got != test.want {
478 t.Errorf(`(&NumError{"ParseFloat", %q, "failed"}).Error() = %v, want %v`, test.num, got, test.want)
483 func BenchmarkParseInt(b *testing.B) {
484 b.Run("Pos", func(b *testing.B) {
485 benchmarkParseInt(b, 1)
487 b.Run("Neg", func(b *testing.B) {
488 benchmarkParseInt(b, -1)
492 type benchCase struct {
493 name string
494 num int64
497 func benchmarkParseInt(b *testing.B, neg int) {
498 cases := []benchCase{
499 {"7bit", 1<<7 - 1},
500 {"26bit", 1<<26 - 1},
501 {"31bit", 1<<31 - 1},
502 {"56bit", 1<<56 - 1},
503 {"63bit", 1<<63 - 1},
505 for _, cs := range cases {
506 b.Run(cs.name, func(b *testing.B) {
507 s := fmt.Sprintf("%d", cs.num*int64(neg))
508 for i := 0; i < b.N; i++ {
509 out, _ := ParseInt(s, 10, 64)
510 BenchSink += int(out)
516 func BenchmarkAtoi(b *testing.B) {
517 b.Run("Pos", func(b *testing.B) {
518 benchmarkAtoi(b, 1)
520 b.Run("Neg", func(b *testing.B) {
521 benchmarkAtoi(b, -1)
525 func benchmarkAtoi(b *testing.B, neg int) {
526 cases := []benchCase{
527 {"7bit", 1<<7 - 1},
528 {"26bit", 1<<26 - 1},
529 {"31bit", 1<<31 - 1},
531 if IntSize == 64 {
532 cases = append(cases, []benchCase{
533 {"56bit", 1<<56 - 1},
534 {"63bit", 1<<63 - 1},
535 }...)
537 for _, cs := range cases {
538 b.Run(cs.name, func(b *testing.B) {
539 s := fmt.Sprintf("%d", cs.num*int64(neg))
540 for i := 0; i < b.N; i++ {
541 out, _ := Atoi(s)
542 BenchSink += out