From 133ae5ff1e14af3bee21e83f9145849a2cdab0fd Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy <mmstickman@gmail.com> Date: Sat, 29 Jul 2017 14:23:41 -0400 Subject: [PATCH] Fix Issue With Ranges --- rustfmt.toml | 2 +- src/parser/shell_expand/ranges.rs | 203 +++++++++++++++--------------- 2 files changed, 99 insertions(+), 106 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index 87ff57d0..247a12e4 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -9,6 +9,6 @@ imports_indent = "Block" reorder_imported_names = true reorder_imports = true reorder_imports_in_group = true -single_line_if_else_max_width = 100 +single_line_if_else_max_width = 80 struct_field_align_threshold = 30 diff --git a/src/parser/shell_expand/ranges.rs b/src/parser/shell_expand/ranges.rs index 5794a420..f102e469 100644 --- a/src/parser/shell_expand/ranges.rs +++ b/src/parser/shell_expand/ranges.rs @@ -1,4 +1,4 @@ -use super::words::{Range, Index}; +use super::words::{Index, Range}; fn stepped_range_numeric(mut start: isize, end: isize, step: isize) -> Option<Vec<String>> { return if step == 0 { @@ -8,82 +8,86 @@ fn stepped_range_numeric(mut start: isize, end: isize, step: isize) -> Option<Ve } else if start > end && step > 0 { None } else { - let mut out = Vec::new(); - let cmp: fn(isize, isize) -> bool = if start < end { - |a: isize, b: isize| -> bool { a < b } - } else { - |a: isize, b: isize| -> bool { a > b } - }; - while cmp(start, end) { - out.push(start.to_string()); - start += step; - } - Some(out) - } + let mut out = Vec::new(); + let cmp: fn(isize, isize) -> bool = if start < end { + |a: isize, b: isize| -> bool { a < b } + } else { + |a: isize, b: isize| -> bool { a > b } + }; + while cmp(start, end) { + out.push(start.to_string()); + start += step; + } + Some(out) + }; } fn stepped_range_chars(mut start: u8, end: u8, step: u8) -> Option<Vec<String>> { - return if step == 0 { + if step == 0 { None } else { - let mut out = Vec::new(); - let cmp: fn(u8, u8) -> bool = if start < end { - |a: u8, b: u8| -> bool { a < b } - } else { - |a: u8, b: u8| -> bool { a > b } - }; - let step_func: fn(u8, u8) -> u8 = if start > end { - |cur: u8, step: u8| -> u8 { cur.wrapping_sub(step) } - } else { - |cur: u8, step: u8| -> u8 { cur.wrapping_add(step) } - }; - while cmp(start, end) { - out.push((start as char).to_string()); - start = step_func(start, step); - } - Some(out) + let mut out = Vec::new(); + let cmp: fn(u8, u8) -> bool = if start < end { + |a: u8, b: u8| -> bool { a < b } + } else { + |a: u8, b: u8| -> bool { a > b } + }; + let step_func: fn(u8, u8) -> u8 = if start > end { + |cur: u8, step: u8| -> u8 { cur.wrapping_sub(step) } + } else { + |cur: u8, step: u8| -> u8 { cur.wrapping_add(step) } + }; + while cmp(start, end) { + out.push((start as char).to_string()); + start = step_func(start, step); + } + Some(out) } } fn numeric_range(start: isize, mut end: isize, step: isize, inclusive: bool) -> Option<Vec<String>> { - return if start < end { - if inclusive { end += if end <= 0 { -1 } else { 1 }; } - stepped_range_numeric(start, end, step) - } else if start > end { - if inclusive { end += if end <= 0 { -1 } else { 1 }; } - stepped_range_numeric(start, end, step) - } else { - Some(vec![start.to_string()]) - } + if start < end { + if inclusive { + end += 1; + } + stepped_range_numeric(start, end, step) + } else if start > end { + if inclusive { + end += if end <= 0 { -1 } else { 1 }; + } + stepped_range_numeric(start, end, step) + } else { + Some(vec![start.to_string()]) + } } #[inline] -fn byte_is_valid_range(b: u8) -> bool { - (b >= b'a' && b <= b'z') || (b >= b'A' && b <= b'Z') -} +fn byte_is_valid_range(b: u8) -> bool { (b >= b'a' && b <= b'z') || (b >= b'A' && b <= b'Z') } use std::u8; fn char_range(start: u8, mut end: u8, step: isize, inclusive: bool) -> Option<Vec<String>> { if !byte_is_valid_range(start) || !byte_is_valid_range(end) { return None; } - + let char_step = match step.checked_abs() { - Some(v) => { - if v > u8::MAX as isize { - return None; - } else { - v as u8 - } + Some(v) => if v > u8::MAX as isize { + return None; + } else { + v as u8 }, None => return None, }; - + if start < end { - if inclusive { end += 1; } + if inclusive { + end += 1; + } return stepped_range_chars(start, end, char_step); } else if start > end { - if inclusive { end -= 1; } + if inclusive { + end -= 1; + } return stepped_range_chars(start, end, char_step); } else { return Some(vec![(start as char).to_string()]); @@ -163,10 +167,10 @@ pub fn parse_range(input: &str) -> Option<Vec<String>> { read += 1; match b { b'.' => { - // this can only be an inclusive range + // this can only be an inclusive range finish!(true, read); - }, - b'0'...b'9' | b'-' | b'a'...b'z' | b'A'...b'Z' => { + } + b'0'...b'9' | b'-' | b'a'...b'z' | b'A'...b'Z' => { // further processing needed to find out if we're reading a step or // the end of an exclusive range. Step until we find another dot or // the iterator ends @@ -190,9 +194,9 @@ pub fn parse_range(input: &str) -> Option<Vec<String>> { } } finish!(dots == 3, read - 1, step); - }, + } // numeric values are OK but no letters anymore - b'0'...b'9' => {}, + b'0'...b'9' => {} // unexpected _ => return None, } @@ -200,13 +204,13 @@ pub fn parse_range(input: &str) -> Option<Vec<String>> { // exhausted the iterator without finding anything new means // exclusive unstepped range finish!(false, start); - }, + } // not a valid byte for ranges _ => return None, } - } - }, - _ => break + } + } + _ => break, } } None @@ -222,16 +226,20 @@ pub fn parse_index_range(input: &str) -> Option<Range> { let mut dots = 1; while let Some((_, byte)) = bytes_iterator.next() { - if byte == b'.' { dots += 1 } else { break } + if byte == b'.' { + dots += 1 + } else { + break; + } } let inclusive = match dots { 2 => false, 3 => true, - _ => break + _ => break, }; - let end = &input[id+dots..]; + let end = &input[id + dots..]; if first.is_empty() { return if end.is_empty() { @@ -239,14 +247,14 @@ pub fn parse_index_range(input: &str) -> Option<Range> { } else { match end.parse::<isize>() { Ok(end) => Some(Range::to(Index::new(end))), - Err(_) => None + Err(_) => None, } - } + }; } else if end.is_empty() { return match first.parse::<isize>() { Ok(start) => Some(Range::from(Index::new(start))), - Err(_) => None - } + Err(_) => None, + }; } if let Ok(start) = first.parse::<isize>() { @@ -258,10 +266,10 @@ pub fn parse_index_range(input: &str) -> Option<Range> { }); } } else { - break + break; } - }, - _ => break + } + _ => break, } } @@ -278,17 +286,14 @@ fn index_ranges() { (Range::inclusive(Index::Forward(0), Index::Backward(0)), "0...-1"), (Range::exclusive(Index::Backward(2), Index::Backward(0)), "-3..-1"), (Range::from(Index::Backward(2)), "-3.."), - (Range::to(Index::Forward(5)), "..5") + (Range::to(Index::Forward(5)), "..5"), ]; - + for (range, string) in valid_cases { assert_eq!(Some(range), parse_index_range(string)); } - let invalid_cases = vec![ - "0..A", - "3-3..42" - ]; + let invalid_cases = vec!["0..A", "3-3..42"]; for range in invalid_cases { assert_eq!(None, parse_index_range(range)) @@ -326,53 +331,31 @@ fn range_expand() { assert_eq!(actual, expected); let actual = parse_range("a...c"); - let expected = Some(vec![ - "a".to_owned(), - "b".to_owned(), - "c".to_owned(), - ]); + let expected = Some(vec!["a".to_owned(), "b".to_owned(), "c".to_owned()]); assert_eq!(actual, expected); let actual = parse_range("c...a"); - let expected = Some(vec![ - "c".to_owned(), - "b".to_owned(), - "a".to_owned() - ]); + let expected = Some(vec!["c".to_owned(), "b".to_owned(), "a".to_owned()]); assert_eq!(actual, expected); let actual = parse_range("A...C"); - let expected = Some(vec![ - "A".to_owned(), - "B".to_owned(), - "C".to_owned(), - ]); + let expected = Some(vec!["A".to_owned(), "B".to_owned(), "C".to_owned()]); assert_eq!(actual, expected); let actual = parse_range("C...A"); - let expected = Some(vec![ - "C".to_owned(), - "B".to_owned(), - "A".to_owned() - ]); + let expected = Some(vec!["C".to_owned(), "B".to_owned(), "A".to_owned()]); assert_eq!(actual, expected); let actual = parse_range("C..A"); - let expected = Some(vec![ - "C".to_owned(), - "B".to_owned(), - ]); + let expected = Some(vec!["C".to_owned(), "B".to_owned()]); assert_eq!(actual, expected); let actual = parse_range("c..a"); - let expected = Some(vec![ - "c".to_owned(), - "b".to_owned(), - ]); + let expected = Some(vec!["c".to_owned(), "b".to_owned()]); assert_eq!(actual, expected); @@ -399,4 +382,14 @@ fn range_expand() { "-2".to_owned(), "-3".to_owned(), ]); + + assert_eq!(actual, expected); + + let actual = parse_range("-3...0"); + let expected = Some(vec!["-3".into(), "-2".into(), "-1".into(), "0".into()]); + assert_eq!(actual, expected); + + let actual = parse_range("-3..0"); + let expected = Some(vec!["-3".into(), "-2".into(), "-1".into()]); + assert_eq!(actual, expected); } -- GitLab