//////////////////////////////////////////////////////////////// add_hook_list keep a reference to the hooked object. Return old handler, or None
| 196 | // keep a reference to the hooked object. |
| 197 | // Return old handler, or None |
| 198 | PyObject *add_hook_list(PyObject *hookedObject, PyObject *args, CMapWordToPtr **ppList) |
| 199 | { |
| 200 | CMapWordToPtr *&pList = *ppList; |
| 201 | if (pList==NULL) |
| 202 | pList = new CMapWordToPtr(); |
| 203 | PyObject *method; |
| 204 | int message; |
| 205 | if (!PyArg_ParseTuple(args,"Oi",&method, &message)) |
| 206 | return NULL; |
| 207 | if (method!=Py_None && !PyCallable_Check(method)) |
| 208 | RETURN_ERR("The parameter must be a callable object or None"); |
| 209 | |
| 210 | void *oldMethod = NULL; |
| 211 | // note I maybe decref, then maybe incref. To ensure the object will |
| 212 | // not be destroyed (ie, ref go to zero) between the 2 calls), I |
| 213 | // add a temporary reference first. |
| 214 | DOINCREF(hookedObject); |
| 215 | if (pList->Lookup(message, oldMethod)) { |
| 216 | pList->RemoveKey(message); |
| 217 | // oldMethod is returned - don't drop its reference. |
| 218 | DODECREF(hookedObject); |
| 219 | } |
| 220 | if (method!=Py_None) { |
| 221 | Py_INCREF(method); |
| 222 | pList->SetAt(message,method); |
| 223 | Py_INCREF(hookedObject); |
| 224 | } |
| 225 | DODECREF(hookedObject); // remove temp reference added above. |
| 226 | if (oldMethod) |
| 227 | return (PyObject *)oldMethod; |
| 228 | else |
| 229 | RETURN_NONE; |
| 230 | // RETURN_NONE; |
| 231 | } |
| 232 | // |
| 233 | // free_hook_list |
| 234 | // |
no test coverage detected