diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h index 87543c0a8190..5d6a63db2b11 100644 --- a/stand/common/bootstrap.h +++ b/stand/common/bootstrap.h @@ -45,7 +45,7 @@ extern char command_errbuf[COMMAND_ERRBUFSZ]; #define CMD_FATAL 4 /* interp.c */ -void interact(void); +void interact(const char *rc); int include(const char *filename); /* interp_backslash.c */ @@ -54,6 +54,10 @@ char *backslash(const char *str); /* interp_parse.c */ int parse(int *argc, char ***argv, const char *str); +/* interp_forth.c */ +void bf_init(const char *rc); +int bf_run(char *line); + /* boot.c */ int autoboot(int timeout, char *prompt); void autoboot_maybe(void); diff --git a/stand/common/interp.c b/stand/common/interp.c index 8e284e97993b..f4117b9b3e58 100644 --- a/stand/common/interp.c +++ b/stand/common/interp.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 1998 Michael Smith - * Copyright (c) 2011 Wojciech A. Koszek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,6 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #include __FBSDID("$FreeBSD$"); @@ -36,60 +36,112 @@ __FBSDID("$FreeBSD$"); #include #include #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 */ -struct interp *interp = -#if defined(BOOT_FORTH) - &boot_interp_forth; -#else - &boot_interp_simple; -#endif +static void prompt(void); +#ifndef BOOT_FORTH +static int perform(int argc, char *argv[]); + +/* + * Perform the command + */ int -default_load_config(void *ctx) +perform(int argc, char *argv[]) { - return INTERP_INCL(interp, "/boot/loader.rc"); + 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 */ /* * Interactive mode */ void -interact(void) +interact(const char *rc) { - static char input[256]; /* big enough? */ + static char input[256]; /* big enough? */ +#ifndef BOOT_FORTH + int argc; + char **argv; +#endif - INTERP_INIT(interp); +#ifdef BOOT_FORTH + bf_init((rc) ? "" : NULL); +#endif - /* - * Read our default configuration - */ - INTERP_LOAD_DEF_CONFIG(interp); - printf("\n"); - /* - * Before interacting, we might want to autoboot. - */ - autoboot_maybe(); + if (rc == NULL) { + /* Read our default configuration. */ + include("/boot/loader.rc"); + } else if (*rc != '\0') + include(rc); - /* - * Not autobooting, go manual - */ - printf("\nType '?' for a list of commands, 'help' for more detailed help.\n"); - if (getenv("prompt") == NULL) - setenv("prompt", "${interpret}", 1); - if (getenv("interpret") == NULL) - setenv("interpret", "OK", 1); + printf("\n"); + /* + * Before interacting, we might want to autoboot. + */ + autoboot_maybe(); + + /* + * Not autobooting, go manual + */ + printf("\nType '?' for a list of commands, 'help' for more detailed help.\n"); + if (getenv("prompt") == NULL) + setenv("prompt", "${interpret}", 1); + if (getenv("interpret") == NULL) + setenv("interpret", "OK", 1); + - for (;;) { - input[0] = '\0'; - prompt(); - ngets(input, sizeof(input)); - INTERP_RUN(interp, input); + for (;;) { + 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 + } } /* @@ -106,90 +158,214 @@ COMMAND_SET(include, "include", "read commands from a file", command_include); static int command_include(int argc, char *argv[]) { - int i; - int res; - char **argvbuf; + int i; + int res; + char **argvbuf; - /* - * Since argv is static, we need to save it here. - */ - argvbuf = (char**) calloc((u_int)argc, sizeof(char*)); - for (i = 0; i < argc; i++) - argvbuf[i] = strdup(argv[i]); + /* + * Since argv is static, we need to save it here. + */ + argvbuf = (char**) calloc((u_int)argc, sizeof(char*)); + for (i = 0; i < argc; i++) + argvbuf[i] = strdup(argv[i]); - res=CMD_OK; - for (i = 1; (i < argc) && (res == CMD_OK); i++) - res = INTERP_INCL(interp, argvbuf[i]); + res=CMD_OK; + for (i = 1; (i < argc) && (res == CMD_OK); i++) + res = include(argvbuf[i]); - for (i = 0; i < argc; i++) - free(argvbuf[i]); - free(argvbuf); + for (i = 0; i < argc; i++) + free(argvbuf[i]); + free(argvbuf); - if (res != CMD_OK) - printf("%s", command_errbuf); - - return(res); + return(res); } /* - * Perform the command + * 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. */ -int -perform(int argc, char *argv[]) +struct includeline { - int result; - struct bootblk_command **cmdp; - bootblk_cmd_t *cmd; + struct includeline *next; +#ifndef BOOT_FORTH + int flags; + int line; +#define SL_QUIET (1<<0) +#define SL_IGNOREERR (1<<1) +#endif + char text[0]; +}; - if (argc < 1) - return(CMD_OK); +int +include(const char *filename) +{ + 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 - /* set return defaults; a successful command will override these */ - command_errmsg = command_errbuf; - strcpy(command_errbuf, "no error message"); - cmd = NULL; - result = CMD_ERROR; + if (((fd = open(filename, O_RDONLY)) == -1)) { + snprintf(command_errbuf, sizeof(command_errbuf), + "can't open '%s': %s", filename, strerror(errno)); + return(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; + /* + * 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; } - if (cmd != NULL) { - result = (cmd)(argc, argv); + /* 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); + } + snprintf(command_errbuf, sizeof(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 { - command_errmsg = "unknown command"; + se->next = sp; } - return result; + 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) { + snprintf(command_errbuf, sizeof(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); + } + + /* 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 + } +#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); + } + return(res); } /* * Emit the current prompt; use the same syntax as the parser * for embedding environment variables. */ -void -prompt(void) +static void +prompt(void) { - char *pr, *p, *cp, *ev; + char *pr, *p, *cp, *ev; + + if ((cp = getenv("prompt")) == NULL) + cp = ">"; + pr = p = strdup(cp); - if ((cp = getenv("prompt")) == NULL) - cp = ">"; - pr = p = strdup(cp); - - while (*p != 0) { - if ((*p == '$') && (*(p+1) == '{')) { - for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++) - ; - *cp = 0; - ev = getenv(p + 2); - - if (ev != NULL) - printf("%s", ev); - p = cp + 1; - continue; - } - putchar(*p++); + while (*p != 0) { + if ((*p == '$') && (*(p+1) == '{')) { + for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++) + ; + *cp = 0; + ev = getenv(p + 2); + + if (ev != NULL) + printf("%s", ev); + p = cp + 1; + continue; } - putchar(' '); - free(pr); + putchar(*p++); + } + putchar(' '); + free(pr); } diff --git a/stand/common/interp.h b/stand/common/interp.h deleted file mode 100644 index 12ef3516ddea..000000000000 --- a/stand/common/interp.h +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (c) 2011 Wojciech A. Koszek - * Copyright (c) 2014 Pedro Souza - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -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); -typedef int interp_load_def_t(void *ctx); // load default configuration files - -struct interp { - interp_init_t *init; - interp_run_t *run; - interp_incl_t *incl; - interp_load_def_t *load_configs; - 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)) - -#define INTERP_LOAD_DEF_CONFIG(i) \ - ((i)->load_configs(((i)->context))) - - - -extern struct interp boot_interp_simple; -extern struct interp boot_interp_forth; -extern struct interp boot_interp_lua; - - -extern struct interp *interp; - -int perform(int argc, char *argv[]); -void prompt(void); - -/* - * Default config loader for interp_simple & intep_forth - * Use it if your interpreter does not use a custom config - * file. - * - * Calls interp->include with 'loader.rc' or 'boot.conf' - */ -int default_load_config(void *ctx); - -struct includeline -{ - struct includeline *next; - int flags; - int line; -#define SL_QUIET (1<<0) -#define SL_IGNOREERR (1<<1) - char text[0]; -}; diff --git a/stand/common/interp_forth.c b/stand/common/interp_forth.c index 42e8ca30cd6c..a3b77769d38a 100644 --- a/stand/common/interp_forth.c +++ b/stand/common/interp_forth.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 1998 Michael Smith - * Copyright (c) 2011 Wojciech A. Koszek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +32,6 @@ __FBSDID("$FreeBSD$"); #include #include "bootstrap.h" #include "ficl.h" -#include "interp.h" extern unsigned bootprog_rev; @@ -62,14 +60,9 @@ extern unsigned bootprog_rev; /* * 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 }; -#define RETURN(x) stackPushINT(bf_vm->pStack,!x); return(x) +FICL_SYSTEM *bf_sys; +FICL_VM *bf_vm; /* * Shim for taking commands from BF and passing them out to 'standard' @@ -78,93 +71,91 @@ struct interp_forth_softc forth_softc = { NULL, NULL, NULL }; static void bf_command(FICL_VM *vm) { - char *name, *line, *tail, *cp; - size_t len; - struct bootblk_command **cmdp; - bootblk_cmd_t *cmd; - int nstrings, i; - int argc, result; - char **argv; + char *name, *line, *tail, *cp; + size_t len; + struct bootblk_command **cmdp; + bootblk_cmd_t *cmd; + int nstrings, i; + int argc, result; + char **argv; - /* Get the name of the current word */ - name = vm->runningWord->name; - - /* Find our command structure */ - cmd = NULL; - SET_FOREACH(cmdp, Xcommand_set) { - if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) - cmd = (*cmdp)->c_fn; - } - if (cmd == NULL) - panic("callout for unknown command '%s'", name); - - /* Check whether we have been compiled or are being interpreted */ - if (stackPopINT(vm->pStack)) { - /* - * Get parameters from stack, in the format: - * an un ... a2 u2 a1 u1 n -- - * Where n is the number of strings, a/u are pairs of - * address/size for strings, and they will be concatenated - * in LIFO order. - */ - nstrings = stackPopINT(vm->pStack); - for (i = 0, len = 0; i < nstrings; i++) - len += stackFetch(vm->pStack, i * 2).i + 1; - line = malloc(strlen(name) + len + 1); - strcpy(line, name); - - if (nstrings) - for (i = 0; i < nstrings; i++) { - len = stackPopINT(vm->pStack); - cp = stackPopPtr(vm->pStack); - strcat(line, " "); - strncat(line, cp, len); - } - } else { - /* Get remainder of invocation */ - tail = vmGetInBuf(vm); - for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++) - ; - - line = malloc(strlen(name) + len + 2); - strcpy(line, name); - if (len > 0) { - strcat(line, " "); - strncat(line, tail, len); - vmUpdateTib(vm, tail + len); - } - } - DEBUG("cmd '%s'", line); - - command_errmsg = command_errbuf; - command_errbuf[0] = 0; - if (!parse(&argc, &argv, line)) { - result = (cmd)(argc, argv); - free(argv); - } else { - result=BF_PARSE; - } - - /* XXX Not sure about the rest of this -- imp */ - - switch (result) { - case CMD_CRIT: - printf("%s\n", command_errmsg); - break; - case CMD_FATAL: - panic("%s\n", command_errmsg); - } - - free(line); + /* Get the name of the current word */ + name = vm->runningWord->name; + + /* Find our command structure */ + cmd = NULL; + SET_FOREACH(cmdp, Xcommand_set) { + if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) + cmd = (*cmdp)->c_fn; + } + if (cmd == NULL) + panic("callout for unknown command '%s'", name); + + /* Check whether we have been compiled or are being interpreted */ + if (stackPopINT(vm->pStack)) { /* - * If there was error during nested ficlExec(), we may no longer have - * valid environment to return. Throw all exceptions from here. + * Get parameters from stack, in the format: + * an un ... a2 u2 a1 u1 n -- + * Where n is the number of strings, a/u are pairs of + * address/size for strings, and they will be concatenated + * in LIFO order. */ - if (result != CMD_OK) - vmThrow(vm, result); + nstrings = stackPopINT(vm->pStack); + for (i = 0, len = 0; i < nstrings; i++) + len += stackFetch(vm->pStack, i * 2).i + 1; + line = malloc(strlen(name) + len + 1); + strcpy(line, name); - /* This is going to be thrown!!! */ - stackPushINT(vm->pStack,result); + if (nstrings) + for (i = 0; i < nstrings; i++) { + len = stackPopINT(vm->pStack); + cp = stackPopPtr(vm->pStack); + strcat(line, " "); + strncat(line, cp, len); + } + } else { + /* Get remainder of invocation */ + tail = vmGetInBuf(vm); + for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++) + ; + + line = malloc(strlen(name) + len + 2); + strcpy(line, name); + if (len > 0) { + strcat(line, " "); + strncat(line, tail, len); + vmUpdateTib(vm, tail + len); + } + } + DEBUG("cmd '%s'", line); + + command_errmsg = command_errbuf; + command_errbuf[0] = 0; + if (!parse(&argc, &argv, line)) { + result = (cmd)(argc, argv); + free(argv); + } else { + result=BF_PARSE; + } + + switch (result) { + case CMD_CRIT: + printf("%s\n", command_errmsg); + break; + case CMD_FATAL: + panic("%s\n", command_errmsg); + } + + free(line); + /* + * If there was error during nested ficlExec(), we may no longer have + * valid environment to return. Throw all exceptions from here. + */ + if (result != CMD_OK) + vmThrow(vm, result); + + /* This is going to be thrown!!! */ + stackPushINT(vm->pStack,result); } /* @@ -258,22 +249,15 @@ bf_command(FICL_VM *vm) /* * Initialise the Forth interpreter, create all our commands as words. */ -static void -interp_forth_init(void *ctx) +void +bf_init(const char *rc) { - struct interp_forth_softc *softc; struct bootblk_command **cmdp; char create_buf[41]; /* 31 characters-long builtins */ - FICL_SYSTEM *bf_sys; - FICL_VM *bf_vm; + int fd; - softc = ctx; - - assert((softc->bf_sys == NULL) && (softc->bf_vm == NULL) && - (softc->pInterp == NULL)); /* No Forth context at this stage */ - - bf_sys = softc->bf_sys = ficlInitSystem(BF_DICTSIZE); - bf_vm = softc->bf_vm = ficlNewVM(bf_sys); + bf_sys = ficlInitSystem(BF_DICTSIZE); + bf_vm = ficlNewVM(bf_sys); /* Put all private definitions in a "builtins" vocabulary */ ficlExec(bf_vm, "vocabulary builtins also builtins definitions"); @@ -294,20 +278,28 @@ interp_forth_init(void *ctx) /* 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", bootprog_rev); + + /* try to load and run init file if present */ + if (rc == NULL) + rc = "/boot/boot.4th"; + if (*rc != '\0') { + fd = open(rc, O_RDONLY); + if (fd != -1) { + (void)ficlExecFD(bf_vm, fd); + close(fd); + } + } } /* * Feed a line of user input to the Forth interpreter */ -static int -interp_forth_run(void *ctx, const char *line) +int +bf_run(char *line) { - struct interp_forth_softc *softc; int result; - softc = ctx; - - result = ficlExec(softc->bf_vm, (char *)line); + result = ficlExec(bf_vm, line); DEBUG("ficlExec '%s' = %d", line, result); switch (result) { @@ -334,34 +326,7 @@ interp_forth_run(void *ctx, const char *line) if (result == VM_USEREXIT) panic("interpreter exit"); - setenv("interpret", softc->bf_vm->state ? "" : "OK", 1); + setenv("interpret", bf_vm->state ? "" : "OK", 1); return (result); } - -static 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) { - /* Hihger layers print the error message */ - snprintf(command_errbuf, sizeof(command_errbuf), - "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, - .load_configs = default_load_config, - .context = &forth_softc -}; diff --git a/stand/common/interp_simple.c b/stand/common/interp_simple.c deleted file mode 100644 index 587cedeae031..000000000000 --- a/stand/common/interp_simple.c +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * Copyright (c) 2011 Wojciech A. Koszek - * Copyright (c) 2014 Pedro Souza - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include "bootstrap.h" -#include "interp.h" - -struct interp_simple_softc { - int dummy; -}; - -static void -interp_simple_init(void *ctx) -{ - - (void)ctx; /* Silent the compiler */ -} - -static 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; -} - -static 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, - .load_configs = default_load_config, - .context = NULL -}; diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index 516c47e37705..f367f292d387 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -501,7 +501,7 @@ main(int argc, CHAR16 *argv[]) #endif } - interact(); /* doesn't return */ + interact(NULL); /* doesn't return */ return (EFI_SUCCESS); /* keep compiler happy */ } diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c index 543dae1af71a..81bc2ff55dd0 100644 --- a/stand/i386/loader/main.c +++ b/stand/i386/loader/main.c @@ -232,7 +232,7 @@ main(void) bios_getsmap(); - interact(); + interact(NULL); /* if we ever get here, it is an error */ return (1); diff --git a/stand/loader.mk b/stand/loader.mk index eea1e60a3ade..7236c8614e06 100644 --- a/stand/loader.mk +++ b/stand/loader.mk @@ -59,8 +59,6 @@ SRCS+= pnp.c .if ${MK_FORTH} != "no" SRCS+= interp_forth.c .include "${BOOTSRC}/ficl.mk" -.else -SRCS+= interp_simple.c .endif .if defined(BOOT_PROMPT_123) diff --git a/stand/mips/beri/loader/main.c b/stand/mips/beri/loader/main.c index 71b69b781572..2d201d8011ee 100644 --- a/stand/mips/beri/loader/main.c +++ b/stand/mips/beri/loader/main.c @@ -149,7 +149,7 @@ main(int argc, char *argv[], char *envv[], struct bootinfo *bootinfop) printf("bootpath=\"%s\"\n", bootpath); #endif - interact(); + interact(NULL); return (0); } diff --git a/stand/ofw/common/main.c b/stand/ofw/common/main.c index 128542c922f3..3c0bbdf97a26 100644 --- a/stand/ofw/common/main.c +++ b/stand/ofw/common/main.c @@ -157,7 +157,7 @@ main(int (*openfirm)(void *)) archsw.arch_readin = ofw_readin; archsw.arch_autoload = ofw_autoload; - interact(); /* doesn't return */ + interact(NULL); /* doesn't return */ OF_exit(); diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c index e72a7482046c..7a24c163d5c4 100644 --- a/stand/powerpc/kboot/main.c +++ b/stand/powerpc/kboot/main.c @@ -122,7 +122,7 @@ main(int argc, const char **argv) setenv("loaddev", bootdev, 1); setenv("LINES", "24", 1); - interact(); /* doesn't return */ + interact(NULL); /* doesn't return */ return (0); } diff --git a/stand/powerpc/ps3/main.c b/stand/powerpc/ps3/main.c index db9ea50959fa..be8708aadefa 100644 --- a/stand/powerpc/ps3/main.c +++ b/stand/powerpc/ps3/main.c @@ -140,7 +140,7 @@ main(void) setenv("LINES", "24", 1); setenv("hw.platform", "ps3", 1); - interact(); /* doesn't return */ + interact(NULL); /* doesn't return */ return (0); } diff --git a/stand/sparc64/loader/main.c b/stand/sparc64/loader/main.c index 140885d50e8e..d3c17c5ea6cc 100644 --- a/stand/sparc64/loader/main.c +++ b/stand/sparc64/loader/main.c @@ -902,7 +902,7 @@ main(int (*openfirm)(void *)) printf("bootpath=\"%s\"\n", bootpath); /* Give control to the machine independent loader code. */ - interact(); + interact(NULL); return (1); } diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c index 5540059797cc..c4efb1f69bd9 100644 --- a/stand/uboot/common/main.c +++ b/stand/uboot/common/main.c @@ -500,7 +500,7 @@ main(int argc, char **argv) archsw.arch_readin = uboot_readin; archsw.arch_autoload = uboot_autoload; - interact(); /* doesn't return */ + interact(NULL); /* doesn't return */ return (0); } diff --git a/stand/userboot/userboot/main.c b/stand/userboot/userboot/main.c index 95bff1745a0f..7f59eb7c3bdd 100644 --- a/stand/userboot/userboot/main.c +++ b/stand/userboot/userboot/main.c @@ -142,7 +142,7 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks) if (setjmp(jb)) return; - interact(); /* doesn't return */ + interact(NULL); /* doesn't return */ exit(0); }