mirror of https://github.com/rusefi/ChibiOS.git
Paths expansion working(ish), to be integrated into the shell.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15448 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
d226497cc2
commit
9857f97478
|
@ -22,6 +22,8 @@
|
||||||
#include "sbuser.h"
|
#include "sbuser.h"
|
||||||
#include "paths.h"
|
#include "paths.h"
|
||||||
|
|
||||||
|
#include "sglob.h"
|
||||||
|
|
||||||
#define SHELL_MAX_LINE_LENGTH 128
|
#define SHELL_MAX_LINE_LENGTH 128
|
||||||
#define SHELL_MAX_ARGUMENTS 20
|
#define SHELL_MAX_ARGUMENTS 20
|
||||||
#define SHELL_PROMPT_STR "> "
|
#define SHELL_PROMPT_STR "> "
|
||||||
|
@ -162,6 +164,48 @@ static void cmd_pwd(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmd_echo(int argc, char *argv[]) {
|
||||||
|
int i, ret;
|
||||||
|
sglob_t sglob;
|
||||||
|
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
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_NEWLINE_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
sglob_free(&sglob);
|
||||||
|
}
|
||||||
|
|
||||||
static void cmd_env(int argc, char *argv[]) {
|
static void cmd_env(int argc, char *argv[]) {
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
char **pp;
|
char **pp;
|
||||||
|
@ -284,6 +328,7 @@ static bool shell_execute(int argc, char *argv[]) {
|
||||||
void (*cmdf)(int argc, char *argv[]);
|
void (*cmdf)(int argc, char *argv[]);
|
||||||
} builtins[] = {
|
} builtins[] = {
|
||||||
{"cd", cmd_cd},
|
{"cd", cmd_cd},
|
||||||
|
{"echo", cmd_echo},
|
||||||
{"env", cmd_env},
|
{"env", cmd_env},
|
||||||
{"exit", cmd_exit},
|
{"exit", cmd_exit},
|
||||||
{"mkdir", cmd_mkdir},
|
{"mkdir", cmd_mkdir},
|
||||||
|
|
|
@ -74,8 +74,8 @@ static char *lsalloc(sglob_t *psglob, size_t len) {
|
||||||
|
|
||||||
lsp = malloc(len + sizeof (lstring_t));
|
lsp = malloc(len + sizeof (lstring_t));
|
||||||
if (lsp != NULL) {
|
if (lsp != NULL) {
|
||||||
lsp->next = psglob->gl_next;
|
lsp->next = psglob->sgl_next;
|
||||||
psglob->gl_next = lsp;
|
psglob->sgl_next = lsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lsp->string;
|
return lsp->string;
|
||||||
|
@ -105,32 +105,19 @@ bool match(const char *pattern, const char *text) {
|
||||||
|
|
||||||
void sglob_init(sglob_t *psglob, size_t offs) {
|
void sglob_init(sglob_t *psglob, size_t offs) {
|
||||||
|
|
||||||
psglob->gl_offs = offs;
|
psglob->sgl_offs = offs;
|
||||||
psglob->gl_buf = NULL;
|
psglob->sgl_buf = NULL;
|
||||||
psglob->gl_next = NULL;
|
psglob->sgl_next = NULL;
|
||||||
psglob->gl_pathc = 0;
|
psglob->sgl_pathc = 0;
|
||||||
psglob->gl_pathv = NULL;
|
psglob->sgl_pathv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sglob_free(sglob_t *psglob) {
|
int sglob_add(sglob_t *psglob, const char *pattern) {
|
||||||
lstring_t *lsp;
|
|
||||||
|
|
||||||
if (psglob->gl_buf != NULL) {
|
|
||||||
free(psglob->gl_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((lsp = psglob->gl_next) != NULL) {
|
|
||||||
psglob->gl_next = lsp->next;
|
|
||||||
free(lsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sglob_add(const char *pattern, sglob_t *psglob) {
|
|
||||||
int ret;
|
int ret;
|
||||||
DIR *dbp;
|
DIR *dbp;
|
||||||
|
|
||||||
dbp = NULL;
|
dbp = NULL;
|
||||||
ret = GLOB_NOSPACE;
|
ret = SGLOB_NOSPACE;
|
||||||
do {
|
do {
|
||||||
char *lastp, *dirp;
|
char *lastp, *dirp;
|
||||||
size_t plen, dirlen;
|
size_t plen, dirlen;
|
||||||
|
@ -144,50 +131,49 @@ int sglob_add(const char *pattern, sglob_t *psglob) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocating a path buffer if not already done.*/
|
/* Allocating a path buffer if not already done.*/
|
||||||
if (psglob->gl_buf == NULL) {
|
if (psglob->sgl_buf == NULL) {
|
||||||
psglob->gl_buf = malloc(PATH_MAX);
|
psglob->sgl_buf = malloc(PATH_MAX);
|
||||||
if (psglob->gl_buf == NULL) {
|
if (psglob->sgl_buf == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need the path pattern in a writable buffer.*/
|
/* We need the path pattern in a writable buffer.*/
|
||||||
strcpy(psglob->gl_buf, pattern);
|
strcpy(psglob->sgl_buf, pattern);
|
||||||
|
|
||||||
/* Finding the last element, the one to be expanded.*/
|
/* Finding the last element, the one to be expanded.*/
|
||||||
lastp = rindex(psglob->gl_buf, '/');
|
lastp = rindex(psglob->sgl_buf, '/');
|
||||||
if (lastp == NULL) {
|
if (lastp == NULL) {
|
||||||
/* It is all last element.*/
|
/* It is all last element.*/
|
||||||
lastp = psglob->gl_buf;
|
lastp = psglob->sgl_buf;
|
||||||
dirp = NULL;
|
dirp = NULL;
|
||||||
dirlen = (size_t)0;
|
dirlen = (size_t)0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*lastp++ = '\0';
|
*lastp++ = '\0';
|
||||||
dirp = psglob->gl_buf;
|
dirp = psglob->sgl_buf;
|
||||||
dirlen = strlen(dirp);
|
dirlen = strlen(dirp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Case with no wildcards.*/
|
/* Case with no wildcards.*/
|
||||||
no_spec = (bool)((index(lastp, '?') == NULL) && (index(lastp, '*') == NULL));
|
no_spec = (bool)((index(lastp, '?') == NULL) &&
|
||||||
|
(index(lastp, '*') == NULL));
|
||||||
if (no_spec) {
|
if (no_spec) {
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
p = lsalloc(psglob, plen);
|
p = lsalloc(psglob, plen);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
strcpy(p, pattern);
|
strcpy(p, pattern);
|
||||||
// psglob->gl_pathv[psglob->gl_offs + psglob->gl_pathc] = p;
|
psglob->sgl_pathc++;
|
||||||
// psglob->gl_pathv[psglob->gl_offs + psglob->gl_pathc + 1] = NULL;
|
|
||||||
psglob->gl_pathc++;
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opening the directory part of the path. If it fauls then it is not
|
/* Opening the directory part of the path. If it faults then it is not
|
||||||
reported as an error but an empty sglob is returned, this can be
|
reported as an error but an empty sglob is returned, this can be
|
||||||
detected from outside.*/
|
detected from outside.*/
|
||||||
dbp = opendir(dirp);
|
dbp = opendir(dirp == NULL ? "." : dirp);
|
||||||
if (dbp == NULL) {
|
if (dbp == NULL) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -208,20 +194,62 @@ int sglob_add(const char *pattern, sglob_t *psglob) {
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if (dirlen > 0) {
|
if (dirlen > 0) {
|
||||||
strcat(p, dirp);
|
strcat(p, dirp); /* TODO Optimize strcat */
|
||||||
strcat(p, "/");
|
strcat(p, "/");
|
||||||
}
|
}
|
||||||
strcat(p, dp->d_name);
|
strcat(p, dp->d_name);
|
||||||
// psglob->gl_pathv[psglob->gl_offs + psglob->gl_pathc] = p;
|
psglob->sgl_pathc++;
|
||||||
// psglob->gl_pathv[psglob->gl_offs + psglob->gl_pathc + 1] = NULL;
|
|
||||||
psglob->gl_pathc++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dbp);
|
closedir(dbp);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
while (false);
|
while (false);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return SGLOB_NOSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = psglob->sgl_offs;
|
||||||
|
lsp = psglob->sgl_next;
|
||||||
|
while (lsp != NULL) {
|
||||||
|
psglob->sgl_pathv[i++] = lsp->string;
|
||||||
|
lsp = lsp->next;
|
||||||
|
}
|
||||||
|
psglob->sgl_pathv[i] = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sglob_free(sglob_t *psglob) {
|
||||||
|
lstring_t *lsp;
|
||||||
|
|
||||||
|
if (psglob->sgl_buf != NULL) {
|
||||||
|
free(psglob->sgl_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psglob->sgl_pathv != NULL) {
|
||||||
|
free(psglob->sgl_pathv);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((lsp = psglob->sgl_next) != NULL) {
|
||||||
|
psglob->sgl_next = lsp->next;
|
||||||
|
free(lsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -32,9 +32,8 @@
|
||||||
/* Module constants. */
|
/* Module constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define GLOB_NOSPACE 1
|
#define SGLOB_NOSPACE 1
|
||||||
#define GLOB_ABORTED 2
|
#define SGLOB_NOMATCH 3
|
||||||
#define GLOB_NOMATCH 3
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module pre-compile time settings. */
|
/* Module pre-compile time settings. */
|
||||||
|
@ -54,11 +53,11 @@ typedef struct lstring {
|
||||||
} lstring_t;
|
} lstring_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int gl_offs;
|
int sgl_offs;
|
||||||
lstring_t *gl_next;
|
lstring_t *sgl_next;
|
||||||
char *gl_buf;
|
char *sgl_buf;
|
||||||
int gl_pathc;
|
int sgl_pathc;
|
||||||
char **gl_pathv;
|
char **sgl_pathv;
|
||||||
} sglob_t;
|
} sglob_t;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -73,8 +72,9 @@ 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(const char *pattern, sglob_t *psglob);
|
int sglob_add(sglob_t *psglob, const char *pattern);
|
||||||
void glob_free(sglob_t *psglob);
|
int sglob_build(sglob_t *psglob);
|
||||||
|
void sglob_free(sglob_t *psglob);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue