summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macro.c93
-rw-r--r--mdoc.c142
-rw-r--r--private.h9
-rw-r--r--strings.c2
4 files changed, 156 insertions, 90 deletions
diff --git a/macro.c b/macro.c
index 7fa37d96..6e2258d8 100644
--- a/macro.c
+++ b/macro.c
@@ -35,6 +35,17 @@ static int rewind_expblock(struct mdoc *, int, int, int);
static int rewind_head(struct mdoc *, int, int);
static int rewind_body(struct mdoc *, int, int, int);
static int append_delims(struct mdoc *, int, int *, char *);
+static int lookup(struct mdoc *, int, const char *);
+
+
+static int
+lookup(struct mdoc *mdoc, int from, const char *p)
+{
+
+ if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
+ return(MDOC_MAX);
+ return(mdoc_find(mdoc, p));
+}
static int
@@ -292,7 +303,7 @@ macro_close_explicit(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
+ if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
if ( ! flushed) {
if ( ! rewind_expblock(mdoc, ppos, tok, tt))
return(0);
@@ -383,7 +394,7 @@ macro_text(MACRO_PROT_ARGS)
if (ARGS_PUNCT == c)
break;
- if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
+ if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
if ( ! rewind_elem(mdoc, ppos, tok)) {
mdoc_argv_free(argc, argv);
return(0);
@@ -426,8 +437,9 @@ macro_text(MACRO_PROT_ARGS)
int
macro_scoped(MACRO_PROT_ARGS)
{
- int c, lastarg, argc;
+ int c, lastarg, argc, j;
struct mdoc_arg argv[MDOC_LINEARG_MAX];
+ char *p;
assert ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags));
@@ -458,22 +470,45 @@ macro_scoped(MACRO_PROT_ARGS)
mdoc_argv_free(argc, argv);
- /* XXX - Assumes header isn't parsed! */
-
- if (0 != buf[*pos]) {
- mdoc_head_alloc(mdoc, ppos, tok);
+ if (0 == buf[*pos]) {
+ mdoc_body_alloc(mdoc, ppos, tok);
mdoc->next = MDOC_NEXT_CHILD;
+ return(1);
+ }
- mdoc_word_alloc(mdoc, lastarg, &buf[*pos]);
- mdoc->next = MDOC_NEXT_SIBLING;
+ mdoc_head_alloc(mdoc, ppos, tok);
+ mdoc->next = MDOC_NEXT_CHILD;
- if ( ! rewind_head(mdoc, ppos, tok))
+ for (j = 0; j < MDOC_LINEARG_MAX; j++) {
+ lastarg = *pos;
+ c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p);
+
+ if (ARGS_ERROR == c)
return(0);
+ if (ARGS_PUNCT == c)
+ break;
+ if (ARGS_EOLN == c)
+ break;
+
+ if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
+ mdoc_word_alloc(mdoc, lastarg, p);
+ mdoc->next = MDOC_NEXT_SIBLING;
+ continue;
+ }
- while (buf[*pos])
- (*pos)++;
+ if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
+ return(0);
+ break;
}
+ if (j == MDOC_LINEARG_MAX)
+ return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
+
+ if ( ! rewind_head(mdoc, ppos, tok))
+ return(0);
+ if (1 == ppos && ! append_delims(mdoc, tok, pos, buf))
+ return(0);
+
mdoc_body_alloc(mdoc, ppos, tok);
mdoc->next = MDOC_NEXT_CHILD;
@@ -516,7 +551,7 @@ macro_scoped_line(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX == (c = mdoc_find(mdoc, p))) {
+ if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
mdoc_word_alloc(mdoc, lastarg, p);
mdoc->next = MDOC_NEXT_SIBLING;
continue;
@@ -591,7 +626,7 @@ macro_constant_scoped(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
+ if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
if ( ! flushed) {
if ( ! rewind_head(mdoc, ppos, tok))
return(0);
@@ -641,7 +676,8 @@ macro_constant_scoped(MACRO_PROT_ARGS)
int
macro_constant_delimited(MACRO_PROT_ARGS)
{
- int lastarg, flushed, j, c, maxargs;
+ int lastarg, flushed, j, c, maxargs, argc;
+ struct mdoc_arg argv[MDOC_LINEARG_MAX];
char *p;
lastarg = ppos;
@@ -653,6 +689,8 @@ macro_constant_delimited(MACRO_PROT_ARGS)
case (MDOC_Ns):
/* FALLTHROUGH */
case (MDOC_Ux):
+ /* FALLTHROUGH */
+ case (MDOC_St):
maxargs = 0;
break;
default:
@@ -660,9 +698,27 @@ macro_constant_delimited(MACRO_PROT_ARGS)
break;
}
- mdoc_elem_alloc(mdoc, lastarg, tok, 0, NULL);
+ for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
+ lastarg = *pos;
+ c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf);
+ if (ARGV_EOLN == c || ARGV_WORD == c)
+ break;
+ else if (ARGV_ARG == c)
+ continue;
+ mdoc_argv_free(argc, argv);
+ return(0);
+ }
+
+ if ( ! mdoc_valid_pre(mdoc, tok, ppos, argc, argv)) {
+ mdoc_argv_free(argc, argv);
+ return(0);
+ }
+
+ mdoc_elem_alloc(mdoc, lastarg, tok, argc, argv);
mdoc->next = MDOC_NEXT_CHILD;
+ mdoc_argv_free(argc, argv);
+
for (j = 0; j < MDOC_LINEARG_MAX; j++) {
lastarg = *pos;
@@ -680,7 +736,7 @@ macro_constant_delimited(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
+ if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
if ( ! flushed && ! rewind_elem(mdoc, ppos, tok))
return(0);
flushed = 1;
@@ -722,6 +778,9 @@ macro_constant(MACRO_PROT_ARGS)
struct mdoc_arg argv[MDOC_LINEARG_MAX];
char *p;
+ /*assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));*/
+ /*FIXME*/
+
fl = 0;
if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
fl = ARGS_QUOTED;
diff --git a/mdoc.c b/mdoc.c
index f7a9754a..8ce5f3a4 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -91,99 +91,102 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ macro_scoped, 0 }, /* Sh */
{ macro_scoped, 0 }, /* Ss */
{ macro_text, 0 }, /* Pp */
- { macro_scoped_line, 0 }, /* D1 */
- { macro_scoped_line, 0 }, /* Dl */
+ { macro_scoped_line, MDOC_PARSED }, /* D1 */
+ { macro_scoped_line, MDOC_PARSED }, /* Dl */
{ macro_scoped, MDOC_EXPLICIT }, /* Bd */
{ macro_close_explicit, 0 }, /* Ed */
{ macro_scoped, MDOC_EXPLICIT }, /* Bl */
{ macro_close_explicit, 0 }, /* El */
- { macro_scoped, MDOC_NESTED }, /* It */
- { macro_text, MDOC_CALLABLE }, /* Ad */
- { macro_constant, 0 }, /* An */
- { macro_text, MDOC_CALLABLE }, /* Ar */
+ { macro_scoped, MDOC_NESTED | MDOC_PARSED }, /* It */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
+ { macro_constant, MDOC_PARSED }, /* An */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
{ macro_constant, MDOC_QUOTABLE }, /* Cd */
- { macro_text, MDOC_CALLABLE }, /* Cm */
- { macro_text, MDOC_CALLABLE }, /* Dv */
- { macro_text, MDOC_CALLABLE }, /* Er */
- { macro_text, MDOC_CALLABLE }, /* Ev */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */
{ macro_constant, 0 }, /* Ex */
- { macro_text, MDOC_CALLABLE | MDOC_QUOTABLE }, /* Fa */
+ { macro_text, MDOC_CALLABLE | MDOC_QUOTABLE | MDOC_PARSED }, /* Fa */
{ macro_constant, 0 }, /* Fd */
- { macro_text, MDOC_CALLABLE }, /* Fl */
- { macro_text, MDOC_CALLABLE | MDOC_QUOTABLE }, /* Fn */
- { macro_text, 0 }, /* Ft */
- { macro_text, MDOC_CALLABLE }, /* Ic */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
+ { macro_text, MDOC_CALLABLE | MDOC_QUOTABLE | MDOC_PARSED }, /* Fn */
+ { macro_text, MDOC_PARSED }, /* Ft */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */
{ macro_constant, 0 }, /* In */
- { macro_text, MDOC_CALLABLE }, /* Li */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Li */
{ macro_constant, 0 }, /* Nd */
- { macro_text, MDOC_CALLABLE }, /* Nm */
- { macro_scoped_line, MDOC_CALLABLE }, /* Op */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
{ macro_obsolete, 0 }, /* Ot */
- { macro_text, MDOC_CALLABLE }, /* Pa */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
{ macro_constant, 0 }, /* Rv */
- { macro_constant, 0 }, /* St */
- { macro_text, MDOC_CALLABLE }, /* Va */
- { macro_text, MDOC_CALLABLE }, /* Vt */
- { macro_text, MDOC_CALLABLE }, /* Xr */
- { macro_constant, MDOC_QUOTABLE }, /* %A */
- { macro_constant, MDOC_QUOTABLE }, /* %B */
+ /* XXX - supposed to be (but isn't) callable. */
+ { macro_constant_delimited, MDOC_PARSED }, /* St */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
+ { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %A */
+ { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %B */
{ macro_constant, MDOC_QUOTABLE }, /* %D */
- { macro_constant, MDOC_QUOTABLE }, /* %I */
- { macro_constant, MDOC_QUOTABLE }, /* %J */
+ { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %I */
+ { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %J */
{ macro_constant, MDOC_QUOTABLE }, /* %N */
{ macro_constant, MDOC_QUOTABLE }, /* %O */
{ macro_constant, MDOC_QUOTABLE }, /* %P */
{ macro_constant, MDOC_QUOTABLE }, /* %R */
- { macro_constant, MDOC_QUOTABLE }, /* %T */
+ { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %T */
{ macro_constant, MDOC_QUOTABLE }, /* %V */
- { macro_close_explicit, MDOC_CALLABLE }, /* Ac */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Ao */
- { macro_scoped_line, MDOC_CALLABLE }, /* Aq */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Ac */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Ao */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */
{ macro_constant, 0 }, /* At */
- { macro_close_explicit, MDOC_CALLABLE }, /* Bc */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Bc */
{ macro_scoped, MDOC_EXPLICIT }, /* Bf */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Bo */
- { macro_scoped_line, MDOC_CALLABLE }, /* Bq */
- { macro_constant_delimited, 0 }, /* Bsx */
- { macro_constant_delimited, 0 }, /* Bx */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Bo */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */
+ { macro_constant_delimited, MDOC_PARSED }, /* Bsx */
+ { macro_constant_delimited, MDOC_PARSED }, /* Bx */
{ macro_constant, 0 }, /* Db */
- { macro_close_explicit, MDOC_CALLABLE }, /* Dc */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Do */
- { macro_scoped_line, MDOC_CALLABLE }, /* Dq */
- { macro_close_explicit, MDOC_CALLABLE }, /* Ec */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Dc */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Do */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Ec */
{ macro_close_explicit, 0 }, /* Ef */
- { macro_text, MDOC_CALLABLE }, /* Em */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Eo */
- { macro_constant_delimited, 0 }, /* Fx */
- { macro_text, 0 }, /* Ms */
- { macro_constant_delimited, MDOC_CALLABLE }, /* No */
- { macro_constant_delimited, MDOC_CALLABLE }, /* Ns */
- { macro_constant_delimited, 0 }, /* Nx */
- { macro_constant_delimited, 0 }, /* Ox */
- { macro_close_explicit, MDOC_CALLABLE }, /* Pc */
- { macro_constant, 0 }, /* Pf */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Po */
- { macro_scoped_line, MDOC_CALLABLE }, /* Pq */
- { macro_close_explicit, MDOC_CALLABLE }, /* Qc */
- { macro_scoped_line, MDOC_CALLABLE }, /* Ql */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Qo */
- { macro_scoped_line, MDOC_CALLABLE }, /* Qq */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Em */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Eo */
+ { macro_constant_delimited, MDOC_PARSED }, /* Fx */
+ { macro_text, MDOC_PARSED }, /* Ms */
+ { macro_constant_delimited, MDOC_CALLABLE | MDOC_PARSED }, /* No */
+ { macro_constant_delimited, MDOC_CALLABLE | MDOC_PARSED }, /* Ns */
+ { macro_constant_delimited, MDOC_PARSED }, /* Nx */
+ { macro_constant_delimited, MDOC_PARSED }, /* Ox */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Pc */
+ { macro_constant, MDOC_PARSED }, /* Pf */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Po */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Qc */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Qo */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */
{ macro_close_explicit, 0 }, /* Re */
{ macro_scoped, MDOC_EXPLICIT }, /* Rs */
- { macro_close_explicit, MDOC_CALLABLE }, /* Sc */
- { macro_constant_scoped, MDOC_CALLABLE }, /* So */
- { macro_scoped_line, MDOC_CALLABLE }, /* Sq */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Sc */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* So */
+ { macro_scoped_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */
{ macro_constant, 0 }, /* Sm */
- { macro_text, MDOC_CALLABLE }, /* Sx */
- { macro_text, MDOC_CALLABLE }, /* Sy */
- { macro_text, MDOC_CALLABLE }, /* Tn */
- { macro_constant_delimited, 0 }, /* Ux */
- { macro_close_explicit, MDOC_CALLABLE }, /* Xc */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Xo */
- { macro_scoped, MDOC_EXPLICIT }, /* Fo */ /* XXX - supposed to be (but isn't) callable. */
- { macro_close_explicit, 0 }, /* Fc */ /* XXX - supposed to be (but isn't) callable. */
- { macro_constant_scoped, MDOC_CALLABLE }, /* Oo */
- { macro_close_explicit, MDOC_CALLABLE }, /* Oc */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */
+ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */
+ { macro_constant_delimited, MDOC_PARSED }, /* Ux */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Xc */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Xo */
+ /* XXX - .Fo supposed to be (but isn't) callable. */
+ { macro_scoped, MDOC_EXPLICIT | MDOC_PARSED }, /* Fo */
+ /* XXX - .Fc supposed to be (but isn't) callable. */
+ { macro_close_explicit, MDOC_PARSED }, /* Fc */
+ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Oo */
+ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Oc */
{ macro_scoped, MDOC_EXPLICIT }, /* Bk */
{ macro_close_explicit, 0 }, /* Ek */
{ macro_constant, 0 }, /* Bt */
@@ -556,6 +559,7 @@ argfree(size_t sz, struct mdoc_arg *p)
/* LINTED */
for (j = 0; j < (int)p[i].sz; j++)
free(p[i].value[j]);
+ free(p[i].value);
}
free(p);
}
diff --git a/private.h b/private.h
index 5f9a3161..15226c4f 100644
--- a/private.h
+++ b/private.h
@@ -43,10 +43,11 @@ struct mdoc_macro {
int (*fp)(struct mdoc *, int, int, int *, char *);
int flags;
#define MDOC_CALLABLE (1 << 0)
-#define MDOC_EXPLICIT (1 << 1)
-#define MDOC_QUOTABLE (1 << 2)
-#define MDOC_PROLOGUE (1 << 3)
-#define MDOC_NESTED (1 << 4)
+#define MDOC_PARSED (1 << 1)
+#define MDOC_EXPLICIT (1 << 2)
+#define MDOC_QUOTABLE (1 << 3)
+#define MDOC_PROLOGUE (1 << 4)
+#define MDOC_NESTED (1 << 5)
};
extern const struct mdoc_macro *const mdoc_macros;
diff --git a/strings.c b/strings.c
index da8a0ca5..0a30ecfe 100644
--- a/strings.c
+++ b/strings.c
@@ -133,6 +133,8 @@ mdoc_atotime(const char *p)
{
struct tm tm;
+ (void)memset(&tm, 0, sizeof(struct tm));
+
if (strptime(p, "%b %d %Y", &tm))
return(mktime(&tm));
if (strptime(p, "%b %d, %Y", &tm))