]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Get rid of 'ab'-s, added return to functions.
authorPavel Machek <pavel@ucw.cz>
Fri, 25 Feb 2000 11:15:26 +0000 (11:15 +0000)
committerPavel Machek <pavel@ucw.cz>
Fri, 25 Feb 2000 11:15:26 +0000 (11:15 +0000)
filter/config.Y
filter/filter.c
filter/filter.h
filter/test.conf

index 05608c95552e3bff3fa1386261abc11aea3cd90e..856189ec3393cf69f9d6cd516710765632580f28 100644 (file)
@@ -6,7 +6,7 @@
  *     Can be freely distributed and used under the terms of the GNU GPL.
  *
        FIXME (nonurgent): define keyword
-       FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
+       FIXME (for BGP): whole system of paths, path ~ string, path.prepend(), path.originate
        FIXME: create community lists
        FIXME: '! =' should not be permitted. Ze `!=' by nemelo byt totez jako `! =' Nadefinujes si pres %token novy token a do cf-lex.l pridas nove pravidlo, ktere jej rozpoznava. Napriklad !=      return NEQ;
        FIXME: IP addresses in ipv6
@@ -25,9 +25,11 @@ CF_HDR
 #include "nest/route.h"
 #include <string.h>
 
+#define P(a,b) ((a<<8) | b)
+
 CF_DECLS
 
-CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST, UNSET,
+CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST, UNSET, RETURN,
        ACCEPT, REJECT, ERROR, QUITBIRD,
        INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
        IF, THEN, ELSE, CASE,
@@ -41,7 +43,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST, UNSET,
 %nonassoc THEN
 %nonassoc ELSE
 
-%type <x> term block cmds cmd function_body constant print_one print_list var_list var_listn any_dynamic
+%type <x> term block cmds cmd function_body constant print_one print_list var_list var_listn any_dynamic function_call
 %type <f> filter filter_body where_filter
 %type <i> type break_command pair
 %type <e> set_item set_items switch_body
@@ -132,11 +134,11 @@ where_filter:
      struct filter *f = cfg_alloc(sizeof(struct filter));
      struct f_inst *i, *acc, *rej;
      acc = f_new_inst();               /* ACCEPT */
-     acc->code = 'p,';
+     acc->code = P('p',',');
      acc->a1.p = NULL;
      acc->a2.i = F_ACCEPT;
      rej = f_new_inst();               /* REJECT */
-     rej->code = 'p,';
+     rej->code = P('p',',');
      rej->a1.p = NULL;
      rej->a2.i = F_REJECT;
      i = f_new_inst();                 /* IF */
@@ -274,17 +276,41 @@ any_dynamic:
 rtadot: /* EMPTY, we are not permitted RTA. prefix */
  ;
 
+function_call:
+   SYM '(' var_list ')' {
+     struct symbol *sym;
+     struct f_inst *inst = $3;
+     if ($1->class != SYM_FUNCTION)
+       cf_error("You can not call something which is not function. Really.");
+     printf("You are calling function %s\n", $1->name);
+     $$ = f_new_inst();
+     $$->code = P('c','a');
+     $$->a1.p = inst;
+     $$->a2.p = $1->aux2;
+     sym = (void *) $1->aux;
+     while (sym || inst) {
+       if (!sym || !inst)
+        cf_error("wrong number of arguments for function %s.", $1->name);
+       printf( "You should pass parameter called %s\n", sym->name);
+       inst->a1.p = sym;
+       sym = (void *) sym->aux;
+       inst = inst->next;
+     }
+   }
+ ;
+
+
 term:
    '(' term ')'      { $$ = $2; }
  | term '+' term     { $$ = f_new_inst(); $$->code = '+';  $$->a1.p = $1; $$->a2.p = $3; }
- | term '=' term     { $$ = f_new_inst(); $$->code = '=='; $$->a1.p = $1; $$->a2.p = $3; }
- | term '!' '=' term { $$ = f_new_inst(); $$->code = '!='; $$->a1.p = $1; $$->a2.p = $4; }
+ | term '=' term     { $$ = f_new_inst(); $$->code = P('=','='); $$->a1.p = $1; $$->a2.p = $3; }
+ | term '!' '=' term { $$ = f_new_inst(); $$->code = P('!','='); $$->a1.p = $1; $$->a2.p = $4; }
  | term '<' term     { $$ = f_new_inst(); $$->code = '<';  $$->a1.p = $1; $$->a2.p = $3; }
