-/* $Id: man.c,v 1.162 2015/04/23 15:35:59 schwarze Exp $ */
+/* $Id: man.c,v 1.166 2015/10/22 21:54:23 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
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));
+ man_ptext(man, ln, buf, offs);
}
static void
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++)
roff_elem_alloc(man, line, offs, MAN_sp);
man->next = ROFF_NEXT_SIBLING;
}
- return(1);
+ return 1;
}
/*
man->last->flags |= MAN_EOS;
man_descope(man, line, offs);
- return(1);
+ return 1;
}
static int
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. */
n = man->last;
if (n->type == ROFFT_BODY &&
strcmp(n->prev->child->string, "NAME"))
- return(2);
+ return 2;
}
/*
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
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.
{
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;
}