socsvn commit: r268168 - soc2014/pedrosouza/lua_loader/head/sys/boot/common
pedrosouza at FreeBSD.org
pedrosouza at FreeBSD.org
Fri May 16 17:00:25 UTC 2014
Author: pedrosouza
Date: Fri May 16 17:00:22 2014
New Revision: 268168
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=268168
Log:
Update loader interpreter to use the interp struct interface
Added:
soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.h
soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_simple.c
Modified:
soc2014/pedrosouza/lua_loader/head/sys/boot/common/Makefile.inc
soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.c
soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_forth.c
Modified: soc2014/pedrosouza/lua_loader/head/sys/boot/common/Makefile.inc
==============================================================================
--- soc2014/pedrosouza/lua_loader/head/sys/boot/common/Makefile.inc Fri May 16 16:36:07 2014 (r268167)
+++ soc2014/pedrosouza/lua_loader/head/sys/boot/common/Makefile.inc Fri May 16 17:00:22 2014 (r268168)
@@ -2,6 +2,7 @@
SRCS+= boot.c commands.c console.c devopen.c interp.c
SRCS+= interp_backslash.c interp_parse.c ls.c misc.c
+SRCS+= interp_simple.c
SRCS+= module.c panic.c
.if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64"
Modified: soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.c
==============================================================================
--- soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.c Fri May 16 16:36:07 2014 (r268167)
+++ soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.c Fri May 16 17:00:22 2014 (r268168)
@@ -36,55 +36,17 @@
#include <stand.h>
#include <string.h>
#include "bootstrap.h"
+#include "interp.h"
-#ifdef BOOT_FORTH
-#include "ficl.h"
-#define RETURN(x) stackPushINT(bf_vm->pStack,!x); return(x)
-
-extern FICL_VM *bf_vm;
-#else
-#define RETURN(x) return(x)
-#endif
#define MAXARGS 20 /* maximum number of arguments allowed */
-static void prompt(void);
-
-#ifndef BOOT_FORTH
-static int perform(int argc, char *argv[]);
-
-/*
- * Perform the command
- */
-int
-perform(int argc, char *argv[])
-{
- int result;
- struct bootblk_command **cmdp;
- bootblk_cmd_t *cmd;
-
- if (argc < 1)
- return(CMD_OK);
-
- /* set return defaults; a successful command will override these */
- command_errmsg = command_errbuf;
- strcpy(command_errbuf, "no error message");
- cmd = NULL;
- result = CMD_ERROR;
-
- /* search the command set for the command */
- SET_FOREACH(cmdp, Xcommand_set) {
- if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name))
- cmd = (*cmdp)->c_fn;
- }
- if (cmd != NULL) {
- result = (cmd)(argc, argv);
- } else {
- command_errmsg = "unknown command";
- }
- RETURN(result);
-}
-#endif /* ! BOOT_FORTH */
+struct interp *interp =
+#ifdef BOOT_FORTH
+ &boot_interp_forth;
+#else
+ &boot_interp_simple;
+#endif
/*
* Interactive mode
@@ -93,20 +55,14 @@
interact(void)
{
static char input[256]; /* big enough? */
-#ifndef BOOT_FORTH
- int argc;
- char **argv;
-#endif
-#ifdef BOOT_FORTH
- bf_init();
-#endif
+ INTERP_INIT(interp);
/*
* Read our default configuration
*/
- if (include("/boot/loader.rc") != CMD_OK)
- include("/boot/boot.conf");
+ if (INTERP_INCL(interp, "/boot/loader.rc") != CMD_OK)
+ INTERP_INCL(interp, "/boot/boot.conf");
printf("\n");
/*
* Before interacting, we might want to autoboot.
@@ -127,18 +83,7 @@
input[0] = '\0';
prompt();
ngets(input, sizeof(input));
-#ifdef BOOT_FORTH
- bf_vm->sourceID.i = 0;
- bf_run(input);
-#else
- if (!parse(&argc, &argv, input)) {
- if (perform(argc, argv))
- printf("%s: %s\n", argv[0], command_errmsg);
- free(argv);
- } else {
- printf("parse error\n");
- }
-#endif
+ INTERP_RUN(interp, input);
}
}
@@ -169,7 +114,7 @@
res=CMD_OK;
for (i = 1; (i < argc) && (res == CMD_OK); i++)
- res = include(argvbuf[i]);
+ res = INTERP_INCL(interp, argvbuf[i]);
for (i = 0; i < argc; i++)
free(argvbuf[i]);
@@ -179,165 +124,42 @@
}
/*
- * Header prepended to each line. The text immediately follows the header.
- * We try to make this short in order to save memory -- the loader has
- * limited memory available, and some of the forth files are very long.
+ * Perform the command
*/
-struct includeline
-{
- struct includeline *next;
-#ifndef BOOT_FORTH
- int flags;
- int line;
-#define SL_QUIET (1<<0)
-#define SL_IGNOREERR (1<<1)
-#endif
- char text[0];
-};
-
int
-include(const char *filename)
+perform(int argc, char *argv[])
{
- struct includeline *script, *se, *sp;
- char input[256]; /* big enough? */
-#ifdef BOOT_FORTH
- int res;
- char *cp;
- int prevsrcid, fd, line;
-#else
- int argc,res;
- char **argv, *cp;
- int fd, flags, line;
-#endif
+ int result;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
- if (((fd = open(filename, O_RDONLY)) == -1)) {
- sprintf(command_errbuf,"can't open '%s': %s", filename, strerror(errno));
- return(CMD_ERROR);
- }
+ if (argc < 1)
+ return(CMD_OK);
- /*
- * Read the script into memory.
- */
- script = se = NULL;
- line = 0;
-
- while (fgetstr(input, sizeof(input), fd) >= 0) {
- line++;
-#ifdef BOOT_FORTH
- cp = input;
-#else
- flags = 0;
- /* Discard comments */
- if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0)
- continue;
- cp = input;
- /* Echo? */
- if (input[0] == '@') {
- cp++;
- flags |= SL_QUIET;
- }
- /* Error OK? */
- if (input[0] == '-') {
- cp++;
- flags |= SL_IGNOREERR;
- }
-#endif
- /* Allocate script line structure and copy line, flags */
- if (*cp == '\0')
- continue; /* ignore empty line, save memory */
- sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
- /* On malloc failure (it happens!), free as much as possible and exit */
- if (sp == NULL) {
- while (script != NULL) {
- se = script;
- script = script->next;
- free(se);
- }
- sprintf(command_errbuf, "file '%s' line %d: memory allocation "
- "failure - aborting", filename, line);
- return (CMD_ERROR);
- }
- strcpy(sp->text, cp);
-#ifndef BOOT_FORTH
- sp->flags = flags;
- sp->line = line;
-#endif
- sp->next = NULL;
-
- if (script == NULL) {
- script = sp;
- } else {
- se->next = sp;
- }
- se = sp;
- }
- close(fd);
-
- /*
- * Execute the script
- */
-#ifndef BOOT_FORTH
- argv = NULL;
-#else
- prevsrcid = bf_vm->sourceID.i;
- bf_vm->sourceID.i = fd;
-#endif
- res = CMD_OK;
- for (sp = script; sp != NULL; sp = sp->next) {
-
-#ifdef BOOT_FORTH
- res = bf_run(sp->text);
- if (res != VM_OUTOFTEXT) {
- sprintf(command_errbuf, "Error while including %s, in the line:\n%s", filename, sp->text);
- res = CMD_ERROR;
- break;
- } else
- res = CMD_OK;
-#else
- /* print if not being quiet */
- if (!(sp->flags & SL_QUIET)) {
- prompt();
- printf("%s\n", sp->text);
- }
+ /* set return defaults; a successful command will override these */
+ command_errmsg = command_errbuf;
+ strcpy(command_errbuf, "no error message");
+ cmd = NULL;
+ result = CMD_ERROR;
- /* Parse the command */
- if (!parse(&argc, &argv, sp->text)) {
- if ((argc > 0) && (perform(argc, argv) != 0)) {
- /* normal command */
- printf("%s: %s\n", argv[0], command_errmsg);
- if (!(sp->flags & SL_IGNOREERR)) {
- res=CMD_ERROR;
- break;
- }
- }
- free(argv);
- argv = NULL;
- } else {
- printf("%s line %d: parse error\n", filename, sp->line);
- res=CMD_ERROR;
- break;
- }
-#endif
+ /* search the command set for the command */
+ SET_FOREACH(cmdp, Xcommand_set) {
+ if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name))
+ cmd = (*cmdp)->c_fn;
}
-#ifndef BOOT_FORTH
- if (argv != NULL)
- free(argv);
-#else
- bf_vm->sourceID.i = prevsrcid;
-#endif
- while(script != NULL) {
- se = script;
- script = script->next;
- free(se);
+ if (cmd != NULL) {
+ result = (cmd)(argc, argv);
+ } else {
+ command_errmsg = "unknown command";
}
- return(res);
+ return result;
}
/*
* Emit the current prompt; use the same syntax as the parser
* for embedding environment variables.
*/
-static void
+void
prompt(void)
{
char *pr, *p, *cp, *ev;
Added: soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp.h Fri May 16 17:00:22 2014 (r268168)
@@ -0,0 +1,46 @@
+typedef void interp_init_t(void *ctx);
+typedef int interp_run_t(void *ctx, const char *input);
+typedef int interp_incl_t(void *ctx, const char *filename);
+
+struct interp {
+ interp_init_t *init;
+ interp_run_t *run;
+ interp_incl_t *incl;
+ void *context;
+};
+
+#define INTERP_INIT(i) do { \
+ if (((i) != NULL) && ((i)->init != NULL)) { \
+ ((i)->init((i)->context)); \
+ } \
+} while (0)
+
+#define INTERP_RUN(i, input) \
+ ((i)->run(((i)->context), input))
+
+#define INTERP_INCL(i, filename) \
+ ((i)->incl(((i)->context), filename))
+
+
+
+extern struct interp boot_interp_simple;
+extern struct interp boot_interp_forth;
+/*
+extern struct interp boot_interp_tcl;
+extern struct interp boot_interp_lua;
+*/
+
+extern struct interp *interp;
+
+int perform(int argc, char *argv[]);
+void prompt(void);
+
+struct includeline
+{
+ struct includeline *next;
+ int flags;
+ int line;
+#define SL_QUIET (1<<0)
+#define SL_IGNOREERR (1<<1)
+ char text[0];
+};
\ No newline at end of file
Modified: soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_forth.c
==============================================================================
--- soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_forth.c Fri May 16 16:36:07 2014 (r268167)
+++ soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_forth.c Fri May 16 17:00:22 2014 (r268168)
@@ -32,6 +32,7 @@
#include <stand.h>
#include "bootstrap.h"
#include "ficl.h"
+#include "interp.h"
extern char bootprog_rev[];
@@ -60,10 +61,14 @@
/*
* BootForth Interface to Ficl Forth interpreter.
*/
+struct interp_forth_softc {
+ FICL_SYSTEM *bf_sys;
+ FICL_VM *bf_vm;
+ FICL_WORD *pInterp;
+};
+struct interp_forth_softc forth_softc = { NULL, NULL, NULL };
-FICL_SYSTEM *bf_sys;
-FICL_VM *bf_vm;
-FICL_WORD *pInterp;
+#define RETURN(x) stackPushINT(bf_vm->pStack,!x); return(x)
/*
* Shim for taking commands from BF and passing them out to 'standard'
@@ -241,55 +246,64 @@
* Initialise the Forth interpreter, create all our commands as words.
*/
void
-bf_init(void)
+interp_forth_init(void *ctx)
{
+ struct interp_forth_softc *softc;
struct bootblk_command **cmdp;
char create_buf[41]; /* 31 characters-long builtins */
int fd;
- bf_sys = ficlInitSystem(BF_DICTSIZE);
- bf_vm = ficlNewVM(bf_sys);
+ softc = ctx;
+
+ assert((softc->bf_sys == NULL) && (softc->bf_vm == NULL) &&
+ (softc->pInterp == NULL)); /* No Forth context at this stage */
+
+ softc->bf_sys = ficlInitSystem(BF_DICTSIZE);
+ softc->bf_vm = ficlNewVM(softc->bf_sys);
/* Put all private definitions in a "builtins" vocabulary */
- ficlExec(bf_vm, "vocabulary builtins also builtins definitions");
+ ficlExec(softc->bf_vm, "vocabulary builtins also builtins definitions");
/* Builtin constructor word */
- ficlExec(bf_vm, BUILTIN_CONSTRUCTOR);
+ ficlExec(softc->bf_vm, BUILTIN_CONSTRUCTOR);
/* make all commands appear as Forth words */
SET_FOREACH(cmdp, Xcommand_set) {
- ficlBuild(bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT);
- ficlExec(bf_vm, "forth definitions builtins");
+ ficlBuild(softc->bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT);
+ ficlExec(softc->bf_vm, "forth definitions builtins");
sprintf(create_buf, "builtin: %s", (*cmdp)->c_name);
- ficlExec(bf_vm, create_buf);
- ficlExec(bf_vm, "builtins definitions");
+ ficlExec(softc->bf_vm, create_buf);
+ ficlExec(softc->bf_vm, "builtins definitions");
}
- ficlExec(bf_vm, "only forth definitions");
+ ficlExec(softc->bf_vm, "only forth definitions");
/* Export some version numbers so that code can detect the loader/host version */
- ficlSetEnv(bf_sys, "FreeBSD_version", __FreeBSD_version);
- ficlSetEnv(bf_sys, "loader_version",
+ ficlSetEnv(softc->bf_sys, "FreeBSD_version", __FreeBSD_version);
+ ficlSetEnv(softc->bf_sys, "loader_version",
(bootprog_rev[0] - '0') * 10 + (bootprog_rev[2] - '0'));
/* try to load and run init file if present */
if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) {
- (void)ficlExecFD(bf_vm, fd);
+ (void)ficlExecFD(softc->bf_vm, fd);
close(fd);
}
/* Do this last, so /boot/boot.4th can change it */
- pInterp = ficlLookup(bf_sys, "interpret");
+ softc->pInterp = ficlLookup(softc->bf_sys, "interpret");
}
/*
* Feed a line of user input to the Forth interpreter
*/
int
-bf_run(char *line)
+interp_forth_run(void *ctx, const char *line)
{
+ struct interp_forth_softc *softc;
int result;
- result = ficlExec(bf_vm, line);
+ softc = ctx;
+
+ result = ficlExec(softc->bf_vm, (char*)line);
DEBUG("ficlExec '%s' = %d", line, result);
switch (result) {
@@ -314,7 +328,31 @@
if (result == VM_USEREXIT)
panic("interpreter exit");
- setenv("interpret", bf_vm->state ? "" : "OK", 1);
+ setenv("interpret", softc->bf_vm->state ? "" : "OK", 1);
return result;
}
+
+int
+interp_forth_incl(void *ctx, const char *filename)
+{
+ struct interp_forth_softc *softc;
+ int fd;
+
+ softc = ctx;
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ printf("can't open %s\n", filename);
+ return (CMD_ERROR);
+ }
+ return (ficlExecFD(softc->bf_vm, fd));
+}
+
+
+struct interp boot_interp_forth = {
+ .init = interp_forth_init,
+ .run = interp_forth_run,
+ .incl = interp_forth_incl,
+ .context = &forth_softc,
+};
Added: soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_simple.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2014/pedrosouza/lua_loader/head/sys/boot/common/interp_simple.c Fri May 16 17:00:22 2014 (r268168)
@@ -0,0 +1,155 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+#include "interp.h"
+
+struct interp_simple_softc {
+ int dummy;
+};
+
+void
+interp_simple_init(void *ctx)
+{
+
+ (void)ctx; /* Silent the compiler */
+}
+
+int
+interp_simple_run(void *ctx, const char *input)
+{
+ struct interp_simple_softc *softc;
+ int argc;
+ char **argv;
+
+ softc = ctx;
+ (void)softc; /* Currently unused */
+
+ if (!parse(&argc, &argv, input)) {
+ if (perform(argc, argv))
+ printf("%s: %s\n", argv[0], command_errmsg);
+ free(argv);
+ } else {
+ printf("parse error\n");
+ }
+ return 0;
+}
+
+int
+interp_simple_incl(void *ctx, const char *filename)
+{
+ struct includeline *script, *se, *sp;
+ char input[256]; /* big enough? */
+ int argc,res;
+ char **argv, *cp;
+ int fd, flags, line;
+
+ (void)ctx; /* Silent the compiler */
+
+ if (((fd = open(filename, O_RDONLY)) == -1)) {
+ sprintf(command_errbuf,"can't open '%s': %s\n", filename, strerror(errno));
+ return(CMD_ERROR);
+ }
+
+ /*
+ * Read the script into memory.
+ */
+ script = se = NULL;
+ line = 0;
+
+ while (fgetstr(input, sizeof(input), fd) >= 0) {
+ line++;
+ flags = 0;
+ /* Discard comments */
+ if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0)
+ continue;
+ cp = input;
+ /* Echo? */
+ if (input[0] == '@') {
+ cp++;
+ flags |= SL_QUIET;
+ }
+ /* Error OK? */
+ if (input[0] == '-') {
+ cp++;
+ flags |= SL_IGNOREERR;
+ }
+ /* Allocate script line structure and copy line, flags */
+ if (*cp == '\0')
+ continue; /* ignore empty line, save memory */
+ sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
+ /* On malloc failure (it happens!), free as much as possible and exit */
+ if (sp == NULL) {
+ while (script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ sprintf(command_errbuf, "file '%s' line %d: memory allocation "
+ "failure - aborting\n", filename, line);
+ return (CMD_ERROR);
+ }
+ strcpy(sp->text, cp);
+ sp->flags = flags;
+ sp->line = line;
+ sp->next = NULL;
+
+ if (script == NULL) {
+ script = sp;
+ } else {
+ se->next = sp;
+ }
+ se = sp;
+ }
+ close(fd);
+
+ /*
+ * Execute the script
+ */
+ argv = NULL;
+ res = CMD_OK;
+ for (sp = script; sp != NULL; sp = sp->next) {
+
+ /* print if not being quiet */
+ if (!(sp->flags & SL_QUIET)) {
+ prompt();
+ printf("%s\n", sp->text);
+ }
+
+ /* Parse the command */
+ if (!parse(&argc, &argv, sp->text)) {
+ if ((argc > 0) && (perform(argc, argv) != 0)) {
+ /* normal command */
+ printf("%s: %s\n", argv[0], command_errmsg);
+ if (!(sp->flags & SL_IGNOREERR)) {
+ res=CMD_ERROR;
+ break;
+ }
+ }
+ free(argv);
+ argv = NULL;
+ } else {
+ printf("%s line %d: parse error\n", filename, sp->line);
+ res=CMD_ERROR;
+ break;
+ }
+ }
+ if (argv != NULL)
+ free(argv);
+ while(script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ return(res);
+}
+
+struct interp boot_interp_simple = {
+ .init = interp_simple_init,
+ .run = interp_simple_run,
+ .incl = interp_simple_incl,
+ .context = NULL,
+};
+
More information about the svn-soc-all
mailing list