summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-07-14 17:00:49 -0400
committerJakob Kaivo <jkk@ung.org>2020-07-14 17:00:49 -0400
commitfe5a38fc526c373c5cabad4f963fbd99ffb712e9 (patch)
tree4e4d46aa2c985a5ea2064902bc433c30a3999255
parent6b8dfa2858c16b3cba4cd1e560000c47db3e50e6 (diff)
split i/o stuff out to io.c
-rw-r--r--Makefile6
-rw-r--r--io.c71
-rw-r--r--more.c76
-rw-r--r--more.h7
4 files changed, 100 insertions, 60 deletions
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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <unistd.h>
+
+#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);