summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-01-12 10:31:53 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-01-12 10:31:53 +0000
commit062881c5bc9c7803c1b4caaca0d73dfd937f3445 (patch)
tree4eef2bacce9049ce36b7779756435cbc274a4dc9
parent9a5b4bcb2e33907e5840f6a576a7cac39f080343 (diff)
downloadmandoc-062881c5bc9c7803c1b4caaca0d73dfd937f3445.tar.gz
*** empty log message ***
-rw-r--r--argv.c3
-rw-r--r--macro.c8
-rw-r--r--mdoc.c37
-rw-r--r--mdoc.h4
-rw-r--r--mdocml.c51
-rw-r--r--validate.c204
6 files changed, 208 insertions, 99 deletions
diff --git a/argv.c b/argv.c
index c3c1e4dc..e70969b3 100644
--- a/argv.c
+++ b/argv.c
@@ -404,6 +404,9 @@ mdoc_argv(struct mdoc *mdoc, int line, int tok,
i = *pos;
argv = &buf[++(*pos)];
+ v->line = line;
+ v->pos = *pos;
+
while (buf[*pos] && ! isspace(buf[*pos]))
(*pos)++;
diff --git a/macro.c b/macro.c
index e8da371e..74764e53 100644
--- a/macro.c
+++ b/macro.c
@@ -153,10 +153,10 @@ rewind_expblock(struct mdoc *mdoc, int tok)
struct mdoc_node *n;
int t;
- assert(mdoc->last);
+ n = mdoc->last ? mdoc->last->parent : NULL;
/* LINTED */
- for (n = mdoc->last; n; n = n->parent) {
+ for ( ; n; n = n->parent) {
if (MDOC_BLOCK != n->type)
continue;
if (tok == (t = n->data.block.tok))
@@ -187,7 +187,7 @@ rewind_impblock(struct mdoc *mdoc, int tok)
break;
if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
continue;
- if (MDOC_NESTED & mdoc_macros[t].flags)
+ if (MDOC_NESTED & mdoc_macros[tok].flags)
return(1);
return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
}
@@ -293,7 +293,7 @@ macro_close_explicit(MACRO_PROT_ARGS)
}
if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
- if (buf[*pos])
+ if (0 == buf[*pos])
return(rewind_expblock(mdoc, tt));
return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_EQ0));
}
diff --git a/mdoc.c b/mdoc.c
index f2dd666d..2e1f3893 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -283,7 +283,8 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf)
if ('.' != *buf) {
if (SEC_PROLOGUE != mdoc->sec_lastn) {
- mdoc_word_alloc(mdoc, line, 0, buf);
+ if ( ! mdoc_word_alloc(mdoc, line, 0, buf))
+ return(0);
mdoc->next = MDOC_NEXT_SIBLING;
return(1);
}
@@ -392,37 +393,7 @@ mdoc_macro(struct mdoc *mdoc, int tok,
static int
mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *p)
{
- const char *nn, *on, *nt, *ot, *act;
-
- switch (p->type) {
- case (MDOC_TEXT):
- nn = p->data.text.string;
- nt = "text";
- break;
- case (MDOC_BODY):
- nn = mdoc_macronames[p->data.body.tok];
- nt = "body";
- break;
- case (MDOC_ELEM):
- nn = mdoc_macronames[p->data.elem.tok];
- nt = "elem";
- break;
- case (MDOC_HEAD):
- nn = mdoc_macronames[p->data.head.tok];
- nt = "head";
- break;
- case (MDOC_TAIL):
- nn = mdoc_macronames[p->data.tail.tok];
- nt = "tail";
- break;
- case (MDOC_BLOCK):
- nn = mdoc_macronames[p->data.block.tok];
- nt = "block";
- break;
- default:
- abort();
- /* NOTREACHED */
- }
+ const char *on, *ot, *act;
assert(mdoc->last);
assert(mdoc->first);
@@ -708,6 +679,8 @@ argcpy(struct mdoc_arg *dst, const struct mdoc_arg *src)
{
int i;
+ dst->line = src->line;
+ dst->pos = src->pos;
dst->arg = src->arg;
if (0 == (dst->sz = src->sz))
return;
diff --git a/mdoc.h b/mdoc.h
index 99ce0082..d40086ca 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -202,6 +202,7 @@ enum mdoc_err {
ERR_SYNTAX_ARGFORM,
ERR_SYNTAX_ARGVAL,
ERR_SYNTAX_ARGBAD,
+ ERR_SYNTAX_ARGMISS,
ERR_SYNTAX_ARGMANY,
ERR_MACRO_NOTSUP,
ERR_MACRO_NOTCALL,
@@ -219,6 +220,7 @@ enum mdoc_err {
ERR_ARGS_LE2,
ERR_ARGS_LE8,
ERR_ARGS_MANY,
+ ERR_SYNTAX_CHILDBAD,
ERR_SYNTAX_CHILDHEAD,
ERR_SYNTAX_CHILDBODY,
ERR_SYNTAX_EMPTYBODY,
@@ -260,6 +262,8 @@ enum mdoc_warn {
struct mdoc_arg {
int arg;
+ int line;
+ int pos;
size_t sz;
char **value;
};
diff --git a/mdocml.c b/mdocml.c
index f3b0a524..92a55375 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -244,7 +244,7 @@ print_node(const struct mdoc_node *n, int indent)
for (i = 0; i < (int)sz; i++)
(void)printf(" \"%s\"", params[i]);
- (void)printf("\n");
+ (void)printf(" %d:%d\n", n->line, n->pos);
if (n->child)
print_node(n->child, indent + 1);
@@ -328,7 +328,6 @@ msg_err(void *arg, int line, int col, enum mdoc_err type)
{
char *lit;
struct md_parse *p;
- int i;
p = (struct md_parse *)arg;
@@ -409,11 +408,17 @@ msg_err(void *arg, int line, int col, enum mdoc_err type)
lit = "syntax: expected value for macro argument";
break;
case (ERR_SYNTAX_ARGBAD):
- lit = "syntax: invalid value for macro argument";
+ lit = "syntax: invalid value(s) for macro argument";
+ break;
+ case (ERR_SYNTAX_ARGMISS):
+ lit = "syntax: missing required argument(s) for macro";
break;
case (ERR_SYNTAX_ARGMANY):
lit = "syntax: too many values for macro argument";
break;
+ case (ERR_SYNTAX_CHILDBAD):
+ lit = "syntax: invalid child for parent macro";
+ break;
case (ERR_SYNTAX_CHILDHEAD):
lit = "syntax: expected only block-header section";
break;
@@ -431,18 +436,8 @@ msg_err(void *arg, int line, int col, enum mdoc_err type)
/* NOTREACHED */
}
- (void)fprintf(stderr, "%s:%d: error: %s", p->name, p->lnn, lit);
-
- if (p->dbg < 1) {
- (void)fprintf(stderr, " (column %d)\n", col);
- return(0);
- }
-
- (void)fprintf(stderr, "\nFrom: %s\n ", p->line);
- for (i = 0; i < col; i++)
- (void)fprintf(stderr, " ");
- (void)fprintf(stderr, "^\n");
-
+ (void)fprintf(stderr, "%s:%d: error: %s (column %d)\n",
+ p->name, line, lit, col);
return(0);
}
@@ -451,24 +446,14 @@ static void
msg_msg(void *arg, int line, int col, const char *msg)
{
struct md_parse *p;
- int i;
p = (struct md_parse *)arg;
if (p->dbg < 2)
return;
- (void)printf("%s:%d: %s", p->name, line, msg);
-
- if (p->dbg < 3) {
- (void)printf(" (column %d)\n", col);
- return;
- }
-
- (void)printf("\nFrom: %s\n ", p->line);
- for (i = 0; i < col; i++)
- (void)printf(" ");
- (void)printf("^\n");
+ (void)printf("%s:%d: %s (column %d)\n",
+ p->name, line, msg, col);
}
@@ -477,7 +462,6 @@ msg_warn(void *arg, int line, int col, enum mdoc_warn type)
{
char *lit;
struct md_parse *p;
- int i;
extern char *__progname;
p = (struct md_parse *)arg;
@@ -533,15 +517,8 @@ msg_warn(void *arg, int line, int col, enum mdoc_warn type)
}
- (void)fprintf(stderr, "%s:%d: warning: %s", p->name, line, lit);
-
- if (p->dbg >= 1) {
- (void)fprintf(stderr, "\nFrom: %s\n ", p->line);
- for (i = 0; i < col; i++)
- (void)fprintf(stderr, " ");
- (void)fprintf(stderr, "^\n");
- } else
- (void)fprintf(stderr, " (column %d)\n", col);
+ (void)fprintf(stderr, "%s:%d: warning: %s (column %d)\n",
+ p->name, line, lit, col);
if (p->warn & MD_WARN_ERR) {
(void)fprintf(stderr, "%s: considering warnings as "
diff --git a/validate.c b/validate.c
index e028aadc..06bfdcd1 100644
--- a/validate.c
+++ b/validate.c
@@ -27,42 +27,56 @@ typedef int (*v_post)(struct mdoc *);
struct valids {
- v_pre pre;
+ v_pre *pre;
v_post *post;
};
static int pre_display(struct mdoc *, struct mdoc_node *);
+static int pre_bd(struct mdoc *, struct mdoc_node *);
+static int pre_bl(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_elemchild_err_ge1(struct mdoc *);
-static int post_elemchild_warn_eq0(struct mdoc *);
-static int post_bodychild_warn_ge1(struct mdoc *);
+
+static int headchild_err_ge1(struct mdoc *);
+static int headchild_err_eq0(struct mdoc *);
+static int elemchild_err_ge1(struct mdoc *);
+static int elemchild_warn_eq0(struct mdoc *);
+static int bodychild_warn_ge1(struct mdoc *);
static int post_sh(struct mdoc *);
+static int post_bl(struct mdoc *);
+
+static v_pre pres_prologue[] = { pre_prologue, NULL };
+static v_pre pres_d1[] = { pre_display, NULL };
+static v_pre pres_bd[] = { pre_display, pre_bd, NULL };
+static v_pre pres_bl[] = { pre_bl, NULL };
+static v_post posts_bd[] = { headchild_err_eq0,
+ bodychild_warn_ge1, NULL };
-static v_post posts_sh[] = { post_headchild_err_ge1,
- post_bodychild_warn_ge1, post_sh, NULL };
-static v_post posts_ss[] = { post_headchild_err_ge1, NULL };
-static v_post posts_pp[] = { post_elemchild_warn_eq0, NULL };
-static v_post posts_dd[] = { post_elemchild_err_ge1, NULL };
-static v_post posts_display[] = { post_headchild_err_ge1, NULL };
+static v_post posts_sh[] = { headchild_err_ge1,
+ bodychild_warn_ge1, post_sh, NULL };
+static v_post posts_bl[] = { headchild_err_eq0,
+ bodychild_warn_ge1, post_bl, NULL };
+static v_post posts_ss[] = { headchild_err_ge1, NULL };
+static v_post posts_pp[] = { elemchild_warn_eq0, NULL };
+static v_post posts_dd[] = { elemchild_err_ge1, NULL };
+static v_post posts_d1[] = { headchild_err_ge1, NULL };
const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, NULL }, /* \" */
- { pre_prologue, posts_dd }, /* Dd */
- { pre_prologue, NULL }, /* Dt */
- { pre_prologue, NULL }, /* Os */
+ { pres_prologue, posts_dd }, /* Dd */
+ { pres_prologue, NULL }, /* Dt */
+ { pres_prologue, NULL }, /* Os */
{ NULL, posts_sh }, /* Sh */ /* FIXME: preceding Pp. */
{ NULL, posts_ss }, /* Ss */ /* FIXME: preceding Pp. */
{ NULL, posts_pp }, /* Pp */ /* FIXME: proceeding... */
- { pre_display, posts_display }, /* D1 */
- { pre_display, posts_display }, /* Dl */
- { pre_display, NULL }, /* Bd */ /* FIXME: preceding Pp. */
+ { pres_d1, posts_d1 }, /* D1 */
+ { pres_d1, posts_d1 }, /* Dl */
+ { pres_bd, posts_bd }, /* Bd */ /* FIXME: preceding Pp. */
{ NULL, NULL }, /* Ed */
- { NULL, NULL }, /* Bl */ /* FIXME: preceding Pp. */
+ { pres_bl, posts_bl }, /* Bl */ /* FIXME: preceding Pp. */
{ NULL, NULL }, /* El */
{ NULL, NULL }, /* It */
{ NULL, NULL }, /* Ad */
@@ -161,31 +175,31 @@ const struct valids mdoc_valids[MDOC_MAX] = {
static int
-post_bodychild_warn_ge1(struct mdoc *mdoc)
+bodychild_warn_ge1(struct mdoc *mdoc)
{
if (MDOC_BODY != mdoc->last->type)
return(1);
if (mdoc->last->child)
return(1);
-
return(mdoc_warn(mdoc, WARN_ARGS_GE1));
}
static int
-post_elemchild_warn_eq0(struct mdoc *mdoc)
+elemchild_warn_eq0(struct mdoc *mdoc)
{
assert(MDOC_ELEM == mdoc->last->type);
if (NULL == mdoc->last->child)
return(1);
- return(mdoc_warn(mdoc, WARN_ARGS_EQ0));
+ return(mdoc_pwarn(mdoc, mdoc->last->child->line,
+ mdoc->last->child->pos, WARN_ARGS_EQ0));
}
static int
-post_elemchild_err_ge1(struct mdoc *mdoc)
+elemchild_err_ge1(struct mdoc *mdoc)
{
assert(MDOC_ELEM == mdoc->last->type);
@@ -196,7 +210,20 @@ post_elemchild_err_ge1(struct mdoc *mdoc)
static int
-post_headchild_err_ge1(struct mdoc *mdoc)
+headchild_err_eq0(struct mdoc *mdoc)
+{
+
+ if (MDOC_HEAD != mdoc->last->type)
+ return(1);
+ if (NULL == mdoc->last->child)
+ return(1);
+ return(mdoc_perr(mdoc, mdoc->last->child->line,
+ mdoc->last->child->pos, ERR_ARGS_EQ0));
+}
+
+
+static int
+headchild_err_ge1(struct mdoc *mdoc)
{
if (MDOC_HEAD != mdoc->last->type)
@@ -212,6 +239,9 @@ pre_display(struct mdoc *mdoc, struct mdoc_node *node)
{
struct mdoc_node *n;
+ if (MDOC_BLOCK != node->type)
+ return(1);
+
for (n = mdoc->last; n; n = n->parent)
if (MDOC_BLOCK == n->type)
if (MDOC_Bd == n->data.block.tok)
@@ -223,6 +253,104 @@ pre_display(struct mdoc *mdoc, struct mdoc_node *node)
static int
+pre_bl(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ int type, err;
+ struct mdoc_arg *argv;
+ size_t i, argc;
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ assert(MDOC_Bl == node->data.block.tok);
+
+ argv = NULL;
+ argc = node->data.block.argc;
+
+ for (i = type = err = 0; i < argc; i++) {
+ argv = &node->data.block.argv[(int)i];
+ assert(argv);
+ switch (argv->arg) {
+ case (MDOC_Bullet):
+ /* FALLTHROUGH */
+ case (MDOC_Dash):
+ /* FALLTHROUGH */
+ case (MDOC_Enum):
+ /* FALLTHROUGH */
+ case (MDOC_Hyphen):
+ /* FALLTHROUGH */
+ case (MDOC_Item):
+ /* FALLTHROUGH */
+ case (MDOC_Tag):
+ /* FALLTHROUGH */
+ case (MDOC_Diag):
+ /* FALLTHROUGH */
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
+ case (MDOC_Ohang):
+ /* FALLTHROUGH */
+ case (MDOC_Inset):
+ if (type)
+ err++;
+ type++;
+ break;
+ default:
+ break;
+ }
+ }
+ if (0 == type)
+ return(mdoc_err(mdoc, ERR_SYNTAX_ARGMISS));
+ if (0 == err)
+ return(1);
+ assert(argv);
+ return(mdoc_perr(mdoc, argv->line,
+ argv->pos, ERR_SYNTAX_ARGBAD));
+}
+
+
+static int
+pre_bd(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ int type, err;
+ struct mdoc_arg *argv;
+ size_t i, argc;
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ assert(MDOC_Bd == node->data.block.tok);
+
+ argv = NULL;
+ argc = node->data.block.argc;
+
+ for (err = i = type = 0; 0 == err && i < argc; i++) {
+ argv = &node->data.block.argv[(int)i];
+ assert(argv);
+ switch (argv->arg) {
+ case (MDOC_Ragged):
+ /* FALLTHROUGH */
+ case (MDOC_Unfilled):
+ /* FALLTHROUGH */
+ case (MDOC_Literal):
+ /* FALLTHROUGH */
+ case (MDOC_File):
+ if (type)
+ err++;
+ type++;
+ break;
+ default:
+ break;
+ }
+ }
+ if (0 == type)
+ return(mdoc_err(mdoc, ERR_SYNTAX_ARGMISS));
+ if (0 == err)
+ return(1);
+ assert(argv);
+ return(mdoc_perr(mdoc, argv->line,
+ argv->pos, ERR_SYNTAX_ARGBAD));
+}
+
+
+static int
pre_prologue(struct mdoc *mdoc, struct mdoc_node *node)
{
@@ -274,6 +402,27 @@ pre_prologue(struct mdoc *mdoc, struct mdoc_node *node)
}
+static int
+post_bl(struct mdoc *mdoc)
+{
+ struct mdoc_node *n;
+
+ if (MDOC_BODY != mdoc->last->type)
+ return(1);
+ assert(MDOC_Bl == mdoc->last->data.body.tok);
+
+ for (n = mdoc->last->child; n; n = n->next) {
+ if (MDOC_BLOCK == n->type)
+ if (MDOC_It == n->data.block.tok)
+ continue;
+ break;
+ }
+ if (NULL == n)
+ return(1);
+ return(mdoc_verr(mdoc, n, ERR_SYNTAX_CHILDBAD));
+}
+
+
/*
* Warn if sections (those that are with a known title, such as NAME,
* DESCRIPTION, and so forth) are out of the conventional order.
@@ -316,6 +465,7 @@ post_sh(struct mdoc *mdoc)
int
mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *node)
{
+ v_pre *p;
int t;
switch (node->type) {
@@ -337,7 +487,10 @@ mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *node)
if (NULL == mdoc_valids[t].pre)
return(1);
- return((*mdoc_valids[t].pre)(mdoc, node));
+ for (p = mdoc_valids[t].pre; *p; p++)
+ if ( ! (*p)(mdoc, node))
+ return(0);
+ return(1);
}
@@ -366,7 +519,6 @@ mdoc_valid_post(struct mdoc *mdoc)
if (NULL == mdoc_valids[t].post)
return(1);
-
for (p = mdoc_valids[t].post; *p; p++)
if ( ! (*p)(mdoc))
return(0);