├── .clang-format ├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── README.md ├── codecov.yml ├── examples ├── CMakeLists.txt ├── DemoAdvanced │ ├── DemoAdvanced.ino │ ├── node_bin.cpp │ ├── node_dev.cpp │ ├── node_root.cpp │ ├── shell.cpp │ ├── shell.h │ └── shell_cmd.cpp ├── DemoBasic │ └── DemoBasic.ino ├── Initialize │ └── Initialize.ino └── demo_linux │ ├── CMakeLists.txt │ ├── commands.c │ ├── commands.h │ ├── demo.c │ ├── fs │ ├── fs.c │ ├── fs.h │ └── path │ │ ├── bin.c │ │ ├── bin.h │ │ ├── dev.c │ │ ├── dev.h │ │ ├── etc.c │ │ ├── etc.h │ │ ├── root.c │ │ └── root.h │ ├── interface.c │ ├── interface.h │ ├── shell.c │ ├── shell.h │ ├── terminal.c │ └── terminal.h ├── library.properties ├── src ├── CMakeLists.txt ├── config │ ├── arduino │ │ └── ush_config.h │ ├── pico │ │ └── ush_config.h │ ├── posix │ │ └── ush_config.h │ └── ush_config_platform.h ├── inc │ ├── ush.h │ ├── ush_commands.h │ ├── ush_const.h │ ├── ush_file.h │ ├── ush_history.h │ ├── ush_internal.h │ ├── ush_node.h │ ├── ush_preconfig.h │ ├── ush_shell.h │ ├── ush_types.h │ └── ush_utils.h ├── microshell.h └── src │ ├── commands │ ├── ush_cmd.c │ ├── ush_cmd_cat.c │ ├── ush_cmd_cd.c │ ├── ush_cmd_echo.c │ ├── ush_cmd_help.c │ ├── ush_cmd_ls.c │ ├── ush_cmd_pwd.c │ └── ush_cmd_xxd.c │ ├── ush.c │ ├── ush_autocomp.c │ ├── ush_autocomp_state.c │ ├── ush_autocomp_utils.c │ ├── ush_commands.c │ ├── ush_file.c │ ├── ush_history.c │ ├── ush_node.c │ ├── ush_node_mount.c │ ├── ush_node_utils.c │ ├── ush_parse.c │ ├── ush_parse_char.c │ ├── ush_parse_utils.c │ ├── ush_process.c │ ├── ush_prompt.c │ ├── ush_read.c │ ├── ush_read_char.c │ ├── ush_read_utils.c │ ├── ush_reset.c │ ├── ush_utils.c │ ├── ush_write.c │ └── ush_write_utils.c ├── tests ├── CMakeLists.txt ├── func_tests │ ├── CMakeLists.txt │ ├── test_func.c │ ├── test_func.h │ ├── test_func_autocomp.c │ ├── test_func_cmd_cat.c │ ├── test_func_cmd_cd.c │ ├── test_func_cmd_echo.c │ ├── test_func_cmd_help.c │ ├── test_func_cmd_ls.c │ ├── test_func_cmd_pwd.c │ ├── test_func_cmd_xxd.c │ ├── test_func_commands.c │ ├── test_func_exec.c │ ├── test_func_file.c │ ├── test_func_input.c │ ├── test_func_mount.c │ ├── test_func_node.c │ ├── test_func_print.c │ ├── test_func_reset.c │ └── ush_config.h └── unit_tests │ ├── CMakeLists.txt │ ├── test_unit_autocomp.c │ ├── test_unit_autocomp_state.c │ ├── test_unit_autocomp_utils.c │ ├── test_unit_cmd.c │ ├── test_unit_cmd_cat.c │ ├── test_unit_cmd_cd.c │ ├── test_unit_cmd_echo.c │ ├── test_unit_cmd_help.c │ ├── test_unit_cmd_ls.c │ ├── test_unit_cmd_pwd.c │ ├── test_unit_cmd_xxd.c │ ├── test_unit_commands.c │ ├── test_unit_file.c │ ├── test_unit_node.c │ ├── test_unit_node_mount.c │ ├── test_unit_node_utils.c │ ├── test_unit_parse.c │ ├── test_unit_parse_char.c │ ├── test_unit_parse_utils.c │ ├── test_unit_process.c │ ├── test_unit_prompt.c │ ├── test_unit_read.c │ ├── test_unit_read_char.c │ ├── test_unit_read_utils.c │ ├── test_unit_reset.c │ ├── test_unit_ush.c │ ├── test_unit_utils.c │ ├── test_unit_write.c │ ├── test_unit_write_utils.c │ └── ush_config.h └── website ├── app.js ├── index.css ├── index.html ├── microshell.html ├── screen.png ├── social.png └── typer.js /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .vscode/ 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests/Unity"] 2 | path = tests/Unity 3 | url = https://github.com/ThrowTheSwitch/Unity 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | compiler: 4 | - gcc 5 | 6 | before_script: 7 | - pip install gcovr 8 | - mkdir build 9 | - cd build 10 | - cmake .. 11 | 12 | script: 13 | - make 14 | - make test 15 | - make coverage 16 | 17 | after_success: 18 | - bash <(curl -s https://codecov.io/bash) 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.0 ) 2 | 3 | project( ush LANGUAGES C VERSION 0.1.0 ) 4 | 5 | set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) 6 | set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) 7 | set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) 8 | 9 | enable_testing( ) 10 | 11 | set (CMAKE_CXX_FLAGS "-Werror -Wall -Wextra -pedantic -g -O0 --coverage" ) 12 | set (CMAKE_C_FLAGS "-Werror -Wall -Wextra -pedantic -g -O0 --coverage" ) 13 | set (CMAKE_EXE_LINKER_FLAGS "--coverage" ) 14 | 15 | add_subdirectory( ${PROJECT_SOURCE_DIR}/src ) 16 | add_subdirectory( ${PROJECT_SOURCE_DIR}/tests ) 17 | add_subdirectory( ${PROJECT_SOURCE_DIR}/examples ) 18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | RUN apt update && apt install -y shellinabox git cmake gcc 3 | 4 | WORKDIR /demo 5 | RUN git clone --recursive https://github.com/marcinbor85/microshell 6 | 7 | WORKDIR /demo/microshell/build 8 | RUN cmake .. 9 | RUN make && make test 10 | 11 | RUN groupadd -g 999 microshell && useradd -r -u 999 -g microshell microshell 12 | USER microshell 13 | 14 | CMD /usr/bin/shellinaboxd -p 4200 --css /etc/shellinabox/options-available/00_White\ On\ Black.css --no-beep -t -s /:microshell:microshell:/:/demo/microshell/build/bin/demo 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Marcin Borowicz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "**/Unity" 3 | - "**/examples" 4 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/demo_linux ) 2 | -------------------------------------------------------------------------------- /examples/DemoAdvanced/DemoAdvanced.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "shell.h" 26 | 27 | void setup() 28 | { 29 | // initialize needed hardware 30 | pinMode(LED_BUILTIN, OUTPUT); 31 | 32 | // initialize shell 33 | shell_init(); 34 | } 35 | 36 | void loop() 37 | { 38 | // non-blocking shell service 39 | shell_service(); 40 | 41 | // do other non-blocking stuff here 42 | // ... 43 | } 44 | -------------------------------------------------------------------------------- /examples/DemoAdvanced/node_bin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | // toggle file execute callback 29 | static void toggle_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 30 | { 31 | // simple toggle led, without any arguments validation 32 | digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); 33 | } 34 | 35 | // set file execute callback 36 | static void set_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 37 | { 38 | // arguments count validation 39 | if (argc != 2) { 40 | // return predefined error message 41 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 42 | return; 43 | } 44 | 45 | // arguments validation 46 | if (strcmp(argv[1], "1") == 0) { 47 | // turn led on 48 | digitalWrite(LED_BUILTIN, HIGH); 49 | } else if (strcmp(argv[1], "0") == 0) { 50 | // turn led off 51 | digitalWrite(LED_BUILTIN, LOW); 52 | } else { 53 | // return predefined error message 54 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 55 | return; 56 | } 57 | } 58 | 59 | // bin directory files descriptor 60 | static const struct ush_file_descriptor bin_files[] = { 61 | { 62 | .name = "toggle", // toogle file name 63 | .description = "toggle led", // optional file description 64 | .help = "usage: toggle\r\n", // optional help manual 65 | .exec = toggle_exec_callback, // optional execute callback 66 | }, 67 | { 68 | .name = "set", // set file name 69 | .description = "set led", 70 | .help = "usage: set {0,1}\r\n", 71 | .exec = set_exec_callback 72 | }, 73 | }; 74 | 75 | // bin directory handler 76 | static struct ush_node_object bin; 77 | 78 | extern struct ush_object ush; 79 | 80 | void shell_bin_mount(void) 81 | { 82 | // mount bin directory 83 | ush_node_mount(&ush, "/bin", &bin, bin_files, sizeof(bin_files) / sizeof(bin_files[0])); 84 | } 85 | -------------------------------------------------------------------------------- /examples/DemoAdvanced/node_dev.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | // led file get data callback 29 | size_t led_get_data_callback(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t **data) 30 | { 31 | // read current led state 32 | bool state = digitalRead(LED_BUILTIN); 33 | // return pointer to data 34 | *data = (uint8_t*)((state) ? "1\r\n" : "0\r\n"); 35 | // return data size 36 | return strlen((char*)(*data)); 37 | } 38 | 39 | // led file set data callback 40 | void led_set_data_callback(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t *data, size_t size) 41 | { 42 | // data size validation 43 | if (size < 1) 44 | return; 45 | 46 | // arguments validation 47 | if (data[0] == '1') { 48 | // turn led on 49 | digitalWrite(LED_BUILTIN, HIGH); 50 | } else if (data[0] == '0') { 51 | // turn led off 52 | digitalWrite(LED_BUILTIN, LOW); 53 | } 54 | } 55 | 56 | // time file get data callback 57 | size_t time_get_data_callback(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t **data) 58 | { 59 | static char time_buf[16]; 60 | // read current time 61 | long current_time = millis(); 62 | // convert 63 | snprintf(time_buf, sizeof(time_buf), "%ld\r\n", current_time); 64 | time_buf[sizeof(time_buf) - 1] = 0; 65 | // return pointer to data 66 | *data = (uint8_t*)time_buf; 67 | // return data size 68 | return strlen((char*)(*data)); 69 | } 70 | 71 | // dev directory files descriptor 72 | static const struct ush_file_descriptor dev_files[] = { 73 | { 74 | .name = "led", 75 | .description = NULL, 76 | .help = NULL, 77 | .exec = NULL, 78 | .get_data = led_get_data_callback, // optional data getter callback 79 | .set_data = led_set_data_callback, // optional data setter callback 80 | }, 81 | { 82 | .name = "time", 83 | .description = NULL, 84 | .help = NULL, 85 | .exec = NULL, 86 | .get_data = time_get_data_callback, 87 | }, 88 | }; 89 | 90 | // dev directory handler 91 | static struct ush_node_object dev; 92 | 93 | extern struct ush_object ush; 94 | 95 | void shell_dev_mount(void) 96 | { 97 | // mount dev directory 98 | ush_node_mount(&ush, "/dev", &dev, dev_files, sizeof(dev_files) / sizeof(dev_files[0])); 99 | } -------------------------------------------------------------------------------- /examples/DemoAdvanced/node_root.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | // info file get data callback 29 | size_t info_get_data_callback(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t **data) 30 | { 31 | static const char *info = "Use MicroShell and make fun!\r\n"; 32 | 33 | // return pointer to data 34 | *data = (uint8_t*)info; 35 | // return data size 36 | return strlen(info); 37 | } 38 | 39 | // root directory files descriptor 40 | static const struct ush_file_descriptor root_files[] = { 41 | { 42 | .name = "info.txt", // info.txt file name 43 | .description = NULL, 44 | .help = NULL, 45 | .exec = NULL, 46 | .get_data = info_get_data_callback, 47 | } 48 | }; 49 | 50 | // root directory handler 51 | static struct ush_node_object root; 52 | 53 | extern struct ush_object ush; 54 | 55 | void shell_root_mount(void) 56 | { 57 | // mount root directory 58 | ush_node_mount(&ush, "/", &root, root_files, sizeof(root_files) / sizeof(root_files[0])); 59 | } 60 | -------------------------------------------------------------------------------- /examples/DemoAdvanced/shell.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | // non-blocking read interface 29 | static int ush_read(struct ush_object *self, char *ch) 30 | { 31 | // should be implemented as a FIFO 32 | if (Serial.available() > 0) { 33 | *ch = Serial.read(); 34 | return 1; 35 | } 36 | return 0; 37 | } 38 | 39 | // non-blocking write interface 40 | static int ush_write(struct ush_object *self, char ch) 41 | { 42 | // should be implemented as a FIFO 43 | return (Serial.write(ch) == 1); 44 | } 45 | 46 | // I/O interface descriptor 47 | static const struct ush_io_interface ush_iface = { 48 | .read = ush_read, 49 | .write = ush_write, 50 | }; 51 | 52 | // working buffers allocations (size could be customized) 53 | #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_ARCH_STM32) 54 | #define BUF_IN_SIZE 128 55 | #define BUF_OUT_SIZE 128 56 | #define PATH_MAX_SIZE 128 57 | #else 58 | #define BUF_IN_SIZE 32 59 | #define BUF_OUT_SIZE 32 60 | #define PATH_MAX_SIZE 32 61 | #endif 62 | 63 | static char ush_in_buf[BUF_IN_SIZE]; 64 | static char ush_out_buf[BUF_OUT_SIZE]; 65 | 66 | // microshell instance handler 67 | struct ush_object ush; 68 | 69 | // microshell descriptor 70 | static const struct ush_descriptor ush_desc = { 71 | .io = &ush_iface, // I/O interface pointer 72 | .input_buffer = ush_in_buf, // working input buffer 73 | .input_buffer_size = sizeof(ush_in_buf), // working input buffer size 74 | .output_buffer = ush_out_buf, // working output buffer 75 | .output_buffer_size = sizeof(ush_out_buf), // working output buffer size 76 | .path_max_length = PATH_MAX_SIZE, // path maximum length (stack) 77 | .hostname = "arduino", // hostname (in prompt) 78 | }; 79 | 80 | extern void shell_commands_add(void); 81 | extern void shell_root_mount(void); 82 | extern void shell_dev_mount(void); 83 | extern void shell_bin_mount(void); 84 | 85 | void shell_init(void) 86 | { 87 | // initialize I/O interface 88 | Serial.begin(115200UL); 89 | 90 | // initialize microshell instance 91 | ush_init(&ush, &ush_desc); 92 | 93 | // add commands 94 | shell_commands_add(); 95 | 96 | // mount nodes (root must be first) 97 | shell_root_mount(); 98 | shell_dev_mount(); 99 | shell_bin_mount(); 100 | } 101 | 102 | void shell_service(void) 103 | { 104 | ush_service(&ush); 105 | } -------------------------------------------------------------------------------- /examples/DemoAdvanced/shell.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef SHELL_H 26 | #define SHELL_H 27 | 28 | void shell_init(void); 29 | void shell_service(void); 30 | 31 | #endif /* SHELL_H */ 32 | -------------------------------------------------------------------------------- /examples/DemoAdvanced/shell_cmd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | // reboot cmd file execute callback 29 | static void reboot_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 30 | { 31 | #if defined(ARDUINO_ARCH_ESP32) 32 | ESP.restart(); 33 | #elif defined(ARDUINO_ARCH_AVR) 34 | void (*reset)(void) = 0; 35 | reset(); 36 | #else 37 | ush_print(self, "error: reboot not supported..."); 38 | #endif 39 | } 40 | 41 | // cmd files descriptor 42 | static const struct ush_file_descriptor cmd_files[] = { 43 | { 44 | .name = "reboot", 45 | .description = "reboot device", 46 | .help = NULL, 47 | .exec = reboot_exec_callback, 48 | }, 49 | }; 50 | 51 | // cmd commands handler 52 | static struct ush_node_object cmd; 53 | 54 | extern struct ush_object ush; 55 | 56 | void shell_commands_add(void) 57 | { 58 | // add custom commands 59 | ush_commands_add(&ush, &cmd, cmd_files, sizeof(cmd_files) / sizeof(cmd_files[0])); 60 | } 61 | -------------------------------------------------------------------------------- /examples/Initialize/Initialize.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | // non-blocking read interface 28 | static int ush_read(struct ush_object *self, char *ch) 29 | { 30 | // should be implemented as a FIFO 31 | if (Serial.available() > 0) { 32 | *ch = Serial.read(); 33 | return 1; 34 | } 35 | return 0; 36 | } 37 | 38 | // non-blocking write interface 39 | static int ush_write(struct ush_object *self, char ch) 40 | { 41 | // should be implemented as a FIFO 42 | return (Serial.write(ch) == 1); 43 | } 44 | 45 | // I/O interface descriptor 46 | static const struct ush_io_interface ush_iface = { 47 | .read = ush_read, 48 | .write = ush_write, 49 | }; 50 | 51 | // working buffers allocations (size could be customized) 52 | #define BUF_IN_SIZE 32 53 | #define BUF_OUT_SIZE 32 54 | #define PATH_MAX_SIZE 32 55 | 56 | static char ush_in_buf[BUF_IN_SIZE]; 57 | static char ush_out_buf[BUF_OUT_SIZE]; 58 | 59 | // microshell instance handler 60 | static struct ush_object ush; 61 | 62 | // microshell descriptor 63 | static const struct ush_descriptor ush_desc = { 64 | .io = &ush_iface, // I/O interface pointer 65 | .input_buffer = ush_in_buf, // working input buffer 66 | .input_buffer_size = sizeof(ush_in_buf), // working input buffer size 67 | .output_buffer = ush_out_buf, // working output buffer 68 | .output_buffer_size = sizeof(ush_out_buf), // working output buffer size 69 | .path_max_length = PATH_MAX_SIZE, // path maximum length (stack) 70 | .hostname = "arduino", // hostname (in prompt) 71 | }; 72 | 73 | // root directory handler 74 | static struct ush_node_object root; 75 | 76 | void setup() 77 | { 78 | // initialize I/O interface 79 | Serial.begin(115200UL); 80 | 81 | // initialize microshell instance 82 | ush_init(&ush, &ush_desc); 83 | 84 | // mount root directory (root must be first) 85 | ush_node_mount(&ush, "/", &root, NULL, 0); 86 | 87 | // mount other directories here 88 | // ... 89 | } 90 | 91 | void loop() 92 | { 93 | // non-blocking microshell service 94 | ush_service(&ush); 95 | 96 | // do other non-blocking stuff here 97 | // ... 98 | } 99 | -------------------------------------------------------------------------------- /examples/demo_linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set( EXAMPLE_DEMO_TARGET demo ) 3 | 4 | set ( USH_TARGET ush_demo ) 5 | build_ush ( ${USH_TARGET} 6 | ${CMAKE_CURRENT_SOURCE_DIR} 7 | ) 8 | target_compile_definitions( 9 | ${USH_TARGET} 10 | PUBLIC 11 | USH_CONFIG_PLATFORM_POSIX 12 | ) 13 | 14 | add_executable( 15 | ${EXAMPLE_DEMO_TARGET} 16 | ${CMAKE_CURRENT_SOURCE_DIR}/demo.c 17 | ${CMAKE_CURRENT_SOURCE_DIR}/interface.c 18 | ${CMAKE_CURRENT_SOURCE_DIR}/commands.c 19 | ${CMAKE_CURRENT_SOURCE_DIR}/terminal.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/shell.c 21 | ${CMAKE_CURRENT_SOURCE_DIR}/fs/fs.c 22 | ${CMAKE_CURRENT_SOURCE_DIR}/fs/path/root.c 23 | ${CMAKE_CURRENT_SOURCE_DIR}/fs/path/etc.c 24 | ${CMAKE_CURRENT_SOURCE_DIR}/fs/path/dev.c 25 | ${CMAKE_CURRENT_SOURCE_DIR}/fs/path/bin.c 26 | ) 27 | target_link_libraries( ${EXAMPLE_DEMO_TARGET} PUBLIC ${USH_TARGET}) 28 | target_compile_options( ${EXAMPLE_DEMO_TARGET} PRIVATE -Werror -Wall -Wextra -g -O0) 29 | -------------------------------------------------------------------------------- /examples/demo_linux/commands.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "commands.h" 26 | 27 | #include 28 | 29 | static void reset_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 30 | { 31 | (void)file; 32 | (void)argc; 33 | (void)argv; 34 | 35 | ush_reset(self); 36 | } 37 | 38 | static const struct ush_file_descriptor cmd_files[] = { 39 | { 40 | .name = "reset", 41 | .description = "reset shell", 42 | .exec = reset_exec_callback, 43 | } 44 | }; 45 | 46 | static struct ush_node_object cmd; 47 | 48 | void commands_register(struct ush_object *ush) 49 | { 50 | ush_commands_add(ush, &cmd, cmd_files, sizeof(cmd_files) / sizeof(cmd_files[0])); 51 | } 52 | -------------------------------------------------------------------------------- /examples/demo_linux/commands.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef COMMANDS_H 26 | #define COMMANDS_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void commands_register(struct ush_object *ush); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* COMMANDS_H */ 41 | -------------------------------------------------------------------------------- /examples/demo_linux/demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include "interface.h" 29 | #include "commands.h" 30 | #include "shell.h" 31 | 32 | int main(int argc, char *argv[]) 33 | { 34 | (void)argc; 35 | (void)argv; 36 | 37 | if (argc == 1) { 38 | interface_open(NULL); 39 | } else if (argc == 2) { 40 | interface_open(argv[1]); 41 | } else { 42 | fprintf(stderr, "wrong arguments\n"); 43 | exit(EXIT_FAILURE); 44 | } 45 | 46 | shell_init(); 47 | 48 | while (1) { 49 | shell_service(); 50 | } 51 | 52 | interface_close(); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "fs.h" 26 | 27 | #include "path/bin.h" 28 | #include "path/dev.h" 29 | #include "path/etc.h" 30 | #include "path/root.h" 31 | 32 | void fs_mount(struct ush_object *ush) 33 | { 34 | root_mount(ush); 35 | etc_mount(ush); 36 | dev_mount(ush); 37 | bin_mount(ush); 38 | } 39 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef FS_H 26 | #define FS_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void fs_mount(struct ush_object *ush); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* FS_H */ 41 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/bin.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "bin.h" 26 | 27 | #include 28 | 29 | static time_t start_time; 30 | 31 | static void print_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 32 | { 33 | (void)self; 34 | (void)file; 35 | 36 | if (argc != 2) { 37 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 38 | return; 39 | } 40 | 41 | ush_print(self, argv[1]); 42 | } 43 | 44 | static void uptime_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 45 | { 46 | (void)self; 47 | (void)file; 48 | (void)argv; 49 | 50 | if (argc != 1) { 51 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 52 | return; 53 | } 54 | 55 | ush_printf(self, "time: %lus\r\n", time(NULL) - start_time); 56 | } 57 | 58 | static const struct ush_file_descriptor g_bin_desc[] = { 59 | { 60 | .name = "uptime", 61 | .help = "usage: uptime\r\n show system uptime\r\n", 62 | .exec = uptime_exec_callback, 63 | }, 64 | { 65 | .name = "print", 66 | .help = "usage: print \r\n print argument to shell\r\n", 67 | .exec = print_exec_callback, 68 | } 69 | }; 70 | 71 | 72 | static struct ush_node_object g_bin; 73 | 74 | void bin_mount(struct ush_object *ush) 75 | { 76 | start_time = time(NULL); 77 | 78 | ush_node_mount(ush, "/bin", &g_bin, g_bin_desc, sizeof(g_bin_desc) / sizeof(g_bin_desc[0])); 79 | } 80 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/bin.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef BIN_H 26 | #define BIN_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void bin_mount(struct ush_object *ush); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* BIN_H */ 41 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/dev.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef DEV_H 26 | #define DEV_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void dev_mount(struct ush_object *ush); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* DEV_H */ 41 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/etc.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "etc.h" 26 | #include "shell.h" 27 | 28 | #include 29 | 30 | static const char *g_config_data = 31 | "# system configuration\r\n" 32 | "freq = 16MHz\r\n" 33 | "ram = 4kB\r\n"; 34 | 35 | static size_t g_config_data_getter(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t **data) 36 | { 37 | (void)self; 38 | (void)file; 39 | 40 | *data = (uint8_t*)g_config_data; 41 | return strlen(g_config_data); 42 | } 43 | 44 | static size_t g_hostname_data_getter(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t **data) 45 | { 46 | (void)self; 47 | (void)file; 48 | 49 | *data = (uint8_t*)shell_get_hostname(); 50 | return strlen((char*)*data); 51 | } 52 | 53 | static void g_hostname_data_setter(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t *data, size_t size) 54 | { 55 | (void)self; 56 | (void)file; 57 | (void)size; 58 | 59 | shell_set_hostname((char*)data); 60 | } 61 | 62 | static const struct ush_file_descriptor g_etc_desc[] = { 63 | { 64 | .name = "config", 65 | .description = "system configuration", 66 | .get_data = g_config_data_getter, 67 | }, 68 | { 69 | .name = "hostname", 70 | .description = "shell hostname", 71 | .get_data = g_hostname_data_getter, 72 | .set_data = g_hostname_data_setter, 73 | }, 74 | }; 75 | 76 | static struct ush_node_object g_etc; 77 | 78 | void etc_mount(struct ush_object *ush) 79 | { 80 | ush_node_mount(ush, "/etc", &g_etc, g_etc_desc, sizeof(g_etc_desc) / sizeof(g_etc_desc[0])); 81 | } 82 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/etc.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef ETC_H 26 | #define ETC_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void etc_mount(struct ush_object *ush); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* ETC_H */ 41 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/root.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "root.h" 26 | #include "shell.h" 27 | 28 | #include 29 | 30 | static const char *g_readme_data = 31 | "Welcome to MicroShell DEMO implementation!\r\n" 32 | "You will see how most common features work.\r\n" 33 | "Enjoy!\r\n"; 34 | 35 | static size_t readme_data_getter(struct ush_object *self, struct ush_file_descriptor const *file, uint8_t **data) 36 | { 37 | (void)self; 38 | (void)file; 39 | 40 | *data = (uint8_t*)g_readme_data; 41 | return strlen(g_readme_data); 42 | } 43 | 44 | static const struct ush_file_descriptor g_root_desc[] = { 45 | { 46 | .name = "readme.txt", 47 | .get_data = readme_data_getter, 48 | } 49 | }; 50 | 51 | static struct ush_node_object g_root; 52 | 53 | void root_mount(struct ush_object *ush) 54 | { 55 | ush_node_mount(ush, "/", &g_root, g_root_desc, sizeof(g_root_desc) / sizeof(g_root_desc[0])); 56 | } 57 | -------------------------------------------------------------------------------- /examples/demo_linux/fs/path/root.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef ROOT_H 26 | #define ROOT_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void root_mount(struct ush_object *ush); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* ROOT_H */ 41 | -------------------------------------------------------------------------------- /examples/demo_linux/interface.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "interface.h" 26 | #include "terminal.h" 27 | 28 | #include 29 | 30 | static FILE *g_io_read; 31 | static FILE *g_io_write; 32 | static const char *g_io_filename; 33 | 34 | static int write_char(struct ush_object *self, char ch) 35 | { 36 | (void)self; 37 | 38 | char c = fputc(ch, g_io_write); 39 | if (c != ch) 40 | return 0; 41 | return 1; 42 | } 43 | 44 | static int read_char(struct ush_object *self, char *ch) 45 | { 46 | (void)self; 47 | 48 | *ch = fgetc(g_io_read); 49 | return 1; 50 | } 51 | 52 | const struct ush_io_interface g_ush_io_interface = { 53 | .read = read_char, 54 | .write = write_char, 55 | }; 56 | 57 | void interface_open(const char *filename) 58 | { 59 | g_io_filename = filename; 60 | 61 | if (filename == NULL) { 62 | g_io_read = stdin; 63 | g_io_write = stdout; 64 | terminal_set_input_mode(); 65 | } else { 66 | g_io_read = fopen(filename, "a+"); 67 | if (g_io_read == NULL) { 68 | fprintf(stderr, "cannot open device\n"); 69 | exit(EXIT_FAILURE); 70 | } 71 | g_io_write = g_io_read; 72 | } 73 | } 74 | 75 | void interface_close(void) 76 | { 77 | if (g_io_filename != NULL) { 78 | fclose(g_io_read); 79 | fclose(g_io_write); 80 | } 81 | terminal_reset_input_mode(); 82 | } 83 | -------------------------------------------------------------------------------- /examples/demo_linux/interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef INTERFACE_H 26 | #define INTERFACE_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | extern const struct ush_io_interface g_ush_io_interface; 35 | 36 | void interface_open(const char *filename); 37 | void interface_close(void); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif /* INTERFACE_H */ 44 | -------------------------------------------------------------------------------- /examples/demo_linux/shell.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "shell.h" 26 | 27 | #include 28 | 29 | #include 30 | 31 | #include "interface.h" 32 | #include "commands.h" 33 | #include "fs/fs.h" 34 | 35 | #define SHELL_HISTORY_LINES 6 /* Must be at least >= 2 */ 36 | #define SHELL_WORK_BUFFER_SIZE 256 37 | #define SHELL_HOSTNAME_SIZE 16 38 | 39 | static char g_hostname_data[SHELL_HOSTNAME_SIZE + 1]; 40 | 41 | static char g_history_buf[SHELL_HISTORY_LINES * SHELL_WORK_BUFFER_SIZE]; 42 | static ush_history g_history = { 43 | .lines = SHELL_HISTORY_LINES, 44 | .length = SHELL_WORK_BUFFER_SIZE, 45 | .buffer = g_history_buf, 46 | }; 47 | 48 | static char g_input_buffer[SHELL_WORK_BUFFER_SIZE]; 49 | static char g_output_buffer[SHELL_WORK_BUFFER_SIZE]; 50 | 51 | static const struct ush_descriptor g_ush_desc = { 52 | .io = &g_ush_io_interface, 53 | .input_history = &g_history, 54 | .input_buffer = g_input_buffer, 55 | .input_buffer_size = sizeof(g_input_buffer), 56 | .output_buffer = g_output_buffer, 57 | .output_buffer_size = sizeof(g_output_buffer), 58 | .path_max_length = SHELL_WORK_BUFFER_SIZE, 59 | .hostname = g_hostname_data, 60 | }; 61 | 62 | static struct ush_object g_ush; 63 | 64 | void shell_init(void) 65 | { 66 | strcpy(g_hostname_data, "host"); 67 | 68 | ush_init(&g_ush, &g_ush_desc); 69 | 70 | commands_register(&g_ush); 71 | fs_mount(&g_ush); 72 | } 73 | 74 | char* shell_get_hostname(void) 75 | { 76 | return g_hostname_data; 77 | } 78 | 79 | void shell_set_hostname(const char *hostname) 80 | { 81 | strncpy(g_hostname_data, hostname, sizeof(g_hostname_data)); 82 | g_hostname_data[sizeof(g_hostname_data) - 1] = 0; 83 | } 84 | 85 | bool shell_service(void) 86 | { 87 | return ush_service(&g_ush); 88 | } 89 | -------------------------------------------------------------------------------- /examples/demo_linux/shell.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef SHELL_H 26 | #define SHELL_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | 34 | void shell_init(void); 35 | bool shell_service(void); 36 | 37 | char* shell_get_hostname(void); 38 | void shell_set_hostname(const char *hostname); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* SHELL_H */ 45 | -------------------------------------------------------------------------------- /examples/demo_linux/terminal.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | struct termios g_saved_attributes; 32 | 33 | void terminal_reset_input_mode(void) 34 | { 35 | tcsetattr(STDIN_FILENO, TCSANOW, &g_saved_attributes); 36 | } 37 | 38 | void terminal_set_input_mode(void) 39 | { 40 | struct termios tattr; 41 | 42 | if (!isatty(STDIN_FILENO)) { 43 | fprintf(stderr, "not a terminal\n"); 44 | exit(EXIT_FAILURE); 45 | } 46 | 47 | tcgetattr(STDIN_FILENO, &g_saved_attributes); 48 | atexit(terminal_reset_input_mode); 49 | 50 | tcgetattr(STDIN_FILENO, &tattr); 51 | tattr.c_lflag &= ~(ICANON|ECHO); 52 | tattr.c_cc[VMIN] = 1; 53 | tattr.c_cc[VTIME] = 0; 54 | tcsetattr(STDIN_FILENO, TCSAFLUSH, &tattr); 55 | } 56 | -------------------------------------------------------------------------------- /examples/demo_linux/terminal.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef TERMINAL_H 26 | #define TERMINAL_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | void terminal_reset_input_mode(void); 33 | void terminal_set_input_mode(void); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* TERMINAL_H */ 40 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=MicroShell 2 | version=0.1.0 3 | author=Marcin Borowicz 4 | maintainer=Marcin Borowicz 5 | sentence=Shell implementation, compatible with VT100 terminal 6 | paragraph=Supports virtual files, auto-completation, mounting paths, and more... 7 | category=Communication 8 | url=https://github.com/marcinbor85/microshell 9 | includes=microshell.h 10 | architectures=* 11 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( 2 | GLOB 3 | SRC_FILES 4 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush.c 5 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_read.c 6 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_read_utils.c 7 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_read_char.c 8 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_parse.c 9 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_parse_char.c 10 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_parse_utils.c 11 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_write.c 12 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_write_utils.c 13 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_prompt.c 14 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_reset.c 15 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_file.c 16 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_history.c 17 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_node.c 18 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_node_utils.c 19 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_node_mount.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_utils.c 21 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_commands.c 22 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_process.c 23 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_autocomp.c 24 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_autocomp_utils.c 25 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ush_autocomp_state.c 26 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd.c 27 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_cd.c 28 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_help.c 29 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_ls.c 30 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_pwd.c 31 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_cat.c 32 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_xxd.c 33 | ${CMAKE_CURRENT_SOURCE_DIR}/src/commands/ush_cmd_echo.c 34 | ) 35 | 36 | set( 37 | USH_SRC_FILES 38 | ${SRC_FILES} 39 | PARENT_SCOPE 40 | ) 41 | 42 | set( 43 | USH_INC_DIRS 44 | ${CMAKE_CURRENT_SOURCE_DIR} 45 | PARENT_SCOPE 46 | ) 47 | 48 | set( 49 | USH_SRC_DIR 50 | ${CMAKE_CURRENT_SOURCE_DIR} 51 | PARENT_SCOPE 52 | ) 53 | 54 | function( build_ush TARGET ) 55 | add_library( 56 | ${TARGET} 57 | STATIC 58 | ${USH_SRC_FILES} 59 | ) 60 | 61 | target_include_directories( 62 | ${TARGET} 63 | PUBLIC 64 | ${ARGV} 65 | ${USH_INC_DIRS} 66 | ) 67 | 68 | target_compile_options( 69 | ${TARGET} 70 | PRIVATE 71 | -Werror -Wall -Wextra -g -O0 72 | ) 73 | endfunction() 74 | -------------------------------------------------------------------------------- /src/config/arduino/ush_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_CONFIG_H 26 | #define USH_CONFIG_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #define USH_CONFIG_FILENAME_ALIGN_SPACE 16 33 | #define USH_CONFIG_CMD_XXD_COLUMNS 8 34 | 35 | #define USH_CONFIG_ENABLE_COMMAND_CAT 1 36 | #define USH_CONFIG_ENABLE_COMMAND_CD 1 37 | #define USH_CONFIG_ENABLE_COMMAND_ECHO 1 38 | #define USH_CONFIG_ENABLE_COMMAND_HELP 1 39 | #define USH_CONFIG_ENABLE_COMMAND_LS 1 40 | #define USH_CONFIG_ENABLE_COMMAND_PWD 1 41 | #define USH_CONFIG_ENABLE_COMMAND_XXD 1 42 | 43 | #define USH_CONFIG_ENABLE_FEATURE_COMMANDS 1 44 | #define USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE 1 45 | #define USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES 1 46 | #define USH_CONFIG_ENABLE_FEATURE_VERSION_PRINT 1 47 | 48 | #define USH_CONFIG_TRANSLATION_OK "ok" 49 | #define USH_CONFIG_TRANSLATION_ERROR "error" 50 | #define USH_CONFIG_TRANSLATION_DIRECTORY_NOT_FOUND "directory not found" 51 | #define USH_CONFIG_TRANSLATION_NESTED_DIRECTORIES_EXIST "nested directories exist" 52 | #define USH_CONFIG_TRANSLATION_CANNOT_FIND_PARENT_NODE "cannot find parent node" 53 | #define USH_CONFIG_TRANSLATION_DIRECTORY_ALREADY_MOUNTED "directory already mounted" 54 | #define USH_CONFIG_TRANSLATION_SYNTAX_ERROR "syntax error" 55 | #define USH_CONFIG_TRANSLATION_WRONG_ARGUMENTS "wrong arguments" 56 | #define USH_CONFIG_TRANSLATION_FILE_NOT_EXECUTABLE "file not executable" 57 | #define USH_CONFIG_TRANSLATION_FILE_NOT_WRITABLE "file not writable" 58 | #define USH_CONFIG_TRANSLATION_FILE_NOT_READABLE "file not readable" 59 | #define USH_CONFIG_TRANSLATION_NO_HELP_AVAILABLE "no help available" 60 | #define USH_CONFIG_TRANSLATION_FILE_NOT_FOUND "file not found" 61 | #define USH_CONFIG_TRANSLATION_READ_ONLY_FILE "read only file" 62 | 63 | #define USH_ASSERT(cond) { } 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif /* USH_CONFIG_H */ 70 | -------------------------------------------------------------------------------- /src/config/pico/ush_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // this file was originally copied from config/arduino/ush_config.h 26 | // for use with Raspberry Pi Pico (RP2040). Because this file is currently 27 | // identical, this is a naming convention only for the build #define 28 | 29 | #ifndef USH_CONFIG_H 30 | #define USH_CONFIG_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #define USH_CONFIG_FILENAME_ALIGN_SPACE 16 37 | #define USH_CONFIG_CMD_XXD_COLUMNS 8 38 | 39 | #define USH_CONFIG_ENABLE_COMMAND_CAT 1 40 | #define USH_CONFIG_ENABLE_COMMAND_CD 1 41 | #define USH_CONFIG_ENABLE_COMMAND_ECHO 1 42 | #define USH_CONFIG_ENABLE_COMMAND_HELP 1 43 | #define USH_CONFIG_ENABLE_COMMAND_LS 1 44 | #define USH_CONFIG_ENABLE_COMMAND_PWD 1 45 | #define USH_CONFIG_ENABLE_COMMAND_XXD 1 46 | 47 | #define USH_CONFIG_ENABLE_FEATURE_COMMANDS 1 48 | #define USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE 1 49 | #define USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES 1 50 | #define USH_CONFIG_ENABLE_FEATURE_VERSION_PRINT 1 51 | 52 | #define USH_CONFIG_TRANSLATION_OK "ok" 53 | #define USH_CONFIG_TRANSLATION_ERROR "error" 54 | #define USH_CONFIG_TRANSLATION_DIRECTORY_NOT_FOUND "directory not found" 55 | #define USH_CONFIG_TRANSLATION_NESTED_DIRECTORIES_EXIST "nested directories exist" 56 | #define USH_CONFIG_TRANSLATION_CANNOT_FIND_PARENT_NODE "cannot find parent node" 57 | #define USH_CONFIG_TRANSLATION_DIRECTORY_ALREADY_MOUNTED "directory already mounted" 58 | #define USH_CONFIG_TRANSLATION_SYNTAX_ERROR "syntax error" 59 | #define USH_CONFIG_TRANSLATION_WRONG_ARGUMENTS "wrong arguments" 60 | #define USH_CONFIG_TRANSLATION_FILE_NOT_EXECUTABLE "file not executable" 61 | #define USH_CONFIG_TRANSLATION_FILE_NOT_WRITABLE "file not writable" 62 | #define USH_CONFIG_TRANSLATION_FILE_NOT_READABLE "file not readable" 63 | #define USH_CONFIG_TRANSLATION_NO_HELP_AVAILABLE "no help available" 64 | #define USH_CONFIG_TRANSLATION_FILE_NOT_FOUND "file not found" 65 | #define USH_CONFIG_TRANSLATION_READ_ONLY_FILE "read only file" 66 | 67 | #define USH_ASSERT(cond) { } 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* USH_CONFIG_H */ 74 | -------------------------------------------------------------------------------- /src/config/posix/ush_config.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | MIT License 4 | 5 | Copyright (c) 2021 Marcin Borowicz 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #ifndef USH_CONFIG_H 27 | #define USH_CONFIG_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #define USH_CONFIG_FILENAME_ALIGN_SPACE 16 37 | #define USH_CONFIG_CMD_XXD_COLUMNS 8 38 | 39 | #define USH_CONFIG_ENABLE_COMMAND_CAT 1 40 | #define USH_CONFIG_ENABLE_COMMAND_CD 1 41 | #define USH_CONFIG_ENABLE_COMMAND_ECHO 1 42 | #define USH_CONFIG_ENABLE_COMMAND_HELP 1 43 | #define USH_CONFIG_ENABLE_COMMAND_LS 1 44 | #define USH_CONFIG_ENABLE_COMMAND_PWD 1 45 | #define USH_CONFIG_ENABLE_COMMAND_XXD 1 46 | 47 | #define USH_CONFIG_ENABLE_FEATURE_COMMANDS 1 48 | #define USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE 1 49 | #define USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES 1 50 | #define USH_CONFIG_ENABLE_FEATURE_VERSION_PRINT 1 51 | 52 | #define USH_CONFIG_TRANSLATION_OK "ok" 53 | #define USH_CONFIG_TRANSLATION_ERROR "error" 54 | #define USH_CONFIG_TRANSLATION_DIRECTORY_NOT_FOUND "directory not found" 55 | #define USH_CONFIG_TRANSLATION_NESTED_DIRECTORIES_EXIST "nested directories exist" 56 | #define USH_CONFIG_TRANSLATION_CANNOT_FIND_PARENT_NODE "cannot find parent node" 57 | #define USH_CONFIG_TRANSLATION_DIRECTORY_ALREADY_MOUNTED "directory already mounted" 58 | #define USH_CONFIG_TRANSLATION_SYNTAX_ERROR "syntax error" 59 | #define USH_CONFIG_TRANSLATION_WRONG_ARGUMENTS "wrong arguments" 60 | #define USH_CONFIG_TRANSLATION_FILE_NOT_EXECUTABLE "file not executable" 61 | #define USH_CONFIG_TRANSLATION_FILE_NOT_WRITABLE "file not writable" 62 | #define USH_CONFIG_TRANSLATION_FILE_NOT_READABLE "file not readable" 63 | #define USH_CONFIG_TRANSLATION_NO_HELP_AVAILABLE "no help available" 64 | #define USH_CONFIG_TRANSLATION_FILE_NOT_FOUND "file not found" 65 | #define USH_CONFIG_TRANSLATION_READ_ONLY_FILE "read only file" 66 | 67 | #define USH_ASSERT(cond) { if (!(cond)) { fprintf(stderr, "ASSERT: %s:%d\n", __FILE__, __LINE__); exit(-1); } } 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* USH_CONFIG_H */ 74 | -------------------------------------------------------------------------------- /src/config/ush_config_platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_CONFIG_PLATFORM_H 26 | #define USH_CONFIG_PLATFORM_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #if defined(ARDUINO) 33 | #include "config/arduino/ush_config.h" 34 | #elif defined(PICO) 35 | #include "config/pico/ush_config.h" 36 | #elif defined(USH_CONFIG_PLATFORM_POSIX) 37 | #include "config/posix/ush_config.h" 38 | #else 39 | #include "ush_config.h" 40 | #endif 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif /* USH_CONFIG_PLATFORM_H */ 47 | -------------------------------------------------------------------------------- /src/inc/ush.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_H 26 | #define USH_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "ush_types.h" 33 | #include "ush_const.h" 34 | #include "ush_preconfig.h" 35 | #include "ush_shell.h" 36 | 37 | #include "ush_file.h" 38 | #include "ush_node.h" 39 | #include "ush_utils.h" 40 | #include "ush_commands.h" 41 | 42 | /** 43 | * @brief Shell initialization. 44 | * 45 | * Main function to initialize shell instance. 46 | * Should be called once before mounting user-specified nodes. 47 | * Could be deinitialized later with ush_deinit function. 48 | * It doesn't check descriptor callback or any other arguments runtime. 49 | * Only assert could be invoked in case of errors. 50 | * 51 | * @param self - pointer to master ush object 52 | * @param desc - pointer to master ush descriptor 53 | */ 54 | void ush_init(struct ush_object *self, const struct ush_descriptor *desc); 55 | 56 | /** 57 | * @brief Shell deinitialization. 58 | * 59 | * Function to deinitialize shell instance. 60 | * It clears all variables and recursive deinitialize mounted nodes. 61 | * 62 | * @param self - pointer to master ush object 63 | */ 64 | void ush_deinit(struct ush_object *self); 65 | 66 | /** 67 | * @brief Shell service function. 68 | * 69 | * Function to handle all internal states and processing logic. 70 | * All callbacks and interface operations are called from it context. 71 | * In case of asynchronous non-blocking environment it should be called periodically. 72 | * In case of synchronous blocking environment, it should be called in loop until return false. 73 | * 74 | * @param self - pointer to master ush object 75 | * 76 | * @return true - in case of "busy, processing ongoing", false - "nothing to do, read input interface" 77 | */ 78 | bool ush_service(struct ush_object *self); 79 | 80 | /** 81 | * @brief Shell reset function. 82 | * 83 | * Function to software reset shell. 84 | * After reset, shell starts with welcome message. 85 | * Current working path will be set to root. 86 | * 87 | * @param self - pointer to master ush object 88 | */ 89 | void ush_reset(struct ush_object *self); 90 | 91 | /** 92 | * @brief Print status message. 93 | * 94 | * Function to print status message to output shell interface. 95 | * 96 | * @param self - pointer to master ush object 97 | * @param status - status to print 98 | */ 99 | void ush_print_status(struct ush_object *self, ush_status_t status); 100 | 101 | /** 102 | * @brief Print custom message without newline. 103 | * 104 | * Function to print custom message without newline to output shell interface. 105 | * 106 | * @param self - pointer to master ush object 107 | * @param buf - pointer to text message to print 108 | */ 109 | void ush_print_no_newline(struct ush_object *self, char *buf); 110 | 111 | /** 112 | * @brief Print custom message. 113 | * 114 | * Function to print custom message to output shell interface. 115 | * 116 | * @param self - pointer to master ush object 117 | * @param buf - pointer to text message to print 118 | */ 119 | void ush_print(struct ush_object *self, char *buf); 120 | 121 | /** 122 | * @brief Print formatted custom message. 123 | * 124 | * Function to print formatted custom message to output shell interface. 125 | * 126 | * @param self - pointer to master ush object 127 | * @param format - pointer to printf format string 128 | */ 129 | void ush_printf(struct ush_object *self, const char *format, ...); 130 | 131 | /** 132 | * @brief Flush output buffer. 133 | * 134 | * Function to print output buffer content to shell output interface. 135 | * 136 | * @param self - pointer to master ush object 137 | */ 138 | void ush_flush(struct ush_object *self); 139 | 140 | #ifdef __cplusplus 141 | } 142 | #endif 143 | 144 | #endif /* USH_H */ 145 | -------------------------------------------------------------------------------- /src/inc/ush_commands.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_COMMANDS_H 26 | #define USH_COMMANDS_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "ush_types.h" 33 | 34 | /** Buildin global commands files array. */ 35 | extern const struct ush_file_descriptor g_ush_buildin_commands[]; 36 | /** Buildin global commands files array size. */ 37 | extern const size_t g_ush_buildin_commands_num; 38 | 39 | /** 40 | * @brief Add global commands. 41 | * 42 | * Function is used to add commands to shell global namespaces. 43 | * Commands are grouped by ush node object so every C module could have its own set of commands. 44 | * 45 | * @param self - pointer to master ush object 46 | * @param node - pointer to added ush node object supervisor of commands file array 47 | * @param file_list - pointer to added commands files array 48 | * @param file_list_size - added commands files array size 49 | * 50 | * @return ush_status_t - USH_STATUS_OK when successfull, otherwise error 51 | */ 52 | ush_status_t ush_commands_add(struct ush_object *self, struct ush_node_object *node, const struct ush_file_descriptor *file_list, size_t file_list_size); 53 | 54 | /** 55 | * @brief Remove global commands. 56 | * 57 | * Function is used to remove commands from shell global namespaces. 58 | * Commands are removed by group, registered to single ush node object. 59 | * 60 | * @param self - pointer to master ush object 61 | * @param node - pointer to removed ush node object supervisor of commands file array 62 | * 63 | * @return USH_STATUS_OK when successfull, otherwise error 64 | */ 65 | ush_status_t ush_commands_remove(struct ush_object *self, struct ush_node_object *node); 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | 71 | #endif /* USH_COMMANDS_H */ 72 | -------------------------------------------------------------------------------- /src/inc/ush_const.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_CONST_H 26 | #define USH_CONST_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /** Library name used in welcome message. */ 33 | #define USH_NAME "microshell" 34 | /** Library version used to identification purposes. */ 35 | #define USH_VERSION "0.1.1 (mcknly/microshell)" 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* USH_CONST_H */ 42 | -------------------------------------------------------------------------------- /src/inc/ush_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_FILE_H 26 | #define USH_FILE_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "ush_types.h" 33 | 34 | /** 35 | * @brief Search file by name. 36 | * 37 | * Function searches file with given name relative to the current working path. 38 | * First it is looks for file in commands global namespaces. 39 | * Next it is looks for file in current working path. 40 | * Name could be absolute or relative. 41 | * 42 | * @param self - pointer to master ush object 43 | * @param name - pointer to file name to search 44 | * 45 | * @return pointer to ush file descriptor when successfull, otherwise NULL 46 | */ 47 | struct ush_file_descriptor const* ush_file_find_by_name(struct ush_object *self, const char *name); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* USH_FILE_H */ 54 | -------------------------------------------------------------------------------- /src/inc/ush_history.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_HISTORY_H 26 | #define USH_HISTORY_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "inc/ush_internal.h" 33 | 34 | /* Calculates character index in the history buffer */ 35 | #define HLINE_IDX(line) ((line) * self->desc->input_history->length) 36 | 37 | void ush_history_reset(struct ush_object *self); 38 | int ush_history_read_char(struct ush_object *self, char *ch); 39 | 40 | void ush_history_load_line(struct ush_object *self, size_t hline_idx); 41 | void ush_history_save_line(struct ush_object *self, size_t hline_idx, bool new_history_line); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif /* USH_HISTORY_H */ 48 | -------------------------------------------------------------------------------- /src/inc/ush_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_INTERNAL_H 26 | #define USH_INTERNAL_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "ush_types.h" 33 | 34 | /* All functions declared in this file is dedicated to internal use only. */ 35 | /* They are exported for unit testing purposes only. */ 36 | 37 | void ush_read_start(struct ush_object *self); 38 | bool ush_read_char(struct ush_object *self); 39 | bool ush_read_char_buffer(struct ush_object *self); 40 | void ush_read_echo_service(struct ush_object *self, char ch); 41 | bool ush_read_char_by_escape_state(struct ush_object *self, char ch); 42 | bool ush_read_service(struct ush_object *self, bool *read); 43 | 44 | void ush_parse_start(struct ush_object *self); 45 | void ush_parse_char(struct ush_object *self); 46 | void ush_parse_char_standard(struct ush_object *self, char ch); 47 | void ush_parse_finish(struct ush_object *self); 48 | bool ush_parse_service(struct ush_object *self); 49 | int ush_parse_get_args(struct ush_object *self, char* *argv); 50 | 51 | void ush_write_pointer(struct ush_object *self, char *text, ush_state_t write_next_state); 52 | void ush_write_pointer_bin(struct ush_object *self, uint8_t *data, size_t data_size, ush_state_t write_next_state); 53 | void ush_write_char(struct ush_object *self); 54 | bool ush_write_service(struct ush_object *self); 55 | 56 | void ush_reset_start(struct ush_object *self); 57 | bool ush_reset_service(struct ush_object *self); 58 | 59 | void ush_prompt_start(struct ush_object *self, ush_state_t prepare_next_state); 60 | bool ush_prompt_service(struct ush_object *self); 61 | 62 | void ush_process_start(struct ush_object *self, const struct ush_file_descriptor *file); 63 | bool ush_process_service(struct ush_object *self); 64 | 65 | #if USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE == 1 66 | 67 | void ush_autocomp_start(struct ush_object *self); 68 | bool ush_autocomp_service(struct ush_object *self); 69 | void ush_autocomp_prepare_candidates(struct ush_object *self); 70 | void ush_autocomp_optimize_continue(struct ush_object *self); 71 | void ush_autocomp_check_for_finish(struct ush_object *self); 72 | bool ush_autocomp_check_for_next(struct ush_object *self); 73 | void ush_autocomp_process_file_index(struct ush_object *self, const struct ush_file_descriptor *file); 74 | bool ush_autocomp_process_file_prepare(struct ush_object *self, struct ush_file_descriptor const **file); 75 | void ush_autocomp_state_prepare(struct ush_object *self); 76 | void ush_autocomp_state_candidates_start(struct ush_object *self); 77 | void ush_autocomp_state_candidates_process(struct ush_object *self); 78 | void ush_autocomp_state_candidates_finish(struct ush_object *self); 79 | void ush_autocomp_state_recall_suffix(struct ush_object *self); 80 | 81 | #endif /* USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE */ 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif /* USH_INTERNAL_H */ 88 | -------------------------------------------------------------------------------- /src/inc/ush_preconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_PRECONFIG_H 26 | #define USH_PRECONFIG_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #if !defined(USH_CONFIG_CUSTOM_FILE) 33 | #include "config/ush_config_platform.h" 34 | #else 35 | #include USH_CONFIG_CUSTOM_FILE 36 | #endif 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* USH_PRECONFIG_H */ 43 | -------------------------------------------------------------------------------- /src/inc/ush_shell.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_SHELL_H 26 | #define USH_SHELL_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "ush_preconfig.h" 33 | 34 | /* Useful VT100 terminal escape sequences. */ 35 | 36 | #if USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES == 1 37 | 38 | #define USH_SHELL_FONT_STYLE_RESET "\x1B[0m" 39 | #define USH_SHELL_FONT_STYLE_BOLD "\x1B[1m" 40 | #define USH_SHELL_FONT_STYLE_DISABLED "\x1B[2m" 41 | #define USH_SHELL_FONT_STYLE_ITALIC "\x1B[3m" 42 | #define USH_SHELL_FONT_STYLE_UNDERSCORE "\x1B[4m" 43 | 44 | #define USH_SHELL_FONT_COLOR_RED "\x1B[31m" 45 | #define USH_SHELL_FONT_COLOR_GREEN "\x1B[32m" 46 | #define USH_SHELL_FONT_COLOR_YELLOW "\x1B[33m" 47 | #define USH_SHELL_FONT_COLOR_BLUE "\x1B[34m" 48 | #define USH_SHELL_FONT_COLOR_MAGENTA "\x1B[35m" 49 | #define USH_SHELL_FONT_COLOR_CYAN "\x1B[36m" 50 | #define USH_SHELL_FONT_COLOR_WHITE "\x1B[37m" 51 | 52 | #define USH_SHELL_CLEAR_SCREEN "\x1B[2J" 53 | #define USH_SHELL_CLEAR_LINE "\x1B[2K" 54 | #define USH_SHELL_HOME "\x1B[H" 55 | 56 | #else 57 | 58 | #define USH_SHELL_FONT_STYLE_RESET 59 | #define USH_SHELL_FONT_STYLE_BOLD 60 | #define USH_SHELL_FONT_STYLE_DISABLED 61 | #define USH_SHELL_FONT_STYLE_ITALIC 62 | #define USH_SHELL_FONT_STYLE_UNDERSCORE 63 | 64 | #define USH_SHELL_FONT_COLOR_RED 65 | #define USH_SHELL_FONT_COLOR_GREEN 66 | #define USH_SHELL_FONT_COLOR_YELLOW 67 | #define USH_SHELL_FONT_COLOR_BLUE 68 | #define USH_SHELL_FONT_COLOR_MAGENTA 69 | #define USH_SHELL_FONT_COLOR_CYAN 70 | #define USH_SHELL_FONT_COLOR_WHITE 71 | 72 | #define USH_SHELL_CLEAR_SCREEN 73 | #define USH_SHELL_CLEAR_LINE 74 | #define USH_SHELL_HOME 75 | 76 | #endif /* USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES */ 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif /* USH_SHELL_H */ 83 | -------------------------------------------------------------------------------- /src/microshell.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef MICROSHELL_H 26 | #define MICROSHELL_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "inc/ush.h" 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* MICROSHELL_H */ 39 | -------------------------------------------------------------------------------- /src/src/commands/ush_cmd_cat.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush.h" 26 | #include "inc/ush_internal.h" 27 | 28 | #if USH_CONFIG_ENABLE_FEATURE_COMMANDS == 1 29 | 30 | #if USH_CONFIG_ENABLE_COMMAND_CAT == 1 31 | 32 | void ush_buildin_cmd_cat_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 33 | { 34 | (void)file; 35 | 36 | if (argc < 2) { 37 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 38 | return; 39 | } 40 | 41 | for (int i = 1; i < argc; i++) { 42 | struct ush_file_descriptor const *f = ush_file_find_by_name(self, argv[i]); 43 | if (f == NULL) { 44 | ush_print_status(self, USH_STATUS_ERROR_FILE_NOT_FOUND); 45 | return; 46 | } 47 | if (f->get_data == NULL) { 48 | ush_print_status(self, USH_STATUS_ERROR_FILE_NOT_READABLE); 49 | return; 50 | } 51 | } 52 | 53 | ush_process_start(self, file); 54 | } 55 | 56 | bool ush_buildin_cmd_cat_service(struct ush_object *self, struct ush_file_descriptor const *file) 57 | { 58 | (void)file; 59 | 60 | USH_ASSERT(self != NULL); 61 | USH_ASSERT(file != NULL); 62 | 63 | bool processed = true; 64 | 65 | switch (self->state) { 66 | 67 | case USH_STATE_PROCESS_START: 68 | self->process_index_item = 1; 69 | self->state = USH_STATE_PROCESS_SERVICE; 70 | break; 71 | 72 | case USH_STATE_PROCESS_SERVICE: { 73 | if (self->process_index_item >= self->args_count) { 74 | self->state = USH_STATE_PROCESS_FINISH; 75 | break; 76 | } 77 | 78 | char *argv[self->args_count]; 79 | ush_parse_get_args(self, argv); 80 | 81 | struct ush_file_descriptor const *f = ush_file_find_by_name(self, argv[self->process_index_item]); 82 | 83 | uint8_t *data; 84 | size_t data_size = f->get_data(self, f, &data); 85 | 86 | ush_write_pointer_bin(self, data, data_size, self->state); 87 | self->process_index_item++; 88 | break; 89 | } 90 | 91 | case USH_STATE_PROCESS_FINISH: 92 | self->state = USH_STATE_RESET_PROMPT; 93 | break; 94 | 95 | default: 96 | processed = false; 97 | break; 98 | } 99 | 100 | return processed; 101 | } 102 | 103 | #endif /* USH_CONFIG_ENABLE_COMMAND_CAT */ 104 | 105 | #endif /* USH_CONFIG_ENABLE_FEATURE_COMMANDS */ 106 | -------------------------------------------------------------------------------- /src/src/commands/ush_cmd_cd.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush.h" 26 | 27 | #if USH_CONFIG_ENABLE_FEATURE_COMMANDS == 1 28 | 29 | #if USH_CONFIG_ENABLE_COMMAND_CD == 1 30 | 31 | void ush_buildin_cmd_cd_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 32 | { 33 | (void)file; 34 | 35 | if (argc != 2) { 36 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 37 | return; 38 | } 39 | 40 | ush_status_t status = ush_node_set_current_dir(self, argv[1]); 41 | if (status != USH_STATUS_OK) { 42 | ush_print_status(self, status); 43 | return; 44 | } 45 | } 46 | 47 | #endif /* USH_CONFIG_ENABLE_COMMAND_CD */ 48 | 49 | #endif /* USH_CONFIG_ENABLE_FEATURE_COMMANDS */ 50 | -------------------------------------------------------------------------------- /src/src/commands/ush_cmd_echo.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush.h" 26 | #include "inc/ush_internal.h" 27 | #include "inc/ush_utils.h" 28 | 29 | #include 30 | 31 | #if USH_CONFIG_ENABLE_FEATURE_COMMANDS == 1 32 | 33 | #if USH_CONFIG_ENABLE_COMMAND_ECHO == 1 34 | 35 | void ush_buildin_cmd_echo_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 36 | { 37 | (void)argv; 38 | (void)file; 39 | 40 | struct ush_file_descriptor const *f = NULL; 41 | uint8_t *data = NULL; 42 | size_t data_size = 0; 43 | 44 | switch (argc) { 45 | 46 | case 4: 47 | if (strcmp(argv[2], ">") != 0) { 48 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 49 | break; 50 | } 51 | f = ush_file_find_by_name(self, argv[3]); 52 | if (f == NULL) { 53 | ush_print_status(self, USH_STATUS_ERROR_FILE_NOT_FOUND); 54 | break; 55 | } 56 | if (f->set_data == NULL) { 57 | ush_print_status(self, USH_STATUS_ERROR_FILE_NOT_WRITABLE); 58 | break; 59 | } 60 | /* fallthrough */ 61 | case 2: { 62 | char *data_in = argv[1]; 63 | size_t max_size = strlen(data_in); 64 | data_size = ush_utils_decode_ascii(data_in, (uint8_t*)data_in, max_size); 65 | data = (uint8_t*)data_in; 66 | } 67 | /* fallthrough */ 68 | case 1: 69 | if (f != NULL) { 70 | f->set_data(self, f, data, data_size); 71 | } else { 72 | if (data != NULL) { 73 | ush_print(self, (char*)data); 74 | } else { 75 | self->state = USH_STATE_RESET; 76 | } 77 | } 78 | break; 79 | default: 80 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 81 | break; 82 | } 83 | } 84 | 85 | #endif /* USH_CONFIG_ENABLE_COMMAND_ECHO */ 86 | 87 | #endif /* USH_CONFIG_ENABLE_FEATURE_COMMANDS */ 88 | -------------------------------------------------------------------------------- /src/src/commands/ush_cmd_pwd.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush.h" 26 | 27 | #if USH_CONFIG_ENABLE_FEATURE_COMMANDS == 1 28 | 29 | #if USH_CONFIG_ENABLE_COMMAND_PWD == 1 30 | 31 | void ush_buildin_cmd_pwd_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 32 | { 33 | (void)argv; 34 | (void)file; 35 | 36 | if (argc != 1) { 37 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS); 38 | return; 39 | } 40 | 41 | ush_print(self, (char*)self->current_node->path); 42 | } 43 | 44 | #endif /* USH_CONFIG_ENABLE_COMMAND_PWD */ 45 | 46 | #endif /* USH_CONFIG_ENABLE_FEATURE_COMMANDS */ 47 | -------------------------------------------------------------------------------- /src/src/ush_autocomp.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_preconfig.h" 27 | #include "inc/ush_utils.h" 28 | #include "inc/ush_node.h" 29 | 30 | #include 31 | 32 | #if USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE == 1 33 | 34 | bool ush_autocomp_service(struct ush_object *self) 35 | { 36 | USH_ASSERT(self != NULL); 37 | 38 | bool processed = true; 39 | 40 | switch (self->state) { 41 | 42 | case USH_STATE_AUTOCOMP_PREPARE: 43 | ush_autocomp_state_prepare(self); 44 | break; 45 | 46 | case USH_STATE_AUTOCOMP_CANDIDATES_START: 47 | ush_autocomp_state_candidates_start(self); 48 | break; 49 | 50 | case USH_STATE_AUTOCOMP_CANDIDATES_COUNT: 51 | case USH_STATE_AUTOCOMP_CANDIDATES_OPTIMISE: 52 | case USH_STATE_AUTOCOMP_CANDIDATES_PRINT: { 53 | ush_autocomp_state_candidates_process(self); 54 | break; 55 | } 56 | 57 | case USH_STATE_AUTOCOMP_CANDIDATES_FINISH: 58 | ush_autocomp_state_candidates_finish(self); 59 | break; 60 | 61 | case USH_STATE_AUTOCOMP_PROMPT_PREPARE: 62 | ush_write_pointer(self, "\r\n", USH_STATE_AUTOCOMP_PROMPT); 63 | break; 64 | 65 | case USH_STATE_AUTOCOMP_PROMPT: 66 | ush_prompt_start(self, USH_STATE_AUTOCOMP_RECALL); 67 | break; 68 | 69 | case USH_STATE_AUTOCOMP_RECALL: 70 | ush_write_pointer(self, self->desc->input_buffer, USH_STATE_READ_CHAR); 71 | break; 72 | 73 | case USH_STATE_AUTOCOMP_RECALL_SUFFIX: { 74 | ush_autocomp_state_recall_suffix(self); 75 | break; 76 | } 77 | 78 | default: 79 | processed = false; 80 | break; 81 | 82 | } 83 | 84 | return processed; 85 | } 86 | 87 | #endif /* USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE */ 88 | -------------------------------------------------------------------------------- /src/src/ush_commands.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_commands.h" 26 | #include "inc/ush_types.h" 27 | #include "inc/ush_preconfig.h" 28 | 29 | ush_status_t ush_commands_add(struct ush_object *self, struct ush_node_object *node, const struct ush_file_descriptor *file_list, size_t file_list_size) 30 | { 31 | USH_ASSERT(self != NULL); 32 | USH_ASSERT(node != NULL); 33 | USH_ASSERT(file_list != NULL); 34 | USH_ASSERT(file_list_size > 0); 35 | 36 | for (size_t i = 0; i < file_list_size; i++) { 37 | USH_ASSERT(file_list[i].name != NULL); 38 | } 39 | 40 | node->file_list = file_list; 41 | node->file_list_size = file_list_size; 42 | node->path = NULL; 43 | 44 | node->next = self->commands; 45 | self->commands = node; 46 | 47 | return USH_STATUS_OK; 48 | } 49 | 50 | ush_status_t ush_commands_remove(struct ush_object *self, struct ush_node_object *node) 51 | { 52 | USH_ASSERT(self != NULL); 53 | USH_ASSERT(node != NULL); 54 | 55 | struct ush_node_object *prev = NULL; 56 | struct ush_node_object *curr = self->commands; 57 | 58 | while (curr != NULL) { 59 | if (curr != node) { 60 | prev = curr; 61 | curr = curr->next; 62 | continue; 63 | } 64 | if (prev == NULL) { 65 | self->commands = node->next; 66 | } else { 67 | prev->next = node->next; 68 | } 69 | return USH_STATUS_OK; 70 | } 71 | 72 | return USH_STATUS_ERROR_NODE_NOT_FOUND; 73 | } 74 | -------------------------------------------------------------------------------- /src/src/ush_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_file.h" 26 | #include "inc/ush_utils.h" 27 | #include "inc/ush_node.h" 28 | 29 | #include 30 | 31 | struct ush_file_descriptor const* ush_file_find_by_name(struct ush_object *self, const char *name) 32 | { 33 | char file_path[self->desc->path_max_length]; 34 | char abs_path[self->desc->path_max_length]; 35 | 36 | struct ush_node_object *curr; 37 | struct ush_file_descriptor const *file; 38 | 39 | curr = self->commands; 40 | while (curr != NULL) { 41 | for (size_t i = 0; i < curr->file_list_size; i++) { 42 | file = &curr->file_list[i]; 43 | if (strcmp(file->name, name) == 0) 44 | return file; 45 | } 46 | curr = curr->next; 47 | } 48 | 49 | ush_node_get_absolute_path(self, name, abs_path); 50 | curr = ush_node_get_parent_by_path(self, abs_path); 51 | while (curr != NULL) { 52 | for (size_t i = 0; i < curr->file_list_size; i++) { 53 | file = &curr->file_list[i]; 54 | ush_utils_join_path(curr->path, file->name, file_path); 55 | if (strcmp(file_path, abs_path) == 0) 56 | return file; 57 | } 58 | curr = curr->next; 59 | } 60 | 61 | return NULL; 62 | } 63 | -------------------------------------------------------------------------------- /src/src/ush_history.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_history.h" 26 | #include "inc/ush_internal.h" 27 | #include "inc/ush_preconfig.h" 28 | 29 | #include 30 | #include 31 | 32 | void ush_history_reset(struct ush_object *self) 33 | { 34 | /* Reset all history variables in ush_object */ 35 | self->history_buf = 0; 36 | self->history_index = 0; 37 | self->history_backspace = 0; 38 | self->history_pos = 0; 39 | 40 | /* Reset history buffer area */ 41 | memset(&self->desc->input_history->buffer[HLINE_IDX(0)], 0x00, 42 | self->desc->input_history->lines * self->desc->input_history->length); 43 | } 44 | 45 | int ush_history_read_char(struct ush_object *self, char *ch) 46 | { 47 | int ret = 0; 48 | 49 | /* Start by returning backspace characters for current line */ 50 | if (self->history_backspace > 0) { 51 | self->history_backspace--; 52 | *ch = '\x08'; 53 | ret = 1; 54 | } 55 | /* Then continue returning history line characters for current line (except for \n and \r) */ 56 | else { 57 | if (self->history_buf[self->history_pos] == '\n' || 58 | self->history_buf[self->history_pos] == '\r') { 59 | self->history_pos++; 60 | } 61 | if (self->history_buf[self->history_pos] != 0x00) { 62 | *ch = self->history_buf[self->history_pos++]; 63 | ret = 1; 64 | } 65 | } 66 | 67 | return ret; 68 | } 69 | 70 | void ush_history_load_line(struct ush_object *self, size_t hline_idx) 71 | { 72 | USH_ASSERT(self != NULL); 73 | 74 | /* Setup erasing parameters for current line */ 75 | self->history_backspace = strlen(&self->desc->input_history->buffer[HLINE_IDX(0)]); 76 | memset(&self->desc->input_history->buffer[0], 0x00, 77 | self->desc->input_history->length); 78 | 79 | /* Setup a history line as character input */ 80 | self->history_buf = &self->desc->input_history->buffer[HLINE_IDX(hline_idx)]; 81 | self->history_pos = 0; 82 | self->state = USH_STATE_READ_CHAR_BUFFER; 83 | } 84 | 85 | void ush_history_save_line(struct ush_object *self, size_t hline_idx, bool new_history_line) 86 | { 87 | USH_ASSERT(self != NULL); 88 | 89 | /* Only save non-empty lines to history */ 90 | if (strlen(&self->desc->input_history->buffer[HLINE_IDX(0)]) > 1) { 91 | 92 | /* Move out the oldest command line from history buffer? */ 93 | if (new_history_line) { 94 | for (size_t i = self->desc->input_history->lines - 1; i > 0; i--) { 95 | memcpy(&self->desc->input_history->buffer[HLINE_IDX(i)], 96 | &self->desc->input_history->buffer[HLINE_IDX(i - 1)], 97 | self->desc->input_history->length); 98 | } 99 | memset(&self->desc->input_history->buffer[HLINE_IDX(0)], 0x00, 100 | self->desc->input_history->length); 101 | self->history_index = 0; 102 | } 103 | else { 104 | /* Copy command line to history line */ 105 | memcpy(&self->desc->input_history->buffer[HLINE_IDX(hline_idx)], 106 | &self->desc->input_history->buffer[HLINE_IDX(0)], 107 | self->desc->input_history->length); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/src/ush_node.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_node.h" 26 | #include "inc/ush_utils.h" 27 | 28 | #include 29 | 30 | struct ush_node_object* ush_node_get_by_path(struct ush_object *self, const char *path) 31 | { 32 | USH_ASSERT(self != NULL); 33 | USH_ASSERT(path != NULL); 34 | 35 | char level_path[self->desc->path_max_length]; 36 | 37 | size_t levels = ush_utils_get_path_levels_count(path); 38 | 39 | if (levels == 0) 40 | return self->root; 41 | if (self->root == NULL) 42 | return NULL; 43 | 44 | struct ush_node_object *curr = self->root->childs; 45 | for (size_t i = 1; i <= levels; i++) { 46 | ush_utils_get_path_level(i, path, level_path); 47 | 48 | bool found = false; 49 | while (curr != NULL) { 50 | if (strcmp(curr->path, level_path) == 0) { 51 | found = true; 52 | break; 53 | } 54 | curr = curr->next; 55 | } 56 | 57 | if (found == false) 58 | break; 59 | 60 | if (i == levels) 61 | return curr; 62 | 63 | curr = curr->childs; 64 | } 65 | 66 | 67 | return NULL; 68 | } 69 | 70 | void ush_node_get_absolute_path(struct ush_object *self, const char *in_path, char *out_path) 71 | { 72 | char abs_path[self->desc->path_max_length]; 73 | 74 | USH_ASSERT(self != NULL); 75 | USH_ASSERT(in_path != NULL); 76 | USH_ASSERT(out_path != NULL); 77 | 78 | if (in_path[0] == '/') { 79 | strcpy(abs_path, in_path); 80 | } else { 81 | strcpy(abs_path, self->current_node->path); 82 | if (strcmp(self->current_node->path, "/") != 0) 83 | strcat(abs_path, "/"); 84 | strcat(abs_path, in_path); 85 | } 86 | 87 | size_t abs_path_len = strlen(abs_path); 88 | if ((abs_path_len > 1) && (abs_path[abs_path_len - 1] == '/')) 89 | abs_path[abs_path_len - 1] = '\0'; 90 | 91 | ush_utils_get_collapse_path(abs_path, out_path); 92 | } 93 | 94 | void ush_node_deinit_recursive(struct ush_object *self, struct ush_node_object *node) 95 | { 96 | USH_ASSERT(self != NULL); 97 | 98 | struct ush_node_object *curr = node; 99 | 100 | while (curr != NULL) { 101 | if (curr->childs != NULL) 102 | ush_node_deinit_recursive(self, curr->childs); 103 | 104 | struct ush_node_object *tmp = curr->next; 105 | memset((uint8_t*)curr, 0, sizeof(struct ush_node_object)); 106 | curr = tmp; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/src/ush_node_mount.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_node.h" 26 | #include "inc/ush_utils.h" 27 | 28 | #include 29 | 30 | ush_status_t ush_node_mount(struct ush_object *self, const char *path, struct ush_node_object *node, const struct ush_file_descriptor *file_list, size_t file_list_size) 31 | { 32 | USH_ASSERT(self != NULL); 33 | USH_ASSERT(node != NULL); 34 | USH_ASSERT(path != NULL); 35 | 36 | for (size_t i = 0; i < file_list_size; i++) { 37 | USH_ASSERT(file_list[i].name != NULL); 38 | } 39 | 40 | node->file_list = file_list; 41 | node->file_list_size = file_list_size; 42 | node->path = path; 43 | 44 | struct ush_node_object *node_exists = ush_node_get_by_path(self, path); 45 | if (node_exists != NULL) 46 | return USH_STATUS_ERROR_NODE_ALREADY_MOUNTED; 47 | 48 | struct ush_node_object *node_parent = ush_node_get_parent_by_path(self, path); 49 | if (node_parent != NULL) { 50 | node->next = node_parent->childs; 51 | node_parent->childs = node; 52 | node->parent = node_parent; 53 | return USH_STATUS_OK; 54 | } 55 | 56 | if (strcmp(path, "/") == 0) { 57 | node->next = NULL; 58 | self->root = node; 59 | self->current_node = self->root; 60 | node->parent = NULL; 61 | return USH_STATUS_OK; 62 | } 63 | 64 | return USH_STATUS_ERROR_NODE_WITHOUT_PARENT; 65 | } 66 | 67 | ush_status_t ush_node_unmount(struct ush_object *self, const char *path) 68 | { 69 | USH_ASSERT(self != NULL); 70 | USH_ASSERT(path != NULL); 71 | 72 | struct ush_node_object *parent_node = ush_node_get_parent_by_path(self, path); 73 | struct ush_node_object *node = ush_node_get_by_path(self, path); 74 | 75 | if ((node == NULL) || ((node != self->root) && (parent_node == NULL))) 76 | return USH_STATUS_ERROR_NODE_NOT_FOUND; 77 | 78 | if (node->childs != NULL) 79 | return USH_STATUS_ERROR_NODE_WITH_CHILDS; 80 | 81 | if (parent_node == NULL) { 82 | self->root = NULL; 83 | return USH_STATUS_OK; 84 | } 85 | 86 | struct ush_node_object *prev = NULL; 87 | struct ush_node_object *curr = parent_node->childs; 88 | 89 | while (curr != NULL) { 90 | if (curr != node) { 91 | prev = curr; 92 | curr = curr->next; 93 | continue; 94 | } 95 | if (prev == NULL) { 96 | parent_node->childs = node->next; 97 | } else { 98 | prev->next = node->next; 99 | } 100 | return USH_STATUS_OK; 101 | } 102 | 103 | return USH_STATUS_ERROR_NODE_NOT_FOUND; 104 | } 105 | -------------------------------------------------------------------------------- /src/src/ush_node_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_node.h" 26 | #include "inc/ush_utils.h" 27 | 28 | #include 29 | 30 | struct ush_node_object* ush_node_get_parent_by_path(struct ush_object *self, const char *path) 31 | { 32 | USH_ASSERT(self != NULL); 33 | USH_ASSERT(path != NULL); 34 | 35 | size_t path_len = strlen(path); 36 | char path_parent[path_len + 1]; 37 | memcpy(path_parent, path, path_len + 1); 38 | 39 | ush_utils_path_upper(path_parent); 40 | if (path_parent[0] == '\0') 41 | return NULL; 42 | 43 | return ush_node_get_by_path(self, path_parent); 44 | } 45 | 46 | ush_status_t ush_node_set_current_dir(struct ush_object *self, const char *path) 47 | { 48 | USH_ASSERT(self != NULL); 49 | USH_ASSERT(path != NULL); 50 | 51 | if (path[0] == '\0') 52 | return USH_STATUS_ERROR_NODE_NOT_FOUND; 53 | 54 | char abs_path[self->desc->path_max_length]; 55 | 56 | ush_node_get_absolute_path(self, path, abs_path); 57 | struct ush_node_object *node = ush_node_get_by_path(self, abs_path); 58 | if (node != NULL) { 59 | self->current_node = node; 60 | return USH_STATUS_OK; 61 | } 62 | 63 | return USH_STATUS_ERROR_NODE_NOT_FOUND; 64 | } 65 | -------------------------------------------------------------------------------- /src/src/ush_parse.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_preconfig.h" 27 | #include "inc/ush_file.h" 28 | #include "inc/ush.h" 29 | 30 | #include 31 | 32 | void ush_parse_finish(struct ush_object *self) 33 | { 34 | USH_ASSERT(self != NULL); 35 | 36 | char *argv[self->args_count]; 37 | int argc; 38 | 39 | argc = ush_parse_get_args(self, argv); 40 | if (argc == 0) 41 | return; 42 | 43 | if (self->desc->exec != NULL) 44 | self->desc->exec(self, NULL, argc, argv); 45 | 46 | struct ush_file_descriptor const *file = ush_file_find_by_name(self, argv[0]); 47 | if (file == NULL) { 48 | ush_print_status(self, USH_STATUS_ERROR_COMMAND_SYNTAX_ERROR); 49 | return; 50 | } 51 | 52 | if (file->exec == NULL) { 53 | ush_print_status(self, USH_STATUS_ERROR_FILE_NOT_EXECUTABLE); 54 | return; 55 | } 56 | 57 | file->exec(self, file, argc, argv); 58 | } 59 | 60 | bool ush_parse_service(struct ush_object *self) 61 | { 62 | USH_ASSERT(self != NULL); 63 | 64 | bool processed = true; 65 | 66 | switch (self->state) { 67 | case USH_STATE_PARSE_PREPARE: 68 | ush_parse_start(self); 69 | break; 70 | case USH_STATE_PARSE_SEARCH_ARG: 71 | case USH_STATE_PARSE_QUOTE_ARG: 72 | case USH_STATE_PARSE_STANDARD_ARG: 73 | ush_parse_char(self); 74 | break; 75 | default: 76 | processed = false; 77 | break; 78 | } 79 | 80 | return processed; 81 | } 82 | -------------------------------------------------------------------------------- /src/src/ush_parse_char.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_preconfig.h" 27 | 28 | void ush_parse_char(struct ush_object *self) 29 | { 30 | USH_ASSERT(self != NULL); 31 | 32 | char ch = self->desc->input_buffer[self->in_pos++]; 33 | 34 | if (ch == '\n' || ch == '\r') { 35 | self->desc->input_buffer[self->out_pos++] = '\0'; 36 | self->state = USH_STATE_RESET_PROMPT; 37 | ush_parse_finish(self); 38 | return; 39 | } 40 | 41 | ush_parse_char_standard(self, ch); 42 | } 43 | -------------------------------------------------------------------------------- /src/src/ush_process.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_types.h" 27 | #include "inc/ush_preconfig.h" 28 | 29 | void ush_process_start(struct ush_object *self, const struct ush_file_descriptor *file) 30 | { 31 | USH_ASSERT(self != NULL); 32 | USH_ASSERT(file != NULL); 33 | 34 | self->process_file = file; 35 | self->state = USH_STATE_PROCESS_START; 36 | } 37 | 38 | bool ush_process_service(struct ush_object *self) 39 | { 40 | USH_ASSERT(self != NULL); 41 | 42 | bool processed = true; 43 | 44 | switch (self->state) { 45 | case USH_STATE_PROCESS_START: 46 | case USH_STATE_PROCESS_SERVICE: 47 | case USH_STATE_PROCESS_FINISH: 48 | USH_ASSERT(self->process_file != NULL); 49 | 50 | if (self->process_file->process == NULL) { 51 | self->state = USH_STATE_RESET; 52 | break; 53 | } 54 | self->process_file->process(self, self->process_file); 55 | break; 56 | default: 57 | processed = false; 58 | break; 59 | } 60 | 61 | return processed; 62 | } 63 | -------------------------------------------------------------------------------- /src/src/ush_prompt.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush.h" 26 | #include "inc/ush_shell.h" 27 | #include "inc/ush_utils.h" 28 | #include "inc/ush_internal.h" 29 | 30 | #include 31 | 32 | void ush_prompt_start(struct ush_object *self, ush_state_t prompt_next_state) 33 | { 34 | self->state = USH_STATE_PROMPT_PREFIX; 35 | self->prompt_next_state = prompt_next_state; 36 | } 37 | 38 | bool ush_prompt_service(struct ush_object *self) 39 | { 40 | USH_ASSERT(self != NULL); 41 | 42 | bool processed = true; 43 | 44 | switch (self->state) { 45 | case USH_STATE_PROMPT_PREFIX: 46 | ush_write_pointer(self, self->desc->prompt_format->prompt_prefix, USH_STATE_PROMPT_HOST); 47 | break; 48 | case USH_STATE_PROMPT_HOST: 49 | ush_write_pointer(self, self->desc->hostname, USH_STATE_PROMPT_SPACE); 50 | break; 51 | case USH_STATE_PROMPT_SPACE: 52 | ush_write_pointer(self, self->desc->prompt_format->prompt_space, USH_STATE_PROMPT_PATH); 53 | break; 54 | case USH_STATE_PROMPT_PATH: { 55 | char *path = ush_utils_path_last(self->current_node->path); 56 | ush_write_pointer(self, (char*)path, USH_STATE_PROMPT_SUFFIX); 57 | break; 58 | } 59 | case USH_STATE_PROMPT_SUFFIX: 60 | ush_write_pointer(self, self->desc->prompt_format->prompt_suffix, self->prompt_next_state); 61 | break; 62 | default: 63 | processed = false; 64 | break; 65 | } 66 | 67 | return processed; 68 | } 69 | -------------------------------------------------------------------------------- /src/src/ush_read.c: -------------------------------------------------------------------------------- 1 | #include "inc/ush_internal.h" 2 | 3 | bool ush_read_service(struct ush_object *self, bool *read) 4 | { 5 | USH_ASSERT(self != NULL); 6 | 7 | bool processed = true; 8 | 9 | switch (self->state) { 10 | case USH_STATE_READ_PREPARE: 11 | ush_read_start(self); 12 | break; 13 | case USH_STATE_READ_CHAR: 14 | *read = ush_read_char(self); 15 | break; 16 | case USH_STATE_READ_CHAR_BUFFER: 17 | *read = ush_read_char_buffer(self); 18 | break; 19 | default: 20 | processed = false; 21 | break; 22 | } 23 | 24 | return processed; 25 | } 26 | -------------------------------------------------------------------------------- /src/src/ush_read_char.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_preconfig.h" 27 | #include "inc/ush_history.h" 28 | 29 | static void ush_read_process(struct ush_object *self, char ch) 30 | { 31 | bool echo = true; 32 | 33 | switch (ch) { 34 | case '\x03': 35 | /* ctrl+c */ 36 | ush_write_pointer(self, "^C", USH_STATE_RESET); 37 | echo = false; 38 | break; 39 | case '\x08': 40 | case '\x7F': 41 | /* backspace */ 42 | if (self->in_pos > 0) { 43 | self->in_pos--; 44 | self->desc->input_buffer[self->in_pos] = '\0'; 45 | } else { 46 | echo = false; 47 | } 48 | break; 49 | case '\x09': 50 | /* tab */ 51 | #if USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE == 1 52 | ush_autocomp_start(self); 53 | #endif /* USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE */ 54 | echo = false; 55 | break; 56 | case '\x1B': 57 | /* escape */ 58 | self->ansi_escape_state = 1; 59 | echo = false; 60 | break; 61 | case '\x01': 62 | case '\x1A': 63 | /* ctrl+a or ctrl+z */ 64 | self->ansi_escape_state = 2; 65 | echo = ush_read_char_by_escape_state(self, ch); 66 | break; 67 | default: 68 | echo = ush_read_char_by_escape_state(self, ch); 69 | break; 70 | } 71 | 72 | if (echo != false) 73 | ush_read_echo_service(self, ch); 74 | } 75 | 76 | bool ush_read_char(struct ush_object *self) 77 | { 78 | USH_ASSERT(self != NULL); 79 | 80 | char ch; 81 | if (self->desc->io->read(self, &ch) == 0) 82 | return false; 83 | 84 | ush_read_process(self, ch); 85 | 86 | return true; 87 | } 88 | 89 | bool ush_read_char_buffer(struct ush_object *self) 90 | { 91 | USH_ASSERT(self != NULL); 92 | 93 | char ch; 94 | if (ush_history_read_char(self, &ch) == 0) { 95 | self->state = USH_STATE_READ_CHAR; 96 | return false; 97 | } 98 | 99 | ush_read_process(self, ch); 100 | 101 | return true; 102 | } 103 | -------------------------------------------------------------------------------- /src/src/ush_reset.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_const.h" 27 | #include "inc/ush_history.h" 28 | #include "inc/ush.h" 29 | 30 | #include 31 | 32 | void ush_reset_start(struct ush_object *self) 33 | { 34 | USH_ASSERT(self != NULL); 35 | 36 | self->state = USH_STATE_RESET; 37 | } 38 | 39 | void ush_reset(struct ush_object *self) 40 | { 41 | USH_ASSERT(self != NULL); 42 | 43 | self->current_node = self->root; 44 | ush_history_reset(self); 45 | 46 | if (USH_CONFIG_ENABLE_FEATURE_VERSION_PRINT) { 47 | ush_write_pointer(self, USH_NAME " " USH_VERSION "\r\n", USH_STATE_RESET_PROMPT); 48 | } 49 | } 50 | 51 | bool ush_reset_service(struct ush_object *self) 52 | { 53 | USH_ASSERT(self != NULL); 54 | 55 | bool processed = true; 56 | 57 | switch (self->state) { 58 | case USH_STATE_RESET: 59 | ush_write_pointer(self, "\r\n", USH_STATE_RESET_PROMPT); 60 | break; 61 | case USH_STATE_RESET_PROMPT: 62 | ush_prompt_start(self, USH_STATE_READ_PREPARE); 63 | break; 64 | default: 65 | processed = false; 66 | break; 67 | } 68 | 69 | return processed; 70 | } 71 | -------------------------------------------------------------------------------- /src/src/ush_write.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_preconfig.h" 27 | 28 | #include 29 | 30 | void ush_write_pointer(struct ush_object *self, char *text, ush_state_t write_next_state) 31 | { 32 | USH_ASSERT(self != NULL); 33 | USH_ASSERT(text != NULL); 34 | USH_ASSERT(write_next_state < USH_STATE__TOTAL_NUM); 35 | 36 | ush_write_pointer_bin(self, (uint8_t*)text, strlen(text), write_next_state); 37 | } 38 | 39 | bool ush_write_service(struct ush_object *self) 40 | { 41 | USH_ASSERT(self != NULL); 42 | 43 | bool processed = true; 44 | 45 | switch (self->state) { 46 | case USH_STATE_WRITE_CHAR: 47 | ush_write_char(self); 48 | break; 49 | default: 50 | processed = false; 51 | break; 52 | } 53 | 54 | return processed; 55 | } 56 | -------------------------------------------------------------------------------- /src/src/ush_write_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "inc/ush_internal.h" 26 | #include "inc/ush_preconfig.h" 27 | 28 | void ush_write_pointer_bin(struct ush_object *self, uint8_t *data, size_t data_size, ush_state_t write_next_state) 29 | { 30 | USH_ASSERT(self != NULL); 31 | USH_ASSERT(data != NULL); 32 | USH_ASSERT(write_next_state < USH_STATE__TOTAL_NUM); 33 | 34 | self->write_pos = 0; 35 | self->write_size = data_size; 36 | self->write_buf = (char*)data; 37 | 38 | self->state = USH_STATE_WRITE_CHAR; 39 | self->write_next_state = write_next_state; 40 | } 41 | 42 | void ush_write_char(struct ush_object *self) 43 | { 44 | USH_ASSERT(self != NULL); 45 | 46 | if (self->write_pos >= self->write_size) { 47 | self->state = self->write_next_state; 48 | return; 49 | } 50 | 51 | char ch = self->write_buf[self->write_pos]; 52 | 53 | if (self->desc->io->write(self, ch) == 0) 54 | return; 55 | 56 | self->write_pos++; 57 | } 58 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set( UNITY_TARGET unity ) 3 | 4 | add_library( 5 | ${UNITY_TARGET} 6 | STATIC 7 | ${CMAKE_CURRENT_SOURCE_DIR}/Unity/src/unity.c 8 | ) 9 | target_include_directories( 10 | ${UNITY_TARGET} 11 | PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Unity/src 13 | ) 14 | 15 | set ( USH_TARGET ush_testfunc ) 16 | build_ush ( ${USH_TARGET} 17 | ${CMAKE_CURRENT_SOURCE_DIR}/func_tests 18 | ) 19 | 20 | set ( TEST_FUNC testfunc ) 21 | add_library( 22 | ${TEST_FUNC} 23 | STATIC 24 | ${CMAKE_CURRENT_SOURCE_DIR}/func_tests/test_func.c 25 | ) 26 | target_include_directories( 27 | ${TEST_FUNC} 28 | PUBLIC 29 | ${PROJECT_SOURCE_DIR}/tests/func_tests 30 | ) 31 | target_link_libraries( 32 | ${TEST_FUNC} 33 | PUBLIC 34 | ${UNITY_TARGET} 35 | ${USH_TARGET} 36 | ) 37 | target_compile_options( 38 | ${TEST_FUNC} 39 | PRIVATE 40 | -Werror -Wall -Wextra -g -O0 41 | ) 42 | 43 | function(create_unit_test TARGET) 44 | add_executable( ${TARGET} ${ARGV} ) 45 | target_include_directories( ${TARGET} PUBLIC 46 | ${PROJECT_SOURCE_DIR}/tests/unit_tests 47 | ${USH_INC_DIRS} 48 | ) 49 | target_link_libraries( ${TARGET} PUBLIC ${UNITY_TARGET}) 50 | target_compile_options( ${TARGET} PRIVATE -Werror -Wall -Wextra -g -O0) 51 | add_test( NAME ${TARGET} COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TARGET} ) 52 | endfunction() 53 | 54 | function(create_func_test TARGET) 55 | add_executable( ${TARGET} ${ARGV} ) 56 | target_link_libraries( ${TARGET} PUBLIC ${TEST_FUNC} ) 57 | target_compile_options( ${TARGET} PRIVATE -Werror -Wall -Wextra -g -O0) 58 | add_test( NAME ${TARGET} COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TARGET} ) 59 | endfunction() 60 | 61 | add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests ) 62 | add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/func_tests ) 63 | 64 | add_custom_target( 65 | coverage 66 | COMMAND gcovr -r ${PROJECT_SOURCE_DIR} --exclude=${PROJECT_SOURCE_DIR}/tests/Unity/ --exclude=${PROJECT_SOURCE_DIR}/examples/ --print-summary --html --html-details -o test_coverage.html 67 | ) 68 | -------------------------------------------------------------------------------- /tests/func_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | create_func_test( test_func_cmd_help 3 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_help.c 4 | ) 5 | 6 | create_func_test( test_func_cmd_pwd 7 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_pwd.c 8 | ) 9 | 10 | create_func_test( test_func_cmd_cd 11 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_cd.c 12 | ) 13 | 14 | create_func_test( test_func_cmd_echo 15 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_echo.c 16 | ) 17 | 18 | create_func_test( test_func_cmd_ls 19 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_ls.c 20 | ) 21 | 22 | create_func_test( test_func_cmd_cat 23 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_cat.c 24 | ) 25 | 26 | create_func_test( test_func_cmd_xxd 27 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_cmd_xxd.c 28 | ) 29 | 30 | create_func_test( test_func_input 31 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_input.c 32 | ) 33 | 34 | create_func_test( test_func_autocomp 35 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_autocomp.c 36 | ) 37 | 38 | create_func_test( test_func_exec 39 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_exec.c 40 | ) 41 | 42 | create_func_test( test_func_mount 43 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_mount.c 44 | ) 45 | 46 | create_func_test( test_func_print 47 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_print.c 48 | ) 49 | 50 | create_func_test( test_func_reset 51 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_reset.c 52 | ) 53 | 54 | create_func_test( test_func_commands 55 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_commands.c 56 | ) 57 | 58 | create_func_test( test_func_file 59 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_file.c 60 | ) 61 | 62 | create_func_test( test_func_node 63 | ${CMAKE_CURRENT_SOURCE_DIR}/test_func_node.c 64 | ) 65 | -------------------------------------------------------------------------------- /tests/func_tests/test_func.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef TEST_FUNC_H 26 | #define TEST_FUNC_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include "unity.h" 37 | 38 | #define TEST_FUNC_IO_BUFFER_SIZE 2048 39 | #define TEST_FUNC_WORK_BUFFER_SIZE 256 40 | 41 | extern char g_write_buf[]; 42 | extern char g_read_buf[]; 43 | 44 | extern uint8_t g_file_buffer_buf[]; 45 | extern size_t g_file_buffer_buf_size; 46 | 47 | extern struct ush_object g_ush; 48 | 49 | extern const struct ush_file_descriptor g_path_root_desc[]; 50 | extern const struct ush_file_descriptor g_path_data_desc[]; 51 | extern const struct ush_file_descriptor g_path_dir111_desc[]; 52 | 53 | extern struct ush_node_object g_path_root; 54 | extern struct ush_node_object g_path_data; 55 | extern struct ush_node_object g_path_dir; 56 | extern struct ush_node_object g_path_dir11; 57 | extern struct ush_node_object g_path_dir111; 58 | 59 | void test_func_init(void); 60 | void test_func_deinit(void); 61 | void test_func_write(const char *text); 62 | void test_func_read(bool reset_g_write_buf_index, int ush_service_loops); 63 | void test_func_read_all(void); 64 | 65 | #define TEST_FUNC_ASK(request, response) \ 66 | {\ 67 | char buf[TEST_FUNC_IO_BUFFER_SIZE];\ 68 | char buf_resp[TEST_FUNC_IO_BUFFER_SIZE];\ 69 | \ 70 | sprintf(buf, "%s\n", request);\ 71 | sprintf(buf_resp, "%s\n%s", request, response);\ 72 | test_func_write(buf);\ 73 | test_func_read_all();\ 74 | TEST_ASSERT_EQUAL_STRING(\ 75 | buf_resp,\ 76 | g_write_buf\ 77 | );\ 78 | } 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif /* TEST_FUNC_H */ 85 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_cmd_cd.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | void setUp(void) 33 | { 34 | test_func_init(); 35 | } 36 | 37 | void tearDown(void) 38 | { 39 | test_func_deinit(); 40 | } 41 | 42 | void test_cmd_cd_abs(void) 43 | { 44 | TEST_FUNC_ASK("cd /data", 45 | "[test data]$ " 46 | ); 47 | 48 | TEST_FUNC_ASK("cd /dir/1", 49 | "[test 1]$ " 50 | ); 51 | 52 | TEST_FUNC_ASK("cd /dir/2/21", 53 | "[test 21]$ " 54 | ); 55 | 56 | TEST_FUNC_ASK("cd /dir/../data", 57 | "[test data]$ " 58 | ); 59 | 60 | TEST_FUNC_ASK("cd /dir/../../../../../dir/1/12/../11", 61 | "[test 11]$ " 62 | ); 63 | } 64 | 65 | void test_cmd_cd_rel(void) 66 | { 67 | TEST_FUNC_ASK("cd data", 68 | "[test data]$ " 69 | ); 70 | 71 | TEST_FUNC_ASK("cd .", 72 | "[test data]$ " 73 | ); 74 | 75 | TEST_FUNC_ASK("cd ./../dir/2/21", 76 | "[test 21]$ " 77 | ); 78 | 79 | TEST_FUNC_ASK("cd ../../../data", 80 | "[test data]$ " 81 | ); 82 | 83 | TEST_FUNC_ASK("cd ../../../../../data", 84 | "[test data]$ " 85 | ); 86 | 87 | TEST_FUNC_ASK("cd ././../../dir/1/12/../11", 88 | "[test 11]$ " 89 | ); 90 | } 91 | 92 | void test_cmd_cd_error(void) 93 | { 94 | TEST_FUNC_ASK("cd", 95 | "error: wrong arguments\r\n" 96 | "[test /]$ " 97 | ); 98 | 99 | TEST_FUNC_ASK("cd 1 2", 100 | "error: wrong arguments\r\n" 101 | "[test /]$ " 102 | ); 103 | 104 | TEST_FUNC_ASK("cd test", 105 | "error: directory not found\r\n" 106 | "[test /]$ " 107 | ); 108 | 109 | TEST_FUNC_ASK("cd di", 110 | "error: directory not found\r\n" 111 | "[test /]$ " 112 | ); 113 | } 114 | 115 | void test_cmd_cd_help(void) 116 | { 117 | TEST_FUNC_ASK("help cd", 118 | "usage: cd \r\n" 119 | "[test /]$ " 120 | ); 121 | } 122 | 123 | int main(int argc, char *argv[]) 124 | { 125 | (void)argc; 126 | (void)argv; 127 | 128 | UNITY_BEGIN(); 129 | 130 | RUN_TEST(test_cmd_cd_abs); 131 | RUN_TEST(test_cmd_cd_rel); 132 | RUN_TEST(test_cmd_cd_error); 133 | RUN_TEST(test_cmd_cd_help); 134 | 135 | return UNITY_END(); 136 | } 137 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_cmd_help.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | void setUp(void) 33 | { 34 | test_func_init(); 35 | } 36 | 37 | void tearDown(void) 38 | { 39 | test_func_deinit(); 40 | } 41 | 42 | void test_cmd_help_self(void) 43 | { 44 | TEST_FUNC_ASK("help", 45 | "help - list available commands\r\n" 46 | "ls - list directory content\r\n" 47 | "cd - change current directory\r\n" 48 | "pwd - print current directory\r\n" 49 | "cat - print files content\r\n" 50 | "xxd - dump file hex content\r\n" 51 | "echo - print string to file\r\n" 52 | "[test /]$ " 53 | ); 54 | } 55 | 56 | void test_cmd_help_help(void) 57 | { 58 | TEST_FUNC_ASK("help help", 59 | "usage: help [file]\r\n" 60 | "[test /]$ " 61 | ); 62 | } 63 | 64 | void test_cmd_help_error(void) 65 | { 66 | TEST_FUNC_ASK("help help abc", 67 | "error: wrong arguments\r\n" 68 | "[test /]$ " 69 | ); 70 | 71 | TEST_FUNC_ASK("help hel", 72 | "error: file not found\r\n" 73 | "[test /]$ " 74 | ); 75 | 76 | TEST_FUNC_ASK("help /data/binary", 77 | "error: no help available\r\n" 78 | "[test /]$ " 79 | ); 80 | } 81 | 82 | void test_cmd_help_file(void) 83 | { 84 | TEST_FUNC_ASK("help ./test", 85 | "nothing special\r\n" 86 | "[test /]$ " 87 | ); 88 | } 89 | 90 | int main(int argc, char *argv[]) 91 | { 92 | (void)argc; 93 | (void)argv; 94 | 95 | UNITY_BEGIN(); 96 | 97 | RUN_TEST(test_cmd_help_self); 98 | RUN_TEST(test_cmd_help_help); 99 | RUN_TEST(test_cmd_help_error); 100 | RUN_TEST(test_cmd_help_file); 101 | 102 | return UNITY_END(); 103 | } 104 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_cmd_pwd.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | void setUp(void) 33 | { 34 | test_func_init(); 35 | } 36 | 37 | void tearDown(void) 38 | { 39 | test_func_deinit(); 40 | } 41 | 42 | void test_cmd_pwd_root(void) 43 | { 44 | TEST_FUNC_ASK("pwd", 45 | "/\r\n" 46 | "[test /]$ " 47 | ); 48 | } 49 | 50 | void test_cmd_pwd_misc(void) 51 | { 52 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/data")); 53 | TEST_FUNC_ASK("pwd", 54 | "/data\r\n" 55 | "[test data]$ " 56 | ); 57 | 58 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/dir/1/11/111")); 59 | TEST_FUNC_ASK("pwd", 60 | "/dir/1/11/111\r\n" 61 | "[test 111]$ " 62 | ); 63 | 64 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/dir/2/21")); 65 | TEST_FUNC_ASK("pwd", 66 | "/dir/2/21\r\n" 67 | "[test 21]$ " 68 | ); 69 | } 70 | 71 | void test_cmd_pwd_error(void) 72 | { 73 | TEST_FUNC_ASK("pwd 1", 74 | "error: wrong arguments\r\n" 75 | "[test /]$ " 76 | ); 77 | } 78 | 79 | void test_cmd_pwd_help(void) 80 | { 81 | TEST_FUNC_ASK("help pwd", 82 | "usage: pwd\r\n" 83 | "[test /]$ " 84 | ); 85 | } 86 | 87 | int main(int argc, char *argv[]) 88 | { 89 | (void)argc; 90 | (void)argv; 91 | 92 | UNITY_BEGIN(); 93 | 94 | RUN_TEST(test_cmd_pwd_root); 95 | RUN_TEST(test_cmd_pwd_error); 96 | RUN_TEST(test_cmd_pwd_help); 97 | RUN_TEST(test_cmd_pwd_misc); 98 | 99 | return UNITY_END(); 100 | } 101 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_commands.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | static struct ush_node_object node = {0}; 33 | 34 | void cmd2_exec_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]) 35 | { 36 | (void)file; 37 | 38 | static char buf[128]; 39 | 40 | strcpy(buf, "test cmd2\r\n"); 41 | for (int i = 1; i < argc; i++) { 42 | strcat(buf, argv[i]); 43 | strcat(buf, "\r\n"); 44 | } 45 | 46 | ush_print_no_newline(self, buf); 47 | } 48 | 49 | static struct ush_file_descriptor files[] = { 50 | { 51 | .name = "cmd1", 52 | .description = "additional cmd1", 53 | }, 54 | { 55 | .name = "cmd2", 56 | .description = "additional cmd2", 57 | .exec = cmd2_exec_callback, 58 | } 59 | }; 60 | 61 | void setUp(void) 62 | { 63 | test_func_init(); 64 | } 65 | 66 | void tearDown(void) 67 | { 68 | test_func_deinit(); 69 | } 70 | 71 | void test_commands_add(void) 72 | { 73 | TEST_FUNC_ASK("cmd1", 74 | "error: syntax error\r\n" 75 | "[test /]$ " 76 | ); 77 | TEST_FUNC_ASK("cmd2", 78 | "error: syntax error\r\n" 79 | "[test /]$ " 80 | ); 81 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_commands_add(&g_ush, &node, files, sizeof(files) / sizeof(files[0]))); 82 | TEST_FUNC_ASK("cmd1", 83 | "error: file not executable\r\n" 84 | "[test /]$ " 85 | ); 86 | TEST_FUNC_ASK("help cmd1", 87 | "error: no help available\r\n" 88 | "[test /]$ " 89 | ); 90 | TEST_FUNC_ASK("cmd2 a b c xyz", 91 | "test cmd2\r\n" 92 | "a\r\n" 93 | "b\r\n" 94 | "c\r\n" 95 | "xyz\r\n" 96 | "[test /]$ " 97 | ); 98 | } 99 | 100 | void test_commands_error(void) 101 | { 102 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_NOT_FOUND, ush_commands_remove(&g_ush, &node)); 103 | } 104 | 105 | void test_commands_remove(void) 106 | { 107 | TEST_FUNC_ASK("pwd", 108 | "/\r\n" 109 | "[test /]$ " 110 | ); 111 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_commands_add(&g_ush, &node, files, sizeof(files) / sizeof(files[0]))); 112 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_commands_remove(&g_ush, &g_ush.buildin_commands)); 113 | TEST_FUNC_ASK("pwd", 114 | "error: syntax error\r\n" 115 | "[test /]$ " 116 | ); 117 | TEST_FUNC_ASK("cmd2 test", 118 | "test cmd2\r\n" 119 | "test\r\n" 120 | "[test /]$ " 121 | ); 122 | } 123 | 124 | int main(int argc, char *argv[]) 125 | { 126 | (void)argc; 127 | (void)argv; 128 | 129 | UNITY_BEGIN(); 130 | 131 | RUN_TEST(test_commands_add); 132 | RUN_TEST(test_commands_error); 133 | RUN_TEST(test_commands_remove); 134 | 135 | return UNITY_END(); 136 | } 137 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_exec.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | void setUp(void) 33 | { 34 | test_func_init(); 35 | } 36 | 37 | void tearDown(void) 38 | { 39 | test_func_deinit(); 40 | } 41 | 42 | void test_exec_ok(void) 43 | { 44 | TEST_FUNC_ASK("test", 45 | "test_exec_callback\r\n" 46 | "[test /]$ " 47 | ); 48 | 49 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/dir/2/21")); 50 | 51 | TEST_FUNC_ASK("../../../test", 52 | "test_exec_callback\r\n" 53 | "[test 21]$ " 54 | ); 55 | TEST_FUNC_ASK("./../../../test", 56 | "test_exec_callback\r\n" 57 | "[test 21]$ " 58 | ); 59 | TEST_FUNC_ASK("/test", 60 | "test_exec_callback\r\n" 61 | "[test 21]$ " 62 | ); 63 | } 64 | 65 | void test_exec_error(void) 66 | { 67 | TEST_FUNC_ASK("/data/binary", 68 | "error: file not executable\r\n" 69 | "[test /]$ " 70 | ); 71 | TEST_FUNC_ASK("data/binary", 72 | "error: file not executable\r\n" 73 | "[test /]$ " 74 | ); 75 | TEST_FUNC_ASK("data/bin", 76 | "error: syntax error\r\n" 77 | "[test /]$ " 78 | ); 79 | } 80 | 81 | int main(int argc, char *argv[]) 82 | { 83 | (void)argc; 84 | (void)argv; 85 | 86 | UNITY_BEGIN(); 87 | 88 | RUN_TEST(test_exec_ok); 89 | RUN_TEST(test_exec_error); 90 | 91 | return UNITY_END(); 92 | } 93 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_input.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | void setUp(void) 33 | { 34 | test_func_init(); 35 | } 36 | 37 | void tearDown(void) 38 | { 39 | test_func_deinit(); 40 | } 41 | 42 | void test_input_empty(void) 43 | { 44 | TEST_FUNC_ASK("", 45 | "[test /]$ " 46 | ); 47 | } 48 | 49 | void test_input_error(void) 50 | { 51 | TEST_FUNC_ASK("abcd", 52 | "error: syntax error\r\n" 53 | "[test /]$ " 54 | ); 55 | } 56 | 57 | void test_input_backspace(void) 58 | { 59 | test_func_write("test\x08\x08\x08\x08\n"); 60 | test_func_read_all(); 61 | TEST_ASSERT_EQUAL_STRING( 62 | "test\x08 \x08\x08 \x08\x08 \x08\x08 \x08\n" 63 | "[test /]$ ", 64 | g_write_buf 65 | ); 66 | 67 | test_func_write("pwx\x08""d\n"); 68 | test_func_read_all(); 69 | TEST_ASSERT_EQUAL_STRING( 70 | "pwx\x08 \x08""d\n" 71 | "/\r\n" 72 | "[test /]$ ", 73 | g_write_buf 74 | ); 75 | 76 | test_func_write("t\x08\x08\x08\x08""pw\x08""wd\n"); 77 | test_func_read_all(); 78 | TEST_ASSERT_EQUAL_STRING( 79 | "t\x08 \x08""pw\x08 \x08""wd\n" 80 | "/\r\n" 81 | "[test /]$ ", 82 | g_write_buf 83 | ); 84 | } 85 | 86 | int main(int argc, char *argv[]) 87 | { 88 | (void)argc; 89 | (void)argv; 90 | 91 | UNITY_BEGIN(); 92 | 93 | RUN_TEST(test_input_empty); 94 | RUN_TEST(test_input_error); 95 | RUN_TEST(test_input_backspace); 96 | 97 | return UNITY_END(); 98 | } 99 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_mount.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include "test_func.h" 31 | 32 | static struct ush_node_object node = {0}; 33 | 34 | void setUp(void) 35 | { 36 | test_func_init(); 37 | } 38 | 39 | void tearDown(void) 40 | { 41 | test_func_deinit(); 42 | } 43 | 44 | void test_mount(void) 45 | { 46 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_NOT_FOUND, ush_node_set_current_dir(&g_ush, "/abc")); 47 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_mount(&g_ush, "/abc", &node, NULL, 0)); 48 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/abc")); 49 | } 50 | 51 | void test_mount_error(void) 52 | { 53 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_ALREADY_MOUNTED, ush_node_mount(&g_ush, "/dir", &node, NULL, 0)); 54 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_WITHOUT_PARENT, ush_node_mount(&g_ush, "/test/abc", &node, NULL, 0)); 55 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_NOT_FOUND, ush_node_unmount(&g_ush, "/test")); 56 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_WITH_CHILDS, ush_node_unmount(&g_ush, "/dir")); 57 | } 58 | 59 | void test_mount_unmount(void) 60 | { 61 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/data")); 62 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_unmount(&g_ush, "/data")); 63 | TEST_ASSERT_EQUAL(USH_STATUS_OK, ush_node_set_current_dir(&g_ush, "/")); 64 | TEST_ASSERT_EQUAL(USH_STATUS_ERROR_NODE_NOT_FOUND, ush_node_set_current_dir(&g_ush, "/data")); 65 | } 66 | 67 | int main(int argc, char *argv[]) 68 | { 69 | (void)argc; 70 | (void)argv; 71 | 72 | UNITY_BEGIN(); 73 | 74 | RUN_TEST(test_mount); 75 | RUN_TEST(test_mount_error); 76 | RUN_TEST(test_mount_unmount); 77 | 78 | return UNITY_END(); 79 | } 80 | -------------------------------------------------------------------------------- /tests/func_tests/test_func_reset.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "test_func.h" 32 | 33 | void setUp(void) 34 | { 35 | test_func_init(); 36 | } 37 | 38 | void tearDown(void) 39 | { 40 | test_func_deinit(); 41 | } 42 | 43 | void test_reset(void) 44 | { 45 | ush_reset(&g_ush); 46 | test_func_read_all(); 47 | TEST_ASSERT_EQUAL_STRING(USH_NAME " " USH_VERSION "\r\n[test /]$ ", g_write_buf); 48 | } 49 | 50 | int main(int argc, char *argv[]) 51 | { 52 | (void)argc; 53 | (void)argv; 54 | 55 | UNITY_BEGIN(); 56 | 57 | RUN_TEST(test_reset); 58 | 59 | return UNITY_END(); 60 | } 61 | -------------------------------------------------------------------------------- /tests/func_tests/ush_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_CONFIG_H 26 | #define USH_CONFIG_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #define USH_CONFIG_FILENAME_ALIGN_SPACE 16 38 | #define USH_CONFIG_CMD_XXD_COLUMNS 8 39 | 40 | #define USH_CONFIG_ENABLE_COMMAND_CAT 1 41 | #define USH_CONFIG_ENABLE_COMMAND_CD 1 42 | #define USH_CONFIG_ENABLE_COMMAND_ECHO 1 43 | #define USH_CONFIG_ENABLE_COMMAND_HELP 1 44 | #define USH_CONFIG_ENABLE_COMMAND_LS 1 45 | #define USH_CONFIG_ENABLE_COMMAND_PWD 1 46 | #define USH_CONFIG_ENABLE_COMMAND_XXD 1 47 | 48 | #define USH_CONFIG_ENABLE_FEATURE_COMMANDS 1 49 | #define USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE 1 50 | #define USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES 0 51 | 52 | #define USH_CONFIG_TRANSLATION_OK "ok" 53 | #define USH_CONFIG_TRANSLATION_ERROR "error" 54 | #define USH_CONFIG_TRANSLATION_DIRECTORY_NOT_FOUND "directory not found" 55 | #define USH_CONFIG_TRANSLATION_NESTED_DIRECTORIES_EXIST "nested directories exist" 56 | #define USH_CONFIG_TRANSLATION_CANNOT_FIND_PARENT_NODE "cannot find parent node" 57 | #define USH_CONFIG_TRANSLATION_DIRECTORY_ALREADY_MOUNTED "directory already mounted" 58 | #define USH_CONFIG_TRANSLATION_SYNTAX_ERROR "syntax error" 59 | #define USH_CONFIG_TRANSLATION_WRONG_ARGUMENTS "wrong arguments" 60 | #define USH_CONFIG_TRANSLATION_FILE_NOT_EXECUTABLE "file not executable" 61 | #define USH_CONFIG_TRANSLATION_FILE_NOT_WRITABLE "file not writable" 62 | #define USH_CONFIG_TRANSLATION_FILE_NOT_READABLE "file not readable" 63 | #define USH_CONFIG_TRANSLATION_NO_HELP_AVAILABLE "no help available" 64 | #define USH_CONFIG_TRANSLATION_FILE_NOT_FOUND "file not found" 65 | #define USH_CONFIG_TRANSLATION_READ_ONLY_FILE "read only file" 66 | 67 | #define USH_ASSERT(cond) { assert(cond); } 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* USH_CONFIG_H */ 74 | -------------------------------------------------------------------------------- /tests/unit_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | create_unit_test( test_unit_utils 3 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_utils.c 4 | ${USH_SRC_DIR}/src/ush_utils.c 5 | ) 6 | 7 | create_unit_test( test_unit_reset 8 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_reset.c 9 | ${USH_SRC_DIR}/src/ush_reset.c 10 | ) 11 | 12 | create_unit_test( test_unit_prompt 13 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_prompt.c 14 | ${USH_SRC_DIR}/src/ush_prompt.c 15 | ) 16 | 17 | create_unit_test( test_unit_write 18 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_write.c 19 | ${USH_SRC_DIR}/src/ush_write.c 20 | ) 21 | 22 | create_unit_test( test_unit_write_utils 23 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_write_utils.c 24 | ${USH_SRC_DIR}/src/ush_write_utils.c 25 | ) 26 | 27 | create_unit_test( test_unit_read 28 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_read.c 29 | ${USH_SRC_DIR}/src/ush_read.c 30 | ) 31 | 32 | create_unit_test( test_unit_read_utils 33 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_read_utils.c 34 | # TODO: Make separate test unit for ush_history.c. 35 | # Right now, calling history functions from here is better than nothing 36 | ${USH_SRC_DIR}/src/ush_history.c 37 | ${USH_SRC_DIR}/src/ush_read_utils.c 38 | ) 39 | 40 | create_unit_test( test_unit_read_char 41 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_read_char.c 42 | # TODO: Make separate test unit for ush_history.c. 43 | # Right now, calling history functions from here is better than nothing 44 | ${USH_SRC_DIR}/src/ush_history.c 45 | ${USH_SRC_DIR}/src/ush_read_char.c 46 | ) 47 | 48 | create_unit_test( test_unit_process 49 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_process.c 50 | ${USH_SRC_DIR}/src/ush_process.c 51 | ) 52 | 53 | create_unit_test( test_unit_parse 54 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_parse.c 55 | ${USH_SRC_DIR}/src/ush_parse.c 56 | ) 57 | 58 | create_unit_test( test_unit_parse_utils 59 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_parse_utils.c 60 | ${USH_SRC_DIR}/src/ush_parse_utils.c 61 | ) 62 | 63 | create_unit_test( test_unit_parse_char 64 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_parse_char.c 65 | ${USH_SRC_DIR}/src/ush_parse_char.c 66 | ) 67 | 68 | create_unit_test( test_unit_commands 69 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_commands.c 70 | ${USH_SRC_DIR}/src/ush_commands.c 71 | ) 72 | 73 | create_unit_test( test_unit_cmd 74 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd.c 75 | ${USH_SRC_DIR}/src/commands/ush_cmd.c 76 | ) 77 | 78 | create_unit_test( test_unit_cmd_cd 79 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_cd.c 80 | ${USH_SRC_DIR}/src/commands/ush_cmd_cd.c 81 | ) 82 | 83 | create_unit_test( test_unit_cmd_pwd 84 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_pwd.c 85 | ${USH_SRC_DIR}/src/commands/ush_cmd_pwd.c 86 | ) 87 | 88 | create_unit_test( test_unit_cmd_echo 89 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_echo.c 90 | ${USH_SRC_DIR}/src/commands/ush_cmd_echo.c 91 | ${USH_SRC_DIR}/src/ush_utils.c 92 | ) 93 | 94 | create_unit_test( test_unit_cmd_cat 95 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_cat.c 96 | ${USH_SRC_DIR}/src/commands/ush_cmd_cat.c 97 | ) 98 | 99 | create_unit_test( test_unit_cmd_help 100 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_help.c 101 | ${USH_SRC_DIR}/src/commands/ush_cmd_help.c 102 | ) 103 | 104 | create_unit_test( test_unit_cmd_ls 105 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_ls.c 106 | ${USH_SRC_DIR}/src/commands/ush_cmd_ls.c 107 | ${USH_SRC_DIR}/src/ush_utils.c 108 | ) 109 | 110 | create_unit_test( test_unit_cmd_xxd 111 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_cmd_xxd.c 112 | ${USH_SRC_DIR}/src/commands/ush_cmd_xxd.c 113 | ${USH_SRC_DIR}/src/ush_utils.c 114 | ) 115 | 116 | create_unit_test( test_unit_file 117 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_file.c 118 | ${USH_SRC_DIR}/src/ush_file.c 119 | ) 120 | 121 | create_unit_test( test_unit_ush 122 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_ush.c 123 | ${USH_SRC_DIR}/src/ush.c 124 | ) 125 | 126 | create_unit_test( test_unit_node_utils 127 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_node_utils.c 128 | ${USH_SRC_DIR}/src/ush_node_utils.c 129 | ) 130 | 131 | create_unit_test( test_unit_node_mount 132 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_node_mount.c 133 | ${USH_SRC_DIR}/src/ush_node_mount.c 134 | ) 135 | 136 | create_unit_test( test_unit_node 137 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_node.c 138 | ${USH_SRC_DIR}/src/ush_node.c 139 | ${USH_SRC_DIR}/src/ush_utils.c 140 | ) 141 | 142 | create_unit_test( test_unit_autocomp 143 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_autocomp.c 144 | ${USH_SRC_DIR}/src/ush_autocomp.c 145 | ) 146 | 147 | create_unit_test( test_unit_autocomp_utils 148 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_autocomp_utils.c 149 | ${USH_SRC_DIR}/src/ush_autocomp_utils.c 150 | ${USH_SRC_DIR}/src/ush_utils.c 151 | ) 152 | 153 | create_unit_test( test_unit_autocomp_state 154 | ${CMAKE_CURRENT_SOURCE_DIR}/test_unit_autocomp_state.c 155 | ${USH_SRC_DIR}/src/ush_autocomp_state.c 156 | ${USH_SRC_DIR}/src/ush_utils.c 157 | ) 158 | -------------------------------------------------------------------------------- /tests/unit_tests/test_unit_cmd_cd.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include "inc/ush_commands.h" 31 | 32 | int g_assert_call_count; 33 | 34 | struct ush_object ush; 35 | 36 | ush_status_t ush_print_status_status; 37 | int ush_print_status_call_count; 38 | 39 | char *ush_node_set_current_dir_path; 40 | int ush_node_set_current_dir_call_count; 41 | ush_status_t ush_node_set_current_dir_return_val; 42 | 43 | extern void ush_buildin_cmd_cd_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]); 44 | 45 | void setUp(void) 46 | { 47 | memset((uint8_t*)&ush, 0, sizeof(ush)); 48 | 49 | ush_print_status_status = USH_STATUS__TOTAL_NUM; 50 | ush_print_status_call_count = 0; 51 | 52 | ush_node_set_current_dir_path = NULL; 53 | ush_node_set_current_dir_call_count = 0; 54 | ush_node_set_current_dir_return_val = USH_STATUS__TOTAL_NUM; 55 | } 56 | 57 | void tearDown(void) 58 | { 59 | 60 | } 61 | 62 | void ush_print_status(struct ush_object *self, ush_status_t status) 63 | { 64 | TEST_ASSERT_EQUAL(&ush, self); 65 | TEST_ASSERT_EQUAL(ush_print_status_status, status); 66 | 67 | ush_print_status_call_count++; 68 | } 69 | 70 | ush_status_t ush_node_set_current_dir(struct ush_object *self, const char *path) 71 | { 72 | TEST_ASSERT_EQUAL(&ush, self); 73 | TEST_ASSERT_EQUAL_STRING(ush_node_set_current_dir_path, path); 74 | 75 | ush_node_set_current_dir_call_count++; 76 | 77 | return ush_node_set_current_dir_return_val; 78 | } 79 | 80 | void test_ush_buildin_cmd_cd_callback_neg(void) 81 | { 82 | for (int i = 0; i < 6; i++) { 83 | setUp(); 84 | if (i != 2) { 85 | ush_print_status_status = USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS; 86 | ush_buildin_cmd_cd_callback(&ush, NULL, i, NULL); 87 | TEST_ASSERT_EQUAL(1, ush_print_status_call_count); 88 | TEST_ASSERT_EQUAL(0, ush_node_set_current_dir_call_count); 89 | } 90 | } 91 | } 92 | 93 | void test_ush_buildin_cmd_cd_callback_pos(void) 94 | { 95 | for (int n = 0; n < USH_STATUS__TOTAL_NUM; n++) { 96 | setUp(); 97 | 98 | ush_status_t status = (ush_status_t)n; 99 | char *argv[2] = {0}; 100 | 101 | argv[1] = "test"; 102 | ush_node_set_current_dir_return_val = status; 103 | ush_node_set_current_dir_path = "test"; 104 | ush_print_status_status = status; 105 | ush_buildin_cmd_cd_callback(&ush, NULL, 2, argv); 106 | TEST_ASSERT_EQUAL(1, ush_node_set_current_dir_call_count); 107 | if (status != USH_STATUS_OK) { 108 | TEST_ASSERT_EQUAL(1, ush_print_status_call_count); 109 | } else { 110 | TEST_ASSERT_EQUAL(0, ush_print_status_call_count); 111 | } 112 | } 113 | } 114 | 115 | int main(int argc, char *argv[]) 116 | { 117 | (void)argc; 118 | (void)argv; 119 | 120 | UNITY_BEGIN(); 121 | 122 | RUN_TEST(test_ush_buildin_cmd_cd_callback_neg); 123 | RUN_TEST(test_ush_buildin_cmd_cd_callback_pos); 124 | 125 | return UNITY_END(); 126 | } 127 | -------------------------------------------------------------------------------- /tests/unit_tests/test_unit_cmd_pwd.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include "inc/ush_commands.h" 31 | 32 | int g_assert_call_count; 33 | 34 | struct ush_object ush; 35 | 36 | ush_status_t ush_print_status_status; 37 | int ush_print_status_call_count; 38 | 39 | char* ush_print_buf; 40 | int ush_print_call_count; 41 | 42 | extern void ush_buildin_cmd_pwd_callback(struct ush_object *self, struct ush_file_descriptor const *file, int argc, char *argv[]); 43 | 44 | void setUp(void) 45 | { 46 | memset((uint8_t*)&ush, 0, sizeof(ush)); 47 | 48 | ush_print_status_status = USH_STATUS__TOTAL_NUM; 49 | ush_print_status_call_count = 0; 50 | 51 | ush_print_buf = NULL; 52 | ush_print_call_count = 0; 53 | } 54 | 55 | void tearDown(void) 56 | { 57 | 58 | } 59 | 60 | void ush_print_status(struct ush_object *self, ush_status_t status) 61 | { 62 | TEST_ASSERT_EQUAL(&ush, self); 63 | TEST_ASSERT_EQUAL(ush_print_status_status, status); 64 | 65 | ush_print_status_call_count++; 66 | } 67 | 68 | void ush_print(struct ush_object *self, char *buf) 69 | { 70 | TEST_ASSERT_EQUAL(&ush, self); 71 | TEST_ASSERT_EQUAL(ush_print_buf, buf); 72 | 73 | ush_print_call_count++; 74 | } 75 | 76 | void test_ush_buildin_cmd_pwd_callback_neg(void) 77 | { 78 | for (int i = 0; i < 6; i++) { 79 | setUp(); 80 | if (i != 1) { 81 | ush_print_status_status = USH_STATUS_ERROR_COMMAND_WRONG_ARGUMENTS; 82 | ush_buildin_cmd_pwd_callback(&ush, NULL, i, NULL); 83 | TEST_ASSERT_EQUAL(1, ush_print_status_call_count); 84 | TEST_ASSERT_EQUAL(0, ush_print_call_count); 85 | } 86 | } 87 | } 88 | 89 | void test_ush_buildin_cmd_pwd_callback_pos(void) 90 | { 91 | struct ush_node_object node; 92 | node.path = "test"; 93 | 94 | ush.current_node = &node; 95 | char *argv[2] = {0}; 96 | 97 | ush_print_buf = "test"; 98 | ush_buildin_cmd_pwd_callback(&ush, NULL, 1, argv); 99 | TEST_ASSERT_EQUAL(1, ush_print_call_count); 100 | } 101 | 102 | int main(int argc, char *argv[]) 103 | { 104 | (void)argc; 105 | (void)argv; 106 | 107 | UNITY_BEGIN(); 108 | 109 | RUN_TEST(test_ush_buildin_cmd_pwd_callback_neg); 110 | RUN_TEST(test_ush_buildin_cmd_pwd_callback_pos); 111 | 112 | return UNITY_END(); 113 | } 114 | -------------------------------------------------------------------------------- /tests/unit_tests/test_unit_read.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include "inc/ush_internal.h" 31 | 32 | int g_assert_call_count; 33 | 34 | struct ush_object ush; 35 | 36 | int ush_read_start_call_count; 37 | int ush_read_char_call_count; 38 | int ush_read_char_buffer_call_count; 39 | bool ush_read_char_return_val; 40 | bool ush_read_char_buffer_return_val; 41 | 42 | void setUp(void) 43 | { 44 | memset((uint8_t*)&ush, 0, sizeof(ush)); 45 | 46 | ush_read_start_call_count = 0; 47 | ush_read_char_call_count = 0; 48 | 49 | ush_read_char_return_val = false; 50 | } 51 | 52 | void tearDown(void) 53 | { 54 | 55 | } 56 | 57 | void ush_read_start(struct ush_object *self) 58 | { 59 | TEST_ASSERT_EQUAL(&ush, self); 60 | 61 | ush_read_start_call_count++; 62 | } 63 | 64 | bool ush_read_char_buffer(struct ush_object *self) 65 | { 66 | TEST_ASSERT_EQUAL(&ush, self); 67 | 68 | ush_read_char_buffer_call_count++; 69 | 70 | return ush_read_char_buffer_return_val; 71 | } 72 | 73 | bool ush_read_char(struct ush_object *self) 74 | { 75 | TEST_ASSERT_EQUAL(&ush, self); 76 | 77 | ush_read_char_call_count++; 78 | 79 | return ush_read_char_return_val; 80 | } 81 | 82 | void test_ush_read_service_state(void) 83 | { 84 | for (int i = 0; i < USH_STATE__TOTAL_NUM; i++) { 85 | setUp(); 86 | 87 | ush.state = (ush_state_t)i; 88 | bool read; 89 | 90 | switch (ush.state) { 91 | case USH_STATE_READ_PREPARE: 92 | TEST_ASSERT_TRUE(ush_read_service(&ush, &read)); 93 | TEST_ASSERT_EQUAL(1, ush_read_start_call_count); 94 | TEST_ASSERT_EQUAL(0, ush_read_char_call_count); 95 | break; 96 | case USH_STATE_READ_CHAR: 97 | TEST_ASSERT_TRUE(ush_read_service(&ush, &read)); 98 | TEST_ASSERT_EQUAL(0, ush_read_start_call_count); 99 | TEST_ASSERT_EQUAL(1, ush_read_char_call_count); 100 | break; 101 | case USH_STATE_READ_CHAR_BUFFER: 102 | TEST_ASSERT_TRUE(ush_read_service(&ush, &read)); 103 | TEST_ASSERT_EQUAL(0, ush_read_start_call_count); 104 | TEST_ASSERT_EQUAL(1, ush_read_char_buffer_call_count); 105 | break; 106 | default: 107 | TEST_ASSERT_FALSE(ush_read_service(&ush, &read)); 108 | TEST_ASSERT_EQUAL(0, ush_read_start_call_count); 109 | TEST_ASSERT_EQUAL(0, ush_read_char_call_count); 110 | break; 111 | } 112 | } 113 | } 114 | 115 | void test_ush_read_service_read(void) 116 | { 117 | bool read; 118 | 119 | ush.state = USH_STATE_READ_CHAR; 120 | 121 | read = false; 122 | ush_read_char_return_val = true; 123 | TEST_ASSERT_TRUE(ush_read_service(&ush, &read)); 124 | TEST_ASSERT_TRUE(read); 125 | 126 | read = true; 127 | ush_read_char_return_val = false; 128 | TEST_ASSERT_TRUE(ush_read_service(&ush, &read)); 129 | TEST_ASSERT_FALSE(read); 130 | } 131 | 132 | int main(int argc, char *argv[]) 133 | { 134 | (void)argc; 135 | (void)argv; 136 | 137 | UNITY_BEGIN(); 138 | 139 | RUN_TEST(test_ush_read_service_state); 140 | RUN_TEST(test_ush_read_service_read); 141 | 142 | return UNITY_END(); 143 | } 144 | -------------------------------------------------------------------------------- /tests/unit_tests/ush_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Marcin Borowicz 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef USH_CONFIG_H 26 | #define USH_CONFIG_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | #include 34 | 35 | #define USH_CONFIG_FILENAME_ALIGN_SPACE 16 36 | #define USH_CONFIG_CMD_XXD_COLUMNS 8 37 | 38 | #define USH_CONFIG_ENABLE_COMMAND_CAT 1 39 | #define USH_CONFIG_ENABLE_COMMAND_CD 1 40 | #define USH_CONFIG_ENABLE_COMMAND_ECHO 1 41 | #define USH_CONFIG_ENABLE_COMMAND_HELP 1 42 | #define USH_CONFIG_ENABLE_COMMAND_LS 1 43 | #define USH_CONFIG_ENABLE_COMMAND_PWD 1 44 | #define USH_CONFIG_ENABLE_COMMAND_XXD 1 45 | 46 | #define USH_CONFIG_ENABLE_FEATURE_COMMANDS 1 47 | #define USH_CONFIG_ENABLE_FEATURE_AUTOCOMPLETE 1 48 | #define USH_CONFIG_ENABLE_FEATURE_SHELL_STYLES 1 49 | #define USH_CONFIG_ENABLE_FEATURE_VERSION_PRINT 1 50 | 51 | #define USH_CONFIG_TRANSLATION_OK "ok" 52 | #define USH_CONFIG_TRANSLATION_ERROR "error" 53 | #define USH_CONFIG_TRANSLATION_DIRECTORY_NOT_FOUND "directory not found" 54 | #define USH_CONFIG_TRANSLATION_NESTED_DIRECTORIES_EXIST "nested directories exist" 55 | #define USH_CONFIG_TRANSLATION_CANNOT_FIND_PARENT_NODE "cannot find parent node" 56 | #define USH_CONFIG_TRANSLATION_DIRECTORY_ALREADY_MOUNTED "directory already mounted" 57 | #define USH_CONFIG_TRANSLATION_SYNTAX_ERROR "syntax error" 58 | #define USH_CONFIG_TRANSLATION_WRONG_ARGUMENTS "wrong arguments" 59 | #define USH_CONFIG_TRANSLATION_FILE_NOT_EXECUTABLE "file not executable" 60 | #define USH_CONFIG_TRANSLATION_FILE_NOT_WRITABLE "file not writable" 61 | #define USH_CONFIG_TRANSLATION_FILE_NOT_READABLE "file not readable" 62 | #define USH_CONFIG_TRANSLATION_NO_HELP_AVAILABLE "no help available" 63 | #define USH_CONFIG_TRANSLATION_FILE_NOT_FOUND "file not found" 64 | #define USH_CONFIG_TRANSLATION_READ_ONLY_FILE "read only file" 65 | 66 | extern int g_assert_call_count; 67 | 68 | #define USH_ASSERT(cond) { if (!(cond)) { g_assert_call_count++; } } 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* USH_CONFIG_H */ 75 | -------------------------------------------------------------------------------- /website/app.js: -------------------------------------------------------------------------------- 1 | // from: https://hackernoon.com/how-to-make-a-terminal-like-portfolio-website-for-yourself-27d7a7030004 2 | 3 | Typer.speed = 3; 4 | Typer.file = "microshell.html"; 5 | Typer.init(); 6 | 7 | var timer = setInterval("t();", 10); 8 | 9 | function t() { 10 | Typer.addText({"keyCode": 123748}); 11 | 12 | if (Typer.index > Typer.text.length) { 13 | clearInterval(timer); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /website/index.css: -------------------------------------------------------------------------------- 1 | /* from: https://hackernoon.com/how-to-make-a-terminal-like-portfolio-website-for-yourself-27d7a7030004 */ 2 | 3 | body { 4 | background-color: #000 5 | } 6 | 7 | #console { 8 | font-family: courier, monospace; 9 | color: #fff; 10 | max-width: 750px; 11 | margin-left: auto; 12 | margin-right: auto; 13 | margin-top: 40px; 14 | font-size: 14px; 15 | } 16 | 17 | a { 18 | color: #0cd; 19 | text-decoration: underline; 20 | } 21 | 22 | #a { 23 | color: #0f0; 24 | } 25 | 26 | #c { 27 | color: #0cd; 28 | } 29 | 30 | #b { 31 | color: #ff0096; 32 | } 33 | 34 | #u { 35 | font-weight: bold; 36 | } 37 | 38 | #k { 39 | animation: change 1s; 40 | } 41 | 42 | #op { 43 | color: #888888 44 | } 45 | 46 | @keyframes change { 47 | 0% { color: #0f0; } 48 | 50% { color: #0f0; } 49 | 99% { color: black; } 50 | } 51 | -------------------------------------------------------------------------------- /website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | microshell.pl 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /website/microshell.html: -------------------------------------------------------------------------------- 1 | marcinbor85@microshell.pl:~$ cd microshell/website 2 | marcinbor85@microshell.pl:~$ cat description.txt 3 | 4 | Microshell 5 | 6 | This is not yet another simple Command Line Interface. 7 | It's quite complex and powerfull compared to other available bare-metal CLI. 8 | At the same time it is very light, flexible and powerfull. 9 | It's ready to be embedded in any commercial product. 10 | 11 | What are the advantages? 12 | - names autocompletation (do You like a TAB-functionality on You favorite bash shell?) 13 | - no dynamic allocations (no memory leaks - no problem) 14 | - hardware independent (works just as well on AVR, PIC, STM32, ESP32 as it on x86 or RPI) 15 | - rich set of examples (available in the Arduino Library Manager) 16 | - pure C source code (works on rich set of compilers) 17 | - backspace key feature (simply works) 18 | - compatible vith VT100 standard (works out of the box with default putty configuration) 19 | - easy to extend (adding more "weird" features it has never been easier) 20 | - buildin commands (must-have, basic support of LS, CAT, PWD, HELP, XXD, ECHO) 21 | - scalable (configuration allows You to exclude unnecessary modules from building) 22 | - translation-ready (do You want Hindi translation? no problem!) 23 | - no internal buffers (support unlimited data stream lengths) 24 | - no static variables (possibility to use multiple independent shells in single system) 25 | - object oriented architecture (pointers attack!) 26 | - support root tree with static virtual files with callbacks (full customization) 27 | - extremely simple to integrate (only 1 simple interface with IO operations) 28 | - asynchronous architecture (static callbacks is not a problem) 29 | - non-blocking api (You just need to call one non-blocking function on main loop) 30 | - unit and functional tests (for greater certainty that nothing will break down) 31 | 32 | Want to try it? 33 | You can do it in Your favorite PC web browser. Demo does not support mobile browsers yet. 34 | There is a live >> DEMO << presenting the possibilities of the Microshell library. 35 | Have fun and enjoy! There are some hidden-features, let's find a rabbit! 36 | 37 | Free source code is available on my Github profile. 38 | 39 | What next? 40 | There are some ideas for future development: 41 | - session management with authorization 42 | - support dynamic file systems 43 | - memory security improvements 44 | - lookup global paths 45 | - scripts support 46 | 47 | If You want to contribute this project - excellent! Fork it, make bugs, and send a PR :) 48 | If You want to support me in developing this project - please donate. 49 | In case of any question, feel free to send my an email. 50 | 51 | Cheers! 52 | -------------------------------------------------------------------------------- /website/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcknly/microshell/2aae81658e710c3f1b13c78036ee6719b2ee172b/website/screen.png -------------------------------------------------------------------------------- /website/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcknly/microshell/2aae81658e710c3f1b13c78036ee6719b2ee172b/website/social.png -------------------------------------------------------------------------------- /website/typer.js: -------------------------------------------------------------------------------- 1 | // from: https://hackernoon.com/how-to-make-a-terminal-like-portfolio-website-for-yourself-27d7a7030004 2 | 3 | var Typer = { 4 | text: "", 5 | accessCountimer:null, 6 | index: 0, 7 | speed: 2, 8 | file: "", 9 | accessCount: 0, 10 | deniedCount: 0, 11 | init: function() { 12 | accessCountimer = setInterval( 13 | function() { 14 | Typer.updLstChr(); 15 | }, 16 | 500 17 | ); 18 | $.get(Typer.file, function(data) { 19 | Typer.text = data; 20 | Typer.text = Typer.text.slice(0, Typer.text.length - 1); 21 | }); 22 | }, 23 | 24 | content: function() { 25 | return $("#console").html(); 26 | }, 27 | 28 | write: function(str) { 29 | $("#console").append(str); 30 | return false; 31 | }, 32 | 33 | addText: function(key) { 34 | 35 | if (key.keyCode == 18) { 36 | Typer.accessCount++; 37 | 38 | if (Typer.accessCount >= 3) 39 | Typer.makeAccess(); 40 | 41 | } else if (key.keyCode == 20) { 42 | Typer.deniedCount++; 43 | 44 | if (Typer.deniedCount >= 3) 45 | Typer.makeDenied(); 46 | 47 | } else if (key.keyCode == 27) { 48 | Typer.hidepop(); 49 | 50 | } else if (Typer.text) { 51 | var cont = Typer.content(); 52 | 53 | if (cont.substring(cont.length - 1, cont.length) == "|") 54 | $("#console").html($("#console").html().substring(0, cont.length - 1)); 55 | if (key.keyCode != 8) { 56 | Typer.index += Typer.speed; 57 | } else { 58 | if (Typer.index > 0) 59 | Typer.index -= Typer.speed; 60 | } 61 | 62 | var text = Typer.text.substring(0,Typer.index); 63 | var rtn = new RegExp("\n", "g"); 64 | 65 | $("#console").html(text.replace(rtn, "
")); 66 | window.scrollBy(0,50); 67 | } 68 | 69 | if (key.preventDefault && key.keyCode != 122) 70 | key.preventDefault() 71 | 72 | if(key.keyCode != 122) 73 | key.returnValue = false; 74 | 75 | }, 76 | 77 | updLstChr: function(){ 78 | var cont = this.content(); 79 | 80 | if (cont.substring(cont.length - 1,cont.length) == "|") { 81 | $("#console").html($("#console").html().substring(0, cont.length - 1)); 82 | } else { 83 | this.write("|"); 84 | } 85 | } 86 | } 87 | --------------------------------------------------------------------------------