Date: Fri, 16 May 2014 17:00:23 GMT From: pedrosouza@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r268168 - soc2014/pedrosouza/lua_loader/head/sys/boot/common Message-ID: <201405161700.s4GH0NPg069178@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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, +}; +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405161700.s4GH0NPg069178>