[scripting] Modified if-else-fi branches
authorLynus Vaz <lynus@Arch.localdomain>
Fri, 26 Jun 2009 07:13:38 +0000 (12:43 +0530)
committerLynus Vaz <lynus@Arch.localdomain>
Fri, 26 Jun 2009 07:13:38 +0000 (12:43 +0530)
src/core/exec.c
src/hci/arith.c
src/hci/commands/if_cmd.c
src/hci/gen_stack.c
src/hci/parse.c
src/include/gpxe/gen_stack.h
src/include/gpxe/parse.h

index ed85b30..25b31f1 100644 (file)
@@ -42,7 +42,6 @@ int optind;
 int nextchar;
 
 extern struct generic_stack if_stack;
-extern int if_tos;
 
 /**
  * Execute command
@@ -81,7 +80,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 ( !if_stack.ptr || ( ( int * ) if_stack.ptr )[if_tos] || !strcmp ( cmd->name, "if" ) || !strcmp ( cmd->name, "fi" ) || !strcmp ( cmd->name, "else" ) )
+                       if ( TOP_GEN_STACK_INT ( &if_stack ) || !strcmp ( cmd->name, "if" ) || !strcmp ( cmd->name, "fi" ) || !strcmp ( cmd->name, "else" ) )
                                return cmd->exec ( argc, ( char ** ) argv );
                        else
                                return 0;
@@ -92,24 +91,6 @@ int execv ( const char *command, char * const argv[] ) {
        return -ENOEXEC;
 }
 
-struct char_table dquote_table[3] = {
-       { .token = '"', .type = ENDQUOTES },
-       { .token = '$', .type = FUNC, .next.parse_func = dollar_expand },
-       { .token = '\\', .type = FUNC, .next.parse_func = parse_escape }
-};
-struct char_table squote_table[1] = {
-       { .token = '\'', .type = ENDQUOTES }
-};
-static struct char_table table[6] = {
-       { .token = '\\', .type = FUNC, .next.parse_func = parse_escape },
-       { .token = '"', .type = TABLE, .next = 
-                               {.next_table = { .ntable = dquote_table, .len = 3 } } },
-       { .token = '$', .type = FUNC, .next.parse_func = dollar_expand },
-       { .token = '\'', .type = TABLE, .next = { .next_table = { .ntable = squote_table, .len = 1 } } },
-       { .token = ' ', .type = ENDTOK },
-       { .token = '\t', .type = ENDTOK }
-};
-
 static int expand_command ( const char *command, struct generic_stack *argv_stack ) {
        char *head, *end;
        char *nstring;
@@ -121,8 +102,7 @@ static int expand_command ( const char *command, struct generic_stack *argv_stac
        argc = 0;
        init_generic_stack ( argv_stack, sizeof ( int ) );
        
-       stringcpy ( &expcmd, command );
-       if ( ! expcmd.value ) {
+       if ( !stringcpy ( &expcmd, command ) ) {
                argc = -ENOMEM;
                return argc;
        }
@@ -137,7 +117,10 @@ static int expand_command ( const char *command, struct generic_stack *argv_stac
                if ( *head == '#' ) { /* Comment is a new word that starts with # */
                        break;
                }
