Beispiel #1
0
/*
 * Rewind scope.  If a code "er" != MANDOCERR_MAX has been provided, it
 * will be used if an explicit block scope is being closed out.
 */
int
man_unscope(struct man *man, const struct man_node *to, 
		enum mandocerr er)
{
	struct man_node	*n;

	assert(to);

	man->next = MAN_NEXT_SIBLING;

	/* LINTED */
	while (man->last != to) {
		/*
		 * Save the parent here, because we may delete the
		 * man->last node in the post-validation phase and reset
		 * it to man->last->parent, causing a step in the closing
		 * out to be lost.
		 */
		n = man->last->parent;
		rew_warn(man, man->last, er);
		if ( ! man_valid_post(man))
			return(0);
		man->last = n;
		assert(man->last);
	}

	rew_warn(man, man->last, er);
	if ( ! man_valid_post(man))
		return(0);

	return(1);
}
Beispiel #2
0
static int
man_node_append(struct man *man, struct man_node *p)
{

	assert(man->last);
	assert(man->first);
	assert(MAN_ROOT != p->type);

	switch (man->next) {
	case (MAN_NEXT_SIBLING):
		man->last->next = p;
		p->prev = man->last;
		p->parent = man->last->parent;
		break;
	case (MAN_NEXT_CHILD):
		man->last->child = p;
		p->parent = man->last;
		break;
	default:
		abort();
		/* NOTREACHED */
	}
	
	assert(p->parent);
	p->parent->nchild++;

	if ( ! man_valid_pre(man, p))
		return(0);

	switch (p->type) {
	case (MAN_HEAD):
		assert(MAN_BLOCK == p->parent->type);
		p->parent->head = p;
		break;
	case (MAN_TAIL):
		assert(MAN_BLOCK == p->parent->type);
		p->parent->tail = p;
		break;
	case (MAN_BODY):
		assert(MAN_BLOCK == p->parent->type);
		p->parent->body = p;
		break;
	default:
		break;
	}

	man->last = p;

	switch (p->type) {
	case (MAN_TBL):
		/* FALLTHROUGH */
	case (MAN_TEXT):
		if ( ! man_valid_post(man))
			return(0);
		break;
	default:
		break;
	}

	return(1);
}
Beispiel #3
0
static int
man_node_append(struct man *man, struct man_node *p)
{

	assert(man->last);
	assert(man->first);
	assert(MAN_ROOT != p->type);

	switch (man->next) {
	case MAN_NEXT_SIBLING:
		man->last->next = p;
		p->prev = man->last;
		p->parent = man->last->parent;
		break;
	case MAN_NEXT_CHILD:
		man->last->child = p;
		p->parent = man->last;
		break;
	default:
		abort();
		/* NOTREACHED */
	}

	assert(p->parent);
	p->parent->nchild++;

	switch (p->type) {
	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:
		assert(MAN_BLOCK == p->parent->type);
		p->parent->tail = p;
		break;
	case MAN_BODY:
		assert(MAN_BLOCK == p->parent->type);
		p->parent->body = p;
		break;
	default:
		break;
	}

	man->last = p;

	switch (p->type) {
	case MAN_TBL:
		/* FALLTHROUGH */
	case MAN_TEXT:
		if ( ! man_valid_post(man))
			return(0);
		break;
	default:
		break;
	}

	return(1);
}
Beispiel #4
0
/* ARGSUSED */
int
in_line_eoln(MACRO_PROT_ARGS)
{
	int		 la;
	char		*p;
	struct man_node	*n;

	if ( ! man_elem_alloc(man, line, ppos, tok))
		return(0);

	n = man->last;

	for (;;) {
		la = *pos;
		if ( ! man_args(man, line, pos, buf, &p))
			break;
		if ( ! man_word_alloc(man, line, la, p))
			return(0);
	}

	/*
	 * Append MAN_EOS in case the last snipped argument
	 * ends with a dot, e.g. `.IR syslog (3).'
	 */

	if (n != man->last &&
	    mandoc_eos(man->last->string, strlen(man->last->string)))
		man->last->flags |= MAN_EOS;

	/*
	 * If no arguments are specified and this is MAN_SCOPED (i.e.,
	 * next-line scoped), then set our mode to indicate that we're
	 * waiting for terms to load into our context.
	 */

	if (n == man->last && MAN_SCOPED & man_macros[tok].flags) {
		assert( ! (MAN_NSCOPED & man_macros[tok].flags));
		man->flags |= MAN_ELINE;
		return(1);
	} 

	/* Set ignorable context, if applicable. */

	if (MAN_NSCOPED & man_macros[tok].flags) {
		assert( ! (MAN_SCOPED & man_macros[tok].flags));
		man->flags |= MAN_ILINE;
	}

	assert(MAN_ROOT != man->last->type);
	man->next = MAN_NEXT_SIBLING;
	
	/*
	 * Rewind our element scope.  Note that when TH is pruned, we'll
	 * be back at the root, so make sure that we don't clobber as
	 * its sibling.
	 */

	for ( ; man->last; man->last = man->last->parent) {
		if (man->last == n)
			break;
		if (man->last->type == MAN_ROOT)
			break;
		if ( ! man_valid_post(man))
			return(0);
	}

	assert(man->last);

	/*
	 * Same here regarding whether we're back at the root. 
	 */

	if (man->last->type != MAN_ROOT && ! man_valid_post(man))
		return(0);

	return(1);
}