summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/common/interp.c')
-rw-r--r--sys/boot/common/interp.c131
1 files changed, 100 insertions, 31 deletions
diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c
index 69a2fc3..5c4aa51 100644
--- a/sys/boot/common/interp.c
+++ b/sys/boot/common/interp.c
@@ -23,12 +23,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: interp.c,v 1.3 1998/09/03 02:10:07 msmith Exp $
+ * $Id: interp.c,v 1.4 1998/09/14 18:27:04 msmith Exp $
*/
/*
* Simple commandline interpreter, toplevel and misc.
*
- * XXX may be obsoleted by BootFORTH
+ * XXX may be obsoleted by BootFORTH or some other, better, interpreter.
*/
#include <stand.h>
@@ -87,11 +87,10 @@ interact(void)
source("/boot/boot.conf");
printf("\n");
/*
- * Before interacting, we might want to autoboot
+ * Before interacting, we might want to autoboot.
*/
- if (getenv("no_autoboot") == NULL)
- autoboot(10, NULL); /* try to boot automatically */
-
+ autoboot_maybe();
+
/*
* Not autobooting, go manual
*/
@@ -114,7 +113,13 @@ interact(void)
}
/*
- * Read command from a file
+ * Read commands from a file, then execute them.
+ *
+ * We store the commands in memory and close the source file so that the media
+ * holding it can safely go away while we are executing.
+ *
+ * Commands may be prefixed with '@' (so they aren't displayed) or '-' (so
+ * that the script won't stop if they fail).
*/
COMMAND_SET(source, "source", "read commands from a file", command_source);
@@ -128,39 +133,103 @@ command_source(int argc, char *argv[])
return(CMD_OK);
}
+struct sourceline
+{
+ char *text;
+ int flags;
+ int line;
+#define SL_QUIET (1<<0)
+#define SL_IGNOREERR (1<<1)
+ struct sourceline *next;
+};
+
void
source(char *filename)
{
- char input[256]; /* big enough? */
- int argc;
- char **argv, *cp;
- int fd;
+ struct sourceline *script, *se, *sp;
+ char input[256]; /* big enough? */
+ int argc;
+ char **argv, *cp;
+ int fd, flags, line;
if (((fd = open(filename, O_RDONLY)) == -1)) {
printf("can't open '%s': %s\n", filename, strerror(errno));
- } else {
- while (fgetstr(input, sizeof(input), fd) > 0) {
-
- /* Discard comments */
- if (input[0] == '#')
- continue;
- cp = input;
- /* Echo? */
- if (input[0] == '@') {
- cp++;
- } else {
- prompt();
- printf("%s\n", input);
- }
+ return;
+ }
- if (!parse(&argc, &argv, cp)) {
- if ((argc > 0) &&
- (perform(argc, argv) != 0))
- printf("%s: %s\n", argv[0], command_errmsg);
- free(argv);
+ /*
+ * Read the script into memory.
+ */
+ script = se = NULL;
+ line = 0;
+
+ while (fgetstr(input, sizeof(input), fd) > 0) {
+ line++;
+ flags = 0;
+ /* Discard comments */
+ if (input[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 */
+ sp = malloc(sizeof(struct sourceline) + strlen(input) + 1);
+ sp->text = (char *)sp + sizeof(struct sourceline);
+ strcpy(sp->text, input);
+ 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;
+ 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 > 1) && (perform(argc, argv) != 0)) {
+ /* normal command */
+ printf("%s: %s\n", argv[0], command_errmsg);
+ if (!(sp->flags & SL_IGNOREERR))
+ break;
}
+ free(argv);
+ argv = NULL;
+ } else {
+ printf("%s line %d: parse error\n", filename, sp->line);
+ break;
}
- close(fd);
+ }
+ if (argv != NULL)
+ free(argv);
+ while(script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
}
}
OpenPOWER on IntegriCloud