summaryrefslogtreecommitdiffstats
path: root/usr.bin/mandoc/man_macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/mandoc/man_macro.c')
-rw-r--r--usr.bin/mandoc/man_macro.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/usr.bin/mandoc/man_macro.c b/usr.bin/mandoc/man_macro.c
index 5b4c8eaa441..8a57bd9899c 100644
--- a/usr.bin/mandoc/man_macro.c
+++ b/usr.bin/mandoc/man_macro.c
@@ -1,4 +1,4 @@
-/* $Id: man_macro.c,v 1.14 2010/04/02 11:37:07 schwarze Exp $ */
+/* $Id: man_macro.c,v 1.15 2010/04/25 16:32:19 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -31,6 +31,7 @@ static int blk_close(MACRO_PROT_ARGS);
static int blk_dotted(MACRO_PROT_ARGS);
static int blk_exp(MACRO_PROT_ARGS);
static int blk_imp(MACRO_PROT_ARGS);
+static int blk_cond(MACRO_PROT_ARGS);
static int in_line_eoln(MACRO_PROT_ARGS);
static int rew_scope(enum man_type,
@@ -84,6 +85,9 @@ const struct man_macro __man_macros[MAN_MAX] = {
{ blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ami */
{ blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ig */
{ blk_dotted, 0 }, /* . */
+ { blk_cond, 0 }, /* if */
+ { blk_cond, 0 }, /* ie */
+ { blk_cond, 0 }, /* el */
};
const struct man_macro * const man_macros = __man_macros;
@@ -277,6 +281,50 @@ rew_scope(enum man_type type, struct man *m, enum mant tok)
/*
+ * Closure for brace blocks (if, ie, el).
+ */
+int
+man_brace_close(struct man *m, int line, int ppos)
+{
+ struct man_node *nif;
+
+ nif = m->last->parent;
+ while (nif &&
+ MAN_if != nif->tok &&
+ MAN_ie != nif->tok &&
+ MAN_el != nif->tok)
+ nif = nif->parent;
+
+ if (NULL == nif)
+ return(man_pwarn(m, line, ppos, WNOSCOPE));
+
+ if (MAN_ie != nif->tok || MAN_USE & nif->flags)
+ m->flags &= ~MAN_EL_USE;
+ else
+ m->flags |= MAN_EL_USE;
+
+ if (MAN_USE & nif->flags) {
+ if (nif->prev) {
+ nif->prev->next = nif->child;
+ nif->child->prev = nif->prev;
+ nif->prev = NULL;
+ } else {
+ nif->parent->child = nif->child;
+ }
+ nif->parent->nchild += nif->nchild - 1;
+ while (nif->child) {
+ nif->child->parent = nif->parent;
+ nif->child = nif->child->next;
+ }
+ nif->nchild = 0;
+ nif->parent = NULL;
+ }
+ man_node_delete(m, nif);
+ return(1);
+}
+
+
+/*
* Closure for dotted macros (de, dei, am, ami, ign). This must handle
* any of these as the parent node, so it needs special handling.
* Beyond this, it's the same as blk_close().
@@ -479,6 +527,50 @@ blk_imp(MACRO_PROT_ARGS)
}
+/*
+ * Parse a conditional roff instruction.
+ */
+int
+blk_cond(MACRO_PROT_ARGS)
+{
+ char *p = buf + *pos;
+ int use;
+
+ if (MAN_el == tok)
+ use = m->flags & MAN_EL_USE;
+ else {
+ use = 'n' == *p++;
+ /* XXX skip the rest of the condition for now */
+ while (*p && !isblank(*p))
+ p++;
+ }
+ m->flags &= ~MAN_EL_USE;
+
+ /* advance to the code controlled by the condition */
+ while (*p && isblank(*p))
+ p++;
+ if ('\0' == *p)
+ return(1);
+
+ /* single-line body */
+ if (strncmp("\\{", p, 2)) {
+ if (use && ! man_parseln(m, line, p))
+ return(0);
+ if (MAN_ie == tok && !use)
+ m->flags |= MAN_EL_USE;
+ return(1);
+ }
+
+ /* multi-line body */
+ if ( ! man_block_alloc(m, line, ppos, tok))
+ return(0);
+ if (use)
+ m->last->flags |= MAN_USE;
+ p += 2;
+ return(*p ? man_parseln(m, line, p) : 1);
+}
+
+
int
in_line_eoln(MACRO_PROT_ARGS)
{