- | term '<' '=' term { $$ = f_new_inst(); $$->code = '<='; $$->a1.p = $1; $$->a2.p = $4; }
+ | term '<' '=' term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $1; $$->a2.p = $4; }
  | term '>' term     { $$ = f_new_inst(); $$->code = '<';  $$->a1.p = $3; $$->a2.p = $1; }
- | term '>' '=' term { $$ = f_new_inst(); $$->code = '<='; $$->a1.p = $4; $$->a2.p = $1; }
+ | term '>' '=' term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $4; $$->a2.p = $1; }
  | term '~' term     { $$ = f_new_inst(); $$->code = '~';  $$->a1.p = $1; $$->a2.p = $3; }
- | DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = 'de';  $$->a1.p = $3; }
+ | DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = P('d','e');  $$->a1.p = $3; }
 
  | constant { $$ = $1; }
  | SYM {
@@ -308,11 +334,12 @@ term:
  | rtadot NET     { $$ = f_new_inst(); $$->code = 'a'; $$->aux = T_PREFIX; $$->a2.i = 0x12345678; }
  | rtadot SOURCE  { $$ = f_new_inst(); $$->code = 'a'; $$->aux = T_ENUM_RTS; $$->a2.i = OFFSETOF(struct rta, gw); }
 
- | rtadot any_dynamic { $$ = $2; $$->code = 'ea'; }
+ | rtadot any_dynamic { $$ = $2; $$->code = P('e','a'); }
 
- | term '.' IP { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->aux = T_IP; }
- | term '.' LEN { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->aux = T_INT; }
- | term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = 'iM'; $$->a1.p = $1; $$->a2.p = $5; }
+ | term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
+ | term '.' LEN { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_INT; }
+ | term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; }
+ | function_call { $$ = $1; /* 1 shift/reduce conflict */ }
  ;
 
 break_command:
@@ -383,41 +410,28 @@ cmd:
      $$->a1.p = $1;
      $$->a2.p = $3;
    }
+ | RETURN term ';' {
+     $$ = f_new_inst();
+     printf( "Ook, we'll return the value\n" );
+     $$->code = 'r';
+     $$->a1.p = $2;
+   }
  | rtadot any_dynamic '=' term ';' {
      $$ = $2;
-     $$->code  = 'eS';
+     $$->code  = P('e','S');
      $$->a1.p = $4;
    }
  | UNSET '(' rtadot any_dynamic ')' ';' {
      $$ = $4;
      $$->aux = T_VOID;
-     $$->code = 'eS';
+     $$->code = P('e','S');
      $$->a1.p = NULL;
    }
- | break_command print_list ';' { $$ = f_new_inst(); $$->code = 'p,'; $$->a1.p = $2; $$->a2.i = $1; }
- | SYM '(' var_list ')' ';' {
-     struct symbol *sym;
-     struct f_inst *inst = $3;
-     if ($1->class != SYM_FUNCTION)
-       cf_error("You can not call something which is not function. Really.");
-     printf("You are calling function %s\n", $1->name);
-     $$ = f_new_inst();
-     $$->code = 'ca';
-     $$->a1.p = inst;
-     $$->a2.p = $1->aux2;
-     sym = (void *) $1->aux;
-     while (sym || inst) {
-       if (!sym || !inst)
-        cf_error("wrong number of arguments for function %s.", $1->name);
-       printf( "You should pass parameter called %s\n", sym->name);
-       inst->a1.p = sym;
-       sym = (void *) sym->aux;
-       inst = inst->next;
-     }
-   }
+ | break_command print_list ';' { $$ = f_new_inst(); $$->code = P('p',','); $$->a1.p = $2; $$->a2.i = $1; }
+ | function_call ';' { $$ = $1; }
  | CASE term '{' switch_body '}' {
       $$ = f_new_inst();
-      $$->code = 'SW';
+      $$->code = P('S','W');
       $$->a1.p = $2;
       $$->a2.p = build_tree( $4 );
    }
