xref: /openbsd/usr.bin/mandoc/mdoc_macro.c (revision 17df1aa7)
1 /*	$Id: mdoc_macro.c,v 1.38 2010/05/14 19:52:43 schwarze Exp $ */
2 /*
3  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <assert.h>
18 #include <ctype.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <time.h>
23 
24 #include "libmdoc.h"
25 
26 enum	rew {
27 	REWIND_REWIND,
28 	REWIND_NOHALT,
29 	REWIND_HALT
30 };
31 
32 static	int	  	blk_full(MACRO_PROT_ARGS);
33 static	int	  	blk_exp_close(MACRO_PROT_ARGS);
34 static	int	  	blk_part_exp(MACRO_PROT_ARGS);
35 static	int	  	blk_part_imp(MACRO_PROT_ARGS);
36 static	int	  	ctx_synopsis(MACRO_PROT_ARGS);
37 static	int	  	in_line_eoln(MACRO_PROT_ARGS);
38 static	int	  	in_line_argn(MACRO_PROT_ARGS);
39 static	int	  	in_line(MACRO_PROT_ARGS);
40 static	int	  	obsolete(MACRO_PROT_ARGS);
41 
42 static	int	  	append_delims(struct mdoc *,
43 				int, int *, char *);
44 static	enum mdoct	lookup(enum mdoct, const char *);
45 static	enum mdoct	lookup_raw(const char *);
46 static	int	  	phrase(struct mdoc *, int, int,
47 				char *, enum margserr, int);
48 static	enum mdoct 	rew_alt(enum mdoct);
49 static	int	  	rew_dobreak(enum mdoct,
50 				const struct mdoc_node *);
51 static	enum rew  	rew_dohalt(enum mdoct, enum mdoc_type,
52 				const struct mdoc_node *);
53 static	int	  	rew_elem(struct mdoc *, enum mdoct);
54 static	int	  	rew_last(struct mdoc *,
55 				const struct mdoc_node *);
56 static	int	  	rew_sub(enum mdoc_type, struct mdoc *,
57 				enum mdoct, int, int);
58 static	int	  	swarn(struct mdoc *, enum mdoc_type, int,
59 				int, const struct mdoc_node *);
60 
61 const	struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
62 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */
63 	{ in_line_eoln, MDOC_PROLOGUE }, /* Dd */
64 	{ in_line_eoln, MDOC_PROLOGUE }, /* Dt */
65 	{ in_line_eoln, MDOC_PROLOGUE }, /* Os */
66 	{ blk_full, 0 }, /* Sh */
67 	{ blk_full, 0 }, /* Ss */
68 	{ in_line_eoln, 0 }, /* Pp */
69 	{ blk_part_imp, MDOC_PARSED }, /* D1 */
70 	{ blk_part_imp, MDOC_PARSED }, /* Dl */
71 	{ blk_full, MDOC_EXPLICIT }, /* Bd */
72 	{ blk_exp_close, MDOC_EXPLICIT }, /* Ed */
73 	{ blk_full, MDOC_EXPLICIT }, /* Bl */
74 	{ blk_exp_close, MDOC_EXPLICIT }, /* El */
75 	{ blk_full, MDOC_PARSED }, /* It */
76 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
77 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */
78 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
79 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */
80 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
81 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
82 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
83 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */
84 	{ in_line_eoln, 0 }, /* Ex */
85 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */
86 	{ in_line_eoln, 0 }, /* Fd */
87 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
88 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
89 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
90 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */
91 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
92 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */
93 	{ blk_full, 0 }, /* Nd */
94 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
95 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
96 	{ obsolete, 0 }, /* Ot */
97 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
98 	{ in_line_eoln, 0 }, /* Rv */
99 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
100 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
101 	{ ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
102 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
103 	{ in_line_eoln, 0 }, /* %A */
104 	{ in_line_eoln, 0 }, /* %B */
105 	{ in_line_eoln, 0 }, /* %D */
106 	{ in_line_eoln, 0 }, /* %I */
107 	{ in_line_eoln, 0 }, /* %J */
108 	{ in_line_eoln, 0 }, /* %N */
109 	{ in_line_eoln, 0 }, /* %O */
110 	{ in_line_eoln, 0 }, /* %P */
111 	{ in_line_eoln, 0 }, /* %R */
112 	{ in_line_eoln, 0 }, /* %T */
113 	{ in_line_eoln, 0 }, /* %V */
114 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */
115 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */
116 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */
117 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */
118 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */
119 	{ blk_full, MDOC_EXPLICIT }, /* Bf */
120 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */
121 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */
122 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */
123 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */
124 	{ in_line_eoln, 0 }, /* Db */
125 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */
126 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */
127 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */
128 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */
129 	{ blk_exp_close, MDOC_EXPLICIT }, /* Ef */
130 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */
131 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */
132 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */
133 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */
134 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* No */
135 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ns */
136 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */
137 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */
138 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */
139 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */
140 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */
141 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */
142 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */
143 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */
144 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */
145 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */
146 	{ blk_exp_close, MDOC_EXPLICIT }, /* Re */
147 	{ blk_full, MDOC_EXPLICIT }, /* Rs */
148 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */
149 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */
150 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */
151 	{ in_line_eoln, 0 }, /* Sm */
152 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */
153 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */
154 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */
155 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */
156 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */
157 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */
158 	{ blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */
159 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */
160 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */
161 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */
162 	{ blk_full, MDOC_EXPLICIT }, /* Bk */
163 	{ blk_exp_close, MDOC_EXPLICIT }, /* Ek */
164 	{ in_line_eoln, 0 }, /* Bt */
165 	{ in_line_eoln, 0 }, /* Hf */
166 	{ obsolete, 0 }, /* Fr */
167 	{ in_line_eoln, 0 }, /* Ud */
168 	{ in_line_eoln, 0 }, /* Lb */
169 	{ in_line_eoln, 0 }, /* Lp */
170 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */
171 	{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */
172 	{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */
173 	{ blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */
174 	{ blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */
175 	{ in_line_eoln, 0 }, /* %C */
176 	{ obsolete, 0 }, /* Es */
177 	{ obsolete, 0 }, /* En */
178 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
179 	{ in_line_eoln, 0 }, /* %Q */
180 	{ in_line_eoln, 0 }, /* br */
181 	{ in_line_eoln, 0 }, /* sp */
182 	{ in_line_eoln, 0 }, /* %U */
183 };
184 
185 const	struct mdoc_macro * const mdoc_macros = __mdoc_macros;
186 
187 
188 static int
189 swarn(struct mdoc *mdoc, enum mdoc_type type,
190 		int line, int pos, const struct mdoc_node *p)
191 {
192 	const char	*n, *t, *tt;
193 
194 	n = t = "<root>";
195 	tt = "block";
196 
197 	switch (type) {
198 	case (MDOC_BODY):
199 		tt = "multi-line";
200 		break;
201 	case (MDOC_HEAD):
202 		tt = "line";
203 		break;
204 	default:
205 		break;
206 	}
207 
208 	switch (p->type) {
209 	case (MDOC_BLOCK):
210 		n = mdoc_macronames[p->tok];
211 		t = "block";
212 		break;
213 	case (MDOC_BODY):
214 		n = mdoc_macronames[p->tok];
215 		t = "multi-line";
216 		break;
217 	case (MDOC_HEAD):
218 		n = mdoc_macronames[p->tok];
219 		t = "line";
220 		break;
221 	default:
222 		break;
223 	}
224 
225 	if ( ! (MDOC_IGN_SCOPE & mdoc->pflags))
226 		return(mdoc_verr(mdoc, line, pos,
227 				"%s scope breaks %s scope of %s",
228 				tt, t, n));
229 	return(mdoc_vwarn(mdoc, line, pos,
230 				"%s scope breaks %s scope of %s",
231 				tt, t, n));
232 }
233 
234 
235 /*
236  * This is called at the end of parsing.  It must traverse up the tree,
237  * closing out open [implicit] scopes.  Obviously, open explicit scopes
238  * are errors.
239  */
240 int
241 mdoc_macroend(struct mdoc *m)
242 {
243 	struct mdoc_node *n;
244 
245 	/* Scan for open explicit scopes. */
246 
247 	n = MDOC_VALID & m->last->flags ?  m->last->parent : m->last;
248 
249 	for ( ; n; n = n->parent) {
250 		if (MDOC_BLOCK != n->type)
251 			continue;
252 		if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags))
253 			continue;
254 		return(mdoc_nerr(m, n, EOPEN));
255 	}
256 
257 	/* Rewind to the first. */
258 
259 	return(rew_last(m, m->first));
260 }
261 
262 
263 /*
264  * Look up a macro from within a subsequent context.
265  */
266 static enum mdoct
267 lookup(enum mdoct from, const char *p)
268 {
269 	/* FIXME: make -diag lists be un-PARSED. */
270 
271 	if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
272 		return(MDOC_MAX);
273 	return(lookup_raw(p));
274 }
275 
276 
277 /*
278  * Lookup a macro following the initial line macro.
279  */
280 static enum mdoct
281 lookup_raw(const char *p)
282 {
283 	enum mdoct	 res;
284 
285 	if (MDOC_MAX == (res = mdoc_hash_find(p)))
286 		return(MDOC_MAX);
287 	if (MDOC_CALLABLE & mdoc_macros[res].flags)
288 		return(res);
289 	return(MDOC_MAX);
290 }
291 
292 
293 static int
294 rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
295 {
296 
297 	assert(to);
298 	mdoc->next = MDOC_NEXT_SIBLING;
299 
300 	/* LINTED */
301 	while (mdoc->last != to) {
302 		if ( ! mdoc_valid_post(mdoc))
303 			return(0);
304 		if ( ! mdoc_action_post(mdoc))
305 			return(0);
306 		mdoc->last = mdoc->last->parent;
307 		assert(mdoc->last);
308 	}
309 
310 	if ( ! mdoc_valid_post(mdoc))
311 		return(0);
312 	return(mdoc_action_post(mdoc));
313 }
314 
315 
316 /*
317  * Return the opening macro of a closing one, e.g., `Ec' has `Eo' as its
318  * matching pair.
319  */
320 static enum mdoct
321 rew_alt(enum mdoct tok)
322 {
323 	switch (tok) {
324 	case (MDOC_Ac):
325 		return(MDOC_Ao);
326 	case (MDOC_Bc):
327 		return(MDOC_Bo);
328 	case (MDOC_Brc):
329 		return(MDOC_Bro);
330 	case (MDOC_Dc):
331 		return(MDOC_Do);
332 	case (MDOC_Ec):
333 		return(MDOC_Eo);
334 	case (MDOC_Ed):
335 		return(MDOC_Bd);
336 	case (MDOC_Ef):
337 		return(MDOC_Bf);
338 	case (MDOC_Ek):
339 		return(MDOC_Bk);
340 	case (MDOC_El):
341 		return(MDOC_Bl);
342 	case (MDOC_Fc):
343 		return(MDOC_Fo);
344 	case (MDOC_Oc):
345 		return(MDOC_Oo);
346 	case (MDOC_Pc):
347 		return(MDOC_Po);
348 	case (MDOC_Qc):
349 		return(MDOC_Qo);
350 	case (MDOC_Re):
351 		return(MDOC_Rs);
352 	case (MDOC_Sc):
353 		return(MDOC_So);
354 	case (MDOC_Xc):
355 		return(MDOC_Xo);
356 	default:
357 		break;
358 	}
359 	abort();
360 	/* NOTREACHED */
361 }
362 
363 
364 /*
365  * Rewind rules.  This indicates whether to stop rewinding
366  * (REWIND_HALT) without touching our current scope, stop rewinding and
367  * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
368  * The scope-closing and so on occurs in the various rew_* routines.
369  */
370 static enum rew
371 rew_dohalt(enum mdoct tok, enum mdoc_type type,
372 		const struct mdoc_node *p)
373 {
374 
375 	if (MDOC_ROOT == p->type)
376 		return(REWIND_HALT);
377 	if (MDOC_VALID & p->flags)
378 		return(REWIND_NOHALT);
379 
380 	switch (tok) {
381 	case (MDOC_Aq):
382 		/* FALLTHROUGH */
383 	case (MDOC_Bq):
384 		/* FALLTHROUGH */
385 	case (MDOC_Brq):
386 		/* FALLTHROUGH */
387 	case (MDOC_D1):
388 		/* FALLTHROUGH */
389 	case (MDOC_Dl):
390 		/* FALLTHROUGH */
391 	case (MDOC_Dq):
392 		/* FALLTHROUGH */
393 	case (MDOC_Op):
394 		/* FALLTHROUGH */
395 	case (MDOC_Pq):
396 		/* FALLTHROUGH */
397 	case (MDOC_Ql):
398 		/* FALLTHROUGH */
399 	case (MDOC_Qq):
400 		/* FALLTHROUGH */
401 	case (MDOC_Sq):
402 		/* FALLTHROUGH */
403 	case (MDOC_Vt):
404 		assert(MDOC_TAIL != type);
405 		if (type == p->type && tok == p->tok)
406 			return(REWIND_REWIND);
407 		break;
408 	case (MDOC_It):
409 		assert(MDOC_TAIL != type);
410 		if (type == p->type && tok == p->tok)
411 			return(REWIND_REWIND);
412 		if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
413 			return(REWIND_HALT);
414 		break;
415 	case (MDOC_Sh):
416 		if (type == p->type && tok == p->tok)
417 			return(REWIND_REWIND);
418 		break;
419 	case (MDOC_Nd):
420 		/* FALLTHROUGH */
421 	case (MDOC_Ss):
422 		assert(MDOC_TAIL != type);
423 		if (type == p->type && tok == p->tok)
424 			return(REWIND_REWIND);
425 		if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
426 			return(REWIND_HALT);
427 		break;
428 	case (MDOC_Ao):
429 		/* FALLTHROUGH */
430 	case (MDOC_Bd):
431 		/* FALLTHROUGH */
432 	case (MDOC_Bf):
433 		/* FALLTHROUGH */
434 	case (MDOC_Bk):
435 		/* FALLTHROUGH */
436 	case (MDOC_Bl):
437 		/* FALLTHROUGH */
438 	case (MDOC_Bo):
439 		/* FALLTHROUGH */
440 	case (MDOC_Bro):
441 		/* FALLTHROUGH */
442 	case (MDOC_Do):
443 		/* FALLTHROUGH */
444 	case (MDOC_Eo):
445 		/* FALLTHROUGH */
446 	case (MDOC_Fo):
447 		/* FALLTHROUGH */
448 	case (MDOC_Oo):
449 		/* FALLTHROUGH */
450 	case (MDOC_Po):
451 		/* FALLTHROUGH */
452 	case (MDOC_Qo):
453 		/* FALLTHROUGH */
454 	case (MDOC_Rs):
455 		/* FALLTHROUGH */
456 	case (MDOC_So):
457 		/* FALLTHROUGH */
458 	case (MDOC_Xo):
459 		if (type == p->type && tok == p->tok)
460 			return(REWIND_REWIND);
461 		break;
462 	/* Multi-line explicit scope close. */
463 	case (MDOC_Ac):
464 		/* FALLTHROUGH */
465 	case (MDOC_Bc):
466 		/* FALLTHROUGH */
467 	case (MDOC_Brc):
468 		/* FALLTHROUGH */
469 	case (MDOC_Dc):
470 		/* FALLTHROUGH */
471 	case (MDOC_Ec):
472 		/* FALLTHROUGH */
473 	case (MDOC_Ed):
474 		/* FALLTHROUGH */
475 	case (MDOC_Ek):
476 		/* FALLTHROUGH */
477 	case (MDOC_El):
478 		/* FALLTHROUGH */
479 	case (MDOC_Fc):
480 		/* FALLTHROUGH */
481 	case (MDOC_Ef):
482 		/* FALLTHROUGH */
483 	case (MDOC_Oc):
484 		/* FALLTHROUGH */
485 	case (MDOC_Pc):
486 		/* FALLTHROUGH */
487 	case (MDOC_Qc):
488 		/* FALLTHROUGH */
489 	case (MDOC_Re):
490 		/* FALLTHROUGH */
491 	case (MDOC_Sc):
492 		/* FALLTHROUGH */
493 	case (MDOC_Xc):
494 		if (type == p->type && rew_alt(tok) == p->tok)
495 			return(REWIND_REWIND);
496 		break;
497 	default:
498 		abort();
499 		/* NOTREACHED */
500 	}
501 
502 	return(REWIND_NOHALT);
503 }
504 
505 
506 /*
507  * See if we can break an encountered scope (the rew_dohalt has returned
508  * REWIND_NOHALT).
509  */
510 static int
511 rew_dobreak(enum mdoct tok, const struct mdoc_node *p)
512 {
513 
514 	assert(MDOC_ROOT != p->type);
515 	if (MDOC_ELEM == p->type)
516 		return(1);
517 	if (MDOC_TEXT == p->type)
518 		return(1);
519 	if (MDOC_VALID & p->flags)
520 		return(1);
521 
522 	switch (tok) {
523 	case (MDOC_It):
524 		return(MDOC_It == p->tok);
525 	case (MDOC_Nd):
526 		return(MDOC_Nd == p->tok);
527 	case (MDOC_Ss):
528 		return(MDOC_Ss == p->tok);
529 	case (MDOC_Sh):
530 		if (MDOC_Nd == p->tok)
531 			return(1);
532 		if (MDOC_Ss == p->tok)
533 			return(1);
534 		return(MDOC_Sh == p->tok);
535 	case (MDOC_El):
536 		if (MDOC_It == p->tok)
537 			return(1);
538 		break;
539 	case (MDOC_Oc):
540 		if (MDOC_Op == p->tok)
541 			return(1);
542 		break;
543 	default:
544 		break;
545 	}
546 
547 	if (MDOC_EXPLICIT & mdoc_macros[tok].flags)
548 		return(p->tok == rew_alt(tok));
549 	else if (MDOC_BLOCK == p->type)
550 		return(1);
551 
552 	return(tok == p->tok);
553 }
554 
555 
556 static int
557 rew_elem(struct mdoc *mdoc, enum mdoct tok)
558 {
559 	struct mdoc_node *n;
560 
561 	n = mdoc->last;
562 	if (MDOC_ELEM != n->type)
563 		n = n->parent;
564 	assert(MDOC_ELEM == n->type);
565 	assert(tok == n->tok);
566 
567 	return(rew_last(mdoc, n));
568 }
569 
570 
571 static int
572 rew_sub(enum mdoc_type t, struct mdoc *m,
573 		enum mdoct tok, int line, int ppos)
574 {
575 	struct mdoc_node *n;
576 	enum rew	  c;
577 
578 	/* LINTED */
579 	for (n = m->last; n; n = n->parent) {
580 		c = rew_dohalt(tok, t, n);
581 		if (REWIND_HALT == c) {
582 			if (MDOC_BLOCK != t)
583 				return(1);
584 			if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
585 				return(1);
586 			return(mdoc_perr(m, line, ppos, ENOCTX));
587 		}
588 		if (REWIND_REWIND == c)
589 			break;
590 		else if (rew_dobreak(tok, n))
591 			continue;
592 		if ( ! swarn(m, t, line, ppos, n))
593 			return(0);
594 	}
595 
596 	assert(n);
597 	if ( ! rew_last(m, n))
598 		return(0);
599 
600 	/*
601 	 * The current block extends an enclosing block beyond a line
602 	 * break.  Now that the current block ends, close the enclosing
603 	 * block, too.
604 	 */
605 	if (NULL != (n = n->pending)) {
606 		assert(MDOC_HEAD == n->type);
607 		if ( ! rew_last(m, n))
608 			return(0);
609 		if ( ! mdoc_body_alloc(m, n->line, n->pos, n->tok))
610 			return(0);
611 	}
612 	return(1);
613 }
614 
615 
616 static int
617 append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
618 {
619 	int		 lastarg;
620 	enum margserr	 ac;
621 	char		*p;
622 
623 	if (0 == buf[*pos])
624 		return(1);
625 
626 	for (;;) {
627 		lastarg = *pos;
628 		ac = mdoc_zargs(mdoc, line, pos, buf, ARGS_NOWARN, &p);
629 
630 		if (ARGS_ERROR == ac)
631 			return(0);
632 		else if (ARGS_EOLN == ac)
633 			break;
634 		assert(mdoc_isdelim(p));
635 		if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
636 			return(0);
637 	}
638 
639 	return(1);
640 }
641 
642 
643 /*
644  * Close out block partial/full explicit.
645  */
646 static int
647 blk_exp_close(MACRO_PROT_ARGS)
648 {
649 	int	 	 j, lastarg, maxargs, flushed, nl;
650 	enum margserr	 ac;
651 	enum mdoct	 ntok;
652 	char		*p;
653 
654 	nl = MDOC_NEWLINE & m->flags;
655 
656 	switch (tok) {
657 	case (MDOC_Ec):
658 		maxargs = 1;
659 		break;
660 	default:
661 		maxargs = 0;
662 		break;
663 	}
664 
665 	if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
666 		if (buf[*pos])
667 			if ( ! mdoc_pwarn(m, line, ppos, ENOLINE))
668 				return(0);
669 
670 		if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
671 			return(0);
672 		return(rew_sub(MDOC_BLOCK, m, tok, line, ppos));
673 	}
674 
675 	if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
676 		return(0);
677 
678 	if (maxargs > 0)
679 		if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok)))
680 			return(0);
681 
682 	for (flushed = j = 0; ; j++) {
683 		lastarg = *pos;
684 
685 		if (j == maxargs && ! flushed) {
686 			if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
687 				return(0);
688 			flushed = 1;
689 		}
690 
691 		ac = mdoc_args(m, line, pos, buf, tok, &p);
692 
693 		if (ARGS_ERROR == ac)
694 			return(0);
695 		if (ARGS_PUNCT == ac)
696 			break;
697 		if (ARGS_EOLN == ac)
698 			break;
699 
700 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
701 
702 		if (MDOC_MAX == ntok) {
703 			if ( ! mdoc_word_alloc(m, line, lastarg, p))
704 				return(0);
705 			continue;
706 		}
707 
708 		if ( ! flushed) {
709 			if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
710 				return(0);
711 			flushed = 1;
712 		}
713 		if ( ! mdoc_macro(m, ntok, line, lastarg, pos, buf))
714 			return(0);
715 		break;
716 	}
717 
718 	if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
719 		return(0);
720 
721 	if ( ! nl)
722 		return(1);
723 	return(append_delims(m, line, pos, buf));
724 }
725 
726 
727 static int
728 in_line(MACRO_PROT_ARGS)
729 {
730 	int		 la, lastpunct, cnt, d, nc, nl;
731 	enum margverr	 av;
732 	enum mdoct	 ntok;
733 	enum margserr	 ac;
734 	struct mdoc_arg	*arg;
735 	char		*p;
736 
737 	nl = MDOC_NEWLINE & m->flags;
738 
739 	/*
740 	 * Whether we allow ignored elements (those without content,
741 	 * usually because of reserved words) to squeak by.
742 	 */
743 
744 	switch (tok) {
745 	case (MDOC_An):
746 		/* FALLTHROUGH */
747 	case (MDOC_Ar):
748 		/* FALLTHROUGH */
749 	case (MDOC_Fl):
750 		/* FALLTHROUGH */
751 	case (MDOC_Lk):
752 		/* FALLTHROUGH */
753 	case (MDOC_Nm):
754 		/* FALLTHROUGH */
755 	case (MDOC_Pa):
756 		nc = 1;
757 		break;
758 	default:
759 		nc = 0;
760 		break;
761 	}
762 
763 	for (arg = NULL;; ) {
764 		la = *pos;
765 		av = mdoc_argv(m, line, tok, &arg, pos, buf);
766 
767 		if (ARGV_WORD == av) {
768 			*pos = la;
769 			break;
770 		}
771 		if (ARGV_EOLN == av)
772 			break;
773 		if (ARGV_ARG == av)
774 			continue;
775 
776 		mdoc_argv_free(arg);
777 		return(0);
778 	}
779 
780 	for (cnt = 0, lastpunct = 1;; ) {
781 		la = *pos;
782 		ac = mdoc_args(m, line, pos, buf, tok, &p);
783 
784 		if (ARGS_ERROR == ac)
785 			return(0);
786 		if (ARGS_EOLN == ac)
787 			break;
788 		if (ARGS_PUNCT == ac)
789 			break;
790 
791 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
792 
793 		/*
794 		 * In this case, we've located a submacro and must
795 		 * execute it.  Close out scope, if open.  If no
796 		 * elements have been generated, either create one (nc)
797 		 * or raise a warning.
798 		 */
799 
800 		if (MDOC_MAX != ntok) {
801 			if (0 == lastpunct && ! rew_elem(m, tok))
802 				return(0);
803 			if (nc && 0 == cnt) {
804 				if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
805 					return(0);
806 				if ( ! rew_last(m, m->last))
807 					return(0);
808 			} else if ( ! nc && 0 == cnt) {
809 				mdoc_argv_free(arg);
810 				if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
811 					return(0);
812 			}
813 			if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
814 				return(0);
815 			if ( ! nl)
816 				return(1);
817 			return(append_delims(m, line, pos, buf));
818 		}
819 
820 		/*
821 		 * Non-quote-enclosed punctuation.  Set up our scope, if
822 		 * a word; rewind the scope, if a delimiter; then append
823 		 * the word.
824 		 */
825 
826 		d = ARGS_QWORD == ac ? 0 : mdoc_isdelim(p);
827 
828 		if (ARGS_QWORD != ac && d) {
829 			if (0 == lastpunct && ! rew_elem(m, tok))
830 				return(0);
831 			lastpunct = 1;
832 		} else if (lastpunct) {
833 			if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
834 				return(0);
835 			lastpunct = 0;
836 		}
837 
838 		if ( ! d)
839 			cnt++;
840 		if ( ! mdoc_word_alloc(m, line, la, p))
841 			return(0);
842 
843 		/*
844 		 * `Fl' macros have their scope re-opened with each new
845 		 * word so that the `-' can be added to each one without
846 		 * having to parse out spaces.
847 		 */
848 		if (0 == lastpunct && MDOC_Fl == tok) {
849 			if ( ! rew_elem(m, tok))
850 				return(0);
851 			lastpunct = 1;
852 		}
853 	}
854 
855 	if (0 == lastpunct && ! rew_elem(m, tok))
856 		return(0);
857 
858 	/*
859 	 * If no elements have been collected and we're allowed to have
860 	 * empties (nc), open a scope and close it out.  Otherwise,
861 	 * raise a warning.
862 	 */
863 
864 	if (nc && 0 == cnt) {
865 		if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
866 			return(0);
867 		if ( ! rew_last(m, m->last))
868 			return(0);
869 	} else if ( ! nc && 0 == cnt) {
870 		mdoc_argv_free(arg);
871 		if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
872 			return(0);
873 	}
874 
875 	if ( ! nl)
876 		return(1);
877 	return(append_delims(m, line, pos, buf));
878 }
879 
880 
881 static int
882 blk_full(MACRO_PROT_ARGS)
883 {
884 	int		  la, pcnt;
885 	struct mdoc_arg	 *arg;
886 	struct mdoc_node *head; /* save of head macro */
887 	struct mdoc_node *body; /* save of body macro */
888 	struct mdoc_node *n;
889 	enum mdoct	  ntok;
890 	enum margserr	  ac, lac;
891 	enum margverr	  av;
892 	char		 *p;
893 
894 	/* Close out prior implicit scope. */
895 
896 	if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
897 		if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
898 			return(0);
899 		if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
900 			return(0);
901 	}
902 
903 	/*
904 	 * This routine accomodates implicitly- and explicitly-scoped
905 	 * macro openings.  Implicit ones first close out prior scope
906 	 * (seen above).  Delay opening the head until necessary to
907 	 * allow leading punctuation to print.  Special consideration
908 	 * for `It -column', which has phrase-part syntax instead of
909 	 * regular child nodes.
910 	 */
911 
912 	for (arg = NULL;; ) {
913 		la = *pos;
914 		av = mdoc_argv(m, line, tok, &arg, pos, buf);
915 
916 		if (ARGV_WORD == av) {
917 			*pos = la;
918 			break;
919 		}
920 
921 		if (ARGV_EOLN == av)
922 			break;
923 		if (ARGV_ARG == av)
924 			continue;
925 
926 		mdoc_argv_free(arg);
927 		return(0);
928 	}
929 
930 	if ( ! mdoc_block_alloc(m, line, ppos, tok, arg))
931 		return(0);
932 
933 	head = body = NULL;
934 
935 	/*
936 	 * The `Nd' macro has all arguments in its body: it's a hybrid
937 	 * of block partial-explicit and full-implicit.  Stupid.
938 	 */
939 
940 	if (MDOC_Nd == tok) {
941 		if ( ! mdoc_head_alloc(m, line, ppos, tok))
942 			return(0);
943 		head = m->last;
944 		if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
945 			return(0);
946 		if ( ! mdoc_body_alloc(m, line, ppos, tok))
947 			return(0);
948 		body = m->last;
949 	}
950 
951 	ac = ARGS_ERROR;
952 
953 	for (pcnt = 0; ; ) {
954 		la = *pos;
955 		lac = ac;
956 		ac = mdoc_args(m, line, pos, buf, tok, &p);
957 
958 		if (ARGS_ERROR == ac)
959 			return(0);
960 		if (ARGS_EOLN == ac)
961 			break;
962 
963 /*
964  * XXX Temporarily disable the handling of leading punctuation.
965  *     We must investigate the fallout before enabling this.
966  */
967 #if 0
968 		/* Don't emit leading punct. for phrases. */
969 
970 		if (NULL == head &&
971 				ARGS_PHRASE != ac &&
972 				ARGS_PPHRASE != ac &&
973 				ARGS_PEND != ac &&
974 				ARGS_QWORD != ac &&
975 				1 == mdoc_isdelim(p)) {
976 			if ( ! mdoc_word_alloc(m, line, la, p))
977 				return(0);
978 			continue;
979 		}
980 #endif
981 
982 		/* Always re-open head for phrases. */
983 
984 		if (NULL == head ||
985 				ARGS_PHRASE == ac ||
986 				ARGS_PEND == ac ||
987 				ARGS_PPHRASE == ac) {
988 			if ( ! mdoc_head_alloc(m, line, ppos, tok))
989 				return(0);
990 			head = m->last;
991 		}
992 
993 		if (ARGS_PHRASE == ac ||
994 				ARGS_PEND == ac ||
995 				ARGS_PPHRASE == ac) {
996 			/*
997 			 * Special treatment for the last phrase.  A
998 			 * prior ARGS_PHRASE gets is handled as a
999 			 * regular ARGS_PHRASE, but a prior ARGS_PPHRASE
1000 			 * has special handling.
1001 			 */
1002 			if (ARGS_PEND == ac && ARGS_ERROR == lac)
1003 				ac = ARGS_PHRASE;
1004 			else if (ARGS_PEND == ac && ARGS_PHRASE == lac)
1005 				ac = ARGS_PHRASE;
1006 
1007 			if ( ! phrase(m, line, la, buf, ac, pcnt++))
1008 				return(0);
1009 			if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1010 				return(0);
1011 			continue;
1012 		}
1013 
1014 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1015 
1016 		if (MDOC_MAX == ntok) {
1017 			if ( ! mdoc_word_alloc(m, line, la, p))
1018 				return(0);
1019 			continue;
1020 		}
1021 
1022 		if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
1023 			return(0);
1024 		break;
1025 	}
1026 
1027 	if (NULL == head) {
1028 		if ( ! mdoc_head_alloc(m, line, ppos, tok))
1029 			return(0);
1030 		head = m->last;
1031 	}
1032 
1033 	if (1 == ppos && ! append_delims(m, line, pos, buf))
1034 		return(0);
1035 
1036 	/* If we've already opened our body, exit now. */
1037 
1038 	if (NULL != body)
1039 		return(1);
1040 
1041 	/*
1042 	 * If there is an open (i.e., unvalidated) sub-block requiring
1043 	 * explicit close-out, postpone switching the current block from
1044 	 * head to body until the rew_sub() call closing out that
1045 	 * sub-block.
1046 	 */
1047 	for (n = m->last; n && n != head; n = n->parent) {
1048 		if (MDOC_BLOCK == n->type &&
1049 				MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
1050 				! (MDOC_VALID & n->flags)) {
1051 			assert( ! (MDOC_ACTED & n->flags));
1052 			n->pending = head;
1053 			return(1);
1054 		}
1055 	}
1056 	/* Close out scopes to remain in a consistent state. */
1057 
1058 	if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1059 		return(0);
1060 	if ( ! mdoc_body_alloc(m, line, ppos, tok))
1061 		return(0);
1062 
1063 	return(1);
1064 }
1065 
1066 
1067 static int
1068 blk_part_imp(MACRO_PROT_ARGS)
1069 {
1070 	int		  la;
1071 	enum mdoct	  ntok;
1072 	enum margserr	  ac;
1073 	char		 *p;
1074 	struct mdoc_node *blk; /* saved block context */
1075 	struct mdoc_node *body; /* saved body context */
1076 	struct mdoc_node *n;
1077 
1078 	/*
1079 	 * A macro that spans to the end of the line.  This is generally
1080 	 * (but not necessarily) called as the first macro.  The block
1081 	 * has a head as the immediate child, which is always empty,
1082 	 * followed by zero or more opening punctuation nodes, then the
1083 	 * body (which may be empty, depending on the macro), then zero
1084 	 * or more closing punctuation nodes.
1085 	 */
1086 
1087 	if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL))
1088 		return(0);
1089 
1090 	blk = m->last;
1091 
1092 	if ( ! mdoc_head_alloc(m, line, ppos, tok))
1093 		return(0);
1094 	if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1095 		return(0);
1096 
1097 	/*
1098 	 * Open the body scope "on-demand", that is, after we've
1099 	 * processed all our the leading delimiters (open parenthesis,
1100 	 * etc.).
1101 	 */
1102 
1103 	for (body = NULL; ; ) {
1104 		la = *pos;
1105 		ac = mdoc_args(m, line, pos, buf, tok, &p);
1106 
1107 		if (ARGS_ERROR == ac)
1108 			return(0);
1109 		if (ARGS_EOLN == ac)
1110 			break;
1111 		if (ARGS_PUNCT == ac)
1112 			break;
1113 
1114 /*
1115  * XXX Temporarily disable the handling of leading punctuation.
1116  *     We must investigate the fallout before enabling this.
1117  */
1118 #if 0
1119 		if (NULL == body && ARGS_QWORD != ac &&
1120 				1 == mdoc_isdelim(p)) {
1121 			if ( ! mdoc_word_alloc(m, line, la, p))
1122 				return(0);
1123 			continue;
1124 		}
1125 #endif
1126 
1127 		if (NULL == body) {
1128 		       if ( ! mdoc_body_alloc(m, line, ppos, tok))
1129 			       return(0);
1130 			body = m->last;
1131 		}
1132 
1133 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1134 
1135 		if (MDOC_MAX == ntok) {
1136 			if ( ! mdoc_word_alloc(m, line, la, p))
1137 				return(0);
1138 			continue;
1139 		}
1140 
1141 		if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
1142 			return(0);
1143 		break;
1144 	}
1145 
1146 	/* Clean-ups to leave in a consistent state. */
1147 
1148 	if (NULL == body) {
1149 		if ( ! mdoc_body_alloc(m, line, ppos, tok))
1150 			return(0);
1151 		body = m->last;
1152 	}
1153 
1154 	/*
1155 	 * If we can't rewind to our body, then our scope has already
1156 	 * been closed by another macro (like `Oc' closing `Op').  This
1157 	 * is ugly behaviour nodding its head to OpenBSD's overwhelming
1158 	 * crufty use of `Op' breakage.
1159 	 */
1160 	for (n = m->last; n; n = n->parent)
1161 		if (body == n)
1162 			break;
1163 
1164 	if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK))
1165 		return(0);
1166 
1167 	if (n && ! rew_last(m, body))
1168 		return(0);
1169 
1170 	/* Standard appending of delimiters. */
1171 
1172 	if (1 == ppos && ! append_delims(m, line, pos, buf))
1173 		return(0);
1174 
1175 	/* Rewind scope, if applicable. */
1176 
1177 	if (n && ! rew_last(m, blk))
1178 		return(0);
1179 
1180 	return(1);
1181 }
1182 
1183 
1184 static int
1185 blk_part_exp(MACRO_PROT_ARGS)
1186 {
1187 	int		  la, nl;
1188 	enum margserr	  ac;
1189 	struct mdoc_node *head; /* keep track of head */
1190 	struct mdoc_node *body; /* keep track of body */
1191 	char		 *p;
1192 	enum mdoct	  ntok;
1193 
1194 	nl = MDOC_NEWLINE & m->flags;
1195 
1196 	/*
1197 	 * The opening of an explicit macro having zero or more leading
1198 	 * punctuation nodes; a head with optional single element (the
1199 	 * case of `Eo'); and a body that may be empty.
1200 	 */
1201 
1202 	if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL))
1203 		return(0);
1204 
1205 	for (head = body = NULL; ; ) {
1206 		la = *pos;
1207 		ac = mdoc_args(m, line, pos, buf, tok, &p);
1208 
1209 		if (ARGS_ERROR == ac)
1210 			return(0);
1211 		if (ARGS_PUNCT == ac)
1212 			break;
1213 		if (ARGS_EOLN == ac)
1214 			break;
1215 
1216 /*
1217  * XXX Temporarily disable the handling of leading punctuation.
1218  *     We must investigate the fallout before enabling this.
1219  */
1220 #if 0
1221 		/* Flush out leading punctuation. */
1222 
1223 		if (NULL == head && ARGS_QWORD != ac &&
1224 				1 == mdoc_isdelim(p)) {
1225 			assert(NULL == body);
1226 			if ( ! mdoc_word_alloc(m, line, la, p))
1227 				return(0);
1228 			continue;
1229 		}
1230 #endif
1231 
1232 		if (NULL == head) {
1233 			assert(NULL == body);
1234 			if ( ! mdoc_head_alloc(m, line, ppos, tok))
1235 				return(0);
1236 			head = m->last;
1237 		}
1238 
1239 		/*
1240 		 * `Eo' gobbles any data into the head, but most other
1241 		 * macros just immediately close out and begin the body.
1242 		 */
1243 
1244 		if (NULL == body) {
1245 			assert(head);
1246 			/* No check whether it's a macro! */
1247 			if (MDOC_Eo == tok)
1248 				if ( ! mdoc_word_alloc(m, line, la, p))
1249 					return(0);
1250 
1251 			if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1252 				return(0);
1253 			if ( ! mdoc_body_alloc(m, line, ppos, tok))
1254 				return(0);
1255 			body = m->last;
1256 
1257 			if (MDOC_Eo == tok)
1258 				continue;
1259 		}
1260 
1261 		assert(NULL != head && NULL != body);
1262 
1263 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1264 
1265 		if (MDOC_MAX == ntok) {
1266 			if ( ! mdoc_word_alloc(m, line, la, p))
1267 				return(0);
1268 			continue;
1269 		}
1270 
1271 		if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
1272 			return(0);
1273 		break;
1274 	}
1275 
1276 	/* Clean-up to leave in a consistent state. */
1277 
1278 	if (NULL == head) {
1279 		if ( ! mdoc_head_alloc(m, line, ppos, tok))
1280 			return(0);
1281 		head = m->last;
1282 	}
1283 
1284 	if (NULL == body) {
1285 		if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1286 			return(0);
1287 		if ( ! mdoc_body_alloc(m, line, ppos, tok))
1288 			return(0);
1289 		body = m->last;
1290 	}
1291 
1292 	/* Standard appending of delimiters. */
1293 
1294 	if ( ! nl)
1295 		return(1);
1296 	return(append_delims(m, line, pos, buf));
1297 }
1298 
1299 
1300 /* ARGSUSED */
1301 static int
1302 in_line_argn(MACRO_PROT_ARGS)
1303 {
1304 	int		 la, flushed, j, maxargs, nl;
1305 	enum margserr	 ac;
1306 	enum margverr	 av;
1307 	struct mdoc_arg	*arg;
1308 	char		*p;
1309 	enum mdoct	 ntok;
1310 
1311 	nl = MDOC_NEWLINE & m->flags;
1312 
1313 	/*
1314 	 * A line macro that has a fixed number of arguments (maxargs).
1315 	 * Only open the scope once the first non-leading-punctuation is
1316 	 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then
1317 	 * keep it open until the maximum number of arguments are
1318 	 * exhausted.
1319 	 */
1320 
1321 	switch (tok) {
1322 	case (MDOC_Ap):
1323 		/* FALLTHROUGH */
1324 	case (MDOC_No):
1325 		/* FALLTHROUGH */
1326 	case (MDOC_Ns):
1327 		/* FALLTHROUGH */
1328 	case (MDOC_Ux):
1329 		maxargs = 0;
1330 		break;
1331 	case (MDOC_Xr):
1332 		maxargs = 2;
1333 		break;
1334 	default:
1335 		maxargs = 1;
1336 		break;
1337 	}
1338 
1339 	for (arg = NULL; ; ) {
1340 		la = *pos;
1341 		av = mdoc_argv(m, line, tok, &arg, pos, buf);
1342 
1343 		if (ARGV_WORD == av) {
1344 			*pos = la;
1345 			break;
1346 		}
1347 
1348 		if (ARGV_EOLN == av)
1349 			break;
1350 		if (ARGV_ARG == av)
1351 			continue;
1352 
1353 		mdoc_argv_free(arg);
1354 		return(0);
1355 	}
1356 
1357 	for (flushed = j = 0; ; ) {
1358 		la = *pos;
1359 		ac = mdoc_args(m, line, pos, buf, tok, &p);
1360 
1361 		if (ARGS_ERROR == ac)
1362 			return(0);
1363 		if (ARGS_PUNCT == ac)
1364 			break;
1365 		if (ARGS_EOLN == ac)
1366 			break;
1367 
1368 /*
1369  * XXX Temporarily disable the handling of leading punctuation.
1370  *     We must investigate the fallout before enabling this.
1371  */
1372 #if 0
1373 		if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1374 				ARGS_QWORD != ac &&
1375 				0 == j && 1 == mdoc_isdelim(p)) {
1376 			if ( ! mdoc_word_alloc(m, line, la, p))
1377 				return(0);
1378 			continue;
1379 		} else
1380 #endif
1381 		if (0 == j)
1382 		       if ( ! mdoc_elem_alloc(m, line, la, tok, arg))
1383 			       return(0);
1384 
1385 		if (j == maxargs && ! flushed) {
1386 			if ( ! rew_elem(m, tok))
1387 				return(0);
1388 			flushed = 1;
1389 		}
1390 
1391 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1392 
1393 		if (MDOC_MAX != ntok) {
1394 			if ( ! flushed && ! rew_elem(m, tok))
1395 				return(0);
1396 			flushed = 1;
1397 			if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
1398 				return(0);
1399 			j++;
1400 			break;
1401 		}
1402 
1403 		if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1404 				ARGS_QWORD != ac &&
1405 				! flushed && mdoc_isdelim(p)) {
1406 			if ( ! rew_elem(m, tok))
1407 				return(0);
1408 			flushed = 1;
1409 		}
1410 
1411 		/*
1412 		 * XXX: this is a hack to work around groff's ugliness
1413 		 * as regards `Xr' and extraneous arguments.  It should
1414 		 * ideally be deprecated behaviour, but because this is
1415 		 * code is no here, it's unlikely to be removed.
1416 		 */
1417 		if (MDOC_Xr == tok && j == maxargs) {
1418 			if ( ! mdoc_elem_alloc(m, line, la, MDOC_Ns, NULL))
1419 				return(0);
1420 			if ( ! rew_elem(m, MDOC_Ns))
1421 				return(0);
1422 		}
1423 
1424 		if ( ! mdoc_word_alloc(m, line, la, p))
1425 			return(0);
1426 		j++;
1427 	}
1428 
1429 	if (0 == j && ! mdoc_elem_alloc(m, line, la, tok, arg))
1430 	       return(0);
1431 
1432 	/* Close out in a consistent state. */
1433 
1434 	if ( ! flushed && ! rew_elem(m, tok))
1435 		return(0);
1436 	if ( ! nl)
1437 		return(1);
1438 	return(append_delims(m, line, pos, buf));
1439 }
1440 
1441 
1442 static int
1443 in_line_eoln(MACRO_PROT_ARGS)
1444 {
1445 	int		 la;
1446 	enum margserr	 ac;
1447 	enum margverr	 av;
1448 	struct mdoc_arg	*arg;
1449 	char		*p;
1450 	enum mdoct	 ntok;
1451 
1452 	assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));
1453 
1454 	/* Parse macro arguments. */
1455 
1456 	for (arg = NULL; ; ) {
1457 		la = *pos;
1458 		av = mdoc_argv(m, line, tok, &arg, pos, buf);
1459 
1460 		if (ARGV_WORD == av) {
1461 			*pos = la;
1462 			break;
1463 		}
1464 		if (ARGV_EOLN == av)
1465 			break;
1466 		if (ARGV_ARG == av)
1467 			continue;
1468 
1469 		mdoc_argv_free(arg);
1470 		return(0);
1471 	}
1472 
1473 	/* Open element scope. */
1474 
1475 	if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1476 		return(0);
1477 
1478 	/* Parse argument terms. */
1479 
1480 	for (;;) {
1481 		la = *pos;
1482 		ac = mdoc_args(m, line, pos, buf, tok, &p);
1483 
1484 		if (ARGS_ERROR == ac)
1485 			return(0);
1486 		if (ARGS_EOLN == ac)
1487 			break;
1488 
1489 		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
1490 
1491 		if (MDOC_MAX == ntok) {
1492 			if ( ! mdoc_word_alloc(m, line, la, p))
1493 				return(0);
1494 			continue;
1495 		}
1496 
1497 		if ( ! rew_elem(m, tok))
1498 			return(0);
1499 		return(mdoc_macro(m, ntok, line, la, pos, buf));
1500 	}
1501 
1502 	/* Close out (no delimiters). */
1503 
1504 	return(rew_elem(m, tok));
1505 }
1506 
1507 
1508 /* ARGSUSED */
1509 static int
1510 ctx_synopsis(MACRO_PROT_ARGS)
1511 {
1512 	int		 nl;
1513 
1514 	nl = MDOC_NEWLINE & m->flags;
1515 
1516 	/* If we're not in the SYNOPSIS, go straight to in-line. */
1517 	if (SEC_SYNOPSIS != m->lastsec)
1518 		return(in_line(m, tok, line, ppos, pos, buf));
1519 
1520 	/* If we're a nested call, same place. */
1521 	if ( ! nl)
1522 		return(in_line(m, tok, line, ppos, pos, buf));
1523 
1524 	/*
1525 	 * XXX: this will open a block scope; however, if later we end
1526 	 * up formatting the block scope, then child nodes will inherit
1527 	 * the formatting.  Be careful.
1528 	 */
1529 
1530 	return(blk_part_imp(m, tok, line, ppos, pos, buf));
1531 }
1532 
1533 
1534 /* ARGSUSED */
1535 static int
1536 obsolete(MACRO_PROT_ARGS)
1537 {
1538 
1539 	return(mdoc_pwarn(m, line, ppos, EOBS));
1540 }
1541 
1542 
1543 /*
1544  * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1545  * They're unusual because they're basically free-form text until a
1546  * macro is encountered.
1547  */
1548 static int
1549 phrase(struct mdoc *m, int line, int ppos, char *buf,
1550 		enum margserr ac, int count)
1551 {
1552 	int		 la, pos;
1553 	enum margserr	 aac;
1554 	enum mdoct	 ntok;
1555 	char		*p;
1556 
1557 	assert(ARGS_PHRASE == ac ||
1558 			ARGS_PEND == ac ||
1559 			ARGS_PPHRASE == ac);
1560 
1561 	if (count && ARGS_PPHRASE == ac)
1562 		return(mdoc_word_alloc(m, line, ppos, &buf[ppos]));
1563 
1564 	for (pos = ppos; ; ) {
1565 		la = pos;
1566 
1567 		/* Note: no calling context! */
1568 		aac = mdoc_zargs(m, line, &pos, buf, 0, &p);
1569 
1570 		if (ARGS_ERROR == aac)
1571 			return(0);
1572 		if (ARGS_EOLN == aac)
1573 			break;
1574 
1575 		ntok = ARGS_QWORD == aac || ARGS_PEND == ac ?
1576 			MDOC_MAX : lookup_raw(p);
1577 
1578 		if (MDOC_MAX == ntok) {
1579 			if ( ! mdoc_word_alloc(m, line, la, p))
1580 				return(0);
1581 			continue;
1582 		}
1583 
1584 		if ( ! mdoc_macro(m, ntok, line, la, &pos, buf))
1585 			return(0);
1586 		return(append_delims(m, line, &pos, buf));
1587 	}
1588 
1589 	return(1);
1590 }
1591 
1592 
1593