execute_command_tokens/
lib.rs1pub fn command_tokens<S: AsRef<str>>(cmd: S) -> Vec<String> {
11 let cmd = cmd.as_ref();
12
13 let mut tokens = Vec::with_capacity(1);
14 let mut string_buffer = String::new();
15
16 let mut append_mode = false;
17 let mut quote_mode = false;
18 let mut quote_mode_ending = false; let mut quote_char = ' ';
20 let mut escaping = false;
21
22 for c in cmd.chars() {
23 if escaping {
24 append_mode = true;
25 escaping = false;
26
27 string_buffer.push(c);
28 } else if c.is_whitespace() {
29 if append_mode {
30 if quote_mode {
31 string_buffer.push(c);
32 } else {
33 append_mode = false;
34
35 tokens.push(string_buffer);
36 string_buffer = String::new();
37 }
38 } else if quote_mode_ending {
39 quote_mode_ending = false;
40
41 tokens.push(string_buffer);
42 string_buffer = String::new();
43 }
44 } else {
45 match c {
46 '"' | '\'' => {
47 if append_mode {
48 if quote_mode {
49 if quote_char == c {
50 append_mode = false;
51 quote_mode = false;
52 quote_mode_ending = true;
53 } else {
54 string_buffer.push(c);
55 }
56 } else {
57 quote_mode = true;
58 quote_char = c;
59 }
60 } else {
61 append_mode = true;
62 quote_mode = true;
63 quote_char = c;
64 }
65 },
66 '\\' => {
67 escaping = true;
68 },
69 _ => {
70 append_mode = true;
71 escaping = false;
72
73 string_buffer.push(c);
74 },
75 }
76 }
77 }
78
79 if append_mode || quote_mode_ending {
80 tokens.push(string_buffer);
81 }
82
83 tokens
84}