summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c141
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;
}