]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/mandoc/mdoc_state.c
bhyvectl(8): Normalize the man page date
[FreeBSD/FreeBSD.git] / contrib / mandoc / mdoc_state.c
1 /*      $Id: mdoc_state.c,v 1.15 2019/01/01 07:42:04 schwarze Exp $ */
2 /*
3  * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <sys/types.h>
18
19 #include <assert.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "mandoc.h"
25 #include "roff.h"
26 #include "mdoc.h"
27 #include "libmandoc.h"
28 #include "roff_int.h"
29 #include "libmdoc.h"
30
31 #define STATE_ARGS  struct roff_man *mdoc, struct roff_node *n
32
33 typedef void    (*state_handler)(STATE_ARGS);
34
35 static  void     state_bl(STATE_ARGS);
36 static  void     state_sh(STATE_ARGS);
37 static  void     state_sm(STATE_ARGS);
38
39 static  const state_handler state_handlers[MDOC_MAX - MDOC_Dd] = {
40         NULL,           /* Dd */
41         NULL,           /* Dt */
42         NULL,           /* Os */
43         state_sh,       /* Sh */
44         NULL,           /* Ss */
45         NULL,           /* Pp */
46         NULL,           /* D1 */
47         NULL,           /* Dl */
48         NULL,           /* Bd */
49         NULL,           /* Ed */
50         state_bl,       /* Bl */
51         NULL,           /* El */
52         NULL,           /* It */
53         NULL,           /* Ad */
54         NULL,           /* An */
55         NULL,           /* Ap */
56         NULL,           /* Ar */
57         NULL,           /* Cd */
58         NULL,           /* Cm */
59         NULL,           /* Dv */
60         NULL,           /* Er */
61         NULL,           /* Ev */
62         NULL,           /* Ex */
63         NULL,           /* Fa */
64         NULL,           /* Fd */
65         NULL,           /* Fl */
66         NULL,           /* Fn */
67         NULL,           /* Ft */
68         NULL,           /* Ic */
69         NULL,           /* In */
70         NULL,           /* Li */
71         NULL,           /* Nd */
72         NULL,           /* Nm */
73         NULL,           /* Op */
74         NULL,           /* Ot */
75         NULL,           /* Pa */
76         NULL,           /* Rv */
77         NULL,           /* St */
78         NULL,           /* Va */
79         NULL,           /* Vt */
80         NULL,           /* Xr */
81         NULL,           /* %A */
82         NULL,           /* %B */
83         NULL,           /* %D */
84         NULL,           /* %I */
85         NULL,           /* %J */
86         NULL,           /* %N */
87         NULL,           /* %O */
88         NULL,           /* %P */
89         NULL,           /* %R */
90         NULL,           /* %T */
91         NULL,           /* %V */
92         NULL,           /* Ac */
93         NULL,           /* Ao */
94         NULL,           /* Aq */
95         NULL,           /* At */
96         NULL,           /* Bc */
97         NULL,           /* Bf */
98         NULL,           /* Bo */
99         NULL,           /* Bq */
100         NULL,           /* Bsx */
101         NULL,           /* Bx */
102         NULL,           /* Db */
103         NULL,           /* Dc */
104         NULL,           /* Do */
105         NULL,           /* Dq */
106         NULL,           /* Ec */
107         NULL,           /* Ef */
108         NULL,           /* Em */
109         NULL,           /* Eo */
110         NULL,           /* Fx */
111         NULL,           /* Ms */
112         NULL,           /* No */
113         NULL,           /* Ns */
114         NULL,           /* Nx */
115         NULL,           /* Ox */
116         NULL,           /* Pc */
117         NULL,           /* Pf */
118         NULL,           /* Po */
119         NULL,           /* Pq */
120         NULL,           /* Qc */
121         NULL,           /* Ql */
122         NULL,           /* Qo */
123         NULL,           /* Qq */
124         NULL,           /* Re */
125         NULL,           /* Rs */
126         NULL,           /* Sc */
127         NULL,           /* So */
128         NULL,           /* Sq */
129         state_sm,       /* Sm */
130         NULL,           /* Sx */
131         NULL,           /* Sy */
132         NULL,           /* Tn */
133         NULL,           /* Ux */
134         NULL,           /* Xc */
135         NULL,           /* Xo */
136         NULL,           /* Fo */
137         NULL,           /* Fc */
138         NULL,           /* Oo */
139         NULL,           /* Oc */
140         NULL,           /* Bk */
141         NULL,           /* Ek */
142         NULL,           /* Bt */
143         NULL,           /* Hf */
144         NULL,           /* Fr */
145         NULL,           /* Ud */
146         NULL,           /* Lb */
147         NULL,           /* Lp */
148         NULL,           /* Lk */
149         NULL,           /* Mt */
150         NULL,           /* Brq */
151         NULL,           /* Bro */
152         NULL,           /* Brc */
153         NULL,           /* %C */
154         NULL,           /* Es */
155         NULL,           /* En */
156         NULL,           /* Dx */
157         NULL,           /* %Q */
158         NULL,           /* %U */
159         NULL,           /* Ta */
160 };
161
162
163 void
164 mdoc_state(struct roff_man *mdoc, struct roff_node *n)
165 {
166         state_handler handler;
167
168         if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
169                 return;
170
171         assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
172         if ((mdoc_macro(n->tok)->flags & MDOC_PROLOGUE) == 0)
173                 mdoc->flags |= MDOC_PBODY;
174
175         handler = state_handlers[n->tok - MDOC_Dd];
176         if (*handler)
177                 (*handler)(mdoc, n);
178 }
179
180 static void
181 state_bl(STATE_ARGS)
182 {
183         struct mdoc_arg *args;
184         size_t           i;
185
186         if (n->type != ROFFT_HEAD || n->parent->args == NULL)
187                 return;
188
189         args = n->parent->args;
190         for (i = 0; i < args->argc; i++) {
191                 switch(args->argv[i].arg) {
192                 case MDOC_Diag:
193                         n->norm->Bl.type = LIST_diag;
194                         return;
195                 case MDOC_Column:
196                         n->norm->Bl.type = LIST_column;
197                         return;
198                 default:
199                         break;
200                 }
201         }
202 }
203
204 static void
205 state_sh(STATE_ARGS)
206 {
207         struct roff_node *nch;
208         char             *secname;
209
210         if (n->type != ROFFT_HEAD)
211                 return;
212
213         if ( ! (n->flags & NODE_VALID)) {
214                 secname = NULL;
215                 deroff(&secname, n);
216
217                 /*
218                  * Set the section attribute for the BLOCK, HEAD,
219                  * and HEAD children; the latter can only be TEXT
220                  * nodes, so no recursion is needed.  For other
221                  * nodes, including the .Sh BODY, this is done
222                  * when allocating the node data structures, but
223                  * for .Sh BLOCK and HEAD, the section is still
224                  * unknown at that time.
225                  */
226
227                 n->sec = n->parent->sec = secname == NULL ?
228                     SEC_CUSTOM : mdoc_a2sec(secname);
229                 for (nch = n->child; nch != NULL; nch = nch->next)
230                         nch->sec = n->sec;
231                 free(secname);
232         }
233
234         if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
235                 roff_setreg(mdoc->roff, "nS", 1, '=');
236                 mdoc->flags |= MDOC_SYNOPSIS;
237         } else {
238                 roff_setreg(mdoc->roff, "nS", 0, '=');
239                 mdoc->flags &= ~MDOC_SYNOPSIS;
240         }
241 }
242
243 static void
244 state_sm(STATE_ARGS)
245 {
246
247         if (n->child == NULL)
248                 mdoc->flags ^= MDOC_SMOFF;
249         else if ( ! strcmp(n->child->string, "on"))
250                 mdoc->flags &= ~MDOC_SMOFF;
251         else if ( ! strcmp(n->child->string, "off"))
252                 mdoc->flags |= MDOC_SMOFF;
253 }