#include "console.h"
#include <unistd.h>
#include <stdio.h>
#include <readline/readline.h>
#include <assert.h>
/** The global console state */
static struct console _console;
/**
* Our stdin input handler
*/
static void console_input (int fd, short what, void *arg)
{
struct console *console = arg;
(void) console;
(void) fd;
(void) what;
// tell readline to process it
rl_callback_read_char();
}
/**
* Our readline line handler
*/
static void console_line (char *line)
{
struct console *console = &_console;
// invoke the console callback
console->callbacks->on_line(line, console->cb_arg);
}
err_t console_init (struct console **console_ptr, struct event_base *ev_base, const struct console_config *config,
const struct console_callbacks *callbacks, void *cb_arg, struct error_info *err)
{
struct console *console = &_console;
// check it's not already initialized
assert(!console->initialized);
// store
console->callbacks = callbacks;
console->cb_arg = cb_arg;
// setup the input event
if ((console->ev = event_new(ev_base, STDIN_FILENO, EV_READ | EV_PERSIST, &console_input, console)) == NULL)
JUMP_SET_ERROR(err, ERR_EVENT_NEW);
// setup readline
rl_callback_handler_install(config->prompt, &console_line);
// mark it as initialized
console->initialized = true;
// enable input
if (event_add(console->ev, NULL))
JUMP_SET_ERROR(err, ERR_EVENT_ADD);
// ok
*console_ptr = console;
return SUCCESS;
error:
console_destroy(console);
return ERROR_CODE(err);
}
void console_destroy (struct console *console)
{
// remove the input event
if (console->ev)
event_free(console->ev);
console->ev = NULL;
// de-init rl?
if (console->initialized)
rl_callback_handler_remove();
console->initialized = false;
// remove stored stuff
console->callbacks = console->cb_arg = NULL;
}