contrib/mdocml/mdoc.c
static int
mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
{
	enum mdoct	  tok;
	int		  i, sv;
	char		  mac[5];
	struct mdoc_node *n;

	/* Empty post-control lines are ignored. */

	if ('"' == buf[offs]) {
		mdoc_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
		return(1);
	} else if ('\0' == buf[offs])
		return(1);

	sv = offs;

	/* 
	 * Copy the first word into a nil-terminated buffer.
	 * Stop copying when a tab, space, or eoln is encountered.
	 */

	i = 0;
	while (i < 4 && '\0' != buf[offs] && 
			' ' != buf[offs] && '\t' != buf[offs])
		mac[i++] = buf[offs++];

	mac[i] = '\0';

	tok = (i > 1 || i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;

	if (MDOC_MAX == tok) {
		mandoc_vmsg(MANDOCERR_MACRO, m->parse, 
				ln, sv, "%s", buf + sv - 1);
		return(1);
	}

	/* Disregard the first trailing tab, if applicable. */

	if ('\t' == buf[offs])
		offs++;

	/* Jump to the next non-whitespace word. */

	while (buf[offs] && ' ' == buf[offs])
		offs++;

	/* 
	 * Trailing whitespace.  Note that tabs are allowed to be passed
	 * into the parser as "text", so we only warn about spaces here.
	 */

	if ('\0' == buf[offs] && ' ' == buf[offs - 1])
		mdoc_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);

	/*
	 * If an initial macro or a list invocation, divert directly
	 * into macro processing.
	 */

	if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) {
		if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) 
			goto err;
		return(1);
	}

	n = m->last;
	assert(m->last);

	/*
	 * If the first macro of a `Bl -column', open an `It' block
	 * context around the parsed macro.
	 */

	if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
			LIST_column == n->norm->Bl.type) {
		m->flags |= MDOC_FREECOL;
		if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
			goto err;
		return(1);
	}

	/*
	 * If we're following a block-level `It' within a `Bl -column'
	 * context (perhaps opened in the above block or in ptext()),
	 * then open an `It' block context around the parsed macro.
	 */

	if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
			NULL != n->parent &&
			MDOC_Bl == n->parent->tok &&
			LIST_column == n->parent->norm->Bl.type) {
		m->flags |= MDOC_FREECOL;
		if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf)) 
			goto err;
		return(1);
	}

	/* Normal processing of a macro. */

	if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) 
		goto err;

	return(1);

err:	/* Error out. */

	m->flags |= MDOC_HALT;
	return(0);
}
/*
 * Parse a macro line, that is, a line beginning with the control
 * character.
 */
Parse a macro line, that is, a line beginning with the control
character.
Parse a macro line that is a line beginning with the control character .
static int
mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
{
	enum mdoct	  tok;
	int		  i, sv;
	char		  mac[5];
	struct mdoc_node *n;
	if ('"' == buf[offs]) {
		mdoc_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
		return(1);
	} else if ('\0' == buf[offs])
		return(1);
	sv = offs;
	i = 0;
	while (i < 4 && '\0' != buf[offs] && 
			' ' != buf[offs] && '\t' != buf[offs])
		mac[i++] = buf[offs++];
	mac[i] = '\0';
	tok = (i > 1 || i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
	if (MDOC_MAX == tok) {
		mandoc_vmsg(MANDOCERR_MACRO, m->parse, 
				ln, sv, "%s", buf + sv - 1);
		return(1);
	}
	if ('\t' == buf[offs])
		offs++;
	while (buf[offs] && ' ' == buf[offs])
		offs++;
	if ('\0' == buf[offs] && ' ' == buf[offs - 1])
		mdoc_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);
	if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) {
		if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) 
			goto err;
		return(1);
	}
	n = m->last;
	assert(m->last);
	if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
			LIST_column == n->norm->Bl.type) {
		m->flags |= MDOC_FREECOL;
		if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
			goto err;
		return(1);
	}
	if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
			NULL != n->parent &&
			MDOC_Bl == n->parent->tok &&
			LIST_column == n->parent->norm->Bl.type) {
		m->flags |= MDOC_FREECOL;
		if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf)) 
			goto err;
		return(1);
	}
	if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) 
		goto err;
	return(1);
err:	
	m->flags |= MDOC_HALT;
	return(0);
}
static int mdoc_pmacro ( struct mdoc * m , int ln , char * buf , int offs ) { enum mdoct tok ; int i , sv ; char mac [ 5 ] ; struct mdoc_node * n ; if ( ' ' == buf [ offs ] ) { mdoc_pmsg ( m , ln , offs , MANDOCERR_BADCOMMENT ) ; return ( 1 ) ; } else if ( ' \0 ' == buf [ offs ] ) return ( 1 ) ; sv = offs ; i = 0 ; while ( i < 4 && ' \0 ' != buf [ offs ] && ' ' != buf [ offs ] && ' \t ' != buf [ offs ] ) mac [ i ++ ] = buf [ offs ++ ] ; mac [ i ] = ' \0 ' ; tok = ( i > 1 || i < 4 ) ? mdoc_hash_find ( mac ) : MDOC_MAX ; if ( MDOC_MAX == tok ) { mandoc_vmsg ( MANDOCERR_MACRO , m -> parse , ln , sv , " " , buf + sv - 1 ) ; return ( 1 ) ; } if ( ' \t ' == buf [ offs ] ) offs ++ ; while ( buf [ offs ] && ' ' == buf [ offs ] ) offs ++ ; if ( ' \0 ' == buf [ offs ] && ' ' == buf [ offs - 1 ] ) mdoc_pmsg ( m , ln , offs - 1 , MANDOCERR_EOLNSPACE ) ; if ( NULL == m -> last || MDOC_It == tok || MDOC_El == tok ) { if ( ! mdoc_macro ( m , tok , ln , sv , & offs , buf ) ) goto err ; return ( 1 ) ; } n = m -> last ; assert ( m -> last ) ; if ( MDOC_Bl == n -> tok && MDOC_BODY == n -> type && LIST_column == n -> norm -> Bl . type ) { m -> flags |= MDOC_FREECOL ; if ( ! mdoc_macro ( m , MDOC_It , ln , sv , & sv , buf ) ) goto err ; return ( 1 ) ; } if ( MDOC_It == n -> tok && MDOC_BLOCK == n -> type && NULL != n -> parent && MDOC_Bl == n -> parent -> tok && LIST_column == n -> parent -> norm -> Bl . type ) { m -> flags |= MDOC_FREECOL ; if ( ! mdoc_macro ( m , MDOC_It , ln , sv , & sv , buf ) ) goto err ; return ( 1 ) ; } if ( ! mdoc_macro ( m , tok , ln , sv , & offs , buf ) ) goto err ; return ( 1 ) ; err : m -> flags |= MDOC_HALT ; return ( 0 ) ; }
Parse a macro line, that is, a line beginning with the control
 character.
Parse a macro line that is a line beginning with the control character .
/* Empty post-control lines are ignored. */ /* 
	 * Copy the first word into a nil-terminated buffer.
	 * Stop copying when a tab, space, or eoln is encountered.
	 */ /* Disregard the first trailing tab, if applicable. */ /* Jump to the next non-whitespace word. */ /* 
	 * Trailing whitespace.  Note that tabs are allowed to be passed
	 * into the parser as "text", so we only warn about spaces here.
	 */ /*
	 * If an initial macro or a list invocation, divert directly
	 * into macro processing.
	 */ /*
	 * If the first macro of a `Bl -column', open an `It' block
	 * context around the parsed macro.
	 */ /*
	 * If we're following a block-level `It' within a `Bl -column'
	 * context (perhaps opened in the above block or in ptext()),
	 * then open an `It' block context around the parsed macro.
	 */ /* Normal processing of a macro. */ /* Error out. */