示例#1
0
文件: roff.c 项目: StarchLinux/mandoc
/* ARGSUSED */
static enum rofferr
roff_cond(ROFF_ARGS)
{

	roffnode_push(r, tok, NULL, ln, ppos);

	/* 
	 * An `.el' has no conditional body: it will consume the value
	 * of the current rstack entry set in prior `ie' calls or
	 * defaults to DENY.  
	 *
	 * If we're not an `el', however, then evaluate the conditional.
	 */

	r->last->rule = ROFF_el == tok ?
		(r->rstackpos < 0 ? 
		 ROFFRULE_DENY : r->rstack[r->rstackpos--]) :
		roff_evalcond(*bufp, &pos);

	/*
	 * An if-else will put the NEGATION of the current evaluated
	 * conditional into the stack of rules.
	 */

	if (ROFF_ie == tok) {
		if (r->rstackpos == RSTACK_MAX - 1) {
			mandoc_msg(MANDOCERR_MEM, 
				r->parse, ln, ppos, NULL);
			return(ROFF_ERR);
		}
		r->rstack[++r->rstackpos] = 
			ROFFRULE_DENY == r->last->rule ?
			ROFFRULE_ALLOW : ROFFRULE_DENY;
	}

	/* If the parent has false as its rule, then so do we. */

	if (r->last->parent && ROFFRULE_DENY == r->last->parent->rule)
		r->last->rule = ROFFRULE_DENY;

	/*
	 * Determine scope.
	 * If there is nothing on the line after the conditional,
	 * not even whitespace, use next-line scope.
	 */

	if ('\0' == (*bufp)[pos]) {
		r->last->endspan = 2;
		goto out;
	}

	while (' ' == (*bufp)[pos])
		pos++;

	/* An opening brace requests multiline scope. */

	if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) {
		r->last->endspan = -1;
		pos += 2;
		goto out;
	} 

	/*
	 * Anything else following the conditional causes
	 * single-line scope.  Warn if the scope contains
	 * nothing but trailing whitespace.
	 */

	if ('\0' == (*bufp)[pos])
		mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL);

	r->last->endspan = 1;

