diff options
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | nav.c | 25 | ||||
-rw-r--r-- | net.c | 2 | ||||
-rw-r--r-- | net.h | 8 | ||||
-rw-r--r-- | parse.c | 23 | ||||
-rw-r--r-- | parse.h | 10 |
6 files changed, 68 insertions, 6 deletions
diff --git a/main.c b/main.c index 0c36a34..738a3e9 100644 --- a/main.c +++ b/main.c @@ -50,6 +50,12 @@ int cmd_do(char *cmd, struct nav_state *ns) { case 'g': if (nav_to(ns, cmd + 1)) perr("navigation failure"); break; + case 'p': + nav_prev(ns); + break; + case 'n': + nav_next(ns); + break; default: perr("?"); break; diff --git a/nav.c b/nav.c index 3a1d095..59fdca6 100644 --- a/nav.c +++ b/nav.c @@ -3,6 +3,7 @@ #include "nav.h" #include "net.h" +#include "parse.h" /* history */ @@ -20,12 +21,27 @@ void nav_fini(struct nav_state *ns) { } } -void nav_new(struct nav_state *ns) { +void nav_push(struct nav_state *ns, struct doc d) { + while (ns->histc > ns->cur_doc + 1) { + doc_fini(&ns->histv[--ns->histc]); + } if (ns->histc == HIST_MAX) { doc_fini(ns->histv); memmove(ns->histv, &ns->histv[1], sizeof(struct doc) * (HIST_MAX - 1)); ns->histc--; } + ns->histv[ns->histc++] = d; + ns->cur_doc = ns->histc - 1; +} + +void nav_prev(struct nav_state *ns) { + if (ns->cur_doc > 0) ns->cur_doc--; + nav_redraw(ns); +} + +void nav_next(struct nav_state *ns) { + if (ns->cur_doc + 1 < ns->histc) ns->cur_doc++; + nav_redraw(ns); } /* paging */ @@ -91,7 +107,14 @@ int nav_to(struct nav_state *ns, const char *url) { if (net_fetch(&adr, &buf)) { return -1; } + struct doc d; + if (parse_doc(adr.type, &d, &buf)) { + buf_free(&buf); + return -1; + } + nav_push(ns, d); buf_free(&buf); + nav_redraw(ns); return 0; } diff --git a/net.c b/net.c index e90d3c0..b826e96 100644 --- a/net.c +++ b/net.c @@ -29,7 +29,7 @@ int net_addr(const char *url, struct addr *adr, enum protocol prot_default) { } if (adr->prot == PROT_FILE) { - adr->type = TYPE_PLAIN; + adr->type = DOC_PLAIN; adr->host_len = 0; size_t n = strlen(url); if (n >= PATH_MAX) return -1; diff --git a/net.h b/net.h index 8483120..c3e12ef 100644 --- a/net.h +++ b/net.h @@ -14,10 +14,10 @@ enum protocol { }; enum doc_type { - TYPE_UNKNOWN, - TYPE_GOPHERDOC, - TYPE_GEMTEXT, - TYPE_PLAIN, + DOC_UNKNOWN, + DOC_GOPHERDOC, + DOC_GEMTEXT, + DOC_PLAIN, }; struct addr { diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..a1a68d8 --- /dev/null +++ b/parse.c @@ -0,0 +1,23 @@ +#include "parse.h" + +int parse_doc(enum doc_type type, struct doc *d, const buf_t *b) { + switch (type) { + case DOC_PLAIN: + doc_init(d); + for (size_t i = 0; i < b->sz; i++) { + char c = b->buf[i]; + if (c == '\n') { + doc_new_line(d); + } else { + doc_add_textn(d, &c, 1); + } + } + goto ok; + default: + goto err; + } +ok: + return 0; +err: + return -1; +} diff --git a/parse.h b/parse.h new file mode 100644 index 0000000..4f19285 --- /dev/null +++ b/parse.h @@ -0,0 +1,10 @@ +#ifndef PARSE_H +#define PARSE_H + +#include "net.h" +#include "doc.h" +#include "buf.h" + +int parse_doc(enum doc_type type, struct doc *d, const buf_t *b); + +#endif |