]>
Commit | Line | Data |
---|---|---|
52c6b0e2 DL |
1 | /* |
2 | * prep: strip off casts, they cause things to fail matching later. | |
3 | */ | |
4 | ||
5 | @@ | |
6 | identifier casttarget; | |
7 | symbol vty; | |
8 | @@ | |
9 | ||
10 | - (struct casttarget *)vty->index | |
11 | + vty->index | |
12 | ||
13 | /* | |
14 | * variant 1: local variable assigned from vty->index | |
15 | */ | |
16 | ||
17 | @@ | |
18 | identifier sn, nn; | |
19 | identifier fn; | |
20 | @@ | |
21 | ||
22 | int fn(...) | |
23 | { | |
24 | + VTY_DECLVAR_CONTEXT (sn, nn); | |
25 | ... | |
26 | \( | |
27 | - struct sn *nn; | |
28 | ... | |
29 | - nn = vty->index; | |
30 | \| | |
31 | - struct sn *nn = vty->index; | |
32 | \| | |
33 | - struct sn *nn = vty->index; | |
34 | ... | |
35 | - nn = vty->index; | |
36 | \) | |
37 | ... | |
38 | } | |
39 | ||
40 | @@ | |
41 | identifier sn, nn; | |
42 | identifier fn; | |
43 | type Tr; | |
44 | @@ | |
45 | ||
46 | Tr *fn(...) | |
47 | { | |
48 | + struct sn *nn = VTY_GET_CONTEXT(sn); | |
49 | ... | |
50 | \( | |
51 | - struct sn *nn; | |
52 | ... | |
53 | - nn = vty->index; | |
54 | + if (!nn) { | |
55 | + return NULL; | |
56 | + } | |
57 | \| | |
58 | - struct sn *nn = vty->index; | |
59 | + if (!nn) { | |
60 | + return NULL; | |
61 | + } | |
62 | \| | |
63 | - struct sn *nn = vty->index; | |
64 | ... | |
65 | - nn = vty->index; | |
66 | + if (!nn) { | |
67 | + return NULL; | |
68 | + } | |
69 | \) | |
70 | ... | |
71 | } | |
72 | ||
73 | /* | |
74 | * variant 2: vty wrapper func with (vty, vty->index, ...) signature | |
75 | */ | |
76 | ||
77 | /* find calls of this pattern first; arg will be dropped in rule3 */ | |
78 | @rule1@ | |
79 | identifier fn !~ "generic_(set|match)_"; | |
80 | expression arg; | |
81 | @@ | |
82 | ||
83 | fn(arg, arg->index, ...) | |
84 | ||
85 | @ script:python @ | |
86 | fn << rule1.fn; | |
87 | arg << rule1.arg; | |
88 | @@ | |
89 | print "R01 removing vty-index argument on %s(%s, ...)" % (fn, arg) | |
90 | ||
91 | #/* strip arg on the vty wrapper func, add local handling */ | |
92 | @ rule2 @ | |
93 | identifier rule1.fn; | |
94 | identifier arg; | |
95 | identifier T; | |
96 | @@ | |
97 | ||
98 | static int fn (struct vty *vty, | |
99 | - struct T * arg, | |
100 | ...) | |
101 | { | |
102 | + VTY_DECLVAR_CONTEXT (T, arg); | |
103 | ... | |
104 | } | |
105 | ||
106 | /* drop argument on call sites identified earlier */ | |
107 | @ rule3 @ | |
108 | identifier rule1.fn; | |
109 | expression arg; | |
110 | @@ | |
111 | ||
112 | fn(arg, | |
113 | - arg->index, | |
114 | ...) | |
115 | ||
116 | ||
117 | /* | |
118 | * variant 3: function calls with "vty->index" argument (but no vty) | |
119 | * | |
120 | * a bit more complicated since we need to find the type from the header. | |
121 | */ | |
122 | ||
123 | /* find call sites first | |
124 | * remember function name for later declvar insertion | |
125 | */ | |
126 | @ rule11 exists@ | |
127 | identifier fn; | |
128 | identifier fparent; | |
129 | type Tr; | |
130 | @@ | |
131 | ||
132 | Tr fparent (...) | |
133 | { | |
134 | ... | |
135 | fn(vty->index, ...) | |
136 | ... | |
137 | } | |
138 | ||
139 | @ script:python @ | |
140 | fn << rule11.fn; | |
141 | @@ | |
142 | print "R11 removing vty-index argument on %s(...)" % (fn) | |
143 | ||
1a8c43f1 | 144 | #/* find type of the argument - note args are mostly unnamed in FRR :( */ |
52c6b0e2 DL |
145 | @ rule12 @ |
146 | identifier rule11.fn; | |
147 | identifier T, argname; | |
148 | type Tr; | |
149 | @@ | |
150 | ||
151 | ( | |
152 | Tr fn(struct T *, ...); | |
153 | | | |
154 | Tr fn(struct T * argname, ...); | |
155 | ) | |
156 | ||
157 | @ script:python @ | |
158 | fn << rule11.fn; | |
159 | T << rule12.T; | |
160 | @@ | |
161 | print "R12 removing vty-index type is %s for %s(...)" % (T, fn) | |
162 | ||
163 | #/* add declvar | |
164 | # * this is split from rule14 so we support multiple calls in one func */ | |
165 | @ rule13a @ | |
166 | identifier rule11.fparent; | |
167 | identifier rule12.T; | |
168 | @@ | |
169 | ||
170 | int fparent (...) | |
171 | { | |
172 | + VTY_DECLVAR_CONTEXT(T, T); | |
173 | ... | |
174 | } | |
175 | ||
176 | @ rule13b @ | |
177 | identifier rule11.fparent; | |
178 | identifier rule12.T; | |
179 | type Tr; | |
180 | @@ | |
181 | ||
182 | Tr *fparent (...) | |
183 | { | |
184 | + struct T *T = VTY_GET_CONTEXT(T); | |
185 | + if (!T) { | |
186 | + return NULL; | |
187 | + } | |
188 | ... | |
189 | } | |
190 | ||
191 | /* now replace the argument in the call */ | |
192 | @ rule14 exists @ | |
193 | identifier rule11.fn; | |
194 | identifier rule12.T; | |
195 | @@ | |
196 | ||
197 | { | |
198 | ... | |
199 | \( | |
200 | fn( | |
201 | - vty->index, | |
202 | + T, | |
203 | ...) | |
204 | \| | |
205 | fn( | |
206 | - vty->index | |
207 | + T | |
208 | ) | |
209 | \) | |
210 | ... | |
211 | } | |
212 | ||
213 | /* special case ... */ | |
214 | @rule30@ | |
215 | identifier fn =~ "generic_(set|match)_"; | |
216 | expression arg; | |
217 | @@ | |
218 | ||
219 | fn(arg, | |
220 | - arg->index, | |
221 | + VTY_GET_CONTEXT(route_map_index), | |
222 | ...) | |
223 | ||
224 | /* and finally - PUSH_CONTEXT */ | |
225 | @ rule99a exists @ | |
226 | identifier tnode; | |
227 | identifier vexpr =~ "NULL"; | |
228 | @@ | |
229 | ||
230 | - vty->node = tnode; | |
231 | ... | |
232 | - vty->index = vexpr; | |
233 | + VTY_PUSH_CONTEXT_NULL(tnode); | |
234 | ||
235 | @ rule99b exists @ | |
236 | identifier tnode; | |
237 | expression vexpr; | |
238 | @@ | |
239 | ||
240 | - vty->node = tnode; | |
241 | ... | |
242 | - vty->index = vexpr; | |
243 | + VTY_PUSH_CONTEXT(tnode, vexpr); | |
244 |