[scripting] If-else-fi
authorLynus Vaz <lynus@Arch.localdomain>
Tue, 23 Jun 2009 08:58:25 +0000 (14:28 +0530)
committerLynus Vaz <lynus@Arch.localdomain>
Tue, 23 Jun 2009 08:58:25 +0000 (14:28 +0530)
src/config/defaults/pcbios.h
src/config/general.h
src/core/config.c
src/core/exec.c
src/hci/arith.c
src/hci/commands/if_cmd.c [new file with mode: 0644]
src/tests/if_test.gpxe [new file with mode: 0644]

index f7b8a45..84fe464 100644 (file)
@@ -13,7 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define IOAPI_X86
 #define PCIAPI_PCBIOS
 #define TIMER_PCBIOS
-#define CONSOLE_PCBIOS
+//#define CONSOLE_PCBIOS
+#define CONSOLE_SERIAL
 #define NAP_PCBIOS
 #define UMALLOC_MEMTOP
 #define SMBIOS_PCBIOS
index dfc8700..a4ae695 100644 (file)
@@ -105,6 +105,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define LOGIN_CMD              /* Login command */
 #undef TIME_CMD                /* Time commands */
 #undef DIGEST_CMD              /* Image crypto digest commands */
+#define IF_CMD
 
 /*
  * Obscure configuration options
index ecaf781..be88bab 100644 (file)
@@ -204,6 +204,9 @@ REQUIRE_OBJECT ( time_cmd );
 #ifdef DIGEST_CMD
 REQUIRE_OBJECT ( digest_cmd );
 #endif
+#ifdef IF_CMD
+REQUIRE_OBJECT ( if_cmd );
+#endif
 
 /*
  * Drag in miscellaneous objects
index f470d80..b162aa8 100644 (file)
@@ -48,6 +48,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
 int optind;
 int nextchar;
 
+extern int branch_stack[10];
+extern int branch_tos;
+
 /**
  * Execute command
  *
@@ -84,8 +87,12 @@ 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 )
-                       return cmd->exec ( argc, ( char ** ) argv );
+               if ( strcmp ( command, cmd->name ) == 0 ) {
+                       if ( branch_stack[branch_tos] || !strcmp ( cmd -> name, "if" ) || !strcmp ( cmd -> name, "fi" ) || !strcmp ( cmd -> name, "else" ) )
+                               return cmd->exec ( argc, ( char ** ) argv );
+                       else
+                               return 0;
+               }
        }
 
        printf ( "%s: command not found\n", command );
@@ -223,6 +230,7 @@ char * expand_string ( char * input, char **end, const struct char_table *table,
                                case ENDQUOTES: /* 0 for end of input, where next char is to be discarded. Used for ending ' or " */
                                        *head = 0;
                                        *end = head + 1;
+                                       //printf ( "return value: [%s]\n", expstr );
                                        return expstr;
                                        break;
                                case TABLE: /* 1 for recursive call. Probably found quotes */
@@ -234,7 +242,10 @@ char * expand_string ( char * input, char **end, const struct char_table *table,
                                                tmp = expstr;
                                                
                                                new_len = asprintf ( &expstr, "%s%s%s", expstr, nstr, head );
-                                               head = expstr + strlen ( tmp ) + strlen ( nstr );
+                                               if ( in_quotes || tline -> type == TABLE )
+                                                       head = expstr + strlen ( tmp ) + strlen ( nstr );
+                                               else
+                                                       head = expstr + strlen ( tmp );
                                                free ( tmp );
                                                free ( nstr );
                                                if ( !nstr || new_len < 0 ) { /* if new_len < 0, expstr = NULL */
@@ -357,8 +368,11 @@ int system ( const char *command ) {
                        argv[i] = arg -> word;
                        arg = arg -> next;
                        free ( tmp );
+                       
+                       //printf ( "[%s] ", argv[i] );
                }
                argv[i] = NULL;
+               //printf ( "\n" );
                
                if ( argc > 0 )
                        rc = execv ( argv[0], argv );
index 47c422a..06ef5d5 100644 (file)
@@ -82,7 +82,7 @@ static int parse_expr ( char **buffer );
 char * expand_string ( char * input, char **end, const struct char_table *table, int tlen, int in_quotes );
 char * dollar_expand ( char *inp, char **end );
 char * parse_escape ( char *input, char **end );
-static int isnum ( char *string, long *num );
+int isnum ( char *string, long *num );
 
 #define                        ENDQUOTES       0
 #define                        TABLE           1
@@ -133,7 +133,7 @@ static void input ( void ) {
        }
        tok = 0;
        
-       tmp = expand_string ( inp, &end, table, 21, 0 );
+       tmp = expand_string ( inp, &end, table, 21, 1 );
        inp = end;
        free ( orig );
        orig = tmp;
@@ -176,7 +176,7 @@ static void input ( void ) {
 }
 
 /* Check if a string is a number: "-1" and "+42" is accepted, but not "-1a". If so, place it in num and return 1 else num = 0 and return 0 */
-static int isnum ( char *string, long *num ) {
+int isnum ( char *string, long *num ) {
        int flag = 0;
        
        *num = 0;
@@ -272,6 +272,8 @@ static int eval(int op, char *op1, char *op2, char **buffer) {
        int bothints = 1;
        long lhs, rhs;
        
+       printf ( "lhs = %s, rhs = %s\n", op1, op2 );
+       
        if ( op1 ) {
                if ( ! isnum ( op1, &lhs ) ) 
                        bothints = 0;
@@ -456,34 +458,3 @@ int parse_arith ( char *inp_string, char **end, char **buffer ) {
        return 0;
 }
 
-#ifdef __ARITH_TEST__
-int main ( int argc, char *argv[] ) {
-       char *ret_val;
-       int r = 0;
-       char *head, *tail, *string, *t;
-       char line[100];
-       
-       while ( !feof ( stdin ) ) {
-               fgets ( line, 100, stdin );
-               if ( line[strlen ( line ) - 1] == '\n' )
-                       line[strlen ( line ) - 1] = 0;
-               asprintf ( &string, "%s", line );
-               while ( ( head = strstr ( string, "$(" ) ) != NULL ) {
-                       *head++ = 0;
-                       r = parse_arith ( head, &tail, &ret_val );
-                       t = string;
-                       if ( r == 0 ) {
-                               asprintf ( &string, "%s%s%s", string, ret_val, tail );
-                               free ( ret_val );
-                       } else
-                               break;
-                       free ( t );
-               }
-               if ( r == 0 ) {
-                       printf ( "Line: %s\n", string );
-               }
-               free ( string );
-       }
-       return 0;
-}
-#endif
diff --git a/src/hci/commands/if_cmd.c b/src/hci/commands/if_cmd.c
new file mode 100644 (file)
index 0000000..bd9c754
--- /dev/null
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <gpxe/command.h>
+
+int branch_stack[10] = { 1 };
+int branch_tos = 0;
+static int logical_tos = 0;
+static int in_else[10];
+int isnum ( char *string, long *num );
+
+static int if_exec ( int argc, char **argv ) {
+       long cond;
+       if ( argc != 2 ) {
+               printf ( "Syntax: if <condition>\n" );
+               return -1;
+       }
+       
+       if ( !isnum ( argv[1], &cond ) ) {
+               printf ( "non-numeric condition\n" );
+               return -1;
+       }
+       
+       in_else[logical_tos+1] = 0;
+       if ( logical_tos > branch_tos || branch_stack[branch_tos] == 0 ) {
+               logical_tos++;
+               return 0;
+       }
+       
+       //printf ( "Condition is %ld\n", cond );
+       logical_tos = ++branch_tos;
+       branch_stack[branch_tos] = cond ? 1 : 0;
+       return 0;
+}
+
+struct command if_command __command = {
+       .name = "if",
+       .exec = if_exec,
+};
+
+static int fi_exec ( int argc, char **argv ) {
+       if ( argc != 1 ) {
+               printf ( "Syntax: %s\n", argv[0] );
+               return -1;
+       }
+       
+       if ( logical_tos > branch_tos ) {
+               logical_tos--;
+               return 0;
+       }
+       
+       if ( branch_tos )
+               logical_tos = --branch_tos;
+       else {
+               printf ( "fi without if\n" );
+               return -1;
+       }
+       return 0;               
+}
+
+
+struct command fi_command __command = {
+       .name = "fi",
+       .exec = fi_exec,
+};
+
+static int else_exec ( int argc, char **argv ) {
+       if ( argc != 1 ) {
+               printf ( "Syntax: %s\n", argv[0] );
+       }
+
+       //printf ( "logical_tos = %d, branch_tos = %d\n", logical_tos, branch_tos );
+       if ( ( logical_tos == 0 ) || ( in_else[logical_tos] != 0 ) ) {
+               printf ( "else without if\n" );
+               return -1;
+       }
+       
+       in_else[logical_tos] = 1;
+       if ( logical_tos > branch_tos ) {
+               return 0;
+       }
+               
+       branch_stack[branch_tos] = !branch_stack[branch_tos];
+       return 0;
+}
+
+struct command else_command __command = {
+       .name = "else",
+       .exec = else_exec,
+};
\ No newline at end of file
diff --git a/src/tests/if_test.gpxe b/src/tests/if_test.gpxe
new file mode 100644 (file)
index 0000000..5e5d89c
--- /dev/null
@@ -0,0 +1,35 @@
+#!gpxe
+if $(1)
+       echo 1
+       echo 2
+       if $(0)
+               echo "Fail"
+       else
+               if 2
+                       echo 3
+                       echo 3.1
+               else
+                       echo "Fail"
+               fi
+       fi
+       echo 4
+       echo 5
+else
+       echo "Fail"
+       if $(1)
+               echo "Fail"
+               if 1
+                       echo "Fail"
+               fi
+       else
+               echo "Fail"
+               if 2
+                       echo "Fail"
+               else
+                       echo "Fail"
+               fi
+       fi
+       echo "Fail"
+fi
+echo 6
+echo 7
\ No newline at end of file