Brijesh's Git Server — bsh @ 420896e777207fee868cfcaa7801f1d4b44cda46

my own shell program

feat: parser can now detect unfinished quotes, newline, tab and carraige return
Brijesh Wawdhane brijesh@wawdhane.com
Sat, 26 Oct 2024 22:19:50 +0530
commit

420896e777207fee868cfcaa7801f1d4b44cda46

parent

dbeb3fca578539e8c1c26f387d87f95341464c16

2 files changed, 59 insertions(+), 0 deletions(-)

jump to
M src/parser.rssrc/parser.rs

@@ -16,11 +16,26 @@ let mut args = Vec::new();

let mut current_arg = String::new(); let mut in_single_quote = false; let mut in_double_quote = false; + let mut escape_next = false; let chars = input.chars().collect::<Vec<_>>(); for c in chars { + if escape_next { + match c { + 'r' => current_arg.push('\r'), + 'n' => current_arg.push('\n'), + 't' => current_arg.push('\t'), + _ => current_arg.push(c), + } + escape_next = false; + continue; + } + match c { + '\\' => { + escape_next = true; // Escape the next character + } '\'' if !in_double_quote => { in_single_quote = !in_single_quote; // Toggle single quote state }

@@ -42,6 +57,10 @@ _ => {

current_arg.push(c); // Add character to the current argument } } + } + + if in_single_quote || in_double_quote { + return Err("Unclosed quote in input"); } // Finalize the last argument
M src/tests/parser_test.rssrc/tests/parser_test.rs

@@ -24,4 +24,44 @@ let input = "";

let parsed = parser::parse(input); assert!(parsed.is_err(), "Empty input should result in error"); } + + #[test] + fn test_parse_escape_character() { + let input = "echo hello\\ world"; + let parsed = parser::parse(input).expect("Failed to parse command"); + assert_eq!(parsed.command, "echo"); + assert_eq!(parsed.args, vec!["hello world"]); + } + + #[test] + fn test_parse_unclosed_quote() { + let input = "echo \"hello"; + let parsed = parser::parse(input); + assert!(parsed.is_err(), "Unclosed quote should result in error"); + assert_eq!(parsed.unwrap_err(), "Unclosed quote in input"); + } + + #[test] + fn test_parse_carriage_return() { + let input = "echo hello\rworld"; + let parsed = parser::parse(input).expect("Failed to parse command"); + assert_eq!(parsed.command, "echo"); + assert_eq!(parsed.args, vec!["hello\rworld"]); + } + + #[test] + fn test_parse_newline() { + let input = "echo hello\nworld"; + let parsed = parser::parse(input).expect("Failed to parse command"); + assert_eq!(parsed.command, "echo"); + assert_eq!(parsed.args, vec!["hello\nworld"]); + } + + #[test] + fn test_parse_tab() { + let input = "echo hello\tworld"; + let parsed = parser::parse(input).expect("Failed to parse command"); + assert_eq!(parsed.command, "echo"); + assert_eq!(parsed.args, vec!["hello\tworld"]); + } }