Ejemplo n.º 1
0
static int
pre_par(PRE_ARGS)
{

	if (NULL == mdoc->last)
		return(1);
	if (MDOC_ELEM != n->type && MDOC_BLOCK != n->type)
		return(1);

	/* 
	 * Don't allow prior `Lp' or `Pp' prior to a paragraph-type
	 * block:  `Lp', `Pp', or non-compact `Bd' or `Bl'.
	 */

	if (MDOC_Pp != mdoc->last->tok && MDOC_Lp != mdoc->last->tok)
		return(1);
	if (MDOC_Bl == n->tok && n->norm->Bl.comp)
		return(1);
	if (MDOC_Bd == n->tok && n->norm->Bd.comp)
		return(1);
	if (MDOC_It == n->tok && n->parent->norm->Bl.comp)
		return(1);

	mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNPAR);
	mdoc_node_delete(mdoc, mdoc->last);
	return(1);
}
Ejemplo n.º 2
0
void
mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
{

    while (p->child) {
        assert(p->nchild);
        mdoc_node_delete(m, p->child);
    }
    assert(0 == p->nchild);

    mdoc_node_unlink(m, p);
    mdoc_node_free(p);
}
Ejemplo n.º 3
0
static int
post_ignpar(POST_ARGS)
{
	struct mdoc_node *np;

	if (MDOC_BODY != mdoc->last->type)
		return(1);

	if (NULL != (np = mdoc->last->child))
		if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) {
			mdoc_nmsg(mdoc, np, MANDOCERR_IGNPAR);
			mdoc_node_delete(mdoc, np);
		}

	if (NULL != (np = mdoc->last->last))
		if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) {
			mdoc_nmsg(mdoc, np, MANDOCERR_IGNPAR);
			mdoc_node_delete(mdoc, np);
		}

	return(1);
}
Ejemplo n.º 4
0
/*
 * Frees volatile resources (parse tree, meta-data, fields).
 */
