commit - cb75f36c2043dbc8025438662a547f5b162f9e17
commit + c1d27b0e114e6a65f7979971940df212f00bb2ae
blob - f98e328499a42678d5e82a73dfc56a7126464d7c
blob + 3f89716e58df8fb4fc17d02680a8be4cfa49f5ec
--- cmd.c
+++ cmd.c
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;
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;
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);
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));
}
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 &&
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);
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
*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
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
struct line *l;
char buf[FMT_SCALED_STRSIZE];
- downloadwin.page.name = "*Downloads*";
+ downloadwin.mode = "*Downloads*";
erase_buffer(&downloadwin);
if (STAILQ_EMPTY(&downloads)) {
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
#include "pages.h"
#include "parser.h"
+#include "telescope.h"
#include "session.h"
#include "utils.h"
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;
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 = "";
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);
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;
} else if (!strncmp(url, "file://", 7)) {
url += 7;
strlcpy(path, url, sizeof(path));
- initfn = file_type(url);
+ parser = file_type(url);
} else
goto done;
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
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
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
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
#include "hist.h"
#include "mcache.h"
#include "parser.h"
+#include "telescope.h"
#include "utils.h"
static struct timeval tv = { 5 * 60, 0 };
struct mcache_entry {
time_t ts;
- parserfn parser;
+ struct parser *parser;
int trust;
char *buf;
size_t buflen;
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);
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
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}
};
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
}
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;
}
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)
buffer = current_buffer();
- TAILQ_FOREACH(vl, &buffer->head, vlines) {
+ TAILQ_FOREACH(vl, &buffer->vhead, vlines) {
if (vl->parent == l)
break;
}
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;
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;
}
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
#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;
if (r == -1)
return 0;
- r = parser_parse(tab, s, strlen(s));
+ r = parser_parse(buffer, s, strlen(s));
free(s);
return r;
}
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;
/*
* 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 = "";
}
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;
}
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;
}
/* 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
#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
#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;
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]))
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;
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 '*':
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;
}
* 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;
}
}
};
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
#include <stdlib.h>
#include <string.h>
-#include "parser.h"
#include "iri.h"
+#include "parser.h"
+#include "telescope.h"
#include "utils.h"
#ifndef LINE_MAX
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)
}
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];
break;
}
- TAILQ_INSERT_TAIL(&p->head, l, lines);
+ TAILQ_INSERT_TAIL(&b->head, l, lines);
return 1;
}
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};
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;
}
}
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
#include <string.h>
#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;
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;
* 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
#include <string.h>
#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;
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
}
TAILQ_INIT(&tab->buffer.head);
- TAILQ_INIT(&tab->buffer.page.head);
+ TAILQ_INIT(&tab->buffer.vhead);
tab->id = tab_new_id();
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);
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
#include "mcache.h"
#include "minibuffer.h"
#include "parser.h"
+#include "parser.h"
#include "session.h"
#include "telescope.h"
#include "tofu.h"
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);
}
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);
}
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);
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);
}
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();
return;
}
- strlcpy(tab->buffer.page.title, url,
- sizeof(tab->buffer.page.title));
+ strlcpy(tab->buffer.title, url, sizeof(tab->buffer.title));
}
if (!lazy)
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
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
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;
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
#include <sys/time.h>
#include <sys/wait.h>
-#include <assert.h>
#include <curses.h>
#include <errno.h>
#include <locale.h>
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++;
}
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;
}
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)
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;
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)
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)
const char *spin = "-\\|/";
buffer = current_buffer();
- mode = buffer->page.name;
+ mode = buffer->mode;
werase(modeline);
wattr_on(modeline, modeline_face.background, NULL);
if (set_title)
dprintf(1, "\033]2;%s - Telescope\a",
- current_tab->buffer.page.title);
+ current_tab->buffer.title);
}
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;
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
{
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 &&
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);
}
}
}
vl->flags = flags;
- TAILQ_INSERT_TAIL(&buffer->head, vl, vlines);
+ TAILQ_INSERT_TAIL(&buffer->vhead, vl, vlines);
return 1;
}
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:
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);
}
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);
}
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;