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
main(argc,argv)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
prttree(file)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
addsucc(par,child,childbr)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
traverse(node)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
poscomp(p1,p2)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
dmptree()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
plot(rdp,n)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
pllabel(s,x,y)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
plline(x0,y0,x1,y1)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
putwd(w)264 putwd(w)
265 {
266 register char *p;
267
268 p = &w;
269 putchar(*p++);
270 putchar(*p);
271 }
272
273
scx(xi)274 scx(xi)
275 {
276 return(xi * 1024 - 2047);
277 }
278
279
scy(yi)280 scy(yi)
281 {
282 return(2047 - (yi * 256));
283 }
284
285
clean_up(n)286 clean_up(n)
287 {
288 xfreeall();
289 }
290
291
escdodelt()292 escdodelt() /* dummy for dodelt() */
293 {
294 }
295