commit 0fe9ac228cc8e9b9115a6b613ddbb87589335180 from: Omar Polo date: Mon Jun 03 11:15:54 2024 UTC parsers: add a parseline method all our parsers just need a line to parse and don't always need the free method. The gemtext parser could also be simplified with this, but defer it for later. commit - ef1a5eb9f7f71d8d27af99f0766c5d5d9dba62f2 commit + 0fe9ac228cc8e9b9115a6b613ddbb87589335180 blob - 792a676e94ed7fc9dbe717a6bbc97d808856896f blob + 4e45c652434cb4ffda798cc764d23dcb0fc2bf1d --- parser.c +++ parser.c @@ -34,7 +34,11 @@ parser_init(struct tab *tab, parserfn fn) int parser_parse(struct tab *tab, const char *chunk, size_t len) { - return tab->buffer.page.parse(&tab->buffer.page, chunk, len); + struct parser *p = &tab->buffer.page; + + if (p->parse) + return p->parse(p, chunk, len); + return parser_foreach_line(p, chunk, len, p->parseline); } int @@ -59,12 +63,21 @@ parser_parsef(struct tab *tab, const char *fmt, ...) int parser_free(struct tab *tab) { - int r; - char *tilde, *slash; + struct parser *p = &tab->buffer.page; + int r = 1; + char *tilde, *slash; - r = tab->buffer.page.free(&tab->buffer.page); + if (p->free) { + r = p->free(p); + } else if (p->len != 0) { + if (p->parse) + r = p->parse(p, p->buf, p->len); + else + r = parser_foreach_line(p, p->buf, p->len, + p->parseline); + } - if (*tab->buffer.page.title != '\0') + if (*p->title != '\0') return r; /* @@ -72,14 +85,12 @@ parser_free(struct tab *tab) * page title, using the full domain name as fallback. */ if ((tilde = strstr(hist_cur(tab->hist), "/~")) != NULL) { - strlcpy(tab->buffer.page.title, tilde+1, - sizeof(tab->buffer.page.title)); + strlcpy(p->title, tilde+1, sizeof(p->title)); - if ((slash = strchr(tab->buffer.page.title, '/')) != NULL) + if ((slash = strchr(p->title, '/')) != NULL) *slash = '\0'; } else - strlcpy(tab->buffer.page.title, tab->iri.iri_host, - sizeof(tab->buffer.page.title)); + strlcpy(p->title, tab->iri.iri_host, sizeof(p->title)); return r; } blob - b0d9ca3a298cb4d901692cd4e411de3f15072874 blob + bbec8913bcd5b600485f55b4caa29c553af7d851 --- parser_gemtext.c +++ parser_gemtext.c @@ -47,9 +47,9 @@ static int parse_pre_cnt(struct parser*, enum line_typ static int parse_pre_end(struct parser*, enum line_type, const char*, size_t); static void search_title(struct parser*, enum line_type); -typedef int (parselinefn)(struct parser*, enum line_type, const char*, size_t); +typedef int (plinefn)(struct parser*, enum line_type, const char*, size_t); -static parselinefn *parsers[] = { +static plinefn *parsers[] = { [LINE_TEXT] = parse_text, [LINE_LINK] = parse_link, [LINE_TITLE_1] = parse_title, blob - ba333328471a966bb716d45587b30befead9bf0d blob + 6e951cadd8be59d8108eb6c9052b287e250ad451 --- parser_gophermap.c +++ parser_gophermap.c @@ -38,9 +38,7 @@ struct gm_selector { static void gm_parse_selector(char *, struct gm_selector *); -static int gm_parse(struct parser *, const char *, size_t); -static int gm_foreach_line(struct parser *, const char *, size_t); -static int gm_free(struct parser *); +static int gm_parse_line(struct parser *, const char *, size_t); static int gm_serialize(struct parser *, FILE *); void @@ -49,8 +47,7 @@ gophermap_initparser(struct parser *p) memset(p, 0, sizeof(*p)); p->name = "gophermap"; - p->parse = &gm_parse; - p->free = &gm_free; + p->parseline = &gm_parse_line; p->serialize = &gm_serialize; TAILQ_INIT(&p->head); @@ -82,12 +79,6 @@ gm_parse_selector(char *line, struct gm_selector *s) } static int -gm_parse(struct parser *p, const char *buf, size_t size) -{ - return parser_foreach_line(p, buf, size, gm_foreach_line); -} - -static int selector2uri(struct gm_selector *s, char *buf, size_t len) { int r; @@ -143,7 +134,7 @@ err: } static int -gm_foreach_line(struct parser *p, const char *line, size_t linelen) +gm_parse_line(struct parser *p, const char *line, size_t linelen) { char buf[LINE_MAX] = {0}; struct gm_selector s = {0}; @@ -188,18 +179,6 @@ gm_foreach_line(struct parser *p, const char *line, si return 1; } -static int -gm_free(struct parser *p) -{ - /* flush the buffer */ - if (p->len != 0) - gm_foreach_line(p, p->buf, p->len); - - free(p->buf); - - return 1; -} - static inline const char * gopher_skip_selector(const char *path, int *ret_type) { blob - 3f37bb628759061e405c7e346dc716cbb568629f blob + 509eb9750e8073134721617555126699eb403f64 --- parser_textpatch.c +++ parser_textpatch.c @@ -26,10 +26,8 @@ #include "parser.h" #include "utils.h" -static int tpatch_parse(struct parser *, const char *, size_t); static int tpatch_emit_line(struct parser *, const char *, size_t); -static int tpatch_foreach_line(struct parser *, const char *, size_t); -static int tpatch_free(struct parser *); +static int tpatch_parse_line(struct parser *, const char *, size_t); void textpatch_initparser(struct parser *p) @@ -37,8 +35,7 @@ textpatch_initparser(struct parser *p) memset(p, 0, sizeof(*p)); p->name = "text/x-patch"; - p->parse = &tpatch_parse; - p->free = &tpatch_free; + p->parseline = &tpatch_parse_line; p->flags = PARSER_IN_PATCH_HDR; @@ -46,12 +43,6 @@ textpatch_initparser(struct parser *p) } static int -tpatch_parse(struct parser *p, const char *buf, size_t size) -{ - return parser_foreach_line(p, buf, size, tpatch_foreach_line); -} - -static int tpatch_emit_line(struct parser *p, const char *line, size_t linelen) { struct line *l; @@ -107,15 +98,7 @@ tpatch_emit_line(struct parser *p, const char *line, s } static int -tpatch_foreach_line(struct parser *p, const char *line, size_t linelen) +tpatch_parse_line(struct parser *p, const char *line, size_t linelen) { return tpatch_emit_line(p, line, linelen); } - -static int -tpatch_free(struct parser *p) -{ - if (p->len != 0) - return tpatch_emit_line(p, p->buf, p->len); - return 1; -} blob - 5c873c362908fb136108098ac6e44f0796a1da91 blob + 5158068417703854a2dd0fd02b72d9aa20717937 --- parser_textplain.c +++ parser_textplain.c @@ -25,9 +25,7 @@ #include "parser.h" -static int textplain_parse(struct parser*, const char*, size_t); -static int textplain_foreach_line(struct parser*, const char*, size_t); -static int textplain_free(struct parser*); +static int textplain_parse_line(struct parser*, const char*, size_t); static inline int emit_line(struct parser *p, const char *line, size_t len) @@ -59,28 +57,13 @@ textplain_initparser(struct parser *p) memset(p, 0, sizeof(*p)); p->name = "text/plain"; - p->parse = &textplain_parse; - p->free = &textplain_free; + p->parseline = &textplain_parse_line; TAILQ_INIT(&p->head); } static int -textplain_parse(struct parser *p, const char *buf, size_t size) +textplain_parse_line(struct parser *p, const char *line, size_t linelen) { - return parser_foreach_line(p, buf, size, textplain_foreach_line); -} - -static int -textplain_foreach_line(struct parser *p, const char *line, size_t linelen) -{ return emit_line(p, line, linelen); } - -static int -textplain_free(struct parser *p) -{ - if (p->len != 0) - return emit_line(p, p->buf, p->len); - return 1; -} blob - 0f01b1ef285be3e0ee68e7890b1ba4fcc4f923ed blob + a099c7f70b13aef4d6ea62cf11276bf5f31af07d --- telescope.h +++ telescope.h @@ -94,6 +94,7 @@ 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 *); @@ -110,6 +111,7 @@ struct parser { int flags; parserinit init; parsechunkfn parse; + parselinefn parseline; parserfreefn free; parserserial serialize;