static void
mdoc_free1(struct mdoc *mdoc)
{

	if (mdoc->first)
		mdoc_node_delete(mdoc, mdoc->first);
	free(mdoc->meta.msec);
	free(mdoc->meta.vol);
	free(mdoc->meta.arch);
	free(mdoc->meta.date);
	free(mdoc->meta.title);
	free(mdoc->meta.os);
	free(mdoc->meta.name);
}
Ejemplo n.º 5
0
static int
post_prol(POST_ARGS)
{
	/*
	 * Remove prologue macros from the document after they're
	 * processed.  The final document uses mdoc_meta for these
	 * values and discards the originals.
	 */

	mdoc_node_delete(mdoc, mdoc->last);
	if (mdoc->meta.title && mdoc->meta.date && mdoc->meta.os)
		mdoc->flags |= MDOC_PBODY;

	return(1);
}
Ejemplo n.º 6
0
static int
post_st(POST_ARGS)
{
	struct mdoc_node	 *ch;
	const char		 *p;

	if (NULL == (ch = mdoc->last->child)) {
		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_MACROEMPTY);
		mdoc_node_delete(mdoc, mdoc->last);
		return(1);
	}

	assert(MDOC_TEXT == ch->type);

	if (NULL == (p = mdoc_a2st(ch->string))) {
		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADSTANDARD);
		mdoc_node_delete(mdoc, mdoc->last);
	} else {
		free(ch->string);
		ch->string = mandoc_strdup(p);
	}

	return(1);
}
Ejemplo n.º 7
0
static int
ebool(struct mdoc *mdoc)
{

	if (NULL == mdoc->last->child) {
		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_MACROEMPTY);
		mdoc_node_delete(mdoc, mdoc->last);
		return(1);
	}
	check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1);

	assert(MDOC_TEXT == mdoc->last->child->type);

	if (0 == strcmp(mdoc->last->child->string, "on"))
		return(1);
	if (0 == strcmp(mdoc->last->child->string, "off"))
		return(1);

	mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL);
	return(1);
}
Ejemplo n.º 8
0
static int
post_rs(POST_ARGS)
{
	struct mdoc_node *nn, *next, *prev;
	int		  i, j;

	switch (mdoc->last->type) {
	case (MDOC_HEAD):
		check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0);
		return(1);
	case (MDOC_BODY):
		if (mdoc->last->child)
			break;
		check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0);
		return(1);
	default:
		return(1);
	}

	/*
	 * Make sure only certain types of nodes are allowed within the
	 * the `Rs' body.  Delete offending nodes and raise a warning.
	 * Do this before re-ordering for the sake of clarity.
	 */

	next = NULL;
	for (nn = mdoc->last->child; nn; nn = next) {
		for (i = 0; i < RSORD_MAX; i++)
			if (nn->tok == rsord[i])
				break;

		if (i < RSORD_MAX) {
			if (MDOC__J == rsord[i])
				mdoc->last->norm->Rs.child_J = nn;
			next = nn->next;
			continue;
		}

		next = nn->next;
		mdoc_nmsg(mdoc, nn, MANDOCERR_CHILD);
		mdoc_node_delete(mdoc, nn);
	}

	/*
	 * The full `Rs' block needs special handling to order the
	 * sub-elements according to `rsord'.  Pick through each element
	 * and correctly order it.  This is a insertion sort.
	 */

	next = NULL;
	for (nn = mdoc->last->child->next; nn; nn = next) {
		/* Determine order of `nn'. */
		for (i = 0; i < RSORD_MAX; i++)
			if (rsord[i] == nn->tok)
				break;

		/* 
		 * Remove `nn' from the chain.  This somewhat
		 * repeats mdoc_node_unlink(), but since we're
		 * just re-ordering, there's no need for the
		 * full unlink process.
		 */
		
		if (NULL != (next = nn->next))
			next->prev = nn->prev;

		if (NULL != (prev = nn->prev))
			prev->next = nn->next;

		nn->prev = nn->next = NULL;

		/* 
		 * Scan back until we reach a node that's
		 * ordered before `nn'.
		 */

		for ( ; prev ; prev = prev->prev) {
			/* Determine order of `prev'. */
			for (j = 0; j < RSORD_MAX; j++)
				if (rsord[j] == prev->tok)
					break;

			if (j <= i)
				break;
		}

		/*
		 * Set `nn' back into its correct place in front
		 * of the `prev' node.
		 */

		nn->prev = prev;

		if (prev) {
			if (prev->next)
				prev->next->prev = nn;
			nn->next = prev->next;
			prev->next = nn;
		} else {
			mdoc->last->child->prev = nn;
			nn->next = mdoc->last->child;
			mdoc->last->child = nn;
		}
	}

	return(1);
}
Ejemplo n.º 9
0
static int
post_bl_head(POST_ARGS) 
{
	struct mdoc_node *np, *nn, *nnp;
	int		  i, j;

	if (LIST_column != mdoc->last->norm->Bl.type)
		/* FIXME: this should be ERROR class... */
		return(hwarn_eq0(mdoc));

	/*
	 * Convert old-style lists, where the column width specifiers
	 * trail as macro parameters, to the new-style ("normal-form")
	 * lists where they're argument values following -column.
	 */

	/* First, disallow both types and allow normal-form. */

	/* 
	 * TODO: technically, we can accept both and just merge the two
	 * lists, but I'll leave that for another day.
	 */

	if (mdoc->last->norm->Bl.ncols && mdoc->last->nchild) {
		mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_COLUMNS);
		return(0);
	} else if (NULL == mdoc->last->child)
		return(1);

	np = mdoc->last->parent;
	assert(np->args);

	for (j = 0; j < (int)np->args->argc; j++) 
		if (MDOC_Column == np->args->argv[j].arg)
			break;

	assert(j < (int)np->args->argc);
	assert(0 == np->args->argv[j].sz);

	/*
	 * Accomodate for new-style groff column syntax.  Shuffle the
	 * child nodes, all of which must be TEXT, as arguments for the
	 * column field.  Then, delete the head children.
	 */

	np->args->argv[j].sz = (size_t)mdoc->last->nchild;
	np->args->argv[j].value = mandoc_malloc
		((size_t)mdoc->last->nchild * sizeof(char *));

	mdoc->last->norm->Bl.ncols = np->args->argv[j].sz;
	mdoc->last->norm->Bl.cols = (const char **)np->args->argv[j].value;

	for (i = 0, nn = mdoc->last->child; nn; i++) {
		np->args->argv[j].value[i] = nn->string;
		nn->string = NULL;
		nnp = nn;
		nn = nn->next;
		mdoc_node_delete(NULL, nnp);
	}

	mdoc->last->nchild = 0;
	mdoc->last->child = NULL;

	return(1);
}