summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macro.c127
-rw-r--r--mdoc.c12
-rw-r--r--mdoc.h2
-rw-r--r--private.h1
4 files changed, 135 insertions, 7 deletions
diff --git a/macro.c b/macro.c
index ada5eedf..3c201a62 100644
--- a/macro.c
+++ b/macro.c
@@ -24,12 +24,15 @@
#include "private.h"
+/* FIXME: maxlineargs should be per LINE, no per TOKEN. */
+
#define _CC(p) ((const char **)p)
static int scope_rewind_exp(struct mdoc *, int, int, int);
static int scope_rewind_imp(struct mdoc *, int, int);
static int append_text(struct mdoc *, int,
int, int, char *[]);
+static int append_const(struct mdoc *, int, int, int, char *[]);
static int append_scoped(struct mdoc *, int, int, int,
const char *[], int, const struct mdoc_arg *);
static int append_delims(struct mdoc *, int, int *, char *);
@@ -182,6 +185,43 @@ append_scoped(struct mdoc *mdoc, int tok, int pos,
static int
+append_const(struct mdoc *mdoc, int tok,
+ int pos, int sz, char *args[])
+{
+
+ assert(sz >= 0);
+ args[sz] = NULL;
+
+ switch (tok) {
+ /* ======= ADD MORE MACRO CHECKS BELOW. ======= */
+ case (MDOC_Bx):
+ /* FALLTHROUGH */
+ case (MDOC_Bsx):
+ /* FALLTHROUGH */
+ case (MDOC_Os):
+ /* FALLTHROUGH */
+ case (MDOC_Fx):
+ /* FALLTHROUGH */
+ case (MDOC_Nx):
+ assert(sz <= 1);
+ break;
+
+ case (MDOC_Ux):
+ assert(0 == sz);
+ break;
+
+ /* ======= ADD MORE MACRO CHECKS ABOVE. ======= */
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, (size_t)sz, _CC(args));
+ return(1);
+}
+
+
+static int
append_text(struct mdoc *mdoc, int tok,
int pos, int sz, char *args[])
{
@@ -869,3 +909,90 @@ again:
/* NOTREACHED */
}
+
+/*
+ * A delimited-constant macro is similar to a general text macro: the
+ * macro is followed by a 0 or 1 arguments (possibly-unspecified) then
+ * terminating punctuation, other words, or another callable macro.
+ */
+int
+macro_constant_delimited(MACRO_PROT_ARGS)
+{
+ int lastarg, flushed, c, maxargs;
+ char *p, *pp;
+
+ if (SEC_PROLOGUE == mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
+
+ /* Process line parameters. */
+
+ lastarg = ppos;
+ flushed = 0;
+
+ switch (tok) {
+ case (MDOC_Ux):
+ maxargs = 0;
+ break;
+ default:
+ maxargs = 1;
+ break;
+ }
+
+again:
+ lastarg = *pos;
+
+ switch (mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p)) {
+ case (ARGS_ERROR):
+ return(0);
+ case (ARGS_WORD):
+ break;
+ case (ARGS_PUNCT):
+ if ( ! flushed && ! append_const(mdoc, tok, ppos, 0, &p))
+ return(0);
+ if (ppos > 1)
+ return(1);
+ return(append_delims(mdoc, tok, pos, buf));
+ case (ARGS_EOLN):
+ if (flushed)
+ return(1);
+ return(append_const(mdoc, tok, ppos, 0, &p));
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ if (0 == maxargs) {
+ pp = p;
+ if ( ! append_const(mdoc, tok, ppos, 0, &p))
+ return(0);
+ p = pp;
+ flushed = 1;
+ }
+
+ if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
+ if ( ! flushed && ! append_const(mdoc, tok, ppos, 0, &p))
+ return(0);
+ if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
+ return(0);
+ if (ppos > 1)
+ return(1);
+ return(append_delims(mdoc, tok, pos, buf));
+ }
+
+ if ( ! flushed && ! mdoc_isdelim(p)) {
+ if ( ! append_const(mdoc, tok, ppos, 1, &p))
+ return(0);
+ flushed = 1;
+ goto again;
+ } else if ( ! flushed) {
+ pp = p;
+ if ( ! append_const(mdoc, tok, ppos, 0, &p))
+ return(0);
+ p = pp;
+ flushed = 1;
+ }
+
+ mdoc_word_alloc(mdoc, lastarg, p);
+ goto again;
+ /* NOTREACHED */
+}
diff --git a/mdoc.c b/mdoc.c
index 09a34216..32ceebbe 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -143,8 +143,8 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ NULL, 0 }, /* Bf */
{ NULL, 0 }, /* Bo */
{ macro_scoped_pline, MDOC_CALLABLE }, /* Bq */
- { NULL, 0 }, /* Bsx */
- { NULL, 0 }, /* Bx */
+ { macro_constant_delimited, 0 }, /* Bsx */
+ { macro_constant_delimited, 0 }, /* Bx */
{ NULL, 0 }, /* Db */
{ NULL, 0 }, /* Dc */
{ NULL, 0 }, /* Do */
@@ -153,12 +153,12 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ NULL, 0 }, /* Ef */
{ macro_text, MDOC_CALLABLE }, /* Em */
{ NULL, 0 }, /* Eo */
- { NULL, 0 }, /* Fx */
+ { macro_constant_delimited, 0 }, /* Fx */
{ macro_text, 0 }, /* Ms */
{ NULL, 0 }, /* No */
{ NULL, 0 }, /* Ns */
- { NULL, 0 }, /* Nx */
- { NULL, 0 }, /* Ox */
+ { macro_constant_delimited, 0 }, /* Nx */
+ { macro_constant_delimited, 0 }, /* Ox */
{ NULL, 0 }, /* Pc */
{ NULL, 0 }, /* Pf */
{ NULL, 0 }, /* Po */
@@ -176,7 +176,7 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ NULL, 0 }, /* Sx */
{ NULL, 0 }, /* Sy */
{ macro_text, MDOC_CALLABLE }, /* Tn */
- { NULL, 0 }, /* Ux */
+ { macro_constant_delimited, 0 }, /* Ux */
{ NULL, 0 }, /* Xc */
{ NULL, 0 }, /* Xo */
{ NULL, 0 }, /* Fo */
diff --git a/mdoc.h b/mdoc.h
index fa3db9d7..9dcbd89e 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -19,7 +19,7 @@
#ifndef MDOC_H
#define MDOC_H
-#define MDOC_LINEARG_MAX 9
+#define MDOC_LINEARG_MAX 8
#define MDOC___ 0
#define MDOC_Dd 1
diff --git a/private.h b/private.h
index 2c979f2f..4c9d629a 100644
--- a/private.h
+++ b/private.h
@@ -94,6 +94,7 @@ int xstrcmp(const char *, const char *);
void *xcalloc(size_t, size_t);
char *xstrdup(const char *);
+int macro_constant_delimited(MACRO_PROT_ARGS);
int macro_text(MACRO_PROT_ARGS);
int macro_scoped_implicit(MACRO_PROT_ARGS);
int macro_scoped_explicit(MACRO_PROT_ARGS);