]> git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
One of the WARNING messages has to use the word "section" twice in two
[mandoc.git] / mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.122 2013/09/15 18:26:46 schwarze Exp $ */
2 /*
3 * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
4 * Copyright (c) 2010, 2012 Ingo Schwarze <schwarze@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include <assert.h>
23 #include <ctype.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <time.h>
28
29 #include "mdoc.h"
30 #include "mandoc.h"
31 #include "libmdoc.h"
32 #include "libmandoc.h"
33
34 enum rew { /* see rew_dohalt() */
35 REWIND_NONE,
36 REWIND_THIS,
37 REWIND_MORE,
38 REWIND_FORCE,
39 REWIND_LATER,
40 REWIND_ERROR
41 };
42
43 static int blk_full(MACRO_PROT_ARGS);
44 static int blk_exp_close(MACRO_PROT_ARGS);
45 static int blk_part_exp(MACRO_PROT_ARGS);
46 static int blk_part_imp(MACRO_PROT_ARGS);
47 static int ctx_synopsis(MACRO_PROT_ARGS);
48 static int in_line_eoln(MACRO_PROT_ARGS);
49 static int in_line_argn(MACRO_PROT_ARGS);
50 static int in_line(MACRO_PROT_ARGS);
51 static int obsolete(MACRO_PROT_ARGS);
52 static int phrase_ta(MACRO_PROT_ARGS);
53
54 static int dword(struct mdoc *, int, int,
55 const char *, enum mdelim);
56 static int append_delims(struct mdoc *,
57 int, int *, char *);
58 static enum mdoct lookup(enum mdoct, const char *);
59 static enum mdoct lookup_raw(const char *);
60 static int make_pending(struct mdoc_node *, enum mdoct,
61 struct mdoc *, int, int);
62 static int phrase(struct mdoc *, int, int, char *);
63 static enum mdoct rew_alt(enum mdoct);
64 static enum rew rew_dohalt(enum mdoct, enum mdoc_type,
65 const struct mdoc_node *);
66 static int rew_elem(struct mdoc *, enum mdoct);
67 static int rew_last(struct mdoc *,
68 const struct mdoc_node *);
69 static int rew_sub(enum mdoc_type, struct mdoc *,
70 enum mdoct, int, int);
71
72 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
73 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */
74 { in_line_eoln, MDOC_PROLOGUE }, /* Dd */
75 { in_line_eoln, MDOC_PROLOGUE }, /* Dt */
76 { in_line_eoln, MDOC_PROLOGUE }, /* Os */
77 { blk_full, MDOC_PARSED }, /* Sh */
78 { blk_full, MDOC_PARSED }, /* Ss */
79 { in_line_eoln, 0 }, /* Pp */
80 { blk_part_imp, MDOC_PARSED }, /* D1 */
81 { blk_part_imp, MDOC_PARSED }, /* Dl */
82 { blk_full, MDOC_EXPLICIT }, /* Bd */
83 { blk_exp_close, MDOC_EXPLICIT }, /* Ed */
84 { blk_full, MDOC_EXPLICIT }, /* Bl */
85 { blk_exp_close, MDOC_EXPLICIT }, /* El */
86 { blk_full, MDOC_PARSED }, /* It */
87 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
88 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */
89 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
90 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */
91 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
92 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
93 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
94 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */
95 { in_line_eoln, 0 }, /* Ex */
96 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */
97 { in_line_eoln, 0 }, /* Fd */
98 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
99 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
100 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
101 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */
102 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
103 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */
104 { blk_full, 0 }, /* Nd */
105 { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
106 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
107 { obsolete, 0 }, /* Ot */
108 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
109 { in_line_eoln, 0 }, /* Rv */
110 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
111 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
112 { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
113 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
114 { in_line_eoln, 0 }, /* %A */
115 { in_line_eoln, 0 }, /* %B */
116 { in_line_eoln, 0 }, /* %D */
117 { in_line_eoln, 0 }, /* %I */
118 { in_line_eoln, 0 }, /* %J */
119 { in_line_eoln, 0 }, /* %N */
120 { in_line_eoln, 0 }, /* %O */
121 { in_line_eoln, 0 }, /* %P */
122 { in_line_eoln, 0 }, /* %R */
123 { in_line_eoln, 0 }, /* %T */
124 { in_line_eoln, 0 }, /* %V */
125 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */
126 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */
127 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */
128 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */
129 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */
130 { blk_full, MDOC_EXPLICIT }, /* Bf */
131 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */
132 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */
133 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */
134 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */
135 { in_line_eoln, 0 }, /* Db */
136 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */
137 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */
138 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */
139 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */
140 { blk_exp_close, MDOC_EXPLICIT }, /* Ef */
141 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */
142 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */
143 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */
144 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */
145 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* No */
146 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Ns */
147 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */
148 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */
149 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */
150 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */
151 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */
152 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */
153 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */
154 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */
155 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */
156 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */
157 { blk_exp_close, MDOC_EXPLICIT }, /* Re */
158 { blk_full, MDOC_EXPLICIT }, /* Rs */
159 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */
160 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */
161 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */
162 { in_line_eoln, 0 }, /* Sm */
163 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */
164 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */
165 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */
166 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */
167 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */
168 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */
169 { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */
170 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */
171 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */
172 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */
173 { blk_full, MDOC_EXPLICIT }, /* Bk */
174 { blk_exp_close, MDOC_EXPLICIT }, /* Ek */
175 { in_line_eoln, 0 }, /* Bt */
176 { in_line_eoln, 0 }, /* Hf */
177 { obsolete, 0 }, /* Fr */
178 { in_line_eoln, 0 }, /* Ud */
179 { in_line, 0 }, /* Lb */
180 { in_line_eoln, 0 }, /* Lp */
181 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */
182 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */
183 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */
184 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */
185 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */
186 { in_line_eoln, 0 }, /* %C */
187 { obsolete, 0 }, /* Es */
188 { obsolete, 0 }, /* En */
189 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
190 { in_line_eoln, 0 }, /* %Q */
191 { in_line_eoln, 0 }, /* br */
192 { in_line_eoln, 0 }, /* sp */
193 { in_line_eoln, 0 }, /* %U */
194 { phrase_ta, MDOC_CALLABLE | MDOC_PARSED }, /* Ta */
195 };
196
197 const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
198
199
200 /*
201 * This is called at the end of parsing. It must traverse up the tree,
202 * closing out open [implicit] scopes. Obviously, open explicit scopes
203 * are errors.
204 */
205 int
206 mdoc_macroend(struct mdoc *mdoc)
207 {
208 struct mdoc_node *n;
209
210 /* Scan for open explicit scopes. */
211
212 n = MDOC_VALID & mdoc->last->flags ?
213 mdoc->last->parent : mdoc->last;
214
215 for ( ; n; n = n->parent)
216 if (MDOC_BLOCK == n->type &&
217 MDOC_EXPLICIT & mdoc_macros[n->tok].flags)
218 mdoc_nmsg(mdoc, n, MANDOCERR_SCOPEEXIT);
219
220 /* Rewind to the first. */
221
222 return(rew_last(mdoc, mdoc->first));
223 }
224
225
226 /*
227 * Look up a macro from within a subsequent context.
228 */
229 static enum mdoct
230 lookup(enum mdoct from, const char *p)
231 {
232
233 if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
234 return(MDOC_MAX);
235 return(lookup_raw(p));
236 }
237
238
239 /*
240 * Lookup a macro following the initial line macro.
241 */
242 static enum mdoct
243 lookup_raw(const char *p)
244 {
245 enum mdoct res;
246
247 if (MDOC_MAX == (res = mdoc_hash_find(p)))
248 return(MDOC_MAX);
249 if (MDOC_CALLABLE & mdoc_macros[res].flags)
250 return(res);
251 return(MDOC_MAX);
252 }
253
254
255 static int
256 rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
257 {
258 struct mdoc_node *n, *np;
259
260 assert(to);
261 mdoc->next = MDOC_NEXT_SIBLING;
262
263 /* LINTED */
264 while (mdoc->last != to) {
265 /*
266 * Save the parent here, because we may delete the
267 * mdoc->last node in the post-validation phase and reset
268 * it to mdoc->last->parent, causing a step in the closing
269 * out to be lost.
270 */
271 np = mdoc->last->parent;
272 if ( ! mdoc_valid_post(mdoc))
273 return(0);
274 n = mdoc->last;
275 mdoc->last = np;
276 assert(mdoc->last);
277 mdoc->last->last = n;
278 }
279
280 return(mdoc_valid_post(mdoc));
281 }
282
283
284 /*
285 * For a block closing macro, return the corresponding opening one.
286 * Otherwise, return the macro itself.
287 */
288 static enum mdoct
289 rew_alt(enum mdoct tok)
290 {
291 switch (tok) {
292 case (MDOC_Ac):
293 return(MDOC_Ao);
294 case (MDOC_Bc):
295 return(MDOC_Bo);
296 case (MDOC_Brc):
297 return(MDOC_Bro);
298 case (MDOC_Dc):
299 return(MDOC_Do);
300 case (MDOC_Ec):
301 return(MDOC_Eo);
302 case (MDOC_Ed):
303 return(MDOC_Bd);
304 case (MDOC_Ef):
305 return(MDOC_Bf);
306 case (MDOC_Ek):
307 return(MDOC_Bk);
308 case (MDOC_El):
309 return(MDOC_Bl);
310 case (MDOC_Fc):
311 return(MDOC_Fo);
312 case (MDOC_Oc):
313 return(MDOC_Oo);
314 case (MDOC_Pc):
315 return(MDOC_Po);
316 case (MDOC_Qc):
317 return(MDOC_Qo);
318 case (MDOC_Re):
319 return(MDOC_Rs);
320 case (MDOC_Sc):
321 return(MDOC_So);
322 case (MDOC_Xc):
323 return(MDOC_Xo);
324 default:
325 return(tok);
326 }
327 /* NOTREACHED */
328 }
329
330
331 /*
332 * Rewinding to tok, how do we have to handle *p?
333 * REWIND_NONE: *p would delimit tok, but no tok scope is open
334 * inside *p, so there is no need to rewind anything at all.
335 * REWIND_THIS: *p matches tok, so rewind *p and nothing else.
336 * REWIND_MORE: *p is implicit, rewind it and keep searching for tok.
337 * REWIND_FORCE: *p is explicit, but tok is full, force rewinding *p.
338 * REWIND_LATER: *p is explicit and still open, postpone rewinding.
339 * REWIND_ERROR: No tok block is open at all.
340 */
341 static enum rew
342 rew_dohalt(enum mdoct tok, enum mdoc_type type,
343 const struct mdoc_node *p)
344 {
345
346 /*
347 * No matching token, no delimiting block, no broken block.
348 * This can happen when full implicit macros are called for
349 * the first time but try to rewind their previous
350 * instance anyway.
351 */
352 if (MDOC_ROOT == p->type)
353 return(MDOC_BLOCK == type &&
354 MDOC_EXPLICIT & mdoc_macros[tok].flags ?
355 REWIND_ERROR : REWIND_NONE);
356
357 /*
358 * When starting to rewind, skip plain text
359 * and nodes that have already been rewound.
360 */
361 if (MDOC_TEXT == p->type || MDOC_VALID & p->flags)
362 return(REWIND_MORE);
363
364 /*
365 * The easiest case: Found a matching token.
366 * This applies to both blocks and elements.
367 */
368 tok = rew_alt(tok);
369 if (tok == p->tok)
370 return(p->end ? REWIND_NONE :
371 type == p->type ? REWIND_THIS : REWIND_MORE);
372
373 /*
374 * While elements do require rewinding for themselves,
375 * they never affect rewinding of other nodes.
376 */
377 if (MDOC_ELEM == p->type)
378 return(REWIND_MORE);
379
380 /*
381 * Blocks delimited by our target token get REWIND_MORE.
382 * Blocks delimiting our target token get REWIND_NONE.
383 */
384 switch (tok) {
385 case (MDOC_Bl):
386 if (MDOC_It == p->tok)
387 return(REWIND_MORE);
388 break;
389 case (MDOC_It):
390 if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
391 return(REWIND_NONE);
392 break;
393 /*
394 * XXX Badly nested block handling still fails badly
395 * when one block is breaking two blocks of the same type.
396 * This is an incomplete and extremely ugly workaround,
397 * required to let the OpenBSD tree build.
398 */
399 case (MDOC_Oo):
400 if (MDOC_Op == p->tok)
401 return(REWIND_MORE);
402 break;
403 case (MDOC_Nm):
404 return(REWIND_NONE);
405 case (MDOC_Nd):
406 /* FALLTHROUGH */
407 case (MDOC_Ss):
408 if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
409 return(REWIND_NONE);
410 /* FALLTHROUGH */
411 case (MDOC_Sh):
412 if (MDOC_Nd == p->tok || MDOC_Ss == p->tok ||
413 MDOC_Sh == p->tok)
414 return(REWIND_MORE);
415 break;
416 default:
417 break;
418 }
419
420 /*
421 * Default block rewinding rules.
422 * In particular, always skip block end markers,
423 * and let all blocks rewind Nm children.
424 */
425 if (ENDBODY_NOT != p->end || MDOC_Nm == p->tok ||
426 (MDOC_BLOCK == p->type &&
427 ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)))
428 return(REWIND_MORE);
429
430 /*
431 * By default, closing out full blocks
432 * forces closing of broken explicit blocks,
433 * while closing out partial blocks
434 * allows delayed rewinding by default.
435 */
436 return (&blk_full == mdoc_macros[tok].fp ?
437 REWIND_FORCE : REWIND_LATER);
438 }
439
440
441 static int
442 rew_elem(struct mdoc *mdoc, enum mdoct tok)
443 {
444 struct mdoc_node *n;
445
446 n = mdoc->last;
447 if (MDOC_ELEM != n->type)
448 n = n->parent;
449 assert(MDOC_ELEM == n->type);
450 assert(tok == n->tok);
451
452 return(rew_last(mdoc, n));
453 }
454
455
456 /*
457 * We are trying to close a block identified by tok,
458 * but the child block *broken is still open.
459 * Thus, postpone closing the tok block
460 * until the rew_sub call closing *broken.
461 */
462 static int
463 make_pending(struct mdoc_node *broken, enum mdoct tok,
464 struct mdoc *mdoc, int line, int ppos)
465 {
466 struct mdoc_node *breaker;
467
468 /*
469 * Iterate backwards, searching for the block matching tok,
470 * that is, the block breaking the *broken block.
471 */
472 for (breaker = broken->parent; breaker; breaker = breaker->parent) {
473
474 /*
475 * If the *broken block had already been broken before
476 * and we encounter its breaker, make the tok block
477 * pending on the inner breaker.
478 * Graphically, "[A breaker=[B broken=[C->B B] tok=A] C]"
479 * becomes "[A broken=[B [C->B B] tok=A] C]"
480 * and finally "[A [B->A [C->B B] A] C]".
481 */
482 if (breaker == broken->pending) {
483 broken = breaker;
484 continue;
485 }
486
487 if (REWIND_THIS != rew_dohalt(tok, MDOC_BLOCK, breaker))
488 continue;
489 if (MDOC_BODY == broken->type)
490 broken = broken->parent;
491
492 /*
493 * Found the breaker.
494 * If another, outer breaker is already pending on
495 * the *broken block, we must not clobber the link
496 * to the outer breaker, but make it pending on the
497 * new, now inner breaker.
498 * Graphically, "[A breaker=[B broken=[C->A A] tok=B] C]"
499 * becomes "[A breaker=[B->A broken=[C A] tok=B] C]"
500 * and finally "[A [B->A [C->B A] B] C]".
501 */
502 if (broken->pending) {
503 struct mdoc_node *taker;
504
505 /*
506 * If the breaker had also been broken before,
507 * it cannot take on the outer breaker itself,
508 * but must hand it on to its own breakers.
509 * Graphically, this is the following situation:
510 * "[A [B breaker=[C->B B] broken=[D->A A] tok=C] D]"
511 * "[A taker=[B->A breaker=[C->B B] [D->C A] C] D]"
512 */
513 taker = breaker;
514 while (taker->pending)
515 taker = taker->pending;
516 taker->pending = broken->pending;
517 }
518 broken->pending = breaker;
519 mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos,
520 "%s breaks %s", mdoc_macronames[tok],
521 mdoc_macronames[broken->tok]);
522 return(1);
523 }
524
525 /*
526 * Found no matching block for tok.
527 * Are you trying to close a block that is not open?
528 */
529 return(0);
530 }
531
532
533 static int
534 rew_sub(enum mdoc_type t, struct mdoc *mdoc,
535 enum mdoct tok, int line, int ppos)
536 {
537 struct mdoc_node *n;
538
539 n = mdoc->last;
540 while (n) {
541 switch (rew_dohalt(tok, t, n)) {
542 case (REWIND_NONE):
543 return(1);
544 case (REWIND_THIS):
545 break;
546 case (REWIND_FORCE):
547 mandoc_vmsg(MANDOCERR_SCOPEBROKEN, mdoc->parse,
548 line, ppos, "%s breaks %s",
549 mdoc_macronames[tok],
550 mdoc_macronames[n->tok]);
551 /* FALLTHROUGH */
552 case (REWIND_MORE):
553 n = n->parent;
554 continue;
555 case (REWIND_LATER):
556 if (make_pending(n, tok, mdoc, line, ppos) ||
557 MDOC_BLOCK != t)
558 return(1);
559 /* FALLTHROUGH */
560 case (REWIND_ERROR):
561 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_NOSCOPE);
562 return(1);
563 }
564 break;
565 }
566
567 assert(n);
568 if ( ! rew_last(mdoc, n))
569 return(0);
570
571 /*
572 * The current block extends an enclosing block.
573 * Now that the current block ends, close the enclosing block, too.
574 */
575 while (NULL != (n = n->pending)) {
576 if ( ! rew_last(mdoc, n))
577 return(0);
578 if (MDOC_HEAD == n->type &&
579 ! mdoc_body_alloc(mdoc, n->line, n->pos, n->tok))
580 return(0);
581 }
582
583 return(1);
584 }
585
586 /*
587 * Allocate a word and check whether it's punctuation or not.
588 * Punctuation consists of those tokens found in mdoc_isdelim().
589 */
590 static int
591 dword(struct mdoc *mdoc, int line,
592 int col, const char *p, enum mdelim d)
593 {
594
595 if (DELIM_MAX == d)
596 d = mdoc_isdelim(p);
597
598 if ( ! mdoc_word_alloc(mdoc, line, col, p))
599 return(0);
600
601 if (DELIM_OPEN == d)
602 mdoc->last->flags |= MDOC_DELIMO;
603
604 /*
605 * Closing delimiters only suppress the preceding space
606 * when they follow something, not when they start a new
607 * block or element, and not when they follow `No'.
608 *
609 * XXX Explicitly special-casing MDOC_No here feels
610 * like a layering violation. Find a better way
611 * and solve this in the code related to `No'!
612 */
613
614 else if (DELIM_CLOSE == d && mdoc->last->prev &&
615 mdoc->last->prev->tok != MDOC_No &&
616 mdoc->last->parent->tok != MDOC_Fd)
617 mdoc->last->flags |= MDOC_DELIMC;
618
619 return(1);
620 }
621
622 static int
623 append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
624 {
625 int la;
626 enum margserr ac;
627 char *p;
628
629 if ('\0' == buf[*pos])
630 return(1);
631
632 for (;;) {
633 la = *pos;
634 ac = mdoc_zargs(mdoc, line, pos, buf, &p);
635
636 if (ARGS_ERROR == ac)
637 return(0);
638 else if (ARGS_EOLN == ac)
639 break;
640
641 dword(mdoc, line, la, p, DELIM_MAX);
642
643 /*
644 * If we encounter end-of-sentence symbols, then trigger
645 * the double-space.
646 *
647 * XXX: it's easy to allow this to propagate outward to
648 * the last symbol, such that `. )' will cause the
649 * correct double-spacing. However, (1) groff isn't
650 * smart enough to do this and (2) it would require
651 * knowing which symbols break this behaviour, for
652 * example, `. ;' shouldn't propagate the double-space.
653 */
654 if (mandoc_eos(p, strlen(p), 0))
655 mdoc->last->flags |= MDOC_EOS;
656 }
657
658 return(1);
659 }
660
661
662 /*
663 * Close out block partial/full explicit.
664 */
665 static int
666 blk_exp_close(MACRO_PROT_ARGS)
667 {
668 struct mdoc_node *body; /* Our own body. */
669 struct mdoc_node *later; /* A sub-block starting later. */
670 struct mdoc_node *n; /* For searching backwards. */
671
672 int j, lastarg, maxargs, flushed, nl;
673 enum margserr ac;
674 enum mdoct atok, ntok;
675 char *p;
676
677 nl = MDOC_NEWLINE & mdoc->flags;
678
679 switch (tok) {
680 case (MDOC_Ec):
681 maxargs = 1;
682 break;
683 default:
684 maxargs = 0;
685 break;
686 }
687
688 /*
689 * Search backwards for beginnings of blocks,
690 * both of our own and of pending sub-blocks.
691 */
692 atok = rew_alt(tok);
693 body = later = NULL;
694 for (n = mdoc->last; n; n = n->parent) {
695 if (MDOC_VALID & n->flags)
696 continue;
697
698 /* Remember the start of our own body. */
699 if (MDOC_BODY == n->type && atok == n->tok) {
700 if (ENDBODY_NOT == n->end)
701 body = n;
702 continue;
703 }
704
705 if (MDOC_BLOCK != n->type || MDOC_Nm == n->tok)
706 continue;
707 if (atok == n->tok) {
708 assert(body);
709
710 /*
711 * Found the start of our own block.
712 * When there is no pending sub block,
713 * just proceed to closing out.
714 */
715 if (NULL == later)
716 break;
717
718 /*
719 * When there is a pending sub block,
720 * postpone closing out the current block
721 * until the rew_sub() closing out the sub-block.
722 */
723 make_pending(later, tok, mdoc, line, ppos);
724
725 /*
726 * Mark the place where the formatting - but not
727 * the scope - of the current block ends.
728 */
729 if ( ! mdoc_endbody_alloc(mdoc, line, ppos,
730 atok, body, ENDBODY_SPACE))
731 return(0);
732 break;
733 }
734
735 /*
736 * When finding an open sub block, remember the last
737 * open explicit block, or, in case there are only
738 * implicit ones, the first open implicit block.
739 */
740 if (later &&
741 MDOC_EXPLICIT & mdoc_macros[later->tok].flags)
742 continue;
743 if (MDOC_It != n->tok)
744 later = n;
745 }
746
747 if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
748 /* FIXME: do this in validate */
749 if (buf[*pos])
750 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_ARGSLOST);
751
752 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
753 return(0);
754 return(rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos));
755 }
756
757 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
758 return(0);
759
760 if (NULL == later && maxargs > 0)
761 if ( ! mdoc_tail_alloc(mdoc, line, ppos, rew_alt(tok)))
762 return(0);
763
764 for (flushed = j = 0; ; j++) {
765 lastarg = *pos;
766
767 if (j == maxargs && ! flushed) {
768 if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
769 return(0);
770 flushed = 1;
771 }
772
773 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
774
775 if (ARGS_ERROR == ac)
776 return(0);
777 if (ARGS_PUNCT == ac)
778 break;
779 if (ARGS_EOLN == ac)
780 break;
781
782 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
783
784 if (MDOC_MAX == ntok) {
785 if ( ! dword(mdoc, line, lastarg, p, DELIM_MAX))
786 return(0);
787 continue;
788 }
789
790 if ( ! flushed) {
791 if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
792 return(0);
793 flushed = 1;
794 }
795
796 mdoc->flags &= ~MDOC_NEWLINE;
797
798 if ( ! mdoc_macro(mdoc, ntok, line, lastarg, pos, buf))
799 return(0);
800 break;
801 }
802
803 if ( ! flushed && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
804 return(0);
805
806 if ( ! nl)
807 return(1);
808 return(append_delims(mdoc, line, pos, buf));
809 }
810
811
812 static int
813 in_line(MACRO_PROT_ARGS)
814 {
815 int la, scope, cnt, nc, nl;
816 enum margverr av;
817 enum mdoct ntok;
818 enum margserr ac;
819 enum mdelim d;
820 struct mdoc_arg *arg;
821 char *p;
822
823 nl = MDOC_NEWLINE & mdoc->flags;
824
825 /*
826 * Whether we allow ignored elements (those without content,
827 * usually because of reserved words) to squeak by.
828 */
829
830 switch (tok) {
831 case (MDOC_An):
832 /* FALLTHROUGH */
833 case (MDOC_Ar):
834 /* FALLTHROUGH */
835 case (MDOC_Fl):
836 /* FALLTHROUGH */
837 case (MDOC_Mt):
838 /* FALLTHROUGH */
839 case (MDOC_Nm):
840 /* FALLTHROUGH */
841 case (MDOC_Pa):
842 nc = 1;
843 break;
844 default:
845 nc = 0;
846 break;
847 }
848
849 for (arg = NULL;; ) {
850 la = *pos;
851 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
852
853 if (ARGV_WORD == av) {
854 *pos = la;
855 break;
856 }
857 if (ARGV_EOLN == av)
858 break;
859 if (ARGV_ARG == av)
860 continue;
861
862 mdoc_argv_free(arg);
863 return(0);
864 }
865
866 for (cnt = scope = 0;; ) {
867 la = *pos;
868 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
869
870 if (ARGS_ERROR == ac)
871 return(0);
872 if (ARGS_EOLN == ac)
873 break;
874 if (ARGS_PUNCT == ac)
875 break;
876
877 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
878
879 /*
880 * In this case, we've located a submacro and must
881 * execute it. Close out scope, if open. If no
882 * elements have been generated, either create one (nc)
883 * or raise a warning.
884 */
885
886 if (MDOC_MAX != ntok) {
887 if (scope && ! rew_elem(mdoc, tok))
888 return(0);
889 if (nc && 0 == cnt) {
890 if ( ! mdoc_elem_alloc(mdoc, line,
891 ppos, tok, arg))
892 return(0);
893 if ( ! rew_last(mdoc, mdoc->last))
894 return(0);
895 } else if ( ! nc && 0 == cnt) {
896 mdoc_argv_free(arg);
897 mdoc_pmsg(mdoc, line, ppos,
898 MANDOCERR_MACROEMPTY);
899 }
900
901 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
902 return(0);
903 if ( ! nl)
904 return(1);
905 return(append_delims(mdoc, line, pos, buf));
906 }
907
908 /*
909 * Non-quote-enclosed punctuation. Set up our scope, if
910 * a word; rewind the scope, if a delimiter; then append
911 * the word.
912 */
913
914 d = ARGS_QWORD == ac ? DELIM_NONE : mdoc_isdelim(p);
915
916 if (DELIM_NONE != d) {
917 /*
918 * If we encounter closing punctuation, no word
919 * has been omitted, no scope is open, and we're
920 * allowed to have an empty element, then start
921 * a new scope. `Ar', `Fl', and `Li', only do
922 * this once per invocation. There may be more
923 * of these (all of them?).
924 */
925 if (0 == cnt && (nc || MDOC_Li == tok) &&
926 DELIM_CLOSE == d && ! scope) {
927 if ( ! mdoc_elem_alloc(mdoc, line,
928 ppos, tok, arg))
929 return(0);
930 if (MDOC_Ar == tok || MDOC_Li == tok ||
931 MDOC_Fl == tok)
932 cnt++;
933 scope = 1;
934 }
935 /*
936 * Close out our scope, if one is open, before
937 * any punctuation.
938 */
939 if (scope && ! rew_elem(mdoc, tok))
940 return(0);
941 scope = 0;
942 } else if ( ! scope) {
943 if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
944 return(0);
945 scope = 1;
946 }
947
948 if (DELIM_NONE == d)
949 cnt++;
950
951 if ( ! dword(mdoc, line, la, p, d))
952 return(0);
953
954 /*
955 * `Fl' macros have their scope re-opened with each new
956 * word so that the `-' can be added to each one without
957 * having to parse out spaces.
958 */
959 if (scope && MDOC_Fl == tok) {
960 if ( ! rew_elem(mdoc, tok))
961 return(0);
962 scope = 0;
963 }
964 }
965
966 if (scope && ! rew_elem(mdoc, tok))
967 return(0);
968
969 /*
970 * If no elements have been collected and we're allowed to have
971 * empties (nc), open a scope and close it out. Otherwise,
972 * raise a warning.
973 */
974
975 if (nc && 0 == cnt) {
976 if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
977 return(0);
978 if ( ! rew_last(mdoc, mdoc->last))
979 return(0);
980 } else if ( ! nc && 0 == cnt) {
981 mdoc_argv_free(arg);
982 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROEMPTY);
983 }
984
985 if ( ! nl)
986 return(1);
987 return(append_delims(mdoc, line, pos, buf));
988 }
989
990
991 static int
992 blk_full(MACRO_PROT_ARGS)
993 {
994 int la, nl, nparsed;
995 struct mdoc_arg *arg;
996 struct mdoc_node *head; /* save of head macro */
997 struct mdoc_node *body; /* save of body macro */
998 struct mdoc_node *n;
999 enum mdoc_type mtt;
1000 enum mdoct ntok;
1001 enum margserr ac, lac;
1002 enum margverr av;
1003 char *p;
1004
1005 nl = MDOC_NEWLINE & mdoc->flags;
1006
1007 /* Close out prior implicit scope. */
1008
1009 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
1010 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1011 return(0);
1012 if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
1013 return(0);
1014 }
1015
1016 /*
1017 * This routine accommodates implicitly- and explicitly-scoped
1018 * macro openings. Implicit ones first close out prior scope
1019 * (seen above). Delay opening the head until necessary to
1020 * allow leading punctuation to print. Special consideration
1021 * for `It -column', which has phrase-part syntax instead of
1022 * regular child nodes.
1023 */
1024
1025 for (arg = NULL;; ) {
1026 la = *pos;
1027 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1028
1029 if (ARGV_WORD == av) {
1030 *pos = la;
1031 break;
1032 }
1033
1034 if (ARGV_EOLN == av)
1035 break;
1036 if (ARGV_ARG == av)
1037 continue;
1038
1039 mdoc_argv_free(arg);
1040 return(0);
1041 }
1042
1043 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, arg))
1044 return(0);
1045
1046 head = body = NULL;
1047
1048 /*
1049 * Exception: Heads of `It' macros in `-diag' lists are not
1050 * parsed, even though `It' macros in general are parsed.
1051 */
1052 nparsed = MDOC_It == tok &&
1053 MDOC_Bl == mdoc->last->parent->tok &&
1054 LIST_diag == mdoc->last->parent->norm->Bl.type;
1055
1056 /*
1057 * The `Nd' macro has all arguments in its body: it's a hybrid
1058 * of block partial-explicit and full-implicit. Stupid.
1059 */
1060
1061 if (MDOC_Nd == tok) {
1062 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1063 return(0);
1064 head = mdoc->last;
1065 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1066 return(0);
1067 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1068 return(0);
1069 body = mdoc->last;
1070 }
1071
1072 ac = ARGS_ERROR;
1073
1074 for ( ; ; ) {
1075 la = *pos;
1076 /* Initialise last-phrase-type with ARGS_PEND. */
1077 lac = ARGS_ERROR == ac ? ARGS_PEND : ac;
1078 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1079
1080 if (ARGS_PUNCT == ac)
1081 break;
1082
1083 if (ARGS_ERROR == ac)
1084 return(0);
1085
1086 if (ARGS_EOLN == ac) {
1087 if (ARGS_PPHRASE != lac && ARGS_PHRASE != lac)
1088 break;
1089 /*
1090 * This is necessary: if the last token on a
1091 * line is a `Ta' or tab, then we'll get
1092 * ARGS_EOLN, so we must be smart enough to
1093 * reopen our scope if the last parse was a
1094 * phrase or partial phrase.
1095 */
1096 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1097 return(0);
1098 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1099 return(0);
1100 body = mdoc->last;
1101 break;
1102 }
1103
1104 /*
1105 * Emit leading punctuation (i.e., punctuation before
1106 * the MDOC_HEAD) for non-phrase types.
1107 */
1108
1109 if (NULL == head &&
1110 ARGS_PEND != ac &&
1111 ARGS_PHRASE != ac &&
1112 ARGS_PPHRASE != ac &&
1113 ARGS_QWORD != ac &&
1114 DELIM_OPEN == mdoc_isdelim(p)) {
1115 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1116 return(0);
1117 continue;
1118 }
1119
1120 /* Open a head if one hasn't been opened. */
1121
1122 if (NULL == head) {
1123 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1124 return(0);
1125 head = mdoc->last;
1126 }
1127
1128 if (ARGS_PHRASE == ac ||
1129 ARGS_PEND == ac ||
1130 ARGS_PPHRASE == ac) {
1131 /*
1132 * If we haven't opened a body yet, rewind the
1133 * head; if we have, rewind that instead.
1134 */
1135
1136 mtt = body ? MDOC_BODY : MDOC_HEAD;
1137 if ( ! rew_sub(mtt, mdoc, tok, line, ppos))
1138 return(0);
1139
1140 /* Then allocate our body context. */
1141
1142 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1143 return(0);
1144 body = mdoc->last;
1145
1146 /*
1147 * Process phrases: set whether we're in a
1148 * partial-phrase (this effects line handling)
1149 * then call down into the phrase parser.
1150 */
1151
1152 if (ARGS_PPHRASE == ac)
1153 mdoc->flags |= MDOC_PPHRASE;
1154 if (ARGS_PEND == ac && ARGS_PPHRASE == lac)
1155 mdoc->flags |= MDOC_PPHRASE;
1156
1157 if ( ! phrase(mdoc, line, la, buf))
1158 return(0);
1159
1160 mdoc->flags &= ~MDOC_PPHRASE;
1161 continue;
1162 }
1163
1164 ntok = nparsed || ARGS_QWORD == ac ?
1165 MDOC_MAX : lookup(tok, p);
1166
1167 if (MDOC_MAX == ntok) {
1168 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1169 return(0);
1170 continue;
1171 }
1172
1173 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1174 return(0);
1175 break;
1176 }
1177
1178 if (NULL == head) {
1179 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1180 return(0);
1181 head = mdoc->last;
1182 }
1183
1184 if (nl && ! append_delims(mdoc, line, pos, buf))
1185 return(0);
1186
1187 /* If we've already opened our body, exit now. */
1188
1189 if (NULL != body)
1190 goto out;
1191
1192 /*
1193 * If there is an open (i.e., unvalidated) sub-block requiring
1194 * explicit close-out, postpone switching the current block from
1195 * head to body until the rew_sub() call closing out that
1196 * sub-block.
1197 */
1198 for (n = mdoc->last; n && n != head; n = n->parent) {
1199 if (MDOC_BLOCK == n->type &&
1200 MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
1201 ! (MDOC_VALID & n->flags)) {
1202 n->pending = head;
1203 return(1);
1204 }
1205 }
1206
1207 /* Close out scopes to remain in a consistent state. */
1208
1209 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1210 return(0);
1211 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1212 return(0);
1213
1214 out:
1215 if ( ! (MDOC_FREECOL & mdoc->flags))
1216 return(1);
1217
1218 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1219 return(0);
1220 if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
1221 return(0);
1222
1223 mdoc->flags &= ~MDOC_FREECOL;
1224 return(1);
1225 }
1226
1227
1228 static int
1229 blk_part_imp(MACRO_PROT_ARGS)
1230 {
1231 int la, nl;
1232 enum mdoct ntok;
1233 enum margserr ac;
1234 char *p;
1235 struct mdoc_node *blk; /* saved block context */
1236 struct mdoc_node *body; /* saved body context */
1237 struct mdoc_node *n;
1238
1239 nl = MDOC_NEWLINE & mdoc->flags;
1240
1241 /*
1242 * A macro that spans to the end of the line. This is generally
1243 * (but not necessarily) called as the first macro. The block
1244 * has a head as the immediate child, which is always empty,
1245 * followed by zero or more opening punctuation nodes, then the
1246 * body (which may be empty, depending on the macro), then zero
1247 * or more closing punctuation nodes.
1248 */
1249
1250 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL))
1251 return(0);
1252
1253 blk = mdoc->last;
1254
1255 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1256 return(0);
1257 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1258 return(0);
1259
1260 /*
1261 * Open the body scope "on-demand", that is, after we've
1262 * processed all our the leading delimiters (open parenthesis,
1263 * etc.).
1264 */
1265
1266 for (body = NULL; ; ) {
1267 la = *pos;
1268 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1269
1270 if (ARGS_ERROR == ac)
1271 return(0);
1272 if (ARGS_EOLN == ac)
1273 break;
1274 if (ARGS_PUNCT == ac)
1275 break;
1276
1277 if (NULL == body && ARGS_QWORD != ac &&
1278 DELIM_OPEN == mdoc_isdelim(p)) {
1279 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1280 return(0);
1281 continue;
1282 }
1283
1284 if (NULL == body) {
1285 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1286 return(0);
1287 body = mdoc->last;
1288 }
1289
1290 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1291
1292 if (MDOC_MAX == ntok) {
1293 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1294 return(0);
1295 continue;
1296 }
1297
1298 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1299 return(0);
1300 break;
1301 }
1302
1303 /* Clean-ups to leave in a consistent state. */
1304
1305 if (NULL == body) {
1306 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1307 return(0);
1308 body = mdoc->last;
1309 }
1310
1311 for (n = body->child; n && n->next; n = n->next)
1312 /* Do nothing. */ ;
1313
1314 /*
1315 * End of sentence spacing: if the last node is a text node and
1316 * has a trailing period, then mark it as being end-of-sentence.
1317 */
1318
1319 if (n && MDOC_TEXT == n->type && n->string)
1320 if (mandoc_eos(n->string, strlen(n->string), 1))
1321 n->flags |= MDOC_EOS;
1322
1323 /* Up-propagate the end-of-space flag. */
1324
1325 if (n && (MDOC_EOS & n->flags)) {
1326 body->flags |= MDOC_EOS;
1327 body->parent->flags |= MDOC_EOS;
1328 }
1329
1330 /*
1331 * If there is an open sub-block requiring explicit close-out,
1332 * postpone closing out the current block
1333 * until the rew_sub() call closing out the sub-block.
1334 */
1335 for (n = mdoc->last; n && n != body && n != blk->parent;
1336 n = n->parent) {
1337 if (MDOC_BLOCK == n->type &&
1338 MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
1339 ! (MDOC_VALID & n->flags)) {
1340 make_pending(n, tok, mdoc, line, ppos);
1341 if ( ! mdoc_endbody_alloc(mdoc, line, ppos,
1342 tok, body, ENDBODY_NOSPACE))
1343 return(0);
1344 return(1);
1345 }
1346 }
1347
1348 /*
1349 * If we can't rewind to our body, then our scope has already
1350 * been closed by another macro (like `Oc' closing `Op'). This
1351 * is ugly behaviour nodding its head to OpenBSD's overwhelming
1352 * crufty use of `Op' breakage.
1353 */
1354 if (n != body)
1355 mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos,
1356 "%s broken", mdoc_macronames[tok]);
1357
1358 if (n && ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1359 return(0);
1360
1361 /* Standard appending of delimiters. */
1362
1363 if (nl && ! append_delims(mdoc, line, pos, buf))
1364 return(0);
1365
1366 /* Rewind scope, if applicable. */
1367
1368 if (n && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
1369 return(0);
1370
1371 /* Move trailing .Ns out of scope. */
1372
1373 for (n = body->child; n && n->next; n = n->next)
1374 /* Do nothing. */ ;
1375 if (n && MDOC_Ns == n->tok)
1376 mdoc_node_relink(mdoc, n);
1377
1378 return(1);
1379 }
1380
1381
1382 static int
1383 blk_part_exp(MACRO_PROT_ARGS)
1384 {
1385 int la, nl;
1386 enum margserr ac;
1387 struct mdoc_node *head; /* keep track of head */
1388 struct mdoc_node *body; /* keep track of body */
1389 char *p;
1390 enum mdoct ntok;
1391
1392 nl = MDOC_NEWLINE & mdoc->flags;
1393
1394 /*
1395 * The opening of an explicit macro having zero or more leading
1396 * punctuation nodes; a head with optional single element (the
1397 * case of `Eo'); and a body that may be empty.
1398 */
1399
1400 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL))
1401 return(0);
1402
1403 for (head = body = NULL; ; ) {
1404 la = *pos;
1405 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1406
1407 if (ARGS_ERROR == ac)
1408 return(0);
1409 if (ARGS_PUNCT == ac)
1410 break;
1411 if (ARGS_EOLN == ac)
1412 break;
1413
1414 /* Flush out leading punctuation. */
1415
1416 if (NULL == head && ARGS_QWORD != ac &&
1417 DELIM_OPEN == mdoc_isdelim(p)) {
1418 assert(NULL == body);
1419 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1420 return(0);
1421 continue;
1422 }
1423
1424 if (NULL == head) {
1425 assert(NULL == body);
1426 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1427 return(0);
1428 head = mdoc->last;
1429 }
1430
1431 /*
1432 * `Eo' gobbles any data into the head, but most other
1433 * macros just immediately close out and begin the body.
1434 */
1435
1436 if (NULL == body) {
1437 assert(head);
1438 /* No check whether it's a macro! */
1439 if (MDOC_Eo == tok)
1440 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1441 return(0);
1442
1443 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1444 return(0);
1445 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1446 return(0);
1447 body = mdoc->last;
1448
1449 if (MDOC_Eo == tok)
1450 continue;
1451 }
1452
1453 assert(NULL != head && NULL != body);
1454
1455 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1456
1457 if (MDOC_MAX == ntok) {
1458 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1459 return(0);
1460 continue;
1461 }
1462
1463 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1464 return(0);
1465 break;
1466 }
1467
1468 /* Clean-up to leave in a consistent state. */
1469
1470 if (NULL == head)
1471 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1472 return(0);
1473
1474 if (NULL == body) {
1475 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1476 return(0);
1477 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1478 return(0);
1479 }
1480
1481 /* Standard appending of delimiters. */
1482
1483 if ( ! nl)
1484 return(1);
1485 return(append_delims(mdoc, line, pos, buf));
1486 }
1487
1488
1489 /* ARGSUSED */
1490 static int
1491 in_line_argn(MACRO_PROT_ARGS)
1492 {
1493 int la, flushed, j, maxargs, nl;
1494 enum margserr ac;
1495 enum margverr av;
1496 struct mdoc_arg *arg;
1497 char *p;
1498 enum mdoct ntok;
1499
1500 nl = MDOC_NEWLINE & mdoc->flags;
1501
1502 /*
1503 * A line macro that has a fixed number of arguments (maxargs).
1504 * Only open the scope once the first non-leading-punctuation is
1505 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then
1506 * keep it open until the maximum number of arguments are
1507 * exhausted.
1508 */
1509
1510 switch (tok) {
1511 case (MDOC_Ap):
1512 /* FALLTHROUGH */
1513 case (MDOC_No):
1514 /* FALLTHROUGH */
1515 case (MDOC_Ns):
1516 /* FALLTHROUGH */
1517 case (MDOC_Ux):
1518 maxargs = 0;
1519 break;
1520 case (MDOC_Bx):
1521 /* FALLTHROUGH */
1522 case (MDOC_Xr):
1523 maxargs = 2;
1524 break;
1525 default:
1526 maxargs = 1;
1527 break;
1528 }
1529
1530 for (arg = NULL; ; ) {
1531 la = *pos;
1532 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1533
1534 if (ARGV_WORD == av) {
1535 *pos = la;
1536 break;
1537 }
1538
1539 if (ARGV_EOLN == av)
1540 break;
1541 if (ARGV_ARG == av)
1542 continue;
1543
1544 mdoc_argv_free(arg);
1545 return(0);
1546 }
1547
1548 for (flushed = j = 0; ; ) {
1549 la = *pos;
1550 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1551
1552 if (ARGS_ERROR == ac)
1553 return(0);
1554 if (ARGS_PUNCT == ac)
1555 break;
1556 if (ARGS_EOLN == ac)
1557 break;
1558
1559 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1560 ARGS_QWORD != ac && 0 == j &&
1561 DELIM_OPEN == mdoc_isdelim(p)) {
1562 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1563 return(0);
1564 continue;
1565 } else if (0 == j)
1566 if ( ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
1567 return(0);
1568
1569 if (j == maxargs && ! flushed) {
1570 if ( ! rew_elem(mdoc, tok))
1571 return(0);
1572 flushed = 1;
1573 }
1574
1575 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1576
1577 if (MDOC_MAX != ntok) {
1578 if ( ! flushed && ! rew_elem(mdoc, tok))
1579 return(0);
1580 flushed = 1;
1581 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1582 return(0);
1583 j++;
1584 break;
1585 }
1586
1587 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1588 ARGS_QWORD != ac &&
1589 ! flushed &&
1590 DELIM_NONE != mdoc_isdelim(p)) {
1591 if ( ! rew_elem(mdoc, tok))
1592 return(0);
1593 flushed = 1;
1594 }
1595
1596 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1597 return(0);
1598 j++;
1599 }
1600
1601 if (0 == j && ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
1602 return(0);
1603
1604 /* Close out in a consistent state. */
1605
1606 if ( ! flushed && ! rew_elem(mdoc, tok))
1607 return(0);
1608 if ( ! nl)
1609 return(1);
1610 return(append_delims(mdoc, line, pos, buf));
1611 }
1612
1613
1614 static int
1615 in_line_eoln(MACRO_PROT_ARGS)
1616 {
1617 int la;
1618 enum margserr ac;
1619 enum margverr av;
1620 struct mdoc_arg *arg;
1621 char *p;
1622 enum mdoct ntok;
1623
1624 assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));
1625
1626 if (tok == MDOC_Pp)
1627 rew_sub(MDOC_BLOCK, mdoc, MDOC_Nm, line, ppos);
1628
1629 /* Parse macro arguments. */
1630
1631 for (arg = NULL; ; ) {
1632 la = *pos;
1633 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1634
1635 if (ARGV_WORD == av) {
1636 *pos = la;
1637 break;
1638 }
1639 if (ARGV_EOLN == av)
1640 break;
1641 if (ARGV_ARG == av)
1642 continue;
1643
1644 mdoc_argv_free(arg);
1645 return(0);
1646 }
1647
1648 /* Open element scope. */
1649
1650 if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
1651 return(0);
1652
1653 /* Parse argument terms. */
1654
1655 for (;;) {
1656 la = *pos;
1657 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1658
1659 if (ARGS_ERROR == ac)
1660 return(0);
1661 if (ARGS_EOLN == ac)
1662 break;
1663
1664 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1665
1666 if (MDOC_MAX == ntok) {
1667 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1668 return(0);
1669 continue;
1670 }
1671
1672 if ( ! rew_elem(mdoc, tok))
1673 return(0);
1674 return(mdoc_macro(mdoc, ntok, line, la, pos, buf));
1675 }
1676
1677 /* Close out (no delimiters). */
1678
1679 return(rew_elem(mdoc, tok));
1680 }
1681
1682
1683 /* ARGSUSED */
1684 static int
1685 ctx_synopsis(MACRO_PROT_ARGS)
1686 {
1687 int nl;
1688
1689 nl = MDOC_NEWLINE & mdoc->flags;
1690
1691 /* If we're not in the SYNOPSIS, go straight to in-line. */
1692 if ( ! (MDOC_SYNOPSIS & mdoc->flags))
1693 return(in_line(mdoc, tok, line, ppos, pos, buf));
1694
1695 /* If we're a nested call, same place. */
1696 if ( ! nl)
1697 return(in_line(mdoc, tok, line, ppos, pos, buf));
1698
1699 /*
1700 * XXX: this will open a block scope; however, if later we end
1701 * up formatting the block scope, then child nodes will inherit
1702 * the formatting. Be careful.
1703 */
1704 if (MDOC_Nm == tok)
1705 return(blk_full(mdoc, tok, line, ppos, pos, buf));
1706 assert(MDOC_Vt == tok);
1707 return(blk_part_imp(mdoc, tok, line, ppos, pos, buf));
1708 }
1709
1710
1711 /* ARGSUSED */
1712 static int
1713 obsolete(MACRO_PROT_ARGS)
1714 {
1715
1716 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROOBS);
1717 return(1);
1718 }
1719
1720
1721 /*
1722 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1723 * They're unusual because they're basically free-form text until a
1724 * macro is encountered.
1725 */
1726 static int
1727 phrase(struct mdoc *mdoc, int line, int ppos, char *buf)
1728 {
1729 int la, pos;
1730 enum margserr ac;
1731 enum mdoct ntok;
1732 char *p;
1733
1734 for (pos = ppos; ; ) {
1735 la = pos;
1736
1737 ac = mdoc_zargs(mdoc, line, &pos, buf, &p);
1738
1739 if (ARGS_ERROR == ac)
1740 return(0);
1741 if (ARGS_EOLN == ac)
1742 break;
1743
1744 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p);
1745
1746 if (MDOC_MAX == ntok) {
1747 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1748 return(0);
1749 continue;
1750 }
1751
1752 if ( ! mdoc_macro(mdoc, ntok, line, la, &pos, buf))
1753 return(0);
1754 return(append_delims(mdoc, line, &pos, buf));
1755 }
1756
1757 return(1);
1758 }
1759
1760
1761 /* ARGSUSED */
1762 static int
1763 phrase_ta(MACRO_PROT_ARGS)
1764 {
1765 struct mdoc_node *n;
1766 int la;
1767 enum mdoct ntok;
1768 enum margserr ac;
1769 char *p;
1770
1771 /* Make sure we are in a column list or ignore this macro. */
1772 n = mdoc->last;
1773 while (NULL != n && MDOC_Bl != n->tok)
1774 n = n->parent;
1775 if (NULL == n || LIST_column != n->norm->Bl.type) {
1776 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_STRAYTA);
1777 return(1);
1778 }
1779
1780 /* Advance to the next column. */
1781 if ( ! rew_sub(MDOC_BODY, mdoc, MDOC_It, line, ppos))
1782 return(0);
1783 if ( ! mdoc_body_alloc(mdoc, line, ppos, MDOC_It))
1784 return(0);
1785
1786 for (;;) {
1787 la = *pos;
1788 ac = mdoc_zargs(mdoc, line, pos, buf, &p);
1789
1790 if (ARGS_ERROR == ac)
1791 return(0);
1792 if (ARGS_EOLN == ac)
1793 break;
1794
1795 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p);
1796
1797 if (MDOC_MAX == ntok) {
1798 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1799 return(0);
1800 continue;
1801 }
1802
1803 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1804 return(0);
1805 return(append_delims(mdoc, line, pos, buf));
1806 }
1807
1808 return(1);
1809 }