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