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