summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libman.h1
-rw-r--r--man.c23
-rw-r--r--man.h4
-rw-r--r--man_action.c4
-rw-r--r--man_hash.c14
-rw-r--r--man_macro.c101
-rw-r--r--man_term.c2
-rw-r--r--man_validate.c4
-rw-r--r--mandoc.14
9 files changed, 109 insertions, 48 deletions
diff --git a/libman.h b/libman.h
index 8b511487..7159fbbe 100644
--- a/libman.h
+++ b/libman.h
@@ -57,6 +57,7 @@ enum merr {
WMACRO,
WMACROFORM,
WEXITSCOPE,
+ WNOSCOPE,
WERRMAX
};
diff --git a/man.c b/man.c
index 0972c5eb..993d9f4c 100644
--- a/man.c
+++ b/man.c
@@ -40,7 +40,8 @@ const char *const __man_merrnames[WERRMAX] = {
"expected empty block head", /* WNHEADARGS */
"unknown macro", /* WMACRO */
"ill-formed macro", /* WMACROFORM */
- "scope open on exit" /* WEXITSCOPE */
+ "scope open on exit", /* WEXITSCOPE */
+ "no scope context" /* WNOSCOPE */
};
const char *const __man_macronames[MAN_MAX] = {
@@ -50,7 +51,8 @@ const char *const __man_macronames[MAN_MAX] = {
"BI", "IB", "BR", "RB",
"R", "B", "I", "IR",
"RI", "na", "i", "sp",
- "nf", "fi", "r"
+ "nf", "fi", "r", "RE",
+ "RS"
};
const char * const *man_macronames = __man_macronames;
@@ -257,14 +259,17 @@ man_node_alloc(int line, int pos, enum man_type type, int tok)
int
-man_elem_alloc(struct man *man, int line, int pos, int tok)
+man_elem_alloc(struct man *m, int line, int pos, int tok)
{
struct man_node *p;
p = man_node_alloc(line, pos, MAN_ELEM, tok);
if (NULL == p)
return(0);
- return(man_node_append(man, p));
+ if ( ! man_node_append(m, p))
+ return(0);
+ m->next = MAN_NEXT_CHILD;
+ return(1);
}
@@ -314,8 +319,7 @@ man_block_alloc(struct man *m, int line, int pos, int tok)
int
-man_word_alloc(struct man *man,
- int line, int pos, const char *word)
+man_word_alloc(struct man *m, int line, int pos, const char *word)
{
struct man_node *p;
@@ -324,7 +328,10 @@ man_word_alloc(struct man *man,
return(0);
if (NULL == (p->string = strdup(word)))
return(0);
- return(man_node_append(man, p));
+ if ( ! man_node_append(m, p))
+ return(0);
+ m->next = MAN_NEXT_SIBLING;
+ return(1);
}
@@ -360,6 +367,8 @@ man_ptext(struct man *m, int line, char *buf)
/* First allocate word. */
+ /* FIXME: dechunk words! */
+
if ( ! man_word_alloc(m, line, 0, buf))
return(0);
m->next = MAN_NEXT_SIBLING;
diff --git a/man.h b/man.h
index 962131d2..c64dce0e 100644
--- a/man.h
+++ b/man.h
@@ -46,7 +46,9 @@
#define MAN_nf 24
#define MAN_fi 25
#define MAN_r 26
-#define MAN_MAX 27
+#define MAN_RE 27
+#define MAN_RS 28
+#define MAN_MAX 29
enum man_type {
MAN_TEXT,
diff --git a/man_action.c b/man_action.c
index 671246ab..bd700079 100644
--- a/man_action.c
+++ b/man_action.c
@@ -62,7 +62,9 @@ const struct actions man_actions[MAN_MAX] = {
{ NULL }, /* sp */
{ NULL }, /* nf */
{ NULL }, /* fi */
- { NULL }, /* r*/
+ { NULL }, /* r */
+ { NULL }, /* RE */
+ { NULL }, /* RS */
};
diff --git a/man_hash.c b/man_hash.c
index 7f1686fb..abd2408a 100644
--- a/man_hash.c
+++ b/man_hash.c
@@ -39,10 +39,10 @@ man_hash_alloc(void)
/* Initialised to -1. */
- htab = malloc(26 * 5 * sizeof(int));
+ htab = malloc(26 * 6 * sizeof(int));
if (NULL == htab)
return(NULL);
- for (i = 0; i < 26 * 5; i++)
+ for (i = 0; i < 26 * 6; i++)
htab[i] = -1;
for (i = 0; i < MAN_MAX; i++) {
@@ -52,15 +52,15 @@ man_hash_alloc(void)
(x >= 97 && x <= 122));
x -= (x <= 90) ? 65 : 97;
- x *= 5;
+ x *= 6;
- for (j = 0; j < 5; j++)
+ for (j = 0; j < 6; j++)
if (-1 == htab[x + j]) {
htab[x + j] = i;
break;
}
- assert(j < 5);
+ assert(j < 6);
}
return((void *)htab);
@@ -81,9 +81,9 @@ man_hash_find(const void *arg, const char *tmp)
return(MAN_MAX);
x -= (x <= 90) ? 65 : 97;
- x *= 5;
+ x *= 6;
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < 6; i++) {
if (-1 == (tok = htab[x + i]))
return(MAN_MAX);
if (0 == strcmp(tmp, man_macronames[tok]))
diff --git a/man_macro.c b/man_macro.c
index 969f704f..c96217c5 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -27,10 +27,13 @@
static int in_line_eoln(MACRO_PROT_ARGS);
static int blk_imp(MACRO_PROT_ARGS);
+static int blk_close(MACRO_PROT_ARGS);
static int rew_scope(enum man_type, struct man *, int);
static int rew_dohalt(int, enum man_type,
const struct man_node *);
+static int rew_block(int, enum man_type,
+ const struct man_node *);
const struct man_macro __man_macros[MAN_MAX] = {
{ in_line_eoln, 0 }, /* br */
@@ -60,6 +63,8 @@ const struct man_macro __man_macros[MAN_MAX] = {
{ in_line_eoln, 0 }, /* nf */
{ in_line_eoln, 0 }, /* fi */
{ in_line_eoln, 0 }, /* r */
+ { blk_close, 0 }, /* RE */
+ { blk_imp, 0 }, /* RS */
};
const struct man_macro * const man_macros = __man_macros;
@@ -88,6 +93,17 @@ man_unscope(struct man *m, const struct man_node *n)
}
+static int
+rew_block(int ntok, enum man_type type, const struct man_node *n)
+{
+
+ if (MAN_BLOCK == type && ntok == n->parent->tok &&
+ MAN_BODY == n->parent->type)
+ return(REW_REWIND);
+ return(ntok == n->tok ? REW_HALT : REW_NOHALT);
+}
+
+
/*
* There are three scope levels: scoped to the root (all), scoped to the
* section (all less sections), and scoped to subsections (all less
@@ -96,6 +112,7 @@ man_unscope(struct man *m, const struct man_node *n)
static int
rew_dohalt(int tok, enum man_type type, const struct man_node *n)
{
+ int c;
if (MAN_ROOT == n->type)
return(REW_HALT);
@@ -105,42 +122,36 @@ rew_dohalt(int tok, enum man_type type, const struct man_node *n)
if (MAN_VALID & n->flags)
return(REW_NOHALT);
+ /* Rewind to ourselves, first. */
+ if (type == n->type && tok == n->tok)
+ return(REW_REWIND);
+
switch (tok) {
case (MAN_SH):
- /* Rewind to ourselves. */
- if (type == n->type && tok == n->tok)
- return(REW_REWIND);
break;
case (MAN_SS):
- /* Rewind to ourselves. */
- if (type == n->type && tok == n->tok)
- return(REW_REWIND);
/* Rewind to a section, if a block. */
- if (MAN_BLOCK == type && MAN_SH == n->parent->tok &&
- MAN_BODY == n->parent->type)
- return(REW_REWIND);
- /* Don't go beyond a section. */
- if (MAN_SH == n->tok)
- return(REW_HALT);
+ if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
+ return(c);
+ break;
+ case (MAN_RS):
+ /* Rewind to a subsection, if a block. */
+ if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
+ return(c);
+ /* Rewind to a section, if a block. */
+ if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
+ return(c);
break;
default:
- /* Rewind to ourselves. */
- if (type == n->type && tok == n->tok)
- return(REW_REWIND);
+ /* Rewind to an offsetter, if a block. */
+ if (REW_NOHALT != (c = rew_block(MAN_RS, type, n)))
+ return(c);
/* Rewind to a subsection, if a block. */
- if (MAN_BLOCK == type && MAN_SS == n->parent->tok &&
- MAN_BODY == n->parent->type)
- return(REW_REWIND);
- /* Don't go beyond a subsection. */
- if (MAN_SS == n->tok)
- return(REW_HALT);
+ if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
+ return(c);
/* Rewind to a section, if a block. */
- if (MAN_BLOCK == type && MAN_SH == n->parent->tok &&
- MAN_BODY == n->parent->type)
- return(REW_REWIND);
- /* Don't go beyond a section. */
- if (MAN_SH == n->tok)
- return(REW_HALT);
+ if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
+ return(c);
break;
}
@@ -180,6 +191,39 @@ rew_scope(enum man_type type, struct man *m, int tok)
}
+/* ARGSUSED */
+int
+blk_close(MACRO_PROT_ARGS)
+{
+ int ntok;
+ const struct man_node *nn;
+
+ switch (tok) {
+ case (MAN_RE):
+ ntok = MAN_RS;
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ for (nn = m->last->parent; nn; nn = nn->parent)
+ if (ntok == nn->tok)
+ break;
+
+ if (NULL == nn)
+ if ( ! man_pwarn(m, line, ppos, WNOSCOPE))
+ return(0);
+
+ if ( ! rew_scope(MAN_BODY, m, ntok))
+ return(0);
+ if ( ! rew_scope(MAN_BLOCK, m, ntok))
+ return(0);
+ m->next = MAN_NEXT_SIBLING;
+ return(1);
+}
+
+
/*
* Parse an implicit-block macro. These contain a MAN_HEAD and a
* MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
@@ -219,7 +263,6 @@ blk_imp(MACRO_PROT_ARGS)
if ( ! man_word_alloc(m, line, la, p))
return(0);
- m->next = MAN_NEXT_SIBLING;
}
/* Close out head and open body (unless MAN_SCOPE). */
@@ -245,7 +288,6 @@ in_line_eoln(MACRO_PROT_ARGS)
return(0);
n = m->last;
- m->next = MAN_NEXT_CHILD;
for (;;) {
la = *pos;
@@ -258,7 +300,6 @@ in_line_eoln(MACRO_PROT_ARGS)
if ( ! man_word_alloc(m, line, la, p))
return(0);
- m->next = MAN_NEXT_SIBLING;
}
if (n == m->last && (MAN_SCOPED & man_macros[tok].flags)) {
diff --git a/man_term.c b/man_term.c
index 4b3bf98c..a8aa907f 100644
--- a/man_term.c
+++ b/man_term.c
@@ -100,6 +100,8 @@ static const struct termact termacts[MAN_MAX] = {
{ pre_nf, NULL }, /* nf */
{ pre_fi, NULL }, /* fi */
{ pre_r, NULL }, /* r */
+ { NULL, NULL }, /* RE */
+ { NULL, NULL }, /* RS */
};
#ifdef __linux__
diff --git a/man_validate.c b/man_validate.c
index e02df1f9..0656f00b 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -83,6 +83,8 @@ static const struct man_valid man_valids[MAN_MAX] = {
{ pres_bline, posts_eq0 }, /* nf */
{ pres_bline, posts_eq0 }, /* fi */
{ NULL, NULL }, /* r */
+ { NULL, NULL }, /* RE */
+ { NULL, NULL }, /* RS */
};
@@ -137,6 +139,8 @@ static int
check_root(CHKARGS)
{
+ /* FIXME: closing out explicit scope! */
+
/* XXX - make this into a warning? */
if (MAN_BLINE & m->flags)
return(man_nerr(m, n, WEXITSCOPE));
diff --git a/mandoc.1 b/mandoc.1
index a43ed148..e6b2f154 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -275,8 +275,8 @@ In
the
.Sq \&Pa
macro does not underline when under a
-.Sq \&It .
-This behaves correctly in
+.Sq \&It
+in the FILES section. This behaves correctly in
.Nm .
.\" LIST-ITEM
.It