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