]> git.cameronkatri.com Git - mandoc.git/blob - macro.c
*** empty log message ***
[mandoc.git] / macro.c
1 /* $Id: macro.c,v 1.12 2008/12/29 19:25:29 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008 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
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include <assert.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #ifdef __linux__
25 #include <time.h>
26 #endif
27
28 #include "private.h"
29
30 /* FIXME: maxlineargs should be per LINE, no per TOKEN. */
31
32 #define _CC(p) ((const char **)p)
33
34 static int scope_rewind_exp(struct mdoc *, int, int, int);
35 static int scope_rewind_imp(struct mdoc *, int, int);
36 static int append_text(struct mdoc *, int,
37 int, int, char *[]);
38 static int append_const(struct mdoc *, int, int, int, char *[]);
39 static int append_scoped(struct mdoc *, int, int, int,
40 const char *[], int, const struct mdoc_arg *);
41 static int append_delims(struct mdoc *, int, int *, char *);
42
43
44 static int
45 append_delims(struct mdoc *mdoc, int tok, int *pos, char *buf)
46 {
47 int c, lastarg;
48 char *p;
49
50 if (0 == buf[*pos])
51 return(1);
52
53 mdoc_msg(mdoc, *pos, "`%s' flushing punctuation",
54 mdoc_macronames[tok]);
55
56 for (;;) {
57 lastarg = *pos;
58 c = mdoc_args(mdoc, tok, pos, buf, 0, &p);
59 if (ARGS_ERROR == c)
60 return(0);
61 else if (ARGS_EOLN == c)
62 break;
63 assert(mdoc_isdelim(p));
64 mdoc_word_alloc(mdoc, lastarg, p);
65 }
66
67 return(1);
68 }
69
70
71 static int
72 scope_rewind_imp(struct mdoc *mdoc, int ppos, int tok)
73 {
74 struct mdoc_node *n;
75 int t;
76
77 n = mdoc->last ? mdoc->last->parent : NULL;
78
79 /* LINTED */
80 for ( ; n; n = n->parent) {
81 if (MDOC_BLOCK != n->type)
82 continue;
83 if (tok == (t = n->data.block.tok))
84 break;
85 if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
86 continue;
87 return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK));
88 }
89
90 if (n) {
91 mdoc->last = n;
92 mdoc_msg(mdoc, ppos, "scope: rewound implicit `%s'",
93 mdoc_macronames[tok]);
94 return(1);
95 }
96
97 mdoc_msg(mdoc, ppos, "scope: new implicit `%s'",
98 mdoc_macronames[tok]);
99 return(1);
100 }
101
102
103 static int
104 scope_rewind_exp(struct mdoc *mdoc, int ppos, int tok, int dst)
105 {
106 struct mdoc_node *n;
107
108 assert(mdoc->last);
109
110 /* LINTED */
111 for (n = mdoc->last->parent; n; n = n->parent) {
112 if (MDOC_BLOCK != n->type)
113 continue;
114 if (dst == n->data.block.tok)
115 break;
116 return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK));
117 }
118
119 if (NULL == (mdoc->last = n))
120 return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_NOCTX));
121
122 mdoc_msg(mdoc, ppos, "scope: rewound explicit `%s' to `%s'",
123 mdoc_macronames[tok], mdoc_macronames[dst]);
124
125 return(1);
126 }
127
128
129 static int
130 append_scoped(struct mdoc *mdoc, int tok, int pos,
131 int sz, const char *args[],
132 int argc, const struct mdoc_arg *argv)
133 {
134 enum mdoc_sec sec;
135 struct mdoc_node *node;
136
137 switch (tok) {
138 /* ======= ADD MORE MACRO CHECKS BELOW. ======= */
139 case (MDOC_Sh):
140 if (0 == sz)
141 return(mdoc_err(mdoc, tok, pos, ERR_ARGS_GE1));
142
143 sec = mdoc_atosec((size_t)sz, _CC(args));
144 if (SEC_CUSTOM != sec && sec < mdoc->sec_lastn)
145 if ( ! mdoc_warn(mdoc, tok, pos, WARN_SEC_OO))
146 return(0);
147
148 if (SEC_BODY == mdoc->sec_last && SEC_NAME != sec)
149 return(mdoc_err(mdoc, tok, pos, ERR_SEC_NAME));
150
151 if (SEC_CUSTOM != sec)
152 mdoc->sec_lastn = sec;
153 mdoc->sec_last = sec;
154 break;
155
156 case (MDOC_Ss):
157 if (0 == sz)
158 return(mdoc_err(mdoc, tok, pos, ERR_ARGS_GE1));
159 break;
160
161 case (MDOC_Bd):
162 assert(mdoc->last);
163 node = mdoc->last->parent;
164 /* LINTED */
165 for ( ; node; node = node->parent) {
166 if (node->type != MDOC_BLOCK)
167 continue;
168 if (node->data.block.tok != MDOC_Bd)
169 continue;
170 return(mdoc_err(mdoc, tok, pos, ERR_SCOPE_NONEST));
171 }
172 break;
173
174 case (MDOC_Bl):
175 break;
176
177 /* ======= ADD MORE MACRO CHECKS ABOVE. ======= */
178 default:
179 abort();
180 /* NOTREACHED */
181 }
182
183 mdoc_block_alloc(mdoc, pos, tok, (size_t)argc, argv);
184 mdoc_head_alloc(mdoc, pos, tok, (size_t)sz, _CC(args));
185 mdoc_body_alloc(mdoc, pos, tok);
186 return(1);
187 }
188
189
190 static int
191 append_const(struct mdoc *mdoc, int tok,
192 int pos, int sz, char *args[])
193 {
194
195 switch (tok) {
196 /* ======= ADD MORE MACRO CHECKS BELOW. ======= */
197 case (MDOC_At):
198 /* This needs special handling. */
199 if (0 == sz)
200 break;
201 else if (sz > 2)
202 return(mdoc_err(mdoc, tok, pos, ERR_ARGS_LE2));
203
204 if (ATT_DEFAULT != mdoc_atoatt(args[0])) {
205 mdoc_elem_alloc(mdoc, pos, tok, 0,
206 NULL, 1, _CC(&args[0]));
207 } else {
208 mdoc_elem_alloc(mdoc, pos, tok,
209 0, NULL, 0, NULL);
210 if (mdoc_isdelim(args[0]))
211 return(mdoc_err(mdoc, tok, pos, ERR_SYNTAX_NOPUNCT));
212 mdoc_word_alloc(mdoc, pos, args[0]);
213 }
214
215 if (1 == sz)
216 return(1);
217 if (mdoc_isdelim(args[1]))
218 return(mdoc_err(mdoc, tok, pos, ERR_SYNTAX_NOPUNCT));
219 mdoc_word_alloc(mdoc, pos, args[1]);
220 return(1);
221
222 case (MDOC_Nd):
223 if (sz > 0)
224 break;
225 if ( ! mdoc_warn(mdoc, tok, pos, WARN_ARGS_GE1))
226 return(0);
227 break;
228
229 case (MDOC_Hf):
230 if (1 == sz)
231 break;
232 return(mdoc_err(mdoc, tok, pos, ERR_ARGS_EQ1));
233
234 case (MDOC_Bx):
235 /* FALLTHROUGH */
236 case (MDOC_Bsx):
237 /* FALLTHROUGH */
238 case (MDOC_Os):
239 /* FALLTHROUGH */
240 case (MDOC_Fx):
241 /* FALLTHROUGH */
242 case (MDOC_Nx):
243 assert(sz <= 1);
244 break;
245
246 case (MDOC_Ux):
247 assert(0 == sz);
248 break;
249
250 case (MDOC_Bt):
251 /* FALLTHROUGH */
252 case (MDOC_Ud):
253 if (0 == sz)
254 break;
255 return(mdoc_err(mdoc, tok, pos, ERR_ARGS_EQ0));
256
257 /* ======= ADD MORE MACRO CHECKS ABOVE. ======= */
258 default:
259 abort();
260 /* NOTREACHED */
261 }
262
263 mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, (size_t)sz, _CC(args));
264 return(1);
265 }
266
267
268 static int
269 append_text(struct mdoc *mdoc, int tok,
270 int pos, int sz, char *args[])
271 {
272
273 assert(sz >= 0);
274 args[sz] = NULL;
275
276 switch (tok) {
277 /* ======= ADD MORE MACRO CHECKS BELOW. ======= */
278 case (MDOC_Pp):
279 if (0 == sz)
280 break;
281 if ( ! mdoc_warn(mdoc, tok, pos, WARN_ARGS_EQ0))
282 return(0);
283 break;
284
285 case (MDOC_Ft):
286 /* FALLTHROUGH */
287 case (MDOC_Li):
288 /* FALLTHROUGH */
289 case (MDOC_Ms):
290 /* FALLTHROUGH */
291 case (MDOC_Pa):
292 /* FALLTHROUGH */
293 case (MDOC_Tn):
294 if (0 < sz)
295 break;
296 if ( ! mdoc_warn(mdoc, tok, pos, WARN_ARGS_GE1))
297 return(0);
298 break;
299
300 case (MDOC_Ar):
301 /* FALLTHROUGH */
302 case (MDOC_Cm):
303 /* FALLTHROUGH */
304 case (MDOC_Fl):
305 /* These can have no arguments. */
306 break;
307
308 case (MDOC_Ad):
309 /* FALLTHROUGH */
310 case (MDOC_Em):
311 /* FALLTHROUGH */
312 case (MDOC_Er):
313 /* FALLTHROUGH */
314 case (MDOC_Ev):
315 /* FALLTHROUGH */
316 case (MDOC_Fa):
317 /* FALLTHROUGH */
318 case (MDOC_Dv):
319 /* FALLTHROUGH */
320 case (MDOC_Ic):
321 /* FALLTHROUGH */
322 case (MDOC_Sy):
323 /* FALLTHROUGH */
324 case (MDOC_Sx):
325 /* FALLTHROUGH */
326 case (MDOC_Va):
327 /* FALLTHROUGH */
328 case (MDOC_Vt):
329 if (0 < sz)
330 break;
331 return(mdoc_err(mdoc, tok, pos, ERR_ARGS_GE1));
332 /* ======= ADD MORE MACRO CHECKS ABOVE. ======= */
333 default:
334 abort();
335 /* NOTREACHED */
336 }
337
338 mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, (size_t)sz, _CC(args));
339 return(1);
340 }
341
342
343 int
344 macro_text(MACRO_PROT_ARGS)
345 {
346 int lastarg, lastpunct, c, j;
347 char *args[MDOC_LINEARG_MAX], *p;
348
349 if (SEC_PROLOGUE == mdoc->sec_lastn)
350 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
351
352 /* Token pre-processing. */
353
354 switch (tok) {
355 case (MDOC_Pp):
356 /* `.Pp' ignored when following `.Sh' or `.Ss'. */
357 assert(mdoc->last);
358 if (MDOC_BODY != mdoc->last->type)
359 break;
360 switch (mdoc->last->data.body.tok) {
361 case (MDOC_Ss):
362 /* FALLTHROUGH */
363 case (MDOC_Sh):
364 if ( ! mdoc_warn(mdoc, tok, ppos, WARN_IGN_AFTER_BLK))
365 return(0);
366 return(1);
367 default:
368 break;
369 }
370 break;
371 default:
372 break;
373 }
374
375 /* Process line parameters. */
376
377 j = 0;
378 lastarg = ppos;
379 lastpunct = 0;
380
381 again:
382 if (j == MDOC_LINEARG_MAX)
383 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
384
385 /*
386 * Parse out the next argument, unquoted and unescaped. If
387 * we're a word (which may be punctuation followed eventually by
388 * a real word), then fall into checking for callables. If
389 * only punctuation remains and we're the first, then flush
390 * arguments, punctuation and exit; else, return to the caller.
391 */
392
393 lastarg = *pos;
394
395 switch (mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &args[j])) {
396 case (ARGS_ERROR):
397 return(0);
398 case (ARGS_WORD):
399 break;
400 case (ARGS_PUNCT):
401 if ( ! lastpunct && ! append_text(mdoc, tok, ppos, j, args))
402 return(0);
403 if (ppos > 1)
404 return(1);
405 return(append_delims(mdoc, tok, pos, buf));
406 case (ARGS_EOLN):
407 if (lastpunct)
408 return(1);
409 return(append_text(mdoc, tok, ppos, j, args));
410 default:
411 abort();
412 /* NOTREACHED */
413 }
414
415 /*
416 * Command found. First flush out arguments, then call the
417 * command. If we're the line macro when it exits, flush
418 * terminal punctuation.
419 */
420
421 if (MDOC_MAX != (c = mdoc_find(mdoc, args[j]))) {
422 if ( ! lastpunct && ! append_text(mdoc, tok, ppos, j, args))
423 return(0);
424 if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
425 return(0);
426 if (ppos > 1)
427 return(1);
428 return(append_delims(mdoc, tok, pos, buf));
429 }
430
431 /* Word/non-term-punctuation found. */
432
433 if ( ! mdoc_isdelim(args[j])) {
434 /* Words are appended to the array of arguments. */
435 j++;
436 lastpunct = 0;
437 goto again;
438 }
439
440 /*
441 * For punctuation, flush all collected words, then flush
442 * punctuation, then start collecting again. Of course, this
443 * is non-terminal punctuation.
444 */
445
446 p = args[j];
447 if ( ! lastpunct && ! append_text(mdoc, tok, ppos, j, args))
448 return(0);
449
450 mdoc_word_alloc(mdoc, lastarg, p);
451 j = 0;
452 lastpunct = 1;
453
454 goto again;
455 /* NOTREACHED */
456 }
457
458
459 int
460 macro_prologue_dtitle(MACRO_PROT_ARGS)
461 {
462 int lastarg, j;
463 char *args[MDOC_LINEARG_MAX];
464
465 if (SEC_PROLOGUE != mdoc->sec_lastn)
466 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
467 if (0 == mdoc->meta.date)
468 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
469 if (mdoc->meta.title[0])
470 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
471
472 j = -1;
473 lastarg = ppos;
474
475 again:
476 if (j == MDOC_LINEARG_MAX)
477 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
478
479 lastarg = *pos;
480
481 switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[++j])) {
482 case (ARGS_EOLN):
483 if (mdoc->meta.title)
484 return(1);
485 if ( ! mdoc_warn(mdoc, tok, ppos, WARN_ARGS_GE1))
486 return(0);
487 (void)xstrlcpy(mdoc->meta.title,
488 "UNTITLED", META_TITLE_SZ);
489 return(1);
490 case (ARGS_ERROR):
491 return(0);
492 default:
493 break;
494 }
495
496 if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn
497 (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
498 return(0);
499
500 if (0 == j) {
501 if (xstrlcpy(mdoc->meta.title, args[0], META_TITLE_SZ))
502 goto again;
503 return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
504
505 } else if (1 == j) {
506 mdoc->meta.msec = mdoc_atomsec(args[1]);
507 if (MSEC_DEFAULT != mdoc->meta.msec)
508 goto again;
509 return(mdoc_err(mdoc, tok, -1, ERR_SYNTAX_ARGFORM));
510
511 } else if (2 == j) {
512 mdoc->meta.vol = mdoc_atovol(args[2]);
513 if (VOL_DEFAULT != mdoc->meta.vol)
514 goto again;
515 mdoc->meta.arch = mdoc_atoarch(args[2]);
516 if (ARCH_DEFAULT != mdoc->meta.arch)
517 goto again;
518 return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
519 }
520
521 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
522 }
523
524
525 int
526 macro_prologue_os(MACRO_PROT_ARGS)
527 {
528 int lastarg, j;
529 char *args[MDOC_LINEARG_MAX];
530
531 if (SEC_PROLOGUE != mdoc->sec_lastn)
532 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
533 if (0 == mdoc->meta.title[0])
534 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
535 if (mdoc->meta.os[0])
536 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
537
538 j = -1;
539 lastarg = ppos;
540
541 again:
542 if (j == MDOC_LINEARG_MAX)
543 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
544
545 lastarg = *pos;
546
547 switch (mdoc_args(mdoc, tok, pos, buf,
548 ARGS_QUOTED, &args[++j])) {
549 case (ARGS_EOLN):
550 mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
551 return(1);
552 case (ARGS_ERROR):
553 return(0);
554 default:
555 break;
556 }
557
558 if ( ! xstrlcat(mdoc->meta.os, args[j], sizeof(mdoc->meta.os)))
559 return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
560 if ( ! xstrlcat(mdoc->meta.os, " ", sizeof(mdoc->meta.os)))
561 return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
562
563 goto again;
564 /* NOTREACHED */
565 }
566
567
568 int
569 macro_prologue_ddate(MACRO_PROT_ARGS)
570 {
571 int lastarg, j;
572 char *args[MDOC_LINEARG_MAX], date[64];
573
574 if (SEC_PROLOGUE != mdoc->sec_lastn)
575 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
576 if (mdoc->meta.title[0])
577 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
578 if (mdoc->meta.date)
579 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
580
581 j = -1;
582 date[0] = 0;
583 lastarg = ppos;
584
585 again:
586 if (j == MDOC_LINEARG_MAX)
587 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
588
589 lastarg = *pos;
590 switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[++j])) {
591 case (ARGS_EOLN):
592 if (mdoc->meta.date)
593 return(1);
594 mdoc->meta.date = mdoc_atotime(date);
595 if (mdoc->meta.date)
596 return(1);
597 return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGFORM));
598 case (ARGS_ERROR):
599 return(0);
600 default:
601 break;
602 }
603
604 if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn
605 (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
606 return(0);
607
608 if (0 == j) {
609 if (xstrcmp("$Mdocdate: December 29 2008 $", args[j])) {
610 mdoc->meta.date = time(NULL);
611 goto again;
612 } else if (xstrcmp("$Mdocdate:", args[j]))
613 goto again;
614 } else if (4 == j)
615 if ( ! xstrcmp("$", args[j]))
616 goto again;
617
618 if ( ! xstrlcat(date, args[j], sizeof(date)))
619 return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
620 if ( ! xstrlcat(date, " ", sizeof(date)))
621 return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
622
623 goto again;
624 /* NOTREACHED */
625 }
626
627
628 int
629 macro_scoped_explicit(MACRO_PROT_ARGS)
630 {
631 int c, lastarg, j;
632 struct mdoc_arg argv[MDOC_LINEARG_MAX];
633 struct mdoc_node *n;
634
635 if (SEC_PROLOGUE == mdoc->sec_lastn)
636 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
637
638 /*
639 * First close out the explicit scope. The `end' tags (such as
640 * `.El' to `.Bl' don't cause anything to happen: we merely
641 * readjust our last parse point.
642 */
643
644 switch (tok) {
645 case (MDOC_El):
646 return(scope_rewind_exp(mdoc, ppos, tok, MDOC_Bl));
647 case (MDOC_Ed):
648 return(scope_rewind_exp(mdoc, ppos, tok, MDOC_Bd));
649 default:
650 break;
651 }
652
653 assert(MDOC_EXPLICIT & mdoc_macros[tok].flags);
654
655 /* Token pre-processing. */
656
657 switch (tok) {
658 case (MDOC_Bl):
659 /* FALLTHROUGH */
660 case (MDOC_Bd):
661 /* `.Pp' ignored when preceding `.Bl' or `.Bd'. */
662 assert(mdoc->last);
663 if (MDOC_ELEM != mdoc->last->type)
664 break;
665 if (MDOC_Pp != mdoc->last->data.elem.tok)
666 break;
667 if ( ! mdoc_warn(mdoc, tok, ppos, WARN_IGN_BEFORE_BLK))
668 return(0);
669 assert(mdoc->last->prev);
670 n = mdoc->last;
671 mdoc->last = mdoc->last->prev;
672 mdoc->last->next = NULL;
673 mdoc_node_free(n);
674 break;
675 default:
676 break;
677 }
678
679 lastarg = *pos;
680
681 for (j = 0; j < MDOC_LINEARG_MAX; j++) {
682 lastarg = *pos;
683 c = mdoc_argv(mdoc, tok, &argv[j], pos, buf);
684 if (0 == c)
685 break;
686 else if (1 == c)
687 continue;
688
689 mdoc_argv_free(j, argv);
690 return(0);
691 }
692
693 if (MDOC_LINEARG_MAX == j) {
694 mdoc_argv_free(j, argv);
695 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
696 }
697
698 c = append_scoped(mdoc, tok, ppos, 0, NULL, j, argv);
699 mdoc_argv_free(j, argv);
700 return(c);
701 }
702
703
704 /*
705 * Implicity-scoped macros, like `.Ss', have a scope that terminates
706 * with a subsequent call to the same macro. Implicit macros cannot
707 * break the scope of explicitly-scoped macros; however, they can break
708 * the scope of other implicit macros (so `.Sh' can break `.Ss'). This
709 * is ok with macros like `.It' because they exist only within an
710 * explicit context.
711 *
712 * These macros put line arguments (which it's allowed to have) into the
713 * HEAD section and open a BODY scope to be used until the macro scope
714 * closes.
715 */
716 int
717 macro_scoped_implicit(MACRO_PROT_ARGS)
718 {
719 int lastarg, j;
720 char *args[MDOC_LINEARG_MAX];
721 struct mdoc_node *n;
722
723 assert( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags));
724
725 if (SEC_PROLOGUE == mdoc->sec_lastn)
726 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
727
728 /* Token pre-processing. */
729
730 switch (tok) {
731 case (MDOC_Ss):
732 /* FALLTHROUGH */
733 case (MDOC_Sh):
734 /* `.Pp' ignored when preceding `.Ss' or `.Sh'. */
735 if (NULL == mdoc->last)
736 break;
737 if (MDOC_ELEM != mdoc->last->type)
738 break;
739 if (MDOC_Pp != mdoc->last->data.elem.tok)
740 break;
741 if ( ! mdoc_warn(mdoc, tok, ppos, WARN_IGN_BEFORE_BLK))
742 return(0);
743 assert(mdoc->last->prev);
744 n = mdoc->last;
745 mdoc_msg(mdoc, ppos, "removing prior `Pp' macro");
746 mdoc->last = mdoc->last->prev;
747 mdoc->last->next = NULL;
748 mdoc_node_free(n);
749 break;
750 default:
751 break;
752 }
753
754 /* Rewind our scope. */
755
756 if ( ! scope_rewind_imp(mdoc, ppos, tok))
757 return(0);
758
759 j = 0;
760 lastarg = ppos;
761
762 /*
763 * Process until we hit a line. Note that current implicit
764 * macros don't have any arguments, so we don't need to do any
765 * argument processing.
766 */
767
768 again:
769 if (j == MDOC_LINEARG_MAX)
770 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
771
772 lastarg = *pos;
773
774 switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[j])) {
775 case (ARGS_ERROR):
776 return(0);
777 case (ARGS_EOLN):
778 return(append_scoped(mdoc, tok, ppos, j, _CC(args), 0, NULL));
779 default:
780 break;
781 }
782
783 if (MDOC_MAX != mdoc_find(mdoc, args[j]))
784 if ( ! mdoc_warn(mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
785 return(0);
786
787 j++;
788 goto again;
789 /* NOTREACHED */
790 }
791
792
793 /*
794 * A line-scoped macro opens a scope for the contents of its line, which
795 * are placed under the HEAD node. Punctuation trailing the line is put
796 * as a sibling to the HEAD node, under the BLOCK node.
797 */
798 int
799 macro_scoped_line(MACRO_PROT_ARGS)
800 {
801 int lastarg, c, j;
802 char *p;
803 struct mdoc_node *n;
804
805 if (SEC_PROLOGUE == mdoc->sec_lastn)
806 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
807
808 assert(1 == ppos);
809
810 /* Token pre-processing. */
811
812 switch (tok) {
813 case (MDOC_D1):
814 /* FALLTHROUGH */
815 case (MDOC_Dl):
816 /* These can't be nested in a display block. */
817 assert(mdoc->last);
818 for (n = mdoc->last->parent ; n; n = n->parent)
819 if (MDOC_BLOCK != n->type)
820 continue;
821 else if (MDOC_Bd == n->data.block.tok)
822 break;
823 if (NULL == n)
824 break;
825 return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_NONEST));
826 default:
827 break;
828 }
829
830 /*
831 * All line-scoped macros have a HEAD and optionally a BODY
832 * section. We open our scope here; when we exit this function,
833 * we'll rewind our scope appropriately.
834 */
835
836 mdoc_block_alloc(mdoc, ppos, tok, 0, NULL);
837 mdoc_head_alloc(mdoc, ppos, tok, 0, NULL);
838
839 /* Process line parameters. */
840
841 j = 0;
842 lastarg = ppos;
843
844 again:
845 if (j == MDOC_LINEARG_MAX)
846 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
847
848 lastarg = *pos;
849 c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p);
850
851 switch (c) {
852 case (ARGS_ERROR):
853 return(0);
854 case (ARGS_WORD):
855 break;
856 case (ARGS_PUNCT):
857 if ( ! append_delims(mdoc, tok, pos, buf))
858 return(0);
859 return(scope_rewind_imp(mdoc, ppos, tok));
860 case (ARGS_EOLN):
861 return(scope_rewind_imp(mdoc, ppos, tok));
862 default:
863 abort();
864 /* NOTREACHED */
865 }
866
867 if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
868 if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
869 return(0);
870 if ( ! append_delims(mdoc, tok, pos, buf))
871 return(0);
872 return(scope_rewind_imp(mdoc, ppos, tok));
873 }
874
875 if (mdoc_isdelim(p))
876 j = 0;
877
878 mdoc_word_alloc(mdoc, lastarg, p);
879 goto again;
880 /* NOTREACHED */
881 }
882
883
884 /*
885 * Partial-line scope is identical to line scope (macro_scoped_line())
886 * except that trailing punctuation is appended to the BLOCK, instead of
887 * contained within the HEAD.
888 */
889 int
890 macro_scoped_pline(MACRO_PROT_ARGS)
891 {
892 int lastarg, c, j;
893 char *p;
894
895 if (SEC_PROLOGUE == mdoc->sec_lastn)
896 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
897
898 /* Token pre-processing. */
899
900 switch (tok) {
901 case (MDOC_Ql):
902 if ( ! mdoc_warn(mdoc, tok, ppos, WARN_COMPAT_TROFF))
903 return(0);
904 break;
905 default:
906 break;
907 }
908
909 mdoc_block_alloc(mdoc, ppos, tok, 0, NULL);
910 mdoc_head_alloc(mdoc, ppos, tok, 0, NULL);
911
912 /* Process line parameters. */
913
914 j = 0;
915 lastarg = ppos;
916
917 again:
918 if (j == MDOC_LINEARG_MAX)
919 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
920
921 lastarg = *pos;
922 c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p);
923
924 switch (c) {
925 case (ARGS_ERROR):
926 return(0);
927 case (ARGS_WORD):
928 break;
929 case (ARGS_PUNCT):
930 if ( ! scope_rewind_imp(mdoc, ppos, tok))
931 return(0);
932 if (ppos > 1)
933 return(1);
934 return(append_delims(mdoc, tok, pos, buf));
935 case (ARGS_EOLN):
936 return(scope_rewind_imp(mdoc, ppos, tok));
937 default:
938 abort();
939 /* NOTREACHED */
940 }
941
942 if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
943 if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
944 return(0);
945 if ( ! scope_rewind_imp(mdoc, ppos, tok))
946 return(0);
947 if (ppos > 1)
948 return(1);
949 return(append_delims(mdoc, tok, pos, buf));
950 }
951
952 if (mdoc_isdelim(p))
953 j = 0;
954
955 mdoc_word_alloc(mdoc, lastarg, p);
956 goto again;
957 /* NOTREACHED */
958 }
959
960
961 /*
962 * A delimited-constant macro is similar to a general text macro: the
963 * macro is followed by a 0 or 1 arguments (possibly-unspecified) then
964 * terminating punctuation, other words, or another callable macro.
965 */
966 int
967 macro_constant_delimited(MACRO_PROT_ARGS)
968 {
969 int lastarg, flushed, c, maxargs;
970 char *p, *pp;
971
972 if (SEC_PROLOGUE == mdoc->sec_lastn)
973 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
974
975 /* Process line parameters. */
976
977 lastarg = ppos;
978 flushed = 0;
979
980 /* Token pre-processing. */
981
982 switch (tok) {
983 case (MDOC_Ux):
984 maxargs = 0;
985 break;
986 default:
987 maxargs = 1;
988 break;
989 }
990
991 again:
992 lastarg = *pos;
993
994 switch (mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p)) {
995 case (ARGS_ERROR):
996 return(0);
997 case (ARGS_WORD):
998 break;
999 case (ARGS_PUNCT):
1000 if ( ! flushed && ! append_const(mdoc, tok, ppos, 0, &p))
1001 return(0);
1002 if (ppos > 1)
1003 return(1);
1004 return(append_delims(mdoc, tok, pos, buf));
1005 case (ARGS_EOLN):
1006 if (flushed)
1007 return(1);
1008 return(append_const(mdoc, tok, ppos, 0, &p));
1009 default:
1010 abort();
1011 /* NOTREACHED */
1012 }
1013
1014 /* Accepts no arguments: flush out symbol and continue. */
1015
1016 if (0 == maxargs) {
1017 pp = p;
1018 if ( ! append_const(mdoc, tok, ppos, 0, &p))
1019 return(0);
1020 p = pp;
1021 flushed = 1;
1022 }
1023
1024 if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
1025 if ( ! flushed && ! append_const(mdoc, tok, ppos, 0, &p))
1026 return(0);
1027 if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
1028 return(0);
1029 if (ppos > 1)
1030 return(1);
1031 return(append_delims(mdoc, tok, pos, buf));
1032 }
1033
1034 /*
1035 * We only accept one argument; subsequent tokens are considered
1036 * as literal words (until a macro).
1037 */
1038
1039 if ( ! flushed && ! mdoc_isdelim(p)) {
1040 if ( ! append_const(mdoc, tok, ppos, 1, &p))
1041 return(0);
1042 flushed = 1;
1043 goto again;
1044 } else if ( ! flushed) {
1045 pp = p;
1046 if ( ! append_const(mdoc, tok, ppos, 0, &p))
1047 return(0);
1048 p = pp;
1049 flushed = 1;
1050 }
1051
1052 mdoc_word_alloc(mdoc, lastarg, p);
1053 goto again;
1054 /* NOTREACHED */
1055 }
1056
1057
1058 int
1059 macro_constant(MACRO_PROT_ARGS)
1060 {
1061 int lastarg, j;
1062 char *args[MDOC_LINEARG_MAX];
1063
1064 if (SEC_PROLOGUE == mdoc->sec_lastn)
1065 return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE));
1066
1067 j = 0;
1068
1069 again:
1070 if (j == MDOC_LINEARG_MAX)
1071 return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
1072
1073 lastarg = *pos;
1074
1075 switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[j])) {
1076 case (ARGS_ERROR):
1077 return(0);
1078 case (ARGS_WORD):
1079 break;
1080 case (ARGS_EOLN):
1081 return(append_const(mdoc, tok, ppos, j, args));
1082 default:
1083 abort();
1084 /* NOTREACHED */
1085 }
1086
1087 if (MDOC_MAX != mdoc_find(mdoc, args[j]))
1088 if ( ! mdoc_warn(mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
1089 return(0);
1090
1091 j++;
1092 goto again;
1093 /* NOTREACHED */
1094 }