summaryrefslogtreecommitdiffstatshomepage
path: root/man_macro.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-03-24 20:10:53 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-03-24 20:10:53 +0000
commitbdcaee420fe7a05a2069049d14aa31dce93be009 (patch)
tree497c84386ad0639f035b07c56b0fcd0e16c719fb /man_macro.c
parent0cbe61642c46c73e81d998bc81f574b30674e3cb (diff)
downloadmandoc-bdcaee420fe7a05a2069049d14aa31dce93be009.tar.gz
mandoc-bdcaee420fe7a05a2069049d14aa31dce93be009.tar.zst
mandoc-bdcaee420fe7a05a2069049d14aa31dce93be009.zip
Using man_node_delete() instead of man_node_free()/man_node_freelist() and friends (much simpler).
Split blk_imp() into blk_exp() (explicit macros), blk_dotted() (roff macros), and the original. Added de, dei, am, ami, and ig roff macros (for now, these are discarded within the parse).
Diffstat (limited to 'man_macro.c')
-rw-r--r--man_macro.c114
1 files changed, 104 insertions, 10 deletions
diff --git a/man_macro.c b/man_macro.c
index 70c1ab55..5281a905 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -1,4 +1,4 @@
-/* $Id: man_macro.c,v 1.34 2010/03/24 03:46:02 kristaps Exp $ */
+/* $Id: man_macro.c,v 1.35 2010/03/24 20:10:53 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -31,9 +31,11 @@ enum rew {
REW_HALT,
};
-static int in_line_eoln(MACRO_PROT_ARGS);
-static int blk_imp(MACRO_PROT_ARGS);
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 in_line_eoln(MACRO_PROT_ARGS);
static int rew_scope(enum man_type,
struct man *, enum mant);
@@ -71,13 +73,19 @@ const struct man_macro __man_macros[MAN_MAX] = {
{ in_line_eoln, 0 }, /* fi */
{ in_line_eoln, 0 }, /* r */
{ blk_close, 0 }, /* RE */
- { blk_imp, MAN_EXPLICIT }, /* RS */
+ { blk_exp, MAN_EXPLICIT }, /* RS */
{ in_line_eoln, 0 }, /* DT */
{ in_line_eoln, 0 }, /* UC */
{ in_line_eoln, 0 }, /* PD */
{ in_line_eoln, MAN_NSCOPED }, /* Sp */
{ in_line_eoln, 0 }, /* Vb */
{ in_line_eoln, 0 }, /* Ve */
+ { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* de */
+ { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* dei */
+ { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* am */
+ { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ami */
+ { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ig */
+ { blk_dotted, 0 }, /* . */
};
const struct man_macro * const man_macros = __man_macros;
@@ -88,7 +96,6 @@ man_unscope(struct man *m, const struct man_node *n)
{
assert(n);
- m->next = MAN_NEXT_SIBLING;
/* LINTED */
while (m->last != n) {
@@ -102,7 +109,13 @@ man_unscope(struct man *m, const struct man_node *n)
if ( ! man_valid_post(m))
return(0);
- return(man_action_post(m));
+ if ( ! man_action_post(m))
+ return(0);
+
+ m->next = MAN_ROOT == m->last->type ?
+ MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
+
+ return(1);
}
@@ -206,6 +219,37 @@ rew_scope(enum man_type type, struct man *m, enum mant tok)
/* ARGSUSED */
int
+blk_dotted(MACRO_PROT_ARGS)
+{
+ enum mant ntok;
+ struct man_node *nn;
+
+ for (nn = m->last->parent; nn; nn = nn->parent)
+ if (nn->tok == MAN_de || nn->tok == MAN_dei ||
+ nn->tok == MAN_am ||
+ nn->tok == MAN_ami ||
+ nn->tok == MAN_ig) {
+ ntok = nn->tok;
+ break;
+ }
+
+ if (NULL == nn) {
+ if ( ! man_pwarn(m, line, ppos, WNOSCOPE))
+ return(0);
+ return(1);
+ }
+
+ if ( ! rew_scope(MAN_BODY, m, ntok))
+ return(0);
+ if ( ! rew_scope(MAN_BLOCK, m, ntok))
+ return(0);
+
+ return(1);
+}
+
+
+/* ARGSUSED */
+int
blk_close(MACRO_PROT_ARGS)
{
enum mant ntok;
@@ -232,11 +276,61 @@ blk_close(MACRO_PROT_ARGS)
return(0);
if ( ! rew_scope(MAN_BLOCK, m, ntok))
return(0);
- m->next = MAN_NEXT_SIBLING;
+
return(1);
}
+int
+blk_exp(MACRO_PROT_ARGS)
+{
+ int w, la;
+ char *p;
+ struct man_node *n;
+
+ /*
+ * Close out prior scopes. "Regular" explicit macros cannot be
+ * nested, but we allow roff macros to be placed just about
+ * anywhere.
+ */
+
+ if ( ! (MAN_NOCLOSE & man_macros[tok].flags)) {
+ if ( ! rew_scope(MAN_BODY, m, tok))
+ return(0);
+ if ( ! rew_scope(MAN_BLOCK, m, tok))
+ return(0);
+ }
+
+ if ( ! man_block_alloc(m, line, ppos, tok))
+ return(0);
+ if ( ! man_head_alloc(m, line, ppos, tok))
+ return(0);
+
+ n = m->last;
+
+ for (;;) {
+ la = *pos;
+ w = man_args(m, line, pos, buf, &p);
+
+ if (-1 == w)
+ return(0);
+ if (0 == w)
+ break;
+
+ if ( ! man_word_alloc(m, line, la, p))
+ return(0);
+ }
+
+ assert(m);
+ assert(tok != MAN_MAX);
+
+ if ( ! rew_scope(MAN_HEAD, m, tok))
+ return(0);
+ return(man_body_alloc(m, line, ppos, tok));
+}
+
+
+
/*
* Parse an implicit-block macro. These contain a MAN_HEAD and a
* MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
@@ -296,7 +390,6 @@ blk_imp(MACRO_PROT_ARGS)
if ( ! rew_scope(MAN_HEAD, m, tok))
return(0);
-
return(man_body_alloc(m, line, ppos, tok));
}
@@ -371,8 +464,9 @@ in_line_eoln(MACRO_PROT_ARGS)
return(0);
if (m->last->type != MAN_ROOT && ! man_action_post(m))
return(0);
- if (m->last->type != MAN_ROOT)
- m->next = MAN_NEXT_SIBLING;
+
+ m->next = MAN_ROOT == m->last->type ?
+ MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
return(1);
}