]> git.cameronkatri.com Git - mandoc.git/blob - macro.c
*** empty log message ***
[mandoc.git] / macro.c
1 /* $Id: macro.c,v 1.28 2009/01/08 14:55:59 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 static int rewind_elem(struct mdoc *, int);
33 static int rewind_impblock(struct mdoc *, int);
34 static int rewind_expblock(struct mdoc *, int);
35 static int rewind_head(struct mdoc *, int);
36 static int rewind_body(struct mdoc *, int);
37 static int rewind_last(struct mdoc *, struct mdoc_node *);
38 static int append_delims(struct mdoc *,
39 int, int, int *, char *);
40 static int lookup(struct mdoc *, int, const char *);
41
42
43 static int
44 lookup(struct mdoc *mdoc, int from, const char *p)
45 {
46
47 if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
48 return(MDOC_MAX);
49 return(mdoc_find(mdoc, p));
50 }
51
52
53 static int
54 rewind_last(struct mdoc *mdoc, struct mdoc_node *to)
55 {
56
57 assert(to);
58 while (mdoc->last != to) {
59 if ( ! mdoc_valid_post(mdoc))
60 return(0);
61 if ( ! mdoc_action_post(mdoc))
62 return(0);
63 mdoc->last = mdoc->last->parent;
64 assert(mdoc->last);
65 }
66
67 mdoc->next = MDOC_NEXT_SIBLING;
68 if ( ! mdoc_valid_post(mdoc))
69 return(0);
70 return(mdoc_action_post(mdoc));
71 }
72
73
74 static int
75 rewind_elem(struct mdoc *mdoc, int tok)
76 {
77 struct mdoc_node *n;
78
79 n = mdoc->last;
80 if (MDOC_ELEM != n->type)
81 n = n->parent;
82 assert(MDOC_ELEM == n->type);
83 assert(tok == n->data.elem.tok);
84
85 return(rewind_last(mdoc, n));
86 }
87
88
89 static int
90 rewind_body(struct mdoc *mdoc, int tok)
91 {
92 struct mdoc_node *n;
93 int t;
94
95 assert(mdoc->last);
96
97 /* LINTED */
98 for (n = mdoc->last; n; n = n->parent) {
99 if (MDOC_BODY != n->type)
100 continue;
101 if (tok == (t = n->data.head.tok))
102 break;
103 if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
104 continue;
105 return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
106 }
107
108 assert(n);
109 return(rewind_last(mdoc, n));
110 }
111
112
113 static int
114 rewind_head(struct mdoc *mdoc, int tok)
115 {
116 struct mdoc_node *n;
117 int t;
118
119 assert(mdoc->last);
120
121 /* LINTED */
122 for (n = mdoc->last; n; n = n->parent) {
123 if (MDOC_HEAD != n->type)
124 continue;
125 if (tok == (t = n->data.head.tok))
126 break;
127 if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
128 continue;
129 return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
130 }
131
132 assert(n);
133 return(rewind_last(mdoc, n));
134 }
135
136
137 static int
138 rewind_expblock(struct mdoc *mdoc, int tok)
139 {
140 struct mdoc_node *n;
141 int t;
142
143 assert(mdoc->last);
144
145 /* LINTED */
146 for (n = mdoc->last; n; n = n->parent) {
147 if (MDOC_BLOCK != n->type)
148 continue;
149 if (tok == (t = n->data.block.tok))
150 break;
151 if (MDOC_NESTED & mdoc_macros[t].flags)
152 continue;
153 return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
154 }
155
156 assert(n);
157 return(rewind_last(mdoc, n));
158 }
159
160
161 static int
162 rewind_impblock(struct mdoc *mdoc, int tok)
163 {
164 int t;
165 struct mdoc_node *n;
166
167 n = mdoc->last ? mdoc->last->parent : NULL;
168
169 /* LINTED */
170 for ( ; n; n = n->parent) {
171 if (MDOC_BLOCK != n->type)
172 continue;
173 if (tok == (t = n->data.block.tok))
174 break;
175 if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
176 continue;
177 if (MDOC_NESTED & mdoc_macros[t].flags)
178 return(1);
179 return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
180 }
181
182 if (NULL == n)
183 return(1);
184 return(rewind_last(mdoc, n));
185 }
186
187
188 static int
189 append_delims(struct mdoc *mdoc, int tok,
190 int line, int *pos, char *buf)
191 {
192 int c, lastarg;
193 char *p;
194
195 if (0 == buf[*pos])
196 return(1);
197
198 for (;;) {
199 lastarg = *pos;
200 c = mdoc_args(mdoc, line, pos, buf, 0, &p);
201 if (ARGS_ERROR == c)
202 return(0);
203 else if (ARGS_EOLN == c)
204 break;
205 assert(mdoc_isdelim(p));
206 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
207 return(0);
208 mdoc->next = MDOC_NEXT_SIBLING;
209 }
210
211 return(1);
212 }
213
214
215 /* ARGSUSED */
216 int
217 macro_close_explicit(MACRO_PROT_ARGS)
218 {
219 int tt, j, c, lastarg, maxargs, flushed;
220 char *p;
221
222 switch (tok) {
223 case (MDOC_Ac):
224 tt = MDOC_Ao;
225 break;
226 case (MDOC_Bc):
227 tt = MDOC_Bo;
228 break;
229 case (MDOC_Dc):
230 tt = MDOC_Do;
231 break;
232 case (MDOC_Ec):
233 tt = MDOC_Eo;
234 break;
235 case (MDOC_Ed):
236 tt = MDOC_Bd;
237 break;
238 case (MDOC_Ef):
239 tt = MDOC_Bf;
240 break;
241 case (MDOC_Ek):
242 tt = MDOC_Bk;
243 break;
244 case (MDOC_El):
245 tt = MDOC_Bl;
246 break;
247 case (MDOC_Fc):
248 tt = MDOC_Fo;
249 break;
250 case (MDOC_Oc):
251 tt = MDOC_Oo;
252 break;
253 case (MDOC_Pc):
254 tt = MDOC_Po;
255 break;
256 case (MDOC_Qc):
257 tt = MDOC_Qo;
258 break;
259 case (MDOC_Re):
260 tt = MDOC_Rs;
261 break;
262 case (MDOC_Sc):
263 tt = MDOC_So;
264 break;
265 case (MDOC_Xc):
266 tt = MDOC_Xo;
267 break;
268 default:
269 abort();
270 /* NOTREACHED */
271 }
272
273 switch (tok) {
274 case (MDOC_Ec):
275 maxargs = 1;
276 break;
277 default:
278 maxargs = 0;
279 break;
280 }
281
282 if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
283 if (buf[*pos])
284 return(rewind_expblock(mdoc, tt));
285 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_EQ0));
286 }
287
288 if ( ! rewind_body(mdoc, tt))
289 return(0);
290
291 lastarg = ppos;
292 flushed = 0;
293
294 if (maxargs > 0) {
295 if ( ! mdoc_tail_alloc(mdoc, line, ppos, tt))
296 return(0);
297 mdoc->next = MDOC_NEXT_CHILD;
298 }
299
300 for (j = 0; j < MDOC_LINEARG_MAX; j++) {
301 lastarg = *pos;
302
303 if (j == maxargs && ! flushed) {
304 if ( ! rewind_expblock(mdoc, tt))
305 return(0);
306 flushed = 1;
307 }
308
309 c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
310 if (ARGS_ERROR == c)
311 return(0);
312 if (ARGS_PUNCT == c)
313 break;
314 if (ARGS_EOLN == c)
315 break;
316
317 if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
318 if ( ! flushed) {
319 if ( ! rewind_expblock(mdoc, tt))
320 return(0);
321 flushed = 1;
322 }
323 if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
324 return(0);
325 break;
326 }
327
328 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
329 return(0);
330 mdoc->next = MDOC_NEXT_SIBLING;
331 }
332
333 if (MDOC_LINEARG_MAX == j)
334 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
335
336 if ( ! flushed && ! rewind_expblock(mdoc, tt))
337 return(0);
338
339 if (ppos > 1)
340 return(1);
341 return(append_delims(mdoc, tok, line, pos, buf));
342 }
343
344
345 /*
346 * A general text domain macro. When invoked, this opens a scope that
347 * accepts words until either end-of-line, only-punctuation, or a
348 * callable macro. If the word is punctuation (not only-punctuation),
349 * then the scope is closed out, the punctuation appended, then the
350 * scope opened again. If any terminating conditions are met, the scope
351 * is closed out. If this is the first macro in the line and
352 * only-punctuation remains, this punctuation is flushed.
353 */
354 int
355 macro_text(MACRO_PROT_ARGS)
356 {
357 int la, lastpunct, c, sz, fl, argc;
358 struct mdoc_arg argv[MDOC_LINEARG_MAX];
359 char *p;
360
361 la = ppos;
362 lastpunct = 0;
363
364 for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
365 la = *pos;
366
367 c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
368 if (ARGV_EOLN == c || ARGV_WORD == c)
369 break;
370 else if (ARGV_ARG == c)
371 continue;
372 mdoc_argv_free(argc, argv);
373 return(0);
374 }
375
376 if (MDOC_LINEARG_MAX == argc) {
377 mdoc_argv_free(argc, argv);
378 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
379 }
380
381 c = mdoc_elem_alloc(mdoc, line, la, tok, argc, argv);
382
383 if (0 == c) {
384 mdoc_argv_free(argc, argv);
385 return(0);
386 }
387
388 mdoc->next = MDOC_NEXT_CHILD;
389
390 fl = ARGS_DELIM;
391 if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
392 fl |= ARGS_QUOTED;
393
394 for (lastpunct = sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
395 la = *pos;
396
397 if (lastpunct) {
398 c = mdoc_elem_alloc(mdoc, line,
399 la, tok, argc, argv);
400 if (0 == c) {
401 mdoc_argv_free(argc, argv);
402 return(0);
403 }
404 mdoc->next = MDOC_NEXT_CHILD;
405 lastpunct = 0;
406 }
407
408 c = mdoc_args(mdoc, line, pos, buf, fl, &p);
409 if (ARGS_ERROR == c) {
410 mdoc_argv_free(argc, argv);
411 return(0);
412 }
413
414 if (ARGS_EOLN == c)
415 break;
416 if (ARGS_PUNCT == c)
417 break;
418
419 if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
420 if ( ! rewind_elem(mdoc, tok)) {
421 mdoc_argv_free(argc, argv);
422 return(0);
423 }
424 mdoc_argv_free(argc, argv);
425
426 c = mdoc_macro(mdoc, c, line, la, pos, buf);
427 if (0 == c)
428 return(0);
429 if (ppos > 1)
430 return(1);
431 return(append_delims(mdoc, tok, line, pos, buf));
432 }
433
434 if (mdoc_isdelim(p)) {
435 if ( ! rewind_elem(mdoc, tok)) {
436 mdoc_argv_free(argc, argv);
437 return(0);
438 }
439 lastpunct = 1;
440 }
441 if ( ! mdoc_word_alloc(mdoc, line, la, p))
442 return(0);
443 mdoc->next = MDOC_NEXT_SIBLING;
444 }
445
446 mdoc_argv_free(argc, argv);
447
448 if (sz == MDOC_LINEARG_MAX)
449 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
450
451 if ( ! rewind_elem(mdoc, tok))
452 return(0);
453 if (ppos > 1)
454 return(1);
455 return(append_delims(mdoc, tok, line, pos, buf));
456 }
457
458
459 /*
460 * Implicit- or explicit-end multi-line scoped macro.
461 */
462 int
463 macro_scoped(MACRO_PROT_ARGS)
464 {
465 int c, lastarg, argc, j;
466 struct mdoc_arg argv[MDOC_LINEARG_MAX];
467 char *p;
468
469 assert ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags));
470
471 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
472 if ( ! rewind_impblock(mdoc, tok))
473 return(0);
474
475 for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
476 lastarg = *pos;
477 c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
478 if (ARGV_EOLN == c || ARGV_WORD == c)
479 break;
480 else if (ARGV_ARG == c)
481 continue;
482 mdoc_argv_free(argc, argv);
483 return(0);
484 }
485
486 if (MDOC_LINEARG_MAX == argc) {
487 mdoc_argv_free(argc, argv);
488 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
489 }
490
491 c = mdoc_block_alloc(mdoc, line, ppos,
492 tok, (size_t)argc, argv);
493 mdoc_argv_free(argc, argv);
494
495 if (0 == c)
496 return(0);
497
498 mdoc->next = MDOC_NEXT_CHILD;
499
500 if (0 == buf[*pos]) {
501 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
502 return(0);
503 if ( ! rewind_head(mdoc, tok))
504 return(0);
505 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
506 return(0);
507 mdoc->next = MDOC_NEXT_CHILD;
508 return(1);
509 }
510
511 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
512 return(0);
513 mdoc->next = MDOC_NEXT_CHILD;
514
515 for (j = 0; j < MDOC_LINEARG_MAX; j++) {
516 lastarg = *pos;
517 c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
518
519 if (ARGS_ERROR == c)
520 return(0);
521 if (ARGS_PUNCT == c)
522 break;
523 if (ARGS_EOLN == c)
524 break;
525
526 if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
527 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
528 return(0);
529 mdoc->next = MDOC_NEXT_SIBLING;
530 continue;
531 }
532
533 if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
534 return(0);
535 break;
536 }
537
538 if (j == MDOC_LINEARG_MAX)
539 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
540
541 if ( ! rewind_head(mdoc, tok))
542 return(0);
543 if (1 == ppos && ! append_delims(mdoc, tok, line, pos, buf))
544 return(0);
545
546 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
547 return(0);
548 mdoc->next = MDOC_NEXT_CHILD;
549
550 return(1);
551 }
552
553
554 /*
555 * When scoped to a line, a macro encompasses all of the contents. This
556 * differs from constants or text macros, where a new macro will
557 * terminate the existing context.
558 */
559 int
560 macro_scoped_line(MACRO_PROT_ARGS)
561 {
562 int lastarg, c, j;
563 char *p;
564
565 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL))
566 return(0);
567 mdoc->next = MDOC_NEXT_CHILD;
568
569 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
570 return(0);
571 mdoc->next = MDOC_NEXT_CHILD;
572
573 /* XXX - no known argument macros. */
574
575 for (lastarg = ppos, j = 0; j < MDOC_LINEARG_MAX; j++) {
576 lastarg = *pos;
577 c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
578
579 if (ARGS_ERROR == c)
580 return(0);
581 if (ARGS_PUNCT == c)
582 break;
583 if (ARGS_EOLN == c)
584 break;
585
586 if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
587 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
588 return(0);
589 mdoc->next = MDOC_NEXT_SIBLING;
590 continue;
591 }
592
593 if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
594 return(0);
595 break;
596 }
597
598 if (j == MDOC_LINEARG_MAX)
599 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
600
601 if (1 == ppos) {
602 if ( ! rewind_head(mdoc, tok))
603 return(0);
604 if ( ! append_delims(mdoc, tok, line, pos, buf))
605 return(0);
606 }
607 return(rewind_impblock(mdoc, tok));
608 }
609
610
611 /*
612 * Constant-scope macros accept a fixed number of arguments and behave
613 * like constant macros except that they're scoped across lines.
614 */
615 int
616 macro_constant_scoped(MACRO_PROT_ARGS)
617 {
618 int lastarg, flushed, j, c, maxargs;
619 char *p;
620
621 lastarg = ppos;
622 flushed = 0;
623
624 switch (tok) {
625 case (MDOC_Eo):
626 maxargs = 1;
627 break;
628 default:
629 maxargs = 0;
630 break;
631 }
632
633 if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL))
634 return(0);
635 mdoc->next = MDOC_NEXT_CHILD;
636
637 if (0 == maxargs) {
638 if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
639 return(0);
640 if ( ! rewind_head(mdoc, tok))
641 return(0);
642 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
643 return(0);
644 flushed = 1;
645 } else if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
646 return(0);
647
648 mdoc->next = MDOC_NEXT_CHILD;
649
650 for (j = 0; j < MDOC_LINEARG_MAX; j++) {
651 lastarg = *pos;
652
653 if (j == maxargs && ! flushed) {
654 if ( ! rewind_head(mdoc, tok))
655 return(0);
656 flushed = 1;
657 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
658 return(0);
659 mdoc->next = MDOC_NEXT_CHILD;
660 }
661
662 c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
663 if (ARGS_ERROR == c)
664 return(0);
665 if (ARGS_PUNCT == c)
666 break;
667 if (ARGS_EOLN == c)
668 break;
669
670 if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
671 if ( ! flushed) {
672 if ( ! rewind_head(mdoc, tok))
673 return(0);
674 flushed = 1;
675 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
676 return(0);
677 mdoc->next = MDOC_NEXT_CHILD;
678 }
679 if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
680 return(0);
681 break;
682 }
683
684 if ( ! flushed && mdoc_isdelim(p)) {
685 if ( ! rewind_head(mdoc, tok))
686 return(0);
687 flushed = 1;
688 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
689 return(0);
690 mdoc->next = MDOC_NEXT_CHILD;
691 }
692
693 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
694 return(0);
695 mdoc->next = MDOC_NEXT_SIBLING;
696 }
697
698 if (MDOC_LINEARG_MAX == j)
699 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
700
701 if ( ! flushed) {
702 if ( ! rewind_head(mdoc, tok))
703 return(0);
704 if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
705 return(0);
706 mdoc->next = MDOC_NEXT_CHILD;
707 }
708
709 if (ppos > 1)
710 return(1);
711 return(append_delims(mdoc, tok, line, pos, buf));
712 }
713
714
715 /*
716 * Delimited macros are like text macros except that, should punctuation
717 * be encountered, the macro isn't re-started with remaining tokens
718 * (it's only emitted once). Delimited macros can have a maximum number
719 * of arguments.
720 */
721 int
722 macro_constant_delimited(MACRO_PROT_ARGS)
723 {
724 int lastarg, flushed, j, c, maxargs, argc;
725 struct mdoc_arg argv[MDOC_LINEARG_MAX];
726 char *p;
727
728 lastarg = ppos;
729 flushed = 0;
730
731 switch (tok) {
732 case (MDOC_No):
733 /* FALLTHROUGH */
734 case (MDOC_Ns):
735 /* FALLTHROUGH */
736 case (MDOC_Ux):
737 /* FALLTHROUGH */
738 case (MDOC_St):
739 maxargs = 0;
740 break;
741 default:
742 maxargs = 1;
743 break;
744 }
745
746 for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
747 lastarg = *pos;
748 c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
749 if (ARGV_EOLN == c || ARGV_WORD == c)
750 break;
751 else if (ARGV_ARG == c)
752 continue;
753 mdoc_argv_free(argc, argv);
754 return(0);
755 }
756
757 c = mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv);
758 mdoc_argv_free(argc, argv);
759
760 if (0 == c)
761 return(0);
762
763 mdoc->next = MDOC_NEXT_CHILD;
764
765 for (j = 0; j < MDOC_LINEARG_MAX; j++) {
766 lastarg = *pos;
767
768 if (j == maxargs && ! flushed) {
769 if ( ! rewind_elem(mdoc, tok))
770 return(0);
771 flushed = 1;
772 }
773
774 c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
775 if (ARGS_ERROR == c)
776 return(0);
777 if (ARGS_PUNCT == c)
778 break;
779 if (ARGS_EOLN == c)
780 break;
781
782 if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
783 if ( ! flushed && ! rewind_elem(mdoc, tok))
784 return(0);
785 flushed = 1;
786 if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
787 return(0);
788 break;
789 }
790
791 if ( ! flushed && mdoc_isdelim(p)) {
792 if ( ! rewind_elem(mdoc, tok))
793 return(0);
794 flushed = 1;
795 }
796
797 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
798 return(0);
799 mdoc->next = MDOC_NEXT_SIBLING;
800 }
801
802 if (MDOC_LINEARG_MAX == j)
803 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
804
805 if ( ! flushed && rewind_elem(mdoc, tok))
806 return(0);
807
808 if (ppos > 1)
809 return(1);
810 return(append_delims(mdoc, tok, line, pos, buf));
811 }
812
813
814 /*
815 * Constant macros span an entire line: they constitute a macro and all
816 * of its arguments and child data.
817 */
818 int
819 macro_constant(MACRO_PROT_ARGS)
820 {
821 int c, lastarg, argc, sz, fl;
822 struct mdoc_arg argv[MDOC_LINEARG_MAX];
823 char *p;
824
825 /* FIXME: parsing macros! */
826
827 fl = 0;
828 if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
829 fl = ARGS_QUOTED;
830
831 for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
832 lastarg = *pos;
833 c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
834 if (ARGV_EOLN == c)
835 break;
836 else if (ARGV_ARG == c)
837 continue;
838 else if (ARGV_WORD == c)
839 break;
840
841 mdoc_argv_free(argc, argv);
842 return(0);
843 }
844
845 c = mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv);
846 mdoc_argv_free(argc, argv);
847
848 if (0 == c)
849 return(0);
850
851 mdoc->next = MDOC_NEXT_CHILD;
852
853 if (MDOC_LINEARG_MAX == argc)
854 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
855
856 for (sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
857 lastarg = *pos;
858 c = mdoc_args(mdoc, line, pos, buf, fl, &p);
859 if (ARGS_ERROR == c)
860 return(0);
861 if (ARGS_EOLN == c)
862 break;
863
864 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
865 return(0);
866 mdoc->next = MDOC_NEXT_SIBLING;
867 }
868
869 if (MDOC_LINEARG_MAX == sz + argc)
870 return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
871
872 return(rewind_elem(mdoc, tok));
873 }
874
875
876 /* ARGSUSED */
877 int
878 macro_obsolete(MACRO_PROT_ARGS)
879 {
880
881 return(mdoc_pwarn(mdoc, line, ppos, WARN_IGN_OBSOLETE));
882 }
883
884
885 int
886 macro_end(struct mdoc *mdoc)
887 {
888
889 assert(mdoc->first);
890 assert(mdoc->last);
891 return(rewind_last(mdoc, mdoc->first));
892 }