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