1 #include "autod.h"
2 #include <stdio.h>
3
do_autod_register(AutodRegistryNode * head,void ** ptr,autod_destructor_t destr)4 void do_autod_register(AutodRegistryNode *head, void **ptr,
5 autod_destructor_t destr) {
6 AutodRegistryNode *newnode = (AutodRegistryNode*)
7 malloc(sizeof(AutodRegistryNode));
8 newnode->ptr = ptr;
9 newnode->destructor = destr;
10 newnode->next = head->next;
11 head->next = newnode;
12
13 *(ptr) = 0; /* zero the pointer to make sure it doesn't contain
14 * garbage */
15 }
16
do_autod_assign(AutodRegistryNode * head,void ** ptr,void * newvalue)17 void do_autod_assign(AutodRegistryNode *head, void **ptr, void *newvalue) {
18 AutodRegistryNode *n;
19
20 if (*ptr) {
21 /* destroy previous value before attributing a new value; for that,
22 * we must look for the corresponding node in the registry */
23 n = head->next;
24 while (n) {
25 if (n->ptr == ptr) {
26 /* got it, call destructor */
27 (*(n->destructor))(*ptr);
28 break;
29 }
30 }
31
32 if (!n) {
33 /* not found: abort */
34 fprintf(stderr, "autod: FATAL ERROR: attempt to assign to\n"
35 "unregistered pointer.\n\n");
36 abort();
37 }
38 }
39
40 /* we are clear to assign a new value */
41 *ptr = newvalue;
42 }
43
do_autod_cleanup(AutodRegistryNode * head,void * ignore_ptr)44 void do_autod_cleanup(AutodRegistryNode *head, void *ignore_ptr) {
45 AutodRegistryNode *n = head->next;
46 AutodRegistryNode *next;
47
48 while (n) {
49 if (*(n->ptr) && *(n->ptr) != ignore_ptr)
50 (*(n->destructor))(*(n->ptr)); /* call destructor */
51
52 next = n->next;
53 free(n); /* free the node */
54
55 n = next; /* advance to next */
56 }
57 }
58
59