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