From 8a7af4aacc0d67a9887ca1fd665b1694fd62a8ca Mon Sep 17 00:00:00 2001 From: Rory Dudley Date: Mon, 20 May 2024 11:27:45 -0600 Subject: Allow aliases with the same name as their verb Previously, when trying to add an alias that used the same name as its command, an infinite recursion loop would occur, and the program would panic after the call stack got too deep. For instance, something like: alias grep='grep --color=always' would cause it to panic. This patch adds a new field to the Environment struct called 'cs' (for call stack), which can be used to keep track of how many levels deep into the Poem::read() function we are in. At the moment, it only allows going two levels deep, but since it's just a u8 value, this could be increased in the future. The above example now works correctly, but it does mean that aliases within aliases are not possible, currently. --- src/poem.rs | 72 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'src/poem.rs') diff --git a/src/poem.rs b/src/poem.rs index db57e55..362eaaa 100644 --- a/src/poem.rs +++ b/src/poem.rs @@ -19,7 +19,7 @@ mod tests { #[test] fn it_parses_a_verse_with_no_meter() { - let poem = Poem::read("cargo build --release".to_string(), &Environment::new()); + let poem = Poem::read("cargo build --release".to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); assert_eq!(poem.first().unwrap().verb(), "cargo"); @@ -27,7 +27,7 @@ mod tests { #[test] fn it_parses_a_verse_with_the_couplet_meter() { - let poem = Poem::read("ls -la | lolcat".to_string(), &Environment::new()); + let poem = Poem::read("ls -la | lolcat".to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); assert_eq!(poem.first().unwrap().verb(), "ls"); @@ -36,7 +36,7 @@ mod tests { #[test] fn it_parses_a_verse_with_the_quiet_meter() { - let poem = Poem::read("sleep 20 &".to_string(), &Environment::new()); + let poem = Poem::read("sleep 20 &".to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); assert_eq!(poem.first().unwrap().verb(), "sleep"); @@ -45,7 +45,7 @@ mod tests { #[test] fn it_parses_a_verse_with_the_and_meter() { - let poem = Poem::read("sleep 2 && ls -la".to_string(), &Environment::new()); + let poem = Poem::read("sleep 2 && ls -la".to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); assert_eq!(poem.first().unwrap().verb(), "sleep"); @@ -54,7 +54,7 @@ mod tests { #[test] fn it_parses_a_verse_with_the_continue_meter() { - let poem = Poem::read("sleep 2; ls -la".to_string(), &Environment::new()); + let poem = Poem::read("sleep 2; ls -la".to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); assert_eq!(poem.first().unwrap().verb(), "sleep"); @@ -63,7 +63,7 @@ mod tests { #[test] fn it_parses_a_verse_with_the_read_rune() { - let poem = Poem::read("lolcat < src/main.rs".to_string(), &Environment::new()); + let poem = Poem::read("lolcat < src/main.rs".to_string(), &mut Environment::new()); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); let verse = verses.next().unwrap(); @@ -88,7 +88,7 @@ mod tests { fn it_parses_a_verse_with_the_write_rune() { let poem = Poem::read( "cat src/main.rs > /dev/null".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -114,7 +114,7 @@ mod tests { fn it_parses_a_verse_with_the_write2_rune() { let poem = Poem::read( "cat src/main.rs 2> /dev/null".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -140,7 +140,7 @@ mod tests { fn it_parses_a_verse_with_the_write_all_rune() { let poem = Poem::read( "cat src/main.rs &> /dev/null".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -173,7 +173,7 @@ mod tests { fn it_parses_a_verse_with_the_addendum_rune() { let poem = Poem::read( "cat src/main.rs >> /dev/null".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -199,7 +199,7 @@ mod tests { fn it_parses_a_verse_with_the_addendum2_rune() { let poem = Poem::read( "cat src/main.rs 2>> /dev/null".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -225,7 +225,7 @@ mod tests { fn it_parses_a_verse_with_the_addendum_all_rune() { let poem = Poem::read( "cat src/main.rs &>> /dev/null".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -256,31 +256,31 @@ mod tests { #[test] fn it_throws_a_parse_error_if_no_files_are_specified_for_the_read_rune() { - let poem = Poem::read("lolcat <".to_string(), &Environment::new()); + let poem = Poem::read("lolcat <".to_string(), &mut Environment::new()); assert!(poem.is_err()); - let poem = Poem::read("lolcat <;".to_string(), &Environment::new()); + let poem = Poem::read("lolcat <;".to_string(), &mut Environment::new()); assert!(poem.is_err()); - let poem = Poem::read("lolcat < && ls -la".to_string(), &Environment::new()); + let poem = Poem::read("lolcat < && ls -la".to_string(), &mut Environment::new()); assert!(poem.is_err()); } #[test] fn it_throws_a_parse_error_if_no_files_are_specified_for_the_write_rune() { - let poem = Poem::read("cat src/main.rs >".to_string(), &Environment::new()); + let poem = Poem::read("cat src/main.rs >".to_string(), &mut Environment::new()); assert!(poem.is_err()); - let poem = Poem::read("cat src/main.rs >;".to_string(), &Environment::new()); + let poem = Poem::read("cat src/main.rs >;".to_string(), &mut Environment::new()); assert!(poem.is_err()); - let poem = Poem::read("cat > && ls -la".to_string(), &Environment::new()); + let poem = Poem::read("cat > && ls -la".to_string(), &mut Environment::new()); assert!(poem.is_err()); } #[test] fn it_throws_a_parse_error_if_no_files_are_specified_for_the_addendum_rune() { - let poem = Poem::read("cat src/main.rs >>".to_string(), &Environment::new()); + let poem = Poem::read("cat src/main.rs >>".to_string(), &mut Environment::new()); assert!(poem.is_err()); - let poem = Poem::read("cat src/main.rs >>;".to_string(), &Environment::new()); + let poem = Poem::read("cat src/main.rs >>;".to_string(), &mut Environment::new()); assert!(poem.is_err()); - let poem = Poem::read("cat >> && ls -la".to_string(), &Environment::new()); + let poem = Poem::read("cat >> && ls -la".to_string(), &mut Environment::new()); assert!(poem.is_err()); } @@ -288,7 +288,7 @@ mod tests { fn it_parses_a_complex_verse_with_lots_of_different_meters() { let poem = Poem::read( "ls -la | lolcat && echo hello | lolcat && sleep 2 &".to_string(), - &Environment::new(), + &mut Environment::new(), ); assert!(poem.is_ok()); let mut verses = poem.unwrap().into_iter(); @@ -319,25 +319,25 @@ mod tests { #[test] fn it_parses_the_continue_meter_without_a_stanza() { - let poem = Poem::read(";;;;;;;".to_string(), &Environment::new()); + let poem = Poem::read(";;;;;;;".to_string(), &mut Environment::new()); assert!(poem.is_ok()); } #[test] fn it_errors_if_the_couplet_meter_is_used_without_a_stanza() { - let poem = Poem::read("|".to_string(), &Environment::new()); + let poem = Poem::read("|".to_string(), &mut Environment::new()); assert!(poem.is_err()); } #[test] fn it_errors_if_the_quiet_meter_is_used_without_a_stanza() { - let poem = Poem::read("&".to_string(), &Environment::new()); + let poem = Poem::read("&".to_string(), &mut Environment::new()); assert!(poem.is_err()); } #[test] fn it_errors_if_the_and_meter_is_used_without_a_stanza() { - let poem = Poem::read("&&".to_string(), &Environment::new()); + let poem = Poem::read("&&".to_string(), &mut Environment::new()); assert!(poem.is_err()); } @@ -348,7 +348,7 @@ mod tests { sleep 2 "; - let poem = Poem::read(file.to_string(), &Environment::new()); + let poem = Poem::read(file.to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); @@ -388,7 +388,7 @@ mod tests { wc -l src/**/*.rs | lolcat; ls -la | grep git "; - let poem = Poem::read(file.to_string(), &Environment::new()); + let poem = Poem::read(file.to_string(), &mut Environment::new()); assert!(poem.is_ok()); let poem = poem.unwrap(); @@ -398,36 +398,36 @@ mod tests { #[test] fn it_catches_parser_errors_related_to_invalid_use_of_special_runes() { let poetry = "cat file.txt &&&".to_string(); - assert_eq!(Poem::read(poetry, &Environment::new()).is_err(), true); + assert_eq!(Poem::read(poetry, &mut Environment::new()).is_err(), true); let poetry = "cat file.txt&&|".to_string(); - assert_eq!(Poem::read(poetry, &Environment::new()).is_err(), true); + assert_eq!(Poem::read(poetry, &mut Environment::new()).is_err(), true); let poetry = "cat <".to_string(); - assert_eq!(Poem::read(poetry, &Environment::new()).is_err(), true); + assert_eq!(Poem::read(poetry, &mut Environment::new()).is_err(), true); } #[test] fn it_catches_parser_errors_related_to_strings() { let poetry = "echo 'hello".to_string(); - assert_eq!(Poem::read(poetry, &Environment::new()).is_err(), true); + assert_eq!(Poem::read(poetry, &mut Environment::new()).is_err(), true); let poetry = "echo \"hello".to_string(); - assert_eq!(Poem::read(poetry, &Environment::new()).is_err(), true); + assert_eq!(Poem::read(poetry, &mut Environment::new()).is_err(), true); let poetry = "`true".to_string(); - assert_eq!(Poem::read(poetry, &Environment::new()).is_err(), true); + assert_eq!(Poem::read(poetry, &mut Environment::new()).is_err(), true); } #[test] fn it_interprets_tilda_as_home() { let poetry = "cd ~".to_string(); - let poem = Poem::read(poetry, &Environment::new()).unwrap(); + let poem = Poem::read(poetry, &mut Environment::new()).unwrap(); assert_eq!(poem[0].verb(), "cd"); assert_eq!(poem[0].clause(), Some(vec![env!("HOME").to_string()])); let poetry = "cd ~/Code/dwarvish".to_string(); - let poem = Poem::read(poetry, &Environment::new()).unwrap(); + let poem = Poem::read(poetry, &mut Environment::new()).unwrap(); assert_eq!(poem[0].verb(), "cd"); assert_eq!( poem[0].clause(), -- cgit v1.2.3