commit c1d27b0e114e6a65f7979971940df212f00bb2ae from: Omar Polo date: Fri Jun 14 22:15:12 2024 UTC untangle a bit buffers and parsers Now buffers have a nicer interface, taking explicitly the buffer where they push stuff, and the code that deals with buffers doesn't need to peek into the parsers. The parsers now are 'pure' structs without state attached to them, the state was moved to the buffer. commit - cb75f36c2043dbc8025438662a547f5b162f9e17 commit + c1d27b0e114e6a65f7979971940df212f00bb2ae blob - f98e328499a42678d5e82a73dfc56a7126464d7c blob + 3f89716e58df8fb4fc17d02680a8be4cfa49f5ec --- cmd.c +++ cmd.c @@ -253,7 +253,7 @@ cmd_scroll_down(struct buffer *buffer) void cmd_beginning_of_buffer(struct buffer *buffer) { - buffer->current_line = TAILQ_FIRST(&buffer->head); + buffer->current_line = TAILQ_FIRST(&buffer->vhead); buffer->cpoff = 0; buffer->top_line = buffer->current_line; buffer->line_off = 0; @@ -262,7 +262,7 @@ cmd_beginning_of_buffer(struct buffer *buffer) void cmd_end_of_buffer(struct buffer *buffer) { - buffer->current_line = TAILQ_LAST(&buffer->head, vhead); + buffer->current_line = TAILQ_LAST(&buffer->vhead, vhead); if (buffer->current_line == NULL) return; @@ -620,7 +620,7 @@ cmd_link_select(struct buffer *buffer) GUARD_RECURSIVE_MINIBUFFER(); - l = TAILQ_FIRST(&buffer->page.head); + l = TAILQ_FIRST(&buffer->head); while (l != NULL && l->type != LINE_LINK) l = TAILQ_NEXT(l, lines); @@ -640,7 +640,7 @@ cmd_swiper(struct buffer *buffer) GUARD_RECURSIVE_MINIBUFFER(); enter_minibuffer(sensible_self_insert, swiper_select, exit_minibuffer, - NULL, compl_swiper, TAILQ_FIRST(&buffer->page.head), 1); + NULL, compl_swiper, TAILQ_FIRST(&buffer->head), 1); strlcpy(ministate.prompt, "Select line: ", sizeof(ministate.prompt)); } @@ -651,7 +651,7 @@ cmd_toc(struct buffer *buffer) GUARD_RECURSIVE_MINIBUFFER(); - l = TAILQ_FIRST(&buffer->page.head); + l = TAILQ_FIRST(&buffer->head); while (l != NULL && l->type != LINE_TITLE_1 && l->type != LINE_TITLE_2 && @@ -941,7 +941,7 @@ cmd_mini_goto_beginning(struct buffer *buffer) if ((vl = buffer->current_line) != NULL) vl->parent->type = LINE_COMPL; - vl = TAILQ_FIRST(&buffer->head); + vl = TAILQ_FIRST(&buffer->vhead); while (vl != NULL && vl->parent->flags & L_HIDDEN) vl = TAILQ_NEXT(vl, vlines); @@ -966,7 +966,7 @@ cmd_mini_goto_end(struct buffer *buffer) if ((vl = buffer->current_line) != NULL) vl->parent->type = LINE_COMPL; - vl = TAILQ_LAST(&buffer->head, vhead); + vl = TAILQ_LAST(&buffer->vhead, vhead); while (vl != NULL && vl->parent->flags & L_HIDDEN) vl = TAILQ_PREV(vl, vhead, vlines); blob - e633b929ad6e16c34ee3eda17e47d03f3da9cc3f blob + 53d379ca74bbfe2e453391a5dd382022d6ab084d --- compl.c +++ compl.c @@ -78,10 +78,10 @@ compl_ts(void **data, void **ret, const char **descr) *ret = *tab; - if (*(*tab)->buffer.page.title == '\0') + if (*(*tab)->buffer.title == '\0') return hist_cur((*tab)->hist); *descr = hist_cur((*tab)->hist); - return (*tab)->buffer.page.title; + return (*tab)->buffer.title; } /* blob - c69b5a51e53b5caab522d14dd23fec51f52e4d29 blob + d170814554742461eb57783379f97b67f08ea61c --- downloads.c +++ downloads.c @@ -36,7 +36,7 @@ no_downloads(void) l->type = LINE_DOWNLOAD_INFO; l->line = strdup("No downloads"); - TAILQ_INSERT_TAIL(&downloadwin.page.head, l, lines); + TAILQ_INSERT_TAIL(&downloadwin.head, l, lines); } void @@ -46,7 +46,7 @@ recompute_downloads(void) struct line *l; char buf[FMT_SCALED_STRSIZE]; - downloadwin.page.name = "*Downloads*"; + downloadwin.mode = "*Downloads*"; erase_buffer(&downloadwin); if (STAILQ_EMPTY(&downloads)) { @@ -67,7 +67,7 @@ recompute_downloads(void) l->line = strdup(buf); l->alt = strdup(d->path); - TAILQ_INSERT_TAIL(&downloadwin.page.head, l, lines); + TAILQ_INSERT_TAIL(&downloadwin.head, l, lines); } end: blob - 49e10ea66c67584f7e03967da8788545e4f98cf4 blob + 4c0614a1bd8fd277ba066453c872da3d66032d9f --- fs.c +++ fs.c @@ -34,6 +34,7 @@ #include "pages.h" #include "parser.h" +#include "telescope.h" #include "session.h" #include "utils.h" @@ -86,6 +87,7 @@ select_non_dotdot(const struct dirent *d) static void send_dir(struct tab *tab, const char *path) { + struct buffer *buffer = &tab->buffer; struct dirent **names; int (*selector)(const struct dirent *) = select_non_dot; int i, len; @@ -112,8 +114,8 @@ send_dir(struct tab *tab, const char *path) return; } - parser_init(tab, gemtext_initparser); - parser_parsef(tab, "# Index of %s\n\n", path); + parser_init(buffer, &gemtext_parser); + parser_parsef(buffer, "# Index of %s\n\n", path); for (i = 0; i < len; ++i) { const char *sufx = ""; @@ -121,7 +123,7 @@ send_dir(struct tab *tab, const char *path) if (names[i]->d_type == DT_DIR) sufx = "/"; - parser_parsef(tab, "=> %s%s\n", names[i]->d_name, sufx); + parser_parsef(buffer, "=> %s%s\n", names[i]->d_name, sufx); } parser_free(tab); @@ -139,40 +141,40 @@ is_dir(FILE *fp) return S_ISDIR(sb.st_mode); } -static parserinit +static struct parser * file_type(const char *path) { const struct mapping { const char *ext; - parserinit fn; + struct parser *parser; } ms[] = { - {"diff", textpatch_initparser}, - {"gemini", gemtext_initparser}, - {"gmi", gemtext_initparser}, - {"markdown", textplain_initparser}, - {"md", textplain_initparser}, - {"patch", gemtext_initparser}, + {"diff", &textpatch_parser}, + {"gemini", &gemtext_parser}, + {"gmi", &gemtext_parser}, + {"markdown", &textplain_parser}, + {"md", &textplain_parser}, + {"patch", &gemtext_parser}, {NULL, NULL}, }, *m; const char *dot; if ((dot = strrchr(path, '.')) == NULL) - return textplain_initparser; + return &textplain_parser; dot++; for (m = ms; m->ext != NULL; ++m) if (!strcmp(m->ext, dot)) - return m->fn; + return m->parser; - return textplain_initparser; + return &textplain_parser; } void fs_load_url(struct tab *tab, const char *url) { const char *bpath = "bookmarks.gmi", *fallback = "# Not found\n"; - parserinit initfn = gemtext_initparser; + struct parser *parser = &gemtext_parser; char path[PATH_MAX]; FILE *fp = NULL; size_t i; @@ -216,7 +218,7 @@ fs_load_url(struct tab *tab, const char *url) } else if (!strncmp(url, "file://", 7)) { url += 7; strlcpy(path, url, sizeof(path)); - initfn = file_type(url); + parser = file_type(url); } else goto done; @@ -228,12 +230,12 @@ fs_load_url(struct tab *tab, const char *url) goto done; } - parser_init(tab, initfn); + parser_init(&tab->buffer, parser); for (;;) { size_t r; r = fread(buf, 1, sizeof(buf), fp); - if (!parser_parse(tab, buf, r)) + if (!parser_parse(&tab->buffer, buf, r)) break; if (r != sizeof(buf)) break; blob - aeb2fefa2abf58316b2f596b006349b1cbee2348 blob + 2d4a687fef96e329ef2414b0400715e5126f2124 --- help.c +++ help.c @@ -48,7 +48,7 @@ emit_help_item(char *prfx, interactivefn *fn) l->line = strdup(prfx); l->alt = (char*)cmd->cmd; - TAILQ_INSERT_TAIL(&helpwin.page.head, l, lines); + TAILQ_INSERT_TAIL(&helpwin.head, l, lines); } static void @@ -85,7 +85,7 @@ recompute_help(void) if (last_active_map != current_map) { last_active_map = current_map; - helpwin.page.name = "*Help*"; + helpwin.mode = "*Help*"; erase_buffer(&helpwin); rec_compute_help(current_map, p, sizeof(p)); wrap_page(&helpwin, help_cols); blob - 234fc31e30c9c0ee56f9ef045acdb1fbe2370a72 blob + b5766b6d317771d45938c3ce5e19da15a27d85e8 --- identity.c +++ identity.c @@ -80,9 +80,7 @@ size_t about_new_len; const uint8_t *bookmarks; size_t bookmarks_len; -void gemtext_initparser(struct parser *p) { return; } -void textpatch_initparser(struct parser *p) { return; } -void textplain_initparser(struct parser *p) { return; } +struct parser gemtext_parser, textplain_parser, textpatch_parser; void load_page_from_str(struct tab *tab, const char *page) { return; } void erase_buffer(struct buffer *buffer) { return; } blob - addfa81f152e57db2d8304edca08ee25bc157475 blob + b2a57a944ecc6774de923e03763976a4318f740a --- mcache.c +++ mcache.c @@ -27,6 +27,7 @@ #include "hist.h" #include "mcache.h" #include "parser.h" +#include "telescope.h" #include "utils.h" static struct timeval tv = { 5 * 60, 0 }; @@ -38,7 +39,7 @@ static size_t tot; struct mcache_entry { time_t ts; - parserfn parser; + struct parser *parser; int trust; char *buf; size_t buflen; @@ -108,14 +109,14 @@ mcache_tab(struct tab *tab) if ((e = calloc(1, len)) == NULL) return -1; e->ts = time(NULL); - e->parser = tab->buffer.page.init; + e->parser = tab->buffer.parser; e->trust = tab->trust; memcpy(e->url, url, l); if ((fp = open_memstream(&e->buf, &e->buflen)) == NULL) goto err; - if (!parser_serialize(tab, fp)) + if (!parser_serialize(&tab->buffer, fp)) goto err; fclose(fp); @@ -153,8 +154,8 @@ mcache_lookup(const char *url, struct tab *tab) if ((e = ohash_find(&h, slot)) == NULL) return 0; - parser_init(tab, e->parser); - if (!parser_parse(tab, e->buf, e->buflen)) + parser_init(&tab->buffer, e->parser); + if (!parser_parse(&tab->buffer, e->buf, e->buflen)) goto err; if (!parser_free(tab)) goto err; blob - 98f614c6fa5c2ffd1edf1aff9c30a7e17816b9cc blob + 39bb0be8f2462d3078a206abc9626949573f966c --- mime.c +++ mime.c @@ -28,13 +28,13 @@ static int check_for_utf8(char*); static const struct parser_table { const char *mediatype; - void (*parserinit)(struct parser*); + struct parser *parser; } ptable[] = { - { "text/gemini", gemtext_initparser }, - { "text/x-patch", textpatch_initparser }, - { "text/x-diff", textpatch_initparser }, - { "application/x-patch",textpatch_initparser }, - { "text/*", textplain_initparser }, + { "text/gemini", &gemtext_parser }, + { "text/x-patch", &textpatch_parser }, + { "text/x-diff", &textpatch_parser }, + { "application/x-patch",&textpatch_parser }, + { "text/*", &textplain_parser }, { NULL, NULL} }; @@ -86,7 +86,7 @@ setup_parser_for(struct tab *tab) for (t = ptable; t->mediatype != NULL; ++t) { if (!fnmatch(t->mediatype, buf, 0)) { - parser_init(tab, t->parserinit); + parser_init(&tab->buffer, t->parser); return 1; } } blob - b4fbe8a2f8d2663be3688240e15f9aa32568198c blob + f830947eb8c2e60bd29e8fc8f7c293b003fc7d30 --- minibuffer.c +++ minibuffer.c @@ -135,7 +135,7 @@ recompute_completions(int add) } b = &ministate.compl.buffer; - TAILQ_FOREACH(l, &b->page.head, lines) { + TAILQ_FOREACH(l, &b->head, lines) { l->type = LINE_COMPL; if (add && l->flags & L_HIDDEN) continue; @@ -151,7 +151,7 @@ recompute_completions(int add) } if (b->current_line == NULL) - b->current_line = TAILQ_FIRST(&b->head); + b->current_line = TAILQ_FIRST(&b->vhead); b->current_line = adjust_line(b->current_line, b); vl = b->current_line; if (ministate.compl.must_select && vl != NULL) @@ -403,7 +403,7 @@ jump_to_line(struct line *l) buffer = current_buffer(); - TAILQ_FOREACH(vl, &buffer->head, vlines) { + TAILQ_FOREACH(vl, &buffer->vhead, vlines) { if (vl->parent == l) break; } @@ -538,11 +538,9 @@ populate_compl_buffer(complfn *fn, void *data) const char *s, *descr; struct line *l; struct buffer *b; - struct parser *p; void *linedata; b = &ministate.compl.buffer; - p = &b->page; linedata = NULL; descr = NULL; @@ -556,13 +554,13 @@ populate_compl_buffer(complfn *fn, void *data) if ((l->line = strdup(s)) == NULL) abort(); - TAILQ_INSERT_TAIL(&p->head, l, lines); + TAILQ_INSERT_TAIL(&b->head, l, lines); linedata = NULL; descr = NULL; } - if ((l = TAILQ_FIRST(&p->head)) != NULL && + if ((l = TAILQ_FIRST(&b->head)) != NULL && ministate.compl.must_select) l->type = LINE_COMPL_CURRENT; } @@ -700,10 +698,10 @@ minibuffer_init(void) err(1, "hist_new"); TAILQ_INIT(&ministate.compl.buffer.head); - TAILQ_INIT(&ministate.compl.buffer.page.head); + TAILQ_INIT(&ministate.compl.buffer.vhead); ministate.line.type = LINE_TEXT; ministate.vline.parent = &ministate.line; - ministate.buffer.page.name = "*minibuffer*"; + ministate.buffer.mode = "*minibuffer*"; ministate.buffer.current_line = &ministate.vline; } blob - e1168776b481988b2b0c066f6cdbc6ce837932ff blob + 1bd28ce6270695d16e124b303c635ab3451f683a --- parser.c +++ parser.c @@ -23,28 +23,31 @@ #include "parser.h" #include "telescope.h" -static int parser_foreach_line(struct parser *, const char *, size_t); +static int parser_foreach_line(struct buffer *, const char *, size_t); void -parser_init(struct tab *tab, parserfn fn) +parser_init(struct buffer *buffer, struct parser *p) { - erase_buffer(&tab->buffer); - fn(&tab->buffer.page); - tab->buffer.page.init = fn; + erase_buffer(buffer); + + memset(buffer->title, 0, sizeof(buffer->title)); + buffer->parser = p; + buffer->mode = p->name; + buffer->parser_flags = p->initflags; } int -parser_parse(struct tab *tab, const char *chunk, size_t len) +parser_parse(struct buffer *buffer, const char *chunk, size_t len) { - struct parser *p = &tab->buffer.page; + struct parser *p = buffer->parser; if (p->parse) - return p->parse(p, chunk, len); - return parser_foreach_line(p, chunk, len); + return p->parse(buffer, chunk, len); + return parser_foreach_line(buffer, chunk, len); } int -parser_parsef(struct tab *tab, const char *fmt, ...) +parser_parsef(struct buffer *buffer, const char *fmt, ...) { char *s; va_list ap; @@ -57,7 +60,7 @@ parser_parsef(struct tab *tab, const char *fmt, ...) if (r == -1) return 0; - r = parser_parse(tab, s, strlen(s)); + r = parser_parse(buffer, s, strlen(s)); free(s); return r; } @@ -65,24 +68,26 @@ parser_parsef(struct tab *tab, const char *fmt, ...) int parser_free(struct tab *tab) { - struct parser *p = &tab->buffer.page; - int r = 1; - char *tilde, *slash; + struct buffer *buffer = &tab->buffer; + struct parser *p = buffer->parser; + int r = 1; + char *tilde, *slash; if (p->free) { - r = p->free(p); - } else if (p->len != 0) { + r = p->free(buffer); + } else if (buffer->len != 0) { if (p->parse) - r = p->parse(p, p->buf, p->len); + r = p->parse(buffer, buffer->buf, buffer->len); else - r = parser_foreach_line(p, p->buf, p->len); + r = parser_foreach_line(buffer, buffer->buf, + buffer->len); } - free(p->buf); - p->buf = NULL; - p->len = 0; + free(buffer->buf); + buffer->buf = NULL; + buffer->len = 0; - if (*p->title != '\0') + if (*buffer->title != '\0') return r; /* @@ -90,28 +95,30 @@ parser_free(struct tab *tab) * page title, using the full domain name as fallback. */ if ((tilde = strstr(hist_cur(tab->hist), "/~")) != NULL) { - strlcpy(p->title, tilde+1, sizeof(p->title)); + strlcpy(buffer->title, tilde+1, sizeof(buffer->title)); - if ((slash = strchr(p->title, '/')) != NULL) + if ((slash = strchr(buffer->title, '/')) != NULL) *slash = '\0'; } else - strlcpy(p->title, tab->iri.iri_host, sizeof(p->title)); + strlcpy(buffer->title, tab->iri.iri_host, + sizeof(buffer->title)); return r; } int -parser_serialize(struct tab *tab, FILE *fp) +parser_serialize(struct buffer *b, FILE *fp) { + struct parser *p = b->parser; struct line *line; const char *text; int r; - if (tab->buffer.page.serialize != NULL) - return tab->buffer.page.serialize(&tab->buffer.page, fp); + if (p->serialize != NULL) + return p->serialize(b, fp); /* a default implementation good enough for plain text */ - TAILQ_FOREACH(line, &tab->buffer.page.head, lines) { + TAILQ_FOREACH(line, &b->head, lines) { if ((text = line->line) == NULL) text = ""; @@ -124,31 +131,31 @@ parser_serialize(struct tab *tab, FILE *fp) } int -parser_append(struct parser *p, const char *buf, size_t len) +parser_append(struct buffer *b, const char *buf, size_t len) { size_t newlen; char *t; - newlen = len + p->len; + newlen = len + b->len; if ((t = calloc(1, newlen)) == NULL) return 0; - memcpy(t, p->buf, p->len); - memcpy(t + p->len, buf, len); - free(p->buf); - p->buf = t; - p->len = newlen; + memcpy(t, b->buf, b->len); + memcpy(t + b->len, buf, len); + free(b->buf); + b->buf = t; + b->len = newlen; return 1; } int -parser_set_buf(struct parser *p, const char *buf, size_t len) +parser_set_buf(struct buffer *b, const char *buf, size_t len) { char *tmp; if (len == 0) { - p->len = 0; - free(p->buf); - p->buf = NULL; + b->len = 0; + free(b->buf); + b->buf = NULL; return 1; } @@ -160,36 +167,37 @@ parser_set_buf(struct parser *p, const char *buf, size if ((tmp = calloc(1, len)) == NULL) return 0; memcpy(tmp, buf, len); - free(p->buf); - p->buf = tmp; - p->len = len; + free(b->buf); + b->buf = tmp; + b->len = len; return 1; } static int -parser_foreach_line(struct parser *p, const char *buf, size_t size) +parser_foreach_line(struct buffer *b, const char *buf, size_t size) { - char *b, *e; + struct parser *p = b->parser; + char *beg, *end; unsigned int ch; size_t i, l, len; - if (!parser_append(p, buf, size)) + if (!parser_append(b, buf, size)) return 0; - b = p->buf; - len = p->len; + beg = b->buf; + len = b->len; - if (!(p->flags & PARSER_IN_BODY) && len < 3) + if (!(b->parser_flags & PARSER_IN_BODY) && len < 3) return 1; - if (!(p->flags & PARSER_IN_BODY)) { - p->flags |= PARSER_IN_BODY; + if (!(b->parser_flags & PARSER_IN_BODY)) { + b->parser_flags |= PARSER_IN_BODY; /* * drop the BOM: only UTF-8 is supported, and there * it's useless; some editors may still add one * though. */ - if (memmem(b, len, "\xEF\xBB\xBF", 3) == b) { + if (memmem(beg, len, "\xEF\xBB\xBF", 3) == beg) { b += 3; len -= 3; } @@ -197,33 +205,33 @@ parser_foreach_line(struct parser *p, const char *buf, /* drop every "funny" ASCII character */ for (i = 0; i < len; ) { - ch = b[i]; + ch = beg[i]; if ((ch >= ' ' || ch == '\n' || ch == '\t') && ch != 127) { /* del */ ++i; continue; } - memmove(&b[i], &b[i+1], len - i - 1); + memmove(&beg[i], &beg[i+1], len - i - 1); len--; } while (len > 0) { - if ((e = memmem((char*)b, len, "\n", 1)) == NULL) + if ((end = memmem((char*)beg, len, "\n", 1)) == NULL) break; - l = e - b; + l = end - beg; - if (!p->parseline(p, b, l)) + if (!p->parseline(b, beg, l)) return 0; len -= l; - b += l; + beg += l; if (len > 0) { /* skip \n */ len--; - b++; + beg++; } } - return parser_set_buf(p, b, len); + return parser_set_buf(b, beg, len); } blob - 9ee54b926e3370f157ddf1558fcbb2a2466cf902 blob + 0eac68fabed364415954fc82b90e8e820833e5bc --- parser.h +++ parser.h @@ -17,29 +17,31 @@ #ifndef PARSER_H #define PARSER_H -#include "telescope.h" +struct buffer; +struct tab; -typedef void (*parserfn)(struct parser *); +struct parser { + const char *name; + int initflags; -void parser_init(struct tab *, parserfn); -int parser_parse(struct tab *, const char *, size_t); -int parser_parsef(struct tab *, const char *, ...); + int (*parse)(struct buffer *, const char *, size_t); + int (*parseline)(struct buffer *, const char *, size_t); + int (*free)(struct buffer *); + int (*serialize)(struct buffer *, FILE *); +}; + +void parser_init(struct buffer *, struct parser *); +int parser_parse(struct buffer *, const char *, size_t); +int parser_parsef(struct buffer *, const char *, ...); int parser_free(struct tab *); -int parser_serialize(struct tab *, FILE *); +int parser_serialize(struct buffer *, FILE *); -int parser_append(struct parser*, const char*, size_t); -int parser_set_buf(struct parser*, const char*, size_t); +int parser_append(struct buffer *, const char *, size_t); +int parser_set_buf(struct buffer *, const char *, size_t); -/* parser_gemtext.c */ -void gemtext_initparser(struct parser*); +extern struct parser gemtext_parser; +extern struct parser gophermap_parser; +extern struct parser textpatch_parser; +extern struct parser textplain_parser; -/* parser_gophermap.c */ -void gophermap_initparser(struct parser *); - -/* parser_textpatch.c */ -void textpatch_initparser(struct parser *); - -/* parser_textplain.c */ -void textplain_initparser(struct parser*); - #endif blob - fe0e0dc3043977dba823f5063f72446d3e0c3a95 blob + ccab1ade5afda346a97b60e0408826b0cfd29088 --- parser_gemtext.c +++ parser_gemtext.c @@ -30,31 +30,26 @@ #include "defaults.h" #include "parser.h" +#include "telescope.h" #include "utf8.h" -static int gemtext_parse_line(struct parser *, const char *, size_t); -static int gemtext_free(struct parser *); -static int gemtext_serialize(struct parser *, FILE *); +static int gemtext_parse_line(struct buffer *, const char *, size_t); +static int gemtext_free(struct buffer *); +static int gemtext_serialize(struct buffer *, FILE *); -static int parse_link(struct parser *, const char*, size_t); -static int parse_title(struct parser *, const char*, size_t); -static void search_title(struct parser *, enum line_type); +static int parse_link(struct buffer *, const char*, size_t); +static int parse_title(struct buffer *, const char*, size_t); +static void search_title(struct buffer *, enum line_type); -void -gemtext_initparser(struct parser *p) -{ - memset(p, 0, sizeof(*p)); +struct parser gemtext_parser = { + .name = "text/gemini", + .parseline = &gemtext_parse_line, + .free = &gemtext_free, + .serialize = &gemtext_serialize, +}; - p->name = "text/gemini"; - p->parseline = &gemtext_parse_line; - p->free = &gemtext_free; - p->serialize = &gemtext_serialize; - - TAILQ_INIT(&p->head); -} - static inline int -emit_line(struct parser *p, enum line_type type, char *line, char *alt) +emit_line(struct buffer *b, enum line_type type, char *line, char *alt) { struct line *l; @@ -90,26 +85,26 @@ emit_line(struct parser *p, enum line_type type, char if (dont_apply_styling) l->flags &= ~L_HIDDEN; - TAILQ_INSERT_TAIL(&p->head, l, lines); + TAILQ_INSERT_TAIL(&b->head, l, lines); return 1; } static int -parse_link(struct parser *p, const char *line, size_t len) +parse_link(struct buffer *b, const char *line, size_t len) { char *label, *url; const char *start; if (len <= 2) - return emit_line(p, LINE_TEXT, NULL, NULL); + return emit_line(b, LINE_TEXT, NULL, NULL); line += 2, len -= 2; while (len > 0 && isspace((unsigned char)line[0])) line++, len--; if (len == 0) - return emit_line(p, LINE_TEXT, NULL, NULL); + return emit_line(b, LINE_TEXT, NULL, NULL); start = line; while (len > 0 && !isspace((unsigned char)line[0])) @@ -129,11 +124,11 @@ parse_link(struct parser *p, const char *line, size_t return 0; } - return emit_line(p, LINE_LINK, label, url); + return emit_line(b, LINE_LINK, label, url); } static int -parse_title(struct parser *p, const char *line, size_t len) +parse_title(struct buffer *b, const char *line, size_t len) { enum line_type t = LINE_TITLE_1; char *l; @@ -150,36 +145,36 @@ parse_title(struct parser *p, const char *line, size_t line++, len--; if (len == 0) - return emit_line(p, t, NULL, NULL); + return emit_line(b, t, NULL, NULL); - if (t == LINE_TITLE_1 && *p->title == '\0') - strncpy(p->title, line, MIN(sizeof(p->title)-1, len)); + if (t == LINE_TITLE_1 && *b->title == '\0') + strncpy(b->title, line, MIN(sizeof(b->title)-1, len)); if ((l = strndup(line, len)) == NULL) return 0; - return emit_line(p, t, l, NULL); + return emit_line(b, t, l, NULL); } static int -gemtext_parse_line(struct parser *p, const char *line, size_t len) +gemtext_parse_line(struct buffer *b, const char *line, size_t len) { char *l; - if (p->flags & PARSER_IN_PRE) { + if (b->parser_flags & PARSER_IN_PRE) { if (len >= 3 && !strncmp(line, "```", 3)) { - p->flags ^= PARSER_IN_PRE; - return emit_line(p, LINE_PRE_END, NULL, NULL); + b->parser_flags ^= PARSER_IN_PRE; + return emit_line(b, LINE_PRE_END, NULL, NULL); } if (len == 0) - return emit_line(p, LINE_PRE_CONTENT, NULL, NULL); + return emit_line(b, LINE_PRE_CONTENT, NULL, NULL); if ((l = strndup(line, len)) == NULL) return 0; - return emit_line(p, LINE_PRE_CONTENT, l, NULL); + return emit_line(b, LINE_PRE_CONTENT, l, NULL); } if (len == 0) - return emit_line(p, LINE_TEXT, NULL, NULL); + return emit_line(b, LINE_TEXT, NULL, NULL); switch (*line) { case '*': @@ -190,59 +185,59 @@ gemtext_parse_line(struct parser *p, const char *line, while (len > 0 && isspace((unsigned char)*line)) line++, len--; if (len == 0) - return emit_line(p, LINE_ITEM, NULL, NULL); + return emit_line(b, LINE_ITEM, NULL, NULL); if ((l = strndup(line, len)) == NULL) return 0; - return emit_line(p, LINE_ITEM, l, NULL); + return emit_line(b, LINE_ITEM, l, NULL); case '>': line++, len--; while (len > 0 && isspace((unsigned char)*line)) line++, len--; if (len == 0) - return emit_line(p, LINE_QUOTE, NULL, NULL); + return emit_line(b, LINE_QUOTE, NULL, NULL); if ((l = strndup(line, len)) == NULL) return 0; - return emit_line(p, LINE_QUOTE, l, NULL); + return emit_line(b, LINE_QUOTE, l, NULL); case '=': if (len > 1 && line[1] == '>') - return parse_link(p, line, len); + return parse_link(b, line, len); break; case '#': - return parse_title(p, line, len); + return parse_title(b, line, len); case '`': if (len < 3 || strncmp(line, "```", 3) != 0) break; - p->flags |= PARSER_IN_PRE; + b->parser_flags |= PARSER_IN_PRE; line += 3, len -= 3; while (len > 0 && isspace((unsigned char)*line)) line++, len--; if (len == 0) - return emit_line(p, LINE_PRE_START, + return emit_line(b, LINE_PRE_START, NULL, NULL); if ((l = strndup(line, len)) == NULL) return 0; - return emit_line(p, LINE_PRE_START, l, NULL); + return emit_line(b, LINE_PRE_START, l, NULL); } if ((l = strndup(line, len)) == NULL) return 0; - return emit_line(p, LINE_TEXT, l, NULL); + return emit_line(b, LINE_TEXT, l, NULL); } static int -gemtext_free(struct parser *p) +gemtext_free(struct buffer *b) { /* flush the buffer */ - if (p->len != 0) { - if (!gemtext_parse_line(p, p->buf, p->len)) + if (b->len != 0) { + if (!gemtext_parse_line(b, b->buf, b->len)) return 0; - if ((p->flags & PARSER_IN_PRE) && - !emit_line(p, LINE_PRE_END, NULL, NULL)) + if ((b->parser_flags & PARSER_IN_PRE) && + !emit_line(b, LINE_PRE_END, NULL, NULL)) return 0; } @@ -250,24 +245,24 @@ gemtext_free(struct parser *p) * use the first level 2 or 3 header as page title if none * found yet. */ - if (*p->title == '\0') - search_title(p, LINE_TITLE_2); - if (*p->title == '\0') - search_title(p, LINE_TITLE_3); + if (*b->title == '\0') + search_title(b, LINE_TITLE_2); + if (*b->title == '\0') + search_title(b, LINE_TITLE_3); return 1; } static void -search_title(struct parser *p, enum line_type level) +search_title(struct buffer *b, enum line_type level) { struct line *l; - TAILQ_FOREACH(l, &p->head, lines) { + TAILQ_FOREACH(l, &b->head, lines) { if (l->type == level) { if (l->line == NULL) continue; - strlcpy(p->title, l->line, sizeof(p->title)); + strlcpy(b->title, l->line, sizeof(b->title)); break; } } @@ -286,14 +281,14 @@ static const char *gemtext_prefixes[] = { }; static int -gemtext_serialize(struct parser *p, FILE *fp) +gemtext_serialize(struct buffer *b, FILE *fp) { struct line *line; const char *text; const char *alt; int r; - TAILQ_FOREACH(line, &p->head, lines) { + TAILQ_FOREACH(line, &b->head, lines) { if ((text = line->line) == NULL) text = ""; blob - 6e951cadd8be59d8108eb6c9052b287e250ad451 blob + 8c9d0ec372c899409d2ce5a72c7d19c84e3deda0 --- parser_gophermap.c +++ parser_gophermap.c @@ -20,8 +20,9 @@ #include #include -#include "parser.h" #include "iri.h" +#include "parser.h" +#include "telescope.h" #include "utils.h" #ifndef LINE_MAX @@ -38,20 +39,14 @@ struct gm_selector { static void gm_parse_selector(char *, struct gm_selector *); -static int gm_parse_line(struct parser *, const char *, size_t); -static int gm_serialize(struct parser *, FILE *); +static int gm_parse_line(struct buffer *, const char *, size_t); +static int gm_serialize(struct buffer *, FILE *); -void -gophermap_initparser(struct parser *p) -{ - memset(p, 0, sizeof(*p)); - - p->name = "gophermap"; - p->parseline = &gm_parse_line; - p->serialize = &gm_serialize; - - TAILQ_INIT(&p->head); -} +struct parser gophermap_parser = { + .name = "gophermap", + .parseline = &gm_parse_line, + .serialize = &gm_serialize, +}; static void gm_parse_selector(char *line, struct gm_selector *s) @@ -94,7 +89,7 @@ selector2uri(struct gm_selector *s, char *buf, size_t } static inline int -emit_line(struct parser *p, enum line_type type, struct gm_selector *s) +emit_line(struct buffer *b, enum line_type type, struct gm_selector *s) { struct line *l; char buf[LINE_MAX]; @@ -120,7 +115,7 @@ emit_line(struct parser *p, enum line_type type, struc break; } - TAILQ_INSERT_TAIL(&p->head, l, lines); + TAILQ_INSERT_TAIL(&b->head, l, lines); return 1; @@ -134,7 +129,7 @@ err: } static int -gm_parse_line(struct parser *p, const char *line, size_t linelen) +gm_parse_line(struct buffer *b, const char *line, size_t linelen) { char buf[LINE_MAX] = {0}; struct gm_selector s = {0}; @@ -161,17 +156,17 @@ gm_parse_line(struct parser *p, const char *line, size case 'd': /* non-canonical: doc */ case 'h': /* non-canonical: html file */ case 's': /* non-canonical: sound file */ - if (!emit_line(p, LINE_LINK, &s)) + if (!emit_line(b, LINE_LINK, &s)) return 0; break; case 'i': /* non-canonical: message */ - if (!emit_line(p, LINE_TEXT, &s)) + if (!emit_line(b, LINE_TEXT, &s)) return 0; break; case '3': /* error code */ - if (!emit_line(p, LINE_QUOTE, &s)) + if (!emit_line(b, LINE_QUOTE, &s)) return 0; break; } @@ -254,13 +249,13 @@ serialize_link(struct line *line, const char *text, FI } static int -gm_serialize(struct parser *p, FILE *fp) +gm_serialize(struct buffer *b, FILE *fp) { struct line *line; const char *text; int r; - TAILQ_FOREACH(line, &p->head, lines) { + TAILQ_FOREACH(line, &b->head, lines) { if ((text = line->line) == NULL) text = ""; blob - 509eb9750e8073134721617555126699eb403f64 blob + 677a8d446f05d855f392f515d096d910a10a3d9e --- parser_textpatch.c +++ parser_textpatch.c @@ -24,33 +24,27 @@ #include #include "parser.h" +#include "telescope.h" #include "utils.h" -static int tpatch_emit_line(struct parser *, const char *, size_t); -static int tpatch_parse_line(struct parser *, const char *, size_t); +static int tpatch_emit_line(struct buffer *, const char *, size_t); +static int tpatch_parse_line(struct buffer *, const char *, size_t); -void -textpatch_initparser(struct parser *p) -{ - memset(p, 0, sizeof(*p)); +struct parser textpatch_parser = { + .name = "text/x-patch", + .parseline = &tpatch_parse_line, + .initflags = PARSER_IN_PATCH_HDR, +}; - p->name = "text/x-patch"; - p->parseline = &tpatch_parse_line; - - p->flags = PARSER_IN_PATCH_HDR; - - TAILQ_INIT(&p->head); -} - static int -tpatch_emit_line(struct parser *p, const char *line, size_t linelen) +tpatch_emit_line(struct buffer *b, const char *line, size_t linelen) { struct line *l; if ((l = calloc(1, sizeof(*l))) == NULL) return 0; - if (p->flags & PARSER_IN_PATCH_HDR) + if (b->parser_flags & PARSER_IN_PATCH_HDR) l->type = LINE_PATCH_HDR; else l->type = LINE_PATCH; @@ -63,7 +57,7 @@ tpatch_emit_line(struct parser *p, const char *line, s memcpy(l->line, line, linelen); - if (!(p->flags & PARSER_IN_PATCH_HDR)) + if (!(b->parser_flags & PARSER_IN_PATCH_HDR)) switch (*l->line) { case '+': l->type = LINE_PATCH_ADD; @@ -84,21 +78,21 @@ tpatch_emit_line(struct parser *p, const char *line, s * than one file. */ l->type = LINE_PATCH_HDR; - p->flags |= PARSER_IN_PATCH_HDR; + b->parser_flags |= PARSER_IN_PATCH_HDR; break; } if (!strncmp(l->line, "+++", 3)) - p->flags &= ~PARSER_IN_PATCH_HDR; + b->parser_flags &= ~PARSER_IN_PATCH_HDR; } - TAILQ_INSERT_TAIL(&p->head, l, lines); + TAILQ_INSERT_TAIL(&b->head, l, lines); return 1; } static int -tpatch_parse_line(struct parser *p, const char *line, size_t linelen) +tpatch_parse_line(struct buffer *b, const char *line, size_t linelen) { - return tpatch_emit_line(p, line, linelen); + return tpatch_emit_line(b, line, linelen); } blob - 5158068417703854a2dd0fd02b72d9aa20717937 blob + c516f4a24a997ad28535976e391732f755b652e1 --- parser_textplain.c +++ parser_textplain.c @@ -24,11 +24,17 @@ #include #include "parser.h" +#include "telescope.h" -static int textplain_parse_line(struct parser*, const char*, size_t); +static int textplain_parse_line(struct buffer *, const char *, size_t); +struct parser textplain_parser = { + .name = "text/plain", + .parseline = &textplain_parse_line, +}; + static inline int -emit_line(struct parser *p, const char *line, size_t len) +emit_line(struct buffer *b, const char *line, size_t len) { struct line *l; @@ -46,24 +52,13 @@ emit_line(struct parser *p, const char *line, size_t l memcpy(l->line, line, len); } - TAILQ_INSERT_TAIL(&p->head, l, lines); + TAILQ_INSERT_TAIL(&b->head, l, lines); return 1; } -void -textplain_initparser(struct parser *p) -{ - memset(p, 0, sizeof(*p)); - - p->name = "text/plain"; - p->parseline = &textplain_parse_line; - - TAILQ_INIT(&p->head); -} - static int -textplain_parse_line(struct parser *p, const char *line, size_t linelen) +textplain_parse_line(struct buffer *b, const char *line, size_t linelen) { - return emit_line(p, line, linelen); + return emit_line(b, line, linelen); } blob - 65d38ce297b8bf1f42564a8d08e53b3b33d3bd9c blob + bed2d3e5578f38695e8bf6c97905898e363d76b5 --- session.c +++ session.c @@ -80,7 +80,7 @@ new_tab(const char *url, const char *base, struct tab } TAILQ_INIT(&tab->buffer.head); - TAILQ_INIT(&tab->buffer.page.head); + TAILQ_INIT(&tab->buffer.vhead); tab->id = tab_new_id(); @@ -187,7 +187,7 @@ savetab(FILE *fp, struct tab *tab, int killed) fprintf(fp, "killed,"); fprintf(fp, "top=%zu,cur=%zu %s\n", top_line, current_line, - tab->buffer.page.title); + tab->buffer.title); cur = hist_off(tab->hist); size = hist_size(tab->hist); @@ -598,7 +598,7 @@ parse_tab_line(char *line, struct tab **ct) if ((tab = new_tab(uri, NULL, NULL)) == NULL) err(1, "new_tab"); hist_set_offs(tab->hist, tline, cline); - strlcpy(tab->buffer.page.title, title, sizeof(tab->buffer.page.title)); + strlcpy(tab->buffer.title, title, sizeof(tab->buffer.title)); if (current) *ct = tab; blob - f09c9ded06f3ae03d9b9b7d6b0c8d2e27a05511f blob + 317fa406cdd33452a6af50f2b4406942791fffcb --- telescope.c +++ telescope.c @@ -45,6 +45,7 @@ #include "mcache.h" #include "minibuffer.h" #include "parser.h" +#include "parser.h" #include "session.h" #include "telescope.h" #include "tofu.h" @@ -506,7 +507,7 @@ handle_dispatch_imsg(int fd, int event, void *data) return; if (tab) { - if (!parser_parse(tab, imsg.data, + if (!parser_parse(&tab->buffer, imsg.data, imsg_get_len(&imsg))) die(); ui_on_tab_refresh(tab); @@ -614,7 +615,7 @@ load_finger_url(struct tab *tab, const char *url) } strlcat(req.req, "\r\n", sizeof(req.req)); - parser_init(tab, textplain_initparser); + parser_init(&tab->buffer, &textplain_parser); make_request(tab, &req, PROTO_FINGER, NULL); } @@ -673,10 +674,10 @@ load_gopher_url(struct tab *tab, const char *url) path = gopher_skip_selector(tab->iri.iri_path, &type); switch (type) { case '0': - parser_init(tab, textplain_initparser); + parser_init(&tab->buffer, &textplain_parser); break; case '1': - parser_init(tab, gophermap_initparser); + parser_init(&tab->buffer, &gophermap_parser); break; case '7': free(tab->last_input_url); @@ -769,7 +770,7 @@ gopher_send_search_req(struct tab *tab, const char *te strlcat(req.req, "\r\n", sizeof(req.req)); erase_buffer(&tab->buffer); - parser_init(tab, gophermap_initparser); + parser_init(&tab->buffer, &gophermap_parser); make_request(tab, &req, PROTO_GOPHER, NULL); } @@ -777,8 +778,8 @@ gopher_send_search_req(struct tab *tab, const char *te void load_page_from_str(struct tab *tab, const char *page) { - parser_init(tab, gemtext_initparser); - if (!parser_parse(tab, page, strlen(page))) + parser_init(&tab->buffer, &gemtext_parser); + if (!parser_parse(&tab->buffer, page, strlen(page))) abort(); if (!parser_free(tab)) abort(); @@ -867,8 +868,7 @@ load_url(struct tab *tab, const char *url, const char return; } - strlcpy(tab->buffer.page.title, url, - sizeof(tab->buffer.page.title)); + strlcpy(tab->buffer.title, url, sizeof(tab->buffer.title)); } if (!lazy) @@ -921,7 +921,7 @@ write_buffer(const char *path, struct tab *tab) if ((fp = fopen(path, "w")) == NULL) return; - if (!parser_serialize(tab, fp)) + if (!parser_serialize(&tab->buffer, fp)) message("Failed to save the page."); fclose(fp); } blob - 90515f65cd29ee80b8dfcf1cfc0f0989627a913b blob + d6f56be2990aa0037fc88e9091cdec9895b751aa --- telescope.h +++ telescope.h @@ -89,35 +89,6 @@ struct vline { TAILQ_ENTRY(vline) vlines; }; -struct parser; - -typedef void (*parserinit)(struct parser *); - -typedef int (*parsechunkfn)(struct parser *, const char *, size_t); -typedef int (*parselinefn)(struct parser *, const char *, size_t); -typedef int (*parserfreefn)(struct parser *); -typedef int (*parserserial)(struct parser *, FILE *); - -struct parser { - const char *name; - char title[128+1]; - char *buf; - size_t len; - size_t cap; - -#define PARSER_IN_BODY 1 -#define PARSER_IN_PRE 2 -#define PARSER_IN_PATCH_HDR 4 - int flags; - parserinit init; - parsechunkfn parse; - parselinefn parseline; - parserfreefn free; - parserserial serialize; - - TAILQ_HEAD(, line) head; -}; - /* * different types of trust for a certificate. Following * gemini://thfr.info/gemini/modified-trust-verify.gmi @@ -130,9 +101,21 @@ enum trust_state { TS_VERIFIED, }; +struct parser; + struct buffer { - struct parser page; + char title[128 + 1]; + const char *mode; + char *buf; + size_t len; + size_t cap; +#define PARSER_IN_BODY 1 +#define PARSER_IN_PRE 2 +#define PARSER_IN_PATCH_HDR 4 + int parser_flags; + struct parser *parser; + size_t last_line_off; int force_redraw; @@ -143,7 +126,9 @@ struct buffer { struct vline *top_line; struct vline *current_line; size_t cpoff; - TAILQ_HEAD(vhead, vline) head; + + TAILQ_HEAD(, line) head; + TAILQ_HEAD(vhead, vline) vhead; }; #define TAB_CURRENT 0x1 /* only for save_session */ blob - 96ee617abc23624ea778b3e78e9935c9e7375fe8 blob + 98f140024281b30cd2ab0085e907fc006b7be7ae --- ui.c +++ ui.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -144,8 +143,8 @@ set_scroll_position(struct tab *tab, size_t top, size_ size_t i = 0; int topfound = 0; - last = TAILQ_FIRST(&tab->buffer.page.head); - TAILQ_FOREACH(vl, &tab->buffer.head, vlines) { + last = TAILQ_FIRST(&tab->buffer.head); + TAILQ_FOREACH(vl, &tab->buffer.vhead, vlines) { if (last != vl->parent) { last = vl->parent; i++; @@ -163,7 +162,7 @@ set_scroll_position(struct tab *tab, size_t top, size_ } if (!topfound) - tab->buffer.top_line = TAILQ_FIRST(&tab->buffer.head); + tab->buffer.top_line = TAILQ_FIRST(&tab->buffer.vhead); tab->buffer.current_line = tab->buffer.top_line; } @@ -181,7 +180,7 @@ get_scroll_position(struct tab *tab, size_t *top, size tab->buffer.current_line == NULL) return; - TAILQ_FOREACH(l, &tab->buffer.page.head, lines) { + TAILQ_FOREACH(l, &tab->buffer.head, lines) { if (tab->buffer.top_line->parent == l) topfound = 1; if (tab->buffer.current_line->parent == l) @@ -226,7 +225,7 @@ restore_curs_x(struct buffer *buffer) lp = raw_prefixes; vl = buffer->current_line; - if (vl == NULL || vl->len == 0) + if (vl == NULL || vl->len == 0 || vl->parent == NULL) buffer->curs_x = buffer->cpoff = 0; else if (vl->parent->data != NULL) { text = vl->parent->data; @@ -661,7 +660,7 @@ redraw_tabline(void) current = tab == current_tab; - if (*(title = tab->buffer.page.title) == '\0') + if (*(title = tab->buffer.title) == '\0') title = hist_cur(tab->hist); if (tab->flags & TAB_URGENT) @@ -756,7 +755,7 @@ again: goto end; if (buffer->top_line == NULL) - buffer->top_line = TAILQ_FIRST(&buffer->head); + buffer->top_line = TAILQ_FIRST(&buffer->vhead); buffer->top_line = adjust_line(buffer->top_line, buffer); if (buffer->top_line == NULL) @@ -852,7 +851,7 @@ redraw_modeline(struct tab *tab) const char *spin = "-\\|/"; buffer = current_buffer(); - mode = buffer->page.name; + mode = buffer->mode; werase(modeline); wattr_on(modeline, modeline_face.background, NULL); @@ -1057,7 +1056,7 @@ redraw_tab(struct tab *tab) if (set_title) dprintf(1, "\033]2;%s - Telescope\a", - current_tab->buffer.page.title); + current_tab->buffer.title); } void @@ -1124,11 +1123,11 @@ ui_init(void) /* initialize download window */ TAILQ_INIT(&downloadwin.head); - TAILQ_INIT(&downloadwin.page.head); + TAILQ_INIT(&downloadwin.vhead); /* initialize help window */ TAILQ_INIT(&helpwin.head); - TAILQ_INIT(&helpwin.page.head); + TAILQ_INIT(&helpwin.vhead); base_map = &global_map; current_map = &global_map; @@ -1206,7 +1205,7 @@ ui_on_tab_loaded(struct tab *tab) hist_cur_offs(tab->hist, &line_off, &curr_off); if (curr_off != 0 && - tab->buffer.current_line == TAILQ_FIRST(&tab->buffer.head)) { + tab->buffer.current_line == TAILQ_FIRST(&tab->buffer.vhead)) { set_scroll_position(tab, line_off, curr_off); redraw_tab(tab); return; blob - d86351e71dc259ed782b0251ba92d069e6cc4f82 blob + 2a58e03514ae257ca15008d70eedece728b428c0 --- wrap.c +++ wrap.c @@ -39,8 +39,8 @@ empty_linelist(struct buffer *buffer) { struct line *l, *lt; - TAILQ_FOREACH_SAFE(l, &buffer->page.head, lines, lt) { - TAILQ_REMOVE(&buffer->page.head, l, lines); + TAILQ_FOREACH_SAFE(l, &buffer->head, lines, lt) { + TAILQ_REMOVE(&buffer->head, l, lines); free(l->line); if (l->type != LINE_COMPL && @@ -62,8 +62,8 @@ empty_vlist(struct buffer *buffer) buffer->current_line = NULL; buffer->line_max = 0; - TAILQ_FOREACH_SAFE(vl, &buffer->head, vlines, t) { - TAILQ_REMOVE(&buffer->head, vl, vlines); + TAILQ_FOREACH_SAFE(vl, &buffer->vhead, vlines, t) { + TAILQ_REMOVE(&buffer->vhead, vl, vlines); free(vl); } } @@ -96,7 +96,7 @@ push_line(struct buffer *buffer, struct line *l, const } vl->flags = flags; - TAILQ_INSERT_TAIL(&buffer->head, vl, vlines); + TAILQ_INSERT_TAIL(&buffer->vhead, vl, vlines); return 1; } @@ -174,7 +174,7 @@ wrap_page(struct buffer *buffer, int width) empty_vlist(buffer); - TAILQ_FOREACH(l, &buffer->page.head, lines) { + TAILQ_FOREACH(l, &buffer->head, lines) { prfx = line_prefixes[l->type].prfx1; switch (l->type) { case LINE_TEXT: @@ -210,7 +210,7 @@ wrap_page(struct buffer *buffer, int width) if (top_orig == l && buffer->top_line == NULL) { buffer->line_off = buffer->line_max-1; - buffer->top_line = TAILQ_LAST(&buffer->head, vhead); + buffer->top_line = TAILQ_LAST(&buffer->vhead, vhead); while (1) { vl = TAILQ_PREV(buffer->top_line, vhead, vlines); @@ -222,7 +222,7 @@ wrap_page(struct buffer *buffer, int width) } if (orig == l && buffer->current_line == NULL) { - buffer->current_line = TAILQ_LAST(&buffer->head, vhead); + buffer->current_line = TAILQ_LAST(&buffer->vhead, vhead); while (1) { vl = TAILQ_PREV(buffer->current_line, vhead, vlines); @@ -234,7 +234,7 @@ wrap_page(struct buffer *buffer, int width) } if (buffer->current_line == NULL) - buffer->current_line = TAILQ_FIRST(&buffer->head); + buffer->current_line = TAILQ_FIRST(&buffer->vhead); if (buffer->top_line == NULL) buffer->top_line = buffer->current_line;