=================================================================== RCS file: /cvs/mandoc/man.c,v retrieving revision 1.126 retrieving revision 1.139 diff -u -p -r1.126 -r1.139 --- mandoc/man.c 2014/03/23 12:26:58 1.126 +++ mandoc/man.c 2014/09/06 23:24:32 1.139 @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.126 2014/03/23 12:26:58 schwarze Exp $ */ +/* $Id: man.c,v 1.139 2014/09/06 23:24:32 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -16,9 +16,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include @@ -35,9 +33,9 @@ #include "libman.h" #include "libmandoc.h" -const char *const __man_macronames[MAN_MAX] = { +const char *const __man_macronames[MAN_MAX] = { "br", "TH", "SH", "SS", - "TP", "LP", "PP", "P", + "TP", "LP", "PP", "P", "IP", "HP", "SM", "SB", "BI", "IB", "BR", "RB", "R", "B", "I", "IR", @@ -45,17 +43,17 @@ const char *const __man_macronames[MAN_MAX] = { "fi", "RE", "RS", "DT", "UC", "PD", "AT", "in", "ft", "OP", "EX", "EE", - "UR", "UE" + "UR", "UE", "ll" }; const char * const *man_macronames = __man_macronames; -static struct man_node *man_node_alloc(struct man *, int, int, +static struct man_node *man_node_alloc(struct man *, int, int, enum man_type, enum mant); -static int man_node_append(struct man *, +static int man_node_append(struct man *, struct man_node *); static void man_node_free(struct man_node *); -static void man_node_unlink(struct man *, +static void man_node_unlink(struct man *, struct man_node *); static int man_ptext(struct man *, int, char *, int); static int man_pmacro(struct man *, int, char *, int); @@ -68,20 +66,16 @@ const struct man_node * man_node(const struct man *man) { - assert( ! (MAN_HALT & man->flags)); return(man->first); } - const struct man_meta * man_meta(const struct man *man) { - assert( ! (MAN_HALT & man->flags)); return(&man->meta); } - void man_reset(struct man *man) { @@ -90,7 +84,6 @@ man_reset(struct man *man) man_alloc1(man); } - void man_free(struct man *man) { @@ -99,7 +92,6 @@ man_free(struct man *man) free(man); } - struct man * man_alloc(struct roff *roff, struct mparse *parse, int quick) { @@ -116,33 +108,24 @@ man_alloc(struct roff *roff, struct mparse *parse, int return(p); } - int man_endparse(struct man *man) { - assert( ! (MAN_HALT & man->flags)); - if (man_macroend(man)) - return(1); - man->flags |= MAN_HALT; - return(0); + return(man_macroend(man)); } - int man_parseln(struct man *man, int ln, char *buf, int offs) { man->flags |= MAN_NEWLINE; - assert( ! (MAN_HALT & man->flags)); - return (roff_getcontrol(man->roff, buf, &offs) ? - man_pmacro(man, ln, buf, offs) : - man_ptext(man, ln, buf, offs)); + man_pmacro(man, ln, buf, offs) : + man_ptext(man, ln, buf, offs)); } - static void man_free1(struct man *man) { @@ -161,7 +144,6 @@ man_free1(struct man *man) free(man->meta.msec); } - static void man_alloc1(struct man *man) { @@ -185,12 +167,12 @@ man_node_append(struct man *man, struct man_node *p) assert(MAN_ROOT != p->type); switch (man->next) { - case (MAN_NEXT_SIBLING): + case MAN_NEXT_SIBLING: man->last->next = p; p->prev = man->last; p->parent = man->last->parent; break; - case (MAN_NEXT_CHILD): + case MAN_NEXT_CHILD: man->last->child = p; p->parent = man->last; break; @@ -198,23 +180,24 @@ man_node_append(struct man *man, struct man_node *p) abort(); /* NOTREACHED */ } - + assert(p->parent); p->parent->nchild++; - if ( ! man_valid_pre(man, p)) - return(0); - switch (p->type) { - case (MAN_HEAD): + case MAN_BLOCK: + if (p->tok == MAN_SH || p->tok == MAN_SS) + man->flags &= ~MAN_LITERAL; + break; + case MAN_HEAD: assert(MAN_BLOCK == p->parent->type); p->parent->head = p; break; - case (MAN_TAIL): + case MAN_TAIL: assert(MAN_BLOCK == p->parent->type); p->parent->tail = p; break; - case (MAN_BODY): + case MAN_BODY: assert(MAN_BLOCK == p->parent->type); p->parent->body = p; break; @@ -225,9 +208,9 @@ man_node_append(struct man *man, struct man_node *p) man->last = p; switch (p->type) { - case (MAN_TBL): + case MAN_TBL: /* FALLTHROUGH */ - case (MAN_TEXT): + case MAN_TEXT: if ( ! man_valid_post(man)) return(0); break; @@ -238,9 +221,8 @@ man_node_append(struct man *man, struct man_node *p) return(1); } - static struct man_node * -man_node_alloc(struct man *man, int line, int pos, +man_node_alloc(struct man *man, int line, int pos, enum man_type type, enum mant tok) { struct man_node *p; @@ -257,7 +239,6 @@ man_node_alloc(struct man *man, int line, int pos, return(p); } - int man_elem_alloc(struct man *man, int line, int pos, enum mant tok) { @@ -270,7 +251,6 @@ man_elem_alloc(struct man *man, int line, int pos, enu return(1); } - int man_tail_alloc(struct man *man, int line, int pos, enum mant tok) { @@ -283,7 +263,6 @@ man_tail_alloc(struct man *man, int line, int pos, enu return(1); } - int man_head_alloc(struct man *man, int line, int pos, enum mant tok) { @@ -296,7 +275,6 @@ man_head_alloc(struct man *man, int line, int pos, enu return(1); } - int man_body_alloc(struct man *man, int line, int pos, enum mant tok) { @@ -309,7 +287,6 @@ man_body_alloc(struct man *man, int line, int pos, enu return(1); } - int man_block_alloc(struct man *man, int line, int pos, enum mant tok) { @@ -337,7 +314,6 @@ man_word_alloc(struct man *man, int line, int pos, con return(1); } - /* * Free all of the resources held by a node. This does NOT unlink a * node from its context; for that, see man_node_unlink(). @@ -351,7 +327,6 @@ man_node_free(struct man_node *p) free(p); } - void man_node_delete(struct man *man, struct man_node *p) { @@ -368,8 +343,6 @@ man_addeqn(struct man *man, const struct eqn *ep) { struct man_node *n; - assert( ! (MAN_HALT & man->flags)); - n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX); n->eqn = ep; @@ -385,8 +358,6 @@ man_addspan(struct man *man, const struct tbl_span *sp { struct man_node *n; - assert( ! (MAN_HALT & man->flags)); - n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX); n->span = sp; @@ -408,7 +379,7 @@ man_descope(struct man *man, int line, int offs) if (MAN_ELINE & man->flags) { man->flags &= ~MAN_ELINE; - if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX)) + if ( ! man_unscope(man, man->last->parent)) return(0); } @@ -416,7 +387,7 @@ man_descope(struct man *man, int line, int offs) return(1); man->flags &= ~MAN_BLINE; - if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX)) + if ( ! man_unscope(man, man->last->parent)) return(0); return(man_body_alloc(man, line, offs, man->last->tok)); } @@ -453,9 +424,9 @@ man_ptext(struct man *man, int line, char *buf, int of return(1); } - /* + /* * Warn if the last un-escaped character is whitespace. Then - * strip away the remaining spaces (tabs stay!). + * strip away the remaining spaces (tabs stay!). */ i = (int)strlen(buf); @@ -463,7 +434,8 @@ man_ptext(struct man *man, int line, char *buf, int of if (' ' == buf[i - 1] || '\t' == buf[i - 1]) { if (i > 1 && '\\' != buf[i - 2]) - man_pmsg(man, line, i - 1, MANDOCERR_EOLNSPACE); + mandoc_msg(MANDOCERR_SPACE_EOL, man->parse, + line, i - 1, NULL); for (--i; i && ' ' == buf[i]; i--) /* Spin back to non-space. */ ; @@ -493,17 +465,12 @@ man_ptext(struct man *man, int line, char *buf, int of static int man_pmacro(struct man *man, int ln, char *buf, int offs) { - int i, ppos; - enum mant tok; char mac[5]; struct man_node *n; + enum mant tok; + int i, ppos; + int bline; - if ('"' == buf[offs]) { - man_pmsg(man, ln, offs, MANDOCERR_BADCOMMENT); - return(1); - } else if ('\0' == buf[offs]) - return(1); - ppos = offs; /* @@ -512,8 +479,8 @@ man_pmacro(struct man *man, int ln, char *buf, int off */ i = 0; - while (i < 4 && '\0' != buf[offs] && - ' ' != buf[offs] && '\t' != buf[offs]) + while (i < 4 && '\0' != buf[offs] && ' ' != buf[offs] && + '\t' != buf[offs]) mac[i++] = buf[offs++]; mac[i] = '\0'; @@ -521,8 +488,8 @@ man_pmacro(struct man *man, int ln, char *buf, int off tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX; if (MAN_MAX == tok) { - mandoc_vmsg(MANDOCERR_MACRO, man->parse, ln, - ppos, "%s", buf + ppos - 1); + mandoc_msg(MANDOCERR_MACRO, man->parse, + ln, ppos, buf + ppos - 1); return(1); } @@ -531,15 +498,16 @@ man_pmacro(struct man *man, int ln, char *buf, int off while (buf[offs] && ' ' == buf[offs]) offs++; - /* + /* * Trailing whitespace. Note that tabs are allowed to be passed * into the parser as "text", so we only warn about spaces here. */ if ('\0' == buf[offs] && ' ' == buf[offs - 1]) - man_pmsg(man, ln, offs - 1, MANDOCERR_EOLNSPACE); + mandoc_msg(MANDOCERR_SPACE_EOL, man->parse, + ln, offs - 1, NULL); - /* + /* * Remove prior ELINE macro, as it's being clobbered by a new * macro. Note that NSCOPED macros do not close out ELINE * macros---they don't print text---so we let those slip by. @@ -555,7 +523,7 @@ man_pmacro(struct man *man, int ln, char *buf, int off if (MAN_NSCOPED & man_macros[n->tok].flags) n = n->parent; - mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line, + mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line, n->pos, "%s breaks %s", man_macronames[tok], man_macronames[n->tok]); @@ -586,7 +554,7 @@ man_pmacro(struct man *man, int ln, char *buf, int off assert(MAN_BLOCK == n->type); assert(MAN_SCOPED & man_macros[n->tok].flags); - mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line, + mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line, n->pos, "%s breaks %s", man_macronames[tok], man_macronames[n->tok]); @@ -594,69 +562,41 @@ man_pmacro(struct man *man, int ln, char *buf, int off man->flags &= ~MAN_BLINE; } - /* - * Save the fact that we're in the next-line for a block. In - * this way, embedded roff instructions can "remember" state - * when they exit. - */ + /* Remember whether we are in next-line scope for a block head. */ - if (MAN_BLINE & man->flags) - man->flags |= MAN_BPLINE; + bline = man->flags & MAN_BLINE; /* Call to handler... */ assert(man_macros[tok].fp); if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf)) - goto err; + return(0); /* In quick mode (for mandocdb), abort after the NAME section. */ - if (man->quick && MAN_SH == tok && - strcmp(man->last->prev->child->string, "NAME")) - return(2); - - /* - * We weren't in a block-line scope when entering the - * above-parsed macro, so return. - */ - - if ( ! (MAN_BPLINE & man->flags)) { - man->flags &= ~MAN_ILINE; - return(1); + if (man->quick && MAN_SH == tok) { + n = man->last; + if (MAN_BODY == n->type && + strcmp(n->prev->child->string, "NAME")) + return(2); } - man->flags &= ~MAN_BPLINE; /* - * If we're in a block scope, then allow this macro to slip by - * without closing scope around it. + * If we are in a next-line scope for a block head, + * close it out now and switch to the body, + * unless the next-line scope is allowed to continue. */ - if (MAN_ILINE & man->flags) { - man->flags &= ~MAN_ILINE; + if ( ! bline || man->flags & MAN_ELINE || + man_macros[tok].flags & MAN_NSCOPED) return(1); - } - /* - * If we've opened a new next-line element scope, then return - * now, as the next line will close out the block scope. - */ - - if (MAN_ELINE & man->flags) - return(1); - - /* Close out the block scope opened in the prior line. */ - assert(MAN_BLINE & man->flags); man->flags &= ~MAN_BLINE; - if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX)) + if ( ! man_unscope(man, man->last->parent)) return(0); return(man_body_alloc(man, ln, ppos, man->last->tok)); - -err: /* Error out. */ - - man->flags |= MAN_HALT; - return(0); } /* @@ -720,11 +660,18 @@ man_deroff(char **dest, const struct man_node *n) return; } - /* Skip leading whitespace. */ + /* Skip leading whitespace and escape sequences. */ - for (cp = n->string; '\0' != *cp; cp++) - if (0 == isspace((unsigned char)*cp)) + 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; + } /* Skip trailing whitespace. */