index 103710ea60ab825dbd7d1b2c35544df451c3cf34..cbbd1b5803fc9967612ad92694f8325d560a42c1 100644 (file)
@@ -26,6 +26,8 @@
 #include "conf/conf.h"
 #include "filter/filter.h"
 
+#define P(a,b) ((a<<8) | b)
+
 struct f_inst *startup_func = NULL;
 
 #define CMP_ERROR 999
@@ -150,7 +152,7 @@ static struct linpool *f_pool;
 
 #define ARG(x,y) \
        x = interpret(what->y); \
-       if (x.type == T_RETURN) \
+       if (x.type & T_RETURN) \
                return x;
 
 #define ONEARG ARG(v1, a1.p)
@@ -208,10 +210,10 @@ interpret(struct f_inst *what)
     res.val.i = (x); \
     break;
 
-  case '!=': COMPARE(i!=0);
-  case '==': COMPARE(i==0);
+  case P('!','='): COMPARE(i!=0);
+  case P('=','='): COMPARE(i==0);
   case '<': COMPARE(i==-1);
-  case '<=': COMPARE(i!=1);
+  case P('<','='): COMPARE(i!=1);
 
   case '~':
     TWOARGS;
@@ -220,7 +222,7 @@ interpret(struct f_inst *what)
     if (res.val.i == CMP_ERROR)
       runtime( "~ applied on unknown type pair" );
     break;
-  case 'de':
+  case P('d','e'):
     ONEARG;
     res.type = T_BOOL;
     res.val.i = (v1.type != T_VOID);
@@ -270,7 +272,7 @@ interpret(struct f_inst *what)
   case '0':
     printf( "No operation\n" );
     break;
-  case 'p,':
+  case P('p',','):
     ONEARG;
     if (what->a2.i != F_NONL)
       printf( "\n" );
@@ -314,9 +316,10 @@ interpret(struct f_inst *what)
       }
     }
     break;
-  case 'ea':   /* Access to extended attributes [hmm, but we need it read/write, do we?] */
+  case P('e','a'):     /* Access to extended attributes */
     {
       eattr *e = ea_find( (*f_rte)->attrs->eattrs, what->a2.i );
+      /* FIXME: should I search in tmp_attrs, too, or what ? */
       if (!e) {
        res.type = T_VOID;
        break;
@@ -329,7 +332,7 @@ interpret(struct f_inst *what)
       }
     }
     break;
-  case 'eS':
+  case P('e','S'):
     ONEARG;
     if (v1.type != what->aux)
       runtime("Wrong type when setting dynamic attribute\n");
@@ -358,7 +361,7 @@ interpret(struct f_inst *what)
     }
     break;
 
-  case 'cp':   /* Convert prefix to ... */
+  case P('c','p'):     /* Convert prefix to ... */
     ONEARG;
     if (v1.type != T_PREFIX)
       runtime( "Can not convert non-prefix this way" );
@@ -369,11 +372,19 @@ interpret(struct f_inst *what)
     default: bug( "Unknown prefix to conversion\n" );
     }
     break;
-  case 'ca': /* CALL */
+  case 'r':
+    ONEARG;
+    res = v1;
+    res.type |= T_RETURN;
+    break;
+  case P('c','a'): /* CALL: this is special: if T_RETURN and returning some value, mask it out  */
     ONEARG;
     res = interpret(what->a2.p);
+    if (res.type == T_RETURN)
+      return res;
+    res.type &= ~T_RETURN;    
     break;
-  case 'SW':
+  case P('S','W'):
     ONEARG;
     {
       struct f_tree *t = find_tree(what->a2.p, v1);
@@ -390,7 +401,7 @@ interpret(struct f_inst *what)
       return interpret(t->data);
     }
     break;
-  case 'iM': /* IP.MASK(val) */
+  case P('i','M'): /* IP.MASK(val) */
     TWOARGS;
     if (v2.type != T_INT)
       runtime( "Can not use this type for mask.");
@@ -410,6 +421,7 @@ interpret(struct f_inst *what)
   return res;
 }
 
+#undef ARG
 #define ARG(x,y) \
        if (!i_same(f1->y, f2->y)) \
                return 0;
