xref: /netbsd-src/external/bsd/mdocml/dist/mdoc_state.c (revision 544c191c349c1704c9d5e679d12ec15cff579663)
1*544c191cSchristos /*	Id: mdoc_state.c,v 1.15 2019/01/01 07:42:04 schwarze Exp  */
29ff1f2acSchristos /*
3c9bcef03Schristos  * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
49ff1f2acSchristos  *
59ff1f2acSchristos  * Permission to use, copy, modify, and distribute this software for any
69ff1f2acSchristos  * purpose with or without fee is hereby granted, provided that the above
79ff1f2acSchristos  * copyright notice and this permission notice appear in all copies.
89ff1f2acSchristos  *
99ff1f2acSchristos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
109ff1f2acSchristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
119ff1f2acSchristos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
129ff1f2acSchristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
139ff1f2acSchristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
149ff1f2acSchristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
159ff1f2acSchristos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
169ff1f2acSchristos  */
179ff1f2acSchristos #include <sys/types.h>
189ff1f2acSchristos 
19c9bcef03Schristos #include <assert.h>
20*544c191cSchristos #include <stdio.h>
219ff1f2acSchristos #include <stdlib.h>
229ff1f2acSchristos #include <string.h>
239ff1f2acSchristos 
249ff1f2acSchristos #include "mandoc.h"
259ff1f2acSchristos #include "roff.h"
269ff1f2acSchristos #include "mdoc.h"
279ff1f2acSchristos #include "libmandoc.h"
28*544c191cSchristos #include "roff_int.h"
299ff1f2acSchristos #include "libmdoc.h"
309ff1f2acSchristos 
319ff1f2acSchristos #define STATE_ARGS  struct roff_man *mdoc, struct roff_node *n
329ff1f2acSchristos 
339ff1f2acSchristos typedef	void	(*state_handler)(STATE_ARGS);
349ff1f2acSchristos 
359ff1f2acSchristos static	void	 state_bl(STATE_ARGS);
369ff1f2acSchristos static	void	 state_sh(STATE_ARGS);
379ff1f2acSchristos static	void	 state_sm(STATE_ARGS);
389ff1f2acSchristos 
39*544c191cSchristos static	const state_handler state_handlers[MDOC_MAX - MDOC_Dd] = {
409ff1f2acSchristos 	NULL,		/* Dd */
419ff1f2acSchristos 	NULL,		/* Dt */
429ff1f2acSchristos 	NULL,		/* Os */
439ff1f2acSchristos 	state_sh,	/* Sh */
449ff1f2acSchristos 	NULL,		/* Ss */
459ff1f2acSchristos 	NULL,		/* Pp */
469ff1f2acSchristos 	NULL,		/* D1 */
47*544c191cSchristos 	NULL,		/* Dl */
48*544c191cSchristos 	NULL,		/* Bd */
499ff1f2acSchristos 	NULL,		/* Ed */
509ff1f2acSchristos 	state_bl,	/* Bl */
519ff1f2acSchristos 	NULL,		/* El */
529ff1f2acSchristos 	NULL,		/* It */
539ff1f2acSchristos 	NULL,		/* Ad */
549ff1f2acSchristos 	NULL,		/* An */
55c9bcef03Schristos 	NULL,		/* Ap */
569ff1f2acSchristos 	NULL,		/* Ar */
579ff1f2acSchristos 	NULL,		/* Cd */
589ff1f2acSchristos 	NULL,		/* Cm */
599ff1f2acSchristos 	NULL,		/* Dv */
609ff1f2acSchristos 	NULL,		/* Er */
619ff1f2acSchristos 	NULL,		/* Ev */
629ff1f2acSchristos 	NULL,		/* Ex */
639ff1f2acSchristos 	NULL,		/* Fa */
649ff1f2acSchristos 	NULL,		/* Fd */
659ff1f2acSchristos 	NULL,		/* Fl */
669ff1f2acSchristos 	NULL,		/* Fn */
679ff1f2acSchristos 	NULL,		/* Ft */
689ff1f2acSchristos 	NULL,		/* Ic */
699ff1f2acSchristos 	NULL,		/* In */
709ff1f2acSchristos 	NULL,		/* Li */
719ff1f2acSchristos 	NULL,		/* Nd */
729ff1f2acSchristos 	NULL,		/* Nm */
739ff1f2acSchristos 	NULL,		/* Op */
749ff1f2acSchristos 	NULL,		/* Ot */
759ff1f2acSchristos 	NULL,		/* Pa */
769ff1f2acSchristos 	NULL,		/* Rv */
779ff1f2acSchristos 	NULL,		/* St */
789ff1f2acSchristos 	NULL,		/* Va */
799ff1f2acSchristos 	NULL,		/* Vt */
809ff1f2acSchristos 	NULL,		/* Xr */
819ff1f2acSchristos 	NULL,		/* %A */
829ff1f2acSchristos 	NULL,		/* %B */
839ff1f2acSchristos 	NULL,		/* %D */
849ff1f2acSchristos 	NULL,		/* %I */
859ff1f2acSchristos 	NULL,		/* %J */
869ff1f2acSchristos 	NULL,		/* %N */
879ff1f2acSchristos 	NULL,		/* %O */
889ff1f2acSchristos 	NULL,		/* %P */
899ff1f2acSchristos 	NULL,		/* %R */
909ff1f2acSchristos 	NULL,		/* %T */
919ff1f2acSchristos 	NULL,		/* %V */
929ff1f2acSchristos 	NULL,		/* Ac */
939ff1f2acSchristos 	NULL,		/* Ao */
949ff1f2acSchristos 	NULL,		/* Aq */
959ff1f2acSchristos 	NULL,		/* At */
969ff1f2acSchristos 	NULL,		/* Bc */
979ff1f2acSchristos 	NULL,		/* Bf */
989ff1f2acSchristos 	NULL,		/* Bo */
999ff1f2acSchristos 	NULL,		/* Bq */
1009ff1f2acSchristos 	NULL,		/* Bsx */
1019ff1f2acSchristos 	NULL,		/* Bx */
1029ff1f2acSchristos 	NULL,		/* Db */
1039ff1f2acSchristos 	NULL,		/* Dc */
1049ff1f2acSchristos 	NULL,		/* Do */
1059ff1f2acSchristos 	NULL,		/* Dq */
1069ff1f2acSchristos 	NULL,		/* Ec */
1079ff1f2acSchristos 	NULL,		/* Ef */
1089ff1f2acSchristos 	NULL,		/* Em */
1099ff1f2acSchristos 	NULL,		/* Eo */
1109ff1f2acSchristos 	NULL,		/* Fx */
1119ff1f2acSchristos 	NULL,		/* Ms */
1129ff1f2acSchristos 	NULL,		/* No */
1139ff1f2acSchristos 	NULL,		/* Ns */
1149ff1f2acSchristos 	NULL,		/* Nx */
1159ff1f2acSchristos 	NULL,		/* Ox */
1169ff1f2acSchristos 	NULL,		/* Pc */
1179ff1f2acSchristos 	NULL,		/* Pf */
1189ff1f2acSchristos 	NULL,		/* Po */
1199ff1f2acSchristos 	NULL,		/* Pq */
1209ff1f2acSchristos 	NULL,		/* Qc */
1219ff1f2acSchristos 	NULL,		/* Ql */
1229ff1f2acSchristos 	NULL,		/* Qo */
1239ff1f2acSchristos 	NULL,		/* Qq */
1249ff1f2acSchristos 	NULL,		/* Re */
1259ff1f2acSchristos 	NULL,		/* Rs */
1269ff1f2acSchristos 	NULL,		/* Sc */
1279ff1f2acSchristos 	NULL,		/* So */
1289ff1f2acSchristos 	NULL,		/* Sq */
1299ff1f2acSchristos 	state_sm,	/* Sm */
1309ff1f2acSchristos 	NULL,		/* Sx */
1319ff1f2acSchristos 	NULL,		/* Sy */
1329ff1f2acSchristos 	NULL,		/* Tn */
1339ff1f2acSchristos 	NULL,		/* Ux */
1349ff1f2acSchristos 	NULL,		/* Xc */
1359ff1f2acSchristos 	NULL,		/* Xo */
1369ff1f2acSchristos 	NULL,		/* Fo */
1379ff1f2acSchristos 	NULL,		/* Fc */
1389ff1f2acSchristos 	NULL,		/* Oo */
1399ff1f2acSchristos 	NULL,		/* Oc */
1409ff1f2acSchristos 	NULL,		/* Bk */
1419ff1f2acSchristos 	NULL,		/* Ek */
1429ff1f2acSchristos 	NULL,		/* Bt */
1439ff1f2acSchristos 	NULL,		/* Hf */
1449ff1f2acSchristos 	NULL,		/* Fr */
1459ff1f2acSchristos 	NULL,		/* Ud */
1469ff1f2acSchristos 	NULL,		/* Lb */
1479ff1f2acSchristos 	NULL,		/* Lp */
1489ff1f2acSchristos 	NULL,		/* Lk */
1499ff1f2acSchristos 	NULL,		/* Mt */
1509ff1f2acSchristos 	NULL,		/* Brq */
1519ff1f2acSchristos 	NULL,		/* Bro */
1529ff1f2acSchristos 	NULL,		/* Brc */
1539ff1f2acSchristos 	NULL,		/* %C */
1549ff1f2acSchristos 	NULL,		/* Es */
1559ff1f2acSchristos 	NULL,		/* En */
1569ff1f2acSchristos 	NULL,		/* Dx */
1579ff1f2acSchristos 	NULL,		/* %Q */
1589ff1f2acSchristos 	NULL,		/* %U */
1599ff1f2acSchristos 	NULL,		/* Ta */
1609ff1f2acSchristos };
1619ff1f2acSchristos 
1629ff1f2acSchristos 
1639ff1f2acSchristos void
mdoc_state(struct roff_man * mdoc,struct roff_node * n)1649ff1f2acSchristos mdoc_state(struct roff_man *mdoc, struct roff_node *n)
1659ff1f2acSchristos {
1669ff1f2acSchristos 	state_handler handler;
1679ff1f2acSchristos 
168c9bcef03Schristos 	if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
1699ff1f2acSchristos 		return;
1709ff1f2acSchristos 
171c9bcef03Schristos 	assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
172*544c191cSchristos 	if ((mdoc_macro(n->tok)->flags & MDOC_PROLOGUE) == 0)
1739ff1f2acSchristos 		mdoc->flags |= MDOC_PBODY;
1749ff1f2acSchristos 
175*544c191cSchristos 	handler = state_handlers[n->tok - MDOC_Dd];
1769ff1f2acSchristos 	if (*handler)
1779ff1f2acSchristos 		(*handler)(mdoc, n);
1789ff1f2acSchristos }
1799ff1f2acSchristos 
1809ff1f2acSchristos static void
state_bl(STATE_ARGS)1819ff1f2acSchristos state_bl(STATE_ARGS)
1829ff1f2acSchristos {
183c9bcef03Schristos 	struct mdoc_arg	*args;
184c9bcef03Schristos 	size_t		 i;
1859ff1f2acSchristos 
1869ff1f2acSchristos 	if (n->type != ROFFT_HEAD || n->parent->args == NULL)
1879ff1f2acSchristos 		return;
1889ff1f2acSchristos 
189c9bcef03Schristos 	args = n->parent->args;
190c9bcef03Schristos 	for (i = 0; i < args->argc; i++) {
191c9bcef03Schristos 		switch(args->argv[i].arg) {
1929ff1f2acSchristos 		case MDOC_Diag:
1939ff1f2acSchristos 			n->norm->Bl.type = LIST_diag;
194c9bcef03Schristos 			return;
1959ff1f2acSchristos 		case MDOC_Column:
1969ff1f2acSchristos 			n->norm->Bl.type = LIST_column;
197c9bcef03Schristos 			return;
1989ff1f2acSchristos 		default:
1999ff1f2acSchristos 			break;
2009ff1f2acSchristos 		}
2019ff1f2acSchristos 	}
202c9bcef03Schristos }
2039ff1f2acSchristos 
2049ff1f2acSchristos static void
state_sh(STATE_ARGS)2059ff1f2acSchristos state_sh(STATE_ARGS)
2069ff1f2acSchristos {
2079ff1f2acSchristos 	struct roff_node *nch;
2089ff1f2acSchristos 	char		 *secname;
2099ff1f2acSchristos 
2109ff1f2acSchristos 	if (n->type != ROFFT_HEAD)
2119ff1f2acSchristos 		return;
2129ff1f2acSchristos 
2139508192eSchristos 	if ( ! (n->flags & NODE_VALID)) {
2149ff1f2acSchristos 		secname = NULL;
2159ff1f2acSchristos 		deroff(&secname, n);
2169ff1f2acSchristos 
2179ff1f2acSchristos 		/*
2189ff1f2acSchristos 		 * Set the section attribute for the BLOCK, HEAD,
2199ff1f2acSchristos 		 * and HEAD children; the latter can only be TEXT
2209ff1f2acSchristos 		 * nodes, so no recursion is needed.  For other
2219ff1f2acSchristos 		 * nodes, including the .Sh BODY, this is done
2229ff1f2acSchristos 		 * when allocating the node data structures, but
2239ff1f2acSchristos 		 * for .Sh BLOCK and HEAD, the section is still
2249ff1f2acSchristos 		 * unknown at that time.
2259ff1f2acSchristos 		 */
2269ff1f2acSchristos 
2279ff1f2acSchristos 		n->sec = n->parent->sec = secname == NULL ?
2289ff1f2acSchristos 		    SEC_CUSTOM : mdoc_a2sec(secname);
2299ff1f2acSchristos 		for (nch = n->child; nch != NULL; nch = nch->next)
2309ff1f2acSchristos 			nch->sec = n->sec;
2319ff1f2acSchristos 		free(secname);
2329ff1f2acSchristos 	}
2339ff1f2acSchristos 
2349ff1f2acSchristos 	if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
2359ff1f2acSchristos 		roff_setreg(mdoc->roff, "nS", 1, '=');
2369ff1f2acSchristos 		mdoc->flags |= MDOC_SYNOPSIS;
2379ff1f2acSchristos 	} else {
2389ff1f2acSchristos 		roff_setreg(mdoc->roff, "nS", 0, '=');
2399ff1f2acSchristos 		mdoc->flags &= ~MDOC_SYNOPSIS;
2409ff1f2acSchristos 	}
2419ff1f2acSchristos }
2429ff1f2acSchristos 
2439ff1f2acSchristos static void
state_sm(STATE_ARGS)2449ff1f2acSchristos state_sm(STATE_ARGS)
2459ff1f2acSchristos {
2469ff1f2acSchristos 
2479ff1f2acSchristos 	if (n->child == NULL)
2489ff1f2acSchristos 		mdoc->flags ^= MDOC_SMOFF;
2499ff1f2acSchristos 	else if ( ! strcmp(n->child->string, "on"))
2509ff1f2acSchristos 		mdoc->flags &= ~MDOC_SMOFF;
2519ff1f2acSchristos 	else if ( ! strcmp(n->child->string, "off"))
2529ff1f2acSchristos 		mdoc->flags |= MDOC_SMOFF;
2539ff1f2acSchristos }
254