mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 01:43:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			245 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
/*
 | 
						|
 * prep: strip off casts, they cause things to fail matching later.
 | 
						|
 */
 | 
						|
 | 
						|
@@
 | 
						|
identifier casttarget;
 | 
						|
symbol vty;
 | 
						|
@@
 | 
						|
 | 
						|
- (struct casttarget *)vty->index
 | 
						|
+ vty->index
 | 
						|
 | 
						|
/*
 | 
						|
 * variant 1:  local variable assigned from vty->index
 | 
						|
 */
 | 
						|
 | 
						|
@@
 | 
						|
identifier sn, nn;
 | 
						|
identifier fn;
 | 
						|
@@
 | 
						|
 | 
						|
  int fn(...)
 | 
						|
  {
 | 
						|
+ VTY_DECLVAR_CONTEXT (sn, nn);
 | 
						|
  ...
 | 
						|
  \(
 | 
						|
-   struct sn *nn;
 | 
						|
    ...
 | 
						|
-   nn = vty->index;
 | 
						|
  \|
 | 
						|
-   struct sn *nn = vty->index;
 | 
						|
  \|
 | 
						|
-   struct sn *nn = vty->index;
 | 
						|
    ...
 | 
						|
-   nn = vty->index;
 | 
						|
  \)
 | 
						|
  ...
 | 
						|
  }
 | 
						|
 | 
						|
@@
 | 
						|
identifier sn, nn;
 | 
						|
identifier fn;
 | 
						|
type Tr;
 | 
						|
@@
 | 
						|
 | 
						|
  Tr *fn(...)
 | 
						|
  {
 | 
						|
+   struct sn *nn = VTY_GET_CONTEXT(sn);
 | 
						|
  ...
 | 
						|
  \(
 | 
						|
-   struct sn *nn;
 | 
						|
    ...
 | 
						|
-   nn = vty->index;
 | 
						|
+   if (!nn) {
 | 
						|
+     return NULL;
 | 
						|
+   }
 | 
						|
  \|
 | 
						|
-   struct sn *nn = vty->index;
 | 
						|
+   if (!nn) {
 | 
						|
+     return NULL;
 | 
						|
+   }
 | 
						|
  \|
 | 
						|
-   struct sn *nn = vty->index;
 | 
						|
    ...
 | 
						|
-   nn = vty->index;
 | 
						|
+   if (!nn) {
 | 
						|
+     return NULL;
 | 
						|
+   }
 | 
						|
  \)
 | 
						|
  ...
 | 
						|
  }
 | 
						|
 | 
						|
/*
 | 
						|
 * variant 2:  vty wrapper func with (vty, vty->index, ...) signature
 | 
						|
 */
 | 
						|
 | 
						|
/* find calls of this pattern first; arg will be dropped in rule3 */
 | 
						|
@rule1@
 | 
						|
identifier fn !~ "generic_(set|match)_";
 | 
						|
expression arg;
 | 
						|
@@
 | 
						|
 
 | 
						|
 fn(arg, arg->index, ...)
 | 
						|
 | 
						|
@ script:python @
 | 
						|
fn << rule1.fn;
 | 
						|
arg << rule1.arg;
 | 
						|
@@
 | 
						|
print "R01 removing vty-index argument on %s(%s, ...)" % (fn, arg)
 | 
						|
 | 
						|
#/* strip arg on the vty wrapper func, add local handling */
 | 
						|
@ rule2 @
 | 
						|
identifier rule1.fn;
 | 
						|
identifier arg;
 | 
						|
identifier T;
 | 
						|
@@
 | 
						|
 | 
						|
  static int fn (struct vty *vty,
 | 
						|
-                struct T * arg,
 | 
						|
                 ...)
 | 
						|
  {
 | 
						|
+   VTY_DECLVAR_CONTEXT (T, arg);
 | 
						|
    ...
 | 
						|
  }
 | 
						|
 | 
						|
/* drop argument on call sites identified earlier */
 | 
						|
@ rule3 @
 | 
						|
identifier rule1.fn;
 | 
						|
expression arg;
 | 
						|
@@
 | 
						|
 | 
						|
  fn(arg,
 | 
						|
-    arg->index,
 | 
						|
     ...)
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * variant 3:  function calls with "vty->index" argument (but no vty)
 | 
						|
 *
 | 
						|
 * a bit more complicated since we need to find the type from the header.
 | 
						|
 */
 | 
						|
 | 
						|
