literm is a small terminal for the mbed This library allows mbed users to easily create a terminal for their mbed and simplify developpment. Users can simply add their own commands by using the LITERM_CMD macro. Each command is described by a name a description and a fallback which can get literm context and commands arguments. Please refers to the documentation, examples and don't hesitate to submit bugs, advices or request.
literm.cpp
- Committer:
- garfunkheul
- Date:
- 2013-10-08
- Revision:
- 0:ae9f1dd56e92
File content as of revision 0:ae9f1dd56e92:
#include "literm.h" #include "mbed.h" void literm::redraw(const char *line) { out->printf("\x1B[1K"); /* Clear line */ out->printf("\x1B[140D"); /* Move cursor to Left */ out->printf("%s%s", prompt, line); } int do_help(literm *term, char *args) { struct literm_cmd *pcmd = term->get_cmds(); Serial *out = term->get_out(); while (pcmd->prev != NULL) { out->printf("\r\n%s - %s", pcmd->name, pcmd->desc); pcmd = pcmd->prev; } return 0; } literm::literm(Serial *_out) { out = _out; /* Register default config */ sprintf(prompt, "mbed > "); sprintf(welcome, "\r\n\r\nHello from literm library"); /* Register Help command which is the first one */ sprintf(help_cmd.name, "help"); help_cmd.prev = NULL; help_cmd.func = do_help; cmd_list = &help_cmd; } void literm::loop() { int hist_begin = -1; /* -1 = empty hist */ int hist_end = 0; int hist_cur; int hist_full = 0; char hist[HIST_SIZE][MAX_CMDLINE_SIZE]; char cmdline[MAX_CMDLINE_SIZE]; int max_cmdline, i; struct literm_cmd *pcmd; out->printf(welcome); while (1) { begin: pcmd = cmd_list; max_cmdline = 0; hist_cur = -1; /* -1 = no hist used */ out->printf("\r\n%s",prompt); do { if (out->readable()) { cmdline[max_cmdline] = out->getc(); if (cmdline[max_cmdline] == 3) goto begin; if (cmdline[max_cmdline] == 4) goto exit; if (cmdline[max_cmdline] == 8 || cmdline[max_cmdline] == 127) { if (max_cmdline > 0) { max_cmdline--; cmdline[max_cmdline] = '\0'; redraw(cmdline); } } else if (cmdline[max_cmdline] == 27) { out->getc(); /* trash useless value */ char tmp = out->getc(); if (tmp == 65) { /* up */ if (hist_cur != hist_end && hist_begin != -1) { if (hist_cur == -1) hist_cur = hist_begin; else hist_cur--; if (hist_cur < 0) hist_cur = HIST_SIZE - 1; redraw(hist[hist_cur]); } } else if (tmp == 66) { /* down */ if (hist_cur != hist_begin) { hist_cur++; if(hist_cur >= HIST_SIZE) hist_cur = 0; redraw(hist[hist_cur]); } } } else out->putc(cmdline[max_cmdline++]); } } while (cmdline[max_cmdline - 1] != 13); /* use a command from history */ if (hist_cur != -1) { strncpy(cmdline, hist[hist_cur], MAX_CMDLINE_SIZE - 1); max_cmdline = strlen(cmdline); if (hist_cur == hist_begin) goto proceed; /* use a new command */ } else { /* deal with empty lines */ if (max_cmdline < 2 && hist_cur == -1) goto begin; cmdline[max_cmdline - 1] = '\0'; } /* Update History */ hist_begin++; if (hist_begin >= HIST_SIZE) { hist_begin = 0; hist_full = 1; } if (hist_full) hist_end++; if (hist_end >= HIST_SIZE) hist_end = 0; strncpy(hist[hist_begin], cmdline, MAX_CMDLINE_SIZE - 1); proceed: for (i = 0; i < max_cmdline; ++i) { if (cmdline[i] == ' ') { cmdline[i] = '\0'; break; } if (cmdline[i] == '\0') { cmdline[i + 1] = '\0'; break; } } while (strcmp(pcmd->name, cmdline) && pcmd != NULL) pcmd = pcmd->prev; if (pcmd != NULL) (*pcmd->func)(this, cmdline + i + 1); else out->printf("\r\n%s not found", cmdline); } exit: out->printf("\r\nExiting small cli\r\n"); } literm_cmd* literm::get_cmds() { return cmd_list; } Serial* literm::get_out() { return out; } void literm::set_hostname(char *name) { snprintf(prompt, sizeof(prompt) - 1, "%s > ", name); } void literm::set_welcome(char *message) { snprintf(welcome, sizeof(welcome) - 1, "\r\n\r\n%s", message); } void literm::add_cmd(literm_cmd *_cmd) { _cmd->prev = cmd_list; cmd_list = _cmd; }