mirror of
https://github.com/nushell/nushell.git
synced 2025-01-26 16:18:38 +01:00
Fixing the flag issue (#5447)
* Fixing the flag issue * whoops, forgot the original point of the function * Update deparse.rs * Update deparse.rs * Update deparse.rs * maybe this might work * fmt * quotation marks works now due to a rigorous check for args. * fmt and clippy * kept the original escape_quote_string(), escaped " and \ * removed script.nu * Added appropriate comments.
This commit is contained in:
parent
7ee22603ac
commit
8d8f25b210
@ -1,3 +1,6 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
|
||||||
pub fn escape_quote_string(input: &str) -> String {
|
pub fn escape_quote_string(input: &str) -> String {
|
||||||
let mut output = String::with_capacity(input.len() + 2);
|
let mut output = String::with_capacity(input.len() + 2);
|
||||||
output.push('"');
|
output.push('"');
|
||||||
@ -12,3 +15,95 @@ pub fn escape_quote_string(input: &str) -> String {
|
|||||||
output.push('"');
|
output.push('"');
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn looks_like_flag(input: &str) -> bool {
|
||||||
|
if !input.starts_with('-') {
|
||||||
|
false
|
||||||
|
// it does not start with '-'
|
||||||
|
} else if !input.starts_with("--") {
|
||||||
|
if input.len() > 2
|
||||||
|
&& input.chars().nth(2).expect("this should never trigger") != '='
|
||||||
|
&& input.chars().nth(2).expect("this should never trigger") != ' '
|
||||||
|
{
|
||||||
|
false
|
||||||
|
// while it start with '-', it is not of the form '-x=y' or '-x y'
|
||||||
|
} else {
|
||||||
|
input.len() >= 2
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input.len() > 2
|
||||||
|
// it is either a flag --x or a '--'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn escape_quote_string_when_flags_are_unclear(input: &str) -> String {
|
||||||
|
// internal use only. When reading the file for flags goes wrong, revert back to a manual check
|
||||||
|
// for flags.
|
||||||
|
let mut output = String::new();
|
||||||
|
if !looks_like_flag(input) {
|
||||||
|
output.push('"');
|
||||||
|
for c in input.chars() {
|
||||||
|
if c == '"' || c == '\\' {
|
||||||
|
output.push('\\');
|
||||||
|
}
|
||||||
|
output.push(c);
|
||||||
|
}
|
||||||
|
output.push('"');
|
||||||
|
output
|
||||||
|
} else if input.contains(' ') || input.contains('=') {
|
||||||
|
// this is a flag that requires delicate handling
|
||||||
|
let mut flag_tripped = false;
|
||||||
|
for c in input.chars() {
|
||||||
|
if c == '"' || c == '\\' {
|
||||||
|
output.push('\\');
|
||||||
|
}
|
||||||
|
output.push(c);
|
||||||
|
if (c == ' ' || c == '=') && !flag_tripped {
|
||||||
|
flag_tripped = true;
|
||||||
|
output.push('"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.push('"');
|
||||||
|
output
|
||||||
|
} else {
|
||||||
|
// this is a normal flag, aka "--x"
|
||||||
|
String::from(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn escape_quote_string_with_file(input: &str, file: &str) -> String {
|
||||||
|
// use when you want to cross-compare to a file to ensure flags are checked properly
|
||||||
|
let file = File::open(file);
|
||||||
|
match file {
|
||||||
|
Ok(f) => {
|
||||||
|
let lines = BufReader::new(f).lines();
|
||||||
|
for line in lines {
|
||||||
|
let mut flag_start = false;
|
||||||
|
let mut word = String::new();
|
||||||
|
let line_or = line.unwrap_or_else(|_| String::from(" "));
|
||||||
|
if line_or.contains('-') {
|
||||||
|
for n in line_or.chars() {
|
||||||
|
if n == '-' {
|
||||||
|
flag_start = true;
|
||||||
|
}
|
||||||
|
if n == ' ' || n == ':' || n == ')' {
|
||||||
|
flag_start = false;
|
||||||
|
}
|
||||||
|
if flag_start {
|
||||||
|
word.push(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if word == input {
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut final_word = String::new();
|
||||||
|
final_word.push('"');
|
||||||
|
final_word.push_str(input);
|
||||||
|
final_word.push('"');
|
||||||
|
final_word
|
||||||
|
}
|
||||||
|
_ => escape_quote_string_when_flags_are_unclear(input),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@ mod parse_keywords;
|
|||||||
mod parser;
|
mod parser;
|
||||||
mod type_check;
|
mod type_check;
|
||||||
|
|
||||||
pub use deparse::escape_quote_string;
|
pub use deparse::{escape_quote_string, escape_quote_string_with_file};
|
||||||
pub use errors::ParseError;
|
pub use errors::ParseError;
|
||||||
pub use flatten::{flatten_block, flatten_expression, flatten_pipeline, FlatShape};
|
pub use flatten::{flatten_block, flatten_expression, flatten_pipeline, FlatShape};
|
||||||
pub use known_external::KnownExternal;
|
pub use known_external::KnownExternal;
|
||||||
|
@ -17,7 +17,7 @@ use nu_cli::{
|
|||||||
};
|
};
|
||||||
use nu_command::{create_default_context, BufferedReader};
|
use nu_command::{create_default_context, BufferedReader};
|
||||||
use nu_engine::{get_full_help, CallExt};
|
use nu_engine::{get_full_help, CallExt};
|
||||||
use nu_parser::{escape_quote_string, parse};
|
use nu_parser::{escape_quote_string, escape_quote_string_with_file, parse};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Call, Expr, Expression},
|
ast::{Call, Expr, Expression},
|
||||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
engine::{Command, EngineState, Stack, StateWorkingSet},
|
||||||
@ -82,7 +82,7 @@ fn main() -> Result<()> {
|
|||||||
let mut args = std::env::args().skip(1);
|
let mut args = std::env::args().skip(1);
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
if !script_name.is_empty() {
|
if !script_name.is_empty() {
|
||||||
args_to_script.push(escape_quote_string(&arg));
|
args_to_script.push(escape_quote_string_with_file(&arg, &script_name));
|
||||||
} else if arg.starts_with('-') {
|
} else if arg.starts_with('-') {
|
||||||
// Cool, it's a flag
|
// Cool, it's a flag
|
||||||
let flag_value = match arg.as_ref() {
|
let flag_value = match arg.as_ref() {
|
||||||
|
Loading…
Reference in New Issue
Block a user