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