/* find call sites first
 | 
						|
 * remember function name for later declvar insertion
 | 
						|
 */
 | 
						|
@ rule11 exists@
 | 
						|
identifier fn;
 | 
						|
identifier fparent;
 | 
						|
type Tr;
 | 
						|
@@
 | 
						|
 
 | 
						|
  Tr fparent (...)
 | 
						|
  {
 | 
						|
    ...
 | 
						|
    fn(vty->index, ...)
 | 
						|
    ...
 | 
						|
  }
 | 
						|
 | 
						|
@ script:python @
 | 
						|
fn << rule11.fn;
 | 
						|
@@
 | 
						|
print "R11 removing vty-index argument on %s(...)" % (fn)
 | 
						|
 | 
						|
#/* find type of the argument - note args are mostly unnamed in FRR :( */
 | 
						|
@ rule12 @
 | 
						|
identifier rule11.fn;
 | 
						|
identifier T, argname;
 | 
						|
type Tr;
 | 
						|
@@
 | 
						|
 | 
						|
(
 | 
						|
  Tr fn(struct T *, ...);
 | 
						|
|
 | 
						|
  Tr fn(struct T * argname, ...);
 | 
						|
)
 | 
						|
 | 
						|
@ script:python @
 | 
						|
fn << rule11.fn;
 | 
						|
T << rule12.T;
 | 
						|
@@
 | 
						|
print "R12 removing vty-index type is %s for %s(...)" % (T, fn)
 | 
						|
 | 
						|
#/* add declvar
 | 
						|
# * this is split from rule14 so we support multiple calls in one func */
 | 
						|
@ rule13a @
 | 
						|
identifier rule11.fparent;
 | 
						|
identifier rule12.T;
 | 
						|
@@
 | 
						|
 | 
						|
  int fparent (...)
 | 
						|
  {
 | 
						|
+   VTY_DECLVAR_CONTEXT(T, T);
 | 
						|
    ...
 | 
						|
  }
 | 
						|
 | 
						|
@ rule13b @
 | 
						|
identifier rule11.fparent;
 | 
						|
identifier rule12.T;
 | 
						|
type Tr;
 | 
						|
@@
 | 
						|
 | 
						|
  Tr *fparent (...)
 | 
						|
  {
 | 
						|
+   struct T *T = VTY_GET_CONTEXT(T);
 | 
						|
+   if (!T) {
 | 
						|
+     return NULL;
 | 
						|
+   }
 | 
						|
    ...
 | 
						|
  }
 | 
						|
 | 
						|
/* now replace the argument in the call */
 | 
						|
@ rule14 exists @
 | 
						|
identifier rule11.fn;
 | 
						|
identifier rule12.T;
 | 
						|
@@
 | 
						|
 | 
						|
  {
 | 
						|
    ...
 | 
						|
    \(
 | 
						|
    fn(
 | 
						|
-       vty->index,
 | 
						|
+       T,
 | 
						|
        ...)
 | 
						|
    \|
 | 
						|
    fn(
 | 
						|
-       vty->index
 | 
						|
+       T
 | 
						|
        )
 | 
						|
    \)
 | 
						|
    ...
 | 
						|
  }
 | 
						|
 | 
						|
/* special case ... */
 | 
						|
@rule30@
 | 
						|
identifier fn =~ "generic_(set|match)_";
 | 
						|
expression arg;
 | 
						|
@@
 | 
						|
 
 | 
						|
  fn(arg,
 | 
						|
-    arg->index,
 | 
						|
+    VTY_GET_CONTEXT(route_map_index),
 | 
						|
     ...)
 | 
						|
 | 
						|
/* and finally - PUSH_CONTEXT */
 | 
						|
@ rule99a exists @
 | 
						|
identifier tnode;
 | 
						|
identifier vexpr =~ "NULL";
 | 
						|
@@
 | 
						|
 | 
						|
- vty->node = tnode;
 | 
						|
  ...
 | 
						|
- vty->index = vexpr;
 | 
						|
+ VTY_PUSH_CONTEXT_NULL(tnode);
 | 
						|
 | 
						|
@ rule99b exists @
 | 
						|
identifier tnode;
 | 
						|
expression vexpr;
 | 
						|
@@
 | 
						|
 | 
						|
- vty->node = tnode;
 | 
						|
  ...
 | 
						|
- vty->index = vexpr;
 | 
						|
+ VTY_PUSH_CONTEXT(tnode, vexpr);
 | 
						|
 |