]> git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
In -Tman mode, support automatic word keeps in the SYNOPSIS
[mandoc.git] / mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.120 2012/11/18 00:05:35 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 if ( ! mdoc_macro(mdoc, ntok, line, lastarg, pos, buf))
796 return(0);
797 break;
798 }
799
800 if ( ! flushed && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
801 return(0);
802
803 if ( ! nl)
804 return(1);
805 return(append_delims(mdoc, line, pos, buf));
806 }
807
808
809 static int
810 in_line(MACRO_PROT_ARGS)
811 {
812 int la, scope, cnt, nc, nl;
813 enum margverr av;
814 enum mdoct ntok;
815 enum margserr ac;
816 enum mdelim d;
817 struct mdoc_arg *arg;
818 char *p;
819
820 nl = MDOC_NEWLINE & mdoc->flags;
821
822 /*
823 * Whether we allow ignored elements (those without content,
824 * usually because of reserved words) to squeak by.
825 */
826
827 switch (tok) {
828 case (MDOC_An):
829 /* FALLTHROUGH */
830 case (MDOC_Ar):
831 /* FALLTHROUGH */
832 case (MDOC_Fl):
833 /* FALLTHROUGH */
834 case (MDOC_Mt):
835 /* FALLTHROUGH */
836 case (MDOC_Nm):
837 /* FALLTHROUGH */
838 case (MDOC_Pa):
839 nc = 1;
840 break;
841 default:
842 nc = 0;
843 break;
844 }
845
846 for (arg = NULL;; ) {
847 la = *pos;
848 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
849
850 if (ARGV_WORD == av) {
851 *pos = la;
852 break;
853 }
854 if (ARGV_EOLN == av)
855 break;
856 if (ARGV_ARG == av)
857 continue;
858
859 mdoc_argv_free(arg);
860 return(0);
861 }
862
863 for (cnt = scope = 0;; ) {
864 la = *pos;
865 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
866
867 if (ARGS_ERROR == ac)
868 return(0);
869 if (ARGS_EOLN == ac)
870 break;
871 if (ARGS_PUNCT == ac)
872 break;
873
874 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
875
876 /*
877 * In this case, we've located a submacro and must
878 * execute it. Close out scope, if open. If no
879 * elements have been generated, either create one (nc)
880 * or raise a warning.
881 */
882
883 if (MDOC_MAX != ntok) {
884 if (scope && ! rew_elem(mdoc, tok))
885 return(0);
886 if (nc && 0 == cnt) {
887 if ( ! mdoc_elem_alloc(mdoc, line,
888 ppos, tok, arg))
889 return(0);
890 if ( ! rew_last(mdoc, mdoc->last))
891 return(0);
892 } else if ( ! nc && 0 == cnt) {
893 mdoc_argv_free(arg);
894 mdoc_pmsg(mdoc, line, ppos,
895 MANDOCERR_MACROEMPTY);
896 }
897
898 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
899 return(0);
900 if ( ! nl)
901 return(1);
902 return(append_delims(mdoc, line, pos, buf));
903 }
904
905 /*
906 * Non-quote-enclosed punctuation. Set up our scope, if
907 * a word; rewind the scope, if a delimiter; then append
908 * the word.
909 */
910
911 d = ARGS_QWORD == ac ? DELIM_NONE : mdoc_isdelim(p);
912
913 if (DELIM_NONE != d) {
914 /*
915 * If we encounter closing punctuation, no word
916 * has been omitted, no scope is open, and we're
917 * allowed to have an empty element, then start
918 * a new scope. `Ar', `Fl', and `Li', only do
919 * this once per invocation. There may be more
920 * of these (all of them?).
921 */
922 if (0 == cnt && (nc || MDOC_Li == tok) &&
923 DELIM_CLOSE == d && ! scope) {
924 if ( ! mdoc_elem_alloc(mdoc, line,
925 ppos, tok, arg))
926 return(0);
927 if (MDOC_Ar == tok || MDOC_Li == tok ||
928 MDOC_Fl == tok)
929 cnt++;
930 scope = 1;
931 }
932 /*
933 * Close out our scope, if one is open, before
934 * any punctuation.
935 */
936 if (scope && ! rew_elem(mdoc, tok))
937 return(0);
938 scope = 0;
939 } else if ( ! scope) {
940 if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
941 return(0);
942 scope = 1;
943 }
944
945 if (DELIM_NONE == d)
946 cnt++;
947
948 if ( ! dword(mdoc, line, la, p, d))
949 return(0);
950
951 /*
952 * `Fl' macros have their scope re-opened with each new
953 * word so that the `-' can be added to each one without
954 * having to parse out spaces.
955 */
956 if (scope && MDOC_Fl == tok) {
957 if ( ! rew_elem(mdoc, tok))
958 return(0);
959 scope = 0;
960 }
961 }
962
963 if (scope && ! rew_elem(mdoc, tok))
964 return(0);
965
966 /*
967 * If no elements have been collected and we're allowed to have
968 * empties (nc), open a scope and close it out. Otherwise,
969 * raise a warning.
970 */
971
972 if (nc && 0 == cnt) {
973 if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
974 return(0);
975 if ( ! rew_last(mdoc, mdoc->last))
976 return(0);
977 } else if ( ! nc && 0 == cnt) {
978 mdoc_argv_free(arg);
979 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROEMPTY);
980 }
981
982 if ( ! nl)
983 return(1);
984 return(append_delims(mdoc, line, pos, buf));
985 }
986
987
988 static int
989 blk_full(MACRO_PROT_ARGS)
990 {
991 int la, nl, nparsed;
992 struct mdoc_arg *arg;
993 struct mdoc_node *head; /* save of head macro */
994 struct mdoc_node *body; /* save of body macro */
995 struct mdoc_node *n;
996 enum mdoc_type mtt;
997 enum mdoct ntok;
998 enum margserr ac, lac;
999 enum margverr av;
1000 char *p;
1001
1002 nl = MDOC_NEWLINE & mdoc->flags;
1003
1004 /* Close out prior implicit scope. */
1005
1006 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
1007 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1008 return(0);
1009 if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
1010 return(0);
1011 }
1012
1013 /*
1014 * This routine accommodates implicitly- and explicitly-scoped
1015 * macro openings. Implicit ones first close out prior scope
1016 * (seen above). Delay opening the head until necessary to
1017 * allow leading punctuation to print. Special consideration
1018 * for `It -column', which has phrase-part syntax instead of
1019 * regular child nodes.
1020 */
1021
1022 for (arg = NULL;; ) {
1023 la = *pos;
1024 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1025
1026 if (ARGV_WORD == av) {
1027 *pos = la;
1028 break;
1029 }
1030
1031 if (ARGV_EOLN == av)
1032 break;
1033 if (ARGV_ARG == av)
1034 continue;
1035
1036 mdoc_argv_free(arg);
1037 return(0);
1038 }
1039
1040 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, arg))
1041 return(0);
1042
1043 head = body = NULL;
1044
1045 /*
1046 * Exception: Heads of `It' macros in `-diag' lists are not
1047 * parsed, even though `It' macros in general are parsed.
1048 */
1049 nparsed = MDOC_It == tok &&
1050 MDOC_Bl == mdoc->last->parent->tok &&
1051 LIST_diag == mdoc->last->parent->norm->Bl.type;
1052
1053 /*
1054 * The `Nd' macro has all arguments in its body: it's a hybrid
1055 * of block partial-explicit and full-implicit. Stupid.
1056 */
1057
1058 if (MDOC_Nd == tok) {
1059 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1060 return(0);
1061 head = mdoc->last;
1062 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1063 return(0);
1064 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1065 return(0);
1066 body = mdoc->last;
1067 }
1068
1069 ac = ARGS_ERROR;
1070
1071 for ( ; ; ) {
1072 la = *pos;
1073 /* Initialise last-phrase-type with ARGS_PEND. */
1074 lac = ARGS_ERROR == ac ? ARGS_PEND : ac;
1075 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1076
1077 if (ARGS_PUNCT == ac)
1078 break;
1079
1080 if (ARGS_ERROR == ac)
1081 return(0);
1082
1083 if (ARGS_EOLN == ac) {
1084 if (ARGS_PPHRASE != lac && ARGS_PHRASE != lac)
1085 break;
1086 /*
1087 * This is necessary: if the last token on a
1088 * line is a `Ta' or tab, then we'll get
1089 * ARGS_EOLN, so we must be smart enough to
1090 * reopen our scope if the last parse was a
1091 * phrase or partial phrase.
1092 */
1093 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1094 return(0);
1095 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1096 return(0);
1097 body = mdoc->last;
1098 break;
1099 }
1100
1101 /*
1102 * Emit leading punctuation (i.e., punctuation before
1103 * the MDOC_HEAD) for non-phrase types.
1104 */
1105
1106 if (NULL == head &&
1107 ARGS_PEND != ac &&
1108 ARGS_PHRASE != ac &&
1109 ARGS_PPHRASE != ac &&
1110 ARGS_QWORD != ac &&
1111 DELIM_OPEN == mdoc_isdelim(p)) {
1112 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1113 return(0);
1114 continue;
1115 }
1116
1117 /* Open a head if one hasn't been opened. */
1118
1119 if (NULL == head) {
1120 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1121 return(0);
1122 head = mdoc->last;
1123 }
1124
1125 if (ARGS_PHRASE == ac ||
1126 ARGS_PEND == ac ||
1127 ARGS_PPHRASE == ac) {
1128 /*
1129 * If we haven't opened a body yet, rewind the
1130 * head; if we have, rewind that instead.
1131 */
1132
1133 mtt = body ? MDOC_BODY : MDOC_HEAD;
1134 if ( ! rew_sub(mtt, mdoc, tok, line, ppos))
1135 return(0);
1136
1137 /* Then allocate our body context. */
1138
1139 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1140 return(0);
1141 body = mdoc->last;
1142
1143 /*
1144 * Process phrases: set whether we're in a
1145 * partial-phrase (this effects line handling)
1146 * then call down into the phrase parser.
1147 */
1148
1149 if (ARGS_PPHRASE == ac)
1150 mdoc->flags |= MDOC_PPHRASE;
1151 if (ARGS_PEND == ac && ARGS_PPHRASE == lac)
1152 mdoc->flags |= MDOC_PPHRASE;
1153
1154 if ( ! phrase(mdoc, line, la, buf))
1155 return(0);
1156
1157 mdoc->flags &= ~MDOC_PPHRASE;
1158 continue;
1159 }
1160
1161 ntok = nparsed || ARGS_QWORD == ac ?
1162 MDOC_MAX : lookup(tok, p);
1163
1164 if (MDOC_MAX == ntok) {
1165 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1166 return(0);
1167 continue;
1168 }
1169
1170 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1171 return(0);
1172 break;
1173 }
1174
1175 if (NULL == head) {
1176 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1177 return(0);
1178 head = mdoc->last;
1179 }
1180
1181 if (nl && ! append_delims(mdoc, line, pos, buf))
1182 return(0);
1183
1184 /* If we've already opened our body, exit now. */
1185
1186 if (NULL != body)
1187 goto out;
1188
1189 /*
1190 * If there is an open (i.e., unvalidated) sub-block requiring
1191 * explicit close-out, postpone switching the current block from
1192 * head to body until the rew_sub() call closing out that
1193 * sub-block.
1194 */
1195 for (n = mdoc->last; n && n != head; n = n->parent) {
1196 if (MDOC_BLOCK == n->type &&
1197 MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
1198 ! (MDOC_VALID & n->flags)) {
1199 n->pending = head;
1200 return(1);
1201 }
1202 }
1203
1204 /* Close out scopes to remain in a consistent state. */
1205
1206 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1207 return(0);
1208 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1209 return(0);
1210
1211 out:
1212 if ( ! (MDOC_FREECOL & mdoc->flags))
1213 return(1);
1214
1215 if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1216 return(0);
1217 if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
1218 return(0);
1219
1220 mdoc->flags &= ~MDOC_FREECOL;
1221 return(1);
1222 }
1223
1224
1225 static int
1226 blk_part_imp(MACRO_PROT_ARGS)
1227 {
1228 int la, nl;
1229 enum mdoct ntok;
1230 enum margserr ac;
1231 char *p;
1232 struct mdoc_node *blk; /* saved block context */
1233 struct mdoc_node *body; /* saved body context */
1234 struct mdoc_node *n;
1235
1236 nl = MDOC_NEWLINE & mdoc->flags;
1237
1238 /*
1239 * A macro that spans to the end of the line. This is generally
1240 * (but not necessarily) called as the first macro. The block
1241 * has a head as the immediate child, which is always empty,
1242 * followed by zero or more opening punctuation nodes, then the
1243 * body (which may be empty, depending on the macro), then zero
1244 * or more closing punctuation nodes.
1245 */
1246
1247 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL))
1248 return(0);
1249
1250 blk = mdoc->last;
1251
1252 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1253 return(0);
1254 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1255 return(0);
1256
1257 /*
1258 * Open the body scope "on-demand", that is, after we've
1259 * processed all our the leading delimiters (open parenthesis,
1260 * etc.).
1261 */
1262
1263 for (body = NULL; ; ) {
1264 la = *pos;
1265 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1266
1267 if (ARGS_ERROR == ac)
1268 return(0);
1269 if (ARGS_EOLN == ac)
1270 break;
1271 if (ARGS_PUNCT == ac)
1272 break;
1273
1274 if (NULL == body && ARGS_QWORD != ac &&
1275 DELIM_OPEN == mdoc_isdelim(p)) {
1276 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1277 return(0);
1278 continue;
1279 }
1280
1281 if (NULL == body) {
1282 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1283 return(0);
1284 body = mdoc->last;
1285 }
1286
1287 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1288
1289 if (MDOC_MAX == ntok) {
1290 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1291 return(0);
1292 continue;
1293 }
1294
1295 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1296 return(0);
1297 break;
1298 }
1299
1300 /* Clean-ups to leave in a consistent state. */
1301
1302 if (NULL == body) {
1303 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1304 return(0);
1305 body = mdoc->last;
1306 }
1307
1308 for (n = body->child; n && n->next; n = n->next)
1309 /* Do nothing. */ ;
1310
1311 /*
1312 * End of sentence spacing: if the last node is a text node and
1313 * has a trailing period, then mark it as being end-of-sentence.
1314 */
1315
1316 if (n && MDOC_TEXT == n->type && n->string)
1317 if (mandoc_eos(n->string, strlen(n->string), 1))
1318 n->flags |= MDOC_EOS;
1319
1320 /* Up-propagate the end-of-space flag. */
1321
1322 if (n && (MDOC_EOS & n->flags)) {
1323 body->flags |= MDOC_EOS;
1324 body->parent->flags |= MDOC_EOS;
1325 }
1326
1327 /*
1328 * If there is an open sub-block requiring explicit close-out,
1329 * postpone closing out the current block
1330 * until the rew_sub() call closing out the sub-block.
1331 */
1332 for (n = mdoc->last; n && n != body && n != blk->parent;
1333 n = n->parent) {
1334 if (MDOC_BLOCK == n->type &&
1335 MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
1336 ! (MDOC_VALID & n->flags)) {
1337 make_pending(n, tok, mdoc, line, ppos);
1338 if ( ! mdoc_endbody_alloc(mdoc, line, ppos,
1339 tok, body, ENDBODY_NOSPACE))
1340 return(0);
1341 return(1);
1342 }
1343 }
1344
1345 /*
1346 * If we can't rewind to our body, then our scope has already
1347 * been closed by another macro (like `Oc' closing `Op'). This
1348 * is ugly behaviour nodding its head to OpenBSD's overwhelming
1349 * crufty use of `Op' breakage.
1350 */
1351 if (n != body)
1352 mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos,
1353 "%s broken", mdoc_macronames[tok]);
1354
1355 if (n && ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
1356 return(0);
1357
1358 /* Standard appending of delimiters. */
1359
1360 if (nl && ! append_delims(mdoc, line, pos, buf))
1361 return(0);
1362
1363 /* Rewind scope, if applicable. */
1364
1365 if (n && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
1366 return(0);
1367
1368 /* Move trailing .Ns out of scope. */
1369
1370 for (n = body->child; n && n->next; n = n->next)
1371 /* Do nothing. */ ;
1372 if (n && MDOC_Ns == n->tok)
1373 mdoc_node_relink(mdoc, n);
1374
1375 return(1);
1376 }
1377
1378
1379 static int
1380 blk_part_exp(MACRO_PROT_ARGS)
1381 {
1382 int la, nl;
1383 enum margserr ac;
1384 struct mdoc_node *head; /* keep track of head */
1385 struct mdoc_node *body; /* keep track of body */
1386 char *p;
1387 enum mdoct ntok;
1388
1389 nl = MDOC_NEWLINE & mdoc->flags;
1390
1391 /*
1392 * The opening of an explicit macro having zero or more leading
1393 * punctuation nodes; a head with optional single element (the
1394 * case of `Eo'); and a body that may be empty.
1395 */
1396
1397 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL))
1398 return(0);
1399
1400 for (head = body = NULL; ; ) {
1401 la = *pos;
1402 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1403
1404 if (ARGS_ERROR == ac)
1405 return(0);
1406 if (ARGS_PUNCT == ac)
1407 break;
1408 if (ARGS_EOLN == ac)
1409 break;
1410
1411 /* Flush out leading punctuation. */
1412
1413 if (NULL == head && ARGS_QWORD != ac &&
1414 DELIM_OPEN == mdoc_isdelim(p)) {
1415 assert(NULL == body);
1416 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1417 return(0);
1418 continue;
1419 }
1420
1421 if (NULL == head) {
1422 assert(NULL == body);
1423 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1424 return(0);
1425 head = mdoc->last;
1426 }
1427
1428 /*
1429 * `Eo' gobbles any data into the head, but most other
1430 * macros just immediately close out and begin the body.
1431 */
1432
1433 if (NULL == body) {
1434 assert(head);
1435 /* No check whether it's a macro! */
1436 if (MDOC_Eo == tok)
1437 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1438 return(0);
1439
1440 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1441 return(0);
1442 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1443 return(0);
1444 body = mdoc->last;
1445
1446 if (MDOC_Eo == tok)
1447 continue;
1448 }
1449
1450 assert(NULL != head && NULL != body);
1451
1452 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1453
1454 if (MDOC_MAX == ntok) {
1455 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1456 return(0);
1457 continue;
1458 }
1459
1460 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1461 return(0);
1462 break;
1463 }
1464
1465 /* Clean-up to leave in a consistent state. */
1466
1467 if (NULL == head)
1468 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
1469 return(0);
1470
1471 if (NULL == body) {
1472 if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
1473 return(0);
1474 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1475 return(0);
1476 }
1477
1478 /* Standard appending of delimiters. */
1479
1480 if ( ! nl)
1481 return(1);
1482 return(append_delims(mdoc, line, pos, buf));
1483 }
1484
1485
1486 /* ARGSUSED */
1487 static int
1488 in_line_argn(MACRO_PROT_ARGS)
1489 {
1490 int la, flushed, j, maxargs, nl;
1491 enum margserr ac;
1492 enum margverr av;
1493 struct mdoc_arg *arg;
1494 char *p;
1495 enum mdoct ntok;
1496
1497 nl = MDOC_NEWLINE & mdoc->flags;
1498
1499 /*
1500 * A line macro that has a fixed number of arguments (maxargs).
1501 * Only open the scope once the first non-leading-punctuation is
1502 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then
1503 * keep it open until the maximum number of arguments are
1504 * exhausted.
1505 */
1506
1507 switch (tok) {
1508 case (MDOC_Ap):
1509 /* FALLTHROUGH */
1510 case (MDOC_No):
1511 /* FALLTHROUGH */
1512 case (MDOC_Ns):
1513 /* FALLTHROUGH */
1514 case (MDOC_Ux):
1515 maxargs = 0;
1516 break;
1517 case (MDOC_Bx):
1518 /* FALLTHROUGH */
1519 case (MDOC_Xr):
1520 maxargs = 2;
1521 break;
1522 default:
1523 maxargs = 1;
1524 break;
1525 }
1526
1527 for (arg = NULL; ; ) {
1528 la = *pos;
1529 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1530
1531 if (ARGV_WORD == av) {
1532 *pos = la;
1533 break;
1534 }
1535
1536 if (ARGV_EOLN == av)
1537 break;
1538 if (ARGV_ARG == av)
1539 continue;
1540
1541 mdoc_argv_free(arg);
1542 return(0);
1543 }
1544
1545 for (flushed = j = 0; ; ) {
1546 la = *pos;
1547 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1548
1549 if (ARGS_ERROR == ac)
1550 return(0);
1551 if (ARGS_PUNCT == ac)
1552 break;
1553 if (ARGS_EOLN == ac)
1554 break;
1555
1556 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1557 ARGS_QWORD != ac && 0 == j &&
1558 DELIM_OPEN == mdoc_isdelim(p)) {
1559 if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
1560 return(0);
1561 continue;
1562 } else if (0 == j)
1563 if ( ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
1564 return(0);
1565
1566 if (j == maxargs && ! flushed) {
1567 if ( ! rew_elem(mdoc, tok))
1568 return(0);
1569 flushed = 1;
1570 }
1571
1572 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1573
1574 if (MDOC_MAX != ntok) {
1575 if ( ! flushed && ! rew_elem(mdoc, tok))
1576 return(0);
1577 flushed = 1;
1578 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1579 return(0);
1580 j++;
1581 break;
1582 }
1583
1584 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1585 ARGS_QWORD != ac &&
1586 ! flushed &&
1587 DELIM_NONE != mdoc_isdelim(p)) {
1588 if ( ! rew_elem(mdoc, tok))
1589 return(0);
1590 flushed = 1;
1591 }
1592
1593 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1594 return(0);
1595 j++;
1596 }
1597
1598 if (0 == j && ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
1599 return(0);
1600
1601 /* Close out in a consistent state. */
1602
1603 if ( ! flushed && ! rew_elem(mdoc, tok))
1604 return(0);
1605 if ( ! nl)
1606 return(1);
1607 return(append_delims(mdoc, line, pos, buf));
1608 }
1609
1610
1611 static int
1612 in_line_eoln(MACRO_PROT_ARGS)
1613 {
1614 int la;
1615 enum margserr ac;
1616 enum margverr av;
1617 struct mdoc_arg *arg;
1618 char *p;
1619 enum mdoct ntok;
1620
1621 assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));
1622
1623 if (tok == MDOC_Pp)
1624 rew_sub(MDOC_BLOCK, mdoc, MDOC_Nm, line, ppos);
1625
1626 /* Parse macro arguments. */
1627
1628 for (arg = NULL; ; ) {
1629 la = *pos;
1630 av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1631
1632 if (ARGV_WORD == av) {
1633 *pos = la;
1634 break;
1635 }
1636 if (ARGV_EOLN == av)
1637 break;
1638 if (ARGV_ARG == av)
1639 continue;
1640
1641 mdoc_argv_free(arg);
1642 return(0);
1643 }
1644
1645 /* Open element scope. */
1646
1647 if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
1648 return(0);
1649
1650 /* Parse argument terms. */
1651
1652 for (;;) {
1653 la = *pos;
1654 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1655
1656 if (ARGS_ERROR == ac)
1657 return(0);
1658 if (ARGS_EOLN == ac)
1659 break;
1660
1661 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1662
1663 if (MDOC_MAX == ntok) {
1664 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1665 return(0);
1666 continue;
1667 }
1668
1669 if ( ! rew_elem(mdoc, tok))
1670 return(0);
1671 return(mdoc_macro(mdoc, ntok, line, la, pos, buf));
1672 }
1673
1674 /* Close out (no delimiters). */
1675
1676 return(rew_elem(mdoc, tok));
1677 }
1678
1679
1680 /* ARGSUSED */
1681 static int
1682 ctx_synopsis(MACRO_PROT_ARGS)
1683 {
1684 int nl;
1685
1686 nl = MDOC_NEWLINE & mdoc->flags;
1687
1688 /* If we're not in the SYNOPSIS, go straight to in-line. */
1689 if ( ! (MDOC_SYNOPSIS & mdoc->flags))
1690 return(in_line(mdoc, tok, line, ppos, pos, buf));
1691
1692 /* If we're a nested call, same place. */
1693 if ( ! nl)
1694 return(in_line(mdoc, tok, line, ppos, pos, buf));
1695
1696 /*
1697 * XXX: this will open a block scope; however, if later we end
1698 * up formatting the block scope, then child nodes will inherit
1699 * the formatting. Be careful.
1700 */
1701 if (MDOC_Nm == tok)
1702 return(blk_full(mdoc, tok, line, ppos, pos, buf));
1703 assert(MDOC_Vt == tok);
1704 return(blk_part_imp(mdoc, tok, line, ppos, pos, buf));
1705 }
1706
1707
1708 /* ARGSUSED */
1709 static int
1710 obsolete(MACRO_PROT_ARGS)
1711 {
1712
1713 mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROOBS);
1714 return(1);
1715 }
1716
1717
1718 /*
1719 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1720 * They're unusual because they're basically free-form text until a
1721 * macro is encountered.
1722 */
1723 static int
1724 phrase(struct mdoc *mdoc, int line, int ppos, char *buf)
1725 {
1726 int la, pos;
1727 enum margserr ac;
1728 enum mdoct ntok;
1729 char *p;
1730
1731 for (pos = ppos; ; ) {
1732 la = pos;
1733
1734 ac = mdoc_zargs(mdoc, line, &pos, buf, &p);
1735
1736 if (ARGS_ERROR == ac)
1737 return(0);
1738 if (ARGS_EOLN == ac)
1739 break;
1740
1741 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p);
1742
1743 if (MDOC_MAX == ntok) {
1744 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1745 return(0);
1746 continue;
1747 }
1748
1749 if ( ! mdoc_macro(mdoc, ntok, line, la, &pos, buf))
1750 return(0);
1751 return(append_delims(mdoc, line, &pos, buf));
1752 }
1753
1754 return(1);
1755 }
1756
1757
1758 /* ARGSUSED */
1759 static int
1760 phrase_ta(MACRO_PROT_ARGS)
1761 {
1762 int la;
1763 enum mdoct ntok;
1764 enum margserr ac;
1765 char *p;
1766
1767 /*
1768 * FIXME: this is overly restrictive: if the `Ta' is unexpected,
1769 * it should simply error out with ARGSLOST.
1770 */
1771
1772 if ( ! rew_sub(MDOC_BODY, mdoc, MDOC_It, line, ppos))
1773 return(0);
1774 if ( ! mdoc_body_alloc(mdoc, line, ppos, MDOC_It))
1775 return(0);
1776
1777 for (;;) {
1778 la = *pos;
1779 ac = mdoc_zargs(mdoc, line, pos, buf, &p);
1780
1781 if (ARGS_ERROR == ac)
1782 return(0);
1783 if (ARGS_EOLN == ac)
1784 break;
1785
1786 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p);
1787
1788 if (MDOC_MAX == ntok) {
1789 if ( ! dword(mdoc, line, la, p, DELIM_MAX))
1790 return(0);
1791 continue;
1792 }
1793
1794 if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
1795 return(0);
1796 return(append_delims(mdoc, line, pos, buf));
1797 }
1798
1799 return(1);
1800 }