|
8 | 8 | #include "memtracker.h" |
9 | 9 |
|
10 | 10 |
|
11 | | -MemTracker memTracker; |
12 | 11 |
|
13 | 12 | // Used to store references to the Pyobjects instanced in String() and |
14 | 13 | // ItemAt() methods. Those can't be DECREF'ed to 0 because libuast uses them |
15 | 14 | // so we pass ownership to these lists and free them at the end of filter() |
| 15 | +MemTracker memTracker; |
16 | 16 |
|
| 17 | +// WARNING: calls to Attribute MUST Py_DECREF the returned value once |
| 18 | +// used (or add it to the memtracker) |
17 | 19 | static PyObject *Attribute(const void *node, const char *prop) { |
18 | 20 | PyObject *n = (PyObject *)node; |
19 | 21 | return PyObject_GetAttrString(n, prop); |
20 | 22 | } |
21 | 23 |
|
| 24 | +// WARNING: calls to AttributeValue MUST Py_DECREF the returned value once |
| 25 | +// used (or add it to the memtracker) |
22 | 26 | static PyObject *AttributeValue(const void *node, const char *prop) { |
23 | 27 | PyObject *a = Attribute(node, prop); |
24 | 28 | return a && a != Py_None ? a : NULL; |
25 | 29 | } |
26 | 30 |
|
| 31 | +static bool HasAttribute(const void *node, const char *prop) { |
| 32 | + PyObject *o = AttributeValue(node, prop); |
| 33 | + bool res = o != NULL; |
| 34 | + Py_DECREF(o); |
| 35 | + return res; |
| 36 | +} |
| 37 | + |
27 | 38 | static const char *String(const void *node, const char *prop) { |
28 | 39 | const char *retval = NULL; |
29 | 40 | PyObject *o = Attribute(node, prop); |
@@ -163,47 +174,47 @@ static uint32_t PositionValue(const void* node, const char *prop, const char *fi |
163 | 174 | extern "C" |
164 | 175 | { |
165 | 176 | static bool HasStartOffset(const void *node) { |
166 | | - return AttributeValue(node, "start_position"); |
| 177 | + return HasAttribute(node, "start_position"); |
167 | 178 | } |
168 | 179 |
|
169 | 180 | static uint32_t StartOffset(const void *node) { |
170 | 181 | return PositionValue(node, "start_position", "offset"); |
171 | 182 | } |
172 | 183 |
|
173 | 184 | static bool HasStartLine(const void *node) { |
174 | | - return AttributeValue(node, "start_position"); |
| 185 | + return HasAttribute(node, "start_position"); |
175 | 186 | } |
176 | 187 |
|
177 | 188 | static uint32_t StartLine(const void *node) { |
178 | 189 | return PositionValue(node, "start_position", "line"); |
179 | 190 | } |
180 | 191 |
|
181 | 192 | static bool HasStartCol(const void *node) { |
182 | | - return AttributeValue(node, "start_position"); |
| 193 | + return HasAttribute(node, "start_position"); |
183 | 194 | } |
184 | 195 |
|
185 | 196 | static uint32_t StartCol(const void *node) { |
186 | 197 | return PositionValue(node, "start_position", "col"); |
187 | 198 | } |
188 | 199 |
|
189 | 200 | static bool HasEndOffset(const void *node) { |
190 | | - return AttributeValue(node, "end_position"); |
| 201 | + return HasAttribute(node, "end_position"); |
191 | 202 | } |
192 | 203 |
|
193 | 204 | static uint32_t EndOffset(const void *node) { |
194 | 205 | return PositionValue(node, "end_position", "offset"); |
195 | 206 | } |
196 | 207 |
|
197 | 208 | static bool HasEndLine(const void *node) { |
198 | | - return AttributeValue(node, "end_position"); |
| 209 | + return HasAttribute(node, "end_position"); |
199 | 210 | } |
200 | 211 |
|
201 | 212 | static uint32_t EndLine(const void *node) { |
202 | 213 | return PositionValue(node, "end_position", "line"); |
203 | 214 | } |
204 | 215 |
|
205 | 216 | static bool HasEndCol(const void *node) { |
206 | | - return AttributeValue(node, "end_position"); |
| 217 | + return HasAttribute(node, "end_position"); |
207 | 218 | } |
208 | 219 |
|
209 | 220 | static uint32_t EndCol(const void *node) { |
|
0 commit comments