=================================================================== RCS file: /cvs/mandoc/man.c,v retrieving revision 1.48 retrieving revision 1.50 diff -u -p -r1.48 -r1.50 --- mandoc/man.c 2010/01/07 10:05:24 1.48 +++ mandoc/man.c 2010/03/22 05:59:32 1.50 @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.48 2010/01/07 10:05:24 kristaps Exp $ */ +/* $Id: man.c,v 1.50 2010/03/22 05:59:32 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -365,6 +365,7 @@ static int man_ptext(struct man *m, int line, char *buf) { int i, j; + char sv; /* Literal free-form text whitespace is preserved. */ @@ -379,7 +380,11 @@ man_ptext(struct man *m, int line, char *buf) for (i = 0; ' ' == buf[i]; i++) /* Skip leading whitespace. */ ; - if (0 == buf[i]) { + if ('\0' == buf[i]) { + /* Trailing whitespace? */ + if (i && ' ' == buf[i - 1]) + if ( ! man_pwarn(m, line, i - 1, WTSPACE)) + return(0); if ( ! pstring(m, line, 0, &buf[i], 0)) return(0); goto descope; @@ -393,15 +398,30 @@ man_ptext(struct man *m, int line, char *buf) if (i && ' ' == buf[i] && '\\' == buf[i - 1]) continue; - buf[i++] = 0; + sv = buf[i]; + buf[i++] = '\0'; + if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j))) return(0); + /* Trailing whitespace? Check at overwritten byte. */ + + if (' ' == sv && '\0' == buf[i]) + if ( ! man_pwarn(m, line, i - 1, WTSPACE)) + return(0); + for ( ; ' ' == buf[i]; i++) /* Skip trailing whitespace. */ ; j = i; - if (0 == buf[i]) + + /* Trailing whitespace? */ + + if (' ' == buf[i - 1] && '\0' == buf[i]) + if ( ! man_pwarn(m, line, i - 1, WTSPACE)) + return(0); + + if ('\0' == buf[i]) break; } @@ -514,15 +534,29 @@ man_pmacro(struct man *m, int ln, char *buf) if ( ! man_pwarn(m, ln, i - 1, WTSPACE)) goto err; - /* Remove prior ELINE macro, if applicable. */ + /* + * Remove prior ELINE macro, as a macro is clobbering it by + * being invoked without prior text. Note that NSCOPED macros + * do not close out ELINE macros, as they print no text. + */ - if (m->flags & MAN_ELINE) { + if (m->flags & MAN_ELINE && + ! (MAN_NSCOPED & man_macros[c].flags)) { n = m->last; assert(NULL == n->child); assert(0 == n->nchild); if ( ! man_nwarn(m, n, WLNSCOPE)) return(0); + /* FIXME: when called as in: + * + * .B + * .br + * .B + * .br + * hello + */ + if (n->prev) { assert(n != n->parent->child); assert(n == n->prev->next); @@ -548,8 +582,25 @@ man_pmacro(struct man *m, int ln, char *buf) goto err; out: - if ( ! (MAN_BLINE & fl)) + /* + * We weren't in a block-line scope when entering the + * above-parsed macro, so return. + */ + + if ( ! (MAN_BLINE & fl)) { + m->flags &= ~MAN_ILINE; return(1); + } + + /* + * If we're in a block scope, then allow this macro to slip by + * without closing scope around it. + */ + + if (MAN_ILINE & m->flags) { + m->flags &= ~MAN_ILINE; + return(1); + } /* * If we've opened a new next-line element scope, then return