X-Git-Url: https://git.cameronkatri.com/mandoc.git/blobdiff_plain/ccc10e57fbb135c2fc3114a4d642963527f2fbc5..f5330ed0a9932ca87b5c5c013a54a98d784a8df2:/man.c diff --git a/man.c b/man.c index 6c0b1787..31c094e8 100644 --- a/man.c +++ b/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.160 2015/04/19 14:25:41 schwarze Exp $ */ +/* $Id: man.c,v 1.166 2015/10/22 21:54:23 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013, 2014, 2015 Ingo Schwarze @@ -55,13 +55,6 @@ static int man_ptext(struct roff_man *, int, char *, int); static int man_pmacro(struct roff_man *, int, char *, int); -void -man_endparse(struct roff_man *man) -{ - - man_macroend(man); -} - int man_parseln(struct roff_man *man, int ln, char *buf, int offs) { @@ -69,29 +62,9 @@ man_parseln(struct roff_man *man, int ln, char *buf, int offs) if (man->last->type != ROFFT_EQN || ln > man->last->line) man->flags |= MAN_NEWLINE; - return (roff_getcontrol(man->roff, buf, &offs) ? + return roff_getcontrol(man->roff, buf, &offs) ? man_pmacro(man, ln, buf, offs) : - man_ptext(man, ln, buf, offs)); -} - -void -man_elem_alloc(struct roff_man *man, int line, int pos, int tok) -{ - struct roff_node *p; - - p = roff_node_alloc(man, line, pos, ROFFT_ELEM, tok); - roff_node_append(man, p); - man->next = ROFF_NEXT_CHILD; -} - -void -man_block_alloc(struct roff_man *man, int line, int pos, int tok) -{ - struct roff_node *p; - - p = roff_node_alloc(man, line, pos, ROFFT_BLOCK, tok); - roff_node_append(man, p); - man->next = ROFF_NEXT_CHILD; + man_ptext(man, ln, buf, offs); } static void @@ -124,7 +97,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs) if (man->flags & MAN_LITERAL) { roff_word_alloc(man, line, offs, buf + offs); man_descope(man, line, offs); - return(1); + return 1; } for (i = offs; buf[i] == ' '; i++) @@ -139,10 +112,10 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs) /* Allocate a blank entry. */ if (man->last->tok != MAN_SH && man->last->tok != MAN_SS) { - man_elem_alloc(man, line, offs, MAN_sp); + roff_elem_alloc(man, line, offs, MAN_sp); man->next = ROFF_NEXT_SIBLING; } - return(1); + return 1; } /* @@ -179,7 +152,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs) man->last->flags |= MAN_EOS; man_descope(man, line, offs); - return(1); + return 1; } static int @@ -210,7 +183,7 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs) if (tok == TOKEN_NONE) { mandoc_msg(MANDOCERR_MACRO, man->parse, ln, ppos, buf + ppos - 1); - return(1); + return 1; } /* Skip a leading escape sequence or tab. */ @@ -261,7 +234,7 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs) n = man->last; if (n->type == ROFFT_BODY && strcmp(n->prev->child->string, "NAME")) - return(2); + return 2; } /* @@ -272,14 +245,14 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs) if ( ! bline || man->flags & MAN_ELINE || man_macros[tok].flags & MAN_NSCOPED) - return(1); + return 1; assert(man->flags & MAN_BLINE); man->flags &= ~MAN_BLINE; man_unscope(man, man->last->parent); roff_body_alloc(man, ln, ppos, man->last->tok); - return(1); + return 1; } void @@ -309,6 +282,20 @@ man_breakscope(struct roff_man *man, int tok) man->flags &= ~MAN_ELINE; } + /* + * Weird special case: + * Switching fill mode closes section headers. + */ + + if (man->flags & MAN_BLINE && + (tok == MAN_nf || tok == MAN_fi) && + (man->last->tok == MAN_SH || man->last->tok == MAN_SS)) { + n = man->last; + man_unscope(man, n); + roff_body_alloc(man, n->line, n->pos, n->tok); + man->flags &= ~MAN_BLINE; + } + /* * A block header next line scope is open, * and the new macro is not allowed inside block headers. @@ -343,51 +330,40 @@ man_mparse(const struct roff_man *man) { assert(man && man->parse); - return(man->parse); + return man->parse; } void -man_deroff(char **dest, const struct roff_node *n) +man_state(struct roff_man *man, struct roff_node *n) { - char *cp; - size_t sz; - - if (n->type != ROFFT_TEXT) { - for (n = n->child; n; n = n->next) - man_deroff(dest, n); - return; - } - /* Skip leading whitespace and escape sequences. */ - - cp = n->string; - while ('\0' != *cp) { - if ('\\' == *cp) { - cp++; - mandoc_escape((const char **)&cp, NULL, NULL); - } else if (isspace((unsigned char)*cp)) - cp++; - else - break; + switch(n->tok) { + case MAN_nf: + case MAN_EX: + if (man->flags & MAN_LITERAL && ! (n->flags & MAN_VALID)) + mandoc_msg(MANDOCERR_NF_SKIP, man->parse, + n->line, n->pos, "nf"); + man->flags |= MAN_LITERAL; + break; + case MAN_fi: + case MAN_EE: + if ( ! (man->flags & MAN_LITERAL) && + ! (n->flags & MAN_VALID)) + mandoc_msg(MANDOCERR_FI_SKIP, man->parse, + n->line, n->pos, "fi"); + man->flags &= ~MAN_LITERAL; + break; + default: + break; } + man->last->flags |= MAN_VALID; +} - /* Skip trailing whitespace. */ - - for (sz = strlen(cp); sz; sz--) - if (0 == isspace((unsigned char)cp[sz-1])) - break; - - /* Skip empty strings. */ - - if (0 == sz) - return; - - if (NULL == *dest) { - *dest = mandoc_strndup(cp, sz); - return; - } +void +man_validate(struct roff_man *man) +{ - mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp); - free(*dest); - *dest = cp; + man->last = man->first; + man_node_validate(man); + man->flags &= ~MAN_LITERAL; }