version 1.27, 2008/12/01 15:32:36 |
version 1.29, 2008/12/01 16:14:34 |
Line 166 static const int roffarg_St[] = { |
|
Line 166 static const int roffarg_St[] = { |
|
|
|
static const int roffchild_Bl[] = { ROFF_It, ROFF_El, ROFF_MAX }; |
static const int roffchild_Bl[] = { ROFF_It, ROFF_El, ROFF_MAX }; |
static const int roffchild_Fo[] = { ROFF_Fa, ROFF_Fc, ROFF_MAX }; |
static const int roffchild_Fo[] = { ROFF_Fa, ROFF_Fc, ROFF_MAX }; |
static const int roffchild_Oo[] = { ROFF_Op, ROFF_Oc, ROFF_MAX }; |
|
static const int roffchild_Rs[] = { ROFF_Re, ROFF__A, ROFF__B, |
static const int roffchild_Rs[] = { ROFF_Re, ROFF__A, ROFF__B, |
ROFF__D, ROFF__I, ROFF__J, ROFF__N, ROFF__O, ROFF__P, |
ROFF__D, ROFF__I, ROFF__J, ROFF__N, ROFF__O, ROFF__P, |
ROFF__R, ROFF__T, ROFF__V, ROFF_MAX }; |
ROFF__R, ROFF__T, ROFF__V, ROFF_MAX }; |
|
|
static const int roffparent_El[] = { ROFF_Bl, ROFF_It, ROFF_MAX }; |
static const int roffparent_El[] = { ROFF_Bl, ROFF_It, ROFF_MAX }; |
static const int roffparent_Fc[] = { ROFF_Fo, ROFF_Fa, ROFF_MAX }; |
static const int roffparent_Fc[] = { ROFF_Fo, ROFF_Fa, ROFF_MAX }; |
static const int roffparent_Oc[] = { ROFF_Oo, ROFF_Oc, ROFF_MAX }; |
static const int roffparent_Oc[] = { ROFF_Oo, ROFF_MAX }; |
static const int roffparent_It[] = { ROFF_Bl, ROFF_It, ROFF_MAX }; |
static const int roffparent_It[] = { ROFF_Bl, ROFF_It, ROFF_MAX }; |
static const int roffparent_Re[] = { ROFF_Rs, ROFF_MAX }; |
static const int roffparent_Re[] = { ROFF_Rs, ROFF_MAX }; |
|
|
Line 236 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 235 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, 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, 0 }, /* At */ /* XXX at most 2 args */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Bc */ |
{ 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 }, /* 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 | ROFF_CALLABLE | ROFF_LSCOPE }, /* Bq */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Bsx */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Bsx */ |
Line 246 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 245 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 }, /* 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 | ROFF_LSCOPE }, /* Dq */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ec */ |
{ 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 }, /* 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 | ROFF_CALLABLE }, /* Eo */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Fx */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Fx */ |
Line 257 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 256 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 }, /* Ox */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pc */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pc */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Pf */ |
{ 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 | 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 }, /* Qc */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ql */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ql */ |
Line 277 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 276 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xo */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xo */ |
{ roff_layout, NULL, NULL, roffchild_Fo, 0, ROFF_LAYOUT, 0 }, /* Fo */ |
{ roff_layout, NULL, NULL, roffchild_Fo, 0, ROFF_LAYOUT, 0 }, /* Fo */ |
{ roff_noop, NULL, roffparent_Fc, NULL, ROFF_Fo, ROFF_LAYOUT, 0 }, /* Fc */ |
{ roff_noop, NULL, roffparent_Fc, NULL, ROFF_Fo, ROFF_LAYOUT, 0 }, /* Fc */ |
{ roff_layout, NULL, NULL, roffchild_Oo, 0, ROFF_LAYOUT, 0 }, /* Oo */ |
{ roff_layout, NULL, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Oo */ |
{ roff_noop, NULL, roffparent_Oc, NULL, ROFF_Oo, ROFF_LAYOUT, 0 }, /* Oc */ |
{ roff_noop, NULL, roffparent_Oc, NULL, ROFF_Oo, ROFF_LAYOUT, 0 }, /* Oc */ |
{ roff_layout, roffarg_Bk, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Bk */ |
{ roff_layout, roffarg_Bk, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Bk */ |
{ roff_noop, NULL, NULL, NULL, ROFF_Bk, ROFF_LAYOUT, 0 }, /* Ek */ |
{ roff_noop, NULL, NULL, NULL, ROFF_Bk, ROFF_LAYOUT, 0 }, /* Ek */ |
Line 380 roff_free(struct rofftree *tree, int flush) |
|
Line 379 roff_free(struct rofftree *tree, int flush) |
|
error = 1; |
error = 1; |
|
|
if (ROFF_PRELUDE & tree->state) { |
if (ROFF_PRELUDE & tree->state) { |
roff_warn(tree, NULL, "prelude never finished"); |
roff_err(tree, NULL, "prelude never finished"); |
goto end; |
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) |
if (0 != tokens[n->tok].ctx) |
continue; |
continue; |
roff_warn(tree, NULL, "closing explicit scope `%s'", |
roff_err(tree, NULL, "closing explicit scope `%s'", |
toknames[n->tok]); |
toknames[n->tok]); |
goto end; |
goto end; |
} |
} |
Line 439 roff_engine(struct rofftree *tree, char *buf) |
|
Line 438 roff_engine(struct rofftree *tree, char *buf) |
|
assert(buf); |
assert(buf); |
|
|
if (0 == *buf) { |
if (0 == *buf) { |
roff_warn(tree, buf, "blank line"); |
roff_err(tree, buf, "blank line"); |
return(0); |
return(0); |
} else if ('.' != *buf) |
} else if ('.' != *buf) |
return(textparse(tree, buf)); |
return(textparse(tree, buf)); |
Line 554 roffparse(struct rofftree *tree, char *buf) |
|
Line 553 roffparse(struct rofftree *tree, char *buf) |
|
if (ROFF_PRELUDE & tree->state) { |
if (ROFF_PRELUDE & tree->state) { |
assert(NULL == tree->last); |
assert(NULL == tree->last); |
return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER)); |
return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER)); |
} else |
} |
assert(tree->last); |
|
|
|
assert(ROFF_BODY & tree->state); |
assert(ROFF_BODY & tree->state); |
|
|
Line 564 roffparse(struct rofftree *tree, char *buf) |
|
Line 562 roffparse(struct rofftree *tree, char *buf) |
|
* children are satisfied. |
* 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'", |
roff_err(tree, *argvp, "`%s' has invalid parent `%s'", |
toknames[tok], |
toknames[tok], |
toknames[tree->last->tok]); |
toknames[tree->last->tok]); |
return(0); |
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'", |
roff_err(tree, *argvp, "`%s' is invalid child of `%s'", |
toknames[tok], |
toknames[tok], |
toknames[tree->last->tok]); |
toknames[tree->last->tok]); |
Line 614 roffparse(struct rofftree *tree, char *buf) |
|
Line 614 roffparse(struct rofftree *tree, char *buf) |
|
n = NULL; |
n = NULL; |
break; |
break; |
} |
} |
|
if (tokens[n->tok].ctx == n->tok) |
|
continue; |
|
roff_err(tree, *argv, "`%s' breaks `%s' scope", |
|
toknames[tok], toknames[n->tok]); |
|
return(0); |
} |
} |
|
|
/* |
/* |
Line 647 roffparse(struct rofftree *tree, char *buf) |
|
Line 652 roffparse(struct rofftree *tree, char *buf) |
|
* In this, the `El' tag closes out the scope of `Bl'. |
* In this, the `El' tag closes out the scope of `Bl'. |
*/ |
*/ |
|
|
assert(tree->last); |
|
assert(tok != tokens[tok].ctx && 0 != tokens[tok].ctx); |
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 */ |
/* LINTED */ |
do { |
do { |
t = tree->last->tok; |
t = tree->last->tok; |
Line 657 roffparse(struct rofftree *tree, char *buf) |
|
Line 679 roffparse(struct rofftree *tree, char *buf) |
|
return(0); |
return(0); |
} while (t != tokens[tok].ctx); |
} while (t != tokens[tok].ctx); |
|
|
assert(tree->last); |
|
return(1); |
return(1); |
} |
} |
|
|
Line 940 roff_Os(ROFFCALL_ARGS) |
|
Line 961 roff_Os(ROFFCALL_ARGS) |
|
{ |
{ |
|
|
if (ROFF_EXIT == type) { |
if (ROFF_EXIT == type) { |
roffnode_free(tree); |
|
return((*tree->cb.rofftail)(tree->arg)); |
return((*tree->cb.rofftail)(tree->arg)); |
} else if (ROFF_BODY & tree->state) { |
} else if (ROFF_BODY & tree->state) { |
assert( ! (ROFF_PRELUDE & tree->state)); |
assert( ! (ROFF_PRELUDE & tree->state)); |
Line 962 roff_Os(ROFFCALL_ARGS) |
|
Line 982 roff_Os(ROFFCALL_ARGS) |
|
tree->state |= ROFF_BODY; |
tree->state |= ROFF_BODY; |
|
|
assert(NULL == tree->last); |
assert(NULL == tree->last); |
|
|
if (NULL == roffnode_new(tok, tree)) |
|
return(0); |
|
|
|
return((*tree->cb.roffhead)(tree->arg)); |
return((*tree->cb.roffhead)(tree->arg)); |
} |
} |