From 6c63263c382f345aa1d8c3f629febd46ca297347 Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Fri, 19 Jan 2024 07:33:25 +0000 Subject: [PATCH 1/3] Enhancement: dump commands will print to output if no output variable is defined --- duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs | 6 +++++- duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs | 6 +++++- duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs b/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs index a84115a2..c3ae03cd 100755 --- a/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs +++ b/duckscript_sdk/src/sdk/std/debug/dump_instructions/mod.rs @@ -39,13 +39,17 @@ impl Command for CommandImpl { _arguments: Vec, _state: &mut HashMap, _variables: &mut HashMap, - _output_variable: Option, + output_variable: Option, instructions: &Vec, _commands: &mut Commands, _line: usize, ) -> CommandResult { let string_value = format!("{:#?}", instructions).to_string(); + if output_variable.is_none() { + println!("{}", string_value); + } + CommandResult::Continue(Some(string_value)) } } diff --git a/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs b/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs index 963937b3..57cc534f 100755 --- a/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs +++ b/duckscript_sdk/src/sdk/std/debug/dump_state/mod.rs @@ -39,13 +39,17 @@ impl Command for CommandImpl { _arguments: Vec, state: &mut HashMap, _variables: &mut HashMap, - _output_variable: Option, + output_variable: Option, _instructions: &Vec, _commands: &mut Commands, _line: usize, ) -> CommandResult { let string_value = format!("{:#?}", state).to_string(); + if output_variable.is_none() { + println!("{}", string_value); + } + CommandResult::Continue(Some(string_value)) } } diff --git a/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs b/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs index 515e6ce0..9f64e712 100755 --- a/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs +++ b/duckscript_sdk/src/sdk/std/debug/dump_variables/mod.rs @@ -39,13 +39,17 @@ impl Command for CommandImpl { _arguments: Vec, _state: &mut HashMap, variables: &mut HashMap, - _output_variable: Option, + output_variable: Option, _instructions: &Vec, _commands: &mut Commands, _line: usize, ) -> CommandResult { let string_value = format!("{:#?}", variables).to_string(); + if output_variable.is_none() { + println!("{}", string_value); + } + CommandResult::Continue(Some(string_value)) } } From 48ae088b99fac55a2a8cf92547cccfcda03875da Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Fri, 19 Jan 2024 07:33:48 +0000 Subject: [PATCH 2/3] Fix: if/else condition with a command that accepts empty values --- CHANGELOG.md | 5 + duckscript_sdk/src/sdk/std/mod.rs | 2 +- duckscript_sdk/src/sdk/std/print/mod.rs | 114 +++++++++--------- duckscript_sdk/src/sdk/std/println/mod.rs | 55 ++++++--- .../src/sdk/std/println/mod_test.rs | 21 +++- duckscript_sdk/src/sdk/std/println/script.ds | 13 -- duckscript_sdk/src/utils/eval.rs | 20 ++- duckscript_sdk/src/utils/eval_test.rs | 64 ++++++++++ test/std/flowcontrol/if_else_test.ds | 32 +++++ test/std/println_test.ds | 2 +- 10 files changed, 236 insertions(+), 92 deletions(-) delete mode 100644 duckscript_sdk/src/sdk/std/println/script.ds diff --git a/CHANGELOG.md b/CHANGELOG.md index 37bfaeef..115bad60 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## CHANGELOG +### v0.9.3 + +* Fix: if/else condition with a command that accepts empty values +* Enhancement: dump commands will print to output if no output variable is defined + ### v0.9.2 (2023-11-18) * Enhancement: \[Breaking Change\] add support for renaming directories via mv command #374 diff --git a/duckscript_sdk/src/sdk/std/mod.rs b/duckscript_sdk/src/sdk/std/mod.rs index 4a25119f..dad1d517 100755 --- a/duckscript_sdk/src/sdk/std/mod.rs +++ b/duckscript_sdk/src/sdk/std/mod.rs @@ -42,7 +42,7 @@ pub(crate) fn load(commands: &mut Commands) -> Result<(), ScriptError> { commands.set(noop::create(PACKAGE))?; commands.set(not::create(PACKAGE))?; commands.set(print::create(PACKAGE))?; - commands.set(println::create(PACKAGE)?)?; + commands.set(println::create(PACKAGE))?; commands.set(read::create(PACKAGE))?; commands.set(release::create(PACKAGE))?; diff --git a/duckscript_sdk/src/sdk/std/print/mod.rs b/duckscript_sdk/src/sdk/std/print/mod.rs index 6f91f311..2d691751 100755 --- a/duckscript_sdk/src/sdk/std/print/mod.rs +++ b/duckscript_sdk/src/sdk/std/print/mod.rs @@ -134,6 +134,64 @@ fn add_color( } } +pub(crate) fn run_print(arguments: Vec) -> CommandResult { + // collect options + let mut styles = vec![]; + let mut text_color = None; + let mut background_color = None; + let mut index = 0; + let mut looking_for = LookingFor::Flag; + for argument in &arguments { + index = index + 1; + + match looking_for { + LookingFor::Flag => match argument.as_str() { + "--style" | "-s" => looking_for = LookingFor::Style, + "--color" | "-c" => looking_for = LookingFor::TextColor, + "--background-color" | "-bgc" => looking_for = LookingFor::BackgroundColor, + _ => break, + }, + LookingFor::Style => { + styles.push(argument.to_string()); + looking_for = LookingFor::Flag; + } + LookingFor::TextColor => { + text_color = Some(argument.to_string()); + looking_for = LookingFor::Flag; + } + LookingFor::BackgroundColor => { + background_color = Some(argument.to_string()); + looking_for = LookingFor::Flag; + } + } + } + if index > 0 { + index = index - 1; + } + + // generate whole string + let mut string = String::new(); + let mut count = 0; + for argument in &arguments[index..] { + count = count + 1; + string.push_str(argument); + string.push(' '); + } + if count > 0 { + string.remove(string.len() - 1); + } + + // add colors + let mut styled_string = string.normal(); + styled_string = add_color(styled_string, text_color, false); + styled_string = add_color(styled_string, background_color, true); + styled_string = add_styles(styled_string, styles); + + print!("{}", styled_string); + + CommandResult::Continue(Some(count.to_string())) +} + #[derive(Clone)] pub(crate) struct CommandImpl { package: String, @@ -157,61 +215,7 @@ impl Command for CommandImpl { } fn run(&self, arguments: Vec) -> CommandResult { - // collect options - let mut styles = vec![]; - let mut text_color = None; - let mut background_color = None; - let mut index = 0; - let mut looking_for = LookingFor::Flag; - for argument in &arguments { - index = index + 1; - - match looking_for { - LookingFor::Flag => match argument.as_str() { - "--style" | "-s" => looking_for = LookingFor::Style, - "--color" | "-c" => looking_for = LookingFor::TextColor, - "--background-color" | "-bgc" => looking_for = LookingFor::BackgroundColor, - _ => break, - }, - LookingFor::Style => { - styles.push(argument.to_string()); - looking_for = LookingFor::Flag; - } - LookingFor::TextColor => { - text_color = Some(argument.to_string()); - looking_for = LookingFor::Flag; - } - LookingFor::BackgroundColor => { - background_color = Some(argument.to_string()); - looking_for = LookingFor::Flag; - } - } - } - if index > 0 { - index = index - 1; - } - - // generate whole string - let mut string = String::new(); - let mut count = 0; - for argument in &arguments[index..] { - count = count + 1; - string.push_str(argument); - string.push(' '); - } - if count > 0 { - string.remove(string.len() - 1); - } - - // add colors - let mut styled_string = string.normal(); - styled_string = add_color(styled_string, text_color, false); - styled_string = add_color(styled_string, background_color, true); - styled_string = add_styles(styled_string, styles); - - print!("{}", styled_string); - - CommandResult::Continue(Some(count.to_string())) + run_print(arguments) } } diff --git a/duckscript_sdk/src/sdk/std/println/mod.rs b/duckscript_sdk/src/sdk/std/println/mod.rs index bad05ba6..3800e766 100755 --- a/duckscript_sdk/src/sdk/std/println/mod.rs +++ b/duckscript_sdk/src/sdk/std/println/mod.rs @@ -1,22 +1,47 @@ -use crate::types::command::create_alias_command; +use crate::sdk::std::print::run_print; use crate::utils::pckg; -use duckscript::types::command::Command; -use duckscript::types::error::ScriptError; +use duckscript::types::command::{Command, CommandResult}; #[cfg(test)] #[path = "./mod_test.rs"] mod mod_test; -pub(crate) fn create(package: &str) -> Result, ScriptError> { - let name = pckg::concat(package, "Println"); - let command = create_alias_command( - name, - vec!["println".to_string()], - include_str!("help.md").to_string(), - "println".to_string(), - include_str!("script.ds").to_string(), - 0, - )?; - - Ok(Box::new(command)) +#[derive(Clone)] +pub(crate) struct CommandImpl { + package: String, +} + +impl Command for CommandImpl { + fn name(&self) -> String { + pckg::concat(&self.package, "Println") + } + + fn aliases(&self) -> Vec { + vec!["println".to_string()] + } + + fn help(&self) -> String { + include_str!("help.md").to_string() + } + + fn clone_and_box(&self) -> Box { + Box::new((*self).clone()) + } + + fn run(&self, arguments: Vec) -> CommandResult { + let result = run_print(arguments); + + match result { + CommandResult::Continue(_) => println!(""), + _ => (), + }; + + return result; + } +} + +pub(crate) fn create(package: &str) -> Box { + Box::new(CommandImpl { + package: package.to_string(), + }) } diff --git a/duckscript_sdk/src/sdk/std/println/mod_test.rs b/duckscript_sdk/src/sdk/std/println/mod_test.rs index cbc43674..3c7044af 100644 --- a/duckscript_sdk/src/sdk/std/println/mod_test.rs +++ b/duckscript_sdk/src/sdk/std/println/mod_test.rs @@ -1,7 +1,26 @@ use super::*; use crate::test; +use crate::test::CommandValidation; #[test] fn common_functions() { - test::test_common_command_functions(create("").unwrap()); + test::test_common_command_functions(create("")); +} + +#[test] +fn run_no_args() { + test::run_script_and_validate( + vec![create("")], + "out = println", + CommandValidation::Match("out".to_string(), "0".to_string()), + ); +} + +#[test] +fn run_multiple_args() { + test::run_script_and_validate( + vec![create("")], + "out = println 1 2 \"3 4\"", + CommandValidation::Match("out".to_string(), "3".to_string()), + ); } diff --git a/duckscript_sdk/src/sdk/std/println/script.ds b/duckscript_sdk/src/sdk/std/println/script.ds deleted file mode 100644 index d880c0b4..00000000 --- a/duckscript_sdk/src/sdk/std/println/script.ds +++ /dev/null @@ -1,13 +0,0 @@ - -scope::println::count = set 0 - -if not array_is_empty ${scope::println::arguments} - scope::println::commandline = array_join ${scope::println::arguments} "\" \"" - scope::println::commandline = set "\"${scope::println::commandline}" - scope::println::commandline = substring ${scope::println::commandline} -2 - scope::println::count = print %{scope::println::commandline} -end - -echo - -set ${scope::println::count} diff --git a/duckscript_sdk/src/utils/eval.rs b/duckscript_sdk/src/utils/eval.rs index 9193b2c4..6736c11a 100644 --- a/duckscript_sdk/src/utils/eval.rs +++ b/duckscript_sdk/src/utils/eval.rs @@ -12,12 +12,20 @@ mod eval_test; fn parse(arguments: &Vec) -> Result { let mut line_buffer = String::new(); for argument in arguments { - if argument.contains(" ") { - line_buffer.push('"'); - } - line_buffer.push_str(argument); - if argument.contains(" ") { - line_buffer.push('"'); + if argument.is_empty() { + line_buffer.push_str("\"\""); + } else if argument.starts_with("\"") && argument.ends_with("\"") { + line_buffer.push('\\'); + line_buffer.push_str(argument); + line_buffer.push('\\'); + } else { + if argument.contains(" ") { + line_buffer.push('"'); + } + line_buffer.push_str(argument); + if argument.contains(" ") { + line_buffer.push('"'); + } } line_buffer.push(' '); } diff --git a/duckscript_sdk/src/utils/eval_test.rs b/duckscript_sdk/src/utils/eval_test.rs index 8bc18147..26bdd342 100644 --- a/duckscript_sdk/src/utils/eval_test.rs +++ b/duckscript_sdk/src/utils/eval_test.rs @@ -1,4 +1,5 @@ use super::*; +use crate::sdk::std::string::equals::create as EqCreate; use crate::test::SetCommand; #[test] @@ -143,3 +144,66 @@ fn eval_with_error_parse_error() { _ => panic!("invalid result type."), }; } + +#[test] +fn eval_with_eq_empty_args() { + let mut commands = Commands::new(); + match commands.set(EqCreate("")) { + Err(error) => panic!("{}", error), + _ => (), + }; + + let result = eval_with_error( + &vec!["eq".to_string(), "".to_string(), "".to_string()], + &mut HashMap::new(), + &mut HashMap::new(), + &mut commands, + ); + + match result { + CommandResult::Continue(value) => assert_eq!(value.unwrap(), "true"), + _ => panic!("invalid result type."), + }; +} + +#[test] +fn eval_with_eq_true_args() { + let mut commands = Commands::new(); + match commands.set(EqCreate("")) { + Err(error) => panic!("{}", error), + _ => (), + }; + + let result = eval_with_error( + &vec!["eq".to_string(), "true".to_string(), "true".to_string()], + &mut HashMap::new(), + &mut HashMap::new(), + &mut commands, + ); + + match result { + CommandResult::Continue(value) => assert_eq!(value.unwrap(), "true"), + _ => panic!("invalid result type."), + }; +} + +#[test] +fn eval_with_eq_true_and_false_args() { + let mut commands = Commands::new(); + match commands.set(EqCreate("")) { + Err(error) => panic!("{}", error), + _ => (), + }; + + let result = eval_with_error( + &vec!["eq".to_string(), "true".to_string(), "false".to_string()], + &mut HashMap::new(), + &mut HashMap::new(), + &mut commands, + ); + + match result { + CommandResult::Continue(value) => assert_eq!(value.unwrap(), "false"), + _ => panic!("invalid result type."), + }; +} diff --git a/test/std/flowcontrol/if_else_test.ds b/test/std/flowcontrol/if_else_test.ds index ece779e2..5eba54f9 100644 --- a/test/std/flowcontrol/if_else_test.ds +++ b/test/std/flowcontrol/if_else_test.ds @@ -163,6 +163,38 @@ fn test_if_call_to_functions assert ${valid} end +fn test_eq_empty_strings + valid = set false + + if eq "" "" + valid = set true + end + + assert ${valid} +end + +fn test_eq_different_strings + valid = set true + + if eq "1 2" "1 3" + valid = set false + end + + assert ${valid} +end + +fn test_not_is_array_empty + valid = set false + + array = array 1 2 3 + if not array_is_empty ${array} + valid = set true + end + release ${array} + + assert ${valid} +end + fn _test_return_true return true end diff --git a/test/std/println_test.ds b/test/std/println_test.ds index 0a488371..920b47e9 100644 --- a/test/std/println_test.ds +++ b/test/std/println_test.ds @@ -6,7 +6,7 @@ fn test_no_style end fn test_with_style - count = print -s bold -s underline -s italic -s dimmed -s blink --style strikethrough --color bright_green --background-color red bright_green red + count = println -s bold -s underline -s italic -s dimmed -s blink --style strikethrough --color bright_green --background-color red bright_green red assert_eq ${count} 2 colors = array black red green yellow blue magenta cyan white From fcd261e85b3e76d251ad9a41feff2273b961237e Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Fri, 19 Jan 2024 07:37:44 +0000 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 115bad60..02cc708b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### v0.9.3 -* Fix: if/else condition with a command that accepts empty values +* Fix: if/else condition with a command that accepts empty values #390 * Enhancement: dump commands will print to output if no output variable is defined ### v0.9.2 (2023-11-18)