summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Vogel <jvogel4@stny.rr.com>2015-12-06 11:31:56 -0500
committerJohn Vogel <jvogel4@stny.rr.com>2015-12-06 11:31:56 -0500
commitcac955deb5f193ffd9e62213f744890488f35060 (patch)
tree08af3b11e88538091140fe1bad41e13bd109e0e4
parent6cda30754f9b9a5fbd872f1a64bde72d9bc23c9d (diff)
downloadcic-cac955deb5f193ffd9e62213f744890488f35060.tar.gz
Add page.c, for paging log
-rw-r--r--page.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/page.c b/page.c
new file mode 100644
index 0000000..4e8216d
--- /dev/null
+++ b/page.c
@@ -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);
+}