/[cvs]/eggdrop1.9/src/registry.c
ViewVC logotype

Contents of /eggdrop1.9/src/registry.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Fri Mar 22 16:01:20 2002 UTC (17 years, 6 months ago) by ite
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +0 -0 lines
File MIME type: text/x-chdr
FILE REMOVED
* Created eggdrop's library context.
* Moved registry stuff to libeggdrop.
* Some headers vs. prototypes cleanups.

1 #include <stdio.h>
2 #include <string.h> /* strlen(), memset(), memmove() */
3 #include <stdlib.h>
4
5 #include "lib/egglib/hash_table.h"
6 typedef int (*Function)();
7 #include "registry.h"
8
9 typedef struct registry_internal_entry_b {
10 char *key;
11 Function callback;
12 void *client_data;
13 registry_entry_t **main; /* Pointer to the "main" function(s). */
14 int nmain;
15 registry_entry_t **chains; /* Chain functions. */
16 int nchains;
17 Function **listeners; /* Addresses of those who are using this entry. */
18 void ***listener_handles; /* Ditto. */
19 int nlisteners;
20 } registry_internal_entry_t;
21
22 static int update_listeners(registry_internal_entry_t *internal);
23 static int arbitrator(registry_internal_entry_t *internal, ...);
24
25 static hash_table_t *registry_table = NULL;
26
27 int registry_add(registry_entry_t *entry)
28 {
29 registry_internal_entry_t *internal;
30 char *key;
31
32 if (!registry_table) {
33 registry_table = hash_table_create(NULL, NULL, 13, 0);
34 }
35
36 key = (char *)malloc(strlen(entry->class)+strlen(entry->name)+4);
37 sprintf(key, "%s / %s", entry->class, entry->name);
38
39 /* Look up registry entry. */
40 if (hash_table_find(registry_table, key, &internal)) {
41 /* Doesn't exist yet, get a new one. */
42 internal = (registry_internal_entry_t *)malloc(sizeof(*internal));
43 memset(internal, 0, sizeof(*internal));
44 internal->key = key;
45 hash_table_insert(registry_table, key, internal);
46 }
47 else free(key);
48
49 if (entry->flags & REGISTRY_MAIN) {
50 internal->nmain++;
51 internal->main = (registry_entry_t **)realloc(internal->main, internal->nmain * sizeof(void *));
52 internal->main[internal->nmain-1] = entry;
53 }
54 else if (entry->flags & REGISTRY_CHAIN) {
55 internal->nchains++;
56 internal->chains = (registry_entry_t **)realloc(internal->chains, internal->nchains * sizeof(void *));
57 if (entry->flags & REGISTRY_PREPEND) {
58 memmove(internal->chains+1, internal->chains, sizeof(void *) * (internal->nchains-1));
59 internal->chains[0] = entry;
60 }
61 else {
62 internal->chains[internal->nchains-1] = entry;
63 }
64 }
65
66 update_listeners(internal);
67
68 return(0);
69 }
70
71 int registry_add_table(registry_entry_t *entries)
72 {
73 while (entries->callback) {
74 registry_add(entries);
75 entries++;
76 }
77 return(0);
78 }
79
80 int registry_add_simple_chains(registry_simple_chain_t *entries)
81 {
82 registry_entry_t *entry;
83 char *class;
84
85 /* First entry gives the class. */
86 class = entries->name;
87 entries++;
88 while (entries->name) {
89 entry = (registry_entry_t *)calloc(1, sizeof(*entry));
90 entry->class = class;
91 entry->name = entries->name;
92 entry->callback = entries->callback;
93 entry->nargs = entries->nargs;
94 entry->flags = REGISTRY_CHAIN;
95 registry_add(entry);
96 entries++;
97 }
98 return(0);
99 }
100
101 int registry_remove(registry_entry_t *entry)
102 {
103 printf("registry_remove(%s, %s)\n", entry->class, entry->name);
104 return(0);
105 }
106
107 int registry_remove_table(registry_entry_t *entries)
108 {
109 while (entries->callback) {
110 registry_remove(entries);
111 entries++;
112 }
113 return(0);
114 }
115
116 int registry_lookup(const char *class, const char *name, Function *funcptr, void **handleptr)
117 {
118 registry_internal_entry_t *internal;
119 char *key;
120
121 key = (char *)malloc(strlen(class)+strlen(name)+4);
122 sprintf(key, "%s / %s", class, name);
123
124 if (!registry_table) {
125 registry_table = hash_table_create(NULL, NULL, 13, 0);
126 }
127
128 if (hash_table_find(registry_table, key, &internal)) {
129 /* Doesn't exist -- create it. */
130 internal = (registry_internal_entry_t *)malloc(sizeof(*internal));
131 memset(internal, 0, sizeof(*internal));
132 internal->key = key;
133 hash_table_insert(registry_table, key, internal);
134 internal->callback = (Function) arbitrator;
135 internal->client_data = (void *)internal;
136 }
137 else free(key);
138
139 *funcptr = internal->callback;
140 *handleptr = internal->client_data;
141
142 internal->nlisteners++;
143 internal->listeners = (Function **)realloc(internal->listeners, internal->nlisteners * sizeof(void *));
144 internal->listener_handles = (void ***)realloc(internal->listener_handles, internal->nlisteners * sizeof(void *));
145 internal->listeners[internal->nlisteners-1] = funcptr;
146 internal->listener_handles[internal->nlisteners-1] = handleptr;
147
148 return(0);
149 }
150
151 int registry_unlookup(const char *class, const char *name, Function *funcptr, void **handleptr)
152 {
153 /*
154 memmove(entry->listeners+i, entry->listeners+i+1, (entry->nlisteners-i-1) * sizeof(Function *));
155 entry->nlisteners--;
156 if (!entry->nlisteners) {
157 free(entry->listeners);
158 entry->listeners = NULL;
159 }
160 */
161 return(0);
162 }
163
164 static int update_listeners(registry_internal_entry_t *internal)
165 {
166 int i;
167
168 if (internal->nmain != 0 && internal->nchains == 0) {
169 /* If there's just a main function, give them that. */
170 internal->callback = internal->main[internal->nmain-1]->callback;
171 internal->client_data = internal->main[internal->nmain-1]->client_data;
172 }
173 else {
174 /* Otherwise we use an arbitrator. */
175 internal->callback = (Function) arbitrator;
176 internal->client_data = (void *)internal;
177 }
178
179 for (i = 0; i < internal->nlisteners; i++) {
180 *(internal->listeners[i]) = internal->callback;
181 *(internal->listener_handles[i]) = internal->client_data;
182 }
183 return(0);
184 }
185
186 static int arbitrator(registry_internal_entry_t *internal, ...)
187 {
188 registry_entry_t *entry;
189 int i;
190 int *al = (int *)&internal;
191
192 /* Call chains backwards (first-in-last-out). */
193 for (i = internal->nchains-1; i >= 0; i--) {
194 entry = internal->chains[i];
195 entry->action = 0;
196 switch (entry->nargs) {
197 case 1: entry->callback(entry); break;
198 case 2: entry->callback(entry, al[1]); break;
199 case 3: entry->callback(entry, al[1], al[2]); break;
200 case 4: entry->callback(entry, al[1], al[2], al[3]); break;
201 case 5: entry->callback(entry, al[1], al[2], al[3], al[4]); break;
202 case 6: entry->callback(entry, al[1], al[2], al[3], al[4], al[5]); break;
203 case 7: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6]); break;
204 case 8: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6], al[7]); break;
205 case 9: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6], al[7], al[8]); break;
206 case 10: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6], al[7], al[8], al[9]);
207 }
208 if (entry->action & REGISTRY_HALT) break;
209 }
210
211 if (internal->nmain != 0) {
212 entry = internal->main[internal->nmain-1];
213 switch (entry->nargs) {
214 case 1: entry->callback(entry); break;
215 case 2: entry->callback(entry, al[1]); break;
216 case 3: entry->callback(entry, al[1], al[2]); break;
217 case 4: entry->callback(entry, al[1], al[2], al[3]); break;
218 case 5: entry->callback(entry, al[1], al[2], al[3], al[4]); break;
219 case 6: entry->callback(entry, al[1], al[2], al[3], al[4], al[5]); break;
220 case 7: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6]); break;
221 case 8: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6], al[7]); break;
222 case 9: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6], al[7], al[8]); break;
223 case 10: entry->callback(entry, al[1], al[2], al[3], al[4], al[5], al[6], al[7], al[8], al[9]);
224 }
225 return((int)entry->return_value);
226 }
227 return(0);
228 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23