summaryrefslogtreecommitdiffstatshomepage
path: root/macro.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2008-12-29 12:19:41 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2008-12-29 12:19:41 +0000
commitc5c2d788a24f2391b78ebb06a2ce8f1d2469f217 (patch)
treeb7197ff6efa63abe319ccd1ea270a466d9abcaf7 /macro.c
parentab72eac616b1c3c60508e746d6658673934ec9da (diff)
downloadmandoc-c5c2d788a24f2391b78ebb06a2ce8f1d2469f217.tar.gz
mandoc-c5c2d788a24f2391b78ebb06a2ce8f1d2469f217.tar.zst
mandoc-c5c2d788a24f2391b78ebb06a2ce8f1d2469f217.zip
*** empty log message ***
Diffstat (limited to 'macro.c')
-rw-r--r--macro.c131
1 files changed, 129 insertions, 2 deletions
diff --git a/macro.c b/macro.c
index 1b9e2f51..8960f42c 100644
--- a/macro.c
+++ b/macro.c
@@ -1,4 +1,4 @@
-/* $Id: macro.c,v 1.9 2008/12/28 23:07:04 kristaps Exp $ */
+/* $Id: macro.c,v 1.10 2008/12/29 12:19:41 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -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[])
{
@@ -518,7 +558,7 @@ again:
return(0);
if (0 == j) {
- if (xstrcmp("$Mdocdate: December 28 2008 $", args[j])) {
+ if (xstrcmp("$Mdocdate: December 29 2008 $", args[j])) {
mdoc->meta.date = time(NULL);
goto again;
} else if (xstrcmp("$Mdocdate:", args[j]))
@@ -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 */
+}