1 /*
2  * Copyright (c) 2008-2009 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #ifndef __LIB_CONSOLE_H
24 #define __LIB_CONSOLE_H
25 
26 #include <stdbool.h>
27 #include <stddef.h>
28 #include <sys/types.h>
29 #include <compiler.h>
30 
31 /* command args */
32 typedef struct {
33     const char *str;
34     unsigned long u;
35     void *p;
36     long i;
37     bool b;
38 } cmd_args;
39 
40 typedef int (*console_cmd)(int argc, const cmd_args *argv);
41 
42 #define CMD_AVAIL_NORMAL (0x1 << 0)
43 #define CMD_AVAIL_PANIC  (0x1 << 1)
44 #define CMD_AVAIL_ALWAYS (CMD_AVAIL_NORMAL | CMD_AVAIL_PANIC)
45 
46 /* a block of commands to register */
47 typedef struct {
48     const char *cmd_str;
49     const char *help_str;
50     const console_cmd cmd_callback;
51     uint8_t availability_mask;
52 } cmd;
53 
54 typedef struct _cmd_block {
55     struct _cmd_block *next;
56     size_t count;
57     const cmd *list;
58 } cmd_block;
59 
60 /* register a static block of commands at init time */
61 #if WITH_LIB_CONSOLE
62 
63 /* enable the panic shell if we're being built */
64 #if !defined(ENABLE_PANIC_SHELL) && PLATFORM_SUPPORTS_PANIC_SHELL
65 #define ENABLE_PANIC_SHELL 1
66 #endif
67 
68 #define STATIC_COMMAND_START static const cmd _cmd_list[] = {
69 
70 #define STATIC_COMMAND_END(name) }; cmd_block _cmd_block_##name __ALIGNED(sizeof(void *)) __SECTION(".commands") = \
71     { NULL, sizeof(_cmd_list) / sizeof(_cmd_list[0]), _cmd_list }
72 
73 #define STATIC_COMMAND_START_NAMED(name) static const cmd _cmd_list_##name[] = {
74 
75 #define STATIC_COMMAND_END_NAMED(name) }; cmd_block _cmd_block_##name __ALIGNED(sizeof(void *)) __SECTION(".commands") = \
76     { NULL, sizeof(_cmd_list_##name) / sizeof(_cmd_list_##name[0]), _cmd_list_##name }
77 
78 #define STATIC_COMMAND(command_str, help_str, func) { command_str, help_str, func, CMD_AVAIL_NORMAL },
79 #define STATIC_COMMAND_MASKED(command_str, help_str, func, availability_mask) { command_str, help_str, func, availability_mask },
80 
81 #else
82 
83 /* no command blocks, so null them out */
84 #define STATIC_COMMAND_START
85 #define STATIC_COMMAND_END(name)
86 #define STATIC_COMMAND_START_NAMED(name)
87 #define STATIC_COMMAND_END_NAMED(name)
88 
89 #define STATIC_COMMAND(command_str, help_str, func)
90 
91 #endif
92 
93 #define COMMAND_BLOCK_INIT_ITEM(cmd_block_ptr, cmd_ptr) {(cmd_block_ptr)->next = NULL; (cmd_block_ptr)->count = 1; (cmd_block_ptr)->list = cmd_ptr;}
94 
95 /* external api */
96 int console_init(void);
97 void console_start(void);
98 void console_register_commands(cmd_block *block);
99 int console_run_script(const char *string);
100 int console_run_script_locked(const char *string); // special case from inside a command
101 console_cmd console_get_command_handler(const char *command);
102 void console_abort_script(void);
103 
104 #if ENABLE_PANIC_SHELL
105 /* panic shell api */
106 void panic_shell_start(void);
107 #endif
108 
109 extern int lastresult;
110 
111 #endif
112