12153Seric # include	"../hdr/defines.h"
22153Seric # include	"../hdr/had.h"
32153Seric 
4*33423Sbostic SCCSID(@(#)stree.c	4.4);
52153Seric USXALLOC();
62153Seric 
72153Seric struct	tree {
82153Seric 	int	t_dsucc;		/* first successor (trunk) */
92153Seric 	struct	list	*t_osucc;	/* other successors */
102153Seric 	int	t_trunk;		/* != 0 is a trunk delta */
112153Seric };
122153Seric 
132153Seric struct	list {
142153Seric 	struct	list	*l_next;
152153Seric 	int	l_val;
162153Seric };
172153Seric 
182153Seric struct	position {
192153Seric 	int	p_depth;
202153Seric 	int	p_width;
212153Seric 	int	p_node;
222153Seric };
232153Seric 
242153Seric 
252153Seric struct	tree	*tree;
262153Seric struct	position	*pos;
272153Seric int	dval;
282153Seric 
292153Seric struct packet gpkt;
302153Seric struct sid sid;
312153Seric int	num_files;
322153Seric char	had[26];
332153Seric 
main(argc,argv)342153Seric main(argc,argv)
352153Seric int argc;
362153Seric register char *argv[];
372153Seric {
382153Seric 	register int i;
392153Seric 	register char *p;
402153Seric 	char c;
412153Seric 	int testmore;
422153Seric 	extern prttree();
432153Seric 	extern int Fcnt;
442153Seric 
452153Seric 	Fflags = FTLEXIT | FTLMSG | FTLCLN;
462153Seric 	for(i = 1; i < argc; i++)
472153Seric 		if(argv[i][0] == '-' && (c=argv[i][1])) {
482153Seric 			p = &argv[i][2];
492153Seric 			testmore = 0;
502153Seric 			switch (c) {
512153Seric 
522153Seric 			case 'p':
532153Seric 				testmore++;
542153Seric 				break;
552153Seric 
562153Seric 			default:
572153Seric 				fatal("unknown key letter (cm1)");
582153Seric 			}
592153Seric 
602153Seric 			if (testmore) {
612153Seric 				testmore = 0;
62*33423Sbostic 				if (*p) {
63*33423Sbostic 					sprintf(Error,"value after %c arg (cm7)",c);
64*33423Sbostic 					fatal(Error);
65*33423Sbostic 				}
662153Seric 			}
672153Seric 			if (had[c - 'a']++)
682153Seric 				fatal("key letter twice (cm2)");
692153Seric 			argv[i] = 0;
702153Seric 		}
712153Seric 		else num_files++;
722153Seric 
732153Seric 	if(num_files == 0)
742153Seric 		fatal("missing file arg (cm3)");
752153Seric 	setsig();
7632773Sbostic 	Fflags &= ~FTLEXIT;
7732773Sbostic 	Fflags |= FTLJMP;
782153Seric 	for (i = 1; i < argc; i++)
792153Seric 		if (p=argv[i])
802153Seric 			do_file(p,prttree);
812153Seric 	exit(Fcnt ? 1 : 0);
822153Seric }
832153Seric 
842153Seric 
prttree(file)852153Seric prttree(file)
862153Seric {
872153Seric 	register struct idel *rdp;
882153Seric 	register int n, i;
892153Seric 	char str[32];
902153Seric 	extern char had_dir, had_standinp;
912153Seric 	struct stats stats;
922153Seric 	extern poscomp();
932153Seric 
942153Seric 	if (setjmp(Fjmp))
952153Seric 		return;
962153Seric 	sinit(&gpkt, file, 1);
972153Seric 	gpkt.p_verbose = -1;
982153Seric 	gpkt.p_stdout = stderr;
992153Seric 	if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp))
1002153Seric 		fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file);
1012153Seric 
1022153Seric 	if (dodelt(&gpkt,&stats,0,0) == 0)
1032153Seric 		fmterr(&gpkt);
1042153Seric 	fclose(gpkt.p_iop);
1052153Seric 	gpkt.p_iop = 0;
1062153Seric 
1072153Seric 	tree = alloc(n = ((maxser(&gpkt) + 1) * sizeof(struct tree)));
10819944Ssam 	bzero(tree, n);
1092153Seric 	pos = alloc(n = ((maxser(&gpkt) + 1) * sizeof(struct position)));
11019944Ssam 	bzero(pos, n);
1112153Seric 	for (i = 1; i <= maxser(&gpkt); i++)
1122153Seric 		pos[i].p_node = i;
1132153Seric 	rdp = gpkt.p_idel;
1142153Seric 	for (i = 1; i <= maxser(&gpkt); i++) {
1152153Seric 		if (rdp[i].i_sid.s_br == 0)
1162153Seric 			tree[i].t_trunk = 1;
1172153Seric 		else
1182153Seric 			pos[i].p_width = pos[rdp[i].i_pred].p_width + 1;
1192153Seric 		for (n = i + 1; n <= maxser(&gpkt); n++)
1202153Seric 			if (rdp[n].i_pred == i)
1212153Seric 				addsucc(i, n, rdp[n].i_sid.s_br);
1222153Seric 	}
1232153Seric 	dval = 0;
1242153Seric 	traverse(1);
1252153Seric 	if (!HADP) {
1262153Seric 		qsort(&pos[1], maxser(&gpkt), sizeof(pos[1]), poscomp);
1272153Seric 		for (n = 1; n <= maxser(&gpkt); n++) {
1282153Seric 			sid_ba(&rdp[pos[n].p_node].i_sid, str);
1292153Seric 			printf("Node %d\tSid %s\tDepth %d\tWidth %d\n",
1302153Seric 				pos[n].p_node, str, pos[n].p_depth, pos[n].p_width);
1312153Seric 		}
1322153Seric 	}
1332153Seric 	else
1342153Seric 		plot(rdp, maxser(&gpkt));
1352153Seric 	xfreeall();
1362153Seric }
1372153Seric 
1382153Seric 
addsucc(par,child,childbr)1392153Seric addsucc(par, child, childbr)
1402153Seric {
1412153Seric 	struct tree *tp;
1422153Seric 
1432153Seric 	tp = &tree[par];
1442153Seric 	if (tp->t_trunk && tp->t_dsucc == 0 && childbr == 0)
1452153Seric 		tp->t_dsucc = child;
1462153Seric 	else
1472153Seric 		addlist(&tp->t_osucc, child);
1482153Seric }
1492153Seric 
1502153Seric 
1512153Seric addlist(headp, val)
1522153Seric struct list *headp;
1532153Seric {
1542153Seric 	struct list *prev, *p;
1552153Seric 
1562153Seric 	for (p = headp; p = (prev = p)->l_next; )
1572153Seric 		;
1582153Seric 	prev->l_next = p = alloc(sizeof(struct list));
1592153Seric 	p->l_next = 0;
1602153Seric 	p->l_val = val;
1612153Seric }
1622153Seric 
1632153Seric 
traverse(node)1642153Seric traverse(node)
1652153Seric {
1662153Seric 	register struct list *lp;
1672153Seric 
1682153Seric 	pos[node].p_depth = dval;
1692153Seric 	if (lp = tree[node].t_osucc) {
1702153Seric 		traverse(lp->l_val);
1712153Seric 		while (lp = lp->l_next) {
1722153Seric 			++dval;
1732153Seric 			traverse(lp->l_val);
1742153Seric 		}
1752153Seric 	}
1762153Seric 	if (tree[node].t_dsucc) {
1772153Seric 		++dval;
1782153Seric 		traverse(tree[node].t_dsucc);
1792153Seric 	}
1802153Seric }
1812153Seric 
1822153Seric 
poscomp(p1,p2)1832153Seric poscomp(p1, p2)
1842153Seric register struct position *p1, *p2;
1852153Seric {
1862153Seric 	register int diff;
1872153Seric 
1882153Seric 	if (diff = p1->p_depth - p2->p_depth)
1892153Seric 		return(diff);
1902153Seric 	else
1912153Seric 		return(p1->p_width - p2->p_width);
1922153Seric }
1932153Seric 
1942153Seric 
dmptree()1952153Seric dmptree()
1962153Seric {
1972153Seric 	register int n;
1982153Seric 	register struct tree *tp;
1992153Seric 	register struct list *lp;
2002153Seric 
2012153Seric 	for (n = maxser(&gpkt); n; n--) {
2022153Seric 		printf("Node %d", n);
2032153Seric 		tp = &tree[n];
2042153Seric 		if (tp->t_dsucc)
2052153Seric 			printf("\t%d", tp->t_dsucc);
2062153Seric 		for (lp = tp->t_osucc; lp; lp = lp->l_next)
2072153Seric 			printf("\t%d", lp->l_val);
2082153Seric 		printf("\n");
2092153Seric 	}
2102153Seric }
2112153Seric 
2122153Seric 
plot(rdp,n)2132153Seric plot(rdp, n)
2142153Seric register struct idel *rdp;
2152153Seric {
2162153Seric 	char str[32];
2172153Seric 	int i, j, x, y, node;
2182153Seric 	struct tree *tp;
2192153Seric 	struct list *lp;
2202153Seric 
2212153Seric 	for (i = 1; i <= n; i++) {
2222153Seric 		node = pos[i].p_node;
2232153Seric 		x = pos[i].p_width;
2242153Seric 		y = pos[i].p_depth;
2252153Seric 		sid_ba(&rdp[node].i_sid, str);
2262153Seric 		pllabel(str, x, y);
2272153Seric 		tp = &tree[node];
2282153Seric 		if (j = tp->t_dsucc)
2292153Seric 			plline(x, y, pos[j].p_width, pos[j].p_depth);
2302153Seric 		for (lp = tp->t_osucc; lp; lp = lp->l_next) {
2312153Seric 			j = lp->l_val;
2322153Seric 			plline(x, y, pos[j].p_width, pos[j].p_depth);
2332153Seric 		}
2342153Seric 	}
2352153Seric 	pllabel("", 0, 15);
2362153Seric }
2372153Seric 
2382153Seric 
pllabel(s,x,y)2392153Seric pllabel(s, x, y)
2402153Seric {
2412153Seric 	x = scx(x) + 64;
2422153Seric 	y = scy(y) + 64;
2432153Seric 	putchar('m');
2442153Seric 	putwd(x);
2452153Seric 	putwd(y);
2462153Seric 	printf("t%s\n", s);
2472153Seric }
2482153Seric 
2492153Seric 
plline(x0,y0,x1,y1)2502153Seric plline(x0, y0, x1, y1)
2512153Seric {
2522153Seric 	x0 = scx(x0);
2532153Seric 	x1 = scx(x1);
2542153Seric 	y0 = scy(y0);
2552153Seric 	y1 = scy(y1);
2562153Seric 	putchar('l');
2572153Seric 	putwd(x0);
2582153Seric 	putwd(y0);
2592153Seric 	putwd(x1);
2602153Seric 	putwd(y1);
2612153Seric }
2622153Seric 
2632153Seric 
putwd(w)2642153Seric putwd(w)
2652153Seric {
2662153Seric 	register char *p;
2672153Seric 
2682153Seric 	p = &w;
2692153Seric 	putchar(*p++);
2702153Seric 	putchar(*p);
2712153Seric }
2722153Seric 
2732153Seric 
scx(xi)2742153Seric scx(xi)
2752153Seric {
2762153Seric 	return(xi * 1024 - 2047);
2772153Seric }
2782153Seric 
2792153Seric 
scy(yi)2802153Seric scy(yi)
2812153Seric {
2822153Seric 	return(2047 - (yi * 256));
2832153Seric }
2842153Seric 
2852153Seric 
clean_up(n)2862153Seric clean_up(n)
2872153Seric {
2882153Seric 	xfreeall();
2892153Seric }
2902153Seric 
2912153Seric 
escdodelt()2922153Seric escdodelt()	/* dummy for dodelt() */
2932153Seric {
2942153Seric }
295