<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<tt>Michael Brown wrote:</tt>
<blockquote type="cite" cite="mid:201003051630.24203.mbrown@fensystems.co.uk">
<title>Re: [gPXE-devel] Minor Scripting Improvements</title>
<!-- Converted from text/plain format -->
<p><tt><font size="2">Looking at the patch itself...<br>
<br>
Could this be rearranged to avoid goto? We generally use goto only for<br>
structured error clean-up.<br>
</font></tt></p>
</blockquote>
<tt><br>
Ok.<br>
<br>
</tt>
<blockquote type="cite" cite="mid:201003051630.24203.mbrown@fensystems.co.uk">
<p><tt><font size="2">Also, using -ENOTSUP as a magic value meaning
"loop" seems kind of icky. <br>
There's a similarity between "exit" and "loopif" here; both commands
need to<br>
set temporary state that affects the "move to next line of script"
logic. <br>
Maybe have "loopif" set a flag as well; still fairly icky but at least
it's<br>
icky in the same way that "exit" currently is.</font></tt></p>
</blockquote>
<tt><br>
How about abuse of the same state variable? Something like this
80-byte cost attachment... I'm not too sure why it costs so much.<br>
<br>
If the user types in 'loopif' manually at the CLI, they'd get an
unexpected 'exit', however. 'loopif' is really only useful for scripts.<br>
<br>
Thanks again.<br>
<br>
- Shao Miller<br>
-----<br>
<br>
diff --git a/src/hci/shell.c b/src/hci/shell.c<br>
index 5bedbdc..825dac3 100644<br>
--- a/src/hci/shell.c<br>
+++ b/src/hci/shell.c<br>
@@ -35,13 +35,13 @@ FILE_LICENCE ( GPL2_OR_LATER );<br>
static const char shell_prompt[] = "gPXE> ";<br>
<br>
/** Flag set in order to exit shell */<br>
-static int exit_flag = 0;<br>
+int shell_exit_flag = 0;<br>
<br>
/** "exit" command body */<br>
static int exit_exec ( int argc, char **argv __unused ) {<br>
<br>
if ( argc == 1 ) {<br>
- exit_flag = 1;<br>
+ shell_exit_flag = 1;<br>
} else {<br>
printf ( "Usage: exit\n"<br>
"Exits the command shell\n" );<br>
@@ -91,8 +91,8 @@ struct command help_command __command = {<br>
void shell ( void ) {<br>
char *line;<br>
<br>
- exit_flag = 0;<br>
- while ( ! exit_flag ) {<br>
+ shell_exit_flag = 0;<br>
+ while ( ! shell_exit_flag ) {<br>
line = readline ( shell_prompt );<br>
if ( line ) {<br>
system ( line );<br>
diff --git a/src/image/script.c b/src/image/script.c<br>
index 0835ecb..bc29116 100644<br>
--- a/src/image/script.c<br>
+++ b/src/image/script.c<br>
@@ -29,7 +29,9 @@ FILE_LICENCE ( GPL2_OR_LATER );<br>
#include <stdlib.h><br>
#include <ctype.h><br>
#include <errno.h><br>
+#include <gpxe/command.h><br>
#include <gpxe/image.h><br>
+#include <gpxe/shell.h><br>
<br>
struct image_type script_image_type __image_type ( PROBE_NORMAL );<br>
<br>
@@ -51,7 +53,9 @@ static int script_exec ( struct image *image ) {<br>
unregister_image ( image );<br>
<br>
while ( offset < image->len ) {<br>
- <br>
+ /* Reset the loop/exit flag */<br>
+ shell_exit_flag = 0;<br>
+<br>
/* Find length of next line, excluding any terminating '\n' */<br>
eol = memchr_user ( image->data, offset, '\n',<br>
( image->len - offset ) );<br>
@@ -72,9 +76,19 @@ static int script_exec ( struct image *image ) {<br>
goto done;<br>
}<br>
}<br>
- <br>
- /* Move to next line */<br>
- offset += ( len + 1 );<br>
+<br>
+ switch ( shell_exit_flag ) {<br>
+ case 1:<br>
+ /* "exit" command should exit this script */<br>
+ goto done;<br>
+ case 2:<br>
+ /* "loopif" command told us to loop */<br>
+ offset = 0;<br>
+ break;<br>
+ default:<br>
+ /* Move to next line */<br>
+ offset += ( len + 1 );<br>
+ }<br>
}<br>
<br>
rc = 0;<br>
@@ -124,3 +138,16 @@ struct image_type script_image_type __image_type (
PROBE_NORMAL ) = {<br>
.load = script_load,<br>
.exec = script_exec,<br>
};<br>
+<br>
+/** "loopif" command body */<br>
+static int loopif_exec ( int argc, char **argv ) {<br>
+ if ( argc > 1 && strtoul ( argv[1], NULL, 0 ) )<br>
+ shell_exit_flag = 2;<br>
+ return 0;<br>
+}<br>
+<br>
+/** "loopif" command definition */<br>
+struct command loopif_command __command = {<br>
+ .name = "loopif",<br>
+ .exec = loopif_exec,<br>
+};<br>
diff --git a/src/include/gpxe/shell.h b/src/include/gpxe/shell.h<br>
index a65a344..148ea83 100644<br>
--- a/src/include/gpxe/shell.h<br>
+++ b/src/include/gpxe/shell.h<br>
@@ -9,6 +9,7 @@<br>
<br>
FILE_LICENCE ( GPL2_OR_LATER );<br>
<br>
+extern int shell_exit_flag;<br>
extern void shell ( void );<br>
<br>
#endif /* _GPXE_SHELL_H */<br>
<br>
</tt>
</body>
</html>