]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/mandoc/mdoc_state.c
readelf: add newline after dumping dynamic FLAGS / FLAGS_1
[FreeBSD/FreeBSD.git] / contrib / mandoc / mdoc_state.c
1 /*      $Id: mdoc_state.c,v 1.9 2017/11/29 20:05:33 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 <stdlib.h>
21 #include <string.h>
22
23 #include "mandoc.h"
24 #include "roff.h"
25 #include "mdoc.h"
26 #include "libmandoc.h"
27 #include "libmdoc.h"
28
29 #define STATE_ARGS  struct roff_man *mdoc, struct roff_node *n
30
31 typedef void    (*state_handler)(STATE_ARGS);
32
33 static  void     state_bd(STATE_ARGS);
34 static  void     state_bl(STATE_ARGS);
35 static  void     state_dl(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         state_dl,       /* Dl */
48         state_bd,       /* 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 static const state_handler *const state_handlers = __state_handlers - MDOC_Dd;
162
163
164 void
165 mdoc_state(struct roff_man *mdoc, struct roff_node *n)
166 {
167         state_handler handler;
168
169         if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
170                 return;
171
172         assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
173         if ( ! (mdoc_macros[n->tok].flags & MDOC_PROLOGUE))
174                 mdoc->flags |= MDOC_PBODY;
175
176         handler = state_handlers[n->tok];
177         if (*handler)
178                 (*handler)(mdoc, n);
179 }
180
181 void
182 mdoc_state_reset(struct roff_man *mdoc)
183 {
184
185         roff_setreg(mdoc->roff, "nS", 0, '=');
186         mdoc->flags = 0;
187 }
188
189 static void
190 state_bd(STATE_ARGS)
191 {
192         enum mdocargt arg;
193
194         if (n->type != ROFFT_HEAD &&
195             (n->type != ROFFT_BODY || n->end != ENDBODY_NOT))
196                 return;
197
198         if (n->parent->args == NULL)
199                 return;
200
201         arg = n->parent->args->argv[0].arg;
202         if (arg != MDOC_Literal && arg != MDOC_Unfilled)
203                 return;
204
205         state_dl(mdoc, n);
206 }
207
208 static void
209 state_bl(STATE_ARGS)
210 {
211         struct mdoc_arg *args;
212         size_t           i;
213
214         if (n->type != ROFFT_HEAD || n->parent->args == NULL)
215                 return;
216
217         args = n->parent->args;
218         for (i = 0; i < args->argc; i++) {
219                 switch(args->argv[i].arg) {
220                 case MDOC_Diag:
221                         n->norm->Bl.type = LIST_diag;
222                         return;
223                 case MDOC_Column:
224                         n->norm->Bl.type = LIST_column;
225                         return;
226                 default:
227                         break;
228                 }
229         }
230 }
231
232 static void
233 state_dl(STATE_ARGS)
234 {
235
236         switch (n->type) {
237         case ROFFT_HEAD:
238                 mdoc->flags |= MDOC_LITERAL;
239                 break;
240         case ROFFT_BODY:
241                 mdoc->flags &= ~MDOC_LITERAL;
242                 break;
243         default:
244                 break;
245         }
246 }
247
248 static void
249 state_sh(STATE_ARGS)
250 {
251         struct roff_node *nch;
252         char             *secname;
253
254         if (n->type != ROFFT_HEAD)
255                 return;
256
257         if ( ! (n->flags & NODE_VALID)) {
258                 secname = NULL;
259                 deroff(&secname, n);
260
261                 /*
262                  * Set the section attribute for the BLOCK, HEAD,
263                  * and HEAD children; the latter can only be TEXT
264                  * nodes, so no recursion is needed.  For other
265                  * nodes, including the .Sh BODY, this is done
266                  * when allocating the node data structures, but
267                  * for .Sh BLOCK and HEAD, the section is still
268                  * unknown at that time.
269                  */
270
271                 n->sec = n->parent->sec = secname == NULL ?
272                     SEC_CUSTOM : mdoc_a2sec(secname);
273                 for (nch = n->child; nch != NULL; nch = nch->next)
274                         nch->sec = n->sec;
275                 free(secname);
276         }
277
278         if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
279                 roff_setreg(mdoc->roff, "nS", 1, '=');
280                 mdoc->flags |= MDOC_SYNOPSIS;
281         } else {
282                 roff_setreg(mdoc->roff, "nS", 0, '=');
283                 mdoc->flags &= ~MDOC_SYNOPSIS;
284         }
285 }
286
287 static void
288 state_sm(STATE_ARGS)
289 {
290
291         if (n->child == NULL)
292                 mdoc->flags ^= MDOC_SMOFF;
293         else if ( ! strcmp(n->child->string, "on"))
294                 mdoc->flags &= ~MDOC_SMOFF;
295         else if ( ! strcmp(n->child->string, "off"))
296                 mdoc->flags |= MDOC_SMOFF;
297 }