Commit | Line | Data |
---|---|---|
3d28d0af RG |
1 | /* |
2 | * from: sets.c,v 2.3 88/09/19 12:55:30 nhall Exp | |
3 | * $Id$ | |
4 | */ | |
5 | ||
15637ed4 RG |
6 | /* |
7 | * This code is such a kludge that I don't want to put my name on it. | |
8 | * It was a ridiculously fast hack and needs rewriting. | |
9 | * However it does work... | |
10 | */ | |
11 | #include "main.h" | |
12 | #include "malloc.h" | |
13 | #include "sets.h" | |
14 | #include "debug.h" | |
15 | #include <stdio.h> | |
16 | ||
17 | struct Object *CurrentEvent = (struct Object *)0; | |
18 | struct Object *Objtree; | |
19 | struct Object dummy; | |
20 | /* | |
21 | * define a set w/ type and name | |
22 | * return a set number | |
23 | */ | |
24 | #undef NULL | |
25 | #define NULL (struct Object *)0 | |
26 | ||
27 | static FILE *Sfile, *Efile; | |
28 | extern FILE *astringfile; | |
29 | char *Noname = "Unnamed set\0"; | |
30 | ||
31 | initsets(f,s) | |
32 | FILE *f, *s; | |
33 | { | |
34 | static char errorstring[20]; | |
35 | extern struct Object *SameState; | |
36 | Efile = f; | |
37 | Sfile = s; | |
38 | ||
39 | IFDEBUG(X) | |
40 | fprintf(astringfile, "char *%s_sstring[] = {\n", protocol); | |
41 | ENDDEBUG | |
42 | sprintf(errorstring, "%sERROR\0", ST_PREFIX); | |
43 | defineitem(STATESET, errorstring, (char *)0); /* state 0 */ | |
44 | SameState = (struct Object *) Malloc( sizeof (struct Object) ); | |
45 | SameState->obj_kind = OBJ_ITEM; | |
46 | SameState->obj_type = STATESET; | |
47 | SameState->obj_name = "SAME"; | |
48 | SameState->obj_struc = (char *)0; | |
49 | SameState->obj_number = 0; | |
50 | SameState->obj_members = (struct Object *)0; | |
51 | SameState->obj_left = (struct Object *)0; | |
52 | SameState->obj_right = (struct Object *)0; | |
53 | SameState->obj_parent = (struct Object *)0; | |
54 | } | |
55 | ||
56 | /* | |
57 | * get a set based on its type and name | |
58 | * returns address of an Object, may be set or item | |
59 | */ | |
60 | ||
61 | struct Object *lookup(type, name) | |
62 | unsigned char type; | |
63 | char *name; | |
64 | { | |
65 | register struct Object *p = Objtree; | |
66 | int val = 1 ; | |
67 | ||
68 | IFDEBUG(o) | |
69 | fprintf(stdout,"lookup 0x%x,%s \n", | |
70 | type, name); | |
71 | ENDDEBUG | |
72 | ||
73 | while( p && val ) { | |
74 | IFDEBUG(o) | |
75 | fprintf(OUT, "lookup strcmp 0x%x,%s, 0x%x,%s\n", | |
76 | name, name, OBJ_NAME(p), OBJ_NAME(p)); | |
77 | ENDDEBUG | |
78 | if( p->obj_name == (char *)0 ) { | |
79 | fprintf(stderr, "Unnamed set in table!\n"); | |
80 | Exit(-1); | |
81 | } | |
82 | val = (int) strcmp(name, OBJ_NAME(p)); | |
83 | if(val < 0) { | |
84 | /* left */ | |
85 | p = p->obj_left; | |
86 | } else if (val > 0) { | |
87 | /* right */ | |
88 | p = p->obj_right; | |
89 | } | |
90 | } | |
91 | if( p && ( p->obj_type != type)) { | |
92 | fprintf(stdout, "lookup(0x%x,%s) found wrong obj type 0x%x\n", | |
93 | type,name, p->obj_type); | |
94 | p = NULL; | |
95 | } | |
96 | IFDEBUG(o) | |
97 | fprintf(stdout,"lookup 0x%x,%s returning 0x%x\n",type, name, p); | |
98 | ENDDEBUG | |
99 | return(p); | |
100 | } | |
101 | ||
102 | static int states_done = 0; | |
103 | ||
104 | end_states(f) | |
105 | FILE *f; | |
106 | { | |
107 | register unsigned n = Nstates; | |
108 | register int i; | |
109 | extern char Eventshiftstring[]; | |
110 | ||
111 | states_done = 1; | |
112 | ||
113 | for( i = 0; ;i++) { | |
114 | if( (n >>= 1) <= 0 ) break; | |
115 | } | |
116 | Eventshift = i+1; | |
117 | IFDEBUG(d) | |
118 | fprintf(OUT, "Eventshift=%d\n", Eventshift); | |
119 | ENDDEBUG | |
120 | sprintf(Eventshiftstring, "%d\0",Eventshift); | |
121 | fprintf(f, "struct %s_event {\n\tint ev_number;\n", &protocol[0]); | |
122 | IFDEBUG(X) | |
123 | /* finish sstring[] & start estring[] */ | |
124 | fprintf(astringfile, | |
125 | "};\n\nchar *%s_estring[] = {\n", protocol); | |
126 | ENDDEBUG | |
127 | } | |
128 | ||
129 | int FirstEventAttribute = 1; | |
130 | ||
131 | static | |
132 | insert(o) | |
133 | struct Object *o; | |
134 | { | |
135 | struct Object *p = Objtree; | |
136 | struct Object **q = &Objtree; | |
137 | int val=1; | |
138 | ||
139 | ||
140 | if (o->obj_name == (char *)0) { | |
141 | fprintf(stderr, "Internal Error: inserting unnamed object\n"); | |
142 | Exit(-1); | |
143 | } | |
144 | if( o->obj_type == STATESET) { | |
145 | if( states_done ) { | |
146 | fprintf(stderr, "No states may be defined after *TRANSITIONS\n"); | |
147 | Exit(-1); | |
148 | } | |
149 | o->obj_number = Nstates++ ; | |
150 | if(Nstates > MAXSTATES) { | |
151 | fprintf(stderr, "Too many states\n"); | |
152 | Exit(-1); | |
153 | } | |
154 | fprintf(Sfile, "#define %s 0x%x\n", o->obj_name, o->obj_number); | |
155 | IFDEBUG(X) | |
156 | fprintf(astringfile, "\"%s(0x%x)\",\n", o->obj_name, o->obj_number); | |
157 | ENDDEBUG | |
158 | } else { | |
159 | /* EVENTSET */ | |
160 | if( ! states_done ) { | |
161 | fprintf(stderr, "states must precede events\n"); | |
162 | Exit(-1); | |
163 | } | |
164 | o->obj_number = Nevents++ ; | |
165 | if(Nevents > MAXEVENTS) { | |
166 | fprintf(stderr, "Too many events\n"); | |
167 | Exit(-1); | |
168 | } | |
169 | if(o->obj_struc) { | |
170 | if( FirstEventAttribute ) { | |
171 | fprintf(Efile, "\n\tunion{\n"); /*} */ | |
172 | FirstEventAttribute = 0; | |
173 | } | |
174 | fprintf(Efile, | |
175 | "struct %s %s%s;\n\n", o->obj_struc, EV_PREFIX, o->obj_name); | |
176 | } | |
177 | fprintf(Efile, "#define %s 0x%x\n", o->obj_name, o->obj_number); | |
178 | IFDEBUG(X) | |
179 | fprintf(astringfile, "\"%s(0x%x)\",\n", o->obj_name, o->obj_number); | |
180 | ENDDEBUG | |
181 | } | |
182 | IFDEBUG(o) | |
183 | fprintf(OUT, "insert(%s)\n", OBJ_NAME(o) ); | |
184 | if(o->obj_right != NULL) { | |
185 | fprintf(OUT, "insert: unclean Object right\n"); | |
186 | exit(-1); | |
187 | } | |
188 | if(o->obj_left != NULL) { | |
189 | fprintf(OUT, "insert: unclean Object left\n"); | |
190 | exit(-1); | |
191 | } | |
192 | fflush(OUT); | |
193 | ENDDEBUG | |
194 | ||
195 | while( val ) { | |
196 | if(p == NULL) { | |
197 | *q = o; | |
198 | o->obj_parent = (struct Object *)q; | |
199 | break; | |
200 | } | |
201 | if(!(val = strcmp(o->obj_name, p->obj_name)) ) { | |
202 | /* equal */ | |
203 | fprintf(stderr, "re-inserting %s\n",o->obj_name); | |
204 | exit(-1); | |
205 | } | |
206 | if(val < 0) { | |
207 | /* left */ | |
208 | q = &p->obj_left; | |
209 | p = p->obj_left; | |
210 | } else { | |
211 | /* right */ | |
212 | q = &p->obj_right; | |
213 | p = p->obj_right; | |
214 | } | |
215 | } | |
216 | IFDEBUG(a) | |
217 | dumptree(Objtree,0); | |
218 | ENDDEBUG | |
219 | } | |
220 | ||
221 | delete(o) | |
222 | struct Object *o; | |
223 | { | |
224 | register struct Object *p = o->obj_right; | |
225 | register struct Object *q; | |
226 | register struct Object *newparent; | |
227 | register struct Object **np_childlink; | |
228 | ||
229 | IFDEBUG(T) | |
230 | fprintf(stdout, "delete(0x%x)\n", o); | |
231 | dumptree(Objtree,0); | |
232 | ENDDEBUG | |
233 | ||
234 | /* q <== lowest valued node of the right subtree */ | |
235 | while( p ) { | |
236 | q = p; | |
237 | p = p->obj_left; | |
238 | } | |
239 | ||
240 | if (o->obj_parent == (struct Object *)&Objtree) { | |
241 | newparent = (struct Object *)&Objtree; | |
242 | np_childlink = (struct Object **)&Objtree; | |
243 | } else if(o->obj_parent->obj_left == o) { | |
244 | newparent = o->obj_parent; | |
245 | np_childlink = &(o->obj_parent->obj_left); | |
246 | } else { | |
247 | newparent = o->obj_parent; | |
248 | np_childlink = &(o->obj_parent->obj_right); | |
249 | } | |
250 | IFDEBUG(T) | |
251 | fprintf(OUT, "newparent=0x%x\n"); | |
252 | ENDDEBUG | |
253 | ||
254 | if (q) { /* q gets the left, parent gets the right */ | |
255 | IFDEBUG(T) | |
256 | fprintf(OUT, "delete: q null\n"); | |
257 | ENDDEBUG | |
258 | q->obj_left = p; | |
259 | if(p) p->obj_parent = q; | |
260 | p = o->obj_right; | |
261 | } else { /* parent(instead of q) gets the left ; there is no right */ | |
262 | IFDEBUG(T) | |
263 | fprintf(OUT, "delete: q not null\n"); | |
264 | ENDDEBUG | |
265 | p = o->obj_left; | |
266 | } | |
267 | *np_childlink = p; | |
268 | if(p) | |
269 | p->obj_parent = newparent; | |
270 | ||
271 | IFDEBUG(T) | |
272 | fprintf(OUT, "After deleting 0x%x\n",o); | |
273 | dumptree(Objtree,0); | |
274 | ENDDEBUG | |
275 | } | |
276 | ||
277 | struct Object * | |
278 | defineset(type, adr, keep) | |
279 | unsigned char type; | |
280 | char *adr; | |
281 | int keep; | |
282 | { | |
283 | struct Object *onew; | |
284 | IFDEBUG(o) | |
285 | printf("defineset(0x%x,%s, %s)\n", type , adr, keep?"KEEP":"NO_KEEP"); | |
286 | ENDDEBUG | |
287 | ||
288 | onew = (struct Object *)Malloc(sizeof (struct Object)); | |
289 | bzero(onew, sizeof(struct Object)); | |
290 | onew->obj_name = adr; | |
291 | onew->obj_kind = OBJ_SET; | |
292 | onew->obj_type = type; | |
293 | if(keep) | |
294 | insert( onew ); | |
295 | /* address already stashed before calling defineset */ | |
296 | IFDEBUG(o) | |
297 | printf("defineset(0x%x,%s) returning 0x%x\n", type , adr, onew); | |
298 | dumptree(Objtree,0); | |
299 | ENDDEBUG | |
300 | return(onew); | |
301 | } | |
302 | ||
303 | dumpit(o, s) | |
304 | char *o; | |
305 | char *s; | |
306 | { | |
307 | register int i; | |
308 | ||
309 | IFDEBUG(o) | |
310 | fprintf(OUT, "object 0x%x, %s\n",o, s); | |
311 | for(i=0; i< sizeof(struct Object); i+=4) { | |
312 | fprintf(OUT, "0x%x: 0x%x 0x%x 0x%x 0x%x\n", | |
313 | *((int *)o), *o, *(o+1), *(o+2), *(o+3) ); | |
314 | } | |
315 | ENDDEBUG | |
316 | } | |
317 | ||
318 | defineitem(type, adr, struc) | |
319 | unsigned char type; | |
320 | char *adr; | |
321 | char *struc; | |
322 | { | |
323 | struct Object *onew; | |
324 | IFDEBUG(o) | |
325 | printf("defineitem(0x%x, %s at 0x%x, %s)\n", type, adr, adr, struc); | |
326 | ENDDEBUG | |
327 | ||
328 | if( onew = lookup( type, adr ) ) { | |
329 | fprintf(stderr, | |
330 | "Internal error at defineitem: trying to redefine obj type 0x%x, adr %s\n", | |
331 | type, adr); | |
332 | exit(-1); | |
333 | } else { | |
334 | onew = (struct Object *)Malloc(sizeof (struct Object)); | |
335 | bzero(onew, sizeof(struct Object)); | |
336 | onew->obj_name = stash(adr); | |
337 | onew->obj_kind = OBJ_ITEM; | |
338 | onew->obj_type = type; | |
339 | onew->obj_struc = struc?stash(struc):struc; | |
340 | insert( onew ); | |
341 | } | |
342 | IFDEBUG(o) | |
343 | fprintf(OUT, "defineitem(0x%x, %s) returning 0x%x\n", type, adr, onew); | |
344 | ENDDEBUG | |
345 | } | |
346 | ||
347 | member(o, adr) | |
348 | struct Object *o; | |
349 | char *adr; | |
350 | { | |
351 | struct Object *onew, *oold; | |
352 | IFDEBUG(o) | |
353 | printf("member(0x%x, %s)\n", o, adr); | |
354 | ENDDEBUG | |
355 | ||
356 | oold = lookup( o->obj_type, adr ); | |
357 | ||
358 | onew = (struct Object *)Malloc(sizeof (struct Object)); | |
359 | if( oold == NULL ) { | |
360 | extern int lineno; | |
361 | ||
362 | fprintf(stderr, | |
363 | "Warning at line %d: set definition of %s causes definition of\n", | |
364 | lineno, OBJ_NAME(o)); | |
365 | fprintf(stderr, "\t (previously undefined) member %s\n", adr); | |
366 | bzero(onew, sizeof(struct Object)); | |
367 | onew->obj_name = stash(adr); | |
368 | onew->obj_kind = OBJ_ITEM; | |
369 | onew->obj_type = o->obj_type; | |
370 | onew->obj_members = NULL; | |
371 | insert( onew ); | |
372 | } else { | |
373 | if(oold->obj_kind != OBJ_ITEM) { | |
374 | fprintf(stderr, "Sets cannot be members of sets; %s\n", adr); | |
375 | exit(-1); | |
376 | } | |
377 | bcopy(oold, onew, sizeof(struct Object)); | |
378 | onew->obj_members = onew->obj_left = onew->obj_right = NULL; | |
379 | } | |
380 | onew->obj_members = o->obj_members; | |
381 | o->obj_members = onew; | |
382 | } | |
383 | ||
384 | struct Object *Lookup(type, name) | |
385 | unsigned char type; | |
386 | char *name; | |
387 | { | |
388 | register struct Object *o = lookup(type,name); | |
389 | ||
390 | if(o == NULL) { | |
391 | fprintf(stderr, "Trying to use undefined %s: %s\n", | |
392 | type==STATESET?"state":"event", name); | |
393 | Exit(-1); | |
394 | } | |
395 | return(o); | |
396 | } | |
397 | ||
398 | AddCurrentEventName(x) | |
399 | register char **x; | |
400 | { | |
401 | register char *n = EV_PREFIX; ; | |
402 | ||
403 | if( CurrentEvent == (struct Object *)0 ) { | |
404 | fprintf(stderr, "No event named! BARF!\n"); Exit(-1); | |
405 | } | |
406 | ||
407 | if( ! CurrentEvent->obj_struc ) { | |
408 | fprintf(stderr, "No attributes for current event!\n"); Exit(-1); | |
409 | } | |
410 | ||
411 | /* add prefix first */ | |
412 | while(*n) { | |
413 | *(*x)++ = *n++; | |
414 | } | |
415 | ||
416 | n = CurrentEvent->obj_name; | |
417 | ||
418 | while(*n) { | |
419 | *(*x)++ = *n++; | |
420 | } | |
421 | } | |
422 | ||
423 | dumptree(o,i) | |
424 | register struct Object *o; | |
425 | int i; | |
426 | { | |
427 | register int j; | |
428 | ||
429 | if(o == NULL) { | |
430 | for(j=0; j<i; j++) | |
431 | fputc(' ', stdout); | |
432 | fprintf(stdout, "%3d NULL\n", i); | |
433 | } else { | |
434 | dumptree(o->obj_left, i+1); | |
435 | for(j=0; j<i; j++) | |
436 | fputc(' ', stdout); | |
437 | fprintf(stdout, "%3d 0x%x: %s\n", i,o, OBJ_NAME(o)); | |
438 | dumptree(o->obj_right, i+1); | |
439 | } | |
440 | } | |
441 | ||
442 | dump(c,a) | |
443 | { | |
444 | register int x = 8; | |
445 | int zero = 0; | |
446 | #include <sys/signal.h> | |
447 | ||
448 | fprintf(stderr, "dump: c 0x%x, a 0x%x\n",c,a); | |
449 | ||
450 | x = x/zero; | |
451 | kill(0, SIGQUIT); | |
452 | } | |
453 | ||
454 | dump_trans( pred, oldstate, newstate, action, event ) | |
455 | struct Object *oldstate, *newstate, *event; | |
456 | char *pred, *action; | |
457 | { | |
458 | extern int transno; | |
459 | struct Object *o; | |
460 | ||
461 | fprintf(stdout, "\n%d: ", transno); | |
462 | #define dumpit(x)\ | |
463 | if((x)->obj_kind == OBJ_SET) {\ | |
464 | o = (x)->obj_members; fprintf( stdout, "[ " );\ | |
465 | while(o) { fprintf(stdout, "%s ", o->obj_name); o = o->obj_members; }\ | |
466 | fprintf( stdout, " ] ");\ | |
467 | } else { fprintf(stdout, "%s ", (x)->obj_name); } | |
468 | ||
469 | dumpit(newstate); | |
470 | fprintf(stdout, " <== "); | |
471 | dumpit(oldstate); | |
472 | dumpit(event); | |
473 | fprintf(stdout, "\n\t\t%s\n\t\t%s\n", pred?pred:"DEFAULT", | |
474 | action); | |
475 | } |