Annotation of mandoc/mdoc_state.c, Revision 1.3
1.3 ! schwarze 1: /* $Id: mdoc_state.c,v 1.2 2015/10/21 23:51:11 schwarze Exp $ */
1.1 schwarze 2: /*
3: * Copyright (c) 2014, 2015 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 <stdlib.h>
20: #include <string.h>
21:
22: #include "mandoc.h"
23: #include "roff.h"
24: #include "mdoc.h"
25: #include "libmandoc.h"
26: #include "libmdoc.h"
27:
28: #define STATE_ARGS struct roff_man *mdoc, struct roff_node *n
29:
30: typedef void (*state_handler)(STATE_ARGS);
31:
32: static void state_bd(STATE_ARGS);
1.2 schwarze 33: static void state_bl(STATE_ARGS);
1.1 schwarze 34: static void state_dl(STATE_ARGS);
35: static void state_sh(STATE_ARGS);
36: static void state_sm(STATE_ARGS);
37:
38: static const state_handler state_handlers[MDOC_MAX] = {
39: NULL, /* Ap */
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 */
1.2 schwarze 50: state_bl, /* Bl */
1.1 schwarze 51: NULL, /* El */
52: NULL, /* It */
53: NULL, /* Ad */
54: NULL, /* An */
55: NULL, /* Ar */
56: NULL, /* Cd */
57: NULL, /* Cm */
58: NULL, /* Dv */
59: NULL, /* Er */
60: NULL, /* Ev */
61: NULL, /* Ex */
62: NULL, /* Fa */
63: NULL, /* Fd */
64: NULL, /* Fl */
65: NULL, /* Fn */
66: NULL, /* Ft */
67: NULL, /* Ic */
68: NULL, /* In */
69: NULL, /* Li */
70: NULL, /* Nd */
71: NULL, /* Nm */
72: NULL, /* Op */
73: NULL, /* Ot */
74: NULL, /* Pa */
75: NULL, /* Rv */
76: NULL, /* St */
77: NULL, /* Va */
78: NULL, /* Vt */
79: NULL, /* Xr */
80: NULL, /* %A */
81: NULL, /* %B */
82: NULL, /* %D */
83: NULL, /* %I */
84: NULL, /* %J */
85: NULL, /* %N */
86: NULL, /* %O */
87: NULL, /* %P */
88: NULL, /* %R */
89: NULL, /* %T */
90: NULL, /* %V */
91: NULL, /* Ac */
92: NULL, /* Ao */
93: NULL, /* Aq */
94: NULL, /* At */
95: NULL, /* Bc */
96: NULL, /* Bf */
97: NULL, /* Bo */
98: NULL, /* Bq */
99: NULL, /* Bsx */
100: NULL, /* Bx */
101: NULL, /* Db */
102: NULL, /* Dc */
103: NULL, /* Do */
104: NULL, /* Dq */
105: NULL, /* Ec */
106: NULL, /* Ef */
107: NULL, /* Em */
108: NULL, /* Eo */
109: NULL, /* Fx */
110: NULL, /* Ms */
111: NULL, /* No */
112: NULL, /* Ns */
113: NULL, /* Nx */
114: NULL, /* Ox */
115: NULL, /* Pc */
116: NULL, /* Pf */
117: NULL, /* Po */
118: NULL, /* Pq */
119: NULL, /* Qc */
120: NULL, /* Ql */
121: NULL, /* Qo */
122: NULL, /* Qq */
123: NULL, /* Re */
124: NULL, /* Rs */
125: NULL, /* Sc */
126: NULL, /* So */
127: NULL, /* Sq */
128: state_sm, /* Sm */
129: NULL, /* Sx */
130: NULL, /* Sy */
131: NULL, /* Tn */
132: NULL, /* Ux */
133: NULL, /* Xc */
134: NULL, /* Xo */
135: NULL, /* Fo */
136: NULL, /* Fc */
137: NULL, /* Oo */
138: NULL, /* Oc */
139: NULL, /* Bk */
140: NULL, /* Ek */
141: NULL, /* Bt */
142: NULL, /* Hf */
143: NULL, /* Fr */
144: NULL, /* Ud */
145: NULL, /* Lb */
146: NULL, /* Lp */
147: NULL, /* Lk */
148: NULL, /* Mt */
149: NULL, /* Brq */
150: NULL, /* Bro */
151: NULL, /* Brc */
152: NULL, /* %C */
153: NULL, /* Es */
154: NULL, /* En */
155: NULL, /* Dx */
156: NULL, /* %Q */
157: NULL, /* br */
158: NULL, /* sp */
159: NULL, /* %U */
160: NULL, /* Ta */
161: NULL, /* ll */
162: };
163:
164:
165: void
166: mdoc_state(struct roff_man *mdoc, struct roff_node *n)
167: {
168: state_handler handler;
169:
170: if (n->tok == TOKEN_NONE)
171: return;
172:
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))
1.3 ! schwarze 196: return;
! 197:
! 198: if (n->parent->args == NULL)
1.1 schwarze 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);
1.2 schwarze 206: }
207:
208: static void
209: state_bl(STATE_ARGS)
210: {
211:
212: if (n->type != ROFFT_HEAD || n->parent->args == NULL)
213: return;
214:
215: switch(n->parent->args->argv[0].arg) {
216: case MDOC_Diag:
217: n->norm->Bl.type = LIST_diag;
218: break;
219: case MDOC_Column:
220: n->norm->Bl.type = LIST_column;
221: break;
222: default:
223: break;
224: }
1.1 schwarze 225: }
226:
227: static void
228: state_dl(STATE_ARGS)
229: {
230:
231: switch (n->type) {
232: case ROFFT_HEAD:
233: mdoc->flags |= MDOC_LITERAL;
234: break;
235: case ROFFT_BODY:
236: mdoc->flags &= ~MDOC_LITERAL;
237: break;
238: default:
239: break;
240: }
241: }
242:
243: static void
244: state_sh(STATE_ARGS)
245: {
246: struct roff_node *nch;
247: char *secname;
248:
249: if (n->type != ROFFT_HEAD)
250: return;
251:
252: if ( ! (n->flags & MDOC_VALID)) {
253: secname = NULL;
254: deroff(&secname, n);
255:
256: /*
257: * Set the section attribute for the BLOCK, HEAD,
258: * and HEAD children; the latter can only be TEXT
259: * nodes, so no recursion is needed. For other
260: * nodes, including the .Sh BODY, this is done
261: * when allocating the node data structures, but
262: * for .Sh BLOCK and HEAD, the section is still
263: * unknown at that time.
264: */
265:
266: n->sec = n->parent->sec = secname == NULL ?
267: SEC_CUSTOM : mdoc_a2sec(secname);
268: for (nch = n->child; nch != NULL; nch = nch->next)
269: nch->sec = n->sec;
270: free(secname);
271: }
272:
273: if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
274: roff_setreg(mdoc->roff, "nS", 1, '=');
275: mdoc->flags |= MDOC_SYNOPSIS;
276: } else {
277: roff_setreg(mdoc->roff, "nS", 0, '=');
278: mdoc->flags &= ~MDOC_SYNOPSIS;
279: }
280: }
281:
282: static void
283: state_sm(STATE_ARGS)
284: {
285:
286: if (n->child == NULL)
287: mdoc->flags ^= MDOC_SMOFF;
288: else if ( ! strcmp(n->child->string, "on"))
289: mdoc->flags &= ~MDOC_SMOFF;
290: else if ( ! strcmp(n->child->string, "off"))
291: mdoc->flags |= MDOC_SMOFF;
292: }
CVSweb