about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/num/f32.rs6
-rw-r--r--src/libcore/num/f64.rs6
-rw-r--r--src/libcore/num/float.rs6
-rw-r--r--src/libcore/num/int-template.rs6
-rw-r--r--src/libcore/num/strconv.rs38
-rw-r--r--src/libcore/num/uint-template.rs6
6 files changed, 44 insertions, 24 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 6361a6a5cb7..fa82001151e 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -507,7 +507,7 @@ impl num::ToStrRadix for f32 {
 #[inline(always)]
 pub fn from_str(num: &str) -> Option<f32> {
     strconv::from_str_common(num, 10u, true, true, true,
-                             strconv::ExpDec, false)
+                             strconv::ExpDec, false, false)
 }
 
 /**
@@ -540,7 +540,7 @@ pub fn from_str(num: &str) -> Option<f32> {
 #[inline(always)]
 pub fn from_str_hex(num: &str) -> Option<f32> {
     strconv::from_str_common(num, 16u, true, true, true,
-                             strconv::ExpBin, false)
+                             strconv::ExpBin, false, false)
 }
 
 /**
@@ -565,7 +565,7 @@ pub fn from_str_hex(num: &str) -> Option<f32> {
 #[inline(always)]
 pub fn from_str_radix(num: &str, rdx: uint) -> Option<f32> {
     strconv::from_str_common(num, rdx, true, true, false,
-                             strconv::ExpNone, false)
+                             strconv::ExpNone, false, false)
 }
 
 impl from_str::FromStr for f32 {
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 9e731e61ec4..67dfabacd0b 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -529,7 +529,7 @@ impl num::ToStrRadix for f64 {
 #[inline(always)]
 pub fn from_str(num: &str) -> Option<f64> {
     strconv::from_str_common(num, 10u, true, true, true,
-                             strconv::ExpDec, false)
+                             strconv::ExpDec, false, false)
 }
 
 /**
@@ -562,7 +562,7 @@ pub fn from_str(num: &str) -> Option<f64> {
 #[inline(always)]
 pub fn from_str_hex(num: &str) -> Option<f64> {
     strconv::from_str_common(num, 16u, true, true, true,
-                             strconv::ExpBin, false)
+                             strconv::ExpBin, false, false)
 }
 
 /**
@@ -587,7 +587,7 @@ pub fn from_str_hex(num: &str) -> Option<f64> {
 #[inline(always)]
 pub fn from_str_radix(num: &str, rdx: uint) -> Option<f64> {
     strconv::from_str_common(num, rdx, true, true, false,
-                             strconv::ExpNone, false)
+                             strconv::ExpNone, false, false)
 }
 
 impl from_str::FromStr for f64 {
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index c80d52f496b..25082929703 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -242,7 +242,7 @@ impl num::ToStrRadix for float {
 #[inline(always)]
 pub fn from_str(num: &str) -> Option<float> {
     strconv::from_str_common(num, 10u, true, true, true,
-                             strconv::ExpDec, false)
+                             strconv::ExpDec, false, false)
 }
 
 /**
@@ -275,7 +275,7 @@ pub fn from_str(num: &str) -> Option<float> {
 #[inline(always)]
 pub fn from_str_hex(num: &str) -> Option<float> {
     strconv::from_str_common(num, 16u, true, true, true,
-                             strconv::ExpBin, false)
+                             strconv::ExpBin, false, false)
 }
 
 /**
@@ -300,7 +300,7 @@ pub fn from_str_hex(num: &str) -> Option<float> {
 #[inline(always)]
 pub fn from_str_radix(num: &str, radix: uint) -> Option<float> {
     strconv::from_str_common(num, radix, true, true, false,
-                             strconv::ExpNone, false)
+                             strconv::ExpNone, false, false)
 }
 
 impl from_str::FromStr for float {
diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs
index a3cbd9fe7e3..db90ec79465 100644
--- a/src/libcore/num/int-template.rs
+++ b/src/libcore/num/int-template.rs
@@ -202,21 +202,21 @@ impl ops::Neg<T> for T {
 #[inline(always)]
 pub fn from_str(s: &str) -> Option<T> {
     strconv::from_str_common(s, 10u, true, false, false,
-                         strconv::ExpNone, false)
+                         strconv::ExpNone, false, false)
 }
 
 /// Parse a string as a number in the given base.
 #[inline(always)]
 pub fn from_str_radix(s: &str, radix: uint) -> Option<T> {
     strconv::from_str_common(s, radix, true, false, false,
-                         strconv::ExpNone, false)
+                         strconv::ExpNone, false, false)
 }
 
 /// Parse a byte slice as a number in the given base.
 #[inline(always)]
 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
     strconv::from_str_bytes_common(buf, radix, true, false, false,
-                               strconv::ExpNone, false)
+                               strconv::ExpNone, false, false)
 }
 
 impl FromStr for T {
diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs
index 687b6344b39..95da5bc29f5 100644
--- a/src/libcore/num/strconv.rs
+++ b/src/libcore/num/strconv.rs
@@ -429,6 +429,8 @@ priv static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
  *                  `FFp128`. The exponent string itself is always base 10.
  *                  Can conflict with `radix`, see Failure.
  * - `empty_zero` - Whether to accept a empty `buf` as a 0 or not.
+ * - `ignore_underscores` - Whether all underscores within the string should
+ *                          be ignored.
  *
  * # Return value
  * Returns `Some(n)` if `buf` parses to a number n without overflowing, and
@@ -443,16 +445,13 @@ priv static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
  *   between digit and exponent sign `'p'`.
  * - Fails if `radix` > 18 and `special == true` due to conflict
  *   between digit and lowest first character in `inf` and `NaN`, the `'i'`.
- *
- * # Possible improvements
- * - Could accept option to allow ignoring underscores, allowing for numbers
- *   formated like `FF_AE_FF_FF`.
  */
 pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                                     Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>+
                                     NumStrConv>(
         buf: &[u8], radix: uint, negative: bool, fractional: bool,
-        special: bool, exponent: ExponentFormat, empty_zero: bool
+        special: bool, exponent: ExponentFormat, empty_zero: bool,
+        ignore_underscores: bool
         ) -> Option<T> {
     match exponent {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
@@ -540,6 +539,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                 last_accum = accum;
             }
             None => match c {
+                '_' if ignore_underscores => {}
                 'e' | 'E' | 'p' | 'P' => {
                     exp_found = true;
                     break;                       // start of exponent
@@ -583,6 +583,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                     last_accum = accum;
                 }
                 None => match c {
+                    '_' if ignore_underscores => {}
                     'e' | 'E' | 'p' | 'P' => {
                         exp_found = true;
                         break;                   // start of exponent
@@ -610,6 +611,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
     if exp_found {
         let c = buf[i] as char;
         let base = match (c, exponent) {
+            // c is never _ so don't need to handle specially
             ('e', ExpDec) | ('E', ExpDec) => 10u,
             ('p', ExpBin) | ('P', ExpBin) => 2u,
             _ => return None // char doesn't fit given exponent format
@@ -618,7 +620,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
         // parse remaining bytes as decimal integer,
         // skipping the exponent char
         let exp: Option<int> = from_str_bytes_common(
-            buf.slice(i+1, len), 10, true, false, false, ExpNone, false);
+            buf.slice(i+1, len), 10, true, false, false, ExpNone, false,
+            ignore_underscores);
 
         match exp {
             Some(exp_pow) => {
@@ -643,10 +646,12 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
 pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+Mul<T,T>+
                               Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv>(
         buf: &str, radix: uint, negative: bool, fractional: bool,
-        special: bool, exponent: ExponentFormat, empty_zero: bool
+        special: bool, exponent: ExponentFormat, empty_zero: bool,
+        ignore_underscores: bool
         ) -> Option<T> {
     from_str_bytes_common(str::to_bytes(buf), radix, negative,
-                            fractional, special, exponent, empty_zero)
+                          fractional, special, exponent, empty_zero,
+                          ignore_underscores)
 }
 
 #[cfg(test)]
@@ -655,12 +660,27 @@ mod test {
     use option::*;
 
     #[test]
+    fn from_str_ignore_underscores() {
+        let s : Option<u8> = from_str_common("__1__", 2, false, false, false,
+                                             ExpNone, false, true);
+        assert_eq!(s, Some(1u8));
+
+        let n : Option<u8> = from_str_common("__1__", 2, false, false, false,
+                                             ExpNone, false, false);
+        assert_eq!(n, None);
+
+        let f : Option<f32> = from_str_common("_1_._1_e_1_", 10, false, true, false,
+                                              ExpDec, false, true);
+        assert_eq!(f, Some(1.1e1f32));
+    }
+
+    #[test]
     fn from_str_issue5770() {
         // try to parse 0b1_1111_1111 = 511 as a u8. Caused problems
         // since 255*2+1 == 255 (mod 256) so the overflow wasn't
         // detected.
         let n : Option<u8> = from_str_common("111111111", 2, false, false, false,
-                                             ExpNone, false);
+                                             ExpNone, false, false);
         assert_eq!(n, None);
     }
 }
diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs
index 400417284a2..39af025217c 100644
--- a/src/libcore/num/uint-template.rs
+++ b/src/libcore/num/uint-template.rs
@@ -168,21 +168,21 @@ impl ops::Neg<T> for T {
 #[inline(always)]
 pub fn from_str(s: &str) -> Option<T> {
     strconv::from_str_common(s, 10u, false, false, false,
-                             strconv::ExpNone, false)
+                             strconv::ExpNone, false, false)
 }
 
 /// Parse a string as a number in the given base.
 #[inline(always)]
 pub fn from_str_radix(s: &str, radix: uint) -> Option<T> {
     strconv::from_str_common(s, radix, false, false, false,
-                             strconv::ExpNone, false)
+                             strconv::ExpNone, false, false)
 }
 
 /// Parse a byte slice as a number in the given base.
 #[inline(always)]
 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
     strconv::from_str_bytes_common(buf, radix, false, false, false,
-                                   strconv::ExpNone, false)
+                                   strconv::ExpNone, false, false)
 }
 
 impl FromStr for T {