version 1.40, 2008/12/04 23:10:51 |
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, |
Line 83 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 97 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); |
Line 130 static int roffparse(struct rofftree *, char *); |
|
Line 132 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 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 206 static const struct rofftok tokens[ROFF_MAX] = { |
|
Line 211 static const struct rofftok tokens[ROFF_MAX] = { |
|
{ 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 290 static const int tokenargs[ROFF_ARGMAX] = { |
|
Line 295 static const int tokenargs[ROFF_ARGMAX] = { |
|
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 299 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 1144 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) |
{ |
{ |
char *morep[1], *p; |
char *morep[1], *p; |
Line 1393 roff_ordered(ROFFCALL_ARGS) |
|
Line 1434 roff_ordered(ROFFCALL_ARGS) |
|
argv++; |
argv++; |
|
|
if (NULL == *argv) { |
if (NULL == *argv) { |
|
switch (tok) { |
|
case (ROFF_Nm): |
|
if ( ! roffgetname(tree, ordp, *(argv - 1))) |
|
return(0); |
|
break; |
|
default: |
|
*ordp = NULL; |
|
break; |
|
} |
|
|
/* FIXME: satisfies number of args? */ |
|
|
|
ordp[0] = NULL; |
|
return(roffspecial(tree, tok, ordp)); |
return(roffspecial(tree, tok, ordp)); |
} |
} |
|
|
i = 0; |
i = 0; |
while (*argv && i < ROFF_MAXLINEARG) { |
while (*argv && i < ROFF_MAXLINEARG) { |
if (ROFF_MAX != (c = rofffindcallable(*argv))) |
c = rofffindcallable(*argv); |
return(roffcall(tree, c, argv)); |
|
if (roffispunct(*argv)) |
if (ROFF_MAX == c && ! roffispunct(*argv)) { |
|
ordp[i++] = *argv++; |
|
continue; |
|
} |
|
ordp[i] = NULL; |
|
|
|
if (ROFF_MAX == c) |
break; |
break; |
|
|
ordp[i++] = *argv++; |
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; |
ordp[i] = NULL; |
|
|
/* FIXME: too many or too few args? */ |
switch (tok) { |
|
case (ROFF_Nm): |
if (i == ROFF_MAXLINEARG && *argv) { |
if ( ! roffsetname(tree, ordp)) |
roff_err(tree, *argv, "too many args", toknames[tok]); |
return(0); |
return(0); |
break; |
|
default: |
|
break; |
} |
} |
|
|
/* FIXME: error if there's stuff after the punctuation. */ |
|
|
|
if ( ! roffspecial(tree, tok, ordp)) |
if ( ! roffspecial(tree, tok, ordp)) |
return(0); |
return(0); |
|
|
|
/* FIXME: error if there's stuff after the punctuation. */ |
|
|
if ( ! first || NULL == *argv) |
if ( ! first || NULL == *argv) |
return(1); |
return(1); |