Import mandoc-1.14.6.
[dragonfly.git] / contrib / mdocml / mdoc_macro.c
1 /*      $Id: mdoc_macro.c,v 1.234 2020/01/19 18:02:00 schwarze Exp $ */
2 /*
3  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
4  * Copyright (c) 2010, 2012-2020 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 AUTHORS DISCLAIM ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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 #include "config.h"
19
20 #include <sys/types.h>
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 "mandoc.h"
30 #include "roff.h"
31 #include "mdoc.h"
32 #include "libmandoc.h"
33 #include "roff_int.h"
34 #include "libmdoc.h"
35
36 static  void            blk_full(MACRO_PROT_ARGS);
37 static  void            blk_exp_close(MACRO_PROT_ARGS);
38 static  void            blk_part_exp(MACRO_PROT_ARGS);
39 static  void            blk_part_imp(MACRO_PROT_ARGS);
40 static  void            ctx_synopsis(MACRO_PROT_ARGS);
41 static  void            in_line_eoln(MACRO_PROT_ARGS);
42 static  void            in_line_argn(MACRO_PROT_ARGS);
43 static  void            in_line(MACRO_PROT_ARGS);
44 static  void            phrase_ta(MACRO_PROT_ARGS);
45
46 static  void            append_delims(struct roff_man *, int, int *, char *);
47 static  void            dword(struct roff_man *, int, int, const char *,
48                                 enum mdelim, int);
49 static  int             find_pending(struct roff_man *, enum roff_tok,
50                                 int, int, struct roff_node *);
51 static  int             lookup(struct roff_man *, int, int, int, const char *);
52 static  int             macro_or_word(MACRO_PROT_ARGS, char *, int);
53 static  void            break_intermediate(struct roff_node *,
54                                 struct roff_node *);
55 static  int             parse_rest(struct roff_man *, enum roff_tok,
56                                 int, int *, char *);
57 static  enum roff_tok   rew_alt(enum roff_tok);
58 static  void            rew_elem(struct roff_man *, enum roff_tok);
59 static  void            rew_last(struct roff_man *, const struct roff_node *);
60 static  void            rew_pending(struct roff_man *,
61                                 const struct roff_node *);
62
63 static const struct mdoc_macro mdoc_macros[MDOC_MAX - MDOC_Dd] = {
64         { in_line_eoln, MDOC_PROLOGUE | MDOC_JOIN }, /* Dd */
65         { in_line_eoln, MDOC_PROLOGUE }, /* Dt */
66         { in_line_eoln, MDOC_PROLOGUE }, /* Os */
67         { blk_full, MDOC_PARSED | MDOC_JOIN }, /* Sh */
68         { blk_full, MDOC_PARSED | MDOC_JOIN }, /* Ss */
69         { in_line_eoln, 0 }, /* Pp */
70         { blk_part_imp, MDOC_PARSED | MDOC_JOIN }, /* D1 */
71         { blk_part_imp, MDOC_PARSED | MDOC_JOIN }, /* Dl */
72         { blk_full, MDOC_EXPLICIT }, /* Bd */
73         { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ed */
74         { blk_full, MDOC_EXPLICIT }, /* Bl */
75         { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* El */
76         { blk_full, MDOC_PARSED | MDOC_JOIN }, /* It */
77         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
78         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* An */
79         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED |
80                         MDOC_IGNDELIM | MDOC_JOIN }, /* Ap */
81         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
82         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Cd */
83         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
84         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
85         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
86         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */
87         { in_line_eoln, 0 }, /* Ex */
88         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */
89         { in_line_eoln, 0 }, /* Fd */
90         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
91         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
92         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
93         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ic */
94         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
95         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Li */
96         { blk_full, MDOC_JOIN }, /* Nd */
97         { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
98         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
99         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ot */
100         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
101         { in_line_eoln, 0 }, /* Rv */
102         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
103         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
104         { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
105         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
106         { in_line_eoln, MDOC_JOIN }, /* %A */
107         { in_line_eoln, MDOC_JOIN }, /* %B */
108         { in_line_eoln, MDOC_JOIN }, /* %D */
109         { in_line_eoln, MDOC_JOIN }, /* %I */
110         { in_line_eoln, MDOC_JOIN }, /* %J */
111         { in_line_eoln, 0 }, /* %N */
112         { in_line_eoln, MDOC_JOIN }, /* %O */
113         { in_line_eoln, 0 }, /* %P */
114         { in_line_eoln, MDOC_JOIN }, /* %R */
115         { in_line_eoln, MDOC_JOIN }, /* %T */
116         { in_line_eoln, 0 }, /* %V */
117         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
118                          MDOC_EXPLICIT | MDOC_JOIN }, /* Ac */
119         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
120                         MDOC_EXPLICIT | MDOC_JOIN }, /* Ao */
121         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Aq */
122         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */
123         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
124                          MDOC_EXPLICIT | MDOC_JOIN }, /* Bc */
125         { blk_full, MDOC_EXPLICIT }, /* Bf */
126         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
127                         MDOC_EXPLICIT | MDOC_JOIN }, /* Bo */
128         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Bq */
129         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */
130         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */
131         { in_line_eoln, 0 }, /* Db */
132         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
133                          MDOC_EXPLICIT | MDOC_JOIN }, /* Dc */
134         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
135                         MDOC_EXPLICIT | MDOC_JOIN }, /* Do */
136         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Dq */
137         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ec */
138         { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ef */
139         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Em */
140         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */
141         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */
142         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */
143         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* No */
144         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED |
145                         MDOC_IGNDELIM | MDOC_JOIN }, /* Ns */
146         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */
147         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */
148         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
149                          MDOC_EXPLICIT | MDOC_JOIN }, /* Pc */
150         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */
151         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
152                         MDOC_EXPLICIT | MDOC_JOIN }, /* Po */
153         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Pq */
154         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
155                          MDOC_EXPLICIT | MDOC_JOIN }, /* Qc */
156         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ql */
157         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
158                         MDOC_EXPLICIT | MDOC_JOIN }, /* Qo */
159         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Qq */
160         { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Re */
161         { blk_full, MDOC_EXPLICIT }, /* Rs */
162         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
163                          MDOC_EXPLICIT | MDOC_JOIN }, /* Sc */
164         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
165                         MDOC_EXPLICIT | MDOC_JOIN }, /* So */
166         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sq */
167         { in_line_argn, 0 }, /* Sm */
168         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sx */
169         { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sy */
170         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */
171         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ux */
172         { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */
173         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */
174         { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */
175         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
176                          MDOC_EXPLICIT | MDOC_JOIN }, /* Fc */
177         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
178                         MDOC_EXPLICIT | MDOC_JOIN }, /* Oo */
179         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
180                          MDOC_EXPLICIT | MDOC_JOIN }, /* Oc */
181         { blk_full, MDOC_EXPLICIT }, /* Bk */
182         { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ek */
183         { in_line_eoln, 0 }, /* Bt */
184         { in_line_eoln, 0 }, /* Hf */
185         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fr */
186         { in_line_eoln, 0 }, /* Ud */
187         { in_line, 0 }, /* Lb */
188         { in_line_eoln, 0 }, /* Lp */
189         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */
190         { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */
191         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Brq */
192         { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED |
193                         MDOC_EXPLICIT | MDOC_JOIN }, /* Bro */
194         { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
195                          MDOC_EXPLICIT | MDOC_JOIN }, /* Brc */
196         { in_line_eoln, MDOC_JOIN }, /* %C */
197         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Es */
198         { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* En */
199         { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
200         { in_line_eoln, MDOC_JOIN }, /* %Q */
201         { in_line_eoln, 0 }, /* %U */
202         { phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
203         { in_line_eoln, 0 }, /* Tg */
204 };
205
206
207 const struct mdoc_macro *
208 mdoc_macro(enum roff_tok tok)
209 {
210         assert(tok >= MDOC_Dd && tok < MDOC_MAX);
211         return mdoc_macros + (tok - MDOC_Dd);
212 }
213
214 /*
215  * This is called at the end of parsing.  It must traverse up the tree,
216  * closing out open [implicit] scopes.  Obviously, open explicit scopes
217  * are errors.
218  */
219 void
220 mdoc_endparse(struct roff_man *mdoc)
221 {
222         struct roff_node *n;
223
224         /* Scan for open explicit scopes. */
225
226         n = mdoc->last->flags & NODE_VALID ?
227             mdoc->last->parent : mdoc->last;
228
229         for ( ; n; n = n->parent)
230                 if (n->type == ROFFT_BLOCK &&
231                     mdoc_macro(n->tok)->flags & MDOC_EXPLICIT)
232                         mandoc_msg(MANDOCERR_BLK_NOEND,
233                             n->line, n->pos, "%s", roff_name[n->tok]);
234
235         /* Rewind to the first. */
236
237         rew_last(mdoc, mdoc->meta.first);
238 }
239
240 /*
241  * Look up the macro at *p called by "from",
242  * or as a line macro if from == TOKEN_NONE.
243  */
244 static int
245 lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p)
246 {
247         enum roff_tok    res;
248
249         if (mdoc->flags & MDOC_PHRASEQF) {
250                 mdoc->flags &= ~MDOC_PHRASEQF;
251                 return TOKEN_NONE;
252         }
253         if (from == TOKEN_NONE || mdoc_macro(from)->flags & MDOC_PARSED) {
254                 res = roffhash_find(mdoc->mdocmac, p, 0);
255                 if (res != TOKEN_NONE) {
256                         if (mdoc_macro(res)->flags & MDOC_CALLABLE)
257                                 return res;
258                         mandoc_msg(MANDOCERR_MACRO_CALL, line, ppos, "%s", p);
259                 }
260         }
261         return TOKEN_NONE;
262 }
263
264 /*
265  * Rewind up to and including a specific node.
266  */
267 static void
268 rew_last(struct roff_man *mdoc, const struct roff_node *to)
269 {
270
271         if (to->flags & NODE_VALID)
272                 return;
273
274         while (mdoc->last != to) {
275                 mdoc_state(mdoc, mdoc->last);
276                 mdoc->last->flags |= NODE_VALID | NODE_ENDED;
277                 mdoc->last = mdoc->last->parent;
278         }
279         mdoc_state(mdoc, mdoc->last);
280         mdoc->last->flags |= NODE_VALID | NODE_ENDED;
281         mdoc->next = ROFF_NEXT_SIBLING;
282 }
283
284 /*
285  * Rewind up to a specific block, including all blocks that broke it.
286  */
287 static void
288 rew_pending(struct roff_man *mdoc, const struct roff_node *n)
289 {
290
291         for (;;) {
292                 rew_last(mdoc, n);
293
294                 if (mdoc->last == n) {
295                         switch (n->type) {
296                         case ROFFT_HEAD:
297                                 roff_body_alloc(mdoc, n->line, n->pos,
298                                     n->tok);
299                                 if (n->tok == MDOC_Ss)
300                                         mdoc->flags &= ~ROFF_NONOFILL;
301                                 break;
302                         case ROFFT_BLOCK:
303                                 break;
304                         default:
305                                 return;
306                         }
307                         if ( ! (n->flags & NODE_BROKEN))
308                                 return;
309                 } else
310                         n = mdoc->last;
311
312                 for (;;) {
313                         if ((n = n->parent) == NULL)
314                                 return;
315
316                         if (n->type == ROFFT_BLOCK ||
317                             n->type == ROFFT_HEAD) {
318                                 if (n->flags & NODE_ENDED)
319                                         break;
320                                 else
321                                         return;
322                         }
323                 }
324         }
325 }
326
327 /*
328  * For a block closing macro, return the corresponding opening one.
329  * Otherwise, return the macro itself.
330  */
331 static enum roff_tok
332 rew_alt(enum roff_tok tok)
333 {
334         switch (tok) {
335         case MDOC_Ac:
336                 return MDOC_Ao;
337         case MDOC_Bc:
338                 return MDOC_Bo;
339         case MDOC_Brc:
340                 return MDOC_Bro;
341         case MDOC_Dc:
342                 return MDOC_Do;
343         case MDOC_Ec:
344                 return MDOC_Eo;
345         case MDOC_Ed:
346                 return MDOC_Bd;
347         case MDOC_Ef:
348                 return MDOC_Bf;
349         case MDOC_Ek:
350                 return MDOC_Bk;
351         case MDOC_El:
352                 return MDOC_Bl;
353         case MDOC_Fc:
354                 return MDOC_Fo;
355         case MDOC_Oc:
356                 return MDOC_Oo;
357         case MDOC_Pc:
358                 return MDOC_Po;
359         case MDOC_Qc:
360                 return MDOC_Qo;
361         case MDOC_Re:
362                 return MDOC_Rs;
363         case MDOC_Sc:
364                 return MDOC_So;
365         case MDOC_Xc:
366                 return MDOC_Xo;
367         default:
368                 return tok;
369         }
370 }
371
372 static void
373 rew_elem(struct roff_man *mdoc, enum roff_tok tok)
374 {
375         struct roff_node *n;
376
377         n = mdoc->last;
378         if (n->type != ROFFT_ELEM)
379                 n = n->parent;
380         assert(n->type == ROFFT_ELEM);
381         assert(tok == n->tok);
382         rew_last(mdoc, n);
383 }
384
385 static void
386 break_intermediate(struct roff_node *n, struct roff_node *breaker)
387 {
388         if (n != breaker &&
389             n->type != ROFFT_BLOCK && n->type != ROFFT_HEAD &&
390             (n->type != ROFFT_BODY || n->end != ENDBODY_NOT))
391                 n = n->parent;
392         while (n != breaker) {
393                 if ( ! (n->flags & NODE_VALID))
394                         n->flags |= NODE_BROKEN;
395                 n = n->parent;
396         }
397 }
398
399 /*
400  * If there is an open sub-block of the target requiring
401  * explicit close-out, postpone closing out the target until
402  * the rew_pending() call closing out the sub-block.
403  */
404 static int
405 find_pending(struct roff_man *mdoc, enum roff_tok tok, int line, int ppos,
406         struct roff_node *target)
407 {
408         struct roff_node        *n;
409         int                      irc;
410
411         if (target->flags & NODE_VALID)
412                 return 0;
413
414         irc = 0;
415         for (n = mdoc->last; n != NULL && n != target; n = n->parent) {
416                 if (n->flags & NODE_ENDED)
417                         continue;
418                 if (n->type == ROFFT_BLOCK &&
419                     mdoc_macro(n->tok)->flags & MDOC_EXPLICIT) {
420                         irc = 1;
421                         break_intermediate(mdoc->last, target);
422                         if (target->type == ROFFT_HEAD)
423                                 target->flags |= NODE_ENDED;
424                         else if ( ! (target->flags & NODE_ENDED)) {
425                                 mandoc_msg(MANDOCERR_BLK_NEST,
426                                     line, ppos, "%s breaks %s",
427                                     roff_name[tok], roff_name[n->tok]);
428                                 mdoc_endbody_alloc(mdoc, line, ppos,
429                                     tok, target);
430                         }
431                 }
432         }
433         return irc;
434 }
435
436 /*
437  * Allocate a word and check whether it's punctuation or not.
438  * Punctuation consists of those tokens found in mdoc_isdelim().
439  */
440 static void
441 dword(struct roff_man *mdoc, int line, int col, const char *p,
442                 enum mdelim d, int may_append)
443 {
444
445         if (d == DELIM_MAX)
446                 d = mdoc_isdelim(p);
447
448         if (may_append &&
449             ! (mdoc->flags & (MDOC_SYNOPSIS | MDOC_KEEP | MDOC_SMOFF)) &&
450             d == DELIM_NONE && mdoc->last->type == ROFFT_TEXT &&
451             mdoc_isdelim(mdoc->last->string) == DELIM_NONE) {
452                 roff_word_append(mdoc, p);
453                 return;
454         }
455
456         roff_word_alloc(mdoc, line, col, p);
457
458         /*
459          * If the word consists of a bare delimiter,
460          * flag the new node accordingly,
461          * unless doing so was vetoed by the invoking macro.
462          * Always clear the veto, it is only valid for one word.
463          */
464
465         if (d == DELIM_OPEN)
466                 mdoc->last->flags |= NODE_DELIMO;
467         else if (d == DELIM_CLOSE &&
468             ! (mdoc->flags & MDOC_NODELIMC) &&
469             mdoc->last->parent->tok != MDOC_Fd)
470                 mdoc->last->flags |= NODE_DELIMC;
471         mdoc->flags &= ~MDOC_NODELIMC;
472 }
473
474 static void
475 append_delims(struct roff_man *mdoc, int line, int *pos, char *buf)
476 {
477         char            *p;
478         int              la;
479         enum margserr    ac;
480
481         if (buf[*pos] == '\0')
482                 return;
483
484         for (;;) {
485                 la = *pos;
486                 ac = mdoc_args(mdoc, line, pos, buf, TOKEN_NONE, &p);
487                 if (ac == ARGS_EOLN)
488                         break;
489                 dword(mdoc, line, la, p, DELIM_MAX, 1);
490
491                 /*
492                  * If we encounter end-of-sentence symbols, then trigger
493                  * the double-space.
494                  *
495                  * XXX: it's easy to allow this to propagate outward to
496                  * the last symbol, such that `. )' will cause the
497                  * correct double-spacing.  However, (1) groff isn't
498                  * smart enough to do this and (2) it would require
499                  * knowing which symbols break this behaviour, for
500                  * example, `.  ;' shouldn't propagate the double-space.
501                  */
502
503                 if (mandoc_eos(p, strlen(p)))
504                         mdoc->last->flags |= NODE_EOS;
505                 if (ac == ARGS_ALLOC)
506                         free(p);
507         }
508 }
509
510 /*
511  * Parse one word.
512  * If it is a macro, call it and return 1.
513  * Otherwise, allocate it and return 0.
514  */
515 static int
516 macro_or_word(MACRO_PROT_ARGS, char *p, int parsed)
517 {
518         int              ntok;
519
520         ntok = buf[ppos] == '"' || parsed == 0 ||
521             mdoc->flags & MDOC_PHRASELIT ? TOKEN_NONE :
522             lookup(mdoc, tok, line, ppos, p);
523
524         if (ntok == TOKEN_NONE) {
525                 dword(mdoc, line, ppos, p, DELIM_MAX, tok == TOKEN_NONE ||
526                     mdoc_macro(tok)->flags & MDOC_JOIN);
527                 return 0;
528         } else {
529                 if (tok != TOKEN_NONE &&
530                     mdoc_macro(tok)->fp == in_line_eoln)
531                         rew_elem(mdoc, tok);
532                 (*mdoc_macro(ntok)->fp)(mdoc, ntok, line, ppos, pos, buf);
533                 if (tok == TOKEN_NONE)
534                         append_delims(mdoc, line, pos, buf);
535                 return 1;
536         }
537 }
538
539 /*
540  * Close out block partial/full explicit.
541  */
542 static void
543 blk_exp_close(MACRO_PROT_ARGS)
544 {
545         struct roff_node *body;         /* Our own body. */
546         struct roff_node *endbody;      /* Our own end marker. */
547         struct roff_node *itblk;        /* An It block starting later. */
548         struct roff_node *later;        /* A sub-block starting later. */
549         struct roff_node *n;            /* Search back to our block. */
550         struct roff_node *target;       /* For find_pending(). */
551
552         int              j, lastarg, maxargs, nl, pending;
553         enum margserr    ac;
554         enum roff_tok    atok, ntok;
555         char            *p;
556
557         nl = MDOC_NEWLINE & mdoc->flags;
558
559         switch (tok) {
560         case MDOC_Ec:
561                 maxargs = 1;
562                 break;
563         case MDOC_Ek:
564                 mdoc->flags &= ~MDOC_KEEP;
565                 /* FALLTHROUGH */
566         default:
567                 maxargs = 0;
568                 break;
569         }
570
571         /* Search backwards for the beginning of our own body. */
572
573         atok = rew_alt(tok);
574         body = NULL;
575         for (n = mdoc->last; n; n = n->parent) {
576                 if (n->flags & NODE_ENDED || n->tok != atok ||
577                     n->type != ROFFT_BODY || n->end != ENDBODY_NOT)
578                         continue;
579                 body = n;
580                 break;
581         }
582
583         /*
584          * Search backwards for beginnings of blocks,
585          * both of our own and of pending sub-blocks.
586          */
587
588         endbody = itblk = later = NULL;
589         for (n = mdoc->last; n; n = n->parent) {
590                 if (n->flags & NODE_ENDED)
591                         continue;
592
593                 /*
594                  * Mismatching end macros can never break anything
595                  * and we only care about the breaking of BLOCKs.
596                  */
597
598                 if (body == NULL || n->type != ROFFT_BLOCK)
599                         continue;
600
601                 /*
602                  * SYNOPSIS name blocks can not be broken themselves,
603                  * but they do get broken together with a broken child.
604                  */
605
606                 if (n->tok == MDOC_Nm) {
607                         if (later != NULL)
608                                 n->flags |= NODE_BROKEN | NODE_ENDED;
609                         continue;
610                 }
611
612                 if (n->tok == MDOC_It) {
613                         itblk = n;
614                         continue;
615                 }
616
617                 if (atok == n->tok) {
618
619                         /*
620                          * Found the start of our own block.
621                          * When there is no pending sub block,
622                          * just proceed to closing out.
623                          */
624
625                         if (later == NULL ||
626                             (tok == MDOC_El && itblk == NULL))
627                                 break;
628
629                         /*
630                          * When there is a pending sub block, postpone
631                          * closing out the current block until the
632                          * rew_pending() closing out the sub-block.
633                          * Mark the place where the formatting - but not
634                          * the scope - of the current block ends.
635                          */
636
637                         mandoc_msg(MANDOCERR_BLK_NEST,
638                             line, ppos, "%s breaks %s",
639                             roff_name[atok], roff_name[later->tok]);
640
641                         endbody = mdoc_endbody_alloc(mdoc, line, ppos,
642                             atok, body);
643
644                         if (tok == MDOC_El)
645                                 itblk->flags |= NODE_ENDED | NODE_BROKEN;
646
647                         /*
648                          * If a block closing macro taking arguments
649                          * breaks another block, put the arguments
650                          * into the end marker.
651                          */
652
653                         if (maxargs)
654                                 mdoc->next = ROFF_NEXT_CHILD;
655                         break;
656                 }
657
658                 /*
659                  * Explicit blocks close out description lines, but
660                  * even those can get broken together with a child.
661                  */
662
663                 if (n->tok == MDOC_Nd) {
664                         if (later != NULL)
665                                 n->flags |= NODE_BROKEN | NODE_ENDED;
666                         else
667                                 rew_last(mdoc, n);
668                         continue;
669                 }
670
671                 /* Breaking an open sub block. */
672
673                 break_intermediate(mdoc->last, body);
674                 n->flags |= NODE_BROKEN;
675                 if (later == NULL)
676                         later = n;
677         }
678
679         if (body == NULL) {
680                 mandoc_msg(MANDOCERR_BLK_NOTOPEN, line, ppos,
681                     "%s", roff_name[tok]);
682                 if (maxargs && endbody == NULL) {
683                         /*
684                          * Stray .Ec without previous .Eo:
685                          * Break the output line, keep the arguments.
686                          */
687                         roff_elem_alloc(mdoc, line, ppos, ROFF_br);
688                         rew_elem(mdoc, ROFF_br);
689                 }
690         } else if (endbody == NULL) {
691                 rew_last(mdoc, body);
692                 if (maxargs)
693                         mdoc_tail_alloc(mdoc, line, ppos, atok);
694         }
695
696         if ((mdoc_macro(tok)->flags & MDOC_PARSED) == 0) {
697                 if (buf[*pos] != '\0')
698                         mandoc_msg(MANDOCERR_ARG_SKIP, line, ppos,
699                             "%s %s", roff_name[tok], buf + *pos);
700                 if (endbody == NULL && n != NULL)
701                         rew_pending(mdoc, n);
702
703                 /*
704                  * Restore the fill mode that was set before the display.
705                  * This needs to be done here rather than during validation
706                  * such that subsequent nodes get the right flags.
707                  */
708
709                 if (tok == MDOC_Ed && body != NULL) {
710                         if (body->flags & NODE_NOFILL)
711                                 mdoc->flags |= ROFF_NOFILL;
712                         else
713                                 mdoc->flags &= ~ROFF_NOFILL;
714                 }
715                 return;
716         }
717
718         if (endbody != NULL)
719                 n = endbody;
720
721         ntok = TOKEN_NONE;
722         for (j = 0; ; j++) {
723                 lastarg = *pos;
724
725                 if (j == maxargs && n != NULL)
726                         rew_last(mdoc, n);
727
728                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
729                 if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
730                         break;
731
732                 ntok = lookup(mdoc, tok, line, lastarg, p);
733
734                 if (ntok == TOKEN_NONE) {
735                         dword(mdoc, line, lastarg, p, DELIM_MAX,
736                             mdoc_macro(tok)->flags & MDOC_JOIN);
737                         if (ac == ARGS_ALLOC)
738                                 free(p);
739                         continue;
740                 }
741                 if (ac == ARGS_ALLOC)
742                         free(p);
743
744                 if (n != NULL)
745                         rew_last(mdoc, n);
746                 mdoc->flags &= ~MDOC_NEWLINE;
747                 (*mdoc_macro(ntok)->fp)(mdoc, ntok, line, lastarg, pos, buf);
748                 break;
749         }
750
751         if (n != NULL) {
752                 pending = 0;
753                 if (ntok != TOKEN_NONE && n->flags & NODE_BROKEN) {
754                         target = n;
755                         do
756                                 target = target->parent;
757                         while ( ! (target->flags & NODE_ENDED));
758                         pending = find_pending(mdoc, ntok, line, ppos, target);
759                 }
760                 if ( ! pending)
761                         rew_pending(mdoc, n);
762         }
763         if (nl)
764                 append_delims(mdoc, line, pos, buf);
765 }
766
767 static void
768 in_line(MACRO_PROT_ARGS)
769 {
770         int              la, scope, cnt, firstarg, mayopen, nc, nl;
771         enum roff_tok    ntok;
772         enum margserr    ac;
773         enum mdelim      d;
774         struct mdoc_arg *arg;
775         char            *p;
776
777         nl = MDOC_NEWLINE & mdoc->flags;
778
779         /*
780          * Whether we allow ignored elements (those without content,
781          * usually because of reserved words) to squeak by.
782          */
783
784         switch (tok) {
785         case MDOC_An:
786         case MDOC_Ar:
787         case MDOC_Fl:
788         case MDOC_Mt:
789         case MDOC_Nm:
790         case MDOC_Pa:
791                 nc = 1;
792                 break;
793         default:
794                 nc = 0;
795                 break;
796         }
797
798         mdoc_argv(mdoc, line, tok, &arg, pos, buf);
799
800         d = DELIM_NONE;
801         firstarg = 1;
802         mayopen = 1;
803         for (cnt = scope = 0;; ) {
804                 la = *pos;
805                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
806
807                 /*
808                  * At the end of a macro line,
809                  * opening delimiters do not suppress spacing.
810                  */
811
812                 if (ac == ARGS_EOLN) {
813                         if (d == DELIM_OPEN)
814                                 mdoc->last->flags &= ~NODE_DELIMO;
815                         break;
816                 }
817
818                 /*
819                  * The rest of the macro line is only punctuation,
820                  * to be handled by append_delims().
821                  * If there were no other arguments,
822                  * do not allow the first one to suppress spacing,
823                  * even if it turns out to be a closing one.
824                  */
825
826                 if (ac == ARGS_PUNCT) {
827                         if (cnt == 0 && (nc == 0 || tok == MDOC_An))
828                                 mdoc->flags |= MDOC_NODELIMC;
829                         break;
830                 }
831
832                 ntok = (tok == MDOC_Fn && !cnt) ?
833                     TOKEN_NONE : lookup(mdoc, tok, line, la, p);
834
835                 /*
836                  * In this case, we've located a submacro and must
837                  * execute it.  Close out scope, if open.  If no
838                  * elements have been generated, either create one (nc)
839                  * or raise a warning.
840                  */
841
842                 if (ntok != TOKEN_NONE) {
843                         if (scope)
844                                 rew_elem(mdoc, tok);
845                         if (nc && ! cnt) {
846                                 mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
847                                 rew_last(mdoc, mdoc->last);
848                         } else if ( ! nc && ! cnt) {
849                                 mdoc_argv_free(arg);
850                                 mandoc_msg(MANDOCERR_MACRO_EMPTY,
851                                     line, ppos, "%s", roff_name[tok]);
852                         }
853                         (*mdoc_macro(ntok)->fp)(mdoc, ntok,
854                             line, la, pos, buf);
855                         if (nl)
856                                 append_delims(mdoc, line, pos, buf);
857                         if (ac == ARGS_ALLOC)
858                                 free(p);
859                         return;
860                 }
861
862                 /*
863                  * Handle punctuation.  Set up our scope, if a word;
864                  * rewind the scope, if a delimiter; then append the word.
865                  */
866
867                 if ((d = mdoc_isdelim(p)) != DELIM_NONE) {
868                         /*
869                          * If we encounter closing punctuation, no word
870                          * has been emitted, no scope is open, and we're
871                          * allowed to have an empty element, then start
872                          * a new scope.
873                          */
874                         if ((d == DELIM_CLOSE ||
875                              (d == DELIM_MIDDLE && tok == MDOC_Fl)) &&
876                             !cnt && !scope && nc && mayopen) {
877                                 mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
878                                 scope = 1;
879                                 cnt++;
880                                 if (tok == MDOC_Nm)
881                                         mayopen = 0;
882                         }
883                         /*
884                          * Close out our scope, if one is open, before
885                          * any punctuation.
886                          */
887                         if (scope && tok != MDOC_Lk) {
888                                 rew_elem(mdoc, tok);
889                                 scope = 0;
890                                 if (tok == MDOC_Fn)
891                                         mayopen = 0;
892                         }
893                 } else if (mayopen && !scope) {
894                         mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
895                         scope = 1;
896                         cnt++;
897                 }
898
899                 dword(mdoc, line, la, p, d,
900                     mdoc_macro(tok)->flags & MDOC_JOIN);
901
902                 if (ac == ARGS_ALLOC)
903                         free(p);
904
905                 /*
906                  * If the first argument is a closing delimiter,
907                  * do not suppress spacing before it.
908                  */
909
910                 if (firstarg && d == DELIM_CLOSE && !nc)
911                         mdoc->last->flags &= ~NODE_DELIMC;
912                 firstarg = 0;
913
914                 /*
915                  * `Fl' macros have their scope re-opened with each new
916                  * word so that the `-' can be added to each one without
917                  * having to parse out spaces.
918                  */
919                 if (scope && tok == MDOC_Fl) {
920                         rew_elem(mdoc, tok);
921                         scope = 0;
922                 }
923         }
924
925         if (scope && tok != MDOC_Lk) {
926                 rew_elem(mdoc, tok);
927                 scope = 0;
928         }
929
930         /*
931          * If no elements have been collected and we're allowed to have
932          * empties (nc), open a scope and close it out.  Otherwise,
933          * raise a warning.
934          */
935
936         if ( ! cnt) {
937                 if (nc) {
938                         mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
939                         rew_last(mdoc, mdoc->last);
940                 } else {
941                         mdoc_argv_free(arg);
942                         mandoc_msg(MANDOCERR_MACRO_EMPTY,
943                             line, ppos, "%s", roff_name[tok]);
944                 }
945         }
946         if (nl)
947                 append_delims(mdoc, line, pos, buf);
948         if (scope)
949                 rew_elem(mdoc, tok);
950 }
951
952 static void
953 blk_full(MACRO_PROT_ARGS)
954 {
955         struct mdoc_arg  *arg;
956         struct roff_node *blk; /* Our own or a broken block. */
957         struct roff_node *head; /* Our own head. */
958         struct roff_node *body; /* Our own body. */
959         struct roff_node *n;
960         char             *p;
961         size_t            iarg;
962         int               done, la, nl, parsed;
963         enum margserr     ac, lac;
964
965         nl = MDOC_NEWLINE & mdoc->flags;
966
967         if (buf[*pos] == '\0' && (tok == MDOC_Sh || tok == MDOC_Ss)) {
968                 mandoc_msg(MANDOCERR_MACRO_EMPTY,
969                     line, ppos, "%s", roff_name[tok]);
970                 return;
971         }
972
973         if ((mdoc_macro(tok)->flags & MDOC_EXPLICIT) == 0) {
974
975                 /* Here, tok is one of Sh Ss Nm Nd It. */
976
977                 blk = NULL;
978                 for (n = mdoc->last; n != NULL; n = n->parent) {
979                         if (n->flags & NODE_ENDED) {
980                                 if ( ! (n->flags & NODE_VALID))
981                                         n->flags |= NODE_BROKEN;
982                                 continue;
983                         }
984                         if (n->type != ROFFT_BLOCK)
985                                 continue;
986
987                         if (tok == MDOC_It && n->tok == MDOC_Bl) {
988                                 if (blk != NULL) {
989                                         mandoc_msg(MANDOCERR_BLK_BROKEN,
990                                             line, ppos, "It breaks %s",
991                                             roff_name[blk->tok]);
992                                         rew_pending(mdoc, blk);
993                                 }
994                                 break;
995                         }
996
997                         if (mdoc_macro(n->tok)->flags & MDOC_EXPLICIT) {
998                                 switch (tok) {
999                                 case MDOC_Sh:
1000                                 case MDOC_Ss:
1001                                         mandoc_msg(MANDOCERR_BLK_BROKEN,
1002                                             line, ppos,
1003                                             "%s breaks %s", roff_name[tok],
1004                                             roff_name[n->tok]);
1005                                         rew_pending(mdoc, n);
1006                                         n = mdoc->last;
1007                                         continue;
1008                                 case MDOC_It:
1009                                         /* Delay in case it's astray. */
1010                                         blk = n;
1011                                         continue;
1012                                 default:
1013                                         break;
1014                                 }
1015                                 break;
1016                         }
1017
1018                         /* Here, n is one of Sh Ss Nm Nd It. */
1019
1020                         if (tok != MDOC_Sh && (n->tok == MDOC_Sh ||
1021                             (tok != MDOC_Ss && (n->tok == MDOC_Ss ||
1022                              (tok != MDOC_It && n->tok == MDOC_It)))))
1023                                 break;
1024
1025                         /* Item breaking an explicit block. */
1026
1027                         if (blk != NULL) {
1028                                 mandoc_msg(MANDOCERR_BLK_BROKEN, line, ppos,
1029                                     "It breaks %s", roff_name[blk->tok]);
1030                                 rew_pending(mdoc, blk);
1031                                 blk = NULL;
1032                         }
1033
1034                         /* Close out prior implicit scopes. */
1035
1036                         rew_pending(mdoc, n);
1037                 }
1038
1039                 /* Skip items outside lists. */
1040
1041                 if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
1042                         mandoc_msg(MANDOCERR_IT_STRAY,
1043                             line, ppos, "It %s", buf + *pos);
1044                         roff_elem_alloc(mdoc, line, ppos, ROFF_br);
1045                         rew_elem(mdoc, ROFF_br);
1046                         return;
1047                 }
1048         }
1049
1050         /*
1051          * This routine accommodates implicitly- and explicitly-scoped
1052          * macro openings.  Implicit ones first close out prior scope
1053          * (seen above).  Delay opening the head until necessary to
1054          * allow leading punctuation to print.  Special consideration
1055          * for `It -column', which has phrase-part syntax instead of
1056          * regular child nodes.
1057          */
1058
1059         switch (tok) {
1060         case MDOC_Sh:
1061                 mdoc->flags &= ~ROFF_NOFILL;
1062                 break;
1063         case MDOC_Ss:
1064                 mdoc->flags |= ROFF_NONOFILL;
1065                 break;
1066         default:
1067                 break;
1068         }
1069         mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1070         blk = mdoc_block_alloc(mdoc, line, ppos, tok, arg);
1071         head = body = NULL;
1072
1073         /*
1074          * Exception: Heads of `It' macros in `-diag' lists are not
1075          * parsed, even though `It' macros in general are parsed.
1076          */
1077
1078         parsed = tok != MDOC_It ||
1079             mdoc->last->parent->tok != MDOC_Bl ||
1080             mdoc->last->parent->norm->Bl.type != LIST_diag;
1081
1082         /*
1083          * The `Nd' macro has all arguments in its body: it's a hybrid
1084          * of block partial-explicit and full-implicit.  Stupid.
1085          */
1086
1087         if (tok == MDOC_Nd) {
1088                 head = roff_head_alloc(mdoc, line, ppos, tok);
1089                 rew_last(mdoc, head);
1090                 body = roff_body_alloc(mdoc, line, ppos, tok);
1091         }
1092
1093         if (tok == MDOC_Bk)
1094                 mdoc->flags |= MDOC_KEEP;
1095
1096         ac = ARGS_EOLN;
1097         for (;;) {
1098
1099                 /*
1100                  * If we are right after a tab character,
1101                  * do not parse the first word for macros.
1102                  */
1103
1104                 if (mdoc->flags & MDOC_PHRASEQN) {
1105                         mdoc->flags &= ~MDOC_PHRASEQN;
1106                         mdoc->flags |= MDOC_PHRASEQF;
1107                 }
1108
1109                 la = *pos;
1110                 lac = ac;
1111                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1112                 if (ac == ARGS_EOLN) {
1113                         if (lac != ARGS_PHRASE ||
1114                             ! (mdoc->flags & MDOC_PHRASEQF))
1115                                 break;
1116
1117                         /*
1118                          * This line ends in a tab; start the next
1119                          * column now, with a leading blank.
1120                          */
1121
1122                         if (body != NULL)
1123                                 rew_last(mdoc, body);
1124                         body = roff_body_alloc(mdoc, line, ppos, tok);
1125                         roff_word_alloc(mdoc, line, ppos, "\\&");
1126                         break;
1127                 }
1128
1129                 if (tok == MDOC_Bd || tok == MDOC_Bk) {
1130                         mandoc_msg(MANDOCERR_ARG_EXCESS, line, la,
1131                             "%s ... %s", roff_name[tok], buf + la);
1132                         if (ac == ARGS_ALLOC)
1133                                 free(p);
1134                         break;
1135                 }
1136                 if (tok == MDOC_Rs) {
1137                         mandoc_msg(MANDOCERR_ARG_SKIP,
1138                             line, la, "Rs %s", buf + la);
1139                         if (ac == ARGS_ALLOC)
1140                                 free(p);
1141                         break;
1142                 }
1143                 if (ac == ARGS_PUNCT)
1144                         break;
1145
1146                 /*
1147                  * Emit leading punctuation (i.e., punctuation before
1148                  * the ROFFT_HEAD) for non-phrase types.
1149                  */
1150
1151                 if (head == NULL &&
1152                     ac != ARGS_PHRASE &&
1153                     mdoc_isdelim(p) == DELIM_OPEN) {
1154                         dword(mdoc, line, la, p, DELIM_OPEN, 0);
1155                         if (ac == ARGS_ALLOC)
1156                                 free(p);
1157                         continue;
1158                 }
1159
1160                 /* Open a head if one hasn't been opened. */
1161
1162                 if (head == NULL)
1163                         head = roff_head_alloc(mdoc, line, ppos, tok);
1164
1165                 if (ac == ARGS_PHRASE) {
1166
1167                         /*
1168                          * If we haven't opened a body yet, rewind the
1169                          * head; if we have, rewind that instead.
1170                          */
1171
1172                         rew_last(mdoc, body == NULL ? head : body);
1173                         body = roff_body_alloc(mdoc, line, ppos, tok);
1174
1175                         /* Process to the tab or to the end of the line. */
1176
1177                         mdoc->flags |= MDOC_PHRASE;
1178                         parse_rest(mdoc, TOKEN_NONE, line, &la, buf);
1179                         mdoc->flags &= ~MDOC_PHRASE;
1180
1181                         /* There may have been `Ta' macros. */
1182
1183                         while (body->next != NULL)
1184                                 body = body->next;
1185                         continue;
1186                 }
1187
1188                 done = macro_or_word(mdoc, tok, line, la, pos, buf, p, parsed);
1189                 if (ac == ARGS_ALLOC)
1190                         free(p);
1191                 if (done)
1192                         break;
1193         }
1194
1195         if (blk->flags & NODE_VALID)
1196                 return;
1197         if (head == NULL)
1198                 head = roff_head_alloc(mdoc, line, ppos, tok);
1199         if (nl && tok != MDOC_Bd && tok != MDOC_Bl && tok != MDOC_Rs)
1200                 append_delims(mdoc, line, pos, buf);
1201         if (body != NULL)
1202                 goto out;
1203         if (find_pending(mdoc, tok, line, ppos, head))
1204                 return;
1205
1206         /* Close out scopes to remain in a consistent state. */
1207
1208         rew_last(mdoc, head);
1209         body = roff_body_alloc(mdoc, line, ppos, tok);
1210         if (tok == MDOC_Ss)
1211                 mdoc->flags &= ~ROFF_NONOFILL;
1212
1213         /*
1214          * Set up fill mode for display blocks.
1215          * This needs to be done here up front rather than during
1216          * validation such that child nodes get the right flags.
1217          */
1218
1219         if (tok == MDOC_Bd && arg != NULL) {
1220                 for (iarg = 0; iarg < arg->argc; iarg++) {
1221                         switch (arg->argv[iarg].arg) {
1222                         case MDOC_Unfilled:
1223                         case MDOC_Literal:
1224                                 mdoc->flags |= ROFF_NOFILL;
1225                                 break;
1226                         case MDOC_Filled:
1227                         case MDOC_Ragged:
1228                         case MDOC_Centred:
1229                                 mdoc->flags &= ~ROFF_NOFILL;
1230                                 break;
1231                         default:
1232                                 continue;
1233                         }
1234                         break;
1235                 }
1236         }
1237 out:
1238         if (mdoc->flags & MDOC_FREECOL) {
1239                 rew_last(mdoc, body);
1240                 rew_last(mdoc, blk);
1241                 mdoc->flags &= ~MDOC_FREECOL;
1242         }
1243 }
1244
1245 static void
1246 blk_part_imp(MACRO_PROT_ARGS)
1247 {
1248         int               done, la, nl;
1249         enum margserr     ac;
1250         char             *p;
1251         struct roff_node *blk; /* saved block context */
1252         struct roff_node *body; /* saved body context */
1253         struct roff_node *n;
1254
1255         nl = MDOC_NEWLINE & mdoc->flags;
1256
1257         /*
1258          * A macro that spans to the end of the line.  This is generally
1259          * (but not necessarily) called as the first macro.  The block
1260          * has a head as the immediate child, which is always empty,
1261          * followed by zero or more opening punctuation nodes, then the
1262          * body (which may be empty, depending on the macro), then zero
1263          * or more closing punctuation nodes.
1264          */
1265
1266         blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL);
1267         rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok));
1268
1269         /*
1270          * Open the body scope "on-demand", that is, after we've
1271          * processed all our the leading delimiters (open parenthesis,
1272          * etc.).
1273          */
1274
1275         for (body = NULL; ; ) {
1276                 la = *pos;
1277                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1278                 if (ac == ARGS_EOLN || ac == ARGS_PUNCT)
1279                         break;
1280
1281                 if (body == NULL && mdoc_isdelim(p) == DELIM_OPEN) {
1282                         dword(mdoc, line, la, p, DELIM_OPEN, 0);
1283                         if (ac == ARGS_ALLOC)
1284                                 free(p);
1285                         continue;
1286                 }
1287
1288                 if (body == NULL)
1289                         body = roff_body_alloc(mdoc, line, ppos, tok);
1290
1291                 done = macro_or_word(mdoc, tok, line, la, pos, buf, p, 1);
1292                 if (ac == ARGS_ALLOC)
1293                         free(p);
1294                 if (done)
1295                         break;
1296         }
1297         if (body == NULL)
1298                 body = roff_body_alloc(mdoc, line, ppos, tok);
1299
1300         if (find_pending(mdoc, tok, line, ppos, body))
1301                 return;
1302
1303         rew_last(mdoc, body);
1304         if (nl)
1305                 append_delims(mdoc, line, pos, buf);
1306         rew_pending(mdoc, blk);
1307
1308         /* Move trailing .Ns out of scope. */
1309
1310         for (n = body->child; n && n->next; n = n->next)
1311                 /* Do nothing. */ ;
1312         if (n && n->tok == MDOC_Ns)
1313                 roff_node_relink(mdoc, n);
1314 }
1315
1316 static void
1317 blk_part_exp(MACRO_PROT_ARGS)
1318 {
1319         int               done, la, nl;
1320         enum margserr     ac;
1321         struct roff_node *head; /* keep track of head */
1322         char             *p;
1323
1324         nl = MDOC_NEWLINE & mdoc->flags;
1325
1326         /*
1327          * The opening of an explicit macro having zero or more leading
1328          * punctuation nodes; a head with optional single element (the
1329          * case of `Eo'); and a body that may be empty.
1330          */
1331
1332         roff_block_alloc(mdoc, line, ppos, tok);
1333         head = NULL;
1334         for (;;) {
1335                 la = *pos;
1336                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1337                 if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
1338                         break;
1339
1340                 /* Flush out leading punctuation. */
1341
1342                 if (head == NULL && mdoc_isdelim(p) == DELIM_OPEN) {
1343                         dword(mdoc, line, la, p, DELIM_OPEN, 0);
1344                         if (ac == ARGS_ALLOC)
1345                                 free(p);
1346                         continue;
1347                 }
1348
1349                 if (head == NULL) {
1350                         head = roff_head_alloc(mdoc, line, ppos, tok);
1351                         if (tok == MDOC_Eo)  /* Not parsed. */
1352                                 dword(mdoc, line, la, p, DELIM_MAX, 0);
1353                         rew_last(mdoc, head);
1354                         roff_body_alloc(mdoc, line, ppos, tok);
1355                         if (tok == MDOC_Eo) {
1356                                 if (ac == ARGS_ALLOC)
1357                                         free(p);
1358                                 continue;
1359                         }
1360                 }
1361
1362                 done = macro_or_word(mdoc, tok, line, la, pos, buf, p, 1);
1363                 if (ac == ARGS_ALLOC)
1364                         free(p);
1365                 if (done)
1366                         break;
1367         }
1368
1369         /* Clean-up to leave in a consistent state. */
1370
1371         if (head == NULL) {
1372                 rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok));
1373                 roff_body_alloc(mdoc, line, ppos, tok);
1374         }
1375         if (nl)
1376                 append_delims(mdoc, line, pos, buf);
1377 }
1378
1379 static void
1380 in_line_argn(MACRO_PROT_ARGS)
1381 {
1382         struct mdoc_arg *arg;
1383         char            *p;
1384         enum margserr    ac;
1385         enum roff_tok    ntok;
1386         int              state; /* arg#; -1: not yet open; -2: closed */
1387         int              la, maxargs, nl;
1388
1389         nl = mdoc->flags & MDOC_NEWLINE;
1390
1391         /*
1392          * A line macro that has a fixed number of arguments (maxargs).
1393          * Only open the scope once the first non-leading-punctuation is
1394          * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then
1395          * keep it open until the maximum number of arguments are
1396          * exhausted.
1397          */
1398
1399         switch (tok) {
1400         case MDOC_Ap:
1401         case MDOC_Ns:
1402         case MDOC_Ux:
1403                 maxargs = 0;
1404                 break;
1405         case MDOC_Bx:
1406         case MDOC_Es:
1407         case MDOC_Xr:
1408                 maxargs = 2;
1409                 break;
1410         default:
1411                 maxargs = 1;
1412                 break;
1413         }
1414
1415         mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1416
1417         state = -1;
1418         p = NULL;
1419         for (;;) {
1420                 la = *pos;
1421                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1422
1423                 if ((ac == ARGS_WORD || ac == ARGS_ALLOC) && state == -1 &&
1424                     (mdoc_macro(tok)->flags & MDOC_IGNDELIM) == 0 &&
1425                     mdoc_isdelim(p) == DELIM_OPEN) {
1426                         dword(mdoc, line, la, p, DELIM_OPEN, 0);
1427                         if (ac == ARGS_ALLOC)
1428                                 free(p);
1429                         continue;
1430                 }
1431
1432                 if (state == -1 && tok != MDOC_In &&
1433                     tok != MDOC_St && tok != MDOC_Xr) {
1434                         mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
1435                         state = 0;
1436                 }
1437
1438                 if (ac == ARGS_PUNCT || ac == ARGS_EOLN) {
1439                         if (abs(state) < 2 && tok == MDOC_Pf)
1440                                 mandoc_msg(MANDOCERR_PF_SKIP,
1441                                     line, ppos, "Pf %s",
1442                                     p == NULL ? "at eol" : p);
1443                         break;
1444                 }
1445
1446                 if (state == maxargs) {
1447                         rew_elem(mdoc, tok);
1448                         state = -2;
1449                 }
1450
1451                 ntok = (tok == MDOC_Pf && state == 0) ?
1452                     TOKEN_NONE : lookup(mdoc, tok, line, la, p);
1453
1454                 if (ntok != TOKEN_NONE) {
1455                         if (state >= 0) {
1456                                 rew_elem(mdoc, tok);
1457                                 state = -2;
1458                         }
1459                         (*mdoc_macro(ntok)->fp)(mdoc, ntok,
1460                             line, la, pos, buf);
1461                         if (ac == ARGS_ALLOC)
1462                                 free(p);
1463                         break;
1464                 }
1465
1466                 if (mdoc_macro(tok)->flags & MDOC_IGNDELIM ||
1467                     mdoc_isdelim(p) == DELIM_NONE) {
1468                         if (state == -1) {
1469                                 mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
1470                                 state = 1;
1471                         } else if (state >= 0)
1472                                 state++;
1473                 } else if (state >= 0) {
1474                         rew_elem(mdoc, tok);
1475                         state = -2;
1476                 }
1477
1478                 dword(mdoc, line, la, p, DELIM_MAX,
1479                     mdoc_macro(tok)->flags & MDOC_JOIN);
1480                 if (ac == ARGS_ALLOC)
1481                         free(p);
1482                 p = mdoc->last->string;
1483         }
1484
1485         if (state == -1) {
1486                 mandoc_msg(MANDOCERR_MACRO_EMPTY,
1487                     line, ppos, "%s", roff_name[tok]);
1488                 return;
1489         }
1490
1491         if (state == 0 && tok == MDOC_Pf)
1492                 append_delims(mdoc, line, pos, buf);
1493         if (state >= 0)
1494                 rew_elem(mdoc, tok);
1495         if (nl)
1496                 append_delims(mdoc, line, pos, buf);
1497 }
1498
1499 static void
1500 in_line_eoln(MACRO_PROT_ARGS)
1501 {
1502         struct roff_node        *n;
1503         struct mdoc_arg         *arg;
1504
1505         if ((tok == MDOC_Pp || tok == MDOC_Lp) &&
1506             ! (mdoc->flags & MDOC_SYNOPSIS)) {
1507                 n = mdoc->last;
1508                 if (mdoc->next == ROFF_NEXT_SIBLING)
1509                         n = n->parent;
1510                 if (n->tok == MDOC_Nm)
1511                         rew_last(mdoc, n->parent);
1512         }
1513
1514         if (buf[*pos] == '\0' &&
1515             (tok == MDOC_Fd || *roff_name[tok] == '%')) {
1516                 mandoc_msg(MANDOCERR_MACRO_EMPTY,
1517                     line, ppos, "%s", roff_name[tok]);
1518                 return;
1519         }
1520
1521         mdoc_argv(mdoc, line, tok, &arg, pos, buf);
1522         mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
1523         if (parse_rest(mdoc, tok, line, pos, buf))
1524                 return;
1525         rew_elem(mdoc, tok);
1526 }
1527
1528 /*
1529  * The simplest argument parser available: Parse the remaining
1530  * words until the end of the phrase or line and return 0
1531  * or until the next macro, call that macro, and return 1.
1532  */
1533 static int
1534 parse_rest(struct roff_man *mdoc, enum roff_tok tok,
1535     int line, int *pos, char *buf)
1536 {
1537         char            *p;
1538         int              done, la;
1539         enum margserr    ac;
1540
1541         for (;;) {
1542                 la = *pos;
1543                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
1544                 if (ac == ARGS_EOLN)
1545                         return 0;
1546                 done = macro_or_word(mdoc, tok, line, la, pos, buf, p, 1);
1547                 if (ac == ARGS_ALLOC)
1548                         free(p);
1549                 if (done)
1550                         return 1;
1551         }
1552 }
1553
1554 static void
1555 ctx_synopsis(MACRO_PROT_ARGS)
1556 {
1557
1558         if (~mdoc->flags & (MDOC_SYNOPSIS | MDOC_NEWLINE))
1559                 in_line(mdoc, tok, line, ppos, pos, buf);
1560         else if (tok == MDOC_Nm)
1561                 blk_full(mdoc, tok, line, ppos, pos, buf);
1562         else {
1563                 assert(tok == MDOC_Vt);
1564                 blk_part_imp(mdoc, tok, line, ppos, pos, buf);
1565         }
1566 }
1567
1568 /*
1569  * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1570  * They're unusual because they're basically free-form text until a
1571  * macro is encountered.
1572  */
1573 static void
1574 phrase_ta(MACRO_PROT_ARGS)
1575 {
1576         struct roff_node *body, *n;
1577
1578         /* Make sure we are in a column list or ignore this macro. */
1579
1580         body = NULL;
1581         for (n = mdoc->last; n != NULL; n = n->parent) {
1582                 if (n->flags & NODE_ENDED)
1583                         continue;
1584                 if (n->tok == MDOC_It && n->type == ROFFT_BODY)
1585                         body = n;
1586                 if (n->tok == MDOC_Bl && n->end == ENDBODY_NOT)
1587                         break;
1588         }
1589
1590         if (n == NULL || n->norm->Bl.type != LIST_column) {
1591                 mandoc_msg(MANDOCERR_TA_STRAY, line, ppos, "Ta");
1592                 return;
1593         }
1594
1595         /* Advance to the next column. */
1596
1597         rew_last(mdoc, body);
1598         roff_body_alloc(mdoc, line, ppos, MDOC_It);
1599         parse_rest(mdoc, TOKEN_NONE, line, pos, buf);
1600 }