[scripting] While with break and continue
authorLynus Vaz <lynus@Arch.localdomain>
Mon, 29 Jun 2009 05:20:33 +0000 (10:50 +0530)
committerLynus Vaz <lynus@Arch.localdomain>
Mon, 29 Jun 2009 05:20:33 +0000 (10:50 +0530)
src/core/exec.c
src/hci/commands/if_cmd.c
src/tests/while.gpxe

index efa8074..3e94072 100644 (file)
@@ -43,7 +43,6 @@ int nextchar;
 
 extern struct generic_stack if_stack;
 extern struct generic_stack command_list;
-extern struct generic_stack loop_stack;
 extern int prog_ctr;
 
 /**
@@ -83,7 +82,7 @@ int execv ( const char *command, char * const argv[] ) {
        /* Hand off to command implementation */
        for_each_table_entry ( cmd, COMMANDS ) {
                if ( strcmp ( command, cmd->name ) == 0 ) {
-                       if ( TOP_GEN_STACK_INT ( &if_stack ) || !strcmp ( cmd->name, "if" ) || !strcmp ( cmd->name, "fi" ) || !strcmp ( cmd->name, "else" )
+                       if ( TOP_GEN_STACK_INT ( &if_stack ) == 1 || !strcmp ( cmd->name, "if" ) || !strcmp ( cmd->name, "fi" ) || !strcmp ( cmd->name, "else" )
                                || !strcmp ( cmd->name, "while" ) || !strcmp ( cmd->name, "done" ) )
                                return cmd->exec ( argc, ( char ** ) argv );
                        else
@@ -153,20 +152,6 @@ static int expand_command ( const char *command, struct generic_stack *argv_stac
        return argc;
 }
 
-int system_exec_list ( void ) {
-       int rc = 0;
-       while ( prog_ctr < SIZE_GEN_STACK ( &command_list ) ) {
-               const char *command = ELEMENT_GEN_STACK_STRING ( &command_list, prog_ctr );
-               printf ( "command = [%s]\n", command );
-               printf ( "pc = %d. size of loop_stack = %d, command list = %d\n", prog_ctr, loop_stack.tos + 1, SIZE_GEN_STACK ( &command_list ) );
-               //printf ( "pc = %d. command = [%s]\n", prog_ctr, 
-               if ( ( rc = system ( command ) ) != 0 )
-                       return rc;
-       }
-       printf ( "end of list: %d\n", prog_ctr );
-       return rc;
-}
-
 /**
  * Execute command line
  *
@@ -184,7 +169,6 @@ int system ( const char *command ) {
                push_generic_stack ( &command_list, &command, 1 );
                //printf ( "appending %s at %d\n", TOP_GEN_STACK_STRING ( &command_list ), prog_ctr );
        }
-       
 
        argc = expand_command ( command, &argv_stack );
        if ( argc < 0 ) {
index 4a8a66e..bdad281 100644 (file)
@@ -6,13 +6,19 @@
 
 struct generic_stack if_stack;
 struct generic_stack else_stack;
-struct generic_stack loop_stack;
+static struct generic_stack loop_stack;
 struct generic_stack command_list;
 int prog_ctr;
 int isnum ( char *string, long *num );
 
 int system ( const char * );
 
+struct while_info {
+       int loop_start;
+       int if_pos;
+       int is_continue;
+};
+
 static int if_exec ( int argc, char **argv ) {
        long cond;
        int zero = 0;
@@ -89,7 +95,7 @@ void init_if ( void ) {
        int one = 1;
        init_generic_stack ( &if_stack, sizeof ( int ) );
        init_generic_stack ( &else_stack, sizeof ( int ) );
-       init_generic_stack ( &loop_stack, sizeof ( int ) );
+       init_generic_stack ( &loop_stack, sizeof ( struct while_info ) );
        init_generic_stack ( &command_list, sizeof ( char * ) );
        prog_ctr = 0;
        push_generic_stack ( &if_stack, &one, 0 );
@@ -102,6 +108,7 @@ struct init_fn initialise_if __init_fn ( INIT_NORMAL ) = {
 };
 
 static int while_exec ( int argc, char **argv ) {
+       struct while_info w;
        if ( argc != 2 ) {
                printf ( "Syntax: while <condition>\n" );
                return 1;
@@ -109,7 +116,12 @@ static int while_exec ( int argc, char **argv ) {
        if ( if_exec ( argc, argv ) != 0 )
                return 1;
        TOP_GEN_STACK_INT ( &else_stack ) = 1;
-       push_generic_stack ( &loop_stack, &prog_ctr, 0 );
+       
+       w.loop_start = prog_ctr;
+       w.if_pos = if_stack.tos;
+       w.is_continue = 0;
+       
+       push_generic_stack ( &loop_stack, &w, 0 );
        //printf ( "pc = %d. size of loop_stack = %d\n", prog_ctr, SIZE_GEN_STACK ( &loop_stack ) );
        return 0;
 }
@@ -122,7 +134,7 @@ struct command while_command __command = {
 static int done_exec ( int argc, char **argv ) {
        int cond;
        int tmp_pc;
-       int pot;
+       struct while_info pot;
        int rc = 0;
        if ( argc != 1 ) {
                printf ( "Syntax: %s\n", argv[0] );
@@ -139,9 +151,9 @@ static int done_exec ( int argc, char **argv ) {
        pop_generic_stack ( &if_stack, &cond );
        pop_generic_stack ( &loop_stack, &pot );
        
-       while ( cond ) {
+       while ( cond || pot.is_continue ) {
                tmp_pc = prog_ctr;
-               prog_ctr = pot;
+               prog_ctr = pot.loop_start;
                while ( prog_ctr < tmp_pc ) {
                        if ( ( rc = system ( ELEMENT_GEN_STACK_STRING ( &command_list, prog_ctr ) ) ) ) 
                                return rc;
@@ -155,4 +167,40 @@ static int done_exec ( int argc, char **argv ) {
 struct command done_command __command = {
        .name = "done",
        .exec = done_exec,
-};
\ No newline at end of file
+};
+
+static int break_exec ( int argc, char **argv ) {
+       int pos;
+       struct while_info *w;
+       if ( argc != 1 ) {
+               printf ( "Syntax: %s\n", argv[0] );
+               return 1;
+       }
+       w = ( ( struct while_info * ) loop_stack.ptr + ( loop_stack.tos ) );
+       for ( pos = w->if_pos; pos < SIZE_GEN_STACK ( &if_stack ); pos++ )
+               ELEMENT_GEN_STACK_INT ( &if_stack, pos ) = 0;
+       return 0;
+}
+
+struct command break_command __command = {
+       .name = "break",
+       .exec = break_exec,
+};
+
+static int continue_exec ( int argc, char **argv ) {
+       struct while_info *w;
+       if ( argc != 1 ) {
+               printf ( "Syntax: %s\n", argv[0] );
+               return 1;
+       }
+       if ( break_exec ( argc, argv ) )
+               return 1;
+       w = ( ( struct while_info * ) loop_stack.ptr + ( loop_stack.tos ) );
+       w->is_continue = 1;
+       return 0;
+}
+
+struct command continue_command __command = {
+       .name = "continue",
+       .exec = continue_exec,
+};
index 3507038..c0ccf28 100644 (file)
@@ -1,10 +1,17 @@
 #!gpxe
-set a 500
+set a 10
 while $(${a} > 0)
-set b 2
-while $(${b} > 0)
-echo ${a}, ${b}
-set b $(${b} - 1)
-done
-set a $(${a} - 1)
+       if $(${a} == 3 )
+               break
+       fi
+       set b 5
+       while $(${b} > 0)
+               echo ${a}, ${b}
+               if $(${b} == 5)
+                       set b 2
+                       continue
+               fi
+               set b $(${b} - 1)
+       done
+       set a $(${a} - 1)
 done