00001
00002
00003 # ifndef lint
00004 static char rcsid[] = "$Header: /opt/proj/minix/cvsroot/src/commands/yap/commands.c,v 1.1.1.1 2005/04/21 14:55:38 beng Exp $";
00005 # endif
00006
00007 # define _COMMANDS_
00008
00009 # include "in_all.h"
00010 # include "commands.h"
00011 # include "output.h"
00012 # include "process.h"
00013 # include "help.h"
00014 # include "term.h"
00015 # include "prompt.h"
00016 # include "getline.h"
00017 # include "getcomm.h"
00018 # include "pattern.h"
00019 # include "display.h"
00020 # include "options.h"
00021 # include "machine.h"
00022 # include "keys.h"
00023 # include "main.h"
00024 # include "assert.h"
00025 # if USG_OPEN
00026 # include <fcntl.h>
00027 # include <errno.h>
00028 extern int errno;
00029 # endif
00030 # if BSD4_2_OPEN
00031 # include <sys/file.h>
00032 # include <errno.h>
00033 extern int errno;
00034 # endif
00035 # if POSIX_OPEN
00036 # include <sys/types.h>
00037 # include <fcntl.h>
00038 # include <errno.h>
00039 # endif
00040
00041 char *strcpy(), *strcat();
00042
00043 static long lastcount;
00044 static int lastcomm;
00045
00046
00047 STATIC int
00048 do_nocomm(cnt) long cnt; {
00049 }
00050
00051
00052 int
00053 do_chkm(cnt) long cnt; {
00054 register struct keymap *p;
00055
00056 if (!(p = othermap)) {
00057 error("No other keymap");
00058 return;
00059 }
00060 othermap = currmap;
00061 currmap = p;
00062 }
00063
00064 static int searchdir;
00065
00066
00067
00068
00069
00070 STATIC VOID
00071 do_search(str,cnt,dir) char *str; long cnt; int dir; {
00072 register char *p;
00073 register long lineno;
00074
00075 if (str) {
00076
00077
00078
00079
00080 if ((p = readline(str)) == 0) {
00081
00082
00083
00084 return;
00085 }
00086 if ((p = re_comp(p))) {
00087
00088
00089
00090 error(p);
00091 return;
00092 }
00093 searchdir = dir;
00094 }
00095 if (dir < 0) lineno = scr_info.firstline;
00096 else lineno = scr_info.lastline;
00097 for (;;) {
00098 p = 0;
00099 if ((lineno += dir) > 0) p = getline(lineno, 0);
00100 if (interrupt) return;
00101 if (!p) {
00102 error("pattern not found");
00103 return;
00104 }
00105 if (re_exec(p) && --cnt <= 0) {
00106
00107
00108
00109
00110
00111
00112 (VOID) display(lineno,0,pagesize,0);
00113 (VOID) scrollb(2,0);
00114 redraw(0);
00115 return;
00116 }
00117 }
00118
00119 }
00120
00121 STATIC int
00122 do_fsearch(cnt) long cnt; {
00123
00124 do_search("/", cnt, 1);
00125 }
00126
00127 STATIC int
00128 do_bsearch(cnt) long cnt; {
00129
00130 do_search("?", cnt, -1);
00131 }
00132
00133
00134
00135
00136
00137 STATIC int
00138 n_or_rn_search(cnt,dir) long cnt; int dir; {
00139 register char *p;
00140
00141 if (dir == 1) {
00142 p = "/\r";
00143 }
00144 else if (dir == -1) {
00145 p = "?\r";
00146 }
00147 else {
00148 error("No previous pattern");
00149 return;
00150 }
00151 if (!stupid) clrbline();
00152 putline(p);
00153 flush();
00154 do_search((char *) 0, cnt, dir);
00155 }
00156
00157 STATIC int
00158 do_nsearch(cnt) long cnt; {
00159
00160 n_or_rn_search(cnt,searchdir);
00161 }
00162
00163 STATIC int
00164 do_rnsearch(cnt) long cnt; {
00165
00166 n_or_rn_search(cnt, -searchdir);
00167 }
00168
00169 STATIC int shell(esc_ch, cnt) long cnt;
00170 {
00171 register char *p;
00172 static char buf[2];
00173
00174 buf[0] = esc_ch;
00175 if (p = readline(buf)) {
00176 shellescape(p, esc_ch);
00177 if (cnt >= 0 && !hardcopy) {
00178 p = startcomm;
00179 startcomm = 0;
00180 ret_to_continue();
00181 putline(TI);
00182 if (!p) {
00183
00184
00185
00186
00187
00188 redraw(1);
00189 }
00190 }
00191 }
00192 }
00193
00194 STATIC int
00195 do_shell(cnt) long cnt; {
00196 shell('!', cnt);
00197 }
00198
00199 STATIC int
00200 do_pipe(cnt) long cnt; {
00201 shell('|', cnt);
00202 }
00203
00204
00205 STATIC int
00206 do_writefile(cnt) long cnt; {
00207 register char *p;
00208 int fd;
00209
00210 if ((p = readline("Filename: ")) == 0 || !*p) {
00211
00212
00213
00214 return;
00215 }
00216 # if USG_OPEN || BSD4_2_OPEN || POSIX_OPEN
00217 if ((fd = open(p,O_CREAT|O_EXCL|O_WRONLY,0644)) < 0) {
00218 if (errno == EEXIST) {
00219 error("File exists");
00220 return;
00221 }
00222 error("Could not open file");
00223 return;
00224 }
00225 # else
00226 if (!access(p,0)) {
00227 error("File exists");
00228 return;
00229 }
00230 if ((fd = creat(p,0644)) < 0) {
00231 error("Could not open file");
00232 return;
00233 }
00234 # endif
00235 wrt_fd(fd);
00236 (VOID) close(fd);
00237 }
00238
00239 VOID
00240 wrt_fd(fd)
00241 {
00242 register long l = 1;
00243 register char *p = getline(l,0), *pbuf;
00244 char buf[1024];
00245
00246 while (p) {
00247 pbuf = buf;
00248 while (p && pbuf < &buf[1024]) {
00249 if (!*p) {
00250 *pbuf++ = '\n';
00251 p = getline(++l,0);
00252 }
00253 else *pbuf++ = *p++ & 0177;
00254 }
00255 if (write(fd, buf, pbuf - buf) < 0) {
00256 error("Write failed");
00257 break;
00258 }
00259 }
00260 }
00261
00262 STATIC int
00263 do_absolute(cnt) long cnt; {
00264
00265 if (!getline(cnt,0)) {
00266 if (!interrupt) {
00267
00268
00269
00270
00271 do_lline(cnt);
00272 }
00273 return;
00274 }
00275 (VOID) display(cnt,0,pagesize,1);
00276 }
00277
00278
00279 STATIC int
00280 do_visit(cnt) long cnt; {
00281 register char *p;
00282 static char fn[128];
00283
00284 if ((p = readline("Filename: ")) == 0) {
00285 return;
00286 }
00287 if (*p) {
00288 (VOID) strcpy(fn,p);
00289 visitfile(fn);
00290 }
00291 else {
00292
00293
00294
00295 if (!(p = filenames[filecount])) {
00296 error("No current file");
00297 return;
00298 }
00299 visitfile(p);
00300 }
00301 (VOID) display(1L, 0, pagesize, 1);
00302 }
00303
00304
00305 STATIC int
00306 do_error(cnt) long cnt; {
00307
00308 error(currmap->k_help);
00309 }
00310
00311
00312
00313
00314
00315
00316 STATIC int
00317 prev_screen(sz,really) int sz, really; {
00318 register int retval;
00319
00320 retval = scrollb(sz - 1, really && cflag);
00321 if (really && !cflag) {
00322
00323
00324
00325
00326 return display(scr_info.firstline, scr_info.nf, sz, 1);
00327 }
00328 return retval;
00329 }
00330
00331
00332
00333
00334
00335
00336 STATIC int
00337 next_screen(sz,really) int sz, really; {
00338
00339 register int t;
00340 register struct scr_info *p = &scr_info;
00341
00342 if (cflag) {
00343 return scrollf(sz-1,really);
00344 }
00345 t = p->tail->cnt - 1;
00346 if (p->lastline == p->firstline) {
00347 t += p->nf;
00348 }
00349 return display(p->lastline, t, sz, really);
00350 }
00351
00352
00353 STATIC int
00354 do_redraw(cnt) long cnt; {
00355
00356 redraw(1);
00357 }
00358
00359 STATIC int
00360 page_size(cnt) unsigned cnt; {
00361
00362 if (cnt) {
00363 if (cnt > maxpagesize) return maxpagesize;
00364 if (cnt < MINPAGESIZE) return MINPAGESIZE;
00365 return (int) cnt;
00366 }
00367 return pagesize;
00368 }
00369
00370 STATIC int
00371 do_forward(cnt) long cnt; {
00372 register int i;
00373
00374 i = page_size((unsigned) cnt);
00375 if (status & EOFILE) {
00376
00377
00378
00379
00380 (VOID) display(1L,0,i,1);
00381 return;
00382 }
00383 (VOID) next_screen(i,1);
00384 }
00385
00386 STATIC int
00387 do_backward(cnt) long cnt; {
00388 register int i, temp;
00389
00390 i = page_size((unsigned) cnt);
00391 if (!(status & START)) {
00392 (VOID) prev_screen(i,1);
00393 return;
00394 }
00395 if (stdf < 0) {
00396 (VOID) display(1L,0,i,1);
00397 return;
00398 }
00399
00400
00401
00402
00403
00404
00405 temp = pagesize;
00406 pagesize = i;
00407 do_lline(cnt);
00408 pagesize = temp;
00409 }
00410
00411
00412 STATIC int
00413 do_firstline(cnt) long cnt; {
00414
00415 do_absolute(1L);
00416 }
00417
00418 STATIC int
00419 do_lline(cnt) long cnt; {
00420 register int i = 0;
00421 register int j = pagesize - 1;
00422
00423 if ((cnt = to_lastline()) < 0) {
00424
00425
00426
00427 return;
00428 }
00429
00430
00431
00432
00433 while (!(display(cnt,i,j,0) & EOFILE)) {
00434
00435
00436
00437 i+= j;
00438 }
00439 (VOID) scrollb(j - scr_info.tail->cnt, 0);
00440 redraw(0);
00441 }
00442
00443 STATIC int
00444 do_lf(cnt) long cnt; {
00445
00446 if (cnt) {
00447 do_absolute(cnt);
00448 return;
00449 }
00450 (VOID) scrollf(1,1);
00451 }
00452
00453 STATIC int
00454 do_upline(cnt) long cnt; {
00455
00456 if (cnt) {
00457 do_absolute(cnt);
00458 return;
00459 }
00460 (VOID) scrollb(1,1);
00461 }
00462
00463 STATIC int
00464 do_skiplines(cnt) long cnt; {
00465
00466
00467 (VOID) scrollf((int) (cnt + maxpagesize - 1), 0);
00468 redraw(0);
00469 }
00470
00471 STATIC int
00472 do_bskiplines(cnt) long cnt; {
00473
00474
00475 (VOID) scrollb((int) (cnt + pagesize - 1), 0);
00476 redraw(0);
00477 }
00478
00479 STATIC int
00480 do_fscreens(cnt) long cnt; {
00481
00482 do {
00483 if ((next_screen(pagesize,0) & EOFILE) || interrupt) break;
00484 } while (--cnt >= 0);
00485 redraw(0);
00486 }
00487
00488 STATIC int
00489 do_bscreens(cnt) long cnt; {
00490
00491 do {
00492 if ((prev_screen(pagesize,0) & START) || interrupt) break;
00493 } while (--cnt >= 0);
00494 redraw(0);
00495 }
00496
00497 STATIC int
00498 scro_size(cnt) unsigned cnt; {
00499
00500 if (cnt >= maxpagesize) return maxpagesize;
00501 if (cnt) return (int) cnt;
00502 return scrollsize;
00503 }
00504
00505 STATIC int
00506 do_f_scroll(cnt) long cnt; {
00507
00508 (VOID) scrollf(scro_size((unsigned) cnt),1);
00509 }
00510
00511 STATIC int
00512 do_b_scroll(cnt) long cnt; {
00513
00514 (VOID) scrollb(scro_size((unsigned) cnt),1);
00515 }
00516
00517 STATIC int
00518 do_previousfile(cnt) long cnt; {
00519
00520 if (nextfile(- (int) cnt)) {
00521 error("No (Nth) previous file");
00522 return;
00523 }
00524 redraw(0);
00525 }
00526
00527 STATIC int
00528 do_nextfile(cnt) long cnt; {
00529
00530 if (nextfile((int) cnt)) {
00531 error("No (Nth) next file");
00532 return;
00533 }
00534 redraw(0);
00535 }
00536
00537 STATIC int do_lcomm();
00538
00539
00540
00541
00542
00543 struct commands commands[] = {
00544 {"", 0, do_error, ""},
00545 {"", 0, do_nocomm, ""},
00546 {"bf", STICKY|NEEDS_COUNT,
00547 do_previousfile,"Visit previous file"},
00548 {"bl", NEEDS_SCREEN|STICKY,
00549 do_upline, "Scroll one line up, or go to line"},
00550 {"bot", STICKY,
00551 do_lline, "Go to last line of the input"},
00552 {"bp", BACK|NEEDS_SCREEN|TOPREVFILE|STICKY,
00553 do_backward, "display previous page"},
00554 {"bps", SCREENSIZE_ADAPT|BACK|NEEDS_SCREEN|TOPREVFILE|STICKY,
00555 do_backward, "Display previous page, set pagesize"},
00556 {"bs", BACK|NEEDS_SCREEN|STICKY,
00557 do_b_scroll, "Scroll backwards"},
00558 {"bse", 0, do_bsearch, "Search backwards for pattern"},
00559 {"bsl", BACK|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
00560 do_bskiplines, "Skip lines backwards"},
00561 {"bsp", BACK|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
00562 do_bscreens, "Skip screens backwards"},
00563 {"bss", SCROLLSIZE_ADAPT|BACK|NEEDS_SCREEN|STICKY,
00564 do_b_scroll, "Scroll backwards, set scrollsize"},
00565 {"chm", 0, do_chkm, "Switch to other keymap"},
00566 {"exg", STICKY, exgmark, "Exchange current page with mark"},
00567 {"ff", STICKY|NEEDS_COUNT,
00568 do_nextfile, "Visit next file"},
00569 {"fl", NEEDS_SCREEN|STICKY,
00570 do_lf, "Scroll one line down, or go to line"},
00571 {"fp", TONEXTFILE|AHEAD|STICKY,
00572 do_forward, "Display next page"},
00573 {"fps", SCREENSIZE_ADAPT|TONEXTFILE|AHEAD|STICKY,
00574 do_forward, "Display next page, set pagesize"},
00575 {"fs", AHEAD|NEEDS_SCREEN|STICKY,
00576 do_f_scroll, "Scroll forwards"},
00577 {"fse", 0, do_fsearch, "Search forwards for pattern"},
00578 {"fsl", AHEAD|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
00579 do_skiplines, "Skip lines forwards"},
00580 {"fsp", AHEAD|NEEDS_SCREEN|STICKY|NEEDS_COUNT,
00581 do_fscreens, "Skip screens forwards"},
00582 {"fss", SCROLLSIZE_ADAPT|AHEAD|NEEDS_SCREEN|STICKY,
00583 do_f_scroll, "Scroll forwards, set scrollsize"},
00584 {"hlp", 0, do_help, "Give description of all commands"},
00585 {"mar", 0, setmark, "Set a mark on the current page"},
00586 {"nse", STICKY, do_nsearch, "Repeat the last search"},
00587 {"nsr", STICKY, do_rnsearch, "Repeat last search in other direction"},
00588 {"pip", ESC, do_pipe, "pipe input into shell command"},
00589 {"qui", 0, quit, "Exit from yap"},
00590 {"red", 0, do_redraw, "Redraw screen"},
00591 {"rep", 0, do_lcomm, "Repeat last command"},
00592 {"shl", ESC, do_shell, "Execute a shell escape"},
00593 {"tom", 0, tomark, "Go to mark"},
00594 {"top", STICKY, do_firstline, "Go to the first line of the input"},
00595 {"vis", 0, do_visit, "Visit a file"},
00596 {"wrf", 0, do_writefile, "Write input to a file"},
00597 };
00598
00599
00600
00601
00602
00603
00604 int
00605 lookup(s) char *s; {
00606 register struct commands *l, *u, *m;
00607
00608 l = &commands[2];
00609 u = &commands[sizeof(commands) / sizeof(*u) - 1];
00610 do {
00611
00612
00613
00614 m = l + (u - l) / 2;
00615 if (strcmp(s, m->c_cmd) > 0) l = m + 1;
00616 else u = m;
00617 } while (l < u);
00618 if (!strcmp(s, u->c_cmd)) return u - commands;
00619 return 0;
00620 }
00621
00622
00623 STATIC int
00624 do_lcomm(cnt) long cnt; {
00625
00626 if (!lastcomm) {
00627 error("No previous command");
00628 return;
00629 }
00630 do_comm(lastcomm, lastcount);
00631 }
00632
00633
00634
00635
00636
00637 VOID
00638 do_comm(comm, count) register int comm; register long count; {
00639
00640 register struct commands *pcomm;
00641 register int temp;
00642 register int flags;
00643
00644 pcomm = &commands[comm];
00645 flags = pcomm->c_flags;
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 if ((status & EOFILE) && (flags & AHEAD)) {
00658 if (qflag || !(flags & TONEXTFILE)) return;
00659 if (nextfile(1)) quit();
00660 }
00661 if ((status & START) && (flags & BACK)) {
00662 if (qflag || !(flags & TOPREVFILE)) return;
00663 if (nextfile(-1)) quit();
00664 }
00665
00666
00667
00668 if (flags & STICKY) {
00669 lastcomm = comm;
00670 lastcount = count;
00671 }
00672 if (!count) {
00673 if (flags & NEEDS_COUNT) count = 1;
00674 }
00675 else {
00676
00677
00678
00679 if (flags & SCREENSIZE_ADAPT) {
00680 temp = maxpagesize;
00681 if ((unsigned) count < temp) {
00682 temp = count;
00683 }
00684 if (temp < MINPAGESIZE) {
00685 temp = MINPAGESIZE;
00686 }
00687 count = 0;
00688 pagesize = temp;
00689 }
00690
00691
00692
00693 if (flags & SCROLLSIZE_ADAPT) {
00694 temp = maxpagesize - 1;
00695 if ((unsigned) count < temp) {
00696 temp = (int) count;
00697 }
00698 scrollsize = temp;
00699 count = 0;
00700 }
00701 }
00702
00703
00704
00705 (*(pcomm->c_func))(count);
00706 }