aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2008-12-01 16:01:28 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2008-12-01 16:01:28 +0000
commit34e63140e4025ce706092434e50fc5b5000f30cd (patch)
treec5ee9ec5fc49ecb7765718e605995cc411c37168 /roff.c
parentfb2ebae7857605ebef35d26c56cccc959812585e (diff)
downloadmandoc-34e63140e4025ce706092434e50fc5b5000f30cd.tar.gz
mandoc-34e63140e4025ce706092434e50fc5b5000f30cd.tar.zst
mandoc-34e63140e4025ce706092434e50fc5b5000f30cd.zip
Considerable scoping fixes.
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/roff.c b/roff.c
index 3d22e9de..ebf07b3d 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.27 2008/12/01 15:32:36 kristaps Exp $ */
+/* $Id: roff.c,v 1.28 2008/12/01 16:01:28 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -236,7 +236,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Aq */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* At */ /* XXX at most 2 args */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Bc */
- { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Bf */ /* FIXME */
+ { roff_layout, NULL, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Bf */ /* FIXME */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Bo */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Bq */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Bsx */
@@ -246,7 +246,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Do */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Dq */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ec */
- { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ef */ /* FIXME */
+ { roff_noop, NULL, NULL, NULL, ROFF_Bf, ROFF_LAYOUT, 0 }, /* Ef */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Em */ /* XXX needs arg */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Eo */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Fx */
@@ -257,7 +257,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ox */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pc */
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Pf */
- { roff_text, NULL, NULL, NULL, 0, ROFF_LAYOUT, ROFF_PARSED | ROFF_CALLABLE }, /* Po */
+ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Po */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Pq */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Qc */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ql */
@@ -380,14 +380,14 @@ roff_free(struct rofftree *tree, int flush)
error = 1;
if (ROFF_PRELUDE & tree->state) {
- roff_warn(tree, NULL, "prelude never finished");
+ roff_err(tree, NULL, "prelude never finished");
goto end;
}
- for (n = tree->last; n->parent; n = n->parent) {
+ for (n = tree->last; n; n = n->parent) {
if (0 != tokens[n->tok].ctx)
continue;
- roff_warn(tree, NULL, "closing explicit scope `%s'",
+ roff_err(tree, NULL, "closing explicit scope `%s'",
toknames[n->tok]);
goto end;
}
@@ -554,8 +554,7 @@ roffparse(struct rofftree *tree, char *buf)
if (ROFF_PRELUDE & tree->state) {
assert(NULL == tree->last);
return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER));
- } else
- assert(tree->last);
+ }
assert(ROFF_BODY & tree->state);
@@ -564,14 +563,16 @@ roffparse(struct rofftree *tree, char *buf)
* children are satisfied.
*/
- if ( ! roffscan(tree->last->tok, tokens[tok].parents)) {
+ if (tree->last && ! roffscan
+ (tree->last->tok, tokens[tok].parents)) {
roff_err(tree, *argvp, "`%s' has invalid parent `%s'",
toknames[tok],
toknames[tree->last->tok]);
return(0);
}
- if ( ! roffscan(tok, tokens[tree->last->tok].children)) {
+ if (tree->last && ! roffscan
+ (tok, tokens[tree->last->tok].children)) {
roff_err(tree, *argvp, "`%s' is invalid child of `%s'",
toknames[tok],
toknames[tree->last->tok]);
@@ -614,6 +615,11 @@ roffparse(struct rofftree *tree, char *buf)
n = NULL;
break;
}
+ if (tokens[n->tok].ctx == n->tok)
+ continue;
+ roff_err(tree, *argv, "`%s' breaks `%s' scope",
+ toknames[tok], toknames[n->tok]);
+ return(0);
}
/*
@@ -647,9 +653,26 @@ roffparse(struct rofftree *tree, char *buf)
* In this, the `El' tag closes out the scope of `Bl'.
*/
- assert(tree->last);
assert(tok != tokens[tok].ctx && 0 != tokens[tok].ctx);
+ for (n = tree->last; n; n = n->parent)
+ if (n->tok != tokens[tok].ctx) {
+ if (n->tok == tokens[n->tok].ctx)
+ continue;
+ roff_err(tree, *argv, "`%s' breaks `%s' scope",
+ toknames[tok], toknames[n->tok]);
+ return(0);
+ } else
+ break;
+
+
+ if (NULL == n) {
+ roff_err(tree, *argv, "`%s' has no starting tag `%s'",
+ toknames[tok],
+ toknames[tokens[tok].ctx]);
+ return(0);
+ }
+
/* LINTED */
do {
t = tree->last->tok;
@@ -657,7 +680,6 @@ roffparse(struct rofftree *tree, char *buf)
return(0);
} while (t != tokens[tok].ctx);
- assert(tree->last);
return(1);
}
@@ -940,7 +962,6 @@ roff_Os(ROFFCALL_ARGS)
{
if (ROFF_EXIT == type) {
- roffnode_free(tree);
return((*tree->cb.rofftail)(tree->arg));
} else if (ROFF_BODY & tree->state) {
assert( ! (ROFF_PRELUDE & tree->state));
@@ -963,9 +984,6 @@ roff_Os(ROFFCALL_ARGS)
assert(NULL == tree->last);
- if (NULL == roffnode_new(tok, tree))
- return(0);
-
return((*tree->cb.roffhead)(tree->arg));
}