out:
	*offs = pos;
	return(ROFF_RERUN);
}
示例#2
0
文件: roff.c 项目: Spenser309/CS551
/* ARGSUSED */
static enum rofferr
roff_cond(ROFF_ARGS)
{
	int		 sv;
	enum roffrule	 rule;

	/* Stack overflow! */

	if (ROFF_ie == tok && r->rstackpos == RSTACK_MAX - 1) {
		(*r->msg)(MANDOCERR_MEM, r->data, ln, ppos, NULL);
		return(ROFF_ERR);
	}

	/* First, evaluate the conditional. */

	if (ROFF_el == tok) {
		/* 
		 * An `.el' will get the value of the current rstack
		 * entry set in prior `ie' calls or defaults to DENY.
	 	 */
		if (r->rstackpos < 0)
			rule = ROFFRULE_DENY;
		else
			rule = r->rstack[r->rstackpos];
	} else
		rule = roff_evalcond(*bufp, &pos);

	sv = pos;

	while (' ' == (*bufp)[pos])
		pos++;

	/*
	 * Roff is weird.  If we have just white-space after the
	 * conditional, it's considered the BODY and we exit without
	 * really doing anything.  Warn about this.  It's probably
	 * wrong.
	 */

	if ('\0' == (*bufp)[pos] && sv != pos) {
		if ((*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL))
			return(ROFF_IGN);
		return(ROFF_ERR);
	}

	if ( ! roffnode_push(r, tok, ln, ppos))
		return(ROFF_ERR);

	r->last->rule = rule;

	ROFF_DEBUG("roff: cond: %s -> %s\n", roffs[tok].name, 
			ROFFRULE_ALLOW == rule ?  "allow" : "deny");

	if (ROFF_ie == tok) {
		/*
		 * An if-else will put the NEGATION of the current
		 * evaluated conditional into the stack.
		 */
		r->rstackpos++;
		if (ROFFRULE_DENY == r->last->rule)
			r->rstack[r->rstackpos] = ROFFRULE_ALLOW;
		else
			r->rstack[r->rstackpos] = ROFFRULE_DENY;
	}

	/* If the parent has false as its rule, then so do we. */

	if (r->last->parent && ROFFRULE_DENY == r->last->parent->rule) {
		r->last->rule = ROFFRULE_DENY;
		ROFF_DEBUG("roff: cond override: %s -> deny\n",
				roffs[tok].name);
	}

	/*
	 * Determine scope.  If we're invoked with "\{" trailing the
	 * conditional, then we're in a multiline scope.  Else our scope
	 * expires on the next line.
	 */

	r->last->endspan = 1;

	if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) {
		r->last->endspan = -1;
		pos += 2;
		ROFF_DEBUG("roff: cond-scope: %s, multi-line\n", 
				roffs[tok].name);
	} else
		ROFF_DEBUG("roff: cond-scope: %s, one-line\n", 
				roffs[tok].name);

	/*
	 * If there are no arguments on the line, the next-line scope is
	 * assumed.
	 */

	if ('\0' == (*bufp)[pos])
		return(ROFF_IGN);

	/* Otherwise re-run the roff parser after recalculating. */

	*offs = pos;
	return(ROFF_RERUN);
}
示例#3
0
文件: roff.c 项目: Hooman3/minix
/* ARGSUSED */
static enum rofferr
roff_cond(ROFF_ARGS)
{
	int		 sv;
	enum roffrule	 rule;

	/* 
	 * An `.el' has no conditional body: it will consume the value
	 * of the current rstack entry set in prior `ie' calls or
	 * defaults to DENY.  
	 *
	 * If we're not an `el', however, then evaluate the conditional.
	 */

	rule = ROFF_el == tok ?
		(r->rstackpos < 0 ? 
		 ROFFRULE_DENY : r->rstack[r->rstackpos--]) :
		roff_evalcond(*bufp, &pos);

	sv = pos;
	while (' ' == (*bufp)[pos])
		pos++;

	/*
	 * Roff is weird.  If we have just white-space after the
	 * conditional, it's considered the BODY and we exit without
	 * really doing anything.  Warn about this.  It's probably
	 * wrong.
	 */

	if ('\0' == (*bufp)[pos] && sv != pos) {
		mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL);
		return(ROFF_IGN);
	}

	roffnode_push(r, tok, NULL, ln, ppos);

	r->last->rule = rule;

	/*
	 * An if-else will put the NEGATION of the current evaluated
	 * conditional into the stack of rules.
	 */

	if (ROFF_ie == tok) {
		if (r->rstackpos == RSTACK_MAX - 1) {
			mandoc_msg(MANDOCERR_MEM, 
				r->parse, ln, ppos, NULL);
			return(ROFF_ERR);
		}
		r->rstack[++r->rstackpos] = 
			ROFFRULE_DENY == r->last->rule ?
			ROFFRULE_ALLOW : ROFFRULE_DENY;
	}

	/* If the parent has false as its rule, then so do we. */

	if (r->last->parent && ROFFRULE_DENY == r->last->parent->rule)
		r->last->rule = ROFFRULE_DENY;

	/*
	 * Determine scope.  If we're invoked with "\{" trailing the
	 * conditional, then we're in a multiline scope.  Else our scope
	 * expires on the next line.
	 */

	r->last->endspan = 1;

	if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) {
		r->last->endspan = -1;
		pos += 2;
	} 

	/*
	 * If there are no arguments on the line, the next-line scope is
	 * assumed.
	 */

	if ('\0' == (*bufp)[pos])
		return(ROFF_IGN);

	/* Otherwise re-run the roff parser after recalculating. */

	*offs = pos;
	return(ROFF_RERUN);
}