2 * Copyright (c) 2020 Tilman Sauerbeck (tilman at code-monkey de)
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 pub struct Shell<'a> {
27 tx_buf: &'a mut Buffer,
28 command_offset: usize,
29 command_buffer: [u8; 32],
33 fn usb_serial_read(c: *mut u8) -> bool;
36 struct ArgumentIter<'a> {
41 impl<'a> Iterator for ArgumentIter<'a> {
44 fn next(&mut self) -> Option<&'a [u8]> {
46 let mut start : Option<usize> = None;
48 // Find the start of the substring.
49 for o in self.offset..self.command.len() {
50 if self.command[o] != delimiter {
56 start.and_then(|start2| {
57 let mut end : Option<usize> = None;
59 // Find the end of the substring.
60 for o in start2..self.command.len() {
61 if self.command[o] == delimiter {
73 Some(&self.command[start2..end3])
79 fn read_char() -> Option<u8> {
83 if usb_serial_read(&mut c) {
92 pub fn new(tx_buf: &mut Buffer) -> Shell {
96 command_buffer: [0; 32],
100 pub fn update(&mut self) {
101 while let Some(c) = read_char() {
103 if self.command_offset != self.command_buffer.len() {
104 self.command_buffer[self.command_offset] = c;
105 self.command_offset += 1;
108 let command_length = self.command_offset;
109 self.command_offset = 0;
111 if command_length != self.command_buffer.len() {
112 self.command_buffer[command_length] = b'\0';
114 if command_length != 0 {
115 self.dispatch(command_length);
118 self.command_buffer[self.command_offset] = b'\0';
120 self.tx_buf.write(b"maximum command length exceeded.\n");
123 self.tx_buf.write(b"$ ");
129 fn dispatch(&mut self, command_length: usize) {
130 let command : [u8; 32] = self.command_buffer;
132 let mut args_iter = ArgumentIter {
133 command: &command[0..command_length],
137 match args_iter.next() {
141 help Show this help message.
144 self.tx_buf.write(usage);
148 self.tx_buf.write(b"unknown_command: ");
149 self.tx_buf.write(other);
150 self.tx_buf.write(b"\n");