1*2153Seric # include	"../hdr/defines.h"
2*2153Seric # include	"../hdr/had.h"
3*2153Seric 
4*2153Seric SCCSID(@(#)stree.c	4.1);
5*2153Seric USXALLOC();
6*2153Seric 
7*2153Seric struct	tree {
8*2153Seric 	int	t_dsucc;		/* first successor (trunk) */
9*2153Seric 	struct	list	*t_osucc;	/* other successors */
10*2153Seric 	int	t_trunk;		/* != 0 is a trunk delta */
11*2153Seric };
12*2153Seric 
13*2153Seric struct	list {
14*2153Seric 	struct	list	*l_next;
15*2153Seric 	int	l_val;
16*2153Seric };
17*2153Seric 
18*2153Seric struct	position {
19*2153Seric 	int	p_depth;
20*2153Seric 	int	p_width;
21*2153Seric 	int	p_node;
22*2153Seric };
23*2153Seric 
24*2153Seric 
25*2153Seric struct	tree	*tree;
26*2153Seric struct	position	*pos;
27*2153Seric int	dval;
28*2153Seric 
29*2153Seric struct packet gpkt;
30*2153Seric struct sid sid;
31*2153Seric int	num_files;
32*2153Seric char	had[26];
33*2153Seric 
34*2153Seric main(argc,argv)
35*2153Seric int argc;
36*2153Seric register char *argv[];
37*2153Seric {
38*2153Seric 	register int i;
39*2153Seric 	register char *p;
40*2153Seric 	char c;
41*2153Seric 	int testmore;
42*2153Seric 	extern prttree();
43*2153Seric 	extern int Fcnt;
44*2153Seric 
45*2153Seric 	Fflags = FTLEXIT | FTLMSG | FTLCLN;
46*2153Seric 	for(i = 1; i < argc; i++)
47*2153Seric 		if(argv[i][0] == '-' && (c=argv[i][1])) {
48*2153Seric 			p = &argv[i][2];
49*2153Seric 			testmore = 0;
50*2153Seric 			switch (c) {
51*2153Seric 
52*2153Seric 			case 'p':
53*2153Seric 				testmore++;
54*2153Seric 				break;
55*2153Seric 
56*2153Seric 			default:
57*2153Seric 				fatal("unknown key letter (cm1)");
58*2153Seric 			}
59*2153Seric 
60*2153Seric 			if (testmore) {
61*2153Seric 				testmore = 0;
62*2153Seric 				if (*p)
63*2153Seric 					fatal(sprintf(Error,
64*2153Seric 					  "value after %c arg (cm7)",c));
65*2153Seric 			}
66*2153Seric 			if (had[c - 'a']++)
67*2153Seric 				fatal("key letter twice (cm2)");
68*2153Seric 			argv[i] = 0;
69*2153Seric 		}
70*2153Seric 		else num_files++;
71*2153Seric 
72*2153Seric 	if(num_files == 0)
73*2153Seric 		fatal("missing file arg (cm3)");
74*2153Seric 	setsig();
75*2153Seric 	Fflags =& ~FTLEXIT;
76*2153Seric 	Fflags =| FTLJMP;
77*2153Seric 	for (i = 1; i < argc; i++)
78*2153Seric 		if (p=argv[i])
79*2153Seric 			do_file(p,prttree);
80*2153Seric 	exit(Fcnt ? 1 : 0);
81*2153Seric }
82*2153Seric 
83*2153Seric 
84*2153Seric prttree(file)
85*2153Seric {
86*2153Seric 	register struct idel *rdp;
87*2153Seric 	register int n, i;
88*2153Seric 	char str[32];
89*2153Seric 	extern char had_dir, had_standinp;
90*2153Seric 	struct stats stats;
91*2153Seric 	extern poscomp();
92*2153Seric 
93*2153Seric 	if (setjmp(Fjmp))
94*2153Seric 		return;
95*2153Seric 	sinit(&gpkt, file, 1);
96*2153Seric 	gpkt.p_verbose = -1;
97*2153Seric 	gpkt.p_stdout = stderr;
98*2153Seric 	if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp))
99*2153Seric 		fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file);
100*2153Seric 
101*2153Seric 	if (dodelt(&gpkt,&stats,0,0) == 0)
102*2153Seric 		fmterr(&gpkt);
103*2153Seric 	fclose(gpkt.p_iop);
104*2153Seric 	gpkt.p_iop = 0;
105*2153Seric 
106*2153Seric 	tree = alloc(n = ((maxser(&gpkt) + 1) * sizeof(struct tree)));
107*2153Seric 	zero(tree, n);
108*2153Seric 	pos = alloc(n = ((maxser(&gpkt) + 1) * sizeof(struct position)));
109*2153Seric 	zero(pos, n);
110*2153Seric 	for (i = 1; i <= maxser(&gpkt); i++)
111*2153Seric 		pos[i].p_node = i;
112*2153Seric 	rdp = gpkt.p_idel;
113*2153Seric 	for (i = 1; i <= maxser(&gpkt); i++) {
114*2153Seric 		if (rdp[i].i_sid.s_br == 0)
115*2153Seric 			tree[i].t_trunk = 1;
116*2153Seric 		else
117*2153Seric 			pos[i].p_width = pos[rdp[i].i_pred].p_width + 1;
118*2153Seric 		for (n = i + 1; n <= maxser(&gpkt); n++)
119*2153Seric 			if (rdp[n].i_pred == i)
120*2153Seric 				addsucc(i, n, rdp[n].i_sid.s_br);
121*2153Seric 	}
122*2153Seric 	dval = 0;
123*2153Seric 	traverse(1);
124*2153Seric 	if (!HADP) {
125*2153Seric 		qsort(&pos[1], maxser(&gpkt), sizeof(pos[1]), poscomp);
126*2153Seric 		for (n = 1; n <= maxser(&gpkt); n++) {
127*2153Seric 			sid_ba(&rdp[pos[n].p_node].i_sid, str);
128*2153Seric 			printf("Node %d\tSid %s\tDepth %d\tWidth %d\n",
129*2153Seric 				pos[n].p_node, str, pos[n].p_depth, pos[n].p_width);
130*2153Seric 		}
131*2153Seric 	}
132*2153Seric 	else
133*2153Seric 		plot(rdp, maxser(&gpkt));
134*2153Seric 	xfreeall();
135*2153Seric }
136*2153Seric 
137*2153Seric 
138*2153Seric addsucc(par, child, childbr)
139*2153Seric {
140*2153Seric 	struct tree *tp;
141*2153Seric 
142*2153Seric 	tp = &tree[par];
143*2153Seric 	if (tp->t_trunk && tp->t_dsucc == 0 && childbr == 0)
144*2153Seric 		tp->t_dsucc = child;
145*2153Seric 	else
146*2153Seric 		addlist(&tp->t_osucc, child);
147*2153Seric }
148*2153Seric 
149*2153Seric 
150*2153Seric addlist(headp, val)
151*2153Seric struct list *headp;
152*2153Seric {
153*2153Seric 	struct list *prev, *p;
154*2153Seric 
155*2153Seric 	for (p = headp; p = (prev = p)->l_next; )
156*2153Seric 		;
157*2153Seric 	prev->l_next = p = alloc(sizeof(struct list));
158*2153Seric 	p->l_next = 0;
159*2153Seric 	p->l_val = val;
160*2153Seric }
161*2153Seric 
162*2153Seric 
163*2153Seric traverse(node)
164*2153Seric {
165*2153Seric 	register struct list *lp;
166*2153Seric 
167*2153Seric 	pos[node].p_depth = dval;
168*2153Seric 	if (lp = tree[node].t_osucc) {
169*2153Seric 		traverse(lp->l_val);
170*2153Seric 		while (lp = lp->l_next) {
171*2153Seric 			++dval;
172*2153Seric 			traverse(lp->l_val);
173*2153Seric 		}
174*2153Seric 	}
175*2153Seric 	if (tree[node].t_dsucc) {
176*2153Seric 		++dval;
177*2153Seric 		traverse(tree[node].t_dsucc);
178*2153Seric 	}
179*2153Seric }
180*2153Seric 
181*2153Seric 
182*2153Seric poscomp(p1, p2)
183*2153Seric register struct position *p1, *p2;
184*2153Seric {
185*2153Seric 	register int diff;
186*2153Seric 
187*2153Seric 	if (diff = p1->p_depth - p2->p_depth)
188*2153Seric 		return(diff);
189*2153Seric 	else
190*2153Seric 		return(p1->p_width - p2->p_width);
191*2153Seric }
192*2153Seric 
193*2153Seric 
194*2153Seric dmptree()
195*2153Seric {
196*2153Seric 	register int n;
197*2153Seric 	register struct tree *tp;
198*2153Seric 	register struct list *lp;
199*2153Seric 
200*2153Seric 	for (n = maxser(&gpkt); n; n--) {
201*2153Seric 		printf("Node %d", n);
202*2153Seric 		tp = &tree[n];
203*2153Seric 		if (tp->t_dsucc)
204*2153Seric 			printf("\t%d", tp->t_dsucc);
205*2153Seric 		for (lp = tp->t_osucc; lp; lp = lp->l_next)
206*2153Seric 			printf("\t%d", lp->l_val);
207*2153Seric 		printf("\n");
208*2153Seric 	}
209*2153Seric }
210*2153Seric 
211*2153Seric 
212*2153Seric plot(rdp, n)
213*2153Seric register struct idel *rdp;
214*2153Seric {
215*2153Seric 	char str[32];
216*2153Seric 	int i, j, x, y, node;
217*2153Seric 	struct tree *tp;
218*2153Seric 	struct list *lp;
219*2153Seric 
220*2153Seric 	for (i = 1; i <= n; i++) {
221*2153Seric 		node = pos[i].p_node;
222*2153Seric 		x = pos[i].p_width;
223*2153Seric 		y = pos[i].p_depth;
224*2153Seric 		sid_ba(&rdp[node].i_sid, str);
225*2153Seric 		pllabel(str, x, y);
226*2153Seric 		tp = &tree[node];
227*2153Seric 		if (j = tp->t_dsucc)
228*2153Seric 			plline(x, y, pos[j].p_width, pos[j].p_depth);
229*2153Seric 		for (lp = tp->t_osucc; lp; lp = lp->l_next) {
230*2153Seric 			j = lp->l_val;
231*2153Seric 			plline(x, y, pos[j].p_width, pos[j].p_depth);
232*2153Seric 		}
233*2153Seric 	}
234*2153Seric 	pllabel("", 0, 15);
235*2153Seric }
236*2153Seric 
237*2153Seric 
238*2153Seric pllabel(s, x, y)
239*2153Seric {
240*2153Seric 	x = scx(x) + 64;
241*2153Seric 	y = scy(y) + 64;
242*2153Seric 	putchar('m');
243*2153Seric 	putwd(x);
244*2153Seric 	putwd(y);
245*2153Seric 	printf("t%s\n", s);
246*2153Seric }
247*2153Seric 
248*2153Seric 
249*2153Seric plline(x0, y0, x1, y1)
250*2153Seric {
251*2153Seric 	x0 = scx(x0);
252*2153Seric 	x1 = scx(x1);
253*2153Seric 	y0 = scy(y0);
254*2153Seric 	y1 = scy(y1);
255*2153Seric 	putchar('l');
256*2153Seric 	putwd(x0);
257*2153Seric 	putwd(y0);
258*2153Seric 	putwd(x1);
259*2153Seric 	putwd(y1);
260*2153Seric }
261*2153Seric 
262*2153Seric 
263*2153Seric putwd(w)
264*2153Seric {
265*2153Seric 	register char *p;
266*2153Seric 
267*2153Seric 	p = &w;
268*2153Seric 	putchar(*p++);
269*2153Seric 	putchar(*p);
270*2153Seric }
271*2153Seric 
272*2153Seric 
273*2153Seric scx(xi)
274*2153Seric {
275*2153Seric 	return(xi * 1024 - 2047);
276*2153Seric }
277*2153Seric 
278*2153Seric 
279*2153Seric scy(yi)
280*2153Seric {
281*2153Seric 	return(2047 - (yi * 256));
282*2153Seric }
283*2153Seric 
284*2153Seric 
285*2153Seric clean_up(n)
286*2153Seric {
287*2153Seric 	xfreeall();
288*2153Seric }
289*2153Seric 
290*2153Seric 
291*2153Seric escdodelt()	/* dummy for dodelt() */
292*2153Seric {
293*2153Seric }
294