]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Shortened method declarations
authorMaria Matejka <mq@ucw.cz>
Mon, 19 Jun 2023 13:49:51 +0000 (15:49 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 12 Sep 2023 14:20:25 +0000 (16:20 +0200)
filter/decl.m4
filter/f-inst.c

index 8fcbe8749aa5fc523820ecedc50e968e0a8dd5dc..d292f65b9921eba891a6b29725a51d6641c803ba 100644 (file)
@@ -292,6 +292,21 @@ m4_define([[INST_IS_METHOD]])
 m4_define([[INST_METHOD_NAME]],$1)
 FID_INTERPRET_BODY()')
 
+#      Short method constructor
+#      $1 = type
+#      $2 = name
+#      $3 = method inputs
+#      method outputs are always 1
+#      $4 = code
+m4_define(METHOD, `m4_dnl
+INST([[FI_METHOD__]]$1[[__]]$2, m4_eval($3 + 1), 1) {
+  ARG(1, $1);
+  $4
+  METHOD_CONSTRUCTOR("$2");
+}')
+
+m4_define(METHOD_R, `METHOD($1, $2, $3, [[ RESULT($4, $5, $6) ]])')
+
 #      2) Code wrapping
 #      The code produced in 1xx temporary diversions is a raw code without
 #      any auxiliary commands and syntactical structures around. When the
index 34e18ca46c91ad557c97b4f1051c37ba32263c3c..f2519efb4c40abf78e177352049a48ca01faf44b 100644 (file)
  *
  *     Other code is just copied into the interpreter part.
  *
+ *     It's also possible to declare type methods in a short way:
+ *
+ *     m4_dnl  METHOD(type, method name, argument count, code)
+ *     m4_dnl  METHOD_R(type, method name, argument count, result type, union-field, value)
+ *
  *     The filter language uses a simple type system, where values have types
  *     (constants T_*) and also terms (instructions) are statically typed. Our
  *     static typing is partial (some terms do not declare types of arguments
     RESULT(T_BOOL, i, (v1.type != T_VOID) && !undef_value(v1));
   }
 
-  INST(FI_NET_TYPE, 1, 1) {
-    ARG(1, T_NET);
-    METHOD_CONSTRUCTOR("type");
-    RESULT(T_ENUM_NETTYPE, i, v1.val.net->type);
-  }
-
-  INST(FI_IS_V4, 1, 1) {
-    ARG(1, T_IP);
-    METHOD_CONSTRUCTOR("is_v4");
-    RESULT(T_BOOL, i, ipa_is_ip4(v1.val.ip));
-  }
+  METHOD_R(T_NET, type, 0, T_ENUM_NETTYPE, i, v1.val.net->type);
+  METHOD_R(T_IP, is_v4, 0, T_BOOL, i, ipa_is_ip4(v1.val.ip));
 
   /* Add initialized variable */
   INST(FI_VAR_INIT, 1, 0) {
     RESULT_VAL(val);
   }
 
-  INST(FI_PATH_EMPTY, 1, 1) {
-    ARG(1, T_PATH);
-    METHOD_CONSTRUCTOR("empty");
-    RESULT(T_PATH, ad, &null_adata);
-  }
-
-  INST(FI_CLIST_EMPTY, 1, 1) {
-    ARG(1, T_CLIST);
-    METHOD_CONSTRUCTOR("empty");
-    RESULT(T_CLIST, ad, &null_adata);
-  }
-
-  INST(FI_ECLIST_EMPTY, 1, 1) {
-    ARG(1, T_ECLIST);
-    METHOD_CONSTRUCTOR("empty");
-    RESULT(T_ECLIST, ad, &null_adata);
-  }
-
-  INST(FI_LCLIST_EMPTY, 1, 1) {
-    ARG(1, T_LCLIST);
-    METHOD_CONSTRUCTOR("empty");
-    RESULT(T_LCLIST, ad, &null_adata);
-  }
+  METHOD_R(T_PATH, empty, 0, T_PATH, ad, &null_adata);
+  METHOD_R(T_CLIST, empty, 0, T_CLIST, ad, &null_adata);
+  METHOD_R(T_ECLIST, empty, 0, T_ECLIST, ad, &null_adata);
+  METHOD_R(T_LCLIST, empty, 0, T_LCLIST, ad, &null_adata);
 
   /* Common loop begin instruction, always created by f_for_cycle() */
   INST(FI_FOR_LOOP_START, 0, 3) {
     ea_unset_attr(fs->eattrs, fs->pool, 1, da.ea_code);
   }
 
-  INST(FI_NET_LENGTH, 1, 1) {  /* Get length of */
-    ARG(1, T_NET);
-    METHOD_CONSTRUCTOR("len");
-    RESULT(T_INT, i, net_pxlen(v1.val.net));
-  }
-
-  INST(FI_PATH_LENGTH, 1, 1) { /* Get length of */
-    ARG(1, T_PATH);
-    METHOD_CONSTRUCTOR("len");
-    RESULT(T_INT, i, as_path_getlen(v1.val.ad));
-  }
-
-  INST(FI_CLIST_LENGTH, 1, 1) {        /* Get length of */
-    ARG(1, T_CLIST);
-    METHOD_CONSTRUCTOR("len");
-    RESULT(T_INT, i, int_set_get_size(v1.val.ad));
-  }
-
-  INST(FI_ECLIST_LENGTH, 1, 1) { /* Get length of */
-    ARG(1, T_ECLIST);
-    METHOD_CONSTRUCTOR("len");
-    RESULT(T_INT, i, ec_set_get_size(v1.val.ad));
-  }
-
-  INST(FI_LCLIST_LENGTH, 1, 1) {       /* Get length of */
-    ARG(1, T_LCLIST);
-    METHOD_CONSTRUCTOR("len");
-    RESULT(T_INT, i, lc_set_get_size(v1.val.ad));
-  }
+  /* Get length of */
+  METHOD_R(T_NET, len, 0, T_INT, i, net_pxlen(v1.val.net));
+  METHOD_R(T_PATH, len, 0, T_INT, i, as_path_getlen(v1.val.ad));
+  METHOD_R(T_CLIST, len, 0, T_INT, i, int_set_get_size(v1.val.ad));
+  METHOD_R(T_ECLIST, len, 0, T_INT, i, ec_set_get_size(v1.val.ad));
+  METHOD_R(T_LCLIST, len, 0, T_INT, i, lc_set_get_size(v1.val.ad));
 
   INST(FI_NET_SRC, 1, 1) {     /* Get src prefix */
     ARG(1, T_NET);
     RESULT(T_NET, net, dst);
   }
 
-  INST(FI_ROA_MAXLEN, 1, 1) {  /* Get ROA max prefix length */
-    ARG(1, T_NET);
-    METHOD_CONSTRUCTOR("maxlen")
+  /* Get ROA max prefix length */
+  METHOD(T_NET, maxlen, 0, [[
     if (!net_is_roa(v1.val.net))
       runtime( "ROA expected" );
 
     RESULT(T_INT, i, (v1.val.net->type == NET_ROA4) ?
       ((net_addr_roa4 *) v1.val.net)->max_pxlen :
       ((net_addr_roa6 *) v1.val.net)->max_pxlen);
-  }
+  ]]);
 
-  INST(FI_NET_ASN, 1, 1) {     /* Get ROA ASN or community ASN part */
-    ARG(1, T_NET);
-    METHOD_CONSTRUCTOR("asn");
+  /* Get ROA ASN or community ASN part */
+  METHOD_R(T_PAIR, asn, 0, T_INT, i, v1.val.i >> 16);
+  METHOD_R(T_LC, asn, 0, T_INT, i, v1.val.lc.asn);
+
+  METHOD(T_NET, asn, 0, [[
         if (!net_is_roa(v1.val.net))
           runtime( "ROA expected" );
 
         RESULT(T_INT, i, (v1.val.net->type == NET_ROA4) ?
           ((net_addr_roa4 *) v1.val.net)->asn :
           ((net_addr_roa6 *) v1.val.net)->asn);
-  }
-
-  INST(FI_PAIR_ASN, 1, 1) {    /* Get ROA ASN or community ASN part */
-    ARG(1, T_PAIR);
-    METHOD_CONSTRUCTOR("asn");
-    RESULT(T_INT, i, v1.val.i >> 16);
-  }
+  ]]);
 
-  INST(FI_LC_ASN, 1, 1) {      /* Get ROA ASN or community ASN part */
-    ARG(1, T_LC);
-    METHOD_CONSTRUCTOR("asn");
-    RESULT(T_INT, i, v1.val.lc.asn);
-  }
 
-  INST(FI_NET_IP, 1, 1) {      /* Convert prefix to ... */
-    ARG(1, T_NET);
-    METHOD_CONSTRUCTOR("ip");
-    RESULT(T_IP, ip, net_prefix(v1.val.net));
-  }
+  /* Convert prefix to IP */
+  METHOD_R(T_NET, ip, 0, T_IP, ip, net_prefix(v1.val.net));
 
   INST(FI_ROUTE_DISTINGUISHER, 1, 1) {
     ARG(1, T_NET);
     RESULT(T_INT, i, as);
   }
 
-  INST(FI_AS_PATH_LAST_NAG, 1, 1) {    /* Get last ASN from non-aggregated part of AS PATH */
-    ARG(1, T_PATH);
-    METHOD_CONSTRUCTOR("last_nonaggregated");
-    RESULT(T_INT, i, as_path_get_last_nonaggregated(v1.val.ad));
-  }
+  /* Get last ASN from non-aggregated part of AS PATH */
+  METHOD_R(T_PATH, last_nonaggregated, 0, T_INT, i, as_path_get_last_nonaggregated(v1.val.ad));
 
-  INST(FI_PAIR_DATA, 1, 1) {   /* Get data part from the standard community */
-    ARG(1, T_PAIR);
-    METHOD_CONSTRUCTOR("data");
-    RESULT(T_INT, i, v1.val.i & 0xFFFF);
-  }
+  /* Get data part from the standard community */
+  METHOD_R(T_PAIR, data, 0, T_INT, i, v1.val.i & 0xFFFF);
 
-  INST(FI_LC_DATA1, 1, 1) {    /* Get data1 part from the large community */
-    ARG(1, T_LC);
-    METHOD_CONSTRUCTOR("data1");
-    RESULT(T_INT, i, v1.val.lc.ldp1);
-  }
+  /* Get data1 part from the large community */
+  METHOD_R(T_LC, data1, 0, T_INT, i, v1.val.lc.ldp1);
 
-  INST(FI_LC_DATA2, 1, 1) {    /* Get data2 part from the large community */
-    ARG(1, T_LC);
-    METHOD_CONSTRUCTOR("data2");
-    RESULT(T_INT, i, v1.val.lc.ldp2);
-  }
+  /* Get data2 part from the large community */
+  METHOD_R(T_LC, data2, 0, T_INT, i, v1.val.lc.ldp2);
 
   INST(FI_CLIST_MIN, 1, 1) {   /* Get minimum element from list */
     ARG(1, T_CLIST);