Пример #1
0
/*
 * Lookup a macro following the initial line macro.
 */
static enum mdoct
lookup_raw(const char *p)
{
	enum mdoct	 res;

	if (MDOC_MAX == (res = mdoc_hash_find(p)))
		return(MDOC_MAX);
	if (MDOC_CALLABLE & mdoc_macros[res].flags)
		return(res);
	return(MDOC_MAX);
}
Пример #2
0
static int
post_bl_block_width(POST_ARGS)
{
	size_t		  width;
	int		  i;
	enum mdoct	  tok;
	struct mdoc_node *n;
	char		  buf[NUMSIZ];

	n = mdoc->last;

	/*
	 * Calculate the real width of a list from the -width string,
	 * which may contain a macro (with a known default width), a
	 * literal string, or a scaling width.
	 *
	 * If the value to -width is a macro, then we re-write it to be
	 * the macro's width as set in share/tmac/mdoc/doc-common.
	 */

	if (0 == strcmp(n->norm->Bl.width, "Ds"))
		width = 6;
	else if (MDOC_MAX == (tok = mdoc_hash_find(n->norm->Bl.width)))
		return(1);
	else if (0 == (width = mdoc_macro2len(tok)))  {
		mdoc_nmsg(mdoc, n, MANDOCERR_BADWIDTH);
		return(1);
	}

	/* The value already exists: free and reallocate it. */

	assert(n->args);

	for (i = 0; i < (int)n->args->argc; i++) 
		if (MDOC_Width == n->args->argv[i].arg)
			break;

	assert(i < (int)n->args->argc);

	snprintf(buf, NUMSIZ, "%zun", width);
	free(n->args->argv[i].value[0]);
	n->args->argv[i].value[0] = mandoc_strdup(buf);

	/* Set our width! */
	n->norm->Bl.width = n->args->argv[i].value[0];
	return(1);
}
Пример #3
0
/*
 * Look up the macro at *p called by "from",
 * or as a line macro if from == MDOC_MAX.
 */
static enum mdoct
lookup(struct mdoc *mdoc, enum mdoct from, int line, int ppos, const char *p)
{
	enum mdoct	 res;

	if (from == MDOC_MAX || mdoc_macros[from].flags & MDOC_PARSED) {
		res = mdoc_hash_find(p);
		if (res != MDOC_MAX) {
			if (mdoc_macros[res].flags & MDOC_CALLABLE)
				return(res);
			if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
				mandoc_msg(MANDOCERR_MACRO_CALL,
				    mdoc->parse, line, ppos, p);
		}
	}
	return(MDOC_MAX);
}
Пример #4
0
/*
 * Look up the macro at *p called by "from",
 * or as a line macro if from == TOKEN_NONE.
 */
static int
lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p)
{
	int	 res;

	if (mdoc->flags & MDOC_PHRASEQF) {
		mdoc->flags &= ~MDOC_PHRASEQF;
		return TOKEN_NONE;
	}
	if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) {
		res = mdoc_hash_find(p);
		if (res != TOKEN_NONE) {
			if (mdoc_macros[res].flags & MDOC_CALLABLE)
				return res;
			if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
				mandoc_msg(MANDOCERR_MACRO_CALL,
				    mdoc->parse, line, ppos, p);
		}
	}
	return TOKEN_NONE;
}
Пример #5
0
/*
 * 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, j, sv;
    char		  mac[5];
    struct mdoc_node *n;

    /* Empty lines are ignored. */

    offs++;

    if ('\0' == buf[offs])
        return(1);

    i = offs;

    /* Accept tabs/whitespace after the initial control char. */

    if (' ' == buf[i] || '\t' == buf[i]) {
        i++;
        while (buf[i] && (' ' == buf[i] || '\t' == buf[i]))
            i++;
        if ('\0' == buf[i])
            return(1);
    }

    sv = i;

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

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

    tok = (j > 1 || j < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
    if (MDOC_MAX == tok) {
        mdoc_vmsg(m, MANDOCERR_MACRO, ln, sv, "%s", buf + sv - 1);
        return(1);
    }

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

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

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

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

    /*
     * 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[i] && ' ' == buf[i - 1])
        mdoc_pmsg(m, ln, i - 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, &i, 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, &i, buf))
        goto err;

    return(1);

err:	/* Error out. */

    m->flags |= MDOC_HALT;
    return(0);
}
Пример #6
0
/*
 * Parse a macro line, that is, a line beginning with the control
 * character.
 */
static int
mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
{
	struct mdoc_node *n;
	const char	 *cp;
	enum mdoct	  tok;
	int		  i, sv;
	char		  mac[5];

	sv = offs;

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

	i = 0;
	while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
		mac[i++] = buf[offs++];

	mac[i] = '\0';

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

	if (tok == MDOC_MAX) {
		mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
		    ln, sv, buf + sv - 1);
		return(1);
	}

	/* Skip a leading escape sequence or tab. */

	switch (buf[offs]) {
	case '\\':
		cp = buf + offs + 1;
		mandoc_escape(&cp, NULL, NULL);
		offs = cp - buf;
		break;
	case '\t':
		offs++;
		break;
	default:
		break;
	}

	/* 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])
		mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
		    ln, offs - 1, NULL);

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

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

	n = mdoc->last;
	assert(mdoc->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) {
		mdoc->flags |= MDOC_FREECOL;
		mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
		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) {
		mdoc->flags |= MDOC_FREECOL;
		mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
		return(1);
	}

	/* Normal processing of a macro. */

	mdoc_macro(mdoc, tok, ln, sv, &offs, buf);

	/* In quick mode (for mandocdb), abort after the NAME section. */

	if (mdoc->quick && MDOC_Sh == tok &&
	    SEC_NAME != mdoc->last->sec)
		return(2);

	return(1);
}