From fe5a38fc526c373c5cabad4f963fbd99ffb712e9 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Tue, 14 Jul 2020 17:00:49 -0400 Subject: split i/o stuff out to io.c --- Makefile | 6 +++++ io.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ more.c | 76 +++++++++++++++------------------------------------------------- more.h | 7 +++++- 4 files changed, 100 insertions(+), 60 deletions(-) create mode 100644 io.c diff --git a/Makefile b/Makefile index cd954dc..382ed04 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,13 @@ all: $(BINDIR)/more clean: rm -f $(BINDIR)/more $(OBJDIR)/*.o +$(BINDIR)/more: $(OBJDIR)/io.o +$(OBJDIR)/io.o: $(SRCDIR)/more.h +$(OBJDIR)/io.o: $(SRCDIR)/io.c + $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/io.c + $(BINDIR)/more: $(OBJDIR)/more.o +$(OBJDIR)/more.o: $(SRCDIR)/more.h $(OBJDIR)/more.o: $(SRCDIR)/more.c $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/more.c diff --git a/io.c b/io.c new file mode 100644 index 0000000..0aab2ff --- /dev/null +++ b/io.c @@ -0,0 +1,71 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +//#include + +#include "more.h" + +ssize_t more_getline(struct more_file *mf, size_t lineno) +{ + if (mf->nlines <= lineno && mf->nlines != 0) { + fsetpos(mf->f, &(mf->lines[mf->nlines - 1])); + getline(&(mf->buf), &(mf->nbuf), mf->f); + } + + while (mf->nlines <= lineno) { + mf->nlines++; + mf->lines = realloc(mf->lines, mf->nlines * sizeof(*mf->lines)); + + fgetpos(mf->f, &(mf->lines[mf->nlines - 1])); + + getline(&(mf->buf), &(mf->nbuf), mf->f); + + if (mf->backing != mf->f) { + fgetpos(mf->backing, &(mf->lines[mf->nlines - 1])); + fputs(mf->buf, mf->backing); + } + } + + fsetpos(mf->backing, &(mf->lines[lineno])); + return getline(&(mf->buf), &(mf->nbuf), mf->backing); +} + +struct more_file more_open(const char *path) +{ + struct more_file mf = { + .f = stdin, + }; + + if (strcmp(path, "-")) { + mf.f = fopen(path, "r"); + if (!mf.f) { + fprintf(stderr, "more: %s: %s\n", path, strerror(errno)); + return mf; + } + } + + fpos_t pos; + if (fgetpos(mf.f, &pos) != 0) { + mf.backing = tmpfile(); + } else { + mf.backing = mf.f; + } + + return mf; +} + +void more_close(struct more_file *mf) +{ + if (mf->backing != mf->f) { + fclose(mf->backing); + } + + if (mf->f != stdin) { + fclose(mf->f); + } + + free(mf->lines); + free(mf->buf); +} diff --git a/more.c b/more.c index 07180ba..ca434c3 100644 --- a/more.c +++ b/more.c @@ -19,51 +19,21 @@ enum { CTRL_U = 0x15, }; -static ssize_t more_getline(struct morefile *mf, size_t lineno, char **line, size_t *n) +void refresh(const struct more_tty *mt, struct more_file *mf) { - if (mf->nlines <= lineno && mf->nlines != 0) { - fsetpos(mf->f, &(mf->lines[mf->nlines - 1])); - getline(line, n, mf->f); - } - - while (mf->nlines <= lineno) { - mf->nlines++; - mf->lines = realloc(mf->lines, mf->nlines * sizeof(*mf->lines)); - - fgetpos(mf->f, &(mf->lines[mf->nlines - 1])); - - getline(line, n, mf->f); - - if (mf->backing != mf->f) { - fgetpos(mf->backing, &(mf->lines[mf->nlines - 1])); - fputs(*line, mf->backing); - } - } - - fsetpos(mf->backing, &(mf->lines[lineno])); - return getline(line, n, mf->backing); -} - -void refresh(const struct more_tty *mt, struct morefile *mf) -{ - char *line = NULL; - size_t n = 0; for (size_t i = mf->topline; i < mf->topline + mt->lines; i++) { /* FIXME: account for long lines */ - if (more_getline(mf, i, &line, &n) == -1) { + if (more_getline(mf, i) == -1) { break; } - printf("%s", line); + printf("%s", mf->buf); } - free(line); } -void scroll(const struct more_tty *mt, struct morefile *mf, int count, int multiple) +void scroll(const struct more_tty *mt, struct more_file *mf, int count, int multiple) { - char *line = NULL; - size_t n = 0; int by = count ? count * multiple : multiple; if (by < 0) { @@ -77,14 +47,12 @@ void scroll(const struct more_tty *mt, struct morefile *mf, int count, int multi /* FIXME: account for long lines here, too */ mf->topline++; - more_getline(mf, mf->topline + mt->lines + 1, &line, &n); - printf("%s", line); + more_getline(mf, mf->topline + mt->lines + 1); + printf("%s", mf->buf); } - - free(line); } -void mark(const struct more_tty *mt, struct morefile *mf) +void mark(const struct more_tty *mt, struct more_file *mf) { int c = fgetc(mt->tty); if (islower(c)) { @@ -92,7 +60,7 @@ void mark(const struct more_tty *mt, struct morefile *mf) } } -void jump(const struct more_tty *mt, struct morefile *mf) +void jump(const struct more_tty *mt, struct more_file *mf) { int c = fgetc(mt->tty); if (islower(c)) { @@ -103,29 +71,16 @@ void jump(const struct more_tty *mt, struct morefile *mf) int more(const struct more_tty *mt, const char *file) { - struct morefile mf = { - .f = stdin, - }; - - int count = 0; - - if (strcmp(file, "-")) { - mf.f = fopen(file, "r"); - if (!mf.f) { - fprintf(stderr, "more: %s: %s\n", file, strerror(errno)); - retval = 1; - return 1; - } - } + struct more_file mf = more_open(file); - fpos_t pos; - if (fgetpos(mf.f, &pos) != 0) { - mf.backing = tmpfile(); - } else { - mf.backing = mf.f; + if (mf.f == NULL) { + retval = 1; + return 1; } refresh(mt, &mf); + + int count = 0; while (mf.f) { int c = fgetc(mt->tty); @@ -234,9 +189,11 @@ int more(const struct more_tty *mt, const char *file) break; case 'n': + more_close(&mf); return count ? count : 1; case 'p': + more_close(&mf); return count ? -count : -1; case 't': @@ -289,6 +246,7 @@ int more(const struct more_tty *mt, const char *file) } } + more_close(&mf); return 0; } diff --git a/more.h b/more.h index 440aa15..8e6e723 100644 --- a/more.h +++ b/more.h @@ -7,13 +7,18 @@ struct more_tty { int columns; }; -struct morefile { +struct more_file { FILE *f; FILE *backing; size_t topline; fpos_t *lines; size_t nlines; size_t mark[26]; + char *buf; + size_t nbuf; }; struct more_tty more_open_tty(int lines); +struct more_file more_open(const char *path); +void more_close(struct more_file *mf); +ssize_t more_getline(struct more_file *mf, size_t lineno); -- cgit v1.2.1