The ‘calls’ module implements a simple list of functions which can be modified and executed at run-time. It is similar in spirit to the ANSI C ‘atexit’ function. It is intended to be used for:
For example each module could register a self checking function which uses the rest of the nana library. All of these functions would then be called using ‘calls.h’ to check that the entire system is consistent.
A pointer to a ‘void’ function which takes a single ‘void*’ argument. The ‘void *’ argument is intended to be used to pass information such as arguments or pointers to objects (e.g. ‘this’ in C++). All of the checking/printing functions must be of this type, e.g.
void print_object(void *f) { ...; }
This structure represents a single call to a function, i.e. a function pointer (‘FUNC’) and the ‘void*’ argument.
CALL *head = 0;
Adds a call to function ‘fp’ with argument ‘arg’ to the list pointed to by ‘head’.
CALL *global_checks = 0; calls_add(&global_checks,complex_ok,(void *)x);
Execute all/some of the calls in the list given by ‘head’. The arguments ‘fp’ and ‘arg’ must both match for each individual call. The null pointer (‘0’) matches anything whilst any other value requires an exact match between the ‘CALL’ and the arguments to ‘calls_exec’. For example:
calls_exec(&l,0,0); /* execute all functions in l */ calls_exec(&l,complex_print,0); /* calls complex_print(*) in l */ calls_exec(&l,0,(void*) &b); /* calls *(&b) in l */ calls_exec(&l,f,(void*) &b); /* calls f(&b) in l */
Delete all/some of the calls in the list given by ‘head’. The arguments ‘fp’ and ‘arg’ must both match for each individual call. The null pointer (‘0’) matches anything whilst any other value requires an exact match between the ‘CALL’ and the arguments to ‘calls_delete’. For example:
calls_delete(&l,0,0); /* delete all functions in l */ calls_delete(&l,complex_print,0); /* delete complex_print(*) in l */ calls_delete(&l,0,(void*) &b); /* delete *(&b) in l */ calls_delete(&l,f,(void*) &b); /* delete f(&b) in l */
Note: that calls are added to the head of the list rather than the tail. This means that the most recently added call will be executed first (as in a stack).