]> git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
Delimiter whitespace is correctly flagged (required some special handling).
[mandoc.git] / mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.33 2009/08/20 08:59:12 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
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 <assert.h>
18 #include <ctype.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "libmdoc.h"
24
25 #define REWIND_REWIND (1 << 0)
26 #define REWIND_NOHALT (1 << 1)
27 #define REWIND_HALT (1 << 2)
28
29 static int obsolete(MACRO_PROT_ARGS);
30 static int blk_part_exp(MACRO_PROT_ARGS);
31 static int in_line_eoln(MACRO_PROT_ARGS);
32 static int in_line_argn(MACRO_PROT_ARGS);
33 static int in_line(MACRO_PROT_ARGS);
34 static int blk_full(MACRO_PROT_ARGS);
35 static int blk_exp_close(MACRO_PROT_ARGS);
36 static int blk_part_imp(MACRO_PROT_ARGS);
37
38 static int phrase(struct mdoc *, int, int, char *);
39 static int rew_dohalt(int, enum mdoc_type,
40 const struct mdoc_node *);
41 static int rew_alt(int);
42 static int rew_dobreak(int, const struct mdoc_node *);
43 static int rew_elem(struct mdoc *, int);
44 static int rew_sub(enum mdoc_type, struct mdoc *,
45 int, int, int);
46 static int rew_last(struct mdoc *,
47 const struct mdoc_node *);
48 static int append_delims(struct mdoc *, int, int *, char *);
49 static int lookup(struct mdoc *, int, const char *);
50 static int lookup_raw(struct mdoc *, const char *);
51 static int swarn(struct mdoc *, enum mdoc_type, int, int,
52 const struct mdoc_node *);
53
54 /* Central table of library: who gets parsed how. */
55
56 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
57 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */
58 { in_line_eoln, MDOC_PROLOGUE }, /* Dd */
59 { in_line_eoln, MDOC_PROLOGUE }, /* Dt */
60 { in_line_eoln, MDOC_PROLOGUE }, /* Os */
61 { blk_full, 0 }, /* Sh */
62 { blk_full, 0 }, /* Ss */
63 { in_line_eoln, 0 }, /* Pp */
64 { blk_part_imp, MDOC_PARSED }, /* D1 */
65 { blk_part_imp, MDOC_PARSED }, /* Dl */
66 { blk_full, MDOC_EXPLICIT }, /* Bd */
67 { blk_exp_close, MDOC_EXPLICIT }, /* Ed */
68 { blk_full, MDOC_EXPLICIT }, /* Bl */
69 { blk_exp_close, MDOC_EXPLICIT }, /* El */
70 { blk_full, MDOC_PARSED }, /* It */
71 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
72 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */
73 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
74 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */
75 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
76 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
77 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
78 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */
79 { in_line_eoln, 0 }, /* Ex */
80 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */
81 { in_line_eoln, 0 }, /* Fd */
82 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
83 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
84 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
85 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */
86 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
87 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */
88 { blk_full, 0 }, /* Nd */
89 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
90 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
91 { obsolete, 0 }, /* Ot */
92 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
93 { in_line_eoln, 0 }, /* Rv */
94 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
95 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
96 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
97 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
98 { in_line_eoln, 0 }, /* %A */
99 { in_line_eoln, 0 }, /* %B */
100 { in_line_eoln, 0 }, /* %D */
101 { in_line_eoln, 0 }, /* %I */
102 { in_line_eoln, 0 }, /* %J */
103 { in_line_eoln, 0 }, /* %N */
104 { in_line_eoln, 0 }, /* %O */
105 { in_line_eoln, 0 }, /* %P */
106 { in_line_eoln, 0 }, /* %R */
107 { in_line_eoln, 0 }, /* %T */
108 { in_line_eoln, 0 }, /* %V */
109 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */
110 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */
111 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */
112 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */
113 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */
114 { blk_full, MDOC_EXPLICIT }, /* Bf */
115 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */
116 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */
117 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */
118 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */
119 { in_line_eoln, 0 }, /* Db */
120 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */
121 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */
122 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */
123 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */
124 { blk_exp_close, MDOC_EXPLICIT }, /* Ef */
125 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */
126 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */
127 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */
128 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */
129 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* No */
130 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ns */
131 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */
132 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */
133 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */
134 { in_line_argn, MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */
135 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */
136 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */
137 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */
138 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */
139 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */
140 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */
141 { blk_exp_close, MDOC_EXPLICIT }, /* Re */
142 { blk_full, MDOC_EXPLICIT }, /* Rs */
143 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */
144 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */
145 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */
146 { in_line_eoln, 0 }, /* Sm */
147 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */
148 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */
149 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */
150 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */
151 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */
152 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */
153 { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */
154 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */
155 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */
156 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */
157 { blk_full, MDOC_EXPLICIT }, /* Bk */
158 { blk_exp_close, MDOC_EXPLICIT }, /* Ek */
159 { in_line_eoln, 0 }, /* Bt */
160 { in_line_eoln, 0 }, /* Hf */
161 { obsolete, 0 }, /* Fr */
162 { in_line_eoln, 0 }, /* Ud */
163 { in_line_eoln, 0 }, /* Lb */
164 { in_line_eoln, 0 }, /* Lp */
165 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */
166 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */
167 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */
168 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */
169 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */
170 { in_line_eoln, 0 }, /* %C */
171 { obsolete, 0 }, /* Es */
172 { obsolete, 0 }, /* En */
173 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
174 { in_line_eoln, 0 }, /* %Q */
175 { in_line_eoln, 0 }, /* br */
176 { in_line_eoln, 0 }, /* sp */
177 };
178
179 const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
180
181
182 static int
183 swarn(struct mdoc *mdoc, enum mdoc_type type,
184 int line, int pos, const struct mdoc_node *p)
185 {
186 const char *n, *t, *tt;
187
188 n = t = "<root>";
189 tt = "block";
190
191 switch (type) {
192 case (MDOC_BODY):
193 tt = "multi-line";
194 break;
195 case (MDOC_HEAD):
196 tt = "line";
197 break;
198 default:
199 break;
200 }
201
202 switch (p->type) {
203 case (MDOC_BLOCK):
204 n = mdoc_macronames[p->tok];
205 t = "block";
206 break;
207 case (MDOC_BODY):
208 n = mdoc_macronames[p->tok];
209 t = "multi-line";
210 break;
211 case (MDOC_HEAD):
212 n = mdoc_macronames[p->tok];
213 t = "line";
214 break;
215 default:
216 break;
217 }
218
219 if ( ! (MDOC_IGN_SCOPE & mdoc->pflags))
220 return(mdoc_verr(mdoc, line, pos,
221 "%s scope breaks %s scope of %s",
222 tt, t, n));
223 return(mdoc_vwarn(mdoc, line, pos,
224 "%s scope breaks %s scope of %s",
225 tt, t, n));
226 }
227
228
229 /*
230 * This is called at the end of parsing. It must traverse up the tree,
231 * closing out open [implicit] scopes. Obviously, open explicit scopes
232 * are errors.
233 */
234 int
235 mdoc_macroend(struct mdoc *m)
236 {
237 struct mdoc_node *n;
238
239 /* Scan for open explicit scopes. */
240
241 n = MDOC_VALID & m->last->flags ? m->last->parent : m->last;
242
243 for ( ; n; n = n->parent) {
244 if (MDOC_BLOCK != n->type)
245 continue;
246 if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags))
247 continue;
248 return(mdoc_nerr(m, n, EOPEN));
249 }
250
251 /* Rewind to the first. */
252
253 return(rew_last(m, m->first));
254 }
255
256
257 /*
258 * Look up a macro from within a subsequent context.
259 */
260 static int
261 lookup(struct mdoc *mdoc, int from, const char *p)
262 {
263
264 if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
265 return(MDOC_MAX);
266 return(lookup_raw(mdoc, p));
267 }
268
269
270 /*
271 * Lookup a macro following the initial line macro.
272 */
273 static int
274 lookup_raw(struct mdoc *mdoc, const char *p)
275 {
276 int res;
277
278 if (MDOC_MAX == (res = mdoc_hash_find(mdoc->htab, p)))
279 return(MDOC_MAX);
280 if (MDOC_CALLABLE & mdoc_macros[res].flags)
281 return(res);
282 return(MDOC_MAX);
283 }
284
285
286 static int
287 rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
288 {
289
290 assert(to);
291 mdoc->next = MDOC_NEXT_SIBLING;
292
293 /* LINTED */
294 while (mdoc->last != to) {
295 if ( ! mdoc_valid_post(mdoc))
296 return(0);
297 if ( ! mdoc_action_post(mdoc))
298 return(0);
299 mdoc->last = mdoc->last->parent;
300 assert(mdoc->last);
301 }
302
303 if ( ! mdoc_valid_post(mdoc))
304 return(0);
305 return(mdoc_action_post(mdoc));
306 }
307
308
309 /*
310 * Return the opening macro of a closing one, e.g., `Ec' has `Eo' as its
311 * matching pair.
312 */
313 static int
314 rew_alt(int tok)
315 {
316 switch (tok) {
317 case (MDOC_Ac):
318 return(MDOC_Ao);
319 case (MDOC_Bc):
320 return(MDOC_Bo);
321 case (MDOC_Brc):
322 return(MDOC_Bro);
323 case (MDOC_Dc):
324 return(MDOC_Do);
325 case (MDOC_Ec):
326 return(MDOC_Eo);
327 case (MDOC_Ed):
328 return(MDOC_Bd);
329 case (MDOC_Ef):
330 return(MDOC_Bf);
331 case (MDOC_Ek):
332 return(MDOC_Bk);
333 case (MDOC_El):
334 return(MDOC_Bl);
335 case (MDOC_Fc):
336 return(MDOC_Fo);
337 case (MDOC_Oc):
338 return(MDOC_Oo);
339 case (MDOC_Pc):
340 return(MDOC_Po);
341 case (MDOC_Qc):
342 return(MDOC_Qo);
343 case (MDOC_Re):
344 return(MDOC_Rs);
345 case (MDOC_Sc):
346 return(MDOC_So);
347 case (MDOC_Xc):
348 return(MDOC_Xo);
349 default:
350 break;
351 }
352 abort();
353 /* NOTREACHED */
354 }
355
356
357 /*
358 * Rewind rules. This indicates whether to stop rewinding
359 * (REWIND_HALT) without touching our current scope, stop rewinding and
360 * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
361 * The scope-closing and so on occurs in the various rew_* routines.
362 */
363 static int
364 rew_dohalt(int tok, enum mdoc_type type, const struct mdoc_node *p)
365 {
366
367 if (MDOC_ROOT == p->type)
368 return(REWIND_HALT);
369 if (MDOC_VALID & p->flags)
370 return(REWIND_NOHALT);
371
372 switch (tok) {
373 case (MDOC_Aq):
374 /* FALLTHROUGH */
375 case (MDOC_Bq):
376 /* FALLTHROUGH */
377 case (MDOC_Brq):
378 /* FALLTHROUGH */
379 case (MDOC_D1):
380 /* FALLTHROUGH */
381 case (MDOC_Dl):
382 /* FALLTHROUGH */
383 case (MDOC_Dq):
384 /* FALLTHROUGH */
385 case (MDOC_Op):
386 /* FALLTHROUGH */
387 case (MDOC_Pq):
388 /* FALLTHROUGH */
389 case (MDOC_Ql):
390 /* FALLTHROUGH */
391 case (MDOC_Qq):
392 /* FALLTHROUGH */
393 case (MDOC_Sq):
394 assert(MDOC_TAIL != type);
395 if (type == p->type && tok == p->tok)
396 return(REWIND_REWIND);
397 break;
398 case (MDOC_It):
399 assert(MDOC_TAIL != type);
400 if (type == p->type && tok == p->tok)
401 return(REWIND_REWIND);
402 if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
403 return(REWIND_HALT);
404 break;
405 case (MDOC_Sh):
406 if (type == p->type && tok == p->tok)
407 return(REWIND_REWIND);
408 break;
409 case (MDOC_Nd):
410 /* FALLTHROUGH */
411 case (MDOC_Ss):
412 assert(MDOC_TAIL != type);
413 if (type == p->type && tok == p->tok)
414 return(REWIND_REWIND);
415 if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
416 return(REWIND_HALT);
417 break;
418 case (MDOC_Ao):
419 /* FALLTHROUGH */
420 case (MDOC_Bd):
421 /* FALLTHROUGH */
422 case (MDOC_Bf):
423 /* FALLTHROUGH */
424 case (MDOC_Bk):
425 /* FALLTHROUGH */
426 case (MDOC_Bl):
427 /* FALLTHROUGH */
428 case (MDOC_Bo):
429 /* FALLTHROUGH */
430 case (MDOC_Bro):
431 /* FALLTHROUGH */
432 case (MDOC_Do):
433 /* FALLTHROUGH */
434 case (MDOC_Eo):
435 /* FALLTHROUGH */
436 case (MDOC_Fo):
437 /* FALLTHROUGH */
438 case (MDOC_Oo):
439 /* FALLTHROUGH */
440 case (MDOC_Po):
441 /* FALLTHROUGH */
442 case (MDOC_Qo):
443 /* FALLTHROUGH */
444 case (MDOC_Rs):
445 /* FALLTHROUGH */
446 case (MDOC_So):
447 /* FALLTHROUGH */
448 case (MDOC_Xo):
449 if (type == p->type && tok == p->tok)
450 return(REWIND_REWIND);
451 break;
452 /* Multi-line explicit scope close. */
453 case (MDOC_Ac):
454 /* FALLTHROUGH */
455 case (MDOC_Bc):
456 /* FALLTHROUGH */
457 case (MDOC_Brc):
458 /* FALLTHROUGH */
459 case (MDOC_Dc):
460 /* FALLTHROUGH */
461 case (MDOC_Ec):
462 /* FALLTHROUGH */
463 case (MDOC_Ed):
464 /* FALLTHROUGH */
465 case (MDOC_Ek):
466 /* FALLTHROUGH */
467 case (MDOC_El):
468 /* FALLTHROUGH */
469 case (MDOC_Fc):
470 /* FALLTHROUGH */
471 case (MDOC_Ef):
472 /* FALLTHROUGH */
473 case (MDOC_Oc):
474 /* FALLTHROUGH */
475 case (MDOC_Pc):
476 /* FALLTHROUGH */
477 case (MDOC_Qc):
478 /* FALLTHROUGH */
479 case (MDOC_Re):
480 /* FALLTHROUGH */
481 case (MDOC_Sc):
482 /* FALLTHROUGH */
483 case (MDOC_Xc):
484 if (type == p->type && rew_alt(tok) == p->tok)
485 return(REWIND_REWIND);
486 break;
487 default:
488 abort();
489 /* NOTREACHED */
490 }
491
492 return(REWIND_NOHALT);
493 }
494
495
496 /*
497 * See if we can break an encountered scope (the rew_dohalt has returned
498 * REWIND_NOHALT).
499 */
500 static int
501 rew_dobreak(int tok, const struct mdoc_node *p)
502 {
503
504 assert(MDOC_ROOT != p->type);
505 if (MDOC_ELEM == p->type)
506 return(1);
507 if (MDOC_TEXT == p->type)
508 return(1);
509 if (MDOC_VALID & p->flags)
510 return(1);
511
512 switch (tok) {
513 case (MDOC_It):
514 return(MDOC_It == p->tok);
515 case (MDOC_Nd):
516 return(MDOC_Nd == p->tok);
517 case (MDOC_Ss):
518 return(MDOC_Ss == p->tok);
519 case (MDOC_Sh):
520 if (MDOC_Nd == p->tok)
521 return(1);
522 if (MDOC_Ss == p->tok)
523 return(1);
524 return(MDOC_Sh == p->tok);
525 case (MDOC_El):
526 if (MDOC_It == p->tok)
527 return(1);
528 break;
529 case (MDOC_Oc):
530 /* XXX - experimental! */
531 if (MDOC_Op == p->tok)
532 return(1);
533 break;
534 default:
535 break;
536 }
537
538 if (MDOC_EXPLICIT & mdoc_macros[tok].flags)
539 return(p->tok == rew_alt(tok));
540 else if (MDOC_BLOCK == p->type)
541 return(1);
542
543 return(tok == p->tok);
544 }
545
546
547 static int
548 rew_elem(struct mdoc *mdoc, int tok)
549 {
550 struct mdoc_node *n;
551
552 n = mdoc->last;
553 if (MDOC_ELEM != n->type)
554 n = n->parent;
555 assert(MDOC_ELEM == n->type);
556 assert(tok == n->tok);
557
558 return(rew_last(mdoc, n));
559 }
560
561
562 static int
563 rew_sub(enum mdoc_type t, struct mdoc *m,
564 int tok, int line, int ppos)
565 {
566 struct mdoc_node *n;
567 int c;
568
569 /* LINTED */
570 for (n = m->last; n; n = n->parent) {
571 c = rew_dohalt(tok, t, n);
572 if (REWIND_HALT == c) {
573 if (MDOC_BLOCK != t)
574 return(1);
575 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
576 return(1);
577 return(mdoc_perr(m, line, ppos, ENOCTX));
578 }
579 if (REWIND_REWIND == c)
580 break;
581 else if (rew_dobreak(tok, n))
582 continue;
583 if ( ! swarn(m, t, line, ppos, n))
584 return(0);
585 }
586
587 assert(n);
588 return(rew_last(m, n));
589 }
590
591
592 static int
593 append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
594 {
595 int c, lastarg;
596 char *p;
597
598 if (0 == buf[*pos])
599 return(1);
600
601 for (;;) {
602 lastarg = *pos;
603 c = mdoc_zargs(mdoc, line, pos, buf, ARGS_NOWARN, &p);
604 assert(ARGS_PHRASE != c);
605
606 if (ARGS_ERROR == c)
607 return(0);
608 else if (ARGS_EOLN == c)
609 break;
610 assert(mdoc_isdelim(p));
611 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
612 return(0);
613 }
614
615 return(1);
616 }
617
618
619 /*
620 * Close out block partial/full explicit.
621 */
622 static int
623 blk_exp_close(MACRO_PROT_ARGS)
624 {
625 int j, c, lastarg, maxargs, flushed;
626 char *p;
627
628 switch (tok) {
629 case (MDOC_Ec):
630 maxargs = 1;
631 break;
632 default:
633 maxargs = 0;
634 break;
635 }
636
637 if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
638 if (buf[*pos])
639 if ( ! mdoc_pwarn(m, line, ppos, ENOLINE))
640 return(0);
641
642 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
643 return(0);
644 return(rew_sub(MDOC_BLOCK, m, tok, line, ppos));
645 }
646
647 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
648 return(0);
649
650 if (maxargs > 0)
651 if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok)))
652 return(0);
653
654 for (flushed = j = 0; ; j++) {
655 lastarg = *pos;
656
657 if (j == maxargs && ! flushed) {
658 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
659 return(0);
660 flushed = 1;
661 }
662
663 c = mdoc_args(m, line, pos, buf, tok, &p);
664
665 if (ARGS_ERROR == c)
666 return(0);
667 if (ARGS_PUNCT == c)
668 break;
669 if (ARGS_EOLN == c)
670 break;
671
672 if (MDOC_MAX != (c = lookup(m, tok, p))) {
673 if ( ! flushed) {
674 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
675 return(0);
676 flushed = 1;
677 }
678 if ( ! mdoc_macro(m, c, line, lastarg, pos, buf))
679 return(0);
680 break;
681 }
682
683 if ( ! mdoc_word_alloc(m, line, lastarg, p))
684 return(0);
685 }
686
687 if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
688 return(0);
689
690 if (ppos > 1)
691 return(1);
692 return(append_delims(m, line, pos, buf));
693 }
694
695
696 static int
697 in_line(MACRO_PROT_ARGS)
698 {
699 int la, lastpunct, c, w, cnt, d, nc;
700 struct mdoc_arg *arg;
701 char *p;
702
703 /*
704 * Whether we allow ignored elements (those without content,
705 * usually because of reserved words) to squeak by.
706 */
707 switch (tok) {
708 case (MDOC_An):
709 /* FALLTHROUGH */
710 case (MDOC_Ar):
711 /* FALLTHROUGH */
712 case (MDOC_Fl):
713 /* FALLTHROUGH */
714 case (MDOC_Lk):
715 /* FALLTHROUGH */
716 case (MDOC_Nm):
717 /* FALLTHROUGH */
718 case (MDOC_Pa):
719 nc = 1;
720 break;
721 default:
722 nc = 0;
723 break;
724 }
725
726 for (arg = NULL;; ) {
727 la = *pos;
728 c = mdoc_argv(m, line, tok, &arg, pos, buf);
729
730 if (ARGV_WORD == c) {
731 *pos = la;
732 break;
733 }
734 if (ARGV_EOLN == c)
735 break;
736 if (ARGV_ARG == c)
737 continue;
738
739 mdoc_argv_free(arg);
740 return(0);
741 }
742
743 for (cnt = 0, lastpunct = 1;; ) {
744 la = *pos;
745 w = mdoc_args(m, line, pos, buf, tok, &p);
746
747 if (ARGS_ERROR == w)
748 return(0);
749 if (ARGS_EOLN == w)
750 break;
751 if (ARGS_PUNCT == w)
752 break;
753
754 /* Quoted words shouldn't be looked-up. */
755
756 c = ARGS_QWORD == w ? MDOC_MAX : lookup(m, tok, p);
757
758 /*
759 * In this case, we've located a submacro and must
760 * execute it. Close out scope, if open. If no
761 * elements have been generated, either create one (nc)
762 * or raise a warning.
763 */
764
765 if (MDOC_MAX != c) {
766 if (0 == lastpunct && ! rew_elem(m, tok))
767 return(0);
768 if (nc && 0 == cnt) {
769 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
770 return(0);
771 if ( ! rew_last(m, m->last))
772 return(0);
773 } else if ( ! nc && 0 == cnt) {
774 mdoc_argv_free(arg);
775 if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
776 return(0);
777 }
778 c = mdoc_macro(m, c, line, la, pos, buf);
779 if (0 == c)
780 return(0);
781 if (ppos > 1)
782 return(1);
783 return(append_delims(m, line, pos, buf));
784 }
785
786 /*
787 * Non-quote-enclosed punctuation. Set up our scope, if
788 * a word; rewind the scope, if a delimiter; then append
789 * the word.
790 */
791
792 d = mdoc_isdelim(p);
793
794 if (ARGS_QWORD != w && d) {
795 if (0 == lastpunct && ! rew_elem(m, tok))
796 return(0);
797 lastpunct = 1;
798 } else if (lastpunct) {
799 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
800 return(0);
801 lastpunct = 0;
802 }
803
804 if ( ! d)
805 cnt++;
806 if ( ! mdoc_word_alloc(m, line, la, p))
807 return(0);
808 }
809
810 if (0 == lastpunct && ! rew_elem(m, tok))
811 return(0);
812
813 /*
814 * If no elements have been collected and we're allowed to have
815 * empties (nc), open a scope and close it out. Otherwise,
816 * raise a warning.
817 *
818 */
819 if (nc && 0 == cnt) {
820 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
821 return(0);
822 if ( ! rew_last(m, m->last))
823 return(0);
824 } else if ( ! nc && 0 == cnt) {
825 mdoc_argv_free(arg);
826 if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
827 return(0);
828 }
829
830 if (ppos > 1)
831 return(1);
832 return(append_delims(m, line, pos, buf));
833 }
834
835
836 static int
837 blk_full(MACRO_PROT_ARGS)
838 {
839 int c, lastarg, reopen, dohead;
840 struct mdoc_arg *arg;
841 char *p;
842
843 /*
844 * Whether to process a block-head section. If this is
845 * non-zero, then a head will be opened for all line arguments.
846 * If not, then the head will always be empty and only a body
847 * will be opened, which will stay open at the eoln.
848 */
849
850 switch (tok) {
851 case (MDOC_Nd):
852 dohead = 0;
853 break;
854 default:
855 dohead = 1;
856 break;
857 }
858
859 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
860 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
861 return(0);
862 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
863 return(0);
864 }
865
866 for (arg = NULL;; ) {
867 lastarg = *pos;
868 c = mdoc_argv(m, line, tok, &arg, pos, buf);
869
870 if (ARGV_WORD == c) {
871 *pos = lastarg;
872 break;
873 }
874
875 if (ARGV_EOLN == c)
876 break;
877 if (ARGV_ARG == c)
878 continue;
879
880 mdoc_argv_free(arg);
881 return(0);
882 }
883
884 if ( ! mdoc_block_alloc(m, line, ppos, tok, arg))
885 return(0);
886
887 if (0 == buf[*pos]) {
888 if ( ! mdoc_head_alloc(m, line, ppos, tok))
889 return(0);
890 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
891 return(0);
892 if ( ! mdoc_body_alloc(m, line, ppos, tok))
893 return(0);
894 return(1);
895 }
896
897 if ( ! mdoc_head_alloc(m, line, ppos, tok))
898 return(0);
899
900 /* Immediately close out head and enter body, if applicable. */
901
902 if (0 == dohead) {
903 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
904 return(0);
905 if ( ! mdoc_body_alloc(m, line, ppos, tok))
906 return(0);
907 }
908
909 for (reopen = 0;; ) {
910 lastarg = *pos;
911 c = mdoc_args(m, line, pos, buf, tok, &p);
912
913 if (ARGS_ERROR == c)
914 return(0);
915 if (ARGS_EOLN == c)
916 break;
917 if (ARGS_PHRASE == c) {
918 assert(dohead);
919 if (reopen && ! mdoc_head_alloc(m, line, ppos, tok))
920 return(0);
921 /*
922 * Phrases are self-contained macro phrases used
923 * in the columnar output of a macro. They need
924 * special handling.
925 */
926 if ( ! phrase(m, line, lastarg, buf))
927 return(0);
928 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
929 return(0);
930
931 reopen = 1;
932 continue;
933 }
934
935 if (MDOC_MAX == (c = lookup(m, tok, p))) {
936 if ( ! mdoc_word_alloc(m, line, lastarg, p))
937 return(0);
938 continue;
939 }
940
941 if ( ! mdoc_macro(m, c, line, lastarg, pos, buf))
942 return(0);
943 break;
944 }
945
946 if (1 == ppos && ! append_delims(m, line, pos, buf))
947 return(0);
948
949 /* If the body's already open, then just return. */
950 if (0 == dohead)
951 return(1);
952
953 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
954 return(0);
955 if ( ! mdoc_body_alloc(m, line, ppos, tok))
956 return(0);
957
958 return(1);
959 }
960
961
962 static int
963 blk_part_imp(MACRO_PROT_ARGS)
964 {
965 int la, c;
966 char *p;
967 struct mdoc_node *blk, *body, *n;
968
969 /* If applicable, close out prior scopes. */
970
971 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL))
972 return(0);
973 /* Saved for later close-out. */
974 blk = m->last;
975 if ( ! mdoc_head_alloc(m, line, ppos, tok))
976 return(0);
977 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
978 return(0);
979 if ( ! mdoc_body_alloc(m, line, ppos, tok))
980 return(0);
981 /* Saved for later close-out. */
982 body = m->last;
983
984 /* Body argument processing. */
985
986 for (;;) {
987 la = *pos;
988 c = mdoc_args(m, line, pos, buf, tok, &p);
989 assert(ARGS_PHRASE != c);
990
991 if (ARGS_ERROR == c)
992 return(0);
993 if (ARGS_PUNCT == c)
994 break;
995 if (ARGS_EOLN == c)
996 break;
997
998 if (MDOC_MAX == (c = lookup(m, tok, p))) {
999 if ( ! mdoc_word_alloc(m, line, la, p))
1000 return(0);
1001 continue;
1002 }
1003
1004 if ( ! mdoc_macro(m, c, line, la, pos, buf))
1005 return(0);
1006 break;
1007 }
1008
1009 /*
1010 * If we can't rewind to our body, then our scope has already
1011 * been closed by another macro (like `Oc' closing `Op'). This
1012 * is ugly behaviour nodding its head to OpenBSD's overwhelming
1013 * crufty use of `Op' breakage--XXX, deprecate in time.
1014 */
1015 for (n = m->last; n; n = n->parent)
1016 if (body == n)
1017 break;
1018 if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK))
1019 return(0);
1020 if (n && ! rew_last(m, body))
1021 return(0);
1022
1023 /* Standard appending of delimiters. */
1024
1025 if (1 == ppos && ! append_delims(m, line, pos, buf))
1026 return(0);
1027
1028 /* Rewind scope, if applicable. */
1029
1030 if (n && ! rew_last(m, blk))
1031 return(0);
1032
1033 return(1);
1034 }
1035
1036
1037 static int
1038 blk_part_exp(MACRO_PROT_ARGS)
1039 {
1040 int la, flushed, j, c, maxargs;
1041 char *p;
1042
1043 /* Number of head arguments. Only `Eo' has these, */
1044
1045 switch (tok) {
1046 case (MDOC_Eo):
1047 maxargs = 1;
1048 break;
1049 default:
1050 maxargs = 0;
1051 break;
1052 }
1053
1054 /* Begin the block scope. */
1055
1056 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL))
1057 return(0);
1058
1059 /*
1060 * If no head arguments, open and then close out a head, noting
1061 * that we've flushed our terms. `flushed' means that we've
1062 * flushed out the head and the body is open.
1063 */
1064
1065 if (0 == maxargs) {
1066 if ( ! mdoc_head_alloc(m, line, ppos, tok))
1067 return(0);
1068 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1069 return(0);
1070 if ( ! mdoc_body_alloc(m, line, ppos, tok))
1071 return(0);
1072 flushed = 1;
1073 } else {
1074 if ( ! mdoc_head_alloc(m, line, ppos, tok))
1075 return(0);
1076 flushed = 0;
1077 }
1078
1079 /* Process the head/head+body line arguments. */
1080
1081 for (j = 0; ; j++) {
1082 la = *pos;
1083 if (j == maxargs && ! flushed) {
1084 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1085 return(0);
1086 flushed = 1;
1087 if ( ! mdoc_body_alloc(m, line, ppos, tok))
1088 return(0);
1089 }
1090
1091 c = mdoc_args(m, line, pos, buf, tok, &p);
1092 assert(ARGS_PHRASE != c);
1093
1094 if (ARGS_ERROR == c)
1095 return(0);
1096 if (ARGS_PUNCT == c)
1097 break;
1098 if (ARGS_EOLN == c)
1099 break;
1100
1101 if (MDOC_MAX != (c = lookup(m, tok, p))) {
1102 if ( ! flushed) {
1103 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1104 return(0);
1105 flushed = 1;
1106 if ( ! mdoc_body_alloc(m, line, ppos, tok))
1107 return(0);
1108 }
1109 if ( ! mdoc_macro(m, c, line, la, pos, buf))
1110 return(0);
1111 break;
1112 }
1113
1114 if ( ! flushed && mdoc_isdelim(p)) {
1115 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1116 return(0);
1117 flushed = 1;
1118 if ( ! mdoc_body_alloc(m, line, ppos, tok))
1119 return(0);
1120 }
1121
1122 if ( ! mdoc_word_alloc(m, line, la, p))
1123 return(0);
1124 }
1125
1126 /* Close the head and open the body, if applicable. */
1127
1128 if ( ! flushed) {
1129 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1130 return(0);
1131 if ( ! mdoc_body_alloc(m, line, ppos, tok))
1132 return(0);
1133 }
1134
1135 /* Standard appending of delimiters. */
1136
1137 if (ppos > 1)
1138 return(1);
1139 return(append_delims(m, line, pos, buf));
1140 }
1141
1142
1143 static int
1144 in_line_argn(MACRO_PROT_ARGS)
1145 {
1146 int la, flushed, j, c, maxargs;
1147 struct mdoc_arg *arg;
1148 char *p;
1149
1150 /* Fixed maximum arguments per macro, if applicable. */
1151
1152 switch (tok) {
1153 case (MDOC_Ap):
1154 /* FALLTHROUGH */
1155 case (MDOC_No):
1156 /* FALLTHROUGH */
1157 case (MDOC_Ns):
1158 /* FALLTHROUGH */
1159 case (MDOC_Ux):
1160 maxargs = 0;
1161 break;
1162 default:
1163 maxargs = 1;
1164 break;
1165 }
1166
1167 /* Macro argument processing. */
1168
1169 for (arg = NULL;; ) {
1170 la = *pos;
1171 c = mdoc_argv(m, line, tok, &arg, pos, buf);
1172
1173 if (ARGV_WORD == c) {
1174 *pos = la;
1175 break;
1176 }
1177
1178 if (ARGV_EOLN == c)
1179 break;
1180 if (ARGV_ARG == c)
1181 continue;
1182
1183 mdoc_argv_free(arg);
1184 return(0);
1185 }
1186
1187 /* Open the element scope. */
1188
1189 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1190 return(0);
1191
1192 /* Process element arguments. */
1193
1194 for (flushed = j = 0; ; j++) {
1195 la = *pos;
1196
1197 if (j == maxargs && ! flushed) {
1198 if ( ! rew_elem(m, tok))
1199 return(0);
1200 flushed = 1;
1201 }
1202
1203 c = mdoc_args(m, line, pos, buf, tok, &p);
1204
1205 if (ARGS_ERROR == c)
1206 return(0);
1207 if (ARGS_PUNCT == c)
1208 break;
1209 if (ARGS_EOLN == c)
1210 break;
1211
1212 if (MDOC_MAX != (c = lookup(m, tok, p))) {
1213 if ( ! flushed && ! rew_elem(m, tok))
1214 return(0);
1215 flushed = 1;
1216 if ( ! mdoc_macro(m, c, line, la, pos, buf))
1217 return(0);
1218 break;
1219 }
1220
1221 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1222 ! flushed && mdoc_isdelim(p)) {
1223 if ( ! rew_elem(m, tok))
1224 return(0);
1225 flushed = 1;
1226 }
1227
1228 if ( ! mdoc_word_alloc(m, line, la, p))
1229 return(0);
1230 }
1231
1232 /* Close out and append delimiters. */
1233
1234 if ( ! flushed && ! rew_elem(m, tok))
1235 return(0);
1236
1237 if (ppos > 1)
1238 return(1);
1239 return(append_delims(m, line, pos, buf));
1240 }
1241
1242
1243 static int
1244 in_line_eoln(MACRO_PROT_ARGS)
1245 {
1246 int c, w, la;
1247 struct mdoc_arg *arg;
1248 char *p;
1249
1250 assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));
1251
1252 /* Parse macro arguments. */
1253
1254 for (arg = NULL; ; ) {
1255 la = *pos;
1256 c = mdoc_argv(m, line, tok, &arg, pos, buf);
1257
1258 if (ARGV_WORD == c) {
1259 *pos = la;
1260 break;
1261 }
1262 if (ARGV_EOLN == c)
1263 break;
1264 if (ARGV_ARG == c)
1265 continue;
1266
1267 mdoc_argv_free(arg);
1268 return(0);
1269 }
1270
1271 /* Open element scope. */
1272
1273 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1274 return(0);
1275
1276 /* Parse argument terms. */
1277
1278 for (;;) {
1279 la = *pos;
1280 w = mdoc_args(m, line, pos, buf, tok, &p);
1281
1282 if (ARGS_ERROR == w)
1283 return(0);
1284 if (ARGS_EOLN == w)
1285 break;
1286
1287 c = ARGS_QWORD == w ? MDOC_MAX : lookup(m, tok, p);
1288
1289 if (MDOC_MAX != c) {
1290 if ( ! rew_elem(m, tok))
1291 return(0);
1292 return(mdoc_macro(m, c, line, la, pos, buf));
1293 }
1294
1295 if ( ! mdoc_word_alloc(m, line, la, p))
1296 return(0);
1297 }
1298
1299 /* Close out (no delimiters). */
1300
1301 return(rew_elem(m, tok));
1302 }
1303
1304
1305 /* ARGSUSED */
1306 static int
1307 obsolete(MACRO_PROT_ARGS)
1308 {
1309
1310 return(mdoc_pwarn(m, line, ppos, EOBS));
1311 }
1312
1313
1314 /*
1315 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1316 * They're unusual because they're basically free-form text until a
1317 * macro is encountered.
1318 */
1319 static int
1320 phrase(struct mdoc *m, int line, int ppos, char *buf)
1321 {
1322 int c, w, la, pos;
1323 char *p;
1324
1325 for (pos = ppos; ; ) {
1326 la = pos;
1327
1328 /* Note: no calling context! */
1329 w = mdoc_zargs(m, line, &pos, buf, 0, &p);
1330
1331 if (ARGS_ERROR == w)
1332 return(0);
1333 if (ARGS_EOLN == w)
1334 break;
1335
1336 c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(m, p);
1337
1338 if (MDOC_MAX != c) {
1339 if ( ! mdoc_macro(m, c, line, la, &pos, buf))
1340 return(0);
1341 return(append_delims(m, line, &pos, buf));
1342 }
1343
1344 if ( ! mdoc_word_alloc(m, line, la, p))
1345 return(0);
1346 }
1347
1348 return(1);
1349 }
1350
1351