Пример #1
0
/* ARGSUSED */
static enum rofferr
roff_userdef(ROFF_ARGS)
{
	const char	 *arg[9];
	char		 *cp, *n1, *n2;
	int		  i;

	/*
	 * Collect pointers to macro argument strings
	 * and null-terminate them.
	 */
	cp = *bufp + pos;
	for (i = 0; i < 9; i++)
		arg[i] = '\0' == *cp ? "" :
		    mandoc_getarg(r->parse, &cp, ln, &pos);

	/*
	 * Expand macro arguments.
	 */
	*szp = 0;
	n1 = cp = mandoc_strdup(r->current_string);
	while (NULL != (cp = strstr(cp, "\\$"))) {
		i = cp[2] - '1';
		if (0 > i || 8 < i) {
			/* Not an argument invocation. */
			cp += 2;
			continue;
		}

		*szp = strlen(n1) - 3 + strlen(arg[i]) + 1;
		n2 = mandoc_malloc(*szp);

		strlcpy(n2, n1, (size_t)(cp - n1 + 1));
		strlcat(n2, arg[i], *szp);
		strlcat(n2, cp + 3, *szp);

		cp = n2 + (cp - n1);
		free(n1);
		n1 = n2;
	}

	/*
	 * Replace the macro invocation
	 * by the expanded macro.
	 */
	free(*bufp);
	*bufp = n1;
	if (0 == *szp)
		*szp = strlen(*bufp) + 1;

	return(*szp > 1 && '\n' == (*bufp)[(int)*szp - 2] ?
	   ROFF_REPARSE : ROFF_APPEND);
}
Пример #2
0
static int
man_args(struct roff_man *man, int line, int *pos, char *buf, char **v)
{
	char	 *start;

	assert(*pos);
	*v = start = buf + *pos;
	assert(' ' != *start);

	if ('\0' == *start)
		return 0;

	*v = mandoc_getarg(man->parse, v, line, pos);
	return 1;
}
Пример #3
0
static enum margserr
args(struct mdoc *mdoc, int line, int *pos, 
		char *buf, enum argsflag fl, char **v)
{
	char		*p, *pp;
	int		 pairs;
	enum margserr	 rc;

	if ('\0' == buf[*pos]) {
		if (MDOC_PPHRASE & mdoc->flags)
			return(ARGS_EOLN);
		/*
		 * If we're not in a partial phrase and the flag for
		 * being a phrase literal is still set, the punctuation
		 * is unterminated.
		 */
		if (MDOC_PHRASELIT & mdoc->flags)
			mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE);

		mdoc->flags &= ~MDOC_PHRASELIT;
		return(ARGS_EOLN);
	}

	*v = &buf[*pos];

	if (ARGSFL_DELIM == fl)
		if (args_checkpunct(buf, *pos))
			return(ARGS_PUNCT);

	/*
	 * First handle TABSEP items, restricted to `Bl -column'.  This
	 * ignores conventional token parsing and instead uses tabs or
	 * `Ta' macros to separate phrases.  Phrases are parsed again
	 * for arguments at a later phase.
	 */

	if (ARGSFL_TABSEP == fl) {
		/* Scan ahead to tab (can't be escaped). */
		p = strchr(*v, '\t');
		pp = NULL;

		/* Scan ahead to unescaped `Ta'. */
		if ( ! (MDOC_PHRASELIT & mdoc->flags)) 
			for (pp = *v; ; pp++) {
				if (NULL == (pp = strstr(pp, "Ta")))
					break;
				if (pp > *v && ' ' != *(pp - 1))
					continue;
				if (' ' == *(pp + 2) || '\0' == *(pp + 2))
					break;
			}

		/* By default, assume a phrase. */
		rc = ARGS_PHRASE;

		/* 
		 * Adjust new-buffer position to be beyond delimiter
		 * mark (e.g., Ta -> end + 2).
		 */
		if (p && pp) {
			*pos += pp < p ? 2 : 1;
			rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE;
			p = pp < p ? pp : p;
		} else if (p && ! pp) {
			rc = ARGS_PPHRASE;
			*pos += 1;
		} else if (pp && ! p) {
			p = pp;
			*pos += 2;
		} else {
			rc = ARGS_PEND;
			p = strchr(*v, 0);
		}

		/* Whitespace check for eoln case... */
		if ('\0' == *p && ' ' == *(p - 1))
			mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE);

		*pos += (int)(p - *v);

		/* Strip delimiter's preceding whitespace. */
		pp = p - 1;
		while (pp > *v && ' ' == *pp) {
			if (pp > *v && '\\' == *(pp - 1))
				break;
			pp--;
		}
		*(pp + 1) = 0;

		/* Strip delimiter's proceeding whitespace. */
		for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++)
			/* Skip ahead. */ ;

		return(rc);
	}

	/*
	 * Process a quoted literal.  A quote begins with a double-quote
	 * and ends with a double-quote NOT preceded by a double-quote.
	 * NUL-terminate the literal in place.
	 * Collapse pairs of quotes inside quoted literals.
	 * Whitespace is NOT involved in literal termination.
	 */

	if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) {
		if ( ! (MDOC_PHRASELIT & mdoc->flags))
			*v = &buf[++(*pos)];

		if (MDOC_PPHRASE & mdoc->flags)
			mdoc->flags |= MDOC_PHRASELIT;

		pairs = 0;
		for ( ; buf[*pos]; (*pos)++) {
			/* Move following text left after quoted quotes. */
			if (pairs)
				buf[*pos - pairs] = buf[*pos];
			if ('\"' != buf[*pos])
				continue;
			/* Unquoted quotes end quoted args. */
			if ('\"' != buf[*pos + 1])
				break;
			/* Quoted quotes collapse. */
			pairs++;
			(*pos)++;
		}
		if (pairs)
			buf[*pos - pairs] = '\0';

		if ('\0' == buf[*pos]) {
			if (MDOC_PPHRASE & mdoc->flags)
				return(ARGS_QWORD);
			mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE);
			return(ARGS_QWORD);
		}

		mdoc->flags &= ~MDOC_PHRASELIT;
		buf[(*pos)++] = '\0';

		if ('\0' == buf[*pos])
			return(ARGS_QWORD);

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

		if ('\0' == buf[*pos])
			mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE);

		return(ARGS_QWORD);
	}

	p = &buf[*pos];
	*v = mandoc_getarg(mdoc->parse, &p, line, pos);

	return(ARGS_WORD);
}