[librsvg/rustification] strtod.rs: Shitty implementation of strtod(); we'll need it to parse things easily
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustification] strtod.rs: Shitty implementation of strtod(); we'll need it to parse things easily
- Date: Thu, 10 Nov 2016 05:00:19 +0000 (UTC)
commit fb723fade7b904c77f7af71ee2ccc3ae35d522d6
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Nov 9 22:58:08 2016 -0600
strtod.rs: Shitty implementation of strtod(); we'll need it to parse things easily
rust/src/lib.rs | 1 +
rust/src/strtod.rs | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 173 insertions(+), 0 deletions(-)
---
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index e9adc6d..76e2e77 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -20,3 +20,4 @@ pub use path_parser::{
mod path_builder;
mod path_parser;
mod marker;
+mod strtod;
diff --git a/rust/src/strtod.rs b/rust/src/strtod.rs
new file mode 100644
index 0000000..bba2636
--- /dev/null
+++ b/rust/src/strtod.rs
@@ -0,0 +1,172 @@
+enum State {
+ Whitespace,
+ IntegralPart,
+ FractionalPart,
+ ExponentSign,
+ Exponent
+}
+
+pub fn strtod (string: &str) -> (f64, &str) {
+ let mut state = State::Whitespace;
+ let mut value: f64 = 0.0;
+ let mut sign: f64 = 1.0;
+ let mut fraction: f64 = 1.0;
+ let mut exponent_sign: f64 = 1.0;
+ let mut exponent: f64 = 0.0;
+ let mut last_pos: usize = 0;
+
+ for (pos, c) in string.chars ().enumerate () {
+ last_pos = pos;
+
+ match state {
+ State::Whitespace => {
+ if c.is_whitespace () {
+ last_pos += 1;
+ continue;
+ } else if c == '+' || c == '-' {
+ if c == '-' {
+ sign = -1.0;
+ }
+
+ last_pos += 1;
+ state = State::IntegralPart;
+ } else if c.is_digit (10) {
+ state = State::IntegralPart;
+ value = (c as i32 - '0' as i32) as f64;
+ last_pos += 1;
+ println! ("sign: value={}", value);
+ } else if c == '.' {
+ last_pos += 1;
+ state = State::FractionalPart;
+ } else {
+ break;
+ }
+ },
+
+ State::IntegralPart => {
+ if c.is_digit (10) {
+ value = value * 10.0 + (c as i32 - '0' as i32) as f64;
+ last_pos += 1;
+ println! ("int: value={}", value);
+ } else if c == '.' {
+ last_pos += 1;
+ state = State::FractionalPart;
+ } else if c == 'e' || c == 'E' {
+ last_pos += 1;
+ state = State::ExponentSign;
+ } else {
+ break;
+ }
+ },
+
+ State::FractionalPart => {
+ if c.is_digit (10) {
+ fraction *= 0.1;
+ value += fraction * (c as i32 - '0' as i32) as f64;
+ println! ("frac: value={}", value);
+ last_pos += 1;
+ } else if c == 'e' || c == 'E' {
+ last_pos += 1;
+ state = State::ExponentSign;
+ } else {
+ break;
+ }
+ },
+
+ State::ExponentSign => {
+ if c == '+' || c == '-' {
+ if c == '-' {
+ exponent_sign = -1.0;
+ }
+
+ last_pos += 1;
+ state = State::Exponent;
+ } else if c.is_digit (10) {
+ last_pos += 1;
+ exponent = (c as i32 - '0' as i32) as f64;
+ } else {
+ break;
+ }
+ },
+
+ State::Exponent => {
+ if c.is_digit (10) {
+ last_pos += 1;
+ exponent = exponent * 10.0 + (c as i32 - '0' as i32) as f64;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ // return tuple with the value and the non-matching slice
+
+ (sign * value * 10.0f64.powf (exponent * exponent_sign),
+ &string[last_pos .. ])
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn handles_empty_string () {
+ let str = "";
+ assert_eq! (strtod (str), (0.0f64, &str[0..]));
+ }
+
+ #[test]
+ fn handles_integer () {
+ let str = "-123foo";
+ assert_eq! (strtod (str), (-123.0f64, &str[4..]));
+
+ let str = "12345";
+ assert_eq! (strtod (str), (12345.0f64, &str[5..]));
+ }
+
+ #[test]
+ fn handles_float () {
+ let str = "-123.25";
+ assert_eq! (strtod (str), (-123.25f64, &str[7..]));
+
+ let str = "123.25bar";
+ assert_eq! (strtod (str), (123.25f64, &str[6..]));
+ }
+
+ #[test]
+ fn handles_dot_numbers () {
+ let str = "-.25foo";
+ assert_eq! (strtod (str), (-0.25f64, &str[4..]));
+
+ let str = ".25";
+ assert_eq! (strtod (str), (0.25f64, &str[3..]));
+ }
+
+ #[test]
+ fn handles_dot () {
+ let str = "-.";
+ assert_eq! (strtod (str), (-0.0, &str[2..]));
+
+ let str = ".bar";
+ assert_eq! (strtod (str), (0.0, &str[1..]));
+ }
+
+ #[test]
+ fn handles_exponent () {
+ let str = "-123.45e2foo";
+ assert_eq! (strtod (str), (-12345.0, &str[9..]));
+
+ let str = "123.45E2";
+ assert_eq! (strtod (str), (12345.0, &str[8..]));
+ }
+
+ #[test]
+ fn handles_negative_exponent () {
+ let str = "-123.25e-2";
+ assert_eq! (strtod (str), (-1.2325, &str[10..]));
+
+ let str = "123.25E-2bar";
+ assert_eq! (strtod (str), (1.2325, &str[9..]));
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]