1
0
mirror of git://projects.qi-hardware.com/xburst-tools.git synced 2024-11-29 10:50:39 +02:00

Made shell reentrant

This commit is contained in:
Sergey Gridassov 2010-12-10 12:43:54 +03:00
parent f3d7b160a7
commit a80ec957c6
10 changed files with 949 additions and 655 deletions

View File

@ -8,7 +8,7 @@ endif
CC = gcc CC = gcc
TARGET = jzboot TARGET = jzboot
SOURCES = debug.c devmgr.c ingenic.c main.c shell_lex.c usbdev.c shell.c config.c spl_cmdset.c usbboot_cmdset.c SOURCES = debug.c devmgr.c ingenic.c main.c shell_lex.c usbdev.c shell.c shell_builtins.c config.c spl_cmdset.c usbboot_cmdset.c
CFLAGS = --std=gnu99 -Wall -Werror -O2 $(shell pkg-config libusb-1.0 --cflags) CFLAGS = --std=gnu99 -Wall -Werror -O2 $(shell pkg-config libusb-1.0 --cflags)
LIBS += $(shell pkg-config libusb-1.0 --libs) LIBS += $(shell pkg-config libusb-1.0 --libs)

14
main.c
View File

@ -146,7 +146,9 @@ int main(int argc, char *argv[]) {
goto exit_usb; goto exit_usb;
} }
if(shell_init(ingenic) == -1) { shell_context_t *shell = shell_init(ingenic);
if(shell == NULL) {
perror("shell_init"); perror("shell_init");
ret = 1; ret = 1;
@ -155,7 +157,7 @@ int main(int argc, char *argv[]) {
} }
if(config) if(config)
if(shell_source(config) == -1) { if(shell_source(shell, config) == -1) {
perror("shell_source"); perror("shell_source");
ret = 1; ret = 1;
@ -164,23 +166,23 @@ int main(int argc, char *argv[]) {
} }
if(cmd != NULL) { if(cmd != NULL) {
if(shell_execute(cmd) == -1) { if(shell_execute(shell, cmd) == -1) {
perror("shell_execute"); perror("shell_execute");
ret = 1; ret = 1;
} }
} else if(script != NULL) { } else if(script != NULL) {
if(shell_source(script) == -1) { if(shell_source(shell, script) == -1) {
perror("shell_source"); perror("shell_source");
ret = 1; ret = 1;
} }
} else } else
shell_interactive(); shell_interactive(shell);
exit_shell: exit_shell:
shell_fini(); shell_fini(shell);
exit_ingenic: exit_ingenic:
ingenic_close(ingenic); ingenic_close(ingenic);

331
shell.c
View File

@ -27,42 +27,9 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include "shell.h" #include "shell_internal.h"
#include "debug.h" #include "debug.h"
#include "ingenic.h" #include "ingenic.h"
#include "config.h"
static void *device = NULL;
static char linebuf[512];
char *strval = NULL, *line = NULL;
int yylex();
void yyrestart(FILE *new_file);
static int builtin_help(int argc, char *argv[]);
static int builtin_exit(int argc, char *argv[]);
static int builtin_source(int argc, char *argv[]);
static int builtin_echo(int argc, char *argv[]);
static int builtin_sleep(int argc, char *argv[]);
static int builtin_redetect(int argc, char *argv[]);
static int builtin_rebuildcfg(int argc, char *argv[]);
static int builtin_set(int argc, char *argv[]);
static int builtin_safe(int argc, char *argv[]);
static const shell_command_t commands[] = {
{ "help", "- Display this message", builtin_help },
{ "exit", "- Batch: stop current script, interactive: end session", builtin_exit },
{ "source", "<FILENAME> - run specified script", builtin_source },
{ "echo", "<STRING> - output specified string", builtin_echo },
{ "sleep", "<MILLISECONDS> - sleep a specified amount of time", builtin_sleep },
{ "set", "[VARIABLE] [VALUE] - print or set configuraton variables", builtin_set },
{ "safe", "<COMMAND> [ARG]... - run command ignoring errors", builtin_safe },
{ "redetect", " - Redetect CPU", builtin_redetect },
{ "rebuildcfg", " - Rebuild firmware configuration data", builtin_rebuildcfg },
{ NULL, NULL, NULL }
};
static void shell_update_cmdset(void *arg); static void shell_update_cmdset(void *arg);
@ -70,64 +37,106 @@ static const ingenic_callbacks_t shell_callbacks = {
shell_update_cmdset, shell_update_cmdset,
}; };
static const shell_command_t *set_cmds = NULL; static const struct {
static int shell_exit = 0; int set;
const char *name;
const shell_command_t *commands;
} cmdsets[] = {
{ CMDSET_SPL, "SPL", spl_cmdset },
{ CMDSET_USBBOOT, "USBBoot", usbboot_cmdset },
{ 0, NULL, NULL }
};
int shell_init(void *ingenic) { shell_context_t *shell_init(void *ingenic) {
#ifdef WITH_READLINE #ifdef WITH_READLINE
rl_initialize(); rl_initialize();
#endif #endif
debug(LEVEL_DEBUG, "Initializing shell\n"); debug(LEVEL_DEBUG, "Initializing shell\n");
device = ingenic; shell_context_t *ctx = malloc(sizeof(shell_context_t));
memset(ctx, 0, sizeof(shell_context_t));
ctx->device = ingenic;
ingenic_set_callbacks(ingenic, &shell_callbacks, NULL); ingenic_set_callbacks(ingenic, &shell_callbacks, ctx);
shell_update_cmdset(NULL); shell_update_cmdset(ctx);
return ctx;
}
int shell_enumerate_commands(shell_context_t *ctx, int (*callback)(shell_context_t *ctx, const shell_command_t *cmd, void *arg), void *arg) {
for(int i = 0; builtin_cmdset[i].cmd != NULL; i++) {
int ret = callback(ctx, builtin_cmdset + i, arg);
if(ret != 0)
return ret;
}
if(ctx->set_cmds)
for(int i = 0; ctx->set_cmds[i].cmd != NULL; i++) {
int ret = callback(ctx, ctx->set_cmds + i, arg);
if(ret != 0)
return ret;
}
return 0; return 0;
} }
#define STATE_WANTSTR 0 static int shell_run_function(shell_context_t *ctx, const shell_command_t *cmd, void *arg) {
#define STATE_WANTSPACE 1 shell_run_data_t *data = arg;
int shell_run(int argc, char *argv[]) { if(strcmp(cmd->cmd, data->argv[0]) == 0) {
for(int i = 0; commands[i].cmd != NULL; i++) int ret = cmd->handler(ctx, data->argc, data->argv);
if(strcmp(commands[i].cmd, argv[0]) == 0)
return commands[i].handler(argc, argv);
if(set_cmds) { if(ret == 0)
for(int i = 0; set_cmds[i].cmd != NULL; i++) return 1;
if(strcmp(set_cmds[i].cmd, argv[0]) == 0) else
return set_cmds[i].handler(argc, argv); return ret;
} else
return 0;
} }
int shell_run(shell_context_t *ctx, int argc, char *argv[]) {
shell_run_data_t data = { argc, argv };
int ret = shell_enumerate_commands(ctx, shell_run_function, &data);
if(ret != 0) {
debug(LEVEL_ERROR, "Bad command '%s'\n", argv[0]); debug(LEVEL_ERROR, "Bad command '%s'\n", argv[0]);
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} else if(ret == 1) {
return 0;
} else
return ret;
} }
int shell_execute(const char *cmd) { int shell_execute(shell_context_t *ctx, const char *cmd) {
line = strdup(cmd); yyscan_t scanner;
char *ptr = line; if(yylex_init_extra(ctx, &scanner) == -1)
return -1;
ctx->line = strdup(cmd);
char *ptr = ctx->line;
int token; int token;
int state = STATE_WANTSTR; int state = STATE_WANTSTR;
int argc = 0; int argc = 0;
char **argv = NULL; char **argv = NULL;
int fret = -1;
yyrestart(NULL);
do { do {
int noway = 0; int noway = 0;
token = yylex(); token = yylex(&scanner);
if((token == TOK_SEPARATOR || token == TOK_COMMENT || token == 0)) { if((token == TOK_SEPARATOR || token == TOK_COMMENT || token == 0)) {
if(argc > 0) { if(argc > 0) {
int ret = shell_run(argc, argv); int ret = shell_run(ctx, argc, argv);
for(int i = 0; i < argc; i++) { for(int i = 0; i < argc; i++) {
free(argv[i]); free(argv[i]);
@ -139,9 +148,9 @@ int shell_execute(const char *cmd) {
argc = 0; argc = 0;
if(ret == -1) { if(ret == -1) {
free(ptr); fret = -1;
return -1; break;
} }
} }
@ -156,7 +165,7 @@ int shell_execute(const char *cmd) {
argv = realloc(argv, sizeof(char *) * argc); argv = realloc(argv, sizeof(char *) * argc);
argv[oargc] = strval; argv[oargc] = ctx->strval;
state = STATE_WANTSPACE; state = STATE_WANTSPACE;
} else { } else {
@ -167,7 +176,7 @@ int shell_execute(const char *cmd) {
case STATE_WANTSPACE: case STATE_WANTSPACE:
if(token == TOK_STRING) { if(token == TOK_STRING) {
free(strval); free(ctx->strval);
noway = 1; noway = 1;
} else if(token == TOK_SPACE) { } else if(token == TOK_SPACE) {
@ -183,9 +192,10 @@ int shell_execute(const char *cmd) {
free(argv[i]); free(argv[i]);
free(argv); free(argv);
free(ptr);
return -1; fret = -1;
break;
} }
} }
@ -193,28 +203,30 @@ int shell_execute(const char *cmd) {
free(ptr); free(ptr);
return 0; yylex_destroy(&scanner);
return fret;
} }
int shell_pull(char *buf, int maxlen) { int shell_pull(shell_context_t *ctx, char *buf, int maxlen) {
size_t len = strlen(line); size_t len = strlen(ctx->line);
if(len < maxlen) if(len < maxlen)
maxlen = len; maxlen = len;
memcpy(buf, line, maxlen); memcpy(buf, ctx->line, maxlen);
line += maxlen; ctx->line += maxlen;
return maxlen; return maxlen;
} }
void shell_fini() { void shell_fini(shell_context_t *ctx) {
device = NULL; free(ctx);
} }
int shell_source(const char *filename) { int shell_source(shell_context_t *ctx, const char *filename) {
shell_exit = 0; ctx->shell_exit = 0;
FILE *file = fopen(filename, "r"); FILE *file = fopen(filename, "r");
@ -224,8 +236,8 @@ int shell_source(const char *filename) {
char *line; char *line;
while((line = fgets(linebuf, sizeof(linebuf), file)) && !shell_exit) { while((line = fgets(ctx->linebuf, sizeof(ctx->linebuf), file)) && !ctx->shell_exit) {
if(shell_execute(line) == -1) { if(shell_execute(ctx, line) == -1) {
fclose(file); fclose(file);
return -1; return -1;
@ -237,38 +249,37 @@ int shell_source(const char *filename) {
return 0; return 0;
} }
void shell_interactive() { void shell_interactive(shell_context_t *ctx) {
shell_exit = 0; ctx->shell_exit = 0;
#ifndef WITH_READLINE #ifndef WITH_READLINE
char *line; char *line;
while(!shell_exit) { while(!ctx->shell_exit) {
fputs("jzboot> ", stdout); fputs("jzboot> ", stdout);
fflush(stdout); fflush(stdout);
line = fgets(linebuf, sizeof(linebuf), stdin); line = fgets(ctx->linebuf, sizeof(ctx->linebuf), stdin);
if(line == NULL) if(line == NULL)
break; break;
shell_execute(line); shell_execute(ctx, line);
} }
#else #else
rl_set_signals(); rl_set_signals();
while(!shell_exit) { while(!ctx->shell_exit) {
char *line = readline("jzboot> "); char *line = readline("jzboot> ");
if(line == NULL) { if(line == NULL) {
printf("line null, EOP\n");
break; break;
} }
add_history(line); add_history(line);
shell_execute(line); shell_execute(ctx, line);
free(line); free(line);
} }
@ -277,153 +288,18 @@ void shell_interactive() {
#endif #endif
} }
static int builtin_help(int argc, char *argv[]) {
for(int i = 0; commands[i].cmd != NULL; i++) {
printf("%s %s\n", commands[i].cmd, commands[i].description);
}
if(set_cmds) {
for(int i = 0; set_cmds[i].cmd != NULL; i++)
printf("%s %s\n", set_cmds[i].cmd, set_cmds[i].description);
}
return 0;
}
static int builtin_exit(int argc, char *argv[]) {
shell_exit = 1;
return 0;
}
static int builtin_source(int argc, char *argv[]) {
if(argc != 2) {
printf("Usage: %s <FILENAME>\n", argv[0]);
return -1;
}
int ret = shell_source(argv[1]);
if(ret == -1) {
fprintf(stderr, "Error while sourcing file %s: %s\n", argv[1], strerror(errno));
}
shell_exit = 0;
return ret;
}
static int builtin_echo(int argc, char *argv[]) {
if(argc < 2) {
printf("Usage: %s <STRING>\n", argv[0]);
return -1;
}
for(int i = 1; i < argc; i++) {
fputs(argv[i], stdout);
putchar((i < argc - 1) ? ' ' : '\n');
}
return 0;
}
static int builtin_sleep(int argc, char *argv[]) {
if(argc != 2) {
printf("Usage: %s <MILLISECONDS>\n", argv[0]);
return -1;
}
uint32_t ms = atoi(argv[1]);
usleep(ms * 1000);
return 0;
}
static int builtin_redetect(int argc, char *argv[]) {
if(argc != 1) {
printf("Usage: %s\n", argv[0]);
return -1;
}
if(ingenic_redetect(device) == -1) {
perror("ingenic_redetect");
return -1;
} else
return 0;
}
static int builtin_set(int argc, char *argv[]) {
if(argc == 1 && cfg_environ) {
for(int i = 0; cfg_environ[i] != NULL; i++)
printf("%s\n", cfg_environ[i]);
} else if(argc == 2) {
cfg_unsetenv(argv[1]);
} else if(argc == 3) {
cfg_setenv(argv[1], argv[2]);
} else {
printf("Usage: %s [VARIABLE] [VALUE]\n", argv[0]);
return -1;
}
return 0;
}
static int builtin_rebuildcfg(int argc, char *argv[]) {
if(argc != 1) {
printf("Usage: %s\n", argv[0]);
return -1;
}
return ingenic_rebuild(device);
}
static int builtin_safe(int argc, char *argv[]) {
if(argc < 2) {
printf("Usage: %s <COMMAND> [ARG]...\n", argv[0]);
return -1;
}
if(shell_run(argc - 1, argv + 1) == -1)
perror("shell_run");
return 0;
}
static const struct {
int set;
const char *name;
const shell_command_t *commands;
} cmdsets[] = {
{ CMDSET_SPL, "SPL", spl_cmdset },
{ CMDSET_USBBOOT, "USBBoot", usbboot_cmdset },
{ 0, NULL, NULL }
};
static void shell_update_cmdset(void *arg) { static void shell_update_cmdset(void *arg) {
set_cmds = NULL; shell_context_t *ctx = arg;
int set = ingenic_cmdset(device); ctx->set_cmds = NULL;
int set = ingenic_cmdset(ctx->device);
for(int i = 0; cmdsets[i].name != NULL; i++) { for(int i = 0; cmdsets[i].name != NULL; i++) {
if(cmdsets[i].set == set) { if(cmdsets[i].set == set) {
printf("Shell: using command set '%s', run 'help' for command list. CPU: %04X\n", cmdsets[i].name, ingenic_type(device)); printf("Shell: using command set '%s', run 'help' for command list. CPU: %04X\n", cmdsets[i].name, ingenic_type(ctx->device));
set_cmds = cmdsets[i].commands; ctx->set_cmds = cmdsets[i].commands;
return; return;
} }
@ -432,6 +308,11 @@ static void shell_update_cmdset(void *arg) {
debug(LEVEL_ERROR, "Shell: unknown cmdset %d\n", set); debug(LEVEL_ERROR, "Shell: unknown cmdset %d\n", set);
} }
void *shell_device() { void *shell_device(shell_context_t *ctx) {
return device; return ctx->device;
} }
void shell_exit(shell_context_t *ctx, int val) {
ctx->shell_exit = val;
}

34
shell.h
View File

@ -19,32 +19,30 @@
#ifndef __SHELL__H__ #ifndef __SHELL__H__
#define __SHELL__H__ #define __SHELL__H__
typedef struct { #ifndef SHELL_INTERNALS
typedef void shell_context_t;
#endif
typedef struct shell_command {
const char *cmd; const char *cmd;
const char *description; const char *description;
int (*handler)(int argc, char *argv[]); int (*handler)(shell_context_t *ctx, int argc, char *argv[]);
} shell_command_t; } shell_command_t;
int shell_init(void *ingenic); shell_context_t *shell_init(void *ingenic);
void shell_fini(); void shell_fini(shell_context_t *context);
void shell_interactive(); void shell_interactive(shell_context_t *ctx);
int shell_source(const char *filename); int shell_source(shell_context_t *ctx, const char *filename);
int shell_execute(const char *input); int shell_execute(shell_context_t *ctx, const char *input);
void *shell_device(shell_context_t *ctx);
int shell_run(shell_context_t *ctx, int argc, char *argv[]);
void *shell_device(); void shell_exit(shell_context_t *ctx, int val);
int shell_enumerate_commands(shell_context_t *ctx, int (*callback)(shell_context_t *ctx, const shell_command_t *cmd, void *arg), void *arg);
// lexer interface
extern char *strval;
#define TOK_SEPARATOR 1
#define TOK_STRING 2
#define TOK_SPACE 3
#define TOK_COMMENT 4
int shell_pull(char *buf, int maxlen);
extern const shell_command_t spl_cmdset[]; extern const shell_command_t spl_cmdset[];
extern const shell_command_t usbboot_cmdset[]; extern const shell_command_t usbboot_cmdset[];
extern const shell_command_t builtin_cmdset[];
#endif #endif

181
shell_builtins.c Normal file
View File

@ -0,0 +1,181 @@
/*
* JzBoot: an USB bootloader for JZ series of Ingenic(R) microprocessors.
* Copyright (C) 2010 Sergey Gridassov <grindars@gmail.com>,
* Peter Zotov <whitequark@whitequark.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "shell.h"
#include "config.h"
#include "ingenic.h"
static int builtin_help(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_exit(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_source(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_echo(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_sleep(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_redetect(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_rebuildcfg(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_set(shell_context_t *ctx, int argc, char *argv[]);
static int builtin_safe(shell_context_t *ctx, int argc, char *argv[]);
const shell_command_t builtin_cmdset[] = {
{ "help", "- Display this message", builtin_help },
{ "exit", "- Batch: stop current script, interactive: end session", builtin_exit },
{ "source", "<FILENAME> - run specified script", builtin_source },
{ "echo", "<STRING> - output specified string", builtin_echo },
{ "sleep", "<MILLISECONDS> - sleep a specified amount of time", builtin_sleep },
{ "set", "[VARIABLE] [VALUE] - print or set configuraton variables", builtin_set },
{ "safe", "<COMMAND> [ARG]... - run command ignoring errors", builtin_safe },
{ "redetect", " - Redetect CPU", builtin_redetect },
{ "rebuildcfg", " - Rebuild firmware configuration data", builtin_rebuildcfg },
{ NULL, NULL, NULL }
};
static int builtin_help(shell_context_t *ctx, int argc, char *argv[]) {
/* for(int i = 0; commands[i].cmd != NULL; i++) {
printf("%s %s\n", commands[i].cmd, commands[i].description);
}
if(set_cmds) {
for(int i = 0; set_cmds[i].cmd != NULL; i++)
printf("%s %s\n", set_cmds[i].cmd, set_cmds[i].description);
}*/
return 0;
}
static int builtin_exit(shell_context_t *ctx, int argc, char *argv[]) {
shell_exit(ctx, 1);
return 0;
}
static int builtin_source(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 2) {
printf("Usage: %s <FILENAME>\n", argv[0]);
return -1;
}
int ret = shell_source(ctx, argv[1]);
if(ret == -1) {
fprintf(stderr, "Error while sourcing file %s: %s\n", argv[1], strerror(errno));
}
shell_exit(ctx, 0);
return ret;
}
static int builtin_echo(shell_context_t *ctx, int argc, char *argv[]) {
if(argc < 2) {
printf("Usage: %s <STRING>\n", argv[0]);
return -1;
}
for(int i = 1; i < argc; i++) {
fputs(argv[i], stdout);
putchar((i < argc - 1) ? ' ' : '\n');
}
return 0;
}
static int builtin_sleep(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 2) {
printf("Usage: %s <MILLISECONDS>\n", argv[0]);
return -1;
}
uint32_t ms = atoi(argv[1]);
usleep(ms * 1000);
return 0;
}
static int builtin_redetect(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 1) {
printf("Usage: %s\n", argv[0]);
return -1;
}
if(ingenic_redetect(shell_device(ctx)) == -1) {
perror("ingenic_redetect");
return -1;
} else
return 0;
}
static int builtin_set(shell_context_t *ctx, int argc, char *argv[]) {
if(argc == 1 && cfg_environ) {
for(int i = 0; cfg_environ[i] != NULL; i++)
printf("%s\n", cfg_environ[i]);
} else if(argc == 2) {
cfg_unsetenv(argv[1]);
} else if(argc == 3) {
cfg_setenv(argv[1], argv[2]);
} else {
printf("Usage: %s [VARIABLE] [VALUE]\n", argv[0]);
return -1;
}
return 0;
}
static int builtin_rebuildcfg(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 1) {
printf("Usage: %s\n", argv[0]);
return -1;
}
return ingenic_rebuild(shell_device(ctx));
}
static int builtin_safe(shell_context_t *ctx, int argc, char *argv[]) {
if(argc < 2) {
printf("Usage: %s <COMMAND> [ARG]...\n", argv[0]);
return -1;
}
if(shell_run(ctx, argc - 1, argv + 1) == -1)
perror("shell_run");
return 0;
}

62
shell_internal.h Normal file
View File

@ -0,0 +1,62 @@
/*
* JzBoot: an USB bootloader for JZ series of Ingenic(R) microprocessors.
* Copyright (C) 2010 Sergey Gridassov <grindars@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SHELL_INTERNAL__H__
#define __SHELL_INTERNAL__H__
#define SHELL_INTERNALS
#define STATE_WANTSTR 0
#define STATE_WANTSPACE 1
#define TOK_SEPARATOR 1
#define TOK_STRING 2
#define TOK_SPACE 3
#define TOK_COMMENT 4
typedef struct {
void *device;
char linebuf[512];
char *strval;
char *line;
const struct shell_command *set_cmds;
int shell_exit;
} shell_context_t;
typedef struct {
int argc;
char **argv;
} shell_run_data_t;
int shell_pull(shell_context_t *ctx, char *buf, int maxlen);
#ifndef FLEX_SCANNER
typedef void *yyscan_t;
int yylex_init(yyscan_t *ptr_yy_globals);
int yylex_init_extra(shell_context_t *user_defined, yyscan_t *ptr_yy_globals);
int yylex(yyscan_t yyscanner) ;
int yylex_destroy (yyscan_t yyscanner) ;
#else
#define YY_EXTRA_TYPE shell_context_t *
#define YY_INPUT(buf, result, max_size) result = shell_pull(yyextra, buf, max_size);
#endif
#include "shell.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -17,12 +17,10 @@
*/ */
%{ %{
#include "shell.h" #include "shell_internal.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#define YY_INPUT(buf, result, max_size) result = shell_pull(buf, max_size);
static char *str_append(char *str, const char *src) { static char *str_append(char *str, const char *src) {
if(str) { if(str) {
size_t newlen = strlen(str) + strlen(src) + 1; size_t newlen = strlen(str) + strlen(src) + 1;
@ -39,16 +37,16 @@ static char *str_append(char *str, const char *src) {
return strdup(src); return strdup(src);
} }
%} %}
%option noyywrap nounput noinput batch %option noyywrap nounput noinput batch reentrant
%x STR %x STR
%% %%
["] { strval = NULL; BEGIN(STR); } ["] { yyextra->strval = NULL; BEGIN(STR); }
; return TOK_SEPARATOR; ; return TOK_SEPARATOR;
[[:space:]]+ return TOK_SPACE; [[:space:]]+ return TOK_SPACE;
[#] return TOK_COMMENT; [#] return TOK_COMMENT;
[^[:space:];"#]+ { strval = strdup(yytext); return TOK_STRING; } [^[:space:];"#]+ { yyextra->strval = strdup(yytext); return TOK_STRING; }
<STR>[^\\"]+ strval = str_append(strval, yytext); <STR>[^\\"]+ yyextra->strval = str_append(yyextra->strval, yytext);
<STR>\\["] strval = str_append(strval, "\""); <STR>\\["] yyextra->strval = str_append(yyextra->strval, "\"");
<STR>\\ strval = str_append(strval, "\\"); <STR>\\ yyextra->strval = str_append(yyextra->strval, "\\");
<STR>["] { BEGIN(INITIAL); return TOK_STRING; } <STR>["] { BEGIN(INITIAL); return TOK_STRING; }

View File

@ -26,9 +26,9 @@
#include "config.h" #include "config.h"
#include "ingenic.h" #include "ingenic.h"
static int spl_memtest(int argc, char *argv[]); static int spl_memtest(shell_context_t *ctx, int argc, char *argv[]);
static int spl_gpio(int argc, char *argv[]); static int spl_gpio(shell_context_t *ctx, int argc, char *argv[]);
static int spl_boot(int argc, char *argv[]); static int spl_boot(shell_context_t *ctx, int argc, char *argv[]);
const shell_command_t spl_cmdset[] = { const shell_command_t spl_cmdset[] = {
{ "memtest", "[BASE <SIZE>] - SDRAM test", spl_memtest }, { "memtest", "[BASE <SIZE>] - SDRAM test", spl_memtest },
@ -37,14 +37,14 @@ const shell_command_t spl_cmdset[] = {
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };
static int spl_stage1_op(uint32_t op, uint32_t pin, uint32_t base, uint32_t size) { static int spl_stage1_op(shell_context_t *ctx, uint32_t op, uint32_t pin, uint32_t base, uint32_t size) {
if(cfg_getenv("STAGE1_FILE") == NULL) { if(cfg_getenv("STAGE1_FILE") == NULL) {
printf("Variable STAGE1_FILE is not set\n"); printf("Variable STAGE1_FILE is not set\n");
return -1; return -1;
} }
int ret = ingenic_stage1_debugop(shell_device(), cfg_getenv("STAGE1_FILE"), op, pin, base, size); int ret = ingenic_stage1_debugop(shell_device(ctx), cfg_getenv("STAGE1_FILE"), op, pin, base, size);
if(ret == -1) if(ret == -1)
perror("ingenic_stage1_debugop"); perror("ingenic_stage1_debugop");
@ -52,7 +52,7 @@ static int spl_stage1_op(uint32_t op, uint32_t pin, uint32_t base, uint32_t size
return ret; return ret;
} }
static int spl_memtest(int argc, char *argv[]) { static int spl_memtest(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 1 && argc != 3) { if(argc != 1 && argc != 3) {
printf("Usage: %s [BASE <SIZE>]\n", argv[0]); printf("Usage: %s [BASE <SIZE>]\n", argv[0]);
@ -66,7 +66,7 @@ static int spl_memtest(int argc, char *argv[]) {
size = strtoul(argv[2], NULL, 0); size = strtoul(argv[2], NULL, 0);
} else { } else {
start = SDRAM_BASE; start = SDRAM_BASE;
size = ingenic_sdram_size(shell_device()); size = ingenic_sdram_size(shell_device(ctx));
} }
if(cfg_getenv("STAGE1_FILE") == NULL) { if(cfg_getenv("STAGE1_FILE") == NULL) {
@ -77,7 +77,7 @@ static int spl_memtest(int argc, char *argv[]) {
uint32_t fail; uint32_t fail;
int ret = ingenic_memtest(shell_device(), cfg_getenv("STAGE1_FILE"), start, size, &fail); int ret = ingenic_memtest(shell_device(ctx), cfg_getenv("STAGE1_FILE"), start, size, &fail);
if(ret == -1) { if(ret == -1) {
if(errno == EFAULT) { if(errno == EFAULT) {
@ -93,7 +93,7 @@ static int spl_memtest(int argc, char *argv[]) {
return ret; return ret;
} }
static int spl_gpio(int argc, char *argv[]) { static int spl_gpio(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 3 || (strcmp(argv[2], "0") && strcmp(argv[2], "1"))) { if(argc != 3 || (strcmp(argv[2], "0") && strcmp(argv[2], "1"))) {
printf("Usage: %s <PIN> <STATE>\n", argv[0]); printf("Usage: %s <PIN> <STATE>\n", argv[0]);
printf(" STATE := 0 | 1\n"); printf(" STATE := 0 | 1\n");
@ -101,15 +101,15 @@ static int spl_gpio(int argc, char *argv[]) {
return -1; return -1;
} }
return spl_stage1_op(!strcmp(argv[2], "1") ? STAGE1_DEBUG_GPIO_SET : STAGE1_DEBUG_GPIO_CLEAR, atoi(argv[1]), 0, 0); return spl_stage1_op(ctx, !strcmp(argv[2], "1") ? STAGE1_DEBUG_GPIO_SET : STAGE1_DEBUG_GPIO_CLEAR, atoi(argv[1]), 0, 0);
} }
static int spl_boot(int argc, char *argv[]) { static int spl_boot(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 1) { if(argc != 1) {
printf("Usage: %s\n", argv[0]); printf("Usage: %s\n", argv[0]);
} }
int ret = spl_stage1_op(STAGE1_DEBUG_BOOT, 0, 0, 0); int ret = spl_stage1_op(ctx, STAGE1_DEBUG_BOOT, 0, 0, 0);
if(ret == -1) if(ret == -1)
return -1; return -1;
@ -120,7 +120,7 @@ static int spl_boot(int argc, char *argv[]) {
return -1; return -1;
} }
ret = ingenic_loadstage(shell_device(), INGENIC_STAGE2, cfg_getenv("STAGE2_FILE")); ret = ingenic_loadstage(shell_device(ctx), INGENIC_STAGE2, cfg_getenv("STAGE2_FILE"));
if(ret == -1) { if(ret == -1) {
perror("ingenic_loadstage"); perror("ingenic_loadstage");
@ -128,7 +128,7 @@ static int spl_boot(int argc, char *argv[]) {
return -1; return -1;
} }
ret = ingenic_configure_stage2(shell_device()); ret = ingenic_configure_stage2(shell_device(ctx));
if(ret == -1) if(ret == -1)
perror("ingenic_configure_stage2"); perror("ingenic_configure_stage2");

View File

@ -25,14 +25,14 @@
#include "ingenic.h" #include "ingenic.h"
#include "config.h" #include "config.h"
static int usbboot_boot(int argc, char *argv[]); static int usbboot_boot(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_load(int argc, char *argv[]); static int usbboot_load(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_go(int argc, char *argv[]); static int usbboot_go(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_nquery(int argc, char *argv[]); static int usbboot_nquery(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_ndump(int argc, char *argv[]); static int usbboot_ndump(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_nerase(int argc, char *argv[]); static int usbboot_nerase(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_nprogram(int argc, char *argv[]); static int usbboot_nprogram(shell_context_t *ctx, int argc, char *argv[]);
static int usbboot_nload(int argc, char *argv[]); static int usbboot_nload(shell_context_t *ctx, int argc, char *argv[]);
const shell_command_t usbboot_cmdset[] = { const shell_command_t usbboot_cmdset[] = {
@ -51,8 +51,8 @@ const shell_command_t usbboot_cmdset[] = {
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };
static int usbboot_boot(int argc, char *argv[]) { static int usbboot_boot(shell_context_t *ctx, int argc, char *argv[]) {
int ret = ingenic_configure_stage2(shell_device()); int ret = ingenic_configure_stage2(shell_device(ctx));
if(ret == -1) if(ret == -1)
perror("ingenic_configure_stage2"); perror("ingenic_configure_stage2");
@ -60,14 +60,14 @@ static int usbboot_boot(int argc, char *argv[]) {
return ret; return ret;
} }
static int usbboot_load(int argc, char *argv[]) { static int usbboot_load(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 3) { if(argc != 3) {
printf("Usage: %s <FILE> <BASE>\n", argv[0]); printf("Usage: %s <FILE> <BASE>\n", argv[0]);
return -1; return -1;
} }
int ret = ingenic_load_sdram_file(shell_device(), strtoul(argv[2], NULL, 0), argv[1]); int ret = ingenic_load_sdram_file(shell_device(ctx), strtoul(argv[2], NULL, 0), argv[1]);
if(ret == -1) if(ret == -1)
perror("ingenic_load_sdram_file"); perror("ingenic_load_sdram_file");
@ -75,14 +75,14 @@ static int usbboot_load(int argc, char *argv[]) {
return ret; return ret;
} }
static int usbboot_go(int argc, char *argv[]) { static int usbboot_go(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 2) { if(argc != 2) {
printf("Usage: %s <ADDRESS>\n", argv[0]); printf("Usage: %s <ADDRESS>\n", argv[0]);
return -1; return -1;
} }
int ret = ingenic_go(shell_device(), strtoul(argv[1], NULL, 0)); int ret = ingenic_go(shell_device(ctx), strtoul(argv[1], NULL, 0));
if(ret == -1) if(ret == -1)
perror("ingenic_go"); perror("ingenic_go");
@ -90,7 +90,7 @@ static int usbboot_go(int argc, char *argv[]) {
return ret; return ret;
} }
static int usbboot_nquery(int argc, char *argv[]) { static int usbboot_nquery(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 2) { if(argc != 2) {
printf("Usage: %s <DEVICE>\n", argv[0]); printf("Usage: %s <DEVICE>\n", argv[0]);
@ -99,7 +99,7 @@ static int usbboot_nquery(int argc, char *argv[]) {
nand_info_t info; nand_info_t info;
int ret = ingenic_query_nand(shell_device(), atoi(argv[1]), &info); int ret = ingenic_query_nand(shell_device(ctx), atoi(argv[1]), &info);
if(ret == -1) { if(ret == -1) {
perror("ingenic_query_nand"); perror("ingenic_query_nand");
@ -119,7 +119,7 @@ static int usbboot_nquery(int argc, char *argv[]) {
return 0; return 0;
} }
static int usbboot_ndump(int argc, char *argv[]) { static int usbboot_ndump(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 5) { if(argc != 5) {
printf("Usage: %s <DEVICE> <STARTPAGE> <PAGES> <FILE>\n", argv[0]); printf("Usage: %s <DEVICE> <STARTPAGE> <PAGES> <FILE>\n", argv[0]);
@ -131,7 +131,7 @@ static int usbboot_ndump(int argc, char *argv[]) {
if(cfg_getenv("NAND_RAW")) if(cfg_getenv("NAND_RAW"))
type |= NAND_RAW; type |= NAND_RAW;
int ret = ingenic_dump_nand(shell_device(), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), type, argv[4]); int ret = ingenic_dump_nand(shell_device(ctx), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), type, argv[4]);
if(ret == -1) if(ret == -1)
perror("ingenic_dump_nand"); perror("ingenic_dump_nand");
@ -139,14 +139,14 @@ static int usbboot_ndump(int argc, char *argv[]) {
return ret; return ret;
} }
static int usbboot_nerase(int argc, char *argv[]) { static int usbboot_nerase(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 4) { if(argc != 4) {
printf("Usage: %s <DEVICE> <STARTBLOCK> <BLOCKS>\n", argv[0]); printf("Usage: %s <DEVICE> <STARTBLOCK> <BLOCKS>\n", argv[0]);
return -1; return -1;
} }
int ret = ingenic_erase_nand(shell_device(), atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); int ret = ingenic_erase_nand(shell_device(ctx), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
if(ret == -1) if(ret == -1)
perror("ingenic_erase_nand"); perror("ingenic_erase_nand");
@ -155,7 +155,7 @@ static int usbboot_nerase(int argc, char *argv[]) {
} }
static int usbboot_nprogram(int argc, char *argv[]) { static int usbboot_nprogram(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 4) { if(argc != 4) {
printf("Usage: %s <DEVICE> <STARTPAGE> <FILE>\n", argv[0]); printf("Usage: %s <DEVICE> <STARTPAGE> <FILE>\n", argv[0]);
@ -172,7 +172,7 @@ static int usbboot_nprogram(int argc, char *argv[]) {
} else } else
type = NO_OOB; type = NO_OOB;
int ret = ingenic_program_nand(shell_device(), atoi(argv[1]), atoi(argv[2]), type, argv[3]); int ret = ingenic_program_nand(shell_device(ctx), atoi(argv[1]), atoi(argv[2]), type, argv[3]);
if(ret == -1) if(ret == -1)
perror("ingenic_program_nand"); perror("ingenic_program_nand");
@ -180,14 +180,14 @@ static int usbboot_nprogram(int argc, char *argv[]) {
return ret; return ret;
} }
static int usbboot_nload(int argc, char *argv[]) { static int usbboot_nload(shell_context_t *ctx, int argc, char *argv[]) {
if(argc != 5) { if(argc != 5) {
printf("Usage: %s <DEVICE> <STARTPAGE> <PAGES> <BASE>\n", argv[0]); printf("Usage: %s <DEVICE> <STARTPAGE> <PAGES> <BASE>\n", argv[0]);
return -1; return -1;
} }
int ret = ingenic_load_nand(shell_device(), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), strtoul(argv[4], NULL, 0)); int ret = ingenic_load_nand(shell_device(ctx), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), strtoul(argv[4], NULL, 0));
if(ret == -1) if(ret == -1)
perror("ingenic_load_nand"); perror("ingenic_load_nand");