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