summaryrefslogtreecommitdiffstatshomepage
path: root/html4_strict.c
diff options
context:
space:
mode:
Diffstat (limited to 'html4_strict.c')
-rw-r--r--html4_strict.c624
1 files changed, 7 insertions, 617 deletions
diff --git a/html4_strict.c b/html4_strict.c
index 8705f62d..531af5c7 100644
--- a/html4_strict.c
+++ b/html4_strict.c
@@ -1,4 +1,4 @@
-/* $Id: html4_strict.c,v 1.6 2008/11/24 08:50:33 kristaps Exp $ */
+/* $Id: html4_strict.c,v 1.7 2008/11/24 14:24:55 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -17,642 +17,32 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
-#include <ctype.h>
-#include <err.h>
#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
#include "libmdocml.h"
#include "private.h"
-#define ROFF_MAXARG 10
-
-enum roffd {
- ROFF_ENTER = 0,
- ROFF_EXIT
-};
-
-enum rofftype {
- ROFF_TITLE,
- ROFF_COMMENT,
- ROFF_TEXT,
- ROFF_LAYOUT
-};
-
-#define ROFFCALL_ARGS \
- const struct md_args *arg, struct md_mbuf *out, \
- const struct md_rbuf *in, const char *argv[], \
- enum roffd type, struct rofftree *tree
-
-struct rofftree;
-
-struct rofftok {
- int id;
- char name[2];
- int (*cb)(ROFFCALL_ARGS);
- enum rofftype type;
- int flags;
-#define ROFF_NESTED (1 << 0)
-#define ROFF_PARSED (1 << 1)
-#define ROFF_CALLABLE (1 << 2)
-#define ROFF_QUOTES (1 << 3)
-};
-
-struct roffnode {
- int tok;
- struct roffnode *parent;
- size_t line;
-};
-
-struct rofftree {
- struct roffnode *last;
- time_t date;
- char title[256];
- char section[256];
- char volume[256];
- int state;
-#define ROFF_PRELUDE (1 << 1)
-#define ROFF_PRELUDE_Os (1 << 2)
-#define ROFF_PRELUDE_Dt (1 << 3)
-#define ROFF_PRELUDE_Dd (1 << 4)
-#define ROFF_BODY (1 << 5)
-};
-
-#define ROFF___ 0
-#define ROFF_Dd 1
-#define ROFF_Dt 2
-#define ROFF_Os 3
-#define ROFF_Sh 4
-#define ROFF_An 5
-#define ROFF_Li 6
-#define ROFF_MAX 7
-
-static int roff_Dd(ROFFCALL_ARGS);
-static int roff_Dt(ROFFCALL_ARGS);
-static int roff_Os(ROFFCALL_ARGS);
-static int roff_Sh(ROFFCALL_ARGS);
-static int roff_An(ROFFCALL_ARGS);
-static int roff_Li(ROFFCALL_ARGS);
-
-static struct roffnode *roffnode_new(int, size_t,
- struct rofftree *);
-static void roffnode_free(int, struct rofftree *);
-
-static int rofffind(const char *);
-static int roffargs(int, char *, char **);
-static int roffparse(const struct md_args *,
- struct md_mbuf *,
- const struct md_rbuf *,
- char *, size_t, struct rofftree *);
-static int textparse(struct md_mbuf *,
- const struct md_rbuf *,
- const char *, size_t,
- const struct rofftree *);
-
-static void dbg_enter(const struct md_args *, int);
-static void dbg_leave(const struct md_args *, int);
-
-
-static const struct rofftok tokens[ROFF_MAX] =
-{
-{ ROFF___, "\\\"", NULL, ROFF_COMMENT, 0 },
-{ ROFF_Dd, "Dd", roff_Dd, ROFF_TITLE, 0 },
-{ ROFF_Dt, "Dt", roff_Dt, ROFF_TITLE, 0 },
-{ ROFF_Os, "Os", roff_Os, ROFF_TITLE, 0 },
-{ ROFF_Sh, "Sh", roff_Sh, ROFF_LAYOUT, 0 },
-{ ROFF_An, "An", roff_An, ROFF_TEXT, ROFF_PARSED },
-{ ROFF_Li, "Li", roff_Li, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE },
-};
-
int
-md_exit_html4_strict(const struct md_args *args, struct md_mbuf *out,
- const struct md_rbuf *in, int error, void *data)
+md_line_html4_strict(void *data, char *buf, size_t sz)
{
- struct rofftree *tree;
-
- assert(args);
- assert(data);
- tree = (struct rofftree *)data;
-
- if (-1 == error)
- out = NULL;
-
- /* LINTED */
- while (tree->last)
- if ( ! (*tokens[tree->last->tok].cb)(args, out, in,
- NULL, ROFF_EXIT, tree))
- out = NULL;
-
- if (out && (ROFF_PRELUDE & tree->state)) {
- warnx("%s: prelude never finished", in->name);
- error = 1;
- }
-
- free(tree);
- return(error ? 0 : 1);
-}
-
-
-int
-md_init_html4_strict(const struct md_args *args, struct md_mbuf *out,
- const struct md_rbuf *in, void **data)
-{
- struct rofftree *tree;
-
- assert(args);
- assert(in);
- assert(out);
- assert(data);
-
- /* TODO: write HTML-DTD header. */
-
- if (NULL == (tree = calloc(1, sizeof(struct rofftree)))) {
- warn("malloc");
- return(0);
- }
-
- tree->state = ROFF_PRELUDE;
-
- *data = tree;
return(1);
}
int
-md_line_html4_strict(const struct md_args *args, struct md_mbuf *out,
- const struct md_rbuf *in, char *buf,
- size_t sz, void *data)
-{
- struct rofftree *tree;
-
- assert(args);
- assert(in);
- assert(data);
-
- tree = (struct rofftree *)data;
-
- if (0 == sz) {
- warnx("%s: blank line (line %zu)", in->name, in->line);
- return(0);
- } else if ('.' != *buf)
- return(textparse(out, in, buf, sz, tree));
-
- return(roffparse(args, out, in, buf, sz, tree));
-}
-
-
-static int
-textparse(struct md_mbuf *out, const struct md_rbuf *in,
- const char *buf, size_t sz,
- const struct rofftree *tree)
-{
-
- assert(tree);
- assert(out);
- assert(in);
- assert(buf);
- assert(sz > 0);
-
- if (NULL == tree->last) {
- warnx("%s: unexpected text (line %zu)",
- in->name, in->line);
- return(0);
- } else if (NULL == tree->last->parent) {
- warnx("%s: disallowed text (line %zu)",
- in->name, in->line);
- return(0);
- }
-
- if ( ! md_buf_puts(out, buf, sz))
- return(0);
- return(md_buf_putstring(out, " "));
-}
-
-
-static int
-roffargs(int tok, char *buf, char **argv)
-{
- int i;
-
- (void)tok;/* FIXME: quotable strings? */
-
- assert(tok >= 0 && tok < ROFF_MAX);
- assert('.' == *buf);
-
- /* LINTED */
- for (i = 0; *buf && i < ROFF_MAXARG; i++) {
- argv[i] = buf++;
- while (*buf && ! isspace(*buf))
- buf++;
- if (NULL == *buf) {
- continue;
- }
- *buf++ = 0;
- while (*buf && isspace(*buf))
- buf++;
- }
-
- assert(i > 0);
- if (i < ROFF_MAXARG)
- argv[i] = NULL;
-
- return(ROFF_MAXARG > i);
-}
-
-
-static int
-roffparse(const struct md_args *args, struct md_mbuf *out,
- const struct md_rbuf *in, char *buf, size_t sz,
- struct rofftree *tree)
-{
- int tok, t;
- struct roffnode *node;
- char *argv[ROFF_MAXARG];
-
- assert(sz > 0);
-
- /*
- * Extract the token identifier from the buffer. If there's no
- * callback for the token (comment, etc.) then exit immediately.
- * We don't do any error handling (yet), so if the token doesn't
- * exist, die.
- */
-
- if (3 > sz) {
- warnx("%s: malformed line (line %zu)",
- in->name, in->line);
- return(0);
- } else if (ROFF_MAX == (tok = rofffind(buf + 1))) {
- warnx("%s: unknown line token `%c%c' (line %zu)",
- in->name, *(buf + 1),
- *(buf + 2), in->line);
- return(0);
- } else if (ROFF_COMMENT == tokens[tok].type)
- /* Ignore comment tokens. */
- return(1);
-
- if ( ! roffargs(tok, buf, argv)) {
- warnx("%s: too many arguments to `%s' (line %zu)",
- in->name, tokens[tok].name, in->line);
- return(0);
- }
-
- /* Domain cross-contamination (and sanity) checks. */
-
- switch (tokens[tok].type) {
- case (ROFF_TITLE):
- if (ROFF_PRELUDE & tree->state) {
- assert( ! (ROFF_BODY & tree->state));
- break;
- }
- assert(ROFF_BODY & tree->state);
- warnx("%s: prelude token `%s' in body (line %zu)",
- in->name, tokens[tok].name, in->line);
- return(0);
- case (ROFF_LAYOUT):
- /* FALLTHROUGH */
- case (ROFF_TEXT):
- if (ROFF_BODY & tree->state) {
- assert( ! (ROFF_PRELUDE & tree->state));
- break;
- }
- assert(ROFF_PRELUDE & tree->state);
- warnx("%s: body token `%s' in prelude (line %zu)",
- in->name, tokens[tok].name, in->line);
- return(0);
- case (ROFF_COMMENT):
- return(1);
- default:
- abort();
- }
-
- /*
- * Text-domain checks.
- */
-
- if (ROFF_TEXT == tokens[tok].type &&
- ! (ROFF_PARSED & tokens[tok].flags)) {
- warnx("%s: text token `%s' not callable (line %zu)",
- in->name, tokens[tok].name, in->line);
- return(0);
- }
-
- /*
- * If this is a non-nestable layout token and we're below a
- * token of the same type, then recurse upward to the token,
- * closing out the interim scopes.
- *
- * If there's a nested token on the chain, then raise an error
- * as nested tokens have corresponding "ending" tokens and we're
- * breaking their scope.
- */
-
- node = NULL;
-
- if (ROFF_LAYOUT == tokens[tok].type &&
- ! (ROFF_NESTED & tokens[tok].flags)) {
- for (node = tree->last; node; node = node->parent) {
- if (node->tok == tok)
- break;
-
- /* Don't break nested scope. */
-
- if ( ! (ROFF_NESTED & tokens[node->tok].flags))
- continue;
- warnx("%s: scope of %s (line %zu) broken by "
- "%s (line %zu)", in->name,
- tokens[tok].name,
- node->line,
- tokens[node->tok].name,
- in->line);
- return(0);
- }
- }
-
- if (node) {
- assert(ROFF_LAYOUT == tokens[tok].type);
- assert( ! (ROFF_NESTED & tokens[tok].flags));
- assert(node->tok == tok);
-
- /* Clear up to last scoped token. */
-
- /* LINTED */
- do {
- t = tree->last->tok;
- if ( ! (*tokens[tree->last->tok].cb)
- (args, out, in, NULL,
- ROFF_EXIT, tree))
- return(0);
- } while (t != tok);
- }
-
- /* Proceed with actual token processing. */
-
- return((*tokens[tok].cb)(args, out, in, (const char **)argv,
- ROFF_ENTER, tree));
-}
-
-
-static int
-rofffind(const char *name)
-{
- size_t i;
-
- assert(name);
- /* FIXME: use a table, this is slow but ok for now. */
-
- /* LINTED */
- for (i = 0; i < ROFF_MAX; i++)
- /* LINTED */
- if (0 == strncmp(name, tokens[i].name, 2))
- return((int)i);
-
- return(ROFF_MAX);
-}
-
-
-static struct roffnode *
-roffnode_new(int tokid, size_t line, struct rofftree *tree)
-{
- struct roffnode *p;
-
- if (NULL == (p = malloc(sizeof(struct roffnode)))) {
- warn("malloc");
- return(NULL);
- }
-
- p->line = line;
- p->tok = tokid;
- p->parent = tree->last;
- tree->last = p;
- return(p);
-}
-
-
-static void
-roffnode_free(int tokid, struct rofftree *tree)
-{
- struct roffnode *p;
-
- assert(tree->last);
- assert(tree->last->tok == tokid);
-
- p = tree->last;
- tree->last = tree->last->parent;
- free(p);
-}
-
-
-static int dbg_lvl = 0;
-
-
-static void
-dbg_enter(const struct md_args *args, int tokid)
-{
- int i;
- static char buf[72];
-
- assert(args);
- if ( ! (args->dbg & MD_DBG_TREE))
- return;
- assert(tokid >= 0 && tokid <= ROFF_MAX);
-
- buf[0] = 0;
-
- switch (tokens[tokid].type) {
- case (ROFF_LAYOUT):
- /* FALLTHROUGH */
- case (ROFF_TEXT):
- (void)strlcat(buf, "body: ", sizeof(buf));
- break;
- case (ROFF_TITLE):
- (void)strlcat(buf, "prelude: ", sizeof(buf));
- break;
- default:
- abort();
- }
-
- /* LINTED */
- for (i = 0; i < dbg_lvl; i++)
- (void)strlcat(buf, " ", sizeof(buf));
-
- (void)strlcat(buf, tokens[tokid].name, sizeof(buf));
-
- (void)printf("%s\n", buf);
-
- if (ROFF_LAYOUT == tokens[tokid].type)
- dbg_lvl++;
-}
-
-
-static void
-dbg_leave(const struct md_args *args, int tokid)
-{
- assert(args);
- if ( ! (args->dbg & MD_DBG_TREE))
- return;
- if (ROFF_LAYOUT != tokens[tokid].type)
- return;
-
- assert(tokid >= 0 && tokid <= ROFF_MAX);
- assert(dbg_lvl > 0);
- dbg_lvl--;
-}
-
-
-/* ARGSUSED */
-static int
-roff_Dd(ROFFCALL_ARGS)
-{
-
- dbg_enter(arg, ROFF_Dd);
-
- assert(ROFF_PRELUDE & tree->state);
- if (ROFF_PRELUDE_Dt & tree->state ||
- ROFF_PRELUDE_Dd & tree->state) {
- warnx("%s: prelude `Dd' out-of-order (line %zu)",
- in->name, in->line);
- return(0);
- }
-
- assert(NULL == tree->last);
- tree->state |= ROFF_PRELUDE_Dd;
-
- dbg_leave(arg, ROFF_Dd);
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-roff_Dt(ROFFCALL_ARGS)
-{
-
- dbg_enter(arg, ROFF_Dt);
-
- assert(ROFF_PRELUDE & tree->state);
- if ( ! (ROFF_PRELUDE_Dd & tree->state) ||
- (ROFF_PRELUDE_Dt & tree->state)) {
- warnx("%s: prelude `Dt' out-of-order (line %zu)",
- in->name, in->line);
- return(0);
- }
-
- assert(NULL == tree->last);
- tree->state |= ROFF_PRELUDE_Dt;
-
- dbg_leave(arg, ROFF_Dt);
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-roff_Os(ROFFCALL_ARGS)
+md_exit_html4_strict(void *data, int flush)
{
- if (ROFF_EXIT == type) {
- roffnode_free(ROFF_Os, tree);
- dbg_leave(arg, ROFF_Os);
- return(1);
- }
-
- dbg_enter(arg, ROFF_Os);
-
- assert(ROFF_PRELUDE & tree->state);
- if ( ! (ROFF_PRELUDE_Dt & tree->state) ||
- ! (ROFF_PRELUDE_Dd & tree->state)) {
- warnx("%s: prelude `Os' out-of-order (line %zu)",
- in->name, in->line);
- return(0);
- }
-
- assert(NULL == tree->last);
- if (NULL == roffnode_new(ROFF_Os, in->line, tree))
- return(0);
-
- tree->state |= ROFF_PRELUDE_Os;
- tree->state &= ~ROFF_PRELUDE;
- tree->state |= ROFF_BODY;
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-roff_Sh(ROFFCALL_ARGS)
-{
-
- if (ROFF_EXIT == type) {
- roffnode_free(ROFF_Sh, tree);
- dbg_leave(arg, ROFF_Sh);
- return(1);
- }
-
- dbg_enter(arg, ROFF_Sh);
-
- if (NULL == roffnode_new(ROFF_Sh, in->line, tree))
- return(0);
-
- dbg_leave(arg, ROFF_Li);
-
return(1);
}
-/* ARGSUSED */
-static int
-roff_Li(ROFFCALL_ARGS)
+void *
+md_init_html4_strict(const struct md_args *args,
+ struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
{
- dbg_enter(arg, ROFF_Li);
- dbg_leave(arg, ROFF_Li);
-
- return(1);
-}
-
-
-#if 0
-static int
-parse_args(void)
-{
- skip_whitespace();
-
- while (pos < sz) {
-
- if (is_arg) {
- } else if (parsable) {
- if (is_callable_token()) {
- }
- }
-
- skip_whitespace();
- }
-}
-#endif
-
-
-/* ARGSUSED */
-static int
-roff_An(ROFFCALL_ARGS)
-{
-
- dbg_enter(arg, ROFF_An);
-
- /* Do our ML stuff. */
-
- /*parse_args();*/
-
- /* Do our trailing whitespace stuff. */
-
- dbg_leave(arg, ROFF_An);
-
- return(1);
+ return(NULL);
}