git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15449 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
9857f97478
commit
b39ca51b57
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue