contrib/mdocml/mandoc.c
char *
mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
{
	char	 *start, *cp;
	int	  quoted, pairs, white;

	/* Quoting can only start with a new word. */
	start = *cpp;
	quoted = 0;
	if ('"' == *start) {
		quoted = 1;
		start++;
	} 

	pairs = 0;
	white = 0;
	for (cp = start; '\0' != *cp; cp++) {
		/* Move left after quoted quotes and escaped backslashes. */
		if (pairs)
			cp[-pairs] = cp[0];
		if ('\\' == cp[0]) {
			if ('\\' == cp[1]) {
				/* Poor man's copy mode. */
				pairs++;
				cp++;
			} else if (0 == quoted && ' ' == cp[1])
				/* Skip escaped blanks. */
				cp++;
		} else if (0 == quoted) {
			if (' ' == cp[0]) {
				/* Unescaped blanks end unquoted args. */
				white = 1;
				break;
			}
		} else if ('"' == cp[0]) {
			if ('"' == cp[1]) {
				/* Quoted quotes collapse. */
				pairs++;
				cp++;
			} else {
				/* Unquoted quotes end quoted args. */
				quoted = 2;
				break;
			}
		}
	}

	/* Quoted argument without a closing quote. */
	if (1 == quoted)
		mandoc_msg(MANDOCERR_BADQUOTE, parse, ln, *pos, NULL);

	/* Null-terminate this argument and move to the next one. */
	if (pairs)
		cp[-pairs] = '\0';
	if ('\0' != *cp) {
		*cp++ = '\0';
		while (' ' == *cp)
			cp++;
	}
	*pos += (int)(cp - start) + (quoted ? 1 : 0);
	*cpp = cp;

	if ('\0' == *cp && (white || ' ' == cp[-1]))
		mandoc_msg(MANDOCERR_EOLNSPACE, parse, ln, *pos, NULL);

	return(start);
}
/*
 * Parse a quoted or unquoted roff-style request or macro argument.
 * Return a pointer to the parsed argument, which is either the original
 * pointer or advanced by one byte in case the argument is quoted.
 * Null-terminate the argument in place.
 * Collapse pairs of quotes inside quoted arguments.
 * Advance the argument pointer to the next argument,
 * or to the null byte terminating the argument line.
 */
Parse a quoted or unquoted roff-style request or macro argument.
Return a pointer to the parsed argument, which is either the original
pointer or advanced by one byte in case the argument is quoted.
Null-terminate the argument in place.
Collapse pairs of quotes inside quoted arguments.
Advance the argument pointer to the next argument,
or to the null byte terminating the argument line.
Parse a quoted or unquoted roff - style request or macro argument . Return a pointer to the parsed argument which is either the original pointer or advanced by one byte in case the argument is quoted . Null - terminate the argument in place . Collapse pairs of quotes inside quoted arguments . Advance the argument pointer to the next argument or to the null byte terminating the argument line .
char *
mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
{
	char	 *start, *cp;
	int	  quoted, pairs, white;
	start = *cpp;
	quoted = 0;
	if ('"' == *start) {
		quoted = 1;
		start++;
	} 
	pairs = 0;
	white = 0;
	for (cp = start; '\0' != *cp; cp++) {
		if (pairs)
			cp[-pairs] = cp[0];
		if ('\\' == cp[0]) {
			if ('\\' == cp[1]) {
				pairs++;
				cp++;
			} else if (0 == quoted && ' ' == cp[1])
				cp++;
		} else if (0 == quoted) {
			if (' ' == cp[0]) {
				white = 1;
				break;
			}
		} else if ('"' == cp[0]) {
			if ('"' == cp[1]) {
				pairs++;
				cp++;
			} else {
				quoted = 2;
				break;
			}
		}
	}
	if (1 == quoted)
		mandoc_msg(MANDOCERR_BADQUOTE, parse, ln, *pos, NULL);
	if (pairs)
		cp[-pairs] = '\0';
	if ('\0' != *cp) {
		*cp++ = '\0';
		while (' ' == *cp)
			cp++;
	}
	*pos += (int)(cp - start) + (quoted ? 1 : 0);
	*cpp = cp;
	if ('\0' == *cp && (white || ' ' == cp[-1]))
		mandoc_msg(MANDOCERR_EOLNSPACE, parse, ln, *pos, NULL);
	return(start);
}
char * mandoc_getarg ( struct mparse * parse , char * * cpp , int ln , int * pos ) { char * start , * cp ; int quoted , pairs , white ; start = * cpp ; quoted = 0 ; if ( ' ' == * start ) { quoted = 1 ; start ++ ; } pairs = 0 ; white = 0 ; for ( cp = start ; ' \0 ' != * cp ; cp ++ ) { if ( pairs ) cp [ - pairs ] = cp [ 0 ] ; if ( ' \\ ' == cp [ 0 ] ) { if ( ' \\ ' == cp [ 1 ] ) { pairs ++ ; cp ++ ; } else if ( 0 == quoted && ' ' == cp [ 1 ] ) cp ++ ; } else if ( 0 == quoted ) { if ( ' ' == cp [ 0 ] ) { white = 1 ; break ; } } else if ( ' ' == cp [ 0 ] ) { if ( ' ' == cp [ 1 ] ) { pairs ++ ; cp ++ ; } else { quoted = 2 ; break ; } } } if ( 1 == quoted ) mandoc_msg ( MANDOCERR_BADQUOTE , parse , ln , * pos , NULL ) ; if ( pairs ) cp [ - pairs ] = ' \0 ' ; if ( ' \0 ' != * cp ) { * cp ++ = ' \0 ' ; while ( ' ' == * cp ) cp ++ ; } * pos += ( int ) ( cp - start ) + ( quoted ? 1 : 0 ) ; * cpp = cp ; if ( ' \0 ' == * cp && ( white || ' ' == cp [ -1 ] ) ) mandoc_msg ( MANDOCERR_EOLNSPACE , parse , ln , * pos , NULL ) ; return ( start ) ; }
Parse a quoted or unquoted roff-style request or macro argument.
Parse a quoted or unquoted roff - style request or macro argument .
/* Quoting can only start with a new word. */ /* Move left after quoted quotes and escaped backslashes. */ /* Poor man's copy mode. */ /* Skip escaped blanks. */ /* Unescaped blanks end unquoted args. */ /* Quoted quotes collapse. */ /* Unquoted quotes end quoted args. */ /* Quoted argument without a closing quote. */ /* Null-terminate this argument and move to the next one. */