summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2008-11-18 17:12:07 -0800
committerRuss Cox <rsc@golang.org>2008-11-18 17:12:07 -0800
commitd81c463bdd945b62b74fea03bc9ad7660891e1e7 (patch)
tree500b9a192188c7c743f5f6cbbfe5a1cb6fd0e33c /src
parenta4bcb8c18d874d51f348143aa60715ac81bb68ec (diff)
downloadgolang-d81c463bdd945b62b74fea03bc9ad7660891e1e7.tar.gz
return *os.Error instead of bool from strconv.ato*
R=r DELTA=137 (56 added, 4 deleted, 77 changed) OCL=19505 CL=19522
Diffstat (limited to 'src')
-rw-r--r--src/lib/strconv/atof.go57
-rw-r--r--src/lib/strconv/atoi.go93
2 files changed, 100 insertions, 50 deletions
diff --git a/src/lib/strconv/atof.go b/src/lib/strconv/atof.go
index c0bb1a61c..5f019d3ec 100644
--- a/src/lib/strconv/atof.go
+++ b/src/lib/strconv/atof.go
@@ -10,7 +10,10 @@
package strconv
-import "strconv"
+import (
+ "os";
+ "strconv";
+)
// TODO(rsc): Better truncation handling.
func StringToDecimal(s string) (neg bool, d *Decimal, trunc bool, ok bool) {
@@ -314,43 +317,49 @@ func DecimalToFloat32(neg bool, d *Decimal, trunc bool) (f float32, ok bool) {
// returns f, false, true, where f is the nearest floating point
// number rounded using IEEE754 unbiased rounding.
//
-// If s is not syntactically well-formed, returns ok == false.
+// If s is not syntactically well-formed, returns err = os.EINVAL.
//
// If s is syntactically well-formed but is more than 1/2 ULP
// away from the largest floating point number of the given size,
-// returns f = ±Inf, overflow = true, ok = true.
-export func atof64(s string) (f float64, overflow bool, ok bool) {
- neg, d, trunc, ok1 := StringToDecimal(s);
- if !ok1 {
- return 0, false, false;
+// returns f = ±Inf, err = os.ERANGE.
+export func atof64(s string) (f float64, err *os.Error) {
+ neg, d, trunc, ok := StringToDecimal(s);
+ if !ok {
+ return 0, os.EINVAL;
}
if f, ok := DecimalToFloat64(neg, d, trunc); ok {
- return f, false, true;
+ return f, nil;
}
- b, overflow1 := DecimalToFloatBits(neg, d, trunc, &float64info);
- return sys.float64frombits(b), overflow1, true;
+ b, ovf := DecimalToFloatBits(neg, d, trunc, &float64info);
+ f = sys.float64frombits(b);
+ if ovf {
+ err = os.ERANGE;
+ }
+ return f, err
}
-export func atof32(s string) (f float32, overflow bool, ok bool) {
- neg, d, trunc, ok1 := StringToDecimal(s);
- if !ok1 {
- return 0, false, false;
+export func atof32(s string) (f float32, err *os.Error) {
+ neg, d, trunc, ok := StringToDecimal(s);
+ if !ok {
+ return 0, os.EINVAL;
}
if f, ok := DecimalToFloat32(neg, d, trunc); ok {
- return f, false, true;
+ return f, nil;
+ }
+ b, ovf := DecimalToFloatBits(neg, d, trunc, &float32info);
+ f = sys.float32frombits(uint32(b));
+ if ovf {
+ err = os.ERANGE;
}
- b, overflow1 := DecimalToFloatBits(neg, d, trunc, &float32info);
- return sys.float32frombits(uint32(b)), overflow1, true;
+ return f, err
}
-export func atof(s string) (f float, overflow bool, ok bool) {
+export func atof(s string) (f float, err *os.Error) {
if floatsize == 32 {
- var f1 float32;
- f1, overflow, ok = atof32(s);
- return float(f1), overflow, ok;
+ f1, err1 := atof32(s);
+ return float(f1), err1;
}
- var f1 float64;
- f1, overflow, ok = atof64(s);
- return float(f1), overflow, ok;
+ f1, err1 := atof64(s);
+ return float(f1), err1;
}
diff --git a/src/lib/strconv/atoi.go b/src/lib/strconv/atoi.go
index 7f741c304..cd02df1aa 100644
--- a/src/lib/strconv/atoi.go
+++ b/src/lib/strconv/atoi.go
@@ -3,42 +3,59 @@
// license that can be found in the LICENSE file.
package strconv
+import "os"
+
+func IntSize() uint {
+ siz := uint(8);
+ for 1<<siz != 0 {
+ siz *= 2
+ }
+ return siz
+}
+var intsize = IntSize();
// Convert decimal string to unsigned integer.
-// TODO: Doesn't check for overflow.
-export func atoui64(s string) (i uint64, ok bool) {
+export func atoui64(s string) (i uint64, err *os.Error) {
// empty string bad
- if len(s) == 0 {
- return 0, false
+ if len(s) == 0 {
+ return 0, os.EINVAL
}
// pick off zero
if s == "0" {
- return 0, true
+ return 0, nil
}
-
- // otherwise, leading zero bad
+
+ // otherwise, leading zero bad:
+ // don't want to take something intended as octal.
if s[0] == '0' {
- return 0, false
+ return 0, os.EINVAL
}
// parse number
n := uint64(0);
for i := 0; i < len(s); i++ {
if s[i] < '0' || s[i] > '9' {
- return 0, false
+ return 0, os.EINVAL
+ }
+ if n > (1<<64)/10 {
+ return 1<<64-1, os.ERANGE
}
- n = n*10 + uint64(s[i] - '0')
+ n = n*10;
+ d := uint64(s[i] - '0');
+ if n+d < n {
+ return 1<<64-1, os.ERANGE
+ }
+ n += d;
}
- return n, true
+ return n, nil
}
// Convert decimal string to integer.
-// TODO: Doesn't check for overflow.
-export func atoi64(s string) (i int64, ok bool) {
+export func atoi64(s string) (i int64, err *os.Error) {
// empty string bad
if len(s) == 0 {
- return 0, false
+ return 0, os.EINVAL
}
// pick off leading sign
@@ -51,25 +68,49 @@ export func atoi64(s string) (i int64, ok bool) {
}
var un uint64;
- un, ok = atoui64(s);
- if !ok {
- return 0, false
+ un, err = atoui64(s);
+ if err != nil && err != os.ERANGE {
+ return 0, err
+ }
+ if !neg && un >= 1<<63 {
+ return 1<<63-1, os.ERANGE
+ }
+ if neg && un > 1<<63 {
+ return -1<<63, os.ERANGE
}
n := int64(un);
if neg {
n = -n
}
- return n, true
+ return n, nil
}
-export func atoui(s string) (i uint, ok bool) {
- ii, okok := atoui64(s);
- i = uint(ii);
- return i, okok
+export func atoui(s string) (i uint, err *os.Error) {
+ i1, e1 := atoui64(s);
+ if e1 != nil && e1 != os.ERANGE {
+ return 0, e1
+ }
+ i = uint(i1);
+ if uint64(i) != i1 {
+ // TODO: return uint(^0), os.ERANGE.
+ i1 = 1<<64-1;
+ return uint(i1), os.ERANGE
+ }
+ return i, nil
}
-export func atoi(s string) (i int, ok bool) {
- ii, okok := atoi64(s);
- i = int(ii);
- return i, okok
+export func atoi(s string) (i int, err *os.Error) {
+ i1, e1 := atoi64(s);
+ if e1 != nil && e1 != os.ERANGE {
+ return 0, e1
+ }
+ i = int(i1);
+ if int64(i) != i1 {
+ if i1 < 0 {
+ return -1<<(intsize-1), os.ERANGE
+ }
+ return 1<<(intsize-1) - 1, os.ERANGE
+ }
+ return i, nil
}
+