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 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 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 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 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 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 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 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 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 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 264 putwd(w) 265 { 266 register char *p; 267 268 p = &w; 269 putchar(*p++); 270 putchar(*p); 271 } 272 273 274 scx(xi) 275 { 276 return(xi * 1024 - 2047); 277 } 278 279 280 scy(yi) 281 { 282 return(2047 - (yi * 256)); 283 } 284 285 286 clean_up(n) 287 { 288 xfreeall(); 289 } 290 291 292 escdodelt() /* dummy for dodelt() */ 293 { 294 } 295