xref: /dflybsd-src/contrib/mdocml/mdoc_state.c (revision 1e4d43f9c96723e4e55543d240f182e1aac9a4c2)
1*99db7d0eSSascha Wildner /* $Id: mdoc_state.c,v 1.17 2020/06/22 19:20:40 schwarze Exp $ */
254ba9607SSascha Wildner /*
354ba9607SSascha Wildner  * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
454ba9607SSascha Wildner  *
554ba9607SSascha Wildner  * Permission to use, copy, modify, and distribute this software for any
654ba9607SSascha Wildner  * purpose with or without fee is hereby granted, provided that the above
754ba9607SSascha Wildner  * copyright notice and this permission notice appear in all copies.
854ba9607SSascha Wildner  *
954ba9607SSascha Wildner  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1054ba9607SSascha Wildner  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1154ba9607SSascha Wildner  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1254ba9607SSascha Wildner  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1354ba9607SSascha Wildner  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1454ba9607SSascha Wildner  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1554ba9607SSascha Wildner  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1654ba9607SSascha Wildner  */
17*99db7d0eSSascha Wildner #include "config.h"
18*99db7d0eSSascha Wildner 
1954ba9607SSascha Wildner #include <sys/types.h>
2054ba9607SSascha Wildner 
2154ba9607SSascha Wildner #include <assert.h>
2254ba9607SSascha Wildner #include <stdio.h>
2354ba9607SSascha Wildner #include <stdlib.h>
2454ba9607SSascha Wildner #include <string.h>
2554ba9607SSascha Wildner 
2654ba9607SSascha Wildner #include "mandoc.h"
2754ba9607SSascha Wildner #include "roff.h"
2854ba9607SSascha Wildner #include "mdoc.h"
2954ba9607SSascha Wildner #include "libmandoc.h"
3054ba9607SSascha Wildner #include "roff_int.h"
3154ba9607SSascha Wildner #include "libmdoc.h"
3254ba9607SSascha Wildner 
3354ba9607SSascha Wildner #define STATE_ARGS  struct roff_man *mdoc, struct roff_node *n
3454ba9607SSascha Wildner 
3554ba9607SSascha Wildner typedef	void	(*state_handler)(STATE_ARGS);
3654ba9607SSascha Wildner 
3754ba9607SSascha Wildner static	void	 state_bl(STATE_ARGS);
3854ba9607SSascha Wildner static	void	 state_sh(STATE_ARGS);
3954ba9607SSascha Wildner static	void	 state_sm(STATE_ARGS);
4054ba9607SSascha Wildner 
4154ba9607SSascha Wildner static	const state_handler state_handlers[MDOC_MAX - MDOC_Dd] = {
4254ba9607SSascha Wildner 	NULL,		/* Dd */
4354ba9607SSascha Wildner 	NULL,		/* Dt */
4454ba9607SSascha Wildner 	NULL,		/* Os */
4554ba9607SSascha Wildner 	state_sh,	/* Sh */
4654ba9607SSascha Wildner 	NULL,		/* Ss */
4754ba9607SSascha Wildner 	NULL,		/* Pp */
4854ba9607SSascha Wildner 	NULL,		/* D1 */
4954ba9607SSascha Wildner 	NULL,		/* Dl */
5054ba9607SSascha Wildner 	NULL,		/* Bd */
5154ba9607SSascha Wildner 	NULL,		/* Ed */
5254ba9607SSascha Wildner 	state_bl,	/* Bl */
5354ba9607SSascha Wildner 	NULL,		/* El */
5454ba9607SSascha Wildner 	NULL,		/* It */
5554ba9607SSascha Wildner 	NULL,		/* Ad */
5654ba9607SSascha Wildner 	NULL,		/* An */
5754ba9607SSascha Wildner 	NULL,		/* Ap */
5854ba9607SSascha Wildner 	NULL,		/* Ar */
5954ba9607SSascha Wildner 	NULL,		/* Cd */
6054ba9607SSascha Wildner 	NULL,		/* Cm */
6154ba9607SSascha Wildner 	NULL,		/* Dv */
6254ba9607SSascha Wildner 	NULL,		/* Er */
6354ba9607SSascha Wildner 	NULL,		/* Ev */
6454ba9607SSascha Wildner 	NULL,		/* Ex */
6554ba9607SSascha Wildner 	NULL,		/* Fa */
6654ba9607SSascha Wildner 	NULL,		/* Fd */
6754ba9607SSascha Wildner 	NULL,		/* Fl */
6854ba9607SSascha Wildner 	NULL,		/* Fn */
6954ba9607SSascha Wildner 	NULL,		/* Ft */
7054ba9607SSascha Wildner 	NULL,		/* Ic */
7154ba9607SSascha Wildner 	NULL,		/* In */
7254ba9607SSascha Wildner 	NULL,		/* Li */
7354ba9607SSascha Wildner 	NULL,		/* Nd */
7454ba9607SSascha Wildner 	NULL,		/* Nm */
7554ba9607SSascha Wildner 	NULL,		/* Op */
7654ba9607SSascha Wildner 	NULL,		/* Ot */
7754ba9607SSascha Wildner 	NULL,		/* Pa */
7854ba9607SSascha Wildner 	NULL,		/* Rv */
7954ba9607SSascha Wildner 	NULL,		/* St */
8054ba9607SSascha Wildner 	NULL,		/* Va */
8154ba9607SSascha Wildner 	NULL,		/* Vt */
8254ba9607SSascha Wildner 	NULL,		/* Xr */
8354ba9607SSascha Wildner 	NULL,		/* %A */
8454ba9607SSascha Wildner 	NULL,		/* %B */
8554ba9607SSascha Wildner 	NULL,		/* %D */
8654ba9607SSascha Wildner 	NULL,		/* %I */
8754ba9607SSascha Wildner 	NULL,		/* %J */
8854ba9607SSascha Wildner 	NULL,		/* %N */
8954ba9607SSascha Wildner 	NULL,		/* %O */
9054ba9607SSascha Wildner 	NULL,		/* %P */
9154ba9607SSascha Wildner 	NULL,		/* %R */
9254ba9607SSascha Wildner 	NULL,		/* %T */
9354ba9607SSascha Wildner 	NULL,		/* %V */
9454ba9607SSascha Wildner 	NULL,		/* Ac */
9554ba9607SSascha Wildner 	NULL,		/* Ao */
9654ba9607SSascha Wildner 	NULL,		/* Aq */
9754ba9607SSascha Wildner 	NULL,		/* At */
9854ba9607SSascha Wildner 	NULL,		/* Bc */
9954ba9607SSascha Wildner 	NULL,		/* Bf */
10054ba9607SSascha Wildner 	NULL,		/* Bo */
10154ba9607SSascha Wildner 	NULL,		/* Bq */
10254ba9607SSascha Wildner 	NULL,		/* Bsx */
10354ba9607SSascha Wildner 	NULL,		/* Bx */
10454ba9607SSascha Wildner 	NULL,		/* Db */
10554ba9607SSascha Wildner 	NULL,		/* Dc */
10654ba9607SSascha Wildner 	NULL,		/* Do */
10754ba9607SSascha Wildner 	NULL,		/* Dq */
10854ba9607SSascha Wildner 	NULL,		/* Ec */
10954ba9607SSascha Wildner 	NULL,		/* Ef */
11054ba9607SSascha Wildner 	NULL,		/* Em */
11154ba9607SSascha Wildner 	NULL,		/* Eo */
11254ba9607SSascha Wildner 	NULL,		/* Fx */
11354ba9607SSascha Wildner 	NULL,		/* Ms */
11454ba9607SSascha Wildner 	NULL,		/* No */
11554ba9607SSascha Wildner 	NULL,		/* Ns */
11654ba9607SSascha Wildner 	NULL,		/* Nx */
11754ba9607SSascha Wildner 	NULL,		/* Ox */
11854ba9607SSascha Wildner 	NULL,		/* Pc */
11954ba9607SSascha Wildner 	NULL,		/* Pf */
12054ba9607SSascha Wildner 	NULL,		/* Po */
12154ba9607SSascha Wildner 	NULL,		/* Pq */
12254ba9607SSascha Wildner 	NULL,		/* Qc */
12354ba9607SSascha Wildner 	NULL,		/* Ql */
12454ba9607SSascha Wildner 	NULL,		/* Qo */
12554ba9607SSascha Wildner 	NULL,		/* Qq */
12654ba9607SSascha Wildner 	NULL,		/* Re */
12754ba9607SSascha Wildner 	NULL,		/* Rs */
12854ba9607SSascha Wildner 	NULL,		/* Sc */
12954ba9607SSascha Wildner 	NULL,		/* So */
13054ba9607SSascha Wildner 	NULL,		/* Sq */
13154ba9607SSascha Wildner 	state_sm,	/* Sm */
13254ba9607SSascha Wildner 	NULL,		/* Sx */
13354ba9607SSascha Wildner 	NULL,		/* Sy */
13454ba9607SSascha Wildner 	NULL,		/* Tn */
13554ba9607SSascha Wildner 	NULL,		/* Ux */
13654ba9607SSascha Wildner 	NULL,		/* Xc */
13754ba9607SSascha Wildner 	NULL,		/* Xo */
13854ba9607SSascha Wildner 	NULL,		/* Fo */
13954ba9607SSascha Wildner 	NULL,		/* Fc */
14054ba9607SSascha Wildner 	NULL,		/* Oo */
14154ba9607SSascha Wildner 	NULL,		/* Oc */
14254ba9607SSascha Wildner 	NULL,		/* Bk */
14354ba9607SSascha Wildner 	NULL,		/* Ek */
14454ba9607SSascha Wildner 	NULL,		/* Bt */
14554ba9607SSascha Wildner 	NULL,		/* Hf */
14654ba9607SSascha Wildner 	NULL,		/* Fr */
14754ba9607SSascha Wildner 	NULL,		/* Ud */
14854ba9607SSascha Wildner 	NULL,		/* Lb */
14954ba9607SSascha Wildner 	NULL,		/* Lp */
15054ba9607SSascha Wildner 	NULL,		/* Lk */
15154ba9607SSascha Wildner 	NULL,		/* Mt */
15254ba9607SSascha Wildner 	NULL,		/* Brq */
15354ba9607SSascha Wildner 	NULL,		/* Bro */
15454ba9607SSascha Wildner 	NULL,		/* Brc */
15554ba9607SSascha Wildner 	NULL,		/* %C */
15654ba9607SSascha Wildner 	NULL,		/* Es */
15754ba9607SSascha Wildner 	NULL,		/* En */
15854ba9607SSascha Wildner 	NULL,		/* Dx */
15954ba9607SSascha Wildner 	NULL,		/* %Q */
16054ba9607SSascha Wildner 	NULL,		/* %U */
16154ba9607SSascha Wildner 	NULL,		/* Ta */
162*99db7d0eSSascha Wildner 	NULL,		/* Tg */
16354ba9607SSascha Wildner };
16454ba9607SSascha Wildner 
16554ba9607SSascha Wildner 
16654ba9607SSascha Wildner void
mdoc_state(struct roff_man * mdoc,struct roff_node * n)16754ba9607SSascha Wildner mdoc_state(struct roff_man *mdoc, struct roff_node *n)
16854ba9607SSascha Wildner {
16954ba9607SSascha Wildner 	state_handler handler;
17054ba9607SSascha Wildner 
17154ba9607SSascha Wildner 	if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
17254ba9607SSascha Wildner 		return;
17354ba9607SSascha Wildner 
17454ba9607SSascha Wildner 	assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
17554ba9607SSascha Wildner 	if ((mdoc_macro(n->tok)->flags & MDOC_PROLOGUE) == 0)
17654ba9607SSascha Wildner 		mdoc->flags |= MDOC_PBODY;
17754ba9607SSascha Wildner 
17854ba9607SSascha Wildner 	handler = state_handlers[n->tok - MDOC_Dd];
17954ba9607SSascha Wildner 	if (*handler)
18054ba9607SSascha Wildner 		(*handler)(mdoc, n);
18154ba9607SSascha Wildner }
18254ba9607SSascha Wildner 
18354ba9607SSascha Wildner static void
state_bl(STATE_ARGS)18454ba9607SSascha Wildner state_bl(STATE_ARGS)
18554ba9607SSascha Wildner {
18654ba9607SSascha Wildner 	struct mdoc_arg	*args;
18754ba9607SSascha Wildner 	size_t		 i;
18854ba9607SSascha Wildner 
18954ba9607SSascha Wildner 	if (n->type != ROFFT_HEAD || n->parent->args == NULL)
19054ba9607SSascha Wildner 		return;
19154ba9607SSascha Wildner 
19254ba9607SSascha Wildner 	args = n->parent->args;
19354ba9607SSascha Wildner 	for (i = 0; i < args->argc; i++) {
19454ba9607SSascha Wildner 		switch(args->argv[i].arg) {
19554ba9607SSascha Wildner 		case MDOC_Diag:
19654ba9607SSascha Wildner 			n->norm->Bl.type = LIST_diag;
19754ba9607SSascha Wildner 			return;
19854ba9607SSascha Wildner 		case MDOC_Column:
19954ba9607SSascha Wildner 			n->norm->Bl.type = LIST_column;
20054ba9607SSascha Wildner 			return;
20154ba9607SSascha Wildner 		default:
20254ba9607SSascha Wildner 			break;
20354ba9607SSascha Wildner 		}
20454ba9607SSascha Wildner 	}
20554ba9607SSascha Wildner }
20654ba9607SSascha Wildner 
20754ba9607SSascha Wildner static void
state_sh(STATE_ARGS)20854ba9607SSascha Wildner state_sh(STATE_ARGS)
20954ba9607SSascha Wildner {
21054ba9607SSascha Wildner 	struct roff_node *nch;
21154ba9607SSascha Wildner 	char		 *secname;
21254ba9607SSascha Wildner 
21354ba9607SSascha Wildner 	if (n->type != ROFFT_HEAD)
21454ba9607SSascha Wildner 		return;
21554ba9607SSascha Wildner 
21654ba9607SSascha Wildner 	if ( ! (n->flags & NODE_VALID)) {
21754ba9607SSascha Wildner 		secname = NULL;
21854ba9607SSascha Wildner 		deroff(&secname, n);
21954ba9607SSascha Wildner 
22054ba9607SSascha Wildner 		/*
22154ba9607SSascha Wildner 		 * Set the section attribute for the BLOCK, HEAD,
22254ba9607SSascha Wildner 		 * and HEAD children; the latter can only be TEXT
22354ba9607SSascha Wildner 		 * nodes, so no recursion is needed.  For other
22454ba9607SSascha Wildner 		 * nodes, including the .Sh BODY, this is done
22554ba9607SSascha Wildner 		 * when allocating the node data structures, but
22654ba9607SSascha Wildner 		 * for .Sh BLOCK and HEAD, the section is still
22754ba9607SSascha Wildner 		 * unknown at that time.
22854ba9607SSascha Wildner 		 */
22954ba9607SSascha Wildner 
23054ba9607SSascha Wildner 		n->sec = n->parent->sec = secname == NULL ?
23154ba9607SSascha Wildner 		    SEC_CUSTOM : mdoc_a2sec(secname);
23254ba9607SSascha Wildner 		for (nch = n->child; nch != NULL; nch = nch->next)
23354ba9607SSascha Wildner 			nch->sec = n->sec;
23454ba9607SSascha Wildner 		free(secname);
23554ba9607SSascha Wildner 	}
23654ba9607SSascha Wildner 
23754ba9607SSascha Wildner 	if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
23854ba9607SSascha Wildner 		roff_setreg(mdoc->roff, "nS", 1, '=');
23954ba9607SSascha Wildner 		mdoc->flags |= MDOC_SYNOPSIS;
24054ba9607SSascha Wildner 	} else {
24154ba9607SSascha Wildner 		roff_setreg(mdoc->roff, "nS", 0, '=');
24254ba9607SSascha Wildner 		mdoc->flags &= ~MDOC_SYNOPSIS;
24354ba9607SSascha Wildner 	}
24454ba9607SSascha Wildner }
24554ba9607SSascha Wildner 
24654ba9607SSascha Wildner static void
state_sm(STATE_ARGS)24754ba9607SSascha Wildner state_sm(STATE_ARGS)
24854ba9607SSascha Wildner {
24954ba9607SSascha Wildner 
25054ba9607SSascha Wildner 	if (n->child == NULL)
25154ba9607SSascha Wildner 		mdoc->flags ^= MDOC_SMOFF;
25254ba9607SSascha Wildner 	else if ( ! strcmp(n->child->string, "on"))
25354ba9607SSascha Wildner 		mdoc->flags &= ~MDOC_SMOFF;
25454ba9607SSascha Wildner 	else if ( ! strcmp(n->child->string, "off"))
25554ba9607SSascha Wildner 		mdoc->flags |= MDOC_SMOFF;
25654ba9607SSascha Wildner }
257