/************************************************************* * File: mon/more.c * Purpose: Part of core Monitor. This module implements the 'more' * function used by many of the commands. * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history * 970822 Permit ESC to be used to exit more * 980331 changed getchar to GETCHAR for imon95 * 980405 Allow \r in place of \n */ #include #include #include #ifdef PMCC #define GETCHAR getchar #endif #define BEL 007 #define TIKRATE 20000 char more_pat[LINESZ]; int tik_cnt; char more_tiks[] = "|/-\\"; char *more_tik; char *more_msg = "more... "; Optdesc more_opts[] = { {"","paginator"}, {"/str","search for str"}, {"n","repeat last search"}, {"SPACE","next page"}, {"CR","next line"}, {"q|ESC","quit"}, {0}}; /************************************************************* * test more function * compile as: pmcc -DTEST more.c */ #ifdef TEST main(argc,argv) int argc; char *argv[]; { int i,cnt,siz; char tmp[100]; siz = 8; cnt = siz; if (argc == 1) { printf("usage: more [cnt] [siz]\n"); exit(1); } if (argc > 2) sscanf(argv[2],"%d",&siz); if (argc > 1) sscanf(argv[1],"%d",&cnt); ioctl_cbreak(0L); for (i=0;i<60;i++) { mkln(tmp); if (more(tmp,&cnt,siz)) break; } } mkln(p) char *p; { int i; for (i='a';i<='z';i++) *p++ = i; *p = 0; } #endif /************************************************************* * more(p,cnt,size) * The 'more' paginator */ more(p,cnt,size) char *p; int *cnt,size; { int r; if (*cnt == 0) { if (size == 0) return(1); /* if *cnt=0 and size=0 we're done */ while ((r = getinp(cnt,size)) == -1) ; if (r) /* quit */ { *p = 0; return(1); } } if (*cnt == -1) { /* search in progress */ if (!strposn(p,more_pat)) { dotik(256,0); return(0); /* not found yet */ } else { /* found */ *cnt = size; printf("\b \n"); } } printf("%s\n",p); *p = 0; (*cnt)--; return(0); } /************************************************************* * getinp(cnt,size) */ getinp(cnt,size) int *cnt,size; { int i,c; printf("%s",more_msg); for (;;) { c = GETCHAR(); if (c == '\r') c = '\n'; if (strchr("nq/ \n\033",c)) break; putchar(BEL); } era_line(more_msg); if (c == 'q' || c == 033) return(1); switch (c) { case ' ' : *cnt = size; break; case '\n': *cnt = 1; break; case '/' : /* get pattern */ putchar('/'); for (i=0;;) { c = GETCHAR(); if (c == '\r') c = '\n'; if (c == '\n') break; if (c == '\b') { if (i > 0) { putchar(c); i--; } else { putchar('\b'); return(-1); } } else { putchar(c); more_pat[i++] = c; } } more_pat[i] = 0; printf(" "); *cnt = -1; /* enter search mode */ break; case 'n' : printf("/%s ",more_pat); *cnt = -1; /* enter search mode */ break; } return(0); } /************************************************************* * void dotik(rate,use_ret) * rate -- controls how fast the display rotates. The larger * the value, the faster the rotation. * use_ret * specifies that " %c\r" should be used rather than * "\b%c". */ void dotik(rate,use_ret) int rate,use_ret; { tik_cnt -= rate; if (tik_cnt > 0) return; tik_cnt = TIKRATE; if (more_tik == 0) more_tik = more_tiks; if (*more_tik == 0) more_tik = more_tiks; if (use_ret) printf(" %c\r",*more_tik); else printf("\b%c",*more_tik); more_tik++; }