[lib][console] move the state of the console into an object
This will allow in the future multiple instances of it to be active at at a time. Place the current console in a new TLS slot per thread so threads created as a side effect of console commands can properly run commands.
This commit is contained in:
@@ -10,7 +10,13 @@
|
|||||||
#include <lib/console.h>
|
#include <lib/console.h>
|
||||||
|
|
||||||
static void shell_entry(const struct app_descriptor *app, void *args) {
|
static void shell_entry(const struct app_descriptor *app, void *args) {
|
||||||
console_start();
|
console_t *con = console_create(true);
|
||||||
|
if (!con)
|
||||||
|
return;
|
||||||
|
|
||||||
|
console_start(con);
|
||||||
|
|
||||||
|
// TODO: destroy console and free resources
|
||||||
}
|
}
|
||||||
|
|
||||||
APP_START(shell)
|
APP_START(shell)
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ typedef int (*thread_start_routine)(void *arg);
|
|||||||
|
|
||||||
/* thread local storage */
|
/* thread local storage */
|
||||||
enum thread_tls_list {
|
enum thread_tls_list {
|
||||||
|
#ifdef WITH_LIB_CONSOLE
|
||||||
|
TLS_ENTRY_CONSOLE, // current console
|
||||||
|
#endif
|
||||||
#ifdef WITH_LIB_UTHREAD
|
#ifdef WITH_LIB_UTHREAD
|
||||||
TLS_ENTRY_UTHREAD,
|
TLS_ENTRY_UTHREAD,
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ thread_t *thread_create_etc(thread_t *t, const char *name, thread_start_routine
|
|||||||
/* save whether or not we need to free the thread struct and/or stack */
|
/* save whether or not we need to free the thread struct and/or stack */
|
||||||
t->flags = flags;
|
t->flags = flags;
|
||||||
|
|
||||||
/* inheirit thread local storage from the parent */
|
/* inherit thread local storage from the parent */
|
||||||
thread_t *current_thread = get_current_thread();
|
thread_t *current_thread = get_current_thread();
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i < MAX_TLS_ENTRY; i++)
|
for (i=0; i < MAX_TLS_ENTRY; i++)
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include <lib/env.h>
|
#include <lib/env.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LOCAL_TRACE 0
|
||||||
|
|
||||||
// Whether to enable command line history. Uses a nonzero
|
// Whether to enable command line history. Uses a nonzero
|
||||||
// amount of memory, probably shouldn't enable for memory constrained devices.
|
// amount of memory, probably shouldn't enable for memory constrained devices.
|
||||||
#ifndef CONSOLE_ENABLE_HISTORY
|
#ifndef CONSOLE_ENABLE_HISTORY
|
||||||
@@ -42,28 +44,34 @@
|
|||||||
|
|
||||||
#define WHITESPACE " \t"
|
#define WHITESPACE " \t"
|
||||||
|
|
||||||
/* debug buffer */
|
// a single console instance
|
||||||
static char *debug_buffer;
|
typedef struct console {
|
||||||
|
/* command processor state */
|
||||||
|
mutex_t lock;
|
||||||
|
int lastresult;
|
||||||
|
bool abort_script;
|
||||||
|
|
||||||
/* echo commands? */
|
/* debug buffer */
|
||||||
static bool echo = true;
|
char *debug_buffer;
|
||||||
|
|
||||||
/* command processor state */
|
/* echo commands? */
|
||||||
static mutex_t command_lock = MUTEX_INITIAL_VALUE(command_lock);
|
bool echo; // = true;
|
||||||
int lastresult;
|
|
||||||
static bool abort_script;
|
|
||||||
|
|
||||||
#if CONSOLE_ENABLE_HISTORY
|
#if CONSOLE_ENABLE_HISTORY
|
||||||
/* command history stuff */
|
/* command history stuff */
|
||||||
#define HISTORY_LEN 16
|
#define HISTORY_LEN 16
|
||||||
static char history[HISTORY_LEN * LINE_LEN];
|
char history[HISTORY_LEN * LINE_LEN];
|
||||||
static uint history_next = 0;
|
size_t history_next; // = 0;
|
||||||
|
#endif // CONSOLE_ENABLE_HISTORY
|
||||||
|
} console_t;
|
||||||
|
|
||||||
static void add_history(const char *line);
|
#if CONSOLE_ENABLE_HISTORY
|
||||||
static uint start_history_cursor(void);
|
/* command history routines */
|
||||||
static const char *next_history(uint *cursor);
|
static void add_history(console_t *con, const char *line);
|
||||||
static const char *prev_history(uint *cursor);
|
static uint start_history_cursor(console_t *con);
|
||||||
static void dump_history(void);
|
static const char *next_history(console_t *con, uint *cursor);
|
||||||
|
static const char *prev_history(console_t *con, uint *cursor);
|
||||||
|
static void dump_history(console_t *con);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* a linear array of statically defined command blocks,
|
/* a linear array of statically defined command blocks,
|
||||||
@@ -96,16 +104,16 @@ STATIC_COMMAND("history", "command history", &cmd_history)
|
|||||||
STATIC_COMMAND("repeat", "repeats command multiple times", &cmd_repeat)
|
STATIC_COMMAND("repeat", "repeats command multiple times", &cmd_repeat)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
STATIC_COMMAND_END(help);
|
STATIC_COMMAND_END(console);
|
||||||
|
|
||||||
#if CONSOLE_ENABLE_HISTORY
|
#if CONSOLE_ENABLE_HISTORY
|
||||||
static int cmd_history(int argc, const console_cmd_args *argv) {
|
static int cmd_history(int argc, const console_cmd_args *argv) {
|
||||||
dump_history();
|
dump_history(console_get_current());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *history_line(uint line) {
|
static inline char *history_line(console_t *con, uint line) {
|
||||||
return history + line * LINE_LEN;
|
return con->history + line * LINE_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint ptrnext(uint ptr) {
|
static inline uint ptrnext(uint ptr) {
|
||||||
@@ -116,57 +124,57 @@ static inline uint ptrprev(uint ptr) {
|
|||||||
return (ptr - 1) % HISTORY_LEN;
|
return (ptr - 1) % HISTORY_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_history(void) {
|
static void dump_history(console_t *con) {
|
||||||
printf("command history:\n");
|
printf("command history:\n");
|
||||||
uint ptr = ptrprev(history_next);
|
uint ptr = ptrprev(con->history_next);
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i < HISTORY_LEN; i++) {
|
for (i=0; i < HISTORY_LEN; i++) {
|
||||||
if (history_line(ptr)[0] != 0)
|
if (history_line(con, ptr)[0] != 0)
|
||||||
printf("\t%s\n", history_line(ptr));
|
printf("\t%s\n", history_line(con, ptr));
|
||||||
ptr = ptrprev(ptr);
|
ptr = ptrprev(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_history(const char *line) {
|
static void add_history(console_t *con, const char *line) {
|
||||||
// reject some stuff
|
// reject some stuff
|
||||||
if (line[0] == 0)
|
if (line[0] == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint last = ptrprev(history_next);
|
size_t last = ptrprev(con->history_next);
|
||||||
if (strcmp(line, history_line(last)) == 0)
|
if (strcmp(line, history_line(con, last)) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
strlcpy(history_line(history_next), line, LINE_LEN);
|
strlcpy(history_line(con, con->history_next), line, LINE_LEN);
|
||||||
history_next = ptrnext(history_next);
|
con->history_next = ptrnext(con->history_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint start_history_cursor(void) {
|
static uint start_history_cursor(console_t *con) {
|
||||||
return ptrprev(history_next);
|
return ptrprev(con->history_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *next_history(uint *cursor) {
|
static const char *next_history(console_t *con, uint *cursor) {
|
||||||
uint i = ptrnext(*cursor);
|
uint i = ptrnext(*cursor);
|
||||||
|
|
||||||
if (i == history_next)
|
if (i == con->history_next)
|
||||||
return ""; // can't let the cursor hit the head
|
return ""; // can't let the cursor hit the head
|
||||||
|
|
||||||
*cursor = i;
|
*cursor = i;
|
||||||
return history_line(i);
|
return history_line(con, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *prev_history(uint *cursor) {
|
static const char *prev_history(console_t *con, uint *cursor) {
|
||||||
uint i;
|
uint i;
|
||||||
const char *str = history_line(*cursor);
|
const char *str = history_line(con, *cursor);
|
||||||
|
|
||||||
/* if we are already at head, stop here */
|
/* if we are already at head, stop here */
|
||||||
if (*cursor == history_next)
|
if (*cursor == con->history_next)
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
/* back up one */
|
/* back up one */
|
||||||
i = ptrprev(*cursor);
|
i = ptrprev(*cursor);
|
||||||
|
|
||||||
/* if the next one is gonna be null */
|
/* if the next one is gonna be null */
|
||||||
if (history_line(i)[0] == '\0')
|
if (history_line(con, i)[0] == '\0')
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
/* update the cursor */
|
/* update the cursor */
|
||||||
@@ -175,6 +183,20 @@ static const char *prev_history(uint *cursor) {
|
|||||||
}
|
}
|
||||||
#endif // CONSOLE_ENABLE_HISTORY
|
#endif // CONSOLE_ENABLE_HISTORY
|
||||||
|
|
||||||
|
console_t *console_get_current(void) {
|
||||||
|
console_t *con = (console_t *)tls_get(TLS_ENTRY_CONSOLE);
|
||||||
|
DEBUG_ASSERT(con);
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
|
console_t *console_set_current(console_t *con) {
|
||||||
|
console_t *old = (console_t *)tls_get(TLS_ENTRY_CONSOLE);
|
||||||
|
tls_set(TLS_ENTRY_CONSOLE, (uintptr_t)con);
|
||||||
|
LTRACEF("setting new %p, old %p\n", con, old);
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
#if CONSOLE_ENABLE_REPEAT
|
#if CONSOLE_ENABLE_REPEAT
|
||||||
static int cmd_repeat(int argc, const console_cmd_args *argv) {
|
static int cmd_repeat(int argc, const console_cmd_args *argv) {
|
||||||
if (argc < 4) goto usage;
|
if (argc < 4) goto usage;
|
||||||
@@ -203,7 +225,7 @@ static int cmd_repeat(int argc, const console_cmd_args *argv) {
|
|||||||
|
|
||||||
for (int i = 0; i < times; ++i) {
|
for (int i = 0; i < times; ++i) {
|
||||||
printf("[%d/%d]\n", i + 1, times);
|
printf("[%d/%d]\n", i + 1, times);
|
||||||
int result = console_run_script_locked(line);
|
int result = console_run_script_locked(console_get_current(), line);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
printf("terminating repeat loop, command exited with status %d\n",
|
printf("terminating repeat loop, command exited with status %d\n",
|
||||||
result);
|
result);
|
||||||
@@ -238,11 +260,12 @@ static const console_cmd *match_command(const char *command, const uint8_t avail
|
|||||||
static int read_debug_line(const char **outbuffer, void *cookie) {
|
static int read_debug_line(const char **outbuffer, void *cookie) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int escape_level = 0;
|
int escape_level = 0;
|
||||||
|
console_t *con = (console_t *)cookie;
|
||||||
#if CONSOLE_ENABLE_HISTORY
|
#if CONSOLE_ENABLE_HISTORY
|
||||||
uint history_cursor = start_history_cursor();
|
uint history_cursor = start_history_cursor(con);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *buffer = debug_buffer;
|
char *buffer = con->debug_buffer;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* loop until we get a char */
|
/* loop until we get a char */
|
||||||
@@ -256,7 +279,7 @@ static int read_debug_line(const char **outbuffer, void *cookie) {
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\n':
|
case '\n':
|
||||||
if (echo)
|
if (con->echo)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -274,7 +297,7 @@ static int read_debug_line(const char **outbuffer, void *cookie) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
buffer[pos++] = c;
|
buffer[pos++] = c;
|
||||||
if (echo)
|
if (con->echo)
|
||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
} else if (escape_level == 1) {
|
} else if (escape_level == 1) {
|
||||||
@@ -289,13 +312,13 @@ static int read_debug_line(const char **outbuffer, void *cookie) {
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case 67: // right arrow
|
case 67: // right arrow
|
||||||
buffer[pos++] = ' ';
|
buffer[pos++] = ' ';
|
||||||
if (echo)
|
if (con->echo)
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
break;
|
break;
|
||||||
case 68: // left arrow
|
case 68: // left arrow
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
pos--;
|
pos--;
|
||||||
if (echo) {
|
if (con->echo) {
|
||||||
fputs("\b \b", stdout); // wipe out a character
|
fputs("\b \b", stdout); // wipe out a character
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,17 +329,17 @@ static int read_debug_line(const char **outbuffer, void *cookie) {
|
|||||||
// wipe out the current line
|
// wipe out the current line
|
||||||
while (pos > 0) {
|
while (pos > 0) {
|
||||||
pos--;
|
pos--;
|
||||||
if (echo) {
|
if (con->echo) {
|
||||||
fputs("\b \b", stdout); // wipe out a character
|
fputs("\b \b", stdout); // wipe out a character
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == 65)
|
if (c == 65)
|
||||||
strlcpy(buffer, prev_history(&history_cursor), LINE_LEN);
|
strlcpy(buffer, prev_history(con, &history_cursor), LINE_LEN);
|
||||||
else
|
else
|
||||||
strlcpy(buffer, next_history(&history_cursor), LINE_LEN);
|
strlcpy(buffer, next_history(con, &history_cursor), LINE_LEN);
|
||||||
pos = strlen(buffer);
|
pos = strlen(buffer);
|
||||||
if (echo)
|
if (con->echo)
|
||||||
fputs(buffer, stdout);
|
fputs(buffer, stdout);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -342,7 +365,7 @@ done:
|
|||||||
|
|
||||||
#if CONSOLE_ENABLE_HISTORY
|
#if CONSOLE_ENABLE_HISTORY
|
||||||
// add to history
|
// add to history
|
||||||
add_history(buffer);
|
add_history(con, buffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// return a pointer to our buffer
|
// return a pointer to our buffer
|
||||||
@@ -543,7 +566,7 @@ static void convert_args(int argc, console_cmd_args *argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t command_loop(int (*get_line)(const char **, void *), void *get_line_cookie, bool showprompt, bool locked) {
|
static status_t command_loop(console_t *con, int (*get_line)(const char **, void *), void *get_line_cookie, bool showprompt, bool locked) {
|
||||||
bool exit;
|
bool exit;
|
||||||
#if WITH_LIB_ENV
|
#if WITH_LIB_ENV
|
||||||
bool report_result;
|
bool report_result;
|
||||||
@@ -610,34 +633,34 @@ static status_t command_loop(int (*get_line)(const char **, void *), void *get_l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!locked)
|
if (!locked)
|
||||||
mutex_acquire(&command_lock);
|
mutex_acquire(&con->lock);
|
||||||
|
|
||||||
abort_script = false;
|
con->abort_script = false;
|
||||||
lastresult = command->cmd_callback(argc, args);
|
con->lastresult = command->cmd_callback(argc, args);
|
||||||
|
|
||||||
#if WITH_LIB_ENV
|
#if WITH_LIB_ENV
|
||||||
bool report_result;
|
bool report_result;
|
||||||
env_get_bool("reportresult", &report_result, false);
|
env_get_bool("reportresult", &report_result, false);
|
||||||
if (report_result) {
|
if (report_result) {
|
||||||
if (lastresult < 0)
|
if (con->lastresult < 0)
|
||||||
printf("FAIL %d\n", lastresult);
|
printf("FAIL %d\n", con->lastresult);
|
||||||
else
|
else
|
||||||
printf("PASS %d\n", lastresult);
|
printf("PASS %d\n", con->lastresult);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_LIB_ENV
|
#if WITH_LIB_ENV
|
||||||
// stuff the result in an environment var
|
// stuff the result in an environment var
|
||||||
env_set_int("?", lastresult, true);
|
env_set_int("?", con->lastresult, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// someone must have aborted the current script
|
// someone must have aborted the current script
|
||||||
if (abort_script)
|
if (con->abort_script)
|
||||||
exit = true;
|
exit = true;
|
||||||
abort_script = false;
|
con->abort_script = false;
|
||||||
|
|
||||||
if (!locked)
|
if (!locked)
|
||||||
mutex_release(&command_lock);
|
mutex_release(&con->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(outbuf);
|
free(outbuf);
|
||||||
@@ -655,22 +678,39 @@ no_mem_error:
|
|||||||
return ERR_NO_MEMORY;
|
return ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_abort_script(void) {
|
void console_abort_script(console_t *con) {
|
||||||
abort_script = true;
|
if (!con) {
|
||||||
|
con = console_get_current();
|
||||||
|
}
|
||||||
|
con->abort_script = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_start(void) {
|
console_t *console_create(bool with_history) {
|
||||||
debug_buffer = malloc(LINE_LEN);
|
console_t *con = calloc(1, sizeof(console_t));
|
||||||
|
if (!con) {
|
||||||
|
dprintf(INFO, "error allocating console object\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
mutex_init(&con->lock);
|
||||||
|
con->echo = true;
|
||||||
|
con->debug_buffer = malloc(LINE_LEN);
|
||||||
|
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_start(console_t *con) {
|
||||||
dprintf(INFO, "entering main console loop\n");
|
dprintf(INFO, "entering main console loop\n");
|
||||||
|
|
||||||
|
console_set_current(con);
|
||||||
|
|
||||||
while (command_loop(&read_debug_line, NULL, true, false) == NO_ERROR)
|
while (command_loop(con, &read_debug_line, con, true, false) == NO_ERROR)
|
||||||
;
|
;
|
||||||
|
|
||||||
dprintf(INFO, "exiting main console loop\n");
|
console_set_current(NULL);
|
||||||
|
|
||||||
free (debug_buffer);
|
dprintf(INFO, "exiting main console loop\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct line_read_struct {
|
struct line_read_struct {
|
||||||
@@ -706,7 +746,7 @@ static int fetch_next_line(const char **buffer, void *cookie) {
|
|||||||
return bufpos;
|
return bufpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int console_run_script_etc(const char *string, bool locked) {
|
static int console_run_script_etc(console_t *con, const char *string, bool locked) {
|
||||||
struct line_read_struct lineread;
|
struct line_read_struct lineread;
|
||||||
|
|
||||||
lineread.string = string;
|
lineread.string = string;
|
||||||
@@ -714,19 +754,25 @@ static int console_run_script_etc(const char *string, bool locked) {
|
|||||||
lineread.buffer = malloc(LINE_LEN);
|
lineread.buffer = malloc(LINE_LEN);
|
||||||
lineread.buflen = LINE_LEN;
|
lineread.buflen = LINE_LEN;
|
||||||
|
|
||||||
command_loop(&fetch_next_line, (void *)&lineread, false, locked);
|
command_loop(con, &fetch_next_line, (void *)&lineread, false, locked);
|
||||||
|
|
||||||
free(lineread.buffer);
|
free(lineread.buffer);
|
||||||
|
|
||||||
return lastresult;
|
return con->lastresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
int console_run_script(const char *string) {
|
int console_run_script(console_t *con, const char *string) {
|
||||||
return console_run_script_etc(string, false);
|
if (!con) {
|
||||||
|
con = console_get_current();
|
||||||
|
}
|
||||||
|
return console_run_script_etc(con, string, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int console_run_script_locked(const char *string) {
|
int console_run_script_locked(console_t *con, const char *string) {
|
||||||
return console_run_script_etc(string, true);
|
if (!con) {
|
||||||
|
con = console_get_current();
|
||||||
|
}
|
||||||
|
return console_run_script_etc(con, string, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
console_cmd_func console_get_command_handler(const char *commandstr) {
|
console_cmd_func console_get_command_handler(const char *commandstr) {
|
||||||
@@ -767,7 +813,7 @@ static int cmd_help_panic(int argc, const console_cmd_args *argv) {
|
|||||||
|
|
||||||
static int cmd_echo(int argc, const console_cmd_args *argv) {
|
static int cmd_echo(int argc, const console_cmd_args *argv) {
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
echo = argv[1].b;
|
console_get_current()->echo = argv[1].b;
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,18 +19,35 @@ __BEGIN_CDECLS
|
|||||||
#include <lk/console_cmd.h>
|
#include <lk/console_cmd.h>
|
||||||
#include <lib/console/cmd.h>
|
#include <lib/console/cmd.h>
|
||||||
|
|
||||||
/* external api */
|
typedef struct console console_t;
|
||||||
void console_start(void);
|
|
||||||
int console_run_script(const char *string);
|
/* create an instance of the console */
|
||||||
int console_run_script_locked(const char *string); // special case from inside a command
|
/* TODO: actually implement the history option. Currently always implements history according
|
||||||
|
* to the build variable CONSOLE_ENABLE_HISTORY. */
|
||||||
|
console_t *console_create(bool with_history);
|
||||||
|
|
||||||
|
/* Run the main console loop. Will set the current console TLS pointer as a side effect */
|
||||||
|
void console_start(console_t *con);
|
||||||
|
|
||||||
|
/* Routines to let code directly run commands in an existing console */
|
||||||
|
/* NOTE: Passing null as first argument selects the current console associated with the current thread */
|
||||||
|
int console_run_script(console_t *con, const char *string);
|
||||||
|
int console_run_script_locked(console_t *con, const char *string); // special case from inside a command
|
||||||
|
void console_abort_script(console_t *con);
|
||||||
|
|
||||||
|
/* Get/set the current console in the thread's TLS slot reserved for it.
|
||||||
|
* New threads will inherit the pointer from the parent thread.
|
||||||
|
*
|
||||||
|
* TODO: use a ref count to keep the console from being destroyed from underneath it.
|
||||||
|
*/
|
||||||
|
console_t *console_get_current(void);
|
||||||
|
console_t *console_set_current(console_t *con); // returns old console pointer
|
||||||
|
|
||||||
console_cmd_func console_get_command_handler(const char *command);
|
console_cmd_func console_get_command_handler(const char *command);
|
||||||
void console_abort_script(void);
|
|
||||||
|
|
||||||
/* panic shell api */
|
/* panic shell api */
|
||||||
void panic_shell_start(void);
|
void panic_shell_start(void);
|
||||||
|
|
||||||
extern int lastresult;
|
|
||||||
|
|
||||||
/* enable the panic shell if we're being built */
|
/* enable the panic shell if we're being built */
|
||||||
#if !defined(ENABLE_PANIC_SHELL) && PLATFORM_SUPPORTS_PANIC_SHELL
|
#if !defined(ENABLE_PANIC_SHELL) && PLATFORM_SUPPORTS_PANIC_SHELL
|
||||||
#define ENABLE_PANIC_SHELL 1
|
#define ENABLE_PANIC_SHELL 1
|
||||||
|
|||||||
Reference in New Issue
Block a user