[9] | 1 | /* ELLE - Copyright 1982, 1985, 1987 by Ken Harrenstien, SRI International
|
---|
| 2 | * This software is quasi-public; it may be used freely with
|
---|
| 3 | * like software, but may NOT be sold or made part of licensed
|
---|
| 4 | * products without permission of the author.
|
---|
| 5 | */
|
---|
| 6 | /* EEDIAG - Error diagnostics and testing routines
|
---|
| 7 | */
|
---|
| 8 |
|
---|
| 9 | #include "elle.h"
|
---|
| 10 |
|
---|
| 11 | #if FX_DEBUG
|
---|
| 12 |
|
---|
| 13 | /* EFUN: "Debug Mode" */
|
---|
| 14 | /* With no arg, toggles self-checking on and off.
|
---|
| 15 | * With arg of 4 (^U), enters special debug/diagnostics mode.
|
---|
| 16 | */
|
---|
| 17 |
|
---|
| 18 | f_debug(ch)
|
---|
| 19 | int ch;
|
---|
| 20 | { extern int (*vfy_vec)(); /* In E_MAIN.C */
|
---|
| 21 | char *vfy_data();
|
---|
| 22 |
|
---|
| 23 | if(ch < 0) /* Internal call? */
|
---|
| 24 | { dbg_diag();
|
---|
| 25 | return;
|
---|
| 26 | }
|
---|
| 27 | if(exp == 4)
|
---|
| 28 | { askerr();
|
---|
| 29 | return;
|
---|
| 30 | }
|
---|
| 31 | if(vfy_vec) vfy_vec = 0; /* Toggle current value */
|
---|
| 32 | else vfy_vec = (int (*)())vfy_data;
|
---|
| 33 | say(vfy_vec ? "Self-checking on" : "Self-checking off");
|
---|
| 34 | }
|
---|
| 35 | |
---|
| 36 |
|
---|
| 37 | char *
|
---|
| 38 | vfy_data(flag) /* Flag = 0 for quiet check */
|
---|
| 39 | int flag;
|
---|
| 40 | {
|
---|
| 41 | register char *res, *mess;
|
---|
| 42 | char *sbe_mvfy(), *sbe_sbvfy(), *sbe_svfy();
|
---|
| 43 |
|
---|
| 44 | if(res = sbe_mvfy(0)) mess = "Mem mgt";
|
---|
| 45 | else if(res = sbe_sbvfy(cur_buf,0)) mess = "SBBUF";
|
---|
| 46 | else if(res = sbe_svfy(0)) mess = "SD list";
|
---|
| 47 | else return(0); /* Success */
|
---|
| 48 |
|
---|
| 49 | if(flag)
|
---|
| 50 | { int ostate = clean_exit();
|
---|
| 51 | printf("\n%s error: %s !!!\n",mess,res);
|
---|
| 52 | askerr();
|
---|
| 53 | if(ostate > 0) set_tty();
|
---|
| 54 | }
|
---|
| 55 | return(res); /* Error seen */
|
---|
| 56 | }
|
---|
| 57 | |
---|
| 58 |
|
---|
| 59 | extern char *asklin();
|
---|
| 60 | extern int sbx_nfl,sbm_nfl;
|
---|
| 61 |
|
---|
| 62 | char diaghelp[] = "\
|
---|
| 63 | Q - Quit diag mode\n\
|
---|
| 64 | ! - Goto subshell\n\
|
---|
| 65 | V - Verify Mem & SD lists\n\
|
---|
| 66 | MF - Mem Freelist\n\
|
---|
| 67 | M - Mem list\n\
|
---|
| 68 | B - Current buffer SB\n\
|
---|
| 69 | DF - SD Freelist\n\
|
---|
| 70 | D - SDs in use\n\
|
---|
| 71 | DL - SD Logical lists\n\
|
---|
| 72 | DP - SD Physical lists\n\
|
---|
| 73 | C n - Compact; 0-7=sbx_comp(n), 8=SM freelist, 9=SD freelist.\n\
|
---|
| 74 | W - Window printout\n\
|
---|
| 75 | X n - Xercise randomly (GC every n)\n\
|
---|
| 76 | Z n - like X but with notes\n";
|
---|
| 77 |
|
---|
| 78 | dbg_diag()
|
---|
| 79 | { register char *cp;
|
---|
| 80 | register int c;
|
---|
| 81 | char linbuf[100];
|
---|
| 82 | char *sbe_mfl();
|
---|
| 83 | char *sbe_sfl();
|
---|
| 84 | char *sbe_sbs();
|
---|
| 85 | char *sbe_sdlist();
|
---|
| 86 |
|
---|
| 87 | for(;;)
|
---|
| 88 | { printf("D>");
|
---|
| 89 | asklin(cp = linbuf); /* Read a line of input */
|
---|
| 90 | switch(upcase(*cp++))
|
---|
| 91 | {
|
---|
| 92 | case '?':
|
---|
| 93 | writez(1,diaghelp); /* Too long for printf */
|
---|
| 94 | continue;
|
---|
| 95 | case '!':
|
---|
| 96 | f_pshinf(); /* Invoke inferior subshell */
|
---|
| 97 | clean_exit(); /* Restore normal modes */
|
---|
| 98 | continue;
|
---|
| 99 | case 'Q': /* Quit */
|
---|
| 100 | return;
|
---|
| 101 |
|
---|
| 102 | case 'B': /* Print current SBBUF */
|
---|
| 103 | sbe_sbs(cur_buf,1);
|
---|
| 104 | continue;
|
---|
| 105 |
|
---|
| 106 | case 'C': /* C n - Compact */
|
---|
| 107 | c = atoi(&linbuf[1]);
|
---|
| 108 | if(c == 8)
|
---|
| 109 | sbm_ngc(); /* GC the SM nodes */
|
---|
| 110 | #if 0 /* This doesn't work, dangerous to invoke. */
|
---|
| 111 | else if(c == 9)
|
---|
| 112 | sbm_xngc(&sbx_nfl,sizeof(struct sdblk),
|
---|
| 113 | SM_DNODS);
|
---|
| 114 | #endif
|
---|
| 115 | else
|
---|
| 116 | sbx_comp(512,c);
|
---|
| 117 | continue;
|
---|
| 118 |
|
---|
| 119 | case 'D': /* Print all SD blocks in mem order */
|
---|
| 120 | switch(upcase(*cp))
|
---|
| 121 | {
|
---|
| 122 | case 0: /* D - all SDs in mem order */
|
---|
| 123 | sbe_sds();
|
---|
| 124 | continue;
|
---|
| 125 | case 'F': /* DF - SD freelist */
|
---|
| 126 | sbe_sfl(1);
|
---|
| 127 | continue;
|
---|
| 128 | case 'L': /* DL - SD logical list */
|
---|
| 129 | sbe_sdlist(1,0);
|
---|
| 130 | continue;
|
---|
| 131 | case 'P': /* DP - SD physical list */
|
---|
| 132 | sbe_sdlist(1,1);
|
---|
| 133 | continue;
|
---|
| 134 | }
|
---|
| 135 | break; /* failure */
|
---|
| 136 |
|
---|
| 137 | case 'M':
|
---|
| 138 | switch(upcase(*cp))
|
---|
| 139 | {
|
---|
| 140 | case 0: /* M - all mem alloc info */
|
---|
| 141 | sbe_mem();
|
---|
| 142 | continue;
|
---|
| 143 | case 'F': /* MF - mem freelist */
|
---|
| 144 | sbe_mfl(1);
|
---|
| 145 | continue;
|
---|
| 146 | }
|
---|
| 147 | break; /* failure */
|
---|
| 148 |
|
---|
| 149 | case 'V': /* Verify */
|
---|
| 150 | if(cp = vfy_data(0))
|
---|
| 151 | printf(" Failed: %s\n",cp);
|
---|
| 152 | else printf(" OK\n");
|
---|
| 153 | continue;
|
---|
| 154 | case 'W': /* Print out current window */
|
---|
| 155 | db_prwind(cur_win);
|
---|
| 156 | continue;
|
---|
| 157 | case 'X': /* Xercise */
|
---|
| 158 | c = atoi(&linbuf[1]);
|
---|
| 159 | vfy_exer(0, c ? c : 100);
|
---|
| 160 | continue;
|
---|
| 161 | case 'Z': /* Zercise */
|
---|
| 162 | c = atoi(&linbuf[1]);
|
---|
| 163 | vfy_exer(1, c ? c : 100);
|
---|
| 164 | continue;
|
---|
| 165 |
|
---|
| 166 | } /* End of switch */
|
---|
| 167 |
|
---|
| 168 | printf("?? Type ? for help\n");
|
---|
| 169 | } /* Loop forever */
|
---|
| 170 | }
|
---|
| 171 | |
---|
| 172 |
|
---|
| 173 |
|
---|
| 174 | /* VFY_EXER - a "random" editor exerciser. It creates a buffer,
|
---|
| 175 | * fills it with some patterned stuff, and then edits it
|
---|
| 176 | * pseudo-randomly in ways which retain the basic pattern.
|
---|
| 177 | * Frequent GC's and self-checks are done, and execution
|
---|
| 178 | * halted either when an error is seen or when typein is detected.
|
---|
| 179 | */
|
---|
| 180 | char *xer_strs [] = {
|
---|
| 181 | "throne", "too", "sky", "fore", "fingers", "sex", "stone",
|
---|
| 182 | "010", "nazgul", "base"
|
---|
| 183 | };
|
---|
| 184 |
|
---|
| 185 |
|
---|
| 186 | vfy_exer(pf, gcfrq)
|
---|
| 187 | int pf; /* Nonzero to print notes as we go */
|
---|
| 188 | int gcfrq; /* Frequency of GC invocation (# passes per GC) */
|
---|
| 189 | { register int i, k, c;
|
---|
| 190 | long npass;
|
---|
| 191 | char *res, linbuf[100];
|
---|
| 192 | chroff lbeg, lend;
|
---|
| 193 | struct buffer *bfp, *make_buf();
|
---|
| 194 |
|
---|
| 195 | /* Clean out kill buffer first */
|
---|
| 196 | for(i = 0; i < KILL_LEN; ++i)
|
---|
| 197 | kill_push((SBSTR *)0);
|
---|
| 198 |
|
---|
| 199 | bfp = make_buf("**EXORCISE**");
|
---|
| 200 | chg_buf(bfp);
|
---|
| 201 | i = 2000;
|
---|
| 202 | e_gobol();
|
---|
| 203 | do {
|
---|
| 204 | ed_sins("Line ");
|
---|
| 205 | ed_sins(xer_strs[i%10]);
|
---|
| 206 | e_putc(LF);
|
---|
| 207 | } while(--i);
|
---|
| 208 | if(pf) printf("Bufflen: %ld\n", e_blen());
|
---|
| 209 |
|
---|
| 210 | /* Buffer now has stuff in it, start hacking. */
|
---|
| 211 | npass = 0;
|
---|
| 212 | srand(1); /* Start random seed */
|
---|
| 213 | for(;;)
|
---|
| 214 | { if(tinwait() && (*asklin(linbuf)))
|
---|
| 215 | { printf("Typein stop.\n");
|
---|
| 216 | break;
|
---|
| 217 | }
|
---|
| 218 | ++npass;
|
---|
| 219 | printf(" Pass %ld",npass);
|
---|
| 220 | if(npass%gcfrq == 0) /* Time to do a GC? */
|
---|
| 221 | {
|
---|
| 222 | i = rand(); /* Level between 0-4 */
|
---|
| 223 | i = (i < 0 ? -i : i) % 5;
|
---|
| 224 | printf(" - GC lev %d\n", i);
|
---|
| 225 | sbx_comp(512,i);
|
---|
| 226 | goto xerchk;
|
---|
| 227 | }
|
---|
| 228 |
|
---|
| 229 | k = (i = rand())%1024;
|
---|
| 230 | if (i&020000) k = -k;
|
---|
| 231 | e_igoff(k); /* Move randomly */
|
---|
| 232 | e_gobol(); /* Get stuff to flush */
|
---|
| 233 | lbeg = e_dot();
|
---|
| 234 | k = (i = rand())%64;
|
---|
| 235 | if(i&010000) k = -k;
|
---|
| 236 | e_igoff(k);
|
---|
| 237 | lend = e_nldot();
|
---|
| 238 | if(pf) printf(" Kill %ld/ %d;", lbeg, k);
|
---|
| 239 | ed_kill(lbeg, lend);
|
---|
| 240 | if(res = vfy_data(0))
|
---|
| 241 | { printf("XERR after kill: %s\n",res);
|
---|
| 242 | break;
|
---|
| 243 | }
|
---|
| 244 | k = (i = rand())%2048;
|
---|
| 245 | if(i&04000) k = -k;
|
---|
| 246 | e_igoff(k);
|
---|
| 247 | e_gobol();
|
---|
| 248 | e_setcur();
|
---|
| 249 | if(pf) printf(" Yank %ld;", e_dot());
|
---|
| 250 | f_unkill(); /* Yank back */
|
---|
| 251 | if(res = vfy_data(0))
|
---|
| 252 | { printf("XERR after yank: %s\n",res);
|
---|
| 253 | break;
|
---|
| 254 | }
|
---|
| 255 | last_cmd = YANKCMD;
|
---|
| 256 | for(i = rand()%4; i >= 0; --i)
|
---|
| 257 | { if(pf) printf(" Pop;");
|
---|
| 258 | f_unkpop(); /* Do meta-Y */
|
---|
| 259 | if(res = vfy_data(0))
|
---|
| 260 | { printf("XERR after pop: %s\n",res);
|
---|
| 261 | goto out;
|
---|
| 262 | }
|
---|
| 263 | }
|
---|
| 264 | if(rand()&07) /* Slowly add stuff */
|
---|
| 265 | { if(pf) printf(" Add");
|
---|
| 266 | ed_sins("Line ");
|
---|
| 267 | ed_sins(xer_strs[rand()%10]);
|
---|
| 268 | e_putc(LF);
|
---|
| 269 | if(res = vfy_data(0))
|
---|
| 270 | { printf("XERR after ins: %s\n",res);
|
---|
| 271 | break;
|
---|
| 272 | }
|
---|
| 273 | }
|
---|
| 274 | printf("\n");
|
---|
| 275 |
|
---|
| 276 | /* Okay, done with this pass edits, run through the
|
---|
| 277 | * file to ensure pattern is still there
|
---|
| 278 | */
|
---|
| 279 | xerchk: e_gobob();
|
---|
| 280 | while((c = e_getc()) != EOF)
|
---|
| 281 | if(c == LF && (c = e_getc()) != EOF)
|
---|
| 282 | { if( c != 'L'
|
---|
| 283 | || e_getc() != 'i'
|
---|
| 284 | || e_getc() != 'n'
|
---|
| 285 | || e_getc() != 'e'
|
---|
| 286 | || e_getc() != ' ')
|
---|
| 287 | { printf("XERR in pattern!\n");
|
---|
| 288 | goto out;
|
---|
| 289 | }
|
---|
| 290 | }
|
---|
| 291 | }
|
---|
| 292 | /* User typein or error, stop. */
|
---|
| 293 | out: e_setcur();
|
---|
| 294 | redp(RD_SCREEN);
|
---|
| 295 | printf("Loop count = %ld\n",npass);
|
---|
| 296 | }
|
---|
| 297 | |
---|
| 298 |
|
---|
| 299 | /* DB_PRWIND(win) - Print out stuff about given window
|
---|
| 300 | */
|
---|
| 301 | db_prwind(w)
|
---|
| 302 | register struct window *w;
|
---|
| 303 | { register struct scr_line *s;
|
---|
| 304 | register int i;
|
---|
| 305 | char tstr[MAXLINE+MAXCHAR];
|
---|
| 306 | char *db_scflgs();
|
---|
| 307 |
|
---|
| 308 | printf("cur_dot/ %ld cur_buf/ %o cur_win/ %o\n",
|
---|
| 309 | cur_dot, cur_buf, cur_win);
|
---|
| 310 |
|
---|
| 311 | printf("Window %o:\n", w);
|
---|
| 312 | printf(" next/ %o\n", w->w_next);
|
---|
| 313 | printf(" buf / %o\n", w->w_buf);
|
---|
| 314 | printf(" redp/ %o\n", w->w_redp);
|
---|
| 315 |
|
---|
| 316 | printf(" topldot/ %ld\n", w->w_topldot);
|
---|
| 317 | printf(" dot / %ld\n", w->w_dot);
|
---|
| 318 | printf(" bmod/ %ld\n", w->w_bmod);
|
---|
| 319 | printf(" emod/ %ld\n", w->w_emod);
|
---|
| 320 | printf(" oldz/ %ld\n", w->w_oldz);
|
---|
| 321 |
|
---|
| 322 | printf(" pos / %d\n", w->w_pos);
|
---|
| 323 | printf(" ht / %d\n", w->w_ht);
|
---|
| 324 | printf("\
|
---|
| 325 | # Flags Boff Len ! Cols Line\n");
|
---|
| 326 | for(i = w->w_pos; i < w->w_pos + w->w_ht; ++i)
|
---|
| 327 | { s = scr[i];
|
---|
| 328 | printf("%2d %-5.5s %6ld %3d %1d %4d ",
|
---|
| 329 | i, db_scflgs(s->sl_flg), s->sl_boff, s->sl_len,
|
---|
| 330 | s->sl_cont, s->sl_col);
|
---|
| 331 | strncpy(tstr, s->sl_line, MAXLINE);
|
---|
| 332 | tstr[s->sl_col] = 0;
|
---|
| 333 | printf("%-40.40s\n", tstr);
|
---|
| 334 | if(s->sl_flg&SL_MOD)
|
---|
| 335 | { printf("%26d ", s->sl_ncol);
|
---|
| 336 | strncpy(tstr, s->sl_nlin, MAXLINE);
|
---|
| 337 | tstr[s->sl_ncol] = 0;
|
---|
| 338 | printf("%-40.40s\n", tstr);
|
---|
| 339 | }
|
---|
| 340 | }
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | char *
|
---|
| 344 | db_scflgs(flags)
|
---|
| 345 | int flags;
|
---|
| 346 | { static char retstr[10];
|
---|
| 347 | register char *cp;
|
---|
| 348 |
|
---|
| 349 | cp = retstr;
|
---|
| 350 | if(flags&SL_MOD) *cp++ = 'M';
|
---|
| 351 | if(flags&SL_EOL) *cp++ = 'E';
|
---|
| 352 | *cp = 0;
|
---|
| 353 | return(retstr);
|
---|
| 354 | }
|
---|
| 355 |
|
---|
| 356 | #endif /*FX_DEBUG*/
|
---|