From b39ca51b577587b2c82fb7de4dd5a5cbdf14670d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 8 Feb 2022 17:09:55 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15449 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/sb/apps/msh/main.c | 105 ++++++++++++++++++---------------- os/sb/apps/msh/source/sglob.c | 67 ++++++++++++++-------- os/sb/apps/msh/source/sglob.h | 4 +- 3 files changed, 103 insertions(+), 73 deletions(-) diff --git a/os/sb/apps/msh/main.c b/os/sb/apps/msh/main.c index e4fddee3a..c5f3b5d45 100644 --- a/os/sb/apps/msh/main.c +++ b/os/sb/apps/msh/main.c @@ -165,45 +165,13 @@ static void cmd_pwd(int argc, char *argv[]) { } static void cmd_echo(int argc, char *argv[]) { - int i, ret; - sglob_t sglob; + int i; - (void)argv; - - if (argc != 2) { - shell_usage("echo "); - 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]); + for (i = 1; i < argc; i++) { + shell_write(argv[i]); shell_write(" "); - shell_write(SHELL_NEWLINE_STR); } - - sglob_free(&sglob); + shell_write(SHELL_NEWLINE_STR); } static void cmd_env(int argc, char *argv[]) { @@ -429,10 +397,6 @@ static bool shell_execute(int argc, char *argv[]) { * Application entry point. */ 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"); @@ -449,6 +413,11 @@ int main(int argc, char *argv[], char *envp[]) { shell_write(SHELL_NEWLINE_STR SHELL_WELCOME_STR SHELL_NEWLINE_STR); 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.*/ shell_write(prompt); @@ -459,27 +428,65 @@ int main(int argc, char *argv[], char *envp[]) { break; } - /* Parsing arguments.*/ + /* Fetching arguments.*/ tokp = line; - i = 0; + n = 0; while ((ap = fetch_argument(&tokp)) != NULL) { - if (i < SHELL_MAX_ARGUMENTS) { - args[i++] = ap; + if (n < SHELL_MAX_ARGUMENTS) { + args[n++] = ap; } else { - i = 0; + n = 0; shell_error("too many arguments" SHELL_NEWLINE_STR); break; } } - args[i] = NULL; + args[n] = NULL; - /* Executing command, if any.*/ - if (i > 0) { - if (shell_execute(i, args)){ + /* Special case for empty lines.*/ + if (n == 0) { + 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(": command not found" SHELL_NEWLINE_STR); } } + + /* Freeing memory allocated during processing.*/ + sglob_free(&sglob); } } diff --git a/os/sb/apps/msh/source/sglob.c b/os/sb/apps/msh/source/sglob.c index cb8b951b6..6d6dbb600 100644 --- a/os/sb/apps/msh/source/sglob.c +++ b/os/sb/apps/msh/source/sglob.c @@ -73,11 +73,18 @@ static char *lsalloc(sglob_t *psglob, size_t len) { lstring_t *lsp; lsp = malloc(len + sizeof (lstring_t)); - if (lsp != NULL) { - lsp->next = psglob->sgl_next; - psglob->sgl_next = lsp; + if (lsp == NULL) { + return NULL; } + 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; } @@ -108,11 +115,29 @@ void sglob_init(sglob_t *psglob, size_t offs) { psglob->sgl_offs = offs; psglob->sgl_buf = NULL; psglob->sgl_next = NULL; + psglob->sgl_last = NULL; psglob->sgl_pathc = 0; 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; DIR *dbp; @@ -121,7 +146,7 @@ int sglob_add(sglob_t *psglob, const char *pattern) { do { char *lastp, *dirp; size_t plen, dirlen; - bool no_spec; + bool no_spec, found; struct dirent *dp; /* Checking the path length.*/ @@ -155,19 +180,11 @@ int sglob_add(sglob_t *psglob, const char *pattern) { dirlen = strlen(dirp); } - /* Case with no wildcards.*/ + /* Case with no wildcards, adding with no processing.*/ no_spec = (bool)((index(lastp, '?') == NULL) && (index(lastp, '*') == NULL)); if (no_spec) { - char *p; - - p = lsalloc(psglob, plen); - if (p != NULL) { - strcpy(p, pattern); - psglob->sgl_pathc++; - ret = 0; - } - break; + return sglob_add(psglob, pattern); } /* 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.*/ dbp = opendir(dirp == NULL ? "." : dirp); if (dbp == NULL) { - ret = 0; + ret = SGLOB_NOMATCH; break; } /* Scanning the directory for matches.*/ + found = false; while ((dp = readdir(dbp)) != NULL) { char *p; @@ -188,9 +206,10 @@ int sglob_add(sglob_t *psglob, const char *pattern) { } /* Inserting the new found match into the list.*/ + found = true; p = lsalloc(psglob, dirlen + strlen(dp->d_name) + 1); if (p == NULL) { - break; + goto skiperr; } *p = '\0'; if (dirlen > 0) { @@ -201,9 +220,15 @@ int sglob_add(sglob_t *psglob, const char *pattern) { psglob->sgl_pathc++; } - closedir(dbp); + if (found) { + ret = 0; + } + else { + ret = SGLOB_NOMATCH; + } - ret = 0; +skiperr: + closedir(dbp); } while (false); @@ -214,10 +239,6 @@ int sglob_build(sglob_t *psglob) { lstring_t *lsp; int i; - if (psglob->sgl_pathc == 0) { - return SGLOB_NOMATCH; - } - psglob->sgl_pathv = malloc((psglob->sgl_pathc + psglob->sgl_offs + 1) * sizeof (char *)); if (psglob->sgl_pathv == NULL) { diff --git a/os/sb/apps/msh/source/sglob.h b/os/sb/apps/msh/source/sglob.h index 7de4be278..f9ae9db53 100644 --- a/os/sb/apps/msh/source/sglob.h +++ b/os/sb/apps/msh/source/sglob.h @@ -55,6 +55,7 @@ typedef struct lstring { typedef struct { int sgl_offs; lstring_t *sgl_next; + lstring_t *sgl_last; char *sgl_buf; int sgl_pathc; char **sgl_pathv; @@ -72,7 +73,8 @@ typedef struct { extern "C" { #endif 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); void sglob_free(sglob_t *psglob); #ifdef __cplusplus