version 1.39, 2008/12/04 19:31:57 |
version 1.42, 2008/12/05 22:34:30 |
|
|
/* TODO: unify empty-content tags a la <br />. */ |
/* TODO: unify empty-content tags a la <br />. */ |
/* TODO: macros with a set number of arguments? */ |
/* TODO: macros with a set number of arguments? */ |
/* TODO: validate Dt macro arguments. */ |
/* TODO: validate Dt macro arguments. */ |
|
/* FIXME: Bl -diag ignore callable children. */ |
|
|
enum roffd { |
enum roffd { |
ROFF_ENTER = 0, |
ROFF_ENTER = 0, |
|
|
const int *children; /* Limit to kids. */ |
const int *children; /* Limit to kids. */ |
int ctx; /* Blk-close node. */ |
int ctx; /* Blk-close node. */ |
enum rofftype type; /* Type of macro. */ |
enum rofftype type; /* Type of macro. */ |
int flags; |
int flags; |
#define ROFF_PARSED (1 << 0) /* "Parsed". */ |
#define ROFF_PARSED (1 << 0) /* "Parsed". */ |
#define ROFF_CALLABLE (1 << 1) /* "Callable". */ |
#define ROFF_CALLABLE (1 << 1) /* "Callable". */ |
#define ROFF_SHALLOW (1 << 2) /* Nesting block. */ |
#define ROFF_SHALLOW (1 << 2) /* Nesting block. */ |
#define ROFF_LSCOPE (1 << 3) /* Line scope. */ |
#define ROFF_LSCOPE (1 << 3) /* Line scope. */ |
}; |
}; |
|
|
struct roffarg { |
|
int flags; |
|
#define ROFF_VALUE (1 << 0) /* Has a value. */ |
|
}; |
|
|
|
struct roffnode { |
struct roffnode { |
int tok; /* Token id. */ |
int tok; /* Token id. */ |
struct roffnode *parent; /* Parent (or NULL). */ |
struct roffnode *parent; /* Parent (or NULL). */ |
Line 88 struct rofftree { |
|
Line 84 struct rofftree { |
|
struct roffnode *last; /* Last parsed node. */ |
struct roffnode *last; /* Last parsed node. */ |
char *cur; /* Line start. */ |
char *cur; /* Line start. */ |
struct tm tm; /* `Dd' results. */ |
struct tm tm; /* `Dd' results. */ |
|
char name[64]; /* `Nm' results. */ |
char os[64]; /* `Os' results. */ |
char os[64]; /* `Os' results. */ |
char title[64]; /* `Dt' results. */ |
char title[64]; /* `Dt' results. */ |
char section[64]; /* `Dt' results. */ |
char section[64]; /* `Dt' results. */ |
Line 102 struct rofftree { |
|
Line 99 struct rofftree { |
|
void *arg; /* Callbacks' arg. */ |
void *arg; /* Callbacks' arg. */ |
}; |
}; |
|
|
static int roff_Dd(ROFFCALL_ARGS); |
static int roff_Dd(ROFFCALL_ARGS); /* FIXME: deprecate. */ |
static int roff_Dt(ROFFCALL_ARGS); |
static int roff_Dt(ROFFCALL_ARGS); /* FIXME: deprecate. */ |
static int roff_Os(ROFFCALL_ARGS); |
static int roff_Os(ROFFCALL_ARGS); /* FIXME: deprecate. */ |
static int roff_Ns(ROFFCALL_ARGS); |
static int roff_Ns(ROFFCALL_ARGS); /* FIXME: deprecate. */ |
static int roff_Sm(ROFFCALL_ARGS); |
static int roff_Sm(ROFFCALL_ARGS); /* FIXME: deprecate. */ |
static int roff_layout(ROFFCALL_ARGS); |
static int roff_layout(ROFFCALL_ARGS); |
static int roff_text(ROFFCALL_ARGS); |
static int roff_text(ROFFCALL_ARGS); |
static int roff_noop(ROFFCALL_ARGS); |
static int roff_noop(ROFFCALL_ARGS); |
static int roff_depr(ROFFCALL_ARGS); |
static int roff_depr(ROFFCALL_ARGS); |
|
static int roff_ordered(ROFFCALL_ARGS); |
static struct roffnode *roffnode_new(int, struct rofftree *); |
static struct roffnode *roffnode_new(int, struct rofftree *); |
static void roffnode_free(struct rofftree *); |
static void roffnode_free(struct rofftree *); |
static void roff_warn(const struct rofftree *, |
static void roff_warn(const struct rofftree *, |
Line 133 static int roffcall(struct rofftree *, int, char ** |
|
Line 131 static int roffcall(struct rofftree *, int, char ** |
|
static int roffparse(struct rofftree *, char *); |
static int roffparse(struct rofftree *, char *); |
static int textparse(struct rofftree *, char *); |
static int textparse(struct rofftree *, char *); |
static int roffdata(struct rofftree *, int, char *); |
static int roffdata(struct rofftree *, int, char *); |
|
static int roffspecial(struct rofftree *, int, char **); |
|
static int roffsetname(struct rofftree *, char **); |
|
static int roffgetname(struct rofftree *, char **, |
|
const char *); |
|
|
#ifdef __linux__ |
#ifdef __linux__ |
extern size_t strlcat(char *, const char *, size_t); |
extern size_t strlcat(char *, const char *, size_t); |
Line 203 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 205 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fa */ /* XXX needs arg */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fa */ /* XXX needs arg */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Fd */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Fd */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fl */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fl */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fn */ /* XXX needs arg */ /* FIXME */ |
{roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, /*XXX*/ -1 }, /* Fn */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ft */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ft */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ic */ /* XXX needs arg */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ic */ /* XXX needs arg */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* In */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* In */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Li */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Li */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Nd */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Nd */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Nm */ /* FIXME */ |
{roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Nm */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Op */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Op */ |
{ roff_depr, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ot */ |
{ roff_depr, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ot */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pa */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pa */ |
Line 217 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 219 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ roff_text, roffarg_St, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* St */ |
{ roff_text, roffarg_St, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* St */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Va */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Va */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Vt */ /* XXX needs arg */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Vt */ /* XXX needs arg */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xr */ /* XXX needs arg */ |
{roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, /*XXX*/ -1 }, /* Xr */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* %A */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* %A */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE}, /* %B */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE}, /* %B */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* %D */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* %D */ |
Line 249 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 251 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ 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 */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ms */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ms */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */ |
{ roff_Ns, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ns */ |
{ roff_Ns, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ns */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Nx */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Nx */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ox */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ox */ |
Line 271 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 273 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sy */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sy */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Tn */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Tn */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ux */ |
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ux */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xc */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xc */ |
{ 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, NULL, 0, ROFF_LAYOUT, 0 }, /* Oo */ |
{ roff_layout, NULL, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Oo */ |
Line 285 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 287 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ud */ |
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ud */ |
}; |
}; |
|
|
|
#define ROFF_VALUE (1 << 0) |
|
|
static const int tokenargs[ROFF_ARGMAX] = { |
static const int tokenargs[ROFF_ARGMAX] = { |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, ROFF_VALUE, ROFF_VALUE, 0, |
0, ROFF_VALUE, ROFF_VALUE, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, ROFF_VALUE, 0, |
0, 0, ROFF_VALUE, 0, |
|
0, ROFF_VALUE, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
Line 300 static const int tokenargs[ROFF_ARGMAX] = { |
|
Line 305 static const int tokenargs[ROFF_ARGMAX] = { |
|
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
0, 0, 0, 0, |
|
}; |
}; |
|
|
const char *const toknamesp[ROFF_MAX] = { |
const char *const toknamesp[ROFF_MAX] = { |
Line 501 roffargs(const struct rofftree *tree, |
|
Line 505 roffargs(const struct rofftree *tree, |
|
|
|
p = buf; |
p = buf; |
|
|
|
/* |
|
* This is an ugly little loop. It parses a line into |
|
* space-delimited tokens. If a quote mark is encountered, a |
|
* token is alloted the entire quoted text. If whitespace is |
|
* escaped, it's included in the prior alloted token. |
|
*/ |
|
|
/* LINTED */ |
/* LINTED */ |
for (i = 0; *buf && i < ROFF_MAXLINEARG; i++) { |
for (i = 0; *buf && i < ROFF_MAXLINEARG; i++) { |
if ('\"' == *buf) { |
if ('\"' == *buf) { |
Line 516 roffargs(const struct rofftree *tree, |
|
Line 527 roffargs(const struct rofftree *tree, |
|
} |
} |
} else { |
} else { |
argv[i] = buf++; |
argv[i] = buf++; |
while (*buf && ! isspace(*buf)) |
while (*buf) { |
buf++; |
if ( ! isspace(*buf)) { |
|
buf++; |
|
continue; |
|
} |
|
if (*(buf - 1) == '\\') { |
|
buf++; |
|
continue; |
|
} |
|
break; |
|
} |
if (0 == *buf) |
if (0 == *buf) |
continue; |
continue; |
} |
} |
Line 525 roffargs(const struct rofftree *tree, |
|
Line 545 roffargs(const struct rofftree *tree, |
|
while (*buf && isspace(*buf)) |
while (*buf && isspace(*buf)) |
buf++; |
buf++; |
} |
} |
|
|
assert(i > 0); |
assert(i > 0); |
if (ROFF_MAXLINEARG == i && *buf) { |
if (ROFF_MAXLINEARG == i && *buf) { |
roff_err(tree, p, "too many arguments for `%s'", toknames |
roff_err(tree, p, "too many arguments for `%s'", toknames |
Line 861 roffnode_free(struct rofftree *tree) |
|
Line 881 roffnode_free(struct rofftree *tree) |
|
|
|
|
|
static int |
static int |
|
roffspecial(struct rofftree *tree, int tok, char **ordp) |
|
{ |
|
|
|
return((*tree->cb.roffspecial)(tree->arg, tok, |
|
tree->cur, ordp)); |
|
} |
|
|
|
|
|
static int |
roffcall(struct rofftree *tree, int tok, char **argv) |
roffcall(struct rofftree *tree, int tok, char **argv) |
{ |
{ |
|
|
Line 1120 roff_Dt(ROFFCALL_ARGS) |
|
Line 1149 roff_Dt(ROFFCALL_ARGS) |
|
} |
} |
|
|
|
|
|
static int |
|
roffgetname(struct rofftree *tree, char **ordp, const char *start) |
|
{ |
|
if (0 == tree->name[0]) { |
|
roff_err(tree, start, "`Nm' name not set"); |
|
return(0); |
|
} |
|
*ordp++ = tree->name; |
|
*ordp = NULL; |
|
return(1); |
|
} |
|
|
|
|
|
static int |
|
roffsetname(struct rofftree *tree, char **ordp) |
|
{ |
|
|
|
assert(*ordp); |
|
|
|
/* FIXME: not all sections can set this. */ |
|
|
|
if (NULL != *(ordp + 1)) { |
|
roff_err(tree, *ordp, "too many `Nm' args"); |
|
return(0); |
|
} |
|
|
|
if (strlcpy(tree->name, *ordp, sizeof(tree->name)) |
|
>= sizeof(tree->name)) { |
|
roff_err(tree, *ordp, "`Nm' arg too long"); |
|
return(0); |
|
} |
|
|
|
return(1); |
|
} |
|
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
static int |
static int |
roff_Sm(ROFFCALL_ARGS) |
roff_Sm(ROFFCALL_ARGS) |
{ |
{ |
int argcp[1]; |
char *morep[1], *p; |
char *argvp[1], *morep[1], *p; |
|
|
|
p = *argv++; |
p = *argv++; |
|
|
argcp[0] = ROFF_ARGMAX; |
|
argvp[0] = NULL; |
|
if (NULL == (morep[0] = *argv++)) { |
if (NULL == (morep[0] = *argv++)) { |
roff_err(tree, p, "`Sm' expects an argument"); |
roff_err(tree, p, "`Sm' expects an argument"); |
return(0); |
return(0); |
Line 1143 roff_Sm(ROFFCALL_ARGS) |
|
Line 1205 roff_Sm(ROFFCALL_ARGS) |
|
if (*argv) |
if (*argv) |
roff_warn(tree, *argv, "`Sm' shouldn't have arguments"); |
roff_warn(tree, *argv, "`Sm' shouldn't have arguments"); |
|
|
if ( ! (*tree->cb.roffspecial)(tree->arg, |
if ( ! roffspecial(tree, tok, morep)) |
tok, argcp, argvp, morep)) |
|
return(0); |
return(0); |
|
|
while (*argv) |
while (*argv) |
|
|
roff_Ns(ROFFCALL_ARGS) |
roff_Ns(ROFFCALL_ARGS) |
{ |
{ |
int j, c, first; |
int j, c, first; |
int argcp[1]; |
char *morep[1]; |
char *argvp[1], *morep[1]; |
|
|
|
first = (*argv++ == tree->cur); |
first = (*argv++ == tree->cur); |
|
morep[0] = NULL; |
|
|
argcp[0] = ROFF_ARGMAX; |
if ( ! roffspecial(tree, tok, morep)) |
argvp[0] = morep[0] = NULL; |
|
|
|
if ( ! (*tree->cb.roffspecial)(tree->arg, |
|
tok, argcp, argvp, morep)) |
|
return(0); |
return(0); |
|
|
while (*argv) { |
while (*argv) { |
Line 1357 roff_layout(ROFFCALL_ARGS) |
|
Line 1414 roff_layout(ROFFCALL_ARGS) |
|
return(0); |
return(0); |
return((*tree->cb.roffblkbodyin) |
return((*tree->cb.roffblkbodyin) |
(tree->arg, tok, argcp, argvp)); |
(tree->arg, tok, argcp, argvp)); |
|
} |
|
|
|
|
|
/* ARGSUSED */ |
|
static int |
|
roff_ordered(ROFFCALL_ARGS) |
|
{ |
|
int i, first, c; |
|
char *ordp[ROFF_MAXLINEARG]; |
|
|
|
if (ROFF_PRELUDE & tree->state) { |
|
roff_err(tree, *argv, "`%s' disallowed in prelude", |
|
toknames[tok]); |
|
return(0); |
|
} |
|
|
|
first = (*argv == tree->cur); |
|
argv++; |
|
|
|
if (NULL == *argv) { |
|
switch (tok) { |
|
case (ROFF_Nm): |
|
if ( ! roffgetname(tree, ordp, *(argv - 1))) |
|
return(0); |
|
break; |
|
default: |
|
*ordp = NULL; |
|
break; |
|
} |
|
|
|
return(roffspecial(tree, tok, ordp)); |
|
} |
|
|
|
i = 0; |
|
while (*argv && i < ROFF_MAXLINEARG) { |
|
c = rofffindcallable(*argv); |
|
|
|
if (ROFF_MAX == c && ! roffispunct(*argv)) { |
|
ordp[i++] = *argv++; |
|
continue; |
|
} |
|
ordp[i] = NULL; |
|
|
|
if (ROFF_MAX == c) |
|
break; |
|
|
|
switch (tok) { |
|
case (ROFF_Nm): |
|
if ( ! roffsetname(tree, ordp)) |
|
return(0); |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
if ( ! roffspecial(tree, tok, ordp)) |
|
return(0); |
|
|
|
return(roffcall(tree, c, ordp)); |
|
} |
|
|
|
assert(i != ROFF_MAXLINEARG); |
|
ordp[i] = NULL; |
|
|
|
switch (tok) { |
|
case (ROFF_Nm): |
|
if ( ! roffsetname(tree, ordp)) |
|
return(0); |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
if ( ! roffspecial(tree, tok, ordp)) |
|
return(0); |
|
|
|
/* FIXME: error if there's stuff after the punctuation. */ |
|
|
|
if ( ! first || NULL == *argv) |
|
return(1); |
|
|
|
return(roffpurgepunct(tree, argv)); |
} |
} |
|
|
|
|