@@ -436,13 +448,13 @@ i_same(struct f_inst *f1, struct f_inst *f2)
   case ',': /* fall through */
   case '+':
   case '/':
-  case '!=':
-  case '==':
+  case P('!','='):
+  case P('=','='):
   case '<':
-  case '<=': TWOARGS; break;
+  case P('<','='): TWOARGS; break;
 
   case '~': TWOARGS; break;
-  case 'de': ONEARG; break;
+  case P('d','e'): ONEARG; break;
 
   case 's':
     ARG(v2, a2.p);
@@ -465,23 +477,25 @@ i_same(struct f_inst *f1, struct f_inst *f2)
   case 'p': ONEARG; break;
   case '?': TWOARGS; break;
   case '0': break;
-  case 'p,': ONEARG; A2_SAME; break;
+  case P('p',','): ONEARG; A2_SAME; break;
   case 'a': A2_SAME; break;
-  case 'ea': A2_SAME; break;
-  case 'eS': ONEARG; A2_SAME; break;
+  case P('e','a'): A2_SAME; break;
+  case P('e','S'): ONEARG; A2_SAME; break;
 
-  case 'cp': ONEARG; break;
-  case 'ca': /* CALL, FIXME: exponential in some cases */
+  case 'r': ONEARG; break;
+  case P('c','p'): ONEARG; break;
+  case P('c','a'): /* CALL, FIXME: exponential in some cases */
              ONEARG; if (!i_same(f1->a2.p, f2->a2.p)) return 0; break;
-  case 'SW': ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
-  case 'iM': TWOARGS; break;
+  case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
+  case P('i','M'): TWOARGS; break;
   default:
     bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
   }
   return i_same(f1->next, f2->next);
 }
 
-/* FIXME: tmp_attrs is unreferenced. That can't be right */
+/* FIXME: tmp_attrs is unreferenced. That can't be right.
+   Strange. look at eS how dynamic attrs are set. */
 int
 f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool)
 {
@@ -500,8 +514,6 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
   return res.val.i;
 }
 
-
-
 void
 filters_postconfig(void)
 {
index ace72e47921ac957081ef8666b6df70ef0d021c8..a08f12671318eb1110dc220c3f8dc3c9ab9a8def 100644 (file)
@@ -91,16 +91,15 @@ void val_print(struct f_val v);
 /* Internal types */
 /* Do not use type of zero, that way we'll see errors easier. */
 #define T_VOID 1
-#define T_RETURN 2
 
 /* User visible types, which fit in int */
 #define T_INT 0x10
 #define T_BOOL 0x11
 #define T_PAIR 0x12
 
-/* Put enumerational types in 0x30..0x7f range */
+/* Put enumerational types in 0x30..0x3f range */
 #define T_ENUM_LO 0x30
-#define T_ENUM_HI 0x7f
+#define T_ENUM_HI 0x3f
 
 #define T_ENUM_RTS 0x30
 
@@ -111,6 +110,7 @@ void val_print(struct f_val v);
 #define T_PREFIX 0x21
 #define T_STRING 0x22
 
+#define T_RETURN 0x40
 #define T_SET 0x80
 
 struct f_tree {
@@ -121,4 +121,6 @@ struct f_tree {
 
 #define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
 
+/* Create pair from two letters */
+
 #endif
index 616dbc58e84331917b9e2e0ee549184f91665209..e42feadb715bd32ed60628a0213cdab8a3f236b1 100644 (file)
@@ -8,7 +8,7 @@ router id 62.168.0.1;
 
 define xyzzy = 120+10;
 
-function callme ( int arg1; int arg2 )
+function callme(int arg1; int arg2)
 int local1;
 int local2;
 int i;
@@ -23,7 +23,13 @@ int i;
        }       
 }
 
-function startup () 
+function fifteen()
+{
+       print "fifteen called";
+       return 15;
+}
+
+function startup() 
 int i;
 prefix px;
 ip p;
@@ -58,6 +64,9 @@ ip p;
        callme ( 4, 2 );
        callme ( 7, 2 );
 
+       i = fifteen();
+       print "Testing function calls: 15 = " i;
+
        print "done";
        quitbird;
 #      print "*** FAIL: this is unreachable";