Commit | Line | Data |
---|---|---|
49298f2e EA |
1 | # include "../hdr/defines.h" |
2 | # include "../hdr/had.h" | |
3 | ||
5409addc | 4 | SCCSID(@(#)stree.c 4.2); |
49298f2e EA |
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))); | |
5409addc | 107 | bzero(tree, n); |
49298f2e | 108 | pos = alloc(n = ((maxser(&gpkt) + 1) * sizeof(struct position))); |
5409addc | 109 | bzero(pos, n); |
49298f2e EA |
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 | } |