diff options
-rw-r--r-- | action.c | 239 | ||||
-rw-r--r-- | macro.c | 15 | ||||
-rw-r--r-- | validate.c | 69 |
3 files changed, 164 insertions, 159 deletions
@@ -18,6 +18,7 @@ */ #include <assert.h> #include <stdlib.h> +#include <time.h> #include "private.h" @@ -182,64 +183,47 @@ post_sh(struct mdoc *mdoc) static int post_dt(struct mdoc *mdoc) { -#if 0 - int lastarg, j; - char *args[MDOC_LINEARG_MAX]; + int i; + char *p; + size_t sz; + struct mdoc_node *n; - if (SEC_PROLOGUE != mdoc->sec_lastn) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE)); - if (0 == mdoc->meta.date) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO)); - if (mdoc->meta.title[0]) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP)); - - j = -1; - lastarg = ppos; - -again: - if (j == MDOC_LINEARG_MAX) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); - - lastarg = *pos; - - switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[++j])) { - case (ARGS_EOLN): - if (mdoc->meta.title) - return(1); - if ( ! mdoc_warn(mdoc, tok, ppos, WARN_ARGS_GE1)) - return(0); - (void)xstrlcpy(mdoc->meta.title, - "UNTITLED", META_TITLE_SZ); - return(1); - case (ARGS_ERROR): - return(0); - default: - break; - } + assert(MDOC_ELEM == mdoc->last->type); + assert(MDOC_Dt == mdoc->last->data.elem.tok); + assert(0 == mdoc->meta.title[0]); + + sz = META_TITLE_SZ; + (void)xstrlcpy(mdoc->meta.title, "UNTITLED", sz); - if (0 == j) { - if (xstrlcpy(mdoc->meta.title, args[0], META_TITLE_SZ)) - goto again; - return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM)); - - } else if (1 == j) { - mdoc->meta.msec = mdoc_atomsec(args[1]); - if (MSEC_DEFAULT != mdoc->meta.msec) - goto again; - return(mdoc_err(mdoc, tok, -1, ERR_SYNTAX_ARGFORM)); - - } else if (2 == j) { - mdoc->meta.vol = mdoc_atovol(args[2]); - if (VOL_DEFAULT != mdoc->meta.vol) - goto again; - mdoc->meta.arch = mdoc_atoarch(args[2]); - if (ARCH_DEFAULT != mdoc->meta.arch) - goto again; - return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM)); + for (i = 0, n = mdoc->last->child; n; n = n->next, i++) { + assert(MDOC_TEXT == n->type); + p = n->data.text.string; + + switch (i) { + case (0): + if (xstrlcpy(mdoc->meta.title, p, sz)) + break; + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); + case (1): + mdoc->meta.msec = mdoc_atomsec(p); + if (MSEC_DEFAULT != mdoc->meta.msec) + break; + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); + case (2): + mdoc->meta.vol = mdoc_atovol(p); + if (VOL_DEFAULT != mdoc->meta.vol) + break; + mdoc->meta.arch = mdoc_atoarch(p); + if (ARCH_DEFAULT != mdoc->meta.arch) + break; + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); + default: + return(mdoc_err(mdoc, ERR_ARGS_MANY)); + } } - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); -#endif + mdoc_msg(mdoc, "parsed title: %s", mdoc->meta.title); + /* TODO: have vol2a functions. */ return(1); } @@ -247,47 +231,29 @@ again: static int post_os(struct mdoc *mdoc) { -#if 0 - int lastarg, j; - char *args[MDOC_LINEARG_MAX]; - - /* FIXME: if we use `Os' again... ? */ - - if (SEC_PROLOGUE != mdoc->sec_lastn) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE)); - if (0 == mdoc->meta.title[0]) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO)); - if (mdoc->meta.os[0]) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP)); + char *p; + size_t sz; + struct mdoc_node *n; - j = -1; - lastarg = ppos; + assert(MDOC_ELEM == mdoc->last->type); + assert(MDOC_Os == mdoc->last->data.elem.tok); + assert(0 == mdoc->meta.os[0]); -again: - if (j == MDOC_LINEARG_MAX) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + sz = META_OS_SZ; + (void)xstrlcpy(mdoc->meta.os, "LOCAL", sz); - lastarg = *pos; + for (n = mdoc->last->child; n; n = n->next) { + assert(MDOC_TEXT == n->type); + p = n->data.text.string; - switch (mdoc_args(mdoc, tok, pos, buf, - ARGS_QUOTED, &args[++j])) { - case (ARGS_EOLN): - mdoc->sec_lastn = mdoc->sec_last = SEC_BODY; - return(1); - case (ARGS_ERROR): - return(0); - default: - break; + if ( ! xstrlcat(mdoc->meta.os, p, sz)) + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); + if ( ! xstrlcat(mdoc->meta.os, " ", sz)) + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); } - - if ( ! xstrlcat(mdoc->meta.os, args[j], sizeof(mdoc->meta.os))) - return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM)); - if ( ! xstrlcat(mdoc->meta.os, " ", sizeof(mdoc->meta.os))) - return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM)); - - goto again; - /* NOTREACHED */ -#endif + + mdoc_msg(mdoc, "parsed operating system (entering document body)"); + mdoc->sec_lastn = mdoc->sec_last = SEC_BODY; return(1); } @@ -295,63 +261,46 @@ again: static int post_dd(struct mdoc *mdoc) { -#if 0 - int lastarg, j; - char *args[MDOC_LINEARG_MAX], date[64]; - - if (SEC_PROLOGUE != mdoc->sec_lastn) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE)); - if (mdoc->meta.title[0]) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO)); - if (mdoc->meta.date) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP)); - - j = -1; + char date[64]; + size_t sz; + char *p; + struct mdoc_node *n; + + assert(MDOC_ELEM == mdoc->last->type); + assert(MDOC_Dd == mdoc->last->data.elem.tok); + + n = mdoc->last->child; + assert(0 == mdoc->meta.date); date[0] = 0; - lastarg = ppos; - -again: - if (j == MDOC_LINEARG_MAX) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); - - lastarg = *pos; - switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[++j])) { - case (ARGS_EOLN): - if (mdoc->meta.date) - return(1); - mdoc->meta.date = mdoc_atotime(date); - if (mdoc->meta.date) - return(1); - return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGFORM)); - case (ARGS_ERROR): - return(0); - default: - break; - } - - if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn - (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE)) - return(0); - - if (0 == j) { - if (xstrcmp("$Mdocdate$", args[j])) { + + sz = 64; + + for ( ; 0 == mdoc->meta.date && n; n = n->next) { + assert(MDOC_TEXT == n->type); + p = n->data.text.string; + + if (xstrcmp(p, "$Mdocdate$")) { mdoc->meta.date = time(NULL); - goto again; - } else if (xstrcmp("$Mdocdate:", args[j])) - goto again; - } else if (4 == j) - if ( ! xstrcmp("$", args[j])) - goto again; - - if ( ! xstrlcat(date, args[j], sizeof(date))) - return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM)); - if ( ! xstrlcat(date, " ", sizeof(date))) - return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM)); - - goto again; - /* NOTREACHED */ -#endif - return(1); + continue; + } else if (xstrcmp(p, "$")) { + mdoc->meta.date = mdoc_atotime(date); + continue; + } else if (xstrcmp(p, "$Mdocdate:")) + continue; + + if ( ! xstrlcat(date, n->data.text.string, sz)) + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); + if ( ! xstrlcat(date, " ", sz)) + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); + } + + if (mdoc->meta.date && NULL == n) { + mdoc_msg(mdoc, "parsed time: %u since epoch", + mdoc->meta.date); + return(1); + } + + return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM)); } @@ -55,19 +55,20 @@ rewind_last(struct mdoc *mdoc, struct mdoc_node *to) { assert(to); - while (mdoc->last != to) { + if (mdoc->last == to) + return(1); + + do { + mdoc->last = mdoc->last->parent; + assert(mdoc->last); if ( ! mdoc_valid_post(mdoc)) return(0); if ( ! mdoc_action_post(mdoc)) return(0); - mdoc->last = mdoc->last->parent; - assert(mdoc->last); - } + } while (mdoc->last != to); mdoc->next = MDOC_NEXT_SIBLING; - if ( ! mdoc_valid_post(mdoc)) - return(0); - return(mdoc_action_post(mdoc)); + return(1); } @@ -33,6 +33,9 @@ struct valids { static int pre_sh(struct mdoc *, struct mdoc_node *); +static int pre_prologue(struct mdoc *, struct mdoc_node *); +static int pre_prologue(struct mdoc *, struct mdoc_node *); +static int pre_prologue(struct mdoc *, struct mdoc_node *); static int post_headchild_err_ge1(struct mdoc *); static int post_headchild_err_le8(struct mdoc *); static int post_bodychild_warn_ge1(struct mdoc *); @@ -44,9 +47,9 @@ static v_post posts_sh[] = { post_headchild_err_ge1, const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* \" */ - { NULL, NULL }, /* Dd */ /* TODO: pre: ordering, repetition */ - { NULL, NULL }, /* Dt */ /* TODO ... */ - { NULL, NULL }, /* Os */ /* TODO ... */ + { pre_prologue, NULL }, /* Dd */ /* TODO: pre: ordering, repetition */ + { pre_prologue, NULL }, /* Dt */ /* TODO ... */ + { pre_prologue, NULL }, /* Os */ /* TODO ... */ { pre_sh, posts_sh }, /* Sh */ /* FIXME: preceding Pp. */ { NULL, NULL }, /* Ss */ /* FIXME: preceding Pp. */ { NULL, NULL }, /* Pp */ @@ -194,6 +197,58 @@ post_headchild_err_le8(struct mdoc *mdoc) static int +pre_prologue(struct mdoc *mdoc, struct mdoc_node *node) +{ + + if (SEC_PROLOGUE != mdoc->sec_lastn) + return(mdoc_verr(mdoc, node, ERR_SEC_NPROLOGUE)); + assert(MDOC_ELEM == node->type); + + /* Check for ordering. */ + + switch (node->data.elem.tok) { + case (MDOC_Os): + if (mdoc->meta.title[0] && mdoc->meta.date) + break; + return(mdoc_verr(mdoc, node, ERR_SEC_PROLOGUE_OO)); + case (MDOC_Dt): + if (0 == mdoc->meta.title[0] && mdoc->meta.date) + break; + return(mdoc_verr(mdoc, node, ERR_SEC_PROLOGUE_OO)); + case (MDOC_Dd): + if (0 == mdoc->meta.title[0] && 0 == mdoc->meta.date) + break; + return(mdoc_verr(mdoc, node, ERR_SEC_PROLOGUE_OO)); + default: + abort(); + /* NOTREACHED */ + } + + /* Check for repetition. */ + + switch (node->data.elem.tok) { + case (MDOC_Os): + if (0 == mdoc->meta.os[0]) + return(1); + break; + case (MDOC_Dd): + if (0 == mdoc->meta.date) + return(1); + break; + case (MDOC_Dt): + if (0 == mdoc->meta.title[0]) + return(1); + break; + default: + abort(); + /* NOTREACHED */ + } + + return(mdoc_verr(mdoc, node, ERR_SEC_PROLOGUE_REP)); +} + + +static int pre_sh(struct mdoc *mdoc, struct mdoc_node *node) { @@ -208,16 +263,16 @@ mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *node) switch (node->type) { case (MDOC_BODY): - t = mdoc->last->data.body.tok; + t = node->data.body.tok; break; case (MDOC_ELEM): - t = mdoc->last->data.elem.tok; + t = node->data.elem.tok; break; case (MDOC_BLOCK): - t = mdoc->last->data.block.tok; + t = node->data.block.tok; break; case (MDOC_HEAD): - t = mdoc->last->data.head.tok; + t = node->data.head.tok; break; default: return(1); |