| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| #include "os/mynewt.h" |
| #include "console/console.h" |
| #include "shell/shell.h" |
| #include "shell_priv.h" |
| |
| #define SHELL_PROMPT "shell" |
| |
| static struct shell_module shell_modules[MYNEWT_VAL(SHELL_MAX_MODULES)]; |
| static size_t num_of_shell_entities; |
| |
| static const char *prompt; |
| static int default_module = -1; |
| |
| static shell_cmd_func_t app_cmd_handler; |
| static shell_prompt_function_t app_prompt_handler; |
| |
| /* Shared queue for shell events to be processed */ |
| static struct os_eventq *shell_evq; |
| /* Queue for available shell events */ |
| static struct os_event shell_console_ev[MYNEWT_VAL(SHELL_MAX_CMD_QUEUED)]; |
| static struct console_input buf[MYNEWT_VAL(SHELL_MAX_CMD_QUEUED)]; |
| |
| void |
| shell_evq_set(struct os_eventq *evq) |
| { |
| shell_evq = evq; |
| console_line_queue_set(shell_evq); |
| } |
| |
| static const char * |
| get_prompt(void) |
| { |
| const char *str; |
| |
| if (app_prompt_handler) { |
| |
| str = app_prompt_handler(); |
| if (str) { |
| return str; |
| } |
| } |
| |
| if (default_module != -1) { |
| return shell_modules[default_module].name; |
| } |
| |
| return prompt; |
| } |
| |
| static void |
| print_prompt(void) |
| { |
| console_printf("%s%s", get_prompt(), MYNEWT_VAL(SHELL_PROMPT_SUFFIX)); |
| } |
| |
| static size_t |
| line2argv(char *str, char *argv[], size_t size) |
| { |
| size_t argc = 0; |
| |
| if (!strlen(str)) { |
| return 0; |
| } |
| |
| while (*str && *str == ' ') { |
| str++; |
| } |
| |
| if (!*str) { |
| return 0; |
| } |
| |
| argv[argc++] = str; |
| |
| while ((str = strchr(str, ' '))) { |
| *str++ = '\0'; |
| |
| while (*str && *str == ' ') { |
| str++; |
| } |
| |
| if (!*str) { |
| break; |
| } |
| |
| argv[argc++] = str; |
| |
| if (argc == size) { |
| console_printf("Too many parameters (max %zu)\n", size - 1); |
| return 0; |
| } |
| } |
| |
| /* keep it POSIX style where argv[argc] is required to be NULL */ |
| argv[argc] = NULL; |
| |
| return argc; |
| } |
| |
| static int |
| get_destination_module(const char *module_str, int len) |
| { |
| int i; |
| |
| for (i = 0; i < num_of_shell_entities; i++) { |
| if (len < 0) { |
| if (!strcmp(module_str, shell_modules[i].name)) { |
| return i; |
| } |
| } else { |
| if (!strncmp(module_str, shell_modules[i].name, len)) { |
| return i; |
| } |
| } |
| } |
| |
| return -1; |
| } |
| |
| /* For a specific command: argv[0] = module name, argv[1] = command name |
| * If a default module was selected: argv[0] = command name |
| */ |
| static const char * |
| get_command_and_module(char *argv[], int *module) |
| { |
| *module = -1; |
| |
| if (!argv[0]) { |
| console_printf("Unrecognized command\n"); |
| return NULL; |
| } |
| |
| if (default_module == -1) { |
| if (!argv[1] || argv[1][0] == '\0') { |
| console_printf("Unrecognized command: %s\n", argv[0]); |
| return NULL; |
| } |
| |
| *module = get_destination_module(argv[0], -1); |
| if (*module == -1) { |
| console_printf("Illegal module %s\n", argv[0]); |
| return NULL; |
| } |
| |
| return argv[1]; |
| } |
| |
| *module = default_module; |
| return argv[0]; |
| } |
| |
| static void |
| print_command_params(const int module, const int command) |
| { |
| const struct shell_module *shell_module = &shell_modules[module]; |
| const struct shell_cmd *shell_cmd = &shell_module->commands[command]; |
| int i; |
| |
| if (!(shell_cmd->help && shell_cmd->help->params)) { |
| return; |
| } |
| |
| for (i = 0; shell_cmd->help->params[i].param_name; i++) { |
| console_printf("%-30s%s\n", shell_cmd->help->params[i].param_name, |
| shell_cmd->help->params[i].help); |
| } |
| } |
| |
| static int |
| show_cmd_help(char *argv[]) |
| { |
| const char *command = NULL; |
| int module = -1; |
| const struct shell_module *shell_module = NULL; |
| const struct shell_cmd *cmd; |
| int i; |
| |
| command = get_command_and_module(argv, &module); |
| if ((module == -1) || (command == NULL)) { |
| return 0; |
| } |
| |
| shell_module = &shell_modules[module]; |
| for (i = 0; shell_module->commands[i].sc_cmd; i++) { |
| cmd = &shell_module->commands[i]; |
| |
| if (!strcmp(command, cmd->sc_cmd)) { |
| |
| if (!cmd->help || (!cmd->help->summary && |
| !cmd->help->usage && |
| !cmd->help->params)) { |
| console_printf("(no help available)\n"); |
| return 0; |
| } |
| |
| if (cmd->help->summary) { |
| console_printf("Summary:\n"); |
| console_printf("%s\n", cmd->help->summary); |
| } |
| |
| if (cmd->help->usage) { |
| console_printf("Usage:\n"); |
| console_printf("%s\n", cmd->help->usage); |
| } |
| |
| if (cmd->help->params) { |
| console_printf("Parameters:\n"); |
| print_command_params(module, i); |
| } |
| |
| return 0; |
| } |
| } |
| |
| console_printf("Unrecognized command: %s\n", argv[0]); |
| return 0; |
| } |
| |
| static void |
| print_modules(void) |
| { |
| int module; |
| |
| for (module = 0; module < num_of_shell_entities; module++) { |
| console_printf("%s\n", shell_modules[module].name); |
| } |
| } |
| |
| static void |
| print_module_commands(const int module) |
| { |
| const struct shell_module *shell_module = &shell_modules[module]; |
| int i; |
| |
| console_printf("help\n"); |
| |
| for (i = 0; shell_module->commands[i].sc_cmd; i++) { |
| console_printf("%-30s", shell_module->commands[i].sc_cmd); |
| if (shell_module->commands[i].help && |
| shell_module->commands[i].help->summary) { |
| console_printf("%s", shell_module->commands[i].help->summary); |
| } |
| console_printf("\n"); |
| } |
| } |
| |
| static int |
| show_help(int argc, char *argv[]) |
| { |
| int module; |
| |
| /* help per command */ |
| if ((argc > 2) || ((default_module != -1) && (argc == 2))) { |
| return show_cmd_help(&argv[1]); |
| } |
| |
| /* help per module */ |
| if ((argc == 2) || ((default_module != -1) && (argc == 1))) { |
| if (default_module == -1) { |
| module = get_destination_module(argv[1], -1); |
| if (module == -1) { |
| console_printf("Illegal module %s\n", argv[1]); |
| return 0; |
| } |
| } else { |
| module = default_module; |
| } |
| |
| print_module_commands(module); |
| } else { /* help for all entities */ |
| console_printf("Available modules:\n"); |
| print_modules(); |
| console_printf("To select a module, enter 'select <module name>'.\n"); |
| } |
| |
| return 0; |
| } |
| |
| static int |
| set_default_module(const char *name) |
| { |
| int module; |
| |
| module = get_destination_module(name, -1); |
| |
| if (module == -1) { |
| console_printf("Illegal module %s, default is not changed\n", name); |
| return -1; |
| } |
| |
| default_module = module; |
| |
| return 0; |
| } |
| |
| static int |
| select_module(int argc, char *argv[]) |
| { |
| if (argc == 1) { |
| default_module = -1; |
| } else { |
| set_default_module(argv[1]); |
| } |
| |
| return 0; |
| } |
| |
| static shell_cmd_func_t |
| get_cb(int argc, char *argv[]) |
| { |
| const char *first_string = argv[0]; |
| int module = -1; |
| const struct shell_module *shell_module; |
| const char *command; |
| int i; |
| |
| if (!first_string || first_string[0] == '\0') { |
| console_printf("Illegal parameter\n"); |
| return NULL; |
| } |
| |
| if (!strcmp(first_string, "help")) { |
| return show_help; |
| } |
| |
| if (!strcmp(first_string, "select")) { |
| return select_module; |
| } |
| |
| if ((argc == 1) && (default_module == -1)) { |
| console_printf("Missing parameter\n"); |
| return NULL; |
| } |
| |
| command = get_command_and_module(argv, &module); |
| if ((module == -1) || (command == NULL)) { |
| return NULL; |
| } |
| |
| shell_module = &shell_modules[module]; |
| for (i = 0; shell_module->commands[i].sc_cmd; i++) { |
| if (!strcmp(command, shell_module->commands[i].sc_cmd)) { |
| return shell_module->commands[i].sc_cmd_func; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| static void |
| shell_process_command(char *line) |
| { |
| char *argv[MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1]; |
| shell_cmd_func_t sc_cmd_func; |
| size_t argc_offset = 0; |
| size_t argc; |
| |
| argc = line2argv(line, argv, MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1); |
| if (!argc) { |
| print_prompt(); |
| return; |
| } |
| |
| sc_cmd_func = get_cb(argc, argv); |
| if (!sc_cmd_func) { |
| if (app_cmd_handler != NULL) { |
| sc_cmd_func = app_cmd_handler; |
| } else { |
| console_printf("Unrecognized command: %s\n", argv[0]); |
| console_printf("Type 'help' for list of available commands\n"); |
| print_prompt(); |
| return; |
| } |
| } |
| |
| /* Allow invoking a cmd with module name as a prefix; a command should |
| * not know how it was invoked (with or without prefix) |
| */ |
| if (default_module == -1 && sc_cmd_func != select_module && |
| sc_cmd_func != show_help) { |
| argc_offset = 1; |
| } |
| |
| /* Execute callback with arguments */ |
| if (sc_cmd_func(argc - argc_offset, &argv[argc_offset]) < 0) { |
| show_cmd_help(argv); |
| } |
| |
| print_prompt(); |
| } |
| |
| #if MYNEWT_VAL(SHELL_NEWTMGR) |
| static void |
| shell_process_nlip_line(char *shell_line) |
| { |
| size_t shell_line_len; |
| |
| shell_line_len = strlen(shell_line); |
| if (shell_line_len > 2) { |
| if (shell_line[0] == SHELL_NLIP_PKT_START1 && |
| shell_line[1] == SHELL_NLIP_PKT_START2) { |
| shell_nlip_clear_pkt(); |
| shell_nlip_process(&shell_line[2], shell_line_len - 2); |
| } else if (shell_line[0] == SHELL_NLIP_DATA_START1 && |
| shell_line[1] == SHELL_NLIP_DATA_START2) { |
| shell_nlip_process(&shell_line[2], shell_line_len - 2); |
| } else { |
| shell_process_command(shell_line); |
| } |
| } else { |
| shell_process_command(shell_line); |
| } |
| } |
| #endif |
| |
| static void |
| shell(struct os_event *ev) |
| { |
| struct console_input *cmd; |
| |
| if (!ev) { |
| print_prompt(); |
| return; |
| } |
| |
| cmd = ev->ev_arg; |
| if (!cmd) { |
| print_prompt(); |
| return; |
| } |
| |
| #if MYNEWT_VAL(SHELL_NEWTMGR) |
| shell_process_nlip_line(cmd->line); |
| #else |
| shell_process_command(cmd->line); |
| #endif |
| |
| console_line_event_put(ev); |
| } |
| |
| #if MYNEWT_VAL(SHELL_COMPLETION) |
| static int |
| get_command_from_module(const char *command, int len, int module) |
| { |
| int i; |
| const struct shell_module *shell_module; |
| |
| shell_module = &shell_modules[module]; |
| for (i = 0; shell_module->commands[i].sc_cmd; i++) { |
| |
| if (strlen(shell_module->commands[i].sc_cmd) != len) { |
| continue; |
| } |
| |
| if (!strncmp(command, shell_module->commands[i].sc_cmd, len)) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| static int |
| get_token(char **cur, int *null_terminated) |
| { |
| char *str = *cur; |
| |
| *null_terminated = 0; |
| /* remove ' ' at the beginning */ |
| while (*str && *str == ' ') { |
| str++; |
| } |
| |
| if (*str == '\0') { |
| *null_terminated = 1; |
| return 0; |
| } |
| |
| *cur = str; |
| str = strchr(str, ' '); |
| |
| if (str == NULL) { |
| *null_terminated = 1; |
| return strlen(*cur); |
| } |
| |
| return str - *cur; |
| } |
| |
| static int |
| get_last_token(char **cur) |
| { |
| *cur = strrchr(*cur, ' '); |
| if (*cur == NULL) { |
| return 0; |
| } |
| (*cur)++; |
| return strlen(*cur); |
| } |
| |
| static void |
| complete_param(char *line, const char *param_prefix, |
| int param_len, int module_idx, int command_idx, |
| console_append_char_cb append_char) |
| { |
| const char *first_match = NULL; |
| int i, j, common_chars = -1; |
| const struct shell_cmd *command; |
| |
| command = &shell_modules[module_idx].commands[command_idx]; |
| |
| if (!(command->help && command->help->params)) { |
| return; |
| } |
| |
| for (i = 0; command->help->params[i].param_name; i++) { |
| |
| if (strncmp(param_prefix, |
| command->help->params[i].param_name, param_len)) { |
| continue; |
| } |
| |
| if (!first_match) { |
| first_match = command->help->params[i].param_name; |
| continue; |
| } |
| |
| /* more commands match, print first match */ |
| if (first_match && (common_chars < 0)) { |
| console_printf("\n"); |
| console_printf("%s\n", first_match); |
| common_chars = strlen(first_match); |
| } |
| |
| /* cut common part of matching names */ |
| for (j = 0; j < common_chars; j++) { |
| if (first_match[j] != command->help->params[i].param_name[j]) { |
| break; |
| } |
| } |
| |
| common_chars = j; |
| |
| console_printf("%s\n", command->help->params[i].param_name); |
| } |
| |
| /* no match, do nothing */ |
| if (!first_match) { |
| return; |
| } |
| |
| if (common_chars >= 0) { |
| /* multiple match, restore prompt */ |
| print_prompt(); |
| console_printf("%s", line); |
| } else { |
| common_chars = strlen(first_match); |
| } |
| |
| /* complete common part */ |
| for (i = param_len; i < common_chars; i++) { |
| if (!append_char(line, first_match[i])) { |
| return; |
| } |
| } |
| } |
| |
| static void |
| complete_command(char *line, char *command_prefix, |
| int command_len, int module_idx, |
| console_append_char_cb append_char) |
| { |
| const char *first_match = NULL; |
| int i, j, common_chars = -1, space = 0; |
| const struct shell_module *module; |
| |
| module = &shell_modules[module_idx]; |
| |
| for (i = 0; module->commands[i].sc_cmd; i++) { |
| if (strncmp(command_prefix, |
| module->commands[i].sc_cmd, command_len)) { |
| continue; |
| } |
| |
| if (!first_match) { |
| first_match = module->commands[i].sc_cmd; |
| continue; |
| } |
| |
| /* more commands match, print first match */ |
| if (first_match && (common_chars < 0)) { |
| console_printf("\n"); |
| console_printf("%s\n", first_match); |
| common_chars = strlen(first_match); |
| } |
| |
| /* cut common part of matching names */ |
| for (j = 0; j < common_chars; j++) { |
| if (first_match[j] != module->commands[i].sc_cmd[j]) { |
| break; |
| } |
| } |
| |
| common_chars = j; |
| |
| console_printf("%s\n", module->commands[i].sc_cmd); |
| } |
| |
| /* no match, do nothing */ |
| if (!first_match) { |
| return; |
| } |
| |
| if (common_chars >= 0) { |
| /* multiple match, restore prompt */ |
| print_prompt(); |
| console_printf("%s", line); |
| } else { |
| common_chars = strlen(first_match); |
| space = 1; |
| } |
| |
| /* complete common part */ |
| for (i = command_len; i < common_chars; i++) { |
| if (!append_char(line, first_match[i])) { |
| return; |
| } |
| } |
| |
| /* for convenience add space after command */ |
| if (space) { |
| append_char(line, ' '); |
| } |
| } |
| |
| static void |
| complete_module(char *line, char *module_prefix, |
| int module_len, console_append_char_cb append_char) |
| { |
| int i, j; |
| const char *first_match = NULL; |
| int common_chars = -1, space = 0; |
| |
| if (!module_len) { |
| console_printf("\n"); |
| for (i = 0; i < num_of_shell_entities; i++) { |
| console_printf("%s\n", shell_modules[i].name); |
| } |
| print_prompt(); |
| console_printf("%s", line); |
| return; |
| } |
| |
| for (i = 0; i < num_of_shell_entities; i++) { |
| |
| if (strncmp(module_prefix, |
| shell_modules[i].name, |
| module_len)) { |
| continue; |
| } |
| |
| if (!first_match) { |
| first_match = shell_modules[i].name; |
| continue; |
| } |
| |
| /* more commands match, print first match */ |
| if (first_match && (common_chars < 0)) { |
| console_printf("\n"); |
| console_printf("%s\n", first_match); |
| common_chars = strlen(first_match); |
| } |
| |
| /* cut common part of matching names */ |
| for (j = 0; j < common_chars; j++) { |
| if (first_match[j] != shell_modules[i].name[j]) { |
| break; |
| } |
| } |
| |
| common_chars = j; |
| |
| console_printf("%s\n", shell_modules[i].name); |
| } |
| |
| /* no match, do nothing */ |
| if (!first_match) { |
| return; |
| } |
| |
| if (common_chars >= 0) { |
| /* multiple match, restore prompt */ |
| print_prompt(); |
| console_printf("%s", line); |
| } else { |
| common_chars = strlen(first_match); |
| space = 1; |
| } |
| |
| /* complete common part */ |
| for (i = module_len; i < common_chars; i++) { |
| if (!append_char(line, first_match[i])) { |
| return; |
| } |
| } |
| |
| /* for convenience add space after command */ |
| if (space) { |
| append_char(line, ' '); |
| } |
| } |
| |
| static void |
| complete_select(char *line, char *cur, |
| int tok_len, console_append_char_cb append_char) |
| { |
| int null_terminated = 0; |
| |
| cur += tok_len + 1; |
| tok_len = get_token(&cur, &null_terminated); |
| if (tok_len == 0) { |
| if (default_module != -1) { |
| return; |
| } |
| console_printf("\n"); |
| print_modules(); |
| print_prompt(); |
| console_printf("%s", line); |
| return; |
| } |
| |
| if (null_terminated) { |
| if (default_module == -1) { |
| complete_module(line, cur, tok_len, append_char); |
| } |
| } |
| } |
| |
| static void |
| completion(char *line, console_append_char_cb append_char) |
| { |
| char *cur; |
| int tok_len; |
| int module, command; |
| int null_terminated = 0; |
| |
| /* |
| * line to completion is not ended by '\0' as the line that gets from |
| * os_eventq_get function |
| */ |
| if (!append_char(line, '\0')) { |
| return; |
| } |
| |
| cur = line; |
| tok_len = get_token(&cur, &null_terminated); |
| |
| /* empty token - print options */ |
| if (tok_len == 0) { |
| console_printf("\n"); |
| if (default_module == -1) { |
| print_modules(); |
| } else { |
| print_module_commands(default_module); |
| } |
| print_prompt(); |
| console_printf("%s", line); |
| return; |
| } |
| |
| /* token can be completed */ |
| if (null_terminated) { |
| if (default_module == -1) { |
| complete_module(line, cur, tok_len, append_char); |
| return; |
| } |
| complete_command(line, cur, tok_len, |
| default_module, append_char); |
| return; |
| } |
| |
| if (strncmp("select", cur, tok_len) == 0) { |
| complete_select(line, cur, tok_len, append_char); |
| return; |
| } |
| |
| if (default_module != -1) { |
| module = default_module; |
| } else { |
| module = get_destination_module(cur, tok_len); |
| |
| if (module == -1) { |
| return; |
| } |
| |
| cur += tok_len + 1; |
| tok_len = get_token(&cur, &null_terminated); |
| |
| if (tok_len == 0) { |
| console_printf("\n"); |
| print_module_commands(module); |
| print_prompt(); |
| console_printf("%s", line); |
| return; |
| } |
| |
| if (null_terminated) { |
| complete_command(line, cur, tok_len, |
| module, append_char); |
| return; |
| } |
| } |
| |
| command = get_command_from_module(cur, tok_len, module); |
| if (command == -1) { |
| return; |
| } |
| |
| cur += tok_len; |
| tok_len = get_last_token(&cur); |
| if (tok_len == 0) { |
| console_printf("\n"); |
| print_command_params(module, command); |
| print_prompt(); |
| console_printf("%s", line); |
| return; |
| } |
| complete_param(line, cur, tok_len, |
| module, command, append_char); |
| return; |
| } |
| #endif /* MYNEWT_VAL(SHELL_COMPLETION) */ |
| |
| void |
| shell_register_app_cmd_handler(shell_cmd_func_t handler) |
| { |
| app_cmd_handler = handler; |
| } |
| |
| void |
| shell_register_prompt_handler(shell_prompt_function_t handler) |
| { |
| app_prompt_handler = handler; |
| } |
| |
| void |
| shell_register_default_module(const char *name) |
| { |
| int result = set_default_module(name); |
| |
| if (result != -1) { |
| console_printf("\n"); |
| print_prompt(); |
| } |
| } |
| |
| static void |
| shell_avail_queue_init(void) |
| { |
| int i; |
| |
| for (i = 0; i < MYNEWT_VAL(SHELL_MAX_CMD_QUEUED); i++) { |
| shell_console_ev[i].ev_cb = shell; |
| shell_console_ev[i].ev_arg = &buf[i]; |
| console_line_event_put(&shell_console_ev[i]); |
| } |
| } |
| |
| int |
| shell_register(const char *module_name, const struct shell_cmd *commands) |
| { |
| if (num_of_shell_entities >= MYNEWT_VAL(SHELL_MAX_MODULES)) { |
| console_printf("Max number of modules reached\n"); |
| assert(0); |
| } |
| |
| shell_modules[num_of_shell_entities].name = module_name; |
| shell_modules[num_of_shell_entities].commands = commands; |
| ++num_of_shell_entities; |
| |
| return 0; |
| } |
| |
| #if MYNEWT_VAL(SHELL_COMPAT) |
| #define SHELL_COMPAT_MODULE_NAME "compat" |
| static struct shell_cmd compat_commands[MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS) + 1]; |
| static int num_compat_commands; |
| static int module_registered; |
| |
| int |
| shell_cmd_register(const struct shell_cmd *sc) |
| { |
| if (num_compat_commands >= MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS)) { |
| console_printf("Max number of compat commands reached\n"); |
| assert(0); |
| } |
| |
| if (!module_registered) { |
| shell_register(SHELL_COMPAT_MODULE_NAME, compat_commands); |
| set_default_module(SHELL_COMPAT_MODULE_NAME); |
| module_registered = 1; |
| } |
| |
| compat_commands[num_compat_commands].sc_cmd = sc->sc_cmd; |
| compat_commands[num_compat_commands].sc_cmd_func = sc->sc_cmd_func; |
| #if MYNEWT_VAL(SHELL_CMD_HELP) |
| compat_commands[num_compat_commands].help = sc->help; |
| #endif |
| ++num_compat_commands; |
| return 0; |
| } |
| #endif |
| |
| void |
| shell_init(void) |
| { |
| /* Ensure this function only gets called by sysinit. */ |
| SYSINIT_ASSERT_ACTIVE(); |
| |
| #if !MYNEWT_VAL(SHELL_TASK) |
| return; |
| #endif |
| |
| shell_avail_queue_init(); |
| shell_evq_set(os_eventq_dflt_get()); |
| |
| prompt = SHELL_PROMPT; |
| |
| #if MYNEWT_VAL(SHELL_NEWTMGR) |
| shell_nlip_init(); |
| #endif |
| |
| #if MYNEWT_VAL(SHELL_COMPLETION) |
| console_set_completion_cb(completion); |
| #endif |
| |
| #if MYNEWT_VAL(SHELL_OS_MODULE) |
| shell_os_register(); |
| #endif |
| #if MYNEWT_VAL(SHELL_PROMPT_MODULE) |
| shell_prompt_register(); |
| #endif |
| } |