Annotation of mandoc/mdoc_state.c, Revision 1.19
1.19 ! schwarze 1: /* $Id: mdoc_state.c,v 1.18 2022/04/14 16:43:44 schwarze Exp $ */
1.1 schwarze 2: /*
1.19 ! schwarze 3: * Copyright (c) 2014,2015,2017,2018,2022 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 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: */
1.17 schwarze 17: #include "config.h"
18:
1.1 schwarze 19: #include <sys/types.h>
20:
1.6 schwarze 21: #include <assert.h>
1.11 schwarze 22: #include <stdio.h>
1.1 schwarze 23: #include <stdlib.h>
24: #include <string.h>
25:
1.18 schwarze 26: #if DEBUG_MEMORY
27: #include "mandoc_dbg.h"
28: #endif
1.1 schwarze 29: #include "mandoc.h"
30: #include "roff.h"
31: #include "mdoc.h"
32: #include "libmandoc.h"
1.12 schwarze 33: #include "roff_int.h"
1.1 schwarze 34: #include "libmdoc.h"
35:
36: #define STATE_ARGS struct roff_man *mdoc, struct roff_node *n
37:
38: typedef void (*state_handler)(STATE_ARGS);
39:
1.19 ! schwarze 40: static void setsec(struct roff_node *, enum roff_sec);
1.2 schwarze 41: static void state_bl(STATE_ARGS);
1.1 schwarze 42: static void state_sh(STATE_ARGS);
43: static void state_sm(STATE_ARGS);
44:
1.10 schwarze 45: static const state_handler state_handlers[MDOC_MAX - MDOC_Dd] = {
1.1 schwarze 46: NULL, /* Dd */
47: NULL, /* Dt */
48: NULL, /* Os */
49: state_sh, /* Sh */
50: NULL, /* Ss */
51: NULL, /* Pp */
52: NULL, /* D1 */
1.15 schwarze 53: NULL, /* Dl */
54: NULL, /* Bd */
1.1 schwarze 55: NULL, /* Ed */
1.2 schwarze 56: state_bl, /* Bl */
1.1 schwarze 57: NULL, /* El */
58: NULL, /* It */
59: NULL, /* Ad */
60: NULL, /* An */
1.5 schwarze 61: NULL, /* Ap */
1.1 schwarze 62: NULL, /* Ar */
63: NULL, /* Cd */
64: NULL, /* Cm */
65: NULL, /* Dv */
66: NULL, /* Er */
67: NULL, /* Ev */
68: NULL, /* Ex */
69: NULL, /* Fa */
70: NULL, /* Fd */
71: NULL, /* Fl */
72: NULL, /* Fn */
73: NULL, /* Ft */
74: NULL, /* Ic */
75: NULL, /* In */
76: NULL, /* Li */
77: NULL, /* Nd */
78: NULL, /* Nm */
79: NULL, /* Op */
80: NULL, /* Ot */
81: NULL, /* Pa */
82: NULL, /* Rv */
83: NULL, /* St */
84: NULL, /* Va */
85: NULL, /* Vt */
86: NULL, /* Xr */
87: NULL, /* %A */
88: NULL, /* %B */
89: NULL, /* %D */
90: NULL, /* %I */
91: NULL, /* %J */
92: NULL, /* %N */
93: NULL, /* %O */
94: NULL, /* %P */
95: NULL, /* %R */
96: NULL, /* %T */
97: NULL, /* %V */
98: NULL, /* Ac */
99: NULL, /* Ao */
100: NULL, /* Aq */
101: NULL, /* At */
102: NULL, /* Bc */
103: NULL, /* Bf */
104: NULL, /* Bo */
105: NULL, /* Bq */
106: NULL, /* Bsx */
107: NULL, /* Bx */
108: NULL, /* Db */
109: NULL, /* Dc */
110: NULL, /* Do */
111: NULL, /* Dq */
112: NULL, /* Ec */
113: NULL, /* Ef */
114: NULL, /* Em */
115: NULL, /* Eo */
116: NULL, /* Fx */
117: NULL, /* Ms */
118: NULL, /* No */
119: NULL, /* Ns */
120: NULL, /* Nx */
121: NULL, /* Ox */
122: NULL, /* Pc */
123: NULL, /* Pf */
124: NULL, /* Po */
125: NULL, /* Pq */
126: NULL, /* Qc */
127: NULL, /* Ql */
128: NULL, /* Qo */
129: NULL, /* Qq */
130: NULL, /* Re */
131: NULL, /* Rs */
132: NULL, /* Sc */
133: NULL, /* So */
134: NULL, /* Sq */
135: state_sm, /* Sm */
136: NULL, /* Sx */
137: NULL, /* Sy */
138: NULL, /* Tn */
139: NULL, /* Ux */
140: NULL, /* Xc */
141: NULL, /* Xo */
142: NULL, /* Fo */
143: NULL, /* Fc */
144: NULL, /* Oo */
145: NULL, /* Oc */
146: NULL, /* Bk */
147: NULL, /* Ek */
148: NULL, /* Bt */
149: NULL, /* Hf */
150: NULL, /* Fr */
151: NULL, /* Ud */
152: NULL, /* Lb */
153: NULL, /* Lp */
154: NULL, /* Lk */
155: NULL, /* Mt */
156: NULL, /* Brq */
157: NULL, /* Bro */
158: NULL, /* Brc */
159: NULL, /* %C */
160: NULL, /* Es */
161: NULL, /* En */
162: NULL, /* Dx */
163: NULL, /* %Q */
164: NULL, /* %U */
165: NULL, /* Ta */
1.16 schwarze 166: NULL, /* Tg */
1.1 schwarze 167: };
168:
169:
170: void
171: mdoc_state(struct roff_man *mdoc, struct roff_node *n)
172: {
173: state_handler handler;
174:
1.6 schwarze 175: if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
1.1 schwarze 176: return;
177:
1.6 schwarze 178: assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
1.10 schwarze 179: if ((mdoc_macro(n->tok)->flags & MDOC_PROLOGUE) == 0)
1.1 schwarze 180: mdoc->flags |= MDOC_PBODY;
181:
1.10 schwarze 182: handler = state_handlers[n->tok - MDOC_Dd];
1.1 schwarze 183: if (*handler)
184: (*handler)(mdoc, n);
185: }
186:
187: static void
1.2 schwarze 188: state_bl(STATE_ARGS)
189: {
1.9 schwarze 190: struct mdoc_arg *args;
191: size_t i;
1.2 schwarze 192:
193: if (n->type != ROFFT_HEAD || n->parent->args == NULL)
194: return;
195:
1.9 schwarze 196: args = n->parent->args;
197: for (i = 0; i < args->argc; i++) {
198: switch(args->argv[i].arg) {
199: case MDOC_Diag:
200: n->norm->Bl.type = LIST_diag;
201: return;
202: case MDOC_Column:
203: n->norm->Bl.type = LIST_column;
204: return;
205: default:
206: break;
207: }
1.1 schwarze 208: }
209: }
210:
211: static void
1.19 ! schwarze 212: setsec(struct roff_node *n, enum roff_sec sec)
! 213: {
! 214: struct roff_node *nch;
! 215:
! 216: n->sec = sec;
! 217: for (nch = n->child; nch != NULL; nch = nch->next)
! 218: setsec(nch, sec);
! 219: }
! 220:
! 221: /*
! 222: * Set the section attribute for the BLOCK, HEAD, and HEAD children.
! 223: * For other nodes, including the .Sh BODY, this is done when allocating
! 224: * the node data structures, but for .Sh BLOCK and HEAD, the section is
! 225: * still unknown at that time.
! 226: */
! 227: static void
1.1 schwarze 228: state_sh(STATE_ARGS)
229: {
1.19 ! schwarze 230: enum roff_sec sec;
1.1 schwarze 231:
232: if (n->type != ROFFT_HEAD)
233: return;
234:
1.19 ! schwarze 235: if ((n->flags & NODE_VALID) == 0) {
! 236: sec = n->child != NULL && n->child->type == ROFFT_TEXT &&
! 237: n->child->next == NULL ? mdoc_a2sec(n->child->string) :
! 238: SEC_CUSTOM;
! 239: n->parent->sec = sec;
! 240: setsec(n, sec);
1.1 schwarze 241: }
242: if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
243: roff_setreg(mdoc->roff, "nS", 1, '=');
244: mdoc->flags |= MDOC_SYNOPSIS;
245: } else {
246: roff_setreg(mdoc->roff, "nS", 0, '=');
247: mdoc->flags &= ~MDOC_SYNOPSIS;
248: }
249: }
250:
251: static void
252: state_sm(STATE_ARGS)
253: {
254:
255: if (n->child == NULL)
256: mdoc->flags ^= MDOC_SMOFF;
257: else if ( ! strcmp(n->child->string, "on"))
258: mdoc->flags &= ~MDOC_SMOFF;
259: else if ( ! strcmp(n->child->string, "off"))
260: mdoc->flags |= MDOC_SMOFF;
261: }
CVSweb