diff options
| author | John Vogel <jvogel4@stny.rr.com> | 2015-12-06 11:31:56 -0500 |
|---|---|---|
| committer | John Vogel <jvogel4@stny.rr.com> | 2015-12-06 11:31:56 -0500 |
| commit | cac955deb5f193ffd9e62213f744890488f35060 (patch) | |
| tree | 08af3b11e88538091140fe1bad41e13bd109e0e4 /page.c | |
| parent | 6cda30754f9b9a5fbd872f1a64bde72d9bc23c9d (diff) | |
| download | cic-cac955deb5f193ffd9e62213f744890488f35060.tar.gz | |
Add page.c, for paging log
Diffstat (limited to 'page.c')
| -rw-r--r-- | page.c | 184 |
1 files changed, 184 insertions, 0 deletions
@@ -0,0 +1,184 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <curses.h> + +void freefilebuf(char **buffer, ssize_t cnt) +{ + if (!buffer || !cnt) + return; + + while (cnt) + free(buffer[--cnt]); + + free(buffer); +} + +int readfile(FILE *fp, char ***buffer, ssize_t *count, int ncols) +{ + char **buf, **tmp; + char *line; + int ret; + size_t chunks, sz; + ssize_t cnt, len, cuts, clen; +#define CHUNKS 128 + + if (!fp) + return -1; + + buf = malloc(sizeof(char *) * CHUNKS); + if (buf == NULL) { + perror(NULL); + return -1; + } + + ret = 0; + cnt = 0; + chunks = CHUNKS; + + for (cnt = 0; ; cnt++) { + if (cnt == chunks-5) { + chunks += CHUNKS; + tmp = realloc(buf, chunks * sizeof(char *)); + if (tmp == NULL) { + ret = -1; + break; + } + buf = tmp; + } + line = NULL; + sz = 0; + if ((len = getdelim(&line, &sz, '\n', fp)) == -1) { + if (ferror(fp)) + ret = -1; + break; + } + line[--len] = '\0'; /* remove the newline */ + if (len > ncols) { + char *p; + cuts = 0; + clen = len; + p = line; + while ((clen > 0) && (ret != -1)) { + buf[cnt+cuts] = strndup(p, (clen > ncols) ? ncols - 1 : clen); + p += ncols - 1; + clen -= ncols - 1; + cuts++; + if (cnt+cuts == chunks-5) { + chunks += CHUNKS; + tmp = realloc(buf, chunks * sizeof(char *)); + if (tmp == NULL) { + ret = -1; + break; + } + buf = tmp; + } + } + cnt += (cuts - 1); + free(line); + if (ret == -1) + break; + } + else { + buf[cnt] = line; + } + } + + if (ret == -1) { + perror(NULL); + freefilebuf(buf, cnt); + } + else { + *buffer = buf; + *count = cnt; + } + + free(line); + + return ret; +} + +void displayfile(FILE *fp, long fpos, int r, int c, int y, int x) +{ + WINDOW *win; + char **lbuf; + int i, ch, inc, loc; + ssize_t n, ctop, start; + + if (fseek(fp, fpos, SEEK_SET) == -1) { + perror(NULL); + return; + } + + if ((readfile(fp, &lbuf, &n, c) == -1) || (n <= r)) { + freefilebuf(lbuf, n); + return; + } + + inc = 0; + ctop = start = n - r; + + win = newwin(r, c, y, x); + idlok(win, TRUE); + scrollok(win, TRUE); + wsetscrreg(win, 0, r-1); + + for (i = 0; i < r && i < n; i++) + mvwaddnstr(win, i, 0, lbuf[ctop+i], c); + wrefresh(win); + + while ((ch = getch()) != 'q') { + if (n <=r) + continue; + switch (ch) { + case 'f': + if (ctop + r >= n) + break; + ctop += r; + if (ctop > n - r) + ctop = (n - r); + break; + case 'b': + if (ctop == 0) + break; + ctop -= r; + if (ctop < 0) + ctop = 0; + break; + case 'j': + if (ctop + r >= n) + break; + inc = 1; + ctop++; + break; + case 'k': + if (ctop == 0) + break; + inc = -1; + ctop--; + break; + default: + break; + } + if (start != ctop) { + if (inc) { + loc = (inc < 0) ? 0 : r - 1; + wscrl(win, inc); + mvwaddnstr(win, loc, 0, lbuf[ctop+loc], c); + wrefresh(win); + inc = 0; + } + else if (start != ctop) { + wclear(win); + for (i = 0; i < r; i++) + mvwaddnstr(win, i, 0, lbuf[ctop+i], c); + wrefresh(win); + } + start = ctop; + } + } + + freefilebuf(lbuf, n); + delwin(win); +} |
