git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15449 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2022-02-08 17:09:55 +00:00
parent 9857f97478
commit b39ca51b57
3 changed files with 103 additions and 73 deletions

View File

@ -165,45 +165,13 @@ static void cmd_pwd(int argc, char *argv[]) {
} }
static void cmd_echo(int argc, char *argv[]) { static void cmd_echo(int argc, char *argv[]) {
int i, ret; int i;
sglob_t sglob;
(void)argv; for (i = 1; i < argc; i++) {
shell_write(argv[i]);
if (argc != 2) {
shell_usage("echo <string>");
return;
}
sglob_init(&sglob, 0);
ret = sglob_add(&sglob, argv[1]);
if (ret != 0) {
sglob_free(&sglob);
shell_error("echo: out of memory" SHELL_NEWLINE_STR);
return;
}
ret = sglob_build(&sglob);
switch (ret) {
case SGLOB_NOMATCH:
sglob_free(&sglob);
shell_write(argv[1]);
shell_write(SHELL_NEWLINE_STR);
return;
case SGLOB_NOSPACE:
sglob_free(&sglob);
shell_error("echo: out of memory" SHELL_NEWLINE_STR);
return;
}
for (i = 0; i < sglob.sgl_pathc; i++) {
shell_write(sglob.sgl_pathv[i]);
shell_write(" "); shell_write(" ");
shell_write(SHELL_NEWLINE_STR);
} }
shell_write(SHELL_NEWLINE_STR);
sglob_free(&sglob);
} }
static void cmd_env(int argc, char *argv[]) { static void cmd_env(int argc, char *argv[]) {
@ -429,10 +397,6 @@ static bool shell_execute(int argc, char *argv[]) {
* Application entry point. * Application entry point.
*/ */
int main(int argc, char *argv[], char *envp[]) { int main(int argc, char *argv[], char *envp[]) {
char line[SHELL_MAX_LINE_LENGTH];
char *args[SHELL_MAX_ARGUMENTS + 1];
char *ap, *tokp;
int i;
asm volatile ("bkpt"); asm volatile ("bkpt");
@ -449,6 +413,11 @@ int main(int argc, char *argv[], char *envp[]) {
shell_write(SHELL_NEWLINE_STR SHELL_WELCOME_STR SHELL_NEWLINE_STR); shell_write(SHELL_NEWLINE_STR SHELL_WELCOME_STR SHELL_NEWLINE_STR);
while (true) { while (true) {
int i, n, ret;
char line[SHELL_MAX_LINE_LENGTH];
char *args[SHELL_MAX_ARGUMENTS + 1];
char *ap, *tokp;
sglob_t sglob;
/* Prompt.*/ /* Prompt.*/
shell_write(prompt); shell_write(prompt);
@ -459,27 +428,65 @@ int main(int argc, char *argv[], char *envp[]) {
break; break;
} }
/* Parsing arguments.*/ /* Fetching arguments.*/
tokp = line; tokp = line;
i = 0; n = 0;
while ((ap = fetch_argument(&tokp)) != NULL) { while ((ap = fetch_argument(&tokp)) != NULL) {
if (i < SHELL_MAX_ARGUMENTS) { if (n < SHELL_MAX_ARGUMENTS) {
args[i++] = ap; args[n++] = ap;
} }
else { else {
i = 0; n = 0;
shell_error("too many arguments" SHELL_NEWLINE_STR); shell_error("too many arguments" SHELL_NEWLINE_STR);
break; break;
} }
} }
args[i] = NULL; args[n] = NULL;
/* Executing command, if any.*/ /* Special case for empty lines.*/
if (i > 0) { if (n == 0) {
if (shell_execute(i, args)){ continue;
}
/* Adding the command name as-is.*/
sglob_init(&sglob, 0);
ret = sglob_add(&sglob, args[0]);
if (ret == SGLOB_NOSPACE) {
shell_error("msh: out of memory" SHELL_NEWLINE_STR);
break;
}
/* Arguments processing except those starting with a "-" which are
options, those are added without processing.*/
for (i = 1; i < n; i++) {
/* Accumulating arguments expansion into the "glob".*/
if (*args[i] != '-') {
ret = sglob_match(&sglob, args[i]);
}
else {
ret = sglob_add(&sglob, args[i]);
}
if (ret == SGLOB_NOSPACE) {
shell_error("msh: out of memory" SHELL_NEWLINE_STR);
break;
}
}
/* If no errors then executing the command.*/
if (ret != SGLOB_NOSPACE) {
/* Building the full arguments array.*/
ret = sglob_build(&sglob);
if (ret != 0) {
}
if (shell_execute(sglob.sgl_pathc, sglob.sgl_pathv)) {
shell_error("msh: ");
shell_error(args[0]); shell_error(args[0]);
shell_error(": command not found" SHELL_NEWLINE_STR); shell_error(": command not found" SHELL_NEWLINE_STR);
} }
} }
/* Freeing memory allocated during processing.*/
sglob_free(&sglob);
} }
} }

View File

@ -73,11 +73,18 @@ static char *lsalloc(sglob_t *psglob, size_t len) {
lstring_t *lsp; lstring_t *lsp;
lsp = malloc(len + sizeof (lstring_t)); lsp = malloc(len + sizeof (lstring_t));
if (lsp != NULL) { if (lsp == NULL) {
lsp->next = psglob->sgl_next; return NULL;
psglob->sgl_next = lsp;
} }
lsp->next = NULL;
if (psglob->sgl_next == NULL) {
psglob->sgl_next = psglob->sgl_last = lsp;
}
else {
psglob->sgl_last->next = lsp;
psglob->sgl_last = lsp;
}
return lsp->string; return lsp->string;
} }
@ -108,11 +115,29 @@ void sglob_init(sglob_t *psglob, size_t offs) {
psglob->sgl_offs = offs; psglob->sgl_offs = offs;
psglob->sgl_buf = NULL; psglob->sgl_buf = NULL;
psglob->sgl_next = NULL; psglob->sgl_next = NULL;
psglob->sgl_last = NULL;
psglob->sgl_pathc = 0; psglob->sgl_pathc = 0;
psglob->sgl_pathv = NULL; psglob->sgl_pathv = NULL;
} }
int sglob_add(sglob_t *psglob, const char *pattern) { int sglob_add(sglob_t *psglob, const char *s) {
char *p;
int ret;
p = lsalloc(psglob, strlen(s));
if (p != NULL) {
strcpy(p, s);
psglob->sgl_pathc++;
ret = 0;
}
else {
ret = SGLOB_NOSPACE;
}
return ret;
}
int sglob_match(sglob_t *psglob, const char *pattern) {
int ret; int ret;
DIR *dbp; DIR *dbp;
@ -121,7 +146,7 @@ int sglob_add(sglob_t *psglob, const char *pattern) {
do { do {
char *lastp, *dirp; char *lastp, *dirp;
size_t plen, dirlen; size_t plen, dirlen;
bool no_spec; bool no_spec, found;
struct dirent *dp; struct dirent *dp;
/* Checking the path length.*/ /* Checking the path length.*/
@ -155,19 +180,11 @@ int sglob_add(sglob_t *psglob, const char *pattern) {
dirlen = strlen(dirp); dirlen = strlen(dirp);
} }
/* Case with no wildcards.*/ /* Case with no wildcards, adding with no processing.*/
no_spec = (bool)((index(lastp, '?') == NULL) && no_spec = (bool)((index(lastp, '?') == NULL) &&
(index(lastp, '*') == NULL)); (index(lastp, '*') == NULL));
if (no_spec) { if (no_spec) {
char *p; return sglob_add(psglob, pattern);
p = lsalloc(psglob, plen);
if (p != NULL) {
strcpy(p, pattern);
psglob->sgl_pathc++;
ret = 0;
}
break;
} }
/* Opening the directory part of the path. If it faults then it is not /* Opening the directory part of the path. If it faults then it is not
@ -175,11 +192,12 @@ int sglob_add(sglob_t *psglob, const char *pattern) {
detected from outside.*/ detected from outside.*/
dbp = opendir(dirp == NULL ? "." : dirp); dbp = opendir(dirp == NULL ? "." : dirp);
if (dbp == NULL) { if (dbp == NULL) {
ret = 0; ret = SGLOB_NOMATCH;
break; break;
} }
/* Scanning the directory for matches.*/ /* Scanning the directory for matches.*/
found = false;
while ((dp = readdir(dbp)) != NULL) { while ((dp = readdir(dbp)) != NULL) {
char *p; char *p;
@ -188,9 +206,10 @@ int sglob_add(sglob_t *psglob, const char *pattern) {
} }
/* Inserting the new found match into the list.*/ /* Inserting the new found match into the list.*/
found = true;
p = lsalloc(psglob, dirlen + strlen(dp->d_name) + 1); p = lsalloc(psglob, dirlen + strlen(dp->d_name) + 1);
if (p == NULL) { if (p == NULL) {
break; goto skiperr;
} }
*p = '\0'; *p = '\0';
if (dirlen > 0) { if (dirlen > 0) {
@ -201,10 +220,16 @@ int sglob_add(sglob_t *psglob, const char *pattern) {
psglob->sgl_pathc++; psglob->sgl_pathc++;
} }
closedir(dbp); if (found) {
ret = 0; ret = 0;
} }
else {
ret = SGLOB_NOMATCH;
}
skiperr:
closedir(dbp);
}
while (false); while (false);
return ret; return ret;
@ -214,10 +239,6 @@ int sglob_build(sglob_t *psglob) {
lstring_t *lsp; lstring_t *lsp;
int i; int i;
if (psglob->sgl_pathc == 0) {
return SGLOB_NOMATCH;
}
psglob->sgl_pathv = malloc((psglob->sgl_pathc + psglob->sgl_offs + 1) * psglob->sgl_pathv = malloc((psglob->sgl_pathc + psglob->sgl_offs + 1) *
sizeof (char *)); sizeof (char *));
if (psglob->sgl_pathv == NULL) { if (psglob->sgl_pathv == NULL) {

View File

@ -55,6 +55,7 @@ typedef struct lstring {
typedef struct { typedef struct {
int sgl_offs; int sgl_offs;
lstring_t *sgl_next; lstring_t *sgl_next;
lstring_t *sgl_last;
char *sgl_buf; char *sgl_buf;
int sgl_pathc; int sgl_pathc;
char **sgl_pathv; char **sgl_pathv;
@ -72,7 +73,8 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void sglob_init(sglob_t *psglob, size_t offs); void sglob_init(sglob_t *psglob, size_t offs);
int sglob_add(sglob_t *psglob, const char *pattern); int sglob_add(sglob_t *psglob, const char *s);
int sglob_match(sglob_t *psglob, const char *pattern);
int sglob_build(sglob_t *psglob); int sglob_build(sglob_t *psglob);
void sglob_free(sglob_t *psglob); void sglob_free(sglob_t *psglob);
#ifdef __cplusplus #ifdef __cplusplus