summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buf.c18
-rw-r--r--buf.h13
-rw-r--r--doc.h10
-rw-r--r--main.c19
-rw-r--r--nav.c42
-rw-r--r--nav.h8
-rw-r--r--net.c44
-rw-r--r--net.h14
8 files changed, 124 insertions, 44 deletions
diff --git a/buf.c b/buf.c
index dd93116..1f0e2b3 100644
--- a/buf.c
+++ b/buf.c
@@ -1,8 +1,9 @@
#include <stdlib.h>
+#include <string.h>
#include "buf.h"
#include "err.h"
-void buf_init(struct buf *b, size_t n) {
+void buf_init(buf_t *b, size_t n) {
b->buf = calloc(1, n);
if (!b->buf) {
efatal("buf_init");
@@ -11,7 +12,7 @@ void buf_init(struct buf *b, size_t n) {
b->sz = 0;
}
-void buf_grow(struct buf *b, size_t n) {
+void buf_grow(buf_t *b, size_t n) {
size_t sz = b->sz + n;
size_t c = b->cap;
if (sz > c) {
@@ -23,6 +24,17 @@ void buf_grow(struct buf *b, size_t n) {
}
}
-void buf_free(struct buf *b) {
+void buf_cat(buf_t *b, char *src, size_t n) {
+ buf_grow(b, n);
+ memcpy(&b->buf[b->sz], src, n);
+ b->sz += n;
+}
+
+void buf_catc(buf_t *b, char c) {
+ buf_grow(b, 1);
+ b->buf[b->sz++] = c;
+}
+
+void buf_free(buf_t *b) {
free(b->buf);
}
diff --git a/buf.h b/buf.h
index fdf0c52..c275f9c 100644
--- a/buf.h
+++ b/buf.h
@@ -3,13 +3,16 @@
#include <stddef.h>
-struct buf {
+typedef struct buf {
size_t sz, cap;
char *buf;
-};
+} buf_t;
-void buf_init(struct buf *, size_t);
-void buf_grow(struct buf *, size_t);
-void buf_free(struct buf *);
+void buf_init(buf_t *, size_t);
+void buf_grow(buf_t *, size_t);
+void buf_free(buf_t *);
+
+void buf_cat(buf_t *b, char *src, size_t n);
+void buf_catc(buf_t *b, char c);
#endif
diff --git a/doc.h b/doc.h
index 5e9c18c..fccd676 100644
--- a/doc.h
+++ b/doc.h
@@ -2,13 +2,7 @@
#define DOC_H
#include "buf.h"
-
-enum doc_type {
- TYPE_UNKNOWN,
- TYPE_GOPHERDOC,
- TYPE_GEMTEXT,
- TYPE_PLAIN,
-};
+#include "net.h"
#define DOC_LINK_NONE 0xffff
@@ -18,7 +12,7 @@ struct doc_line {
};
struct doc {
- struct buf txt, lnk;
+ buf_t txt, lnk;
size_t latest;
};
diff --git a/main.c b/main.c
index 64343bc..0c36a34 100644
--- a/main.c
+++ b/main.c
@@ -5,7 +5,6 @@
#include <stdlib.h>
#include "doc.h"
-#include "net.h"
#include "err.h"
#include "nav.h"
@@ -13,20 +12,6 @@
/* navigation */
-int nav_to(const char *url) {
- struct addr a;
- static enum protocol prot_default = PROT_FILE; /* change to gopher later */
- if (net_addr(url, &a, prot_default)) {
- return -1;
- }
- prot_default = a.prot;
- return 0;
-}
-
-int nav_link_nr(unsigned long link_nr) {
- return 0;
-}
-
/* commands */
struct cmd {
@@ -48,7 +33,7 @@ int cmd_do(char *cmd, struct nav_state *ns) {
unsigned long n = strtoul(cmd, NULL, 10);
if (errno) {
perr("invalid link number");
- } else if (nav_link_nr(n)) {
+ } else if (nav_link_nr(ns, n)) {
perr("navigation failure");
}
}
@@ -63,7 +48,7 @@ int cmd_do(char *cmd, struct nav_state *ns) {
nav_redraw(ns);
break;
case 'g':
- if (nav_to(cmd + 1)) perr("navigation failure");
+ if (nav_to(ns, cmd + 1)) perr("navigation failure");
break;
default:
perr("?");
diff --git a/nav.c b/nav.c
index 82cf71a..3a1d095 100644
--- a/nav.c
+++ b/nav.c
@@ -1,12 +1,17 @@
#include <string.h>
#include <stdio.h>
+
#include "nav.h"
+#include "net.h"
+
+/* history */
void nav_init(struct nav_state *ns) {
memset(ns, 0, sizeof *ns);
ns->histc = 1;
- doc_init(&ns->histv[0]);
- doc_add_text(&ns->histv[0], "Type ? for command help.");
+ doc_init(ns->histv);
+ doc_add_text(ns->histv, "Type ? for command help.");
+ ns->prot_default = PROT_FILE; /* change to PROT_GOPHER later */
}
void nav_fini(struct nav_state *ns) {
@@ -15,6 +20,16 @@ void nav_fini(struct nav_state *ns) {
}
}
+void nav_new(struct nav_state *ns) {
+ if (ns->histc == HIST_MAX) {
+ doc_fini(ns->histv);
+ memmove(ns->histv, &ns->histv[1], sizeof(struct doc) * (HIST_MAX - 1));
+ ns->histc--;
+ }
+}
+
+/* paging */
+
size_t pg_lines(void) {
return 24;
}
@@ -59,4 +74,27 @@ void nav_pg_down(struct nav_state *ns) {
}
void nav_redraw(struct nav_state *ns) {
+ size_t lines = pg_lines();
+ while (lines-- && nav_line_up(ns));
+ nav_pg_down(ns);
+}
+
+/* network */
+
+int nav_to(struct nav_state *ns, const char *url) {
+ struct addr adr;
+ buf_t buf;
+ if (net_addr(url, &adr, ns->prot_default)) {
+ return -1;
+ }
+ ns->prot_default = adr.prot;
+ if (net_fetch(&adr, &buf)) {
+ return -1;
+ }
+ buf_free(&buf);
+ return 0;
+}
+
+int nav_link_nr(struct nav_state *ns, unsigned long link_nr) {
+ return 0;
}
diff --git a/nav.h b/nav.h
index baefba9..69f666a 100644
--- a/nav.h
+++ b/nav.h
@@ -8,12 +8,20 @@ struct nav_state {
size_t histc, cur_doc;
struct doc histv[HIST_MAX];
size_t cur_ofs[HIST_MAX];
+ enum protocol prot_default;
};
void nav_init(struct nav_state *ns);
void nav_fini(struct nav_state *ns);
+
+void nav_next(struct nav_state *ns);
+void nav_prev(struct nav_state *ns);
+
void nav_pg_up(struct nav_state *ns);
void nav_pg_down(struct nav_state *ns);
void nav_redraw(struct nav_state *ns);
+int nav_to(struct nav_state *ns, const char *url);
+int nav_link_nr(struct nav_state *ns, unsigned long link_nr);
+
#endif
diff --git a/net.c b/net.c
index 73f50d4..e90d3c0 100644
--- a/net.c
+++ b/net.c
@@ -1,5 +1,8 @@
#include <string.h>
+#include <stdio.h>
+
#include "net.h"
+#include "err.h"
int net_addr(const char *url, struct addr *adr, enum protocol prot_default) {
char *prot_mark;
@@ -24,11 +27,40 @@ int net_addr(const char *url, struct addr *adr, enum protocol prot_default) {
} else {
adr->prot = prot_default;
}
- adr->type = TYPE_PLAIN;
- adr->host_len = 0;
- size_t n = strlen(url);
- if (n > PATH_MAX) return -1;
- adr->path_len = n;
- memcpy(adr->path, url, n);
+
+ if (adr->prot == PROT_FILE) {
+ adr->type = TYPE_PLAIN;
+ adr->host_len = 0;
+ size_t n = strlen(url);
+ if (n >= PATH_MAX) return -1;
+ adr->path_len = n;
+ memcpy(adr->path, url, n + 1);
+ } else {
+ return -1;
+ }
+
return 0;
}
+
+int net_fetch(const struct addr *adr, struct buf *buf) {
+ switch (adr->prot) {
+ case PROT_FILE:
+ {
+ FILE *f = fopen(adr->path, "r/o");
+ if (!f) {
+ perr("file not found");
+ return -1;
+ }
+ buf_init(buf, 1024);
+ char b[256];
+ while (fgets(b, sizeof b, f)) {
+ buf_cat(buf, b, strlen(b));
+ }
+ buf_catc(buf, 0);
+ fclose(f);
+ }
+ return 0;
+ default:
+ return -1;
+ }
+}
diff --git a/net.h b/net.h
index 0b4422f..8483120 100644
--- a/net.h
+++ b/net.h
@@ -1,10 +1,10 @@
#ifndef NET_H
#define NET_H
-#include "doc.h"
+#include "buf.h"
-#define HOST_MAX 255
-#define PATH_MAX 255
+#define HOST_MAX 256
+#define PATH_MAX 256
enum protocol {
PROT_UNKNOWN,
@@ -13,6 +13,13 @@ enum protocol {
PROT_GEMINI,
};
+enum doc_type {
+ TYPE_UNKNOWN,
+ TYPE_GOPHERDOC,
+ TYPE_GEMTEXT,
+ TYPE_PLAIN,
+};
+
struct addr {
char host[HOST_MAX];
char path[PATH_MAX];
@@ -22,5 +29,6 @@ struct addr {
};
int net_addr(const char *url, struct addr *adr, enum protocol prot_default);
+int net_fetch(const struct addr *adr, struct buf *buf);
#endif