-               stringcpy ( &expcmd, head );
+               if ( !stringcpy ( &expcmd, head ) ) {
+                       argc = -ENOMEM;
+                       break;
+               }
                head = expcmd.value;
                nstring = expand_string ( &expcmd, &head, &end, table, 6, 0, &success );
                if ( nstring ) {
@@ -147,6 +130,12 @@ static int expand_command ( const char *command, struct generic_stack *argv_stac
                                expcmd.value = NULL;
                                stringcpy ( &expcmd, end );
                                *end = 0;
+                               /*
+                               So if the command is: word1 word2 word3
+                               argv_stack:     word1\0word2 word3
+                                                       word2\0word3
+                                                       word3
+                               */
                        }
                } else {
                        argc = -ENOMEM;
@@ -176,18 +165,15 @@ int system ( const char *command ) {
                rc = argc;
        } else {
                char **argv;
-                               
-               argv = realloc ( argv_stack.ptr, sizeof ( char * ) * ( argc + 1 ) );
-               if ( argv ) {
-                       argv_stack.ptr = argv;
+               if ( ! push_generic_stack ( &argv_stack, NULL, 0 ) ) {
+                       argv = ( char ** ) argv_stack.ptr;
                        argv[argc] = NULL;
-               
                        if ( argc > 0 )
                                rc = execv ( argv[0], argv );
                }
        }
        
-       free_generic_stack ( &argv_stack, 0 );
+       free_generic_stack ( &argv_stack, 1 );
        return rc;
 }
 
index 7187483..1f321d7 100644 (file)
@@ -58,30 +58,6 @@ static signed const char op_prio[NUM_OPS]    = { 10, 10, 9, 9, 9, 8, 8, 6, 6, 7, 6,
 static void ignore_whitespace ( void );
 static int parse_expr ( char **buffer );
 
-struct char_table table[21] = {
-       { .token = '\\', .type = FUNC, .next.parse_func = parse_escape },
-       { .token = '"', .type = TABLE, .next = { .next_table = { .ntable = dquote_table, .len = 3 } } },
-       { .token = '$', .type = FUNC, .next.parse_func = dollar_expand },
-       { .token = '\'', .type = TABLE, .next = { .next_table = { .ntable = squote_table, .len = 1 } } },
-       { .token = ' ', .type = ENDQUOTES },
-       { .token = '\t', .type = ENDQUOTES },
-       { .token = '~', .type = ENDTOK },
-       { .token = '!', .type = ENDTOK },
-       { .token = '*', .type = ENDTOK },
-       { .token = '/', .type = ENDTOK },
-       { .token = '%', .type = ENDTOK },
-       { .token = '+', .type = ENDTOK },
-       { .token = '-', .type = ENDTOK },
-       { .token = '<', .type = ENDTOK },
-       { .token = '=', .type = ENDTOK },
-       { .token = '>', .type = ENDTOK },
-       { .token = '&', .type = ENDTOK },
-       { .token = '|', .type = ENDTOK },
-       { .token = '^', .type = ENDTOK },
-       { .token = '(', .type = ENDTOK },
-       { .token = ')', .type = ENDTOK }
-};
-
 static void input ( void ) {
        char t_op[3] = { '\0', '\0', '\0'};
        char *p1, *p2;
@@ -100,7 +76,7 @@ static void input ( void ) {
        }
        tok = 0;
        
-       tmp = expand_string ( input_str, &inp_ptr, &end, table, 21, 0, &success );
+       tmp = expand_string ( input_str, &inp_ptr, &end, arith_table, 21, 0, &success );
        if ( !tmp ) {
                tok = -1;
                err_val = -ENOMEM;
index e0443a0..884d53b 100644 (file)
@@ -2,10 +2,10 @@
 #include <unistd.h>
 #include <gpxe/command.h>
 #include <gpxe/gen_stack.h>
+#include <gpxe/init.h>
 
-struct generic_stack if_stack = { .ptr = NULL, .tos = -1, .size = sizeof ( int ) };
-static struct generic_stack else_stack = { .ptr = NULL, .tos = -1, .size = sizeof ( int ) };
-int if_tos = 0;
+struct generic_stack if_stack;
+static struct generic_stack else_stack;
 int isnum ( char *string, long *num );
 
 static int if_exec ( int argc, char **argv ) {
@@ -13,21 +13,20 @@ static int if_exec ( int argc, char **argv ) {
        int zero = 0;
        if ( argc != 2 ) {
                printf ( "Syntax: if <condition>\n" );
-               return -1;
+               return 1;
        }
        
        if ( !isnum ( argv[1], &cond ) ) {
-               printf ( "non-numeric condition\n" );
-               return -1;
+               printf ( "non-numeric condition: %s\n", argv[1] );
+               return 1;
        }
-       cond = cond ? 1 : 0;
-       push_generic_stack ( &else_stack, &zero, 0 );
-       push_generic_stack ( &if_stack, &cond, 0 );
-       
-       if ( ( if_tos == -1 || ( ( int * ) if_stack.ptr )[if_tos] ) && if_stack.tos - if_tos == 1 )             /* If the top of logical stack == 1 and the current command has been pushed over it */
-               if_tos++;
-       
-       //printf ( "Condition is %ld\n", cond );
+       cond = TOP_GEN_STACK_INT ( &if_stack ) ? ( cond ? 1 : 0 ) : 0;
+       if ( ( push_generic_stack ( &else_stack, &zero, 0 ) < 0 ) || ( push_generic_stack ( &if_stack, &cond, 0 ) < 0 ) ) {
+               free_generic_stack ( &if_stack );
+               free_generic_stack ( &else_stack );
+               return 1;
+       }
+
        return 0;
 }
 
@@ -40,16 +39,15 @@ static int fi_exec ( int argc, char **argv ) {
        int cond;
        if ( argc != 1 ) {
                printf ( "Syntax: %s\n", argv[0] );
-               return -1;
+               return 1;
        }
        
-       if ( pop_generic_stack ( &if_stack, &cond ) == 0 ) {
-               if ( if_tos - 1 == if_stack.tos ) {
-                       if_tos = if_stack.tos;
-               }
+       if ( if_stack.tos > 0 ) {       
+               if ( pop_generic_stack ( &if_stack, &cond ) < 0 )
+                       return 1;
        } else {
                printf ( "fi without if\n" );
-               return -1;
+               return 1;
        }
        return 0;               
 }
@@ -63,20 +61,34 @@ struct command fi_command __command = {
 static int else_exec ( int argc, char **argv ) {
        if ( argc != 1 ) {
                printf ( "Syntax: %s\n", argv[0] );
+               return 1;
        }
 
-       if ( ( ( int * ) else_stack.ptr )[else_stack.tos] != 0 ) {
+       if ( TOP_GEN_STACK_INT ( &else_stack ) != 0 ) {
                printf ( "else without if\n" );
-               return -1;
+               return 1;
        }
        
-       if ( if_tos == if_stack.tos ) {
-               ( ( int * ) if_stack.ptr )[if_stack.tos] = !( ( ( int * ) if_stack.ptr )[if_stack.tos] );
-       }
+       if ( ELEMENT_GEN_STACK_INT ( &if_stack, if_stack.tos - 1 ) )
+               TOP_GEN_STACK_INT ( &if_stack ) = !TOP_GEN_STACK_INT ( &if_stack );
+       
        return 0;
 }
 
 struct command else_command __command = {
        .name = "else",
        .exec = else_exec,
+};
+
+void init_if ( void ) {
+       int one = 1;
+       init_generic_stack ( &if_stack, sizeof ( int ) );
+       init_generic_stack ( &else_stack, sizeof ( int ) );
+       push_generic_stack ( &if_stack, &one, 0 );
+       push_generic_stack ( &else_stack, &one, 0 );
+       return;
+}
+
+struct init_fn initialise_if __init_fn ( INIT_NORMAL ) = {
+       .initialise = init_if,
 };
\ No newline at end of file
index 209b8c2..5859cc6 100644 (file)
@@ -5,15 +5,12 @@
 
 #include <gpxe/gen_stack.h>
 
-
-
 void init_generic_stack ( struct generic_stack *stack, size_t size ) {
        stack->ptr = NULL;
        stack->tos = -1;
        stack->size = size;
 }
 
-
 int pop_generic_stack ( struct generic_stack *stack, void *ptr ) {
        if ( stack->tos >= 0 ) {
                void *nptr;
index e6ead10..0a5b448 100644 (file)
@@ -5,6 +5,48 @@
 #include <stdlib.h>
 #include <gpxe/settings.h>
 
+const struct char_table arith_table[21] = {
+       { .token = '\\', .type = FUNC, .next.parse_func = parse_escape },
+       { .token = '"', .type = TABLE, .next = { .next_table = { .ntable = dquote_table, .len = 3 } } },
+       { .token = '$', .type = FUNC, .next.parse_func = dollar_expand },
+       { .token = '\'', .type = TABLE, .next = { .next_table = { .ntable = squote_table, .len = 1 } } },
+       { .token = ' ', .type = ENDQUOTES },
+       { .token = '\t', .type = ENDQUOTES },
+       { .token = '~', .type = ENDTOK },
+       { .token = '!', .type = ENDTOK },
+       { .token = '*', .type = ENDTOK },
+       { .token = '/', .type = ENDTOK },
+       { .token = '%', .type = ENDTOK },
+       { .token = '+', .type = ENDTOK },
+       { .token = '-', .type = ENDTOK },
+       { .token = '<', .type = ENDTOK },
+       { .token = '=', .type = ENDTOK },
+       { .token = '>', .type = ENDTOK },
+       { .token = '&', .type = ENDTOK },
+       { .token = '|', .type = ENDTOK },
+       { .token = '^', .type = ENDTOK },
+       { .token = '(', .type = ENDTOK },
+       { .token = ')', .type = ENDTOK }
+};
+
+const struct char_table dquote_table[3] = {
+       { .token = '"', .type = ENDQUOTES },
+       { .token = '$', .type = FUNC, .next.parse_func = dollar_expand },
+       { .token = '\\', .type = FUNC, .next.parse_func = parse_escape }
+};
+const struct char_table squote_table[1] = {
+       { .token = '\'', .type = ENDQUOTES }
+};
+const struct char_table table[6] = {
+       { .token = '\\', .type = FUNC, .next.parse_func = parse_escape },
+       { .token = '"', .type = TABLE, .next = 
+                               {.next_table = { .ntable = dquote_table, .len = 3 } } },
+       { .token = '$', .type = FUNC, .next.parse_func = dollar_expand },
+       { .token = '\'', .type = TABLE, .next = { .next_table = { .ntable = squote_table, .len = 1 } } },
+       { .token = ' ', .type = ENDTOK },
+       { .token = '\t', .type = ENDTOK }
+};
+
 char * string3cat ( struct string *s1, const char *s2, const char *s3 ) { /* The len is the size of s1 */
        char *tmp = s1->value;
        asprintf ( &s1->value, "%s%s%s", s1->value, s2, s3 );
@@ -92,6 +134,10 @@ char * dollar_expand ( struct string *s, char *inp, char ** end ) {
 
 char * parse_escape ( struct string *s, char *input, char **end ) {
        char *exp;
+       if ( ! input[1] ) {
+               printf ( "stray \\\n" );
+               return s->value;
+       }
        *input = 0;
        *end = input + 2;
        if ( input[1] == '\n' ) {
@@ -154,7 +200,12 @@ char * expand_string ( struct string *s, char **head, char **end, const struct c
                                                *success = 1;
                                                *cur_pos = 0;
                                                tmp = s->value;
-                                               stringcat ( s, cur_pos + 1 );
+                                               
+                                               if ( !stringcat ( s, cur_pos + 1 ) ) {
+                                                       printf ( "stringcat failed\n" );
+                                                       return NULL;
+                                               }
+                                               /* tmp is now invalid. Should not be dereferenced */
                                                cur_pos = s->value + ( cur_pos - tmp );
                                                if ( !expand_string ( s, &cur_pos, &end, tline->next.next_table.ntable, tline->next.next_table.len, 1, &s2 ) ) {
                                                        return NULL;
@@ -164,13 +215,9 @@ char * expand_string ( struct string *s, char **head, char **end, const struct c
                                        break;
                                case FUNC: /* Call another function */
                                        {
-                                               char *nstr;
-                                               
                                                *success = 1;
-                                               nstr = tline->next.parse_func ( s, cur_pos, &cur_pos );
-                                               if ( !nstr ) {
+                                               if ( ! tline->next.parse_func ( s, cur_pos, &cur_pos ) )
                                                        return NULL;
-                                               }
                                        }
                                        break;
                                        
index d72c267..4d82a92 100644 (file)
@@ -16,4 +16,9 @@ int push_generic_stack ( struct generic_stack *stack, void *str, int is_string )
 int pop_generic_stack ( struct generic_stack *stack, void *ptr );
 void free_generic_stack ( struct generic_stack *stack, int on_stack );
 
+/* convenience macros */
+#define TOP_GEN_STACK_INT( stack ) ( ( ( int * ) ( stack )->ptr )[( stack )->tos] )
+#define ELEMENT_GEN_STACK_INT( stack, pos ) ( ( ( int * ) ( stack )->ptr )[pos] )
+#define SIZE_GEN_STACK( stack ) ( stack->tos )
+
 #endif
\ No newline at end of file
index 388294d..0fdd952 100644 (file)
@@ -17,7 +17,7 @@ struct char_table {
        int type;
        union {
                struct {
-                       struct char_table *ntable;
+                       const struct char_table *ntable;
                        int len;
                } next_table;
                char * ( *parse_func ) ( struct string *, char *, char ** );
@@ -36,7 +36,9 @@ char * string3cat ( struct string *s1, const char *s2, const char *s3 );
 char * stringcpy ( struct string *s1, const char *s2 );
 char * stringcat ( struct string *s1, const char *s2 );
 
-extern struct char_table dquote_table[3];
-extern struct char_table squote_table[1];
+extern const struct char_table dquote_table[3];
+extern const struct char_table squote_table[1];
+extern const struct char_table arith_table[21];
+extern const struct char_table table[6];
 
 #endif
\ No newline at end of file