You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
4.7 KiB
204 lines
4.7 KiB
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <ctype.h>
|
|
#include "cmd.h"
|
|
|
|
#define MAX_HISTORY (4)
|
|
#define CMDBUF_SIZE (256)
|
|
|
|
enum KEY_ACTION{
|
|
KEY_NULL = 0, /* NULL */
|
|
CTRL_A = 1, /* Ctrl+a */
|
|
CTRL_B = 2, /* Ctrl-b */
|
|
CTRL_C = 3, /* Ctrl-c */
|
|
CTRL_D = 4, /* Ctrl-d */
|
|
CTRL_E = 5, /* Ctrl-e */
|
|
CTRL_F = 6, /* Ctrl-f */
|
|
CTRL_H = 8, /* Ctrl-h */
|
|
TAB = 9, /* Tab */
|
|
CTRL_K = 11, /* Ctrl+k */
|
|
CTRL_L = 12, /* Ctrl+l */
|
|
ENTER = 13, /* Enter */
|
|
CTRL_N = 14, /* Ctrl-n */
|
|
CTRL_P = 16, /* Ctrl-p */
|
|
CTRL_T = 20, /* Ctrl-t */
|
|
CTRL_U = 21, /* Ctrl+u */
|
|
CTRL_W = 23, /* Ctrl+w */
|
|
ESC = 27, /* Escape */
|
|
BACKSPACE = 127 /* Backspace */
|
|
};
|
|
|
|
extern struct cmd_tbl_s __cmdline_cmd_start, __cmdline_cmd_end;
|
|
static int maxargs = 4;
|
|
|
|
static char cmdbuf[CMDBUF_SIZE];
|
|
static int bufidx;
|
|
|
|
static int do_help(cmd_tbl_t s, int argc, char *argv[])
|
|
{
|
|
cmd_tbl_t it = &__cmdline_cmd_start;
|
|
|
|
printf("support commands:\r\n\r\n");
|
|
while (it < &__cmdline_cmd_end) {
|
|
printf("%s\t%s\r\n", it->name, it->help);
|
|
++it;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int cmd_init()
|
|
{
|
|
cmd_tbl_t it = &__cmdline_cmd_start;
|
|
|
|
while (it < &__cmdline_cmd_end) {
|
|
if (it->maxargs > maxargs)
|
|
maxargs = it->maxargs + 1;
|
|
++it;
|
|
}
|
|
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
|
setvbuf(stderr, NULL, _IONBF, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int32_t parse_line(char *cmd, uint32_t len, char *argv[], int _maxargs)
|
|
{
|
|
uint32_t argc;
|
|
char *p;
|
|
uint32_t position;
|
|
|
|
/* Init params */
|
|
p = cmd;
|
|
position = 0;
|
|
argc = 0;
|
|
|
|
while ((position < len) && (argc < _maxargs)) {
|
|
/* Skip all blanks */
|
|
while (((char)(*p) == ' ') && (position < len)) {
|
|
*p = '\0';
|
|
p++;
|
|
position++;
|
|
}
|
|
/* Process begin of a string */
|
|
if (*p == '"') {
|
|
p++;
|
|
position++;
|
|
argv[argc] = p;
|
|
argc++;
|
|
/* Skip this string */
|
|
while ((*p != '"') && (position < len)) {
|
|
p++;
|
|
position++;
|
|
}
|
|
/* Skip '"' */
|
|
*p = '\0';
|
|
p++;
|
|
position++;
|
|
} else {/* Normal char */
|
|
argv[argc] = p;
|
|
argc++;
|
|
while (((char)*p != ' ') && ((char)*p != '\t') && (position < len)) {
|
|
p++;
|
|
position++;
|
|
}
|
|
}
|
|
}
|
|
return argc;
|
|
}
|
|
|
|
int cmd_process(char *line)
|
|
{
|
|
cmd_tbl_t it = &__cmdline_cmd_start;
|
|
int size = strlen(line);
|
|
int i, argc;
|
|
char *argv[maxargs];
|
|
|
|
/* split line */
|
|
for (i = 0; i < maxargs; ++i) {
|
|
argv[i] = NULL;
|
|
}
|
|
|
|
argc = parse_line(line, size, argv, maxargs);
|
|
|
|
if (argc <= 0)
|
|
goto recovery;
|
|
|
|
while (it < &__cmdline_cmd_end) {
|
|
if (strcasecmp(argv[0], it->name) == 0) {
|
|
it->cmd(it, argc, argv);
|
|
return 1;
|
|
}
|
|
++it;
|
|
}
|
|
|
|
/* recovery line */
|
|
recovery:
|
|
for (i = 0; i < size; ++i) {
|
|
if (line[i] == '\0')
|
|
line[i] = ' ';
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
CON_CMD(help, 0, "commands help", do_help)
|
|
|
|
void cmd_loop()
|
|
{
|
|
char c;
|
|
int n;
|
|
|
|
do {
|
|
n = read(STDIN_FILENO, &c, sizeof c);
|
|
if (n <= 0)
|
|
break;
|
|
if (bufidx >= CMDBUF_SIZE) {
|
|
printf("too long\r\n");
|
|
bufidx = 0;
|
|
write(STDOUT_FILENO, "\r\n> ", 4);
|
|
}
|
|
|
|
switch (c) {
|
|
case CTRL_C:
|
|
bufidx = 0;
|
|
write(STDOUT_FILENO, "\r\n> ", 4);
|
|
return;
|
|
case BACKSPACE:
|
|
case CTRL_H:
|
|
if (bufidx > 0) {
|
|
write(STDOUT_FILENO, "\b \b", 3);
|
|
bufidx--;
|
|
cmdbuf[bufidx] = '\0';
|
|
}
|
|
return;
|
|
case CTRL_L:
|
|
write(STDOUT_FILENO,"\x1b[H\x1b[2J",7);
|
|
write(STDOUT_FILENO, "> ", 2);
|
|
if (bufidx > 0)
|
|
write(STDOUT_FILENO, cmdbuf, bufidx);
|
|
return;
|
|
}
|
|
|
|
/* end of line */
|
|
if (c == '\r' || c == '\n') {
|
|
write(STDOUT_FILENO, "\r\n", 2);
|
|
if (bufidx > 0) {
|
|
cmdbuf[bufidx] = '\0';
|
|
cmd_process(cmdbuf);
|
|
write(STDOUT_FILENO, "\r\n", 2);
|
|
bufidx = 0;
|
|
}
|
|
write(STDOUT_FILENO, "> ", 2);
|
|
continue;
|
|
}
|
|
|
|
if (isprint(c)) {
|
|
cmdbuf[bufidx++] = c;
|
|
write(STDOUT_FILENO, &c, 1);
|
|
}
|
|
} while (1) ;
|
|
}
|
|
|
|
|