|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
use std::str::Chars;
|
|
|
|
|
use std::iter::FromIterator;
|
|
|
|
|
use std::process::exit;
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
@ -11,85 +12,39 @@ mod tests {
|
|
|
|
|
}
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_01() {
|
|
|
|
|
dbg!(parse_args("\"Hello world\'\"", 0x07));
|
|
|
|
|
dbg!(parse_args("Hello world", 0x01));
|
|
|
|
|
}
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_02() {
|
|
|
|
|
dbg!(parse_args("Hello worLd", 0x02));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Parses the command line arguments into a list of parameters.
|
|
|
|
|
/// The following parsing modes can be utilized:
|
|
|
|
|
/// 00: Returns exactly what was inputted.
|
|
|
|
|
/// 01: Returns the contents, split by whitespace indiscriminately.
|
|
|
|
|
/// 02: Returns the contents, split by whitespace indiscriminately and made lowercase.
|
|
|
|
|
pub fn parse_args(input: &str, mode: u8) -> Vec<String> {
|
|
|
|
|
let input: Vec<_> = input.chars().map(|arg| arg.clone()).collect(); // Converts from the input string to a vector of chars.
|
|
|
|
|
dbg!(&input);
|
|
|
|
|
let split_input: Vec<_> = input.chars().map(|arg| arg.clone()).collect(); // Converts from the input string to a vector of chars.
|
|
|
|
|
dbg!(&split_input);
|
|
|
|
|
match mode {
|
|
|
|
|
/// Returns exact input string.
|
|
|
|
|
0x00 => {vec![String::from_iter(input.iter())]}, // Simply converts the vector of chars into a string, and puts it as the first element.
|
|
|
|
|
/// Seperates all strings
|
|
|
|
|
0x07 => {
|
|
|
|
|
// First pass: Quoting
|
|
|
|
|
let mut single_quote_begin: Vec<usize> = vec![]; // List of beginning single quotation marks.
|
|
|
|
|
let mut single_quote_end: Vec<usize> = vec![]; // List of ending single quotation marks.
|
|
|
|
|
let mut is_single_quoted: bool = false; // Boolean showing if the current contents are quoted.
|
|
|
|
|
|
|
|
|
|
let mut double_quote_begin: Vec<usize> = vec![]; // List of beginning double quotation marks.
|
|
|
|
|
let mut double_quote_end: Vec<usize> = vec![]; // List of ending double quotation marks.
|
|
|
|
|
let mut is_double_quoted: bool = false; // boolean showing if the current contents are quoted.
|
|
|
|
|
|
|
|
|
|
let mut parameter_index: usize = 0;
|
|
|
|
|
let mut arguments: Vec<String> = vec![];
|
|
|
|
|
for (i, c) in input.iter().enumerate() {
|
|
|
|
|
let c = *c;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let escaped = if i != 0 {*input.get(i - 1).unwrap() == '\\'} else {false} // Checks if previous character is backslash (and index is not zero
|
|
|
|
|
&& if i > 1 {*input.get(i - 2).unwrap() == '\\'} else {false}; // Checks if 2 characters ago is backslash (and index is greater than 1)
|
|
|
|
|
match c {
|
|
|
|
|
|
|
|
|
|
'\'' => { // Single quoted stuff will always be taken literally, no matter what they contain. See the bash manual§3.1.2.2.
|
|
|
|
|
if !escaped && !is_double_quoted {
|
|
|
|
|
if is_single_quoted {
|
|
|
|
|
single_quote_end.push(i);
|
|
|
|
|
is_single_quoted = false;
|
|
|
|
|
} else {
|
|
|
|
|
single_quote_begin.push(i);
|
|
|
|
|
is_single_quoted = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
arguments.insert(parameter_index, c.to_string());
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'\"' => { // Double quoted stuff works kind of like graves do in JavaScript. See the bash manual§3.1.2.3.
|
|
|
|
|
if !escaped && !is_single_quoted {
|
|
|
|
|
if is_double_quoted {
|
|
|
|
|
double_quote_end.push(i);
|
|
|
|
|
is_double_quoted = false;
|
|
|
|
|
} else {
|
|
|
|
|
double_quote_begin.push(i);
|
|
|
|
|
is_double_quoted = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
arguments.insert(parameter_index, c.to_string());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
' ' => {
|
|
|
|
|
if !escaped || !is_single_quoted || !is_double_quoted {
|
|
|
|
|
parameter_index += 1;
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_ => {
|
|
|
|
|
let __: &String = &String::new();
|
|
|
|
|
let mut arg = arguments.get(parameter_index).unwrap_or(__).to_owned();
|
|
|
|
|
arg.push(c);
|
|
|
|
|
arguments.insert(parameter_index, arg.clone());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
arguments
|
|
|
|
|
},
|
|
|
|
|
///
|
|
|
|
|
0x10 => {
|
|
|
|
|
vec![]
|
|
|
|
|
},
|
|
|
|
|
0x00 => {vec![String::from_iter(split_input.iter())]}, // Simply converts the vector of chars into a string, and puts it as the first element.
|
|
|
|
|
0x01 => {
|
|
|
|
|
return input
|
|
|
|
|
.to_string()
|
|
|
|
|
.split_ascii_whitespace()
|
|
|
|
|
.map(|x| x.to_string())
|
|
|
|
|
.collect();
|
|
|
|
|
}
|
|
|
|
|
0x02 => {
|
|
|
|
|
return input
|
|
|
|
|
.to_string()
|
|
|
|
|
.to_ascii_lowercase()
|
|
|
|
|
.split_ascii_whitespace()
|
|
|
|
|
.map(|x| x.to_string())
|
|
|
|
|
.collect();
|
|
|
|
|
}
|
|
|
|
|
_ => panic!("Unexpected input")
|
|
|
|
|
}
|
|
|
|
|
}
|