Minimal shell.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15365 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2022-01-16 14:43:19 +00:00
parent 59684fb925
commit 6af613f1b8
2 changed files with 70 additions and 25 deletions

View File

@ -72,7 +72,7 @@ static const sb_config_t sb_config1 = {
[0] = { [0] = {
.area = {STARTUP_RAM1_BASE, STARTUP_RAM1_SIZE}, .area = {STARTUP_RAM1_BASE, STARTUP_RAM1_SIZE},
.used = true, .used = true,
.writeable = false .writeable = true
}, },
[1] = { [1] = {
.area = {NULL, (size_t)0}, .area = {NULL, (size_t)0},

View File

@ -17,6 +17,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
#include "sbuser.h" #include "sbuser.h"
@ -24,6 +25,7 @@
#define SHELL_MAX_ARGUMENTS 20 #define SHELL_MAX_ARGUMENTS 20
#define SHELL_PROMPT_STR "> " #define SHELL_PROMPT_STR "> "
#define SHELL_NEWLINE_STR "\r\n" #define SHELL_NEWLINE_STR "\r\n"
#define SHELL_WELCOME_STR "ChibiOS/SB shell"
static void shell_write(const char *s) { static void shell_write(const char *s) {
size_t n = strlen(s); size_t n = strlen(s);
@ -82,31 +84,71 @@ bool shell_getline(char *line, size_t size) {
} }
} }
static char *fetch_argument(char *p) { static char *fetch_argument(char **pp) {
char *dp; char *p, *ap;
/* Skipping white space.*/ /* Skipping white space.*/
p += strspn(p, " \t"); ap = *pp;
ap += strspn(ap, " \t");
if (*p == '\0') { if (*ap == '\0') {
dp = p; return NULL;
p = NULL;
} }
else if (*p == '"') {
if (*ap == '"') {
/* If an argument starts with a double quote then its delimiter is another /* If an argument starts with a double quote then its delimiter is another
quote.*/ quote.*/
p++; ap++;
dp = strpbrk(p++, "\""); p = strpbrk(ap, "\"");
} }
else { else {
/* The delimiter is white space.*/ /* The delimiter is white space.*/
dp = strpbrk(p++, " \t"); p = strpbrk(ap, " \t");
} }
if (p != NULL) {
/* Replacing the delimiter with a zero.*/ /* Replacing the delimiter with a zero.*/
*dp = '\0'; *p++ = '\0';
}
else {
/* Final one, pointing on the final zero.*/
p = ap + strlen(ap);
}
*pp = p;
return p; return ap;
}
static int cmd_exit(int argc, char *argv[]) {
(void)argc;
(void)argv;
sbExit(0);
return 0;
}
static int shell_execute(int argc, char *argv[]) {
int i;
static const struct {
const char *name;
int (*cmdf)(int argc, char *argv[]);
} builtins[] = {
{"exit", cmd_exit},
{NULL, NULL}
};
i = 0;
while (builtins[i].name != NULL) {
if (strcmp(builtins[i].name, argv[0]) == 0) {
return builtins[i].cmdf(argc, argv);
}
i++;
}
return -1;
} }
/* /*
@ -138,10 +180,17 @@ int main(int argc, char *argv[], char *envp[]) {
#endif #endif
char line[SHELL_MAX_LINE_LENGTH]; char line[SHELL_MAX_LINE_LENGTH];
char *args[SHELL_MAX_ARGUMENTS + 1]; char *args[SHELL_MAX_ARGUMENTS + 1];
char *p; char *ap, *tokp;
int i, j; int i;
(void)argc;
(void)argv;
(void)envp;
while (true) { while (true) {
/* Welcome.*/
shell_write(SHELL_WELCOME_STR SHELL_NEWLINE_STR);
/* Prompt.*/ /* Prompt.*/
shell_write(SHELL_PROMPT_STR); shell_write(SHELL_PROMPT_STR);
@ -153,24 +202,20 @@ int main(int argc, char *argv[], char *envp[]) {
} }
/* Parsing arguments.*/ /* Parsing arguments.*/
p = line; tokp = line;
i = 0; i = 0;
while ((p = fetch_argument(p)) != NULL) { while ((ap = fetch_argument(&tokp)) != NULL) {
if (i < SHELL_MAX_ARGUMENTS) { if (i < SHELL_MAX_ARGUMENTS) {
args[i++] = p; args[i++] = ap;
} }
else { else {
i = 0; i = 0;
shell_error("too many argu" SHELL_NEWLINE_STR); shell_error("too many arguments" SHELL_NEWLINE_STR);
break; break;
} }
} }
args[i] = NULL; args[i] = NULL;
j = 0; shell_execute(i, args);
while ((p = args[j++]) != NULL) {
shell_write(p);
shell_write(SHELL_NEWLINE_STR);
}
} }
} }