diff options
-rw-r--r-- | libman.h | 1 | ||||
-rw-r--r-- | man.c | 23 | ||||
-rw-r--r-- | man.h | 4 | ||||
-rw-r--r-- | man_action.c | 4 | ||||
-rw-r--r-- | man_hash.c | 14 | ||||
-rw-r--r-- | man_macro.c | 101 | ||||
-rw-r--r-- | man_term.c | 2 | ||||
-rw-r--r-- | man_validate.c | 4 | ||||
-rw-r--r-- | mandoc.1 | 4 |
9 files changed, 109 insertions, 48 deletions
@@ -57,6 +57,7 @@ enum merr { WMACRO, WMACROFORM, WEXITSCOPE, + WNOSCOPE, WERRMAX }; @@ -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; @@ -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 */ }; @@ -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)) { @@ -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)); @@ -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 |