diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 141 |
1 files changed, 73 insertions, 68 deletions
diff --git a/main.c b/main.c index 256e03d..65de555 100644 --- a/main.c +++ b/main.c @@ -22,94 +22,82 @@ int quit(const char *_) { /* documents */ +#define TXT_BUF_SIZE (1024 * 1024) +struct { + char buf[TXT_BUF_SIZE]; + size_t n; +} text; + struct doc { struct doc *prev, *next; struct { - char *buf; - size_t len, cap; - } text; - size_t ofs; + size_t ofs, len, idx; + } txt; }; -struct doc *doc_head, *doc_tail, *doc_cur; - -void doc_free(struct doc *d) { - free(d->text.buf); - free(d); -} +#define DOC_MAX 32 +struct doc docv[DOC_MAX]; +size_t docn = 0, doci = 0; int doc_new(void) { - struct doc *d = calloc(1, sizeof *d); - if (!d) { - return -1; - } - d->text.buf = calloc(256, 1); - if (!d->text.buf) { - free(d); - return -1; - } - d->text.len = 256; - d->text.cap = 256; - if (doc_cur) { - struct doc *p = doc_cur->next; - while (p) { - struct doc *pp = p; - p = p->next; - doc_free(pp); - } - doc_tail = doc_cur; - } - if (doc_tail) { - doc_tail->next = d; - d->prev = doc_tail; + if (doci < docn) { + text.n = docv[doci].txt.ofs; + docn = doci; } - if (!doc_head) doc_head = d; - doc_tail = d; - doc_cur = d; + if (docn >= DOC_MAX) return -1; + memset(&docv[docn], 0, sizeof(struct doc)); + docv[docn].txt.ofs = text.n; + docv[docn].txt.idx = text.n; + doci = docn++; return 0; } int doc_add(char *buf, size_t n) { - if (!doc_cur) return -1; - size_t c = doc_cur->text.cap; - size_t tn = doc_cur->text.len + n + 1; - if (c < tn) { - while (c < tn) c <<= 1; - char *s = realloc(doc_cur->text.buf, c); - if (!s) { - return -1; - } - doc_cur->text.buf = s; + if (text.n + n > TXT_BUF_SIZE) { + return -1; } - memcpy(&doc_cur->text.buf[doc_cur->text.len], buf, n); - doc_cur->text.len += 1; - doc_cur->text.buf[doc_cur->text.len] = 0; + memcpy(&text.buf[text.n], buf, n); + text.n += n; return 0; } void doc_prev(void) { - if (doc_cur && doc_cur->prev) { - doc_cur = doc_cur->prev; - } + if (doci > 0) doci--; } void doc_next(void) { - if (doc_cur && doc_cur->next) { - doc_cur = doc_cur->next; - } -} - -void doc_fini(void) { - while (doc_tail) { - doc_head = doc_tail; - doc_tail = doc_tail->prev;; - doc_free(doc_head); - } + if (doci < docn) doci++; } /* pagination */ +size_t pg_lines() { + return 24; +} + int pg_down(const char *_) { + if (doci >= docn) return -1; + size_t lines = pg_lines(); + size_t i = docv[doci].txt.idx; + size_t end = docv[doci].txt.ofs + docv[doci].txt.len; + while (lines > 0 && i < end) { + putchar(text.buf[i]); + if (text.buf[i] == '\n') lines--; + i++; + } + return 0; +} + +int pg_up(const char *_) { + if (doci >= docn) return -1; + size_t lines = pg_lines() << 1; + size_t i = docv[doci].txt.idx; + while (lines > 0 && i > 0) { + putchar(text.buf[i]); + if (text.buf[i] == '\n') lines--; + i--; + } + pg_down(_); return 0; } @@ -118,19 +106,36 @@ int pg_down(const char *_) { #define HOST_MAX 255 #define PATH_MAX 255 -enum url_type { +enum doc_type { TYPE_GOPHERDOC, TYPE_GEMTEXT, - TYPE_PLAIN + TYPE_PLAIN, + TYPE_UNKNOWN +}; + +enum protocol { + PROT_FILE, + PROT_GOPHER, + PROT_GEMINI, + PROT_UNKNOWN, }; -struct url { +struct addr { char host[HOST_MAX]; char path[PATH_MAX]; size_t host_len, path_len; - enum url_type type; + enum protocol prot; + enum doc_type type; }; +int url_to_addr(const char *url, struct addr *adr) { + char *colon = strchr(url, ':'); + adr->prot = PROT_UNKNOWN; + if (colon) { + } + return -1; +} + int nav_to(const char *url) { return 0; } @@ -149,6 +154,7 @@ struct cmd { struct cmd cmd_tbl[] = { { 'g', nav_to }, { '\n', pg_down }, + { '\b', pg_up }, { 'q', quit } }; @@ -191,6 +197,5 @@ int main(void) { while (running && cmd_get(cmd_buf, sizeof cmd_buf)) { cmd_do(cmd_buf); } - doc_fini(); return 0; } |