1 #ifndef lint 2 static char sccsid[] = "@(#)format.c 4.5 04/24/88"; 3 #endif 4 /* 5 * 6 * UNIX debugger 7 * 8 */ 9 10 #include "defs.h" 11 12 MSG BADMOD; 13 MSG NOFORK; 14 MSG ADWRAP; 15 16 INT mkfault; 17 CHAR *lp; 18 L_INT maxoff; 19 ADDR sigint; 20 ADDR sigqit; 21 STRING errflg; 22 CHAR lastc,peekc; 23 L_INT dot; 24 INT dotinc; 25 L_INT expv; 26 L_INT var[]; 27 28 29 STRING fphack; 30 rdfp() 31 { 32 return(lastc= *fphack++); 33 } 34 35 scanform(icount,ifp,itype,ptype) 36 L_INT icount; 37 STRING ifp; 38 { 39 STRING fp; 40 CHAR modifier; 41 INT fcount, init=1; 42 L_INT savdot; 43 BOOL exact; 44 BOOL doit = 1; 45 46 WHILE icount 47 DO fp=ifp; 48 savdot=dot; init=0; 49 50 IF init==0 ANDF (exact=(findsym(dot,ptype)==0)) ANDF maxoff 51 THEN printf("\n%s:%16t",cursym->n_un.n_name); 52 FI 53 54 /*now loop over format*/ 55 WHILE *fp ANDF errflg==0 56 DO IF digit(modifier = *fp) 57 THEN fcount = 0; 58 WHILE digit(modifier = *fp++) 59 DO fcount *= 10; 60 fcount += modifier-'0'; 61 OD 62 fp--; 63 IF fcount==0 THEN fcount = 1; FI 64 ELSE fcount = 1; 65 FI 66 67 IF *fp==0 THEN break; FI 68 fp=exform(fcount,fp,itype,ptype); 69 OD 70 dotinc=dot-savdot; 71 dot=savdot; 72 73 IF errflg 74 THEN IF icount<0 75 THEN errflg=0; break; 76 ELSE error(errflg); 77 FI 78 FI 79 IF --icount 80 THEN dot=inkdot(dotinc); 81 FI 82 IF mkfault THEN error(0); FI 83 OD 84 } 85 86 STRING 87 exform(fcount,ifp,itype,ptype) 88 INT fcount; 89 STRING ifp; 90 { 91 /* execute single format item `fcount' times 92 * sets `dotinc' and moves `dot' 93 * returns address of next format item 94 */ 95 POS w; 96 L_INT savdot, wx; 97 STRING fp; 98 CHAR c, modifier, longpr; 99 L_REAL fw; 100 struct bad_programming { 101 L_INT sa; 102 INT sb,sc; 103 }; 104 105 WHILE fcount>0 106 DO fp = ifp; c = *fp; 107 longpr=(c>='A')&(c<='Z')|(c=='f')|(c=='4')|(c=='p'); 108 IF itype==NSP ORF *fp=='a' 109 THEN wx=dot; w=dot; 110 ELSE w=get(dot,itype); 111 IF longpr 112 THEN wx=itol(get(inkdot(2),itype),w); 113 ELSE wx=w; 114 FI 115 FI 116 IF c=='F' 117 /* 118 * This used to be the following, but real C compilers won't 119 * let you use a double as a struct! 120 * 121 * THEN fw.sb=get(inkdot(4),itype); 122 * fw.sc=get(inkdot(6),itype); 123 */ 124 THEN (*(struct bad_programming *)&fw).sb=get(inkdot(4),itype); 125 (*(struct bad_programming *)&fw).sc=get(inkdot(6),itype); 126 FI 127 IF errflg THEN return(fp); FI 128 IF mkfault THEN error(0); FI 129 var[0]=wx; 130 modifier = *fp++; 131 dotinc=(longpr?4:2);; 132 133 IF charpos()==0 ANDF modifier!='a' THEN printf("%16m"); FI 134 135 switch(modifier) { 136 137 case SP: case TB: 138 break; 139 140 case 't': case 'T': 141 printf("%T",fcount); return(fp); 142 143 case 'r': case 'R': 144 printf("%M",fcount); return(fp); 145 146 case 'a': 147 psymoff(dot,ptype,":%16t"); dotinc=0; break; 148 149 case 'p': 150 psymoff(var[0],ptype,"%16t"); break; 151 152 case 'u': 153 printf("%-8u",w); break; 154 155 case 'U': 156 printf("%-16U",wx); break; 157 158 case 'c': case 'C': 159 IF modifier=='C' 160 THEN printesc(w&LOBYTE); 161 ELSE printc(w&LOBYTE); 162 FI 163 dotinc=1; break; 164 165 case 'b': case 'B': 166 printf("%-8o", w&LOBYTE); dotinc=1; break; 167 168 case '1': 169 printf("%-8r", w&LOBYTE); dotinc=1; break; 170 171 case '2': 172 case 'w': 173 printf("%-8r", w); break; 174 175 case '4': 176 case 'W': 177 printf("%-16R", wx); break; 178 179 case 's': case 'S': 180 savdot=dot; dotinc=1; 181 WHILE (c=get(dot,itype)&LOBYTE) ANDF errflg==0 182 DO dot=inkdot(1); 183 IF modifier == 'S' 184 THEN printesc(c); 185 ELSE printc(c); 186 FI 187 endline(); 188 OD 189 dotinc=dot-savdot+1; dot=savdot; break; 190 191 case 'x': 192 printf("%-8x",w); break; 193 194 case 'X': 195 printf("%-16X", wx); break; 196 197 case 'Y': 198 printf("%-24Y", wx); break; 199 200 case 'q': 201 printf("%-8q", w); break; 202 203 case 'Q': 204 printf("%-16Q", wx); break; 205 206 case 'o': 207 printf("%-8o", w); break; 208 209 case 'O': 210 printf("%-16O", wx); break; 211 212 case 'i': 213 printins(0,itype,w); printc(EOR); break; 214 215 case 'd': 216 printf("%-8d", w); break; 217 218 case 'D': 219 printf("%-16D", wx); break; 220 221 case 'f': 222 fw = 0; 223 /* 224 * This used to be the following, but real compilers 225 * won't let you use a double as a struct! 226 * 227 * fw.sa = wx; 228 */ 229 (*(struct bad_programming *)&fw).sa = wx; 230 IF (wx & ~0xFFFF00FF) == 0x8000 231 THEN printf("(reserved oprnd)"); 232 ELSE printf("%-16.9f", fw); 233 FI 234 dotinc=4; break; 235 236 case 'F': 237 (*(struct bad_programming *)&fw).sa = wx; 238 IF (wx & ~0xFFFF00FF) == 0x8000 239 THEN printf("%-32s", "(reserved oprnd)"); 240 ELSE printf("%-32.18F", fw); 241 FI 242 dotinc=8; break; 243 244 case 'n': case 'N': 245 printc('\n'); dotinc=0; break; 246 247 case '"': 248 dotinc=0; 249 WHILE *fp != '"' ANDF *fp 250 DO printc(*fp++); OD 251 IF *fp THEN fp++; FI 252 break; 253 254 case '^': 255 dot=inkdot(-dotinc*fcount); return(fp); 256 257 case '+': 258 dot=inkdot(fcount); return(fp); 259 260 case '-': 261 dot=inkdot(-fcount); return(fp); 262 263 default: error(BADMOD); 264 } 265 IF itype!=NSP 266 THEN dot=inkdot(dotinc); 267 FI 268 fcount--; endline(); 269 OD 270 271 return(fp); 272 } 273 274 shell() 275 { 276 #ifndef EDDT 277 INT rc, status, unixpid; 278 STRING argp = lp; 279 STRING getenv(), shell = getenv("SHELL"); 280 #ifdef VFORK 281 char oldstlp; 282 #endif 283 284 if (shell == 0) 285 shell = "/bin/sh"; 286 WHILE lastc!=EOR DO rdc(); OD 287 #ifndef VFORK 288 IF (unixpid=fork())==0 289 #else 290 oldstlp = *lp; 291 IF (unixpid=vfork())==0 292 #endif 293 THEN signal(SIGINT,sigint); signal(SIGQUIT,sigqit); 294 *lp=0; execl(shell, "sh", "-c", argp, 0); 295 _exit(16); 296 #ifndef VFORK 297 ELIF unixpid == -1 298 #else 299 ELIF *lp = oldstlp, unixpid == -1 300 #endif 301 THEN error(NOFORK); 302 ELSE signal(SIGINT,1); 303 WHILE (rc = wait(&status)) != unixpid ANDF rc != -1 DONE 304 signal(SIGINT,sigint); 305 prints("!"); lp--; 306 FI 307 #endif 308 } 309 310 311 printesc(c) 312 { 313 c &= STRIP; 314 IF c==0177 THEN printf("^?"); 315 ELIF c<SP 316 THEN printf("^%c", c + '@'); 317 ELSE printc(c); 318 FI 319 } 320 321 L_INT inkdot(incr) 322 { 323 L_INT newdot; 324 325 newdot=dot+incr; 326 IF (dot NEQ newdot) >> 24 THEN error(ADWRAP); FI 327 return(newdot); 328 } 329 330 digit(c) 331 { 332 return c >= '0' && c <= '9'; 333 } 334