Arithmetic parser with variable expansion
authorLynus Vaz <lynus@Arch.localdomain>
Thu, 28 May 2009 13:42:13 +0000 (19:12 +0530)
committerLynus Vaz <lynus@Arch.localdomain>
Thu, 28 May 2009 13:42:13 +0000 (19:12 +0530)
src/core/exec.c
src/hci/arith.c

index 63ce7f4..b4a1fc1 100644 (file)
@@ -84,7 +84,7 @@ int execv ( const char *command, char * const argv[] ) {
        return -ENOEXEC;
 }
 
-long parse_arith(char *inp_string);
+long parse_arith(char *inp_string, char **end);
 
 /**
  * Expand variables within command line
@@ -102,7 +102,7 @@ static char * expand_command ( const char *command ) {
        char *head;
        char *name;
        char *tail;
-       //int setting_len;
+       int setting_len;
        int new_len;
        char *tmp;
 
@@ -131,19 +131,6 @@ static char * expand_command ( const char *command ) {
                *end = '\0';
                tail = ( end + 1 );
                
-               //This is by Lynus: currently only parsing arith ops
-               {
-                       long arith_res;
-                       arith_res = parse_arith(name);
-                       tmp = expcmd;
-                       new_len = asprintf(&expcmd, "%s%ld%s", head, arith_res, tail);
-                       free(tmp);
-                       if(new_len < 0)
-                               return NULL;
-               }
-               
-#if 0
-
                /* Determine setting length */
                setting_len = fetchf_named_setting ( name, NULL, 0 );
                if ( setting_len < 0 )
@@ -165,7 +152,30 @@ static char * expand_command ( const char *command ) {
                        if ( new_len < 0 )
                                return NULL;
                }
-#endif
+       }
+       
+       while(1)
+       {
+               head = expcmd;
+
+               /* Locate opener */
+               start = strstr ( expcmd, "$(" );
+               
+               if ( ! start )
+                       break;
+               *start = '\0';
+               name = ( start + 2 );
+               
+               //This is by Lynus: currently only parsing arith ops
+               {
+                       long arith_res;
+                       arith_res = parse_arith(name, &tail);
+                       tmp = expcmd;
+                       new_len = asprintf(&expcmd, "%s%ld%s", head, arith_res, tail);
+                       free(tmp);
+                       if(new_len < 0)
+                               return NULL;
+               }
        }
 
        return expcmd;
index 9f2d5bc..a674891 100644 (file)
@@ -29,6 +29,7 @@ Ops: !, ~                             (Highest)
 
 char *inp;
 int tok;
+int brackets;
 
 char *op_table = "!@@" "~@@" "*@@" "/@@" "%@@" "+@@" "-@@" "<@@" "<=@" "<<@" ">@@" ">=@" ">>@" "!=@" "==@" "&@@" "|@@" "^@@" "&&@" "||@";
 signed char op_prio[NUM_OPS]   = { 10, 10, 9, 9, 9, 8, 8, 6, 6, 7, 6, 6, 7, 5, 5, 4, 3, 2, 1, 0 };
@@ -63,6 +64,11 @@ static void input()
 {
        char t_op[3] = { 0, 0, 0};
        char *p1, *p2;
+       
+       if(tok == -1)
+               return;
+               
+       
        ignore_whitespace();
        
        if(*inp)
@@ -78,6 +84,8 @@ static void input()
                if(!p1 || !*inp)
                {
                        tok = *t_op;
+                       if(tok == ')' && brackets <= 0)
+                               tok = -1;
                        return;
                }
                t_op[1] = *inp;
@@ -153,8 +161,10 @@ static long parse_num(void)
                //flag = 1;
        
        if (accept('(')) {
+               brackets++;
                num = parse_expr();
                skip(')');
+               brackets--;
                return flag * num;
        }
        
@@ -262,10 +272,13 @@ static long parse_expr(void)
        return parse_prio(-1);
 }
 
-long parse_arith(char *inp_string)
+long parse_arith(char *inp_string, char **end)
 {
+       long value;
+       brackets = tok = 0;
        inp = inp_string;
        input();
-       return parse_expr();
-       
+       value = parse_expr();
+       *end = inp;
+       return value;
 }