1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
* view.c -- a silly little viewer program
*
* written by Eric S. Raymond <esr@snark.thyrsus.com> December 1994
* to test the scrolling code in ncurses.
*
* Takes a filename argument. It's a simple file-viewer with various
* scroll-up and scroll-down commands.
*
* n -- scroll one line forward
* p -- scroll one line back
*
* Either command accepts a numeric prefix interpreted as a repeat count.
* Thus, typing `5n' should scroll forward 5 lines in the file.
*
* The way you can tell this is working OK is that, in the trace file,
* there should be one scroll operation plus a small number of line
* updates, as opposed to a whole-page update. This means the physical
* scroll operation worked, and the refresh() code only had to do a
* partial repaint.
*/
#include "test.priv.h"
#include <string.h>
#include <ctype.h>
#include <signal.h>
#define MAXLINES 256 /* most lines we can handle */
static void finish(int sig);
static char *lines[MAXLINES];
int main(int argc, char *argv[])
{
FILE *fp;
char buf[BUFSIZ];
int i;
char **lptr, **olptr;
#ifdef TRACE
trace(TRACE_UPDATE);
#endif
if (argc != 2) {
fprintf(stderr, "usage: view file\n");
exit(1);
} else if ((fp = fopen(argv[1], "r")) == (FILE *)NULL) {
perror(argv[1]);
exit(1);
}
(void) signal(SIGINT, finish); /* arrange interrupts to terminate */
(void) initscr(); /* initialize the curses library */
keypad(stdscr, TRUE); /* enable keyboard mapping */
(void) nonl(); /* tell curses not to do NL->CR/NL on output */
(void) cbreak(); /* take input chars one at a time, no wait for \n */
(void) noecho(); /* don't echo input */
scrollok(stdscr, TRUE);
/* slurp the file */
for (lptr = &lines[0]; fgets(buf, BUFSIZ, fp) != (char *)NULL; lptr++) {
if (lptr - lines >= MAXLINES) {
endwin();
(void) fprintf(stderr, "%s: %s is too large\n", argv[0], argv[1]);
exit(1);
}
buf[strlen(buf) - 1] = '\0';
*lptr = (char *)malloc((size_t)(COLS + 1));
(void) strncpy(*lptr, buf, (size_t)COLS);
(*lptr)[COLS] = '\0';
}
(void) fclose(fp);
lptr = lines;
for (;;) {
int n, c;
bool explicit;
for (i = 0; i < LINES; i++) {
move(i, 0);
clrtoeol();
if (lptr[i])
addstr(lptr[i]);
}
explicit = FALSE;
n = 0;
for (;;) {
c = getch();
if (isdigit(c))
n = 10 * n + (c - '0');
else
break;
}
if (!explicit && n == 0)
n = 1;
switch(c) {
case KEY_DOWN:
case 'n':
olptr = lptr;
for (i = 0; i < n; i++)
if (lptr + LINES < lines + MAXLINES && lptr[LINES + 1])
lptr++;
else
break;
wscrl(stdscr, lptr - olptr);
break;
case KEY_UP:
case 'p':
olptr = lptr;
for (i = 0; i < n; i++)
if (lptr > lines)
lptr--;
else
break;
wscrl(stdscr, lptr - olptr);
break;
}
}
finish(0); /* we're done */
}
static void finish(int sig)
{
endwin();
exit(sig != 0);
}
/* view.c ends here */
|