version 1.61, 2008/12/10 13:15:55 |
version 1.64, 2008/12/12 10:11:10 |
|
|
/* TODO: (warn) some sections need specific elements. */ |
/* TODO: (warn) some sections need specific elements. */ |
/* TODO: (warn) NAME section has particular order. */ |
/* TODO: (warn) NAME section has particular order. */ |
/* TODO: macros with a set number of arguments? */ |
/* TODO: macros with a set number of arguments? */ |
/* TODO: validate Dt macro arguments. */ |
|
/* FIXME: Bl -diag supposed to ignore callable children. */ |
/* FIXME: Bl -diag supposed to ignore callable children. */ |
|
|
struct roffnode { |
struct roffnode { |
Line 75 struct rofftree { |
|
Line 74 struct rofftree { |
|
void *arg; /* Callbacks' arg. */ |
void *arg; /* Callbacks' arg. */ |
int csec; /* Current section. */ |
int csec; /* Current section. */ |
int asec; /* Thus-far sections. */ |
int asec; /* Thus-far sections. */ |
|
int literal; /* Literal mode. */ |
}; |
}; |
|
|
static struct roffnode *roffnode_new(int, struct rofftree *); |
static struct roffnode *roffnode_new(int, struct rofftree *); |
Line 219 textparse(struct rofftree *tree, char *buf) |
|
Line 219 textparse(struct rofftree *tree, char *buf) |
|
if ( ! (ROFFSec_NAME & tree->asec)) |
if ( ! (ROFFSec_NAME & tree->asec)) |
return(roff_err(tree, buf, "data before `NAME' section")); |
return(roff_err(tree, buf, "data before `NAME' section")); |
|
|
|
if (tree->literal) |
|
return(roffdata(tree, 0, buf)); |
|
|
/* LINTED */ |
/* LINTED */ |
while (*buf) { |
while (*buf) { |
while (*buf && isspace(*buf)) |
while (*buf && isspace(*buf)) |
|
|
roff_layout(ROFFCALL_ARGS) |
roff_layout(ROFFCALL_ARGS) |
{ |
{ |
int i, c, argcp[ROFF_MAXLINEARG]; |
int i, c, argcp[ROFF_MAXLINEARG]; |
char *argvp[ROFF_MAXLINEARG]; |
char *argvp[ROFF_MAXLINEARG], *p; |
|
|
/* |
/* |
* The roff_layout function is for multi-line macros. A layout |
* The roff_layout function is for multi-line macros. A layout |
Line 1182 roff_layout(ROFFCALL_ARGS) |
|
Line 1185 roff_layout(ROFFCALL_ARGS) |
|
|
|
assert( ! (ROFF_CALLABLE & tokens[tok].flags)); |
assert( ! (ROFF_CALLABLE & tokens[tok].flags)); |
|
|
if ( ! ROFFSec_NAME & tree->asec) |
if ( ! (ROFFSec_PR_Os & tree->asec)) |
return(roff_errp(tree, *argv, tok, ERR_NOT_PR)); |
return(roff_errp(tree, *argv, tok, ERR_NOT_PR)); |
|
|
if (ROFF_EXIT == type) { |
if (ROFF_EXIT == type) { |
Line 1192 roff_layout(ROFFCALL_ARGS) |
|
Line 1195 roff_layout(ROFFCALL_ARGS) |
|
return((*tree->cb.roffblkout)(tree->arg, tok)); |
return((*tree->cb.roffblkout)(tree->arg, tok)); |
} |
} |
|
|
argv++; |
p = *argv++; |
assert( ! (ROFF_CALLABLE & tokens[tok].flags)); |
assert( ! (ROFF_CALLABLE & tokens[tok].flags)); |
|
|
if ( ! roffparseopts(tree, tok, &argv, argcp, argvp)) |
if ( ! roffparseopts(tree, tok, &argv, argcp, argvp)) |
Line 1229 roff_layout(ROFFCALL_ARGS) |
|
Line 1232 roff_layout(ROFFCALL_ARGS) |
|
/* +++ Begin run macro-specific hooks over argv. */ |
/* +++ Begin run macro-specific hooks over argv. */ |
|
|
switch (tok) { |
switch (tok) { |
|
case (ROFF_Bd): |
|
tree->literal++; |
|
break; |
|
|
case (ROFF_Sh): |
case (ROFF_Sh): |
if (NULL == *argv) { |
if (NULL == *argv) { |
argv--; |
argv--; |
Line 1249 roff_layout(ROFFCALL_ARGS) |
|
Line 1256 roff_layout(ROFFCALL_ARGS) |
|
return(0); |
return(0); |
|
|
tree->asec |= tree->csec; |
tree->asec |= tree->csec; |
|
|
|
if ( ! roffspecial(tree, tok, p, argcp, |
|
(const char **)argvp, 0, argv)) |
|
return(0); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 1346 roff_ordered(ROFFCALL_ARGS) |
|
Line 1357 roff_ordered(ROFFCALL_ARGS) |
|
* .Xr arg1 arg2 punctuation |
* .Xr arg1 arg2 punctuation |
*/ |
*/ |
|
|
if ( ! ROFFSec_NAME & tree->asec) |
if ( ! (ROFFSec_PR_Os & tree->asec)) |
return(roff_errp(tree, *argv, tok, ERR_NOT_PR)); |
return(roff_errp(tree, *argv, tok, ERR_NOT_PR)); |
|
|
first = (*argv == tree->cur); |
first = (*argv == tree->cur); |
Line 1399 roff_ordered(ROFFCALL_ARGS) |
|
Line 1410 roff_ordered(ROFFCALL_ARGS) |
|
} |
} |
|
|
|
|
|
static int |
|
macro_default(struct rofftree *tree, int tok, char *args[]) |
|
{ |
|
char **p; |
|
char *argv[ROFF_MAXLINEARG]; |
|
int i, argc[ROFF_MAXLINEARG]; |
|
|
|
if ( ! roffparseopts(tree, tok, &args, argc, argv)) |
|
return(0); |
|
|
|
if ( ! (ROFF_PARSED & tokens[tok].flags)) |
|
return((*tree->cb.macro)(tree->arg, tok, argc, argv, 0, args)); |
|
|
|
p = args; |
|
|
|
while (*args) { |
|
c = rofffindcallable(*args); |
|
if (ROFF_MAX == c) { |
|
if (roffispunct(*args)) { |
|
|
|
|
|
} |
|
} |
|
|
|
if (ROFF_MAX != (c = rofffindcallable(*argv))) { |
|
if ( ! (ROFF_LSCOPE & tokens[tok].flags)) |
|
if ( ! (*tree->cb.roffout)(tree->arg, tok)) |
|
return(0); |
|
|
|
if ( ! roffcall(tree, c, argv)) |
|
return(0); |
|
if (ROFF_LSCOPE & tokens[tok].flags) |
|
if ( ! (*tree->cb.roffout)(tree->arg, tok)) |
|
return(0); |
|
break; |
|
} |
|
|
|
if ( ! roffispunct(*argv)) { |
|
if ( ! roffdata(tree, i++, *argv++)) |
|
return(0); |
|
continue; |
|
} |
|
|
|
i = 1; |
|
for (j = 0; argv[j]; j++) |
|
if ( ! roffispunct(argv[j])) |
|
break; |
|
|
|
if (argv[j]) { |
|
if (ROFF_LSCOPE & tokens[tok].flags) { |
|
if ( ! roffdata(tree, 0, *argv++)) |
|
return(0); |
|
continue; |
|
} |
|
if ( ! (*tree->cb.roffout)(tree->arg, tok)) |
|
return(0); |
|
if ( ! roffdata(tree, 0, *argv++)) |
|
return(0); |
|
if ( ! (*tree->cb.roffin)(tree->arg, tok, |
|
argcp, |
|
(const char **)argvp)) |
|
return(0); |
|
|
|
i = 0; |
|
continue; |
|
} |
|
|
|
if ( ! (*tree->cb.roffout)(tree->arg, tok)) |
|
return(0); |
|
break; |
|
} |
|
} |
|
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
static int |
static int |
roff_text(ROFFCALL_ARGS) |
roff_text(ROFFCALL_ARGS) |
Line 1418 roff_text(ROFFCALL_ARGS) |
|
Line 1503 roff_text(ROFFCALL_ARGS) |
|
* <fl> v W f </fl> ; |
* <fl> v W f </fl> ; |
*/ |
*/ |
|
|
if ( ! ROFFSec_NAME & tree->asec) |
if ( ! (ROFFSec_PR_Os & tree->asec)) |
return(roff_errp(tree, *argv, tok, ERR_NOT_PR)); |
return(roff_errp(tree, *argv, tok, ERR_NOT_PR)); |
|
|
first = (*argv == tree->cur); |
first = (*argv == tree->cur); |
|
|
roff_noop(ROFFCALL_ARGS) |
roff_noop(ROFFCALL_ARGS) |
{ |
{ |
|
|
|
switch (tok) { |
|
case (ROFF_Ed): |
|
tree->literal--; |
|
break; |
|
default: |
|
break; |
|
} |
|
|
return(1); |
return(1); |
} |
} |
|
|
Line 1526 roff_depr(ROFFCALL_ARGS) |
|
Line 1619 roff_depr(ROFFCALL_ARGS) |
|
} |
} |
|
|
|
|
|
/* FIXME: push this into the filter. */ |
static int |
static int |
roff_warnp(const struct rofftree *tree, const char *pos, |
roff_warnp(const struct rofftree *tree, const char *pos, |
int tok, enum rofferr type) |
int tok, enum rofferr type) |
Line 1560 roff_warn(const struct rofftree *tree, const char *pos |
|
Line 1654 roff_warn(const struct rofftree *tree, const char *pos |
|
} |
} |
|
|
|
|
|
/* FIXME: push this into the filter. */ |
static int |
static int |
roff_errp(const struct rofftree *tree, const char *pos, |
roff_errp(const struct rofftree *tree, const char *pos, |
int tok, enum rofferr type) |
int tok, enum rofferr type) |