From ffd50b9cdfa38bc80f2444d917eef5a02c38c32f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 22 Feb 2012 13:18:15 +0100 Subject: [PATCH] Make the various from_str functions return options So that they can be used with user input without causing task failures. Closes #1335 --- src/comp/metadata/decoder.rs | 9 +- src/comp/metadata/tydecode.rs | 4 +- src/comp/syntax/ast_util.rs | 2 +- src/comp/syntax/parse/lexer.rs | 8 +- src/libcore/bool.rs | 10 +- src/libcore/char.rs | 69 +++++-------- src/libcore/float.rs | 88 ++++++++--------- src/libcore/int.rs | 118 ++++++++--------------- src/libcore/option.rs | 10 ++ src/libcore/u64.rs | 16 ++- src/libcore/uint.rs | 83 ++++++---------- src/libstd/net.rs | 9 +- src/test/bench/msgsend.rs | 4 +- src/test/bench/shootout-ackermann.rs | 2 +- src/test/bench/shootout-binarytrees.rs | 3 +- src/test/bench/shootout-fannkuchredux.rs | 2 +- src/test/bench/shootout-fibo.rs | 2 +- src/test/bench/shootout-mandelbrot.rs | 37 +++---- src/test/bench/shootout-nbody.rs | 2 +- src/test/bench/shootout-pfib.rs | 3 +- src/test/bench/shootout-spectralnorm.rs | 2 +- src/test/bench/shootout-threadring.rs | 7 +- src/test/bench/sudoku.rs | 6 +- src/test/bench/task-perf-one-million.rs | 2 +- src/test/bench/task-perf-spawnalot.rs | 8 +- src/test/bench/task-perf-vector-party.rs | 12 +-- 26 files changed, 203 insertions(+), 315 deletions(-) diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 867497f37fdab..06b0acdf4a14d 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -95,13 +95,8 @@ fn variant_enum_id(d: ebml::doc) -> ast::def_id { } fn variant_disr_val(d: ebml::doc) -> option { - alt ebml::maybe_get_doc(d, tag_disr_val) { - some(val_doc) { - let val_buf = ebml::doc_data(val_doc); - let val = int::parse_buf(val_buf, 10u); - ret some(val); - } - _ { ret none;} + option::chain(ebml::maybe_get_doc(d, tag_disr_val)) {|val_doc| + int::parse_buf(ebml::doc_data(val_doc), 10u) } } diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index 9bd7ee75512eb..5d97777c0fb6e 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -390,8 +390,8 @@ fn parse_def_id(buf: [u8]) -> ast::def_id { for b: u8 in crate_part { crate_part_vec += [b]; } for b: u8 in def_part { def_part_vec += [b]; } - let crate_num = uint::parse_buf(crate_part_vec, 10u) as int; - let def_num = uint::parse_buf(def_part_vec, 10u) as int; + let crate_num = option::get(uint::parse_buf(crate_part_vec, 10u)) as int; + let def_num = option::get(uint::parse_buf(def_part_vec, 10u)) as int; ret {crate: crate_num, node: def_num}; } diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index 09242f40c4217..b9d48cb5fb089 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -301,7 +301,7 @@ fn lit_to_const(lit: @lit) -> const_val { lit_str(s) { const_str(s) } lit_int(n, _) { const_int(n) } lit_uint(n, _) { const_uint(n) } - lit_float(n, _) { const_float(float::from_str(n)) } + lit_float(n, _) { const_float(option::get(float::from_str(n))) } lit_nil { const_int(0i64) } lit_bool(b) { const_int(b as i64) } } diff --git a/src/comp/syntax/parse/lexer.rs b/src/comp/syntax/parse/lexer.rs index aa989cb0f61d9..113ca056ed40b 100644 --- a/src/comp/syntax/parse/lexer.rs +++ b/src/comp/syntax/parse/lexer.rs @@ -174,8 +174,8 @@ fn scan_digits(rdr: reader, radix: uint) -> str { while true { let c = rdr.curr; if c == '_' { rdr.bump(); cont; } - alt char::maybe_digit(c) { - some(d) if (d as uint) < radix { + alt char::to_digit(c, radix) { + some(d) { str::push_char(rslt, c); rdr.bump(); } @@ -229,7 +229,7 @@ fn scan_number(c: char, rdr: reader) -> token::token { if str::len_bytes(num_str) == 0u { rdr.fatal("no valid digits found for number"); } - let parsed = u64::from_str(num_str, base as u64); + let parsed = option::get(u64::from_str(num_str, base as u64)); alt tp { either::left(t) { ret token::LIT_INT(parsed as i64, t); } either::right(t) { ret token::LIT_UINT(parsed, t); } @@ -276,7 +276,7 @@ fn scan_number(c: char, rdr: reader) -> token::token { if str::len_bytes(num_str) == 0u { rdr.fatal("no valid digits found for number"); } - let parsed = u64::from_str(num_str, base as u64); + let parsed = option::get(u64::from_str(num_str, base as u64)); ret token::LIT_INT(parsed as i64, ast::ty_i); } } diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index cc4efe54dfc2c..63a38e7846ad2 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -59,11 +59,11 @@ pure fn is_false(v: t) -> bool { !v } #[doc( brief = "Parse logic value from `s`" )] -pure fn from_str(s: str) -> t { +pure fn from_str(s: str) -> option { alt check s { - "true" { true } - "false" { false } - _ { fail "'" + s + "' is not a valid boolean string"; } + "true" { some(true) } + "false" { some(false) } + _ { none } } } @@ -89,7 +89,7 @@ pure fn to_bit(v: t) -> u8 { if v { 1u8 } else { 0u8 } } #[test] fn test_bool_from_str() { all_values { |v| - assert v == from_str(bool::to_str(v)) + assert some(v) == from_str(bool::to_str(v)) } } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 6f3466fb00b2e..123d739ba2c5c 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -38,7 +38,7 @@ export is_alphabetic, is_lowercase, is_uppercase, is_whitespace, is_alphanumeric, is_ascii, is_digit, - to_digit, to_lower, to_upper, maybe_digit, cmp; + to_digit, to_lower, to_upper, cmp; import is_alphabetic = unicode::derived_property::Alphabetic; import is_XID_start = unicode::derived_property::XID_Start; @@ -102,26 +102,18 @@ pure fn is_digit(c: char) -> bool { Safety note: This function fails if `c` is not a valid char", return = "If `c` is between '0' and '9', the corresponding value \ between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is \ - 'b' or 'B', 11, etc." + 'b' or 'B', 11, etc. Returns none if the char does not \ + refer to a digit in the given radix." )] -pure fn to_digit(c: char) -> u8 unsafe { - alt maybe_digit(c) { - option::some(x) { x } - option::none { fail; } - } -} - -#[doc( - brief = "Convert a char to the corresponding digit. Returns none when \ - character is not a valid hexadecimal digit." -)] -pure fn maybe_digit(c: char) -> option { - alt c { - '0' to '9' { option::some(c as u8 - ('0' as u8)) } - 'a' to 'z' { option::some(c as u8 + 10u8 - ('a' as u8)) } - 'A' to 'Z' { option::some(c as u8 + 10u8 - ('A' as u8)) } - _ { option::none } - } +pure fn to_digit(c: char, radix: uint) -> option { + let val = alt c { + '0' to '9' { c as uint - ('0' as uint) } + 'a' to 'z' { c as uint + 10u - ('a' as uint) } + 'A' to 'Z' { c as uint + 10u - ('A' as uint) } + _ { ret none; } + }; + if val < radix { some(val) } + else { none } } /* @@ -192,30 +184,19 @@ fn test_is_whitespace() { #[test] fn test_to_digit() { - assert (to_digit('0') == 0u8); - assert (to_digit('1') == 1u8); - assert (to_digit('2') == 2u8); - assert (to_digit('9') == 9u8); - assert (to_digit('a') == 10u8); - assert (to_digit('A') == 10u8); - assert (to_digit('b') == 11u8); - assert (to_digit('B') == 11u8); - assert (to_digit('z') == 35u8); - assert (to_digit('Z') == 35u8); -} - -#[test] -#[should_fail] -#[ignore(cfg(target_os = "win32"))] -fn test_to_digit_fail_1() { - to_digit(' '); -} - -#[test] -#[should_fail] -#[ignore(cfg(target_os = "win32"))] -fn test_to_digit_fail_2() { - to_digit('$'); + assert to_digit('0', 10u) == some(0u); + assert to_digit('1', 2u) == some(1u); + assert to_digit('2', 3u) == some(2u); + assert to_digit('9', 10u) == some(9u); + assert to_digit('a', 16u) == some(10u); + assert to_digit('A', 16u) == some(10u); + assert to_digit('b', 16u) == some(11u); + assert to_digit('B', 16u) == some(11u); + assert to_digit('z', 36u) == some(35u); + assert to_digit('Z', 36u) == some(35u); + + assert to_digit(' ', 10u) == none; + assert to_digit('$', 36u) == none; } #[test] diff --git a/src/libcore/float.rs b/src/libcore/float.rs index c4e6e0403199d..b21d154097faf 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -122,28 +122,27 @@ Leading and trailing whitespace are ignored. Parameters: -num - A string, possibly empty. +num - A string Returns: - If the string did not represent a valid number. -Otherwise, the floating-point number represented [num]. +none if the string did not represent a valid number. +Otherwise, some(n) where n is the floating-point +number represented by [num]. */ -fn from_str(num: str) -> float { - let num = str::trim(num); - +fn from_str(num: str) -> option { let pos = 0u; //Current byte position in the string. //Used to walk the string in O(n). let len = str::len_bytes(num); //Length of the string, in bytes. - if len == 0u { ret 0.; } + if len == 0u { ret none; } let total = 0f; //Accumulated result let c = 'z'; //Latest char. //The string must start with one of the following characters. alt str::char_at(num, 0u) { '-' | '+' | '0' to '9' | '.' {} - _ { ret NaN; } + _ { ret none; } } //Determine if first char is '-'/'+'. Set [pos] and [neg] accordingly. @@ -173,7 +172,7 @@ fn from_str(num: str) -> float { break; } _ { - ret NaN; + ret none; } } } @@ -193,7 +192,7 @@ fn from_str(num: str) -> float { break; } _ { - ret NaN; + ret none; } } } @@ -238,17 +237,17 @@ fn from_str(num: str) -> float { total = total * multiplier; } } else { - ret NaN; + ret none; } } if(pos < len) { - ret NaN; + ret none; } else { if(neg) { total *= -1f; } - ret total; + ret some(total); } } @@ -291,39 +290,36 @@ fn pow_uint_to_uint_as_float(x: uint, pow: uint) -> float { #[test] fn test_from_str() { - assert ( from_str("3") == 3. ); - assert ( from_str(" 3 ") == 3. ); - assert ( from_str("3.14") == 3.14 ); - assert ( from_str("+3.14") == 3.14 ); - assert ( from_str("-3.14") == -3.14 ); - assert ( from_str("2.5E10") == 25000000000. ); - assert ( from_str("2.5e10") == 25000000000. ); - assert ( from_str("25000000000.E-10") == 2.5 ); - assert ( from_str("") == 0. ); - assert ( from_str(".") == 0. ); - assert ( from_str(".e1") == 0. ); - assert ( from_str(".e-1") == 0. ); - assert ( from_str("5.") == 5. ); - assert ( from_str(".5") == 0.5 ); - assert ( from_str("0.5") == 0.5 ); - assert ( from_str("0.5 ") == 0.5 ); - assert ( from_str(" 0.5 ") == 0.5 ); - assert ( from_str(" -.5 ") == -0.5 ); - assert ( from_str(" -.5 ") == -0.5 ); - assert ( from_str(" -5 ") == -5. ); - - assert ( is_NaN(from_str("x")) ); - assert ( from_str(" ") == 0. ); - assert ( from_str(" ") == 0. ); - assert ( from_str(" 0.5") == 0.5 ); - assert ( from_str(" 0.5 ") == 0.5 ); - assert ( from_str(" .1 ") == 0.1 ); - assert ( is_NaN(from_str("e")) ); - assert ( is_NaN(from_str("E")) ); - assert ( is_NaN(from_str("E1")) ); - assert ( is_NaN(from_str("1e1e1")) ); - assert ( is_NaN(from_str("1e1.1")) ); - assert ( is_NaN(from_str("1e1-1")) ); + assert from_str("3") == some(3.); + assert from_str("3") == some(3.); + assert from_str("3.14") == some(3.14); + assert from_str("+3.14") == some(3.14); + assert from_str("-3.14") == some(-3.14); + assert from_str("2.5E10") == some(25000000000.); + assert from_str("2.5e10") == some(25000000000.); + assert from_str("25000000000.E-10") == some(2.5); + assert from_str(".") == some(0.); + assert from_str(".e1") == some(0.); + assert from_str(".e-1") == some(0.); + assert from_str("5.") == some(5.); + assert from_str(".5") == some(0.5); + assert from_str("0.5") == some(0.5); + assert from_str("0.5") == some(0.5); + assert from_str("0.5") == some(0.5); + assert from_str("-.5") == some(-0.5); + assert from_str("-.5") == some(-0.5); + assert from_str("-5") == some(-5.); + + assert from_str("") == none; + assert from_str("x") == none; + assert from_str(" ") == none; + assert from_str(" ") == none; + assert from_str("e") == none; + assert from_str("E") == none; + assert from_str("E1") == none; + assert from_str("1e1e1") == none; + assert from_str("1e1.1") == none; + assert from_str("1e1-1") == none; } #[test] diff --git a/src/libcore/int.rs b/src/libcore/int.rs index 41814b123ad61..8567fc7ccc8ff 100644 --- a/src/libcore/int.rs +++ b/src/libcore/int.rs @@ -103,17 +103,10 @@ Parameters: buf - A byte buffer radix - The base of the number - -Failure: - -buf must not be empty */ -fn parse_buf(buf: [u8], radix: uint) -> int { - if vec::len::(buf) == 0u { - #error("parse_buf(): buf is empty"); - fail; - } - let i = vec::len::(buf) - 1u; +fn parse_buf(buf: [u8], radix: uint) -> option { + if vec::len(buf) == 0u { ret none; } + let i = vec::len(buf) - 1u; let start = 0u; let power = 1; @@ -123,13 +116,12 @@ fn parse_buf(buf: [u8], radix: uint) -> int { } let n = 0; while true { - let digit = char::to_digit(buf[i] as char); - if (digit as uint) >= radix { - fail; + alt char::to_digit(buf[i] as char, radix) { + some(d) { n += (d as int) * power; } + none { ret none; } } - n += (digit as int) * power; power *= radix as int; - if i <= start { ret n; } + if i <= start { ret some(n); } i -= 1u; } fail; @@ -139,12 +131,8 @@ fn parse_buf(buf: [u8], radix: uint) -> int { Function: from_str Parse a string to an int - -Failure: - -s must not be empty */ -fn from_str(s: str) -> int { parse_buf(str::bytes(s), 10u) } +fn from_str(s: str) -> option { parse_buf(str::bytes(s), 10u) } /* Function: to_str @@ -198,67 +186,45 @@ fn abs(i: int) -> int { #[test] fn test_from_str() { - assert(from_str("0") == 0); - assert(from_str("3") == 3); - assert(from_str("10") == 10); - assert(from_str("123456789") == 123456789); - assert(from_str("00100") == 100); - - assert(from_str("-1") == -1); - assert(from_str("-3") == -3); - assert(from_str("-10") == -10); - assert(from_str("-123456789") == -123456789); - assert(from_str("-00100") == -100); -} - -#[test] -#[should_fail] -#[ignore(cfg(target_os = "win32"))] -fn test_from_str_fail_1() { - from_str(" "); -} - -#[test] -#[should_fail] -#[ignore(cfg(target_os = "win32"))] -fn test_from_str_fail_2() { - from_str("x"); + assert from_str("0") == some(0); + assert from_str("3") == some(3); + assert from_str("10") == some(10); + assert from_str("123456789") == some(123456789); + assert from_str("00100") == some(100); + + assert from_str("-1") == some(-1); + assert from_str("-3") == some(-3); + assert from_str("-10") == some(-10); + assert from_str("-123456789") == some(-123456789); + assert from_str("-00100") == some(-100); + + assert from_str(" ") == none; + assert from_str("x") == none; } #[test] fn test_parse_buf() { import str::bytes; - assert (parse_buf(bytes("123"), 10u) == 123); - assert (parse_buf(bytes("1001"), 2u) == 9); - assert (parse_buf(bytes("123"), 8u) == 83); - assert (parse_buf(bytes("123"), 16u) == 291); - assert (parse_buf(bytes("ffff"), 16u) == 65535); - assert (parse_buf(bytes("FFFF"), 16u) == 65535); - assert (parse_buf(bytes("z"), 36u) == 35); - assert (parse_buf(bytes("Z"), 36u) == 35); - - assert (parse_buf(bytes("-123"), 10u) == -123); - assert (parse_buf(bytes("-1001"), 2u) == -9); - assert (parse_buf(bytes("-123"), 8u) == -83); - assert (parse_buf(bytes("-123"), 16u) == -291); - assert (parse_buf(bytes("-ffff"), 16u) == -65535); - assert (parse_buf(bytes("-FFFF"), 16u) == -65535); - assert (parse_buf(bytes("-z"), 36u) == -35); - assert (parse_buf(bytes("-Z"), 36u) == -35); -} - -#[test] -#[should_fail] -#[ignore(cfg(target_os = "win32"))] -fn test_parse_buf_fail_1() { - parse_buf(str::bytes("Z"), 35u); -} - -#[test] -#[should_fail] -#[ignore(cfg(target_os = "win32"))] -fn test_parse_buf_fail_2() { - parse_buf(str::bytes("-9"), 2u); + assert parse_buf(bytes("123"), 10u) == some(123); + assert parse_buf(bytes("1001"), 2u) == some(9); + assert parse_buf(bytes("123"), 8u) == some(83); + assert parse_buf(bytes("123"), 16u) == some(291); + assert parse_buf(bytes("ffff"), 16u) == some(65535); + assert parse_buf(bytes("FFFF"), 16u) == some(65535); + assert parse_buf(bytes("z"), 36u) == some(35); + assert parse_buf(bytes("Z"), 36u) == some(35); + + assert parse_buf(bytes("-123"), 10u) == some(-123); + assert parse_buf(bytes("-1001"), 2u) == some(-9); + assert parse_buf(bytes("-123"), 8u) == some(-83); + assert parse_buf(bytes("-123"), 16u) == some(-291); + assert parse_buf(bytes("-ffff"), 16u) == some(-65535); + assert parse_buf(bytes("-FFFF"), 16u) == some(-65535); + assert parse_buf(bytes("-z"), 36u) == some(-35); + assert parse_buf(bytes("-Z"), 36u) == some(-35); + + assert parse_buf(str::bytes("Z"), 35u) == none; + assert parse_buf(str::bytes("-9"), 2u) == none; } #[test] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 1ac8b3cc71497..8442197542558 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -40,6 +40,16 @@ fn map(opt: t, f: fn(T) -> U) -> t { alt opt { some(x) { some(f(x)) } none { none } } } +/* +Function: chain + +Update an optional value by optionally running its content through a function +that returns an option. +*/ +fn chain(opt: t, f: fn(T) -> t) -> t { + alt opt { some(x) { f(x) } none { none } } +} + /* Function: is_none diff --git a/src/libcore/u64.rs b/src/libcore/u64.rs index 4c76e79bd0a27..9edf4dd03c739 100644 --- a/src/libcore/u64.rs +++ b/src/libcore/u64.rs @@ -117,19 +117,17 @@ Function: from_str Parse a string as an unsigned integer. */ -fn from_str(buf: str, radix: u64) -> u64 { - if str::len_bytes(buf) == 0u { - #error("parse_buf(): buf is empty"); - fail; - } +fn from_str(buf: str, radix: u64) -> option { + if str::len_bytes(buf) == 0u { ret none; } let i = str::len_bytes(buf) - 1u; let power = 1u64, n = 0u64; while true { - let digit = char::to_digit(buf[i] as char) as u64; - if digit >= radix { fail; } - n += digit * power; + alt char::to_digit(buf[i] as char, radix) { + some(d) { n += d as u64 * power; } + none { ret none; } + } power *= radix; - if i == 0u { ret n; } + if i == 0u { ret some(n); } i -= 1u; } fail; diff --git a/src/libcore/uint.rs b/src/libcore/uint.rs index ee2ec7dff400c..b5e425d2b1de5 100644 --- a/src/libcore/uint.rs +++ b/src/libcore/uint.rs @@ -188,22 +188,18 @@ Failure: buf must not be empty */ -fn parse_buf(buf: [u8], radix: uint) -> uint { - if vec::len::(buf) == 0u { - #error("parse_buf(): buf is empty"); - fail; - } - let i = vec::len::(buf) - 1u; +fn parse_buf(buf: [u8], radix: uint) -> option { + if vec::len(buf) == 0u { ret none; } + let i = vec::len(buf) - 1u; let power = 1u; let n = 0u; while true { - let digit = char::to_digit(buf[i] as char); - if (digit as uint) >= radix { - fail; + alt char::to_digit(buf[i] as char, radix) { + some(d) { n += d * power; } + none { ret none; } } - n += (digit as uint) * power; power *= radix; - if i == 0u { ret n; } + if i == 0u { ret some(n); } i -= 1u; } fail; @@ -213,12 +209,8 @@ fn parse_buf(buf: [u8], radix: uint) -> uint { Function: from_str Parse a string to an int - -Failure: - -s must not be empty */ -fn from_str(s: str) -> uint { parse_buf(str::bytes(s), 10u) } +fn from_str(s: str) -> option { parse_buf(str::bytes(s), 10u) } /* Function: to_str @@ -282,50 +274,29 @@ mod tests { #[test] fn test_from_str() { - assert (uint::from_str("0") == 0u); - assert (uint::from_str("3") == 3u); - assert (uint::from_str("10") == 10u); - assert (uint::from_str("123456789") == 123456789u); - assert (uint::from_str("00100") == 100u); + assert uint::from_str("0") == some(0u); + assert uint::from_str("3") == some(3u); + assert uint::from_str("10") == some(10u); + assert uint::from_str("123456789") == some(123456789u); + assert uint::from_str("00100") == some(100u); + + assert uint::from_str("") == none; + assert uint::from_str(" ") == none; + assert uint::from_str("x") == none; } - #[test] - #[should_fail] - #[ignore(cfg(target_os = "win32"))] - fn test_from_str_fail_1() { - uint::from_str(" "); - } - - #[test] - #[should_fail] - #[ignore(cfg(target_os = "win32"))] - fn test_from_str_fail_2() { - uint::from_str("x"); - } - - #[test] + #[Test] fn test_parse_buf() { import str::bytes; - assert (uint::parse_buf(bytes("123"), 10u) == 123u); - assert (uint::parse_buf(bytes("1001"), 2u) == 9u); - assert (uint::parse_buf(bytes("123"), 8u) == 83u); - assert (uint::parse_buf(bytes("123"), 16u) == 291u); - assert (uint::parse_buf(bytes("ffff"), 16u) == 65535u); - assert (uint::parse_buf(bytes("z"), 36u) == 35u); - } - - #[test] - #[should_fail] - #[ignore(cfg(target_os = "win32"))] - fn test_parse_buf_fail_1() { - uint::parse_buf(str::bytes("Z"), 10u); - } - - #[test] - #[should_fail] - #[ignore(cfg(target_os = "win32"))] - fn test_parse_buf_fail_2() { - uint::parse_buf(str::bytes("_"), 2u); + assert uint::parse_buf(bytes("123"), 10u) == some(123u); + assert uint::parse_buf(bytes("1001"), 2u) == some(9u); + assert uint::parse_buf(bytes("123"), 8u) == some(83u); + assert uint::parse_buf(bytes("123"), 16u) == some(291u); + assert uint::parse_buf(bytes("ffff"), 16u) == some(65535u); + assert uint::parse_buf(bytes("z"), 36u) == some(35u); + + assert uint::parse_buf(str::bytes("Z"), 10u) == none; + assert uint::parse_buf(str::bytes("_"), 2u) == none; } #[test] diff --git a/src/libstd/net.rs b/src/libstd/net.rs index 68f8f29748a45..2325598a2d376 100644 --- a/src/libstd/net.rs +++ b/src/libstd/net.rs @@ -49,10 +49,13 @@ Failure: String must be a valid IPv4 address */ fn parse_addr(ip: str) -> ip_addr { - let parts = vec::map(str::split_byte(ip, "."[0]), - {|s| uint::from_str(s) }); + let parts = vec::map(str::split_byte(ip, "."[0]), {|s| + alt uint::from_str(s) { + some(n) if n <= 255u { n } + _ { fail "Invalid IP Address part." } + } + }); if vec::len(parts) != 4u { fail "Too many dots in IP address"; } - for i in parts { if i > 255u { fail "Invalid IP Address part."; } } ipv4(parts[0] as u8, parts[1] as u8, parts[2] as u8, parts[3] as u8) } diff --git a/src/test/bench/msgsend.rs b/src/test/bench/msgsend.rs index 73db81c88a053..36a974002a21f 100644 --- a/src/test/bench/msgsend.rs +++ b/src/test/bench/msgsend.rs @@ -33,8 +33,8 @@ fn run(args: [str]) { let to_child = task::spawn_listener {|po| server(po, to_parent); }; - let size = uint::from_str(args[1]); - let workers = uint::from_str(args[2]); + let size = option::get(uint::from_str(args[1])); + let workers = option::get(uint::from_str(args[2])); let start = std::time::precise_time_s(); let to_child = to_child; let worker_results = []; diff --git a/src/test/bench/shootout-ackermann.rs b/src/test/bench/shootout-ackermann.rs index ca0555ca49d57..92a6a18230811 100644 --- a/src/test/bench/shootout-ackermann.rs +++ b/src/test/bench/shootout-ackermann.rs @@ -14,7 +14,7 @@ fn ack(m: int, n: int) -> int { fn main(args: [str]) { let n = if vec::len(args) == 2u { - int::from_str(args[1]) + option::get(int::from_str(args[1])) } else { 8 }; diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index 3f1d47d3be2cf..3054e364dd305 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -1,5 +1,4 @@ use std; -import int; enum tree { nil, node(~tree, ~tree, int), } @@ -21,7 +20,7 @@ fn bottom_up_tree(item: int, depth: int) -> ~tree { fn main(args: [str]) { let n = if vec::len(args) == 2u { - int::from_str(args[1]) + option::get(int::from_str(args[1])) } else { 8 }; diff --git a/src/test/bench/shootout-fannkuchredux.rs b/src/test/bench/shootout-fannkuchredux.rs index 65c1971af6e88..26ed2fcf0a4ac 100644 --- a/src/test/bench/shootout-fannkuchredux.rs +++ b/src/test/bench/shootout-fannkuchredux.rs @@ -60,7 +60,7 @@ fn fannkuch(n: int) -> int { fn main(args: [str]) { let n = if vec::len(args) == 2u { - int::from_str(args[1]) + option::get(int::from_str(args[1])) } else { 8 }; diff --git a/src/test/bench/shootout-fibo.rs b/src/test/bench/shootout-fibo.rs index ad31289a10948..2868cb0f667a0 100644 --- a/src/test/bench/shootout-fibo.rs +++ b/src/test/bench/shootout-fibo.rs @@ -10,7 +10,7 @@ fn fib(n: int) -> int { fn main(args: [str]) { let n = if vec::len(args) == 2u { - int::from_str(args[1]) + option::get(int::from_str(args[1])) } else { 30 }; diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 985b2e8250458..984e8d78a18af 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -136,36 +136,21 @@ fn writer(path: str, writech: comm::chan>, size: uint) } } -fn main(argv: [str]) -{ - let size = if vec::len(argv) < 2_u { - 80u - } - else { - uint::from_str(argv[1]) - }; - let yieldevery = if vec::len(argv) < 3_u { - 10_u - } - else { - uint::from_str(argv[2]) - }; - let path = if vec::len(argv) < 4_u { - "" - } - else { - argv[3] - }; +fn main(argv: [str]) { + let size = if vec::len(argv) < 2_u { 80u } + else { option::get(uint::from_str(argv[1])) }; + let yieldevery = if vec::len(argv) < 3_u { 10_u } + else { option::get(uint::from_str(argv[2])) }; + let path = if vec::len(argv) < 4_u { "" } + else { argv[3] }; let writep = comm::port(); let writech = comm::chan(writep); - task::spawn { - || writer(path, writech, size); + task::spawn {|| + writer(path, writech, size); }; let ch = comm::recv(writep); - uint::range(0_u, size) { - |j| task::spawn { - || chanmb(j, size, ch); - }; + uint::range(0_u, size) {|j| + task::spawn {|| chanmb(j, size, ch);}; if j % yieldevery == 0_u { #debug("Y %u", j); task::yield(); diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index c43568c6759b2..ac0f47f520e2c 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -15,7 +15,7 @@ native mod libc { fn main(args: [str]) { let n = if vec::len(args) == 2u { - int::from_str(args[1]) + option::get(int::from_str(args[1])) } else { 100000 }; diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index edf9ed7175446..8105b019de478 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -90,7 +90,8 @@ fn main(argv: [str]) { if opts.stress { stress(2); } else { - let max = uint::parse_buf(str::bytes(argv[1]), 10u) as int; + let max = option::get(uint::parse_buf(str::bytes(argv[1]), + 10u)) as int; let num_trials = 10; diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 44f550968e176..6c475985d49b9 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -43,7 +43,7 @@ fn eval_AtA_times_u(u: [const float], AtAu: [mutable float]) { fn main(args: [str]) { let N = if vec::len(args) == 2u { - uint::from_str(args[1]) + option::get(uint::from_str(args[1])) } else { 1000u }; diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 3e0150fc45c56..539567a28eecb 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -38,11 +38,8 @@ fn roundtrip(id: int, p: comm::port, ch: comm::chan) { } fn main(args: [str]) { - let token = if vec::len(args) < 2u { - 1000 - } else { - int::from_str(args[1]) - }; + let token = if vec::len(args) < 2u { 1000 } + else { option::get(int::from_str(args[1])) }; start(token); } \ No newline at end of file diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 61a083f1f5347..9b02ee0a49fcd 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -35,9 +35,9 @@ fn read_grid(f: io::reader) -> grid_t { while !f.eof() { let comps = str::split_byte(str::trim(f.read_line()), ',' as u8); if vec::len(comps) >= 3u { - let row = uint::from_str(comps[0]) as u8; - let col = uint::from_str(comps[1]) as u8; - g[row][col] = uint::from_str(comps[2]) as u8; + let row = option::get(uint::from_str(comps[0])) as u8; + let col = option::get(uint::from_str(comps[1])) as u8; + g[row][col] = option::get(uint::from_str(comps[2])) as u8; } } ret grid_ctor(g); diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index 98eefbaf06f26..bf74f736a8303 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -47,7 +47,7 @@ fn calc(children: uint, parent_ch: comm::chan) { fn main(args: [str]) { let children = if vec::len(args) == 2u { - uint::from_str(args[1]) + option::get(uint::from_str(args[1])) } else { 100u }; diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs index 3e38ff5ea22fc..de81e0263d5fb 100644 --- a/src/test/bench/task-perf-spawnalot.rs +++ b/src/test/bench/task-perf-spawnalot.rs @@ -1,9 +1,3 @@ -use std; -import vec; -import task; -import uint; -import str; - fn f(&&n: uint) { let i = 0u; while i < n { @@ -18,7 +12,7 @@ fn main(args: [str]) { let n = if vec::len(args) < 2u { 10u - } else { uint::parse_buf(str::bytes(args[1]), 10u) }; + } else { option::get(uint::parse_buf(str::bytes(args[1]), 10u)) }; let i = 0u; while i < n { task::spawn {|| f(n); }; i += 1u; } } diff --git a/src/test/bench/task-perf-vector-party.rs b/src/test/bench/task-perf-vector-party.rs index 000e3670500a4..0b24596da643b 100644 --- a/src/test/bench/task-perf-vector-party.rs +++ b/src/test/bench/task-perf-vector-party.rs @@ -3,12 +3,6 @@ // that synchronization by spawning a number of tasks and then // allocating and freeing vectors. -use std; -import vec; -import uint; -import str; -import task; - fn f(&&n: uint) { uint::range(0u, n) {|i| let v: [u8] = []; @@ -17,9 +11,7 @@ fn f(&&n: uint) { } fn main(args: [str]) { - let n = - if vec::len(args) < 2u { - 100u - } else { uint::parse_buf(str::bytes(args[1]), 10u) }; + let n = if vec::len(args) < 2u { 100u } + else { option::get(uint::from_str(args[1])) }; uint::range(0u, 100u) {|i| task::spawn {|| f(n); };} }