]>
git.cameronkatri.com Git - mandoc.git/blob - macro.c
1 /* $Id: macro.c,v 1.54 2009/02/27 09:39:40 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
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
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.
29 * This has scanning/parsing routines, each of which extract a macro and
30 * its arguments and parameters, then know how to progress to the next
36 static int macro_obsolete(MACRO_PROT_ARGS
);
37 static int macro_constant(MACRO_PROT_ARGS
);
38 static int macro_constant_scoped(MACRO_PROT_ARGS
);
39 static int macro_constant_delimited(MACRO_PROT_ARGS
);
40 static int macro_text(MACRO_PROT_ARGS
);
41 static int macro_scoped(MACRO_PROT_ARGS
);
42 static int macro_scoped_close(MACRO_PROT_ARGS
);
43 static int macro_scoped_line(MACRO_PROT_ARGS
);
45 #define REWIND_REWIND (1 << 0)
46 #define REWIND_NOHALT (1 << 1)
47 #define REWIND_HALT (1 << 2)
49 static int rewind_dohalt(int, enum mdoc_type
,
50 const struct mdoc_node
*);
51 static int rewind_alt(int);
52 static int rewind_dobreak(int, const struct mdoc_node
*);
53 static int rewind_elem(struct mdoc
*, int);
54 static int rewind_impblock(struct mdoc
*, int, int, int);
55 static int rewind_expblock(struct mdoc
*, int, int, int);
56 static int rewind_subblock(enum mdoc_type
,
57 struct mdoc
*, int, int, int);
58 static int rewind_last(struct mdoc
*, struct mdoc_node
*);
59 static int append_delims(struct mdoc
*, int, int *, char *);
60 static int lookup(struct mdoc
*, int, int, int, const char *);
61 static int pwarn(struct mdoc
*, int, int, int);
62 static int perr(struct mdoc
*, int, int, int);
71 /* Central table of library: who gets parsed how. */
73 const struct mdoc_macro __mdoc_macros
[MDOC_MAX
] = {
75 { macro_constant
, MDOC_PROLOGUE
}, /* Dd */
76 { macro_constant
, MDOC_PROLOGUE
}, /* Dt */
77 { macro_constant
, MDOC_PROLOGUE
}, /* Os */
78 { macro_scoped
, 0 }, /* Sh */
79 { macro_scoped
, 0 }, /* Ss */
80 { macro_text
, 0 }, /* Pp */
81 { macro_scoped_line
, MDOC_PARSED
}, /* D1 */
82 { macro_scoped_line
, MDOC_PARSED
}, /* Dl */
83 { macro_scoped
, MDOC_EXPLICIT
}, /* Bd */
84 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Ed */
85 { macro_scoped
, MDOC_EXPLICIT
}, /* Bl */
86 { macro_scoped_close
, MDOC_EXPLICIT
}, /* El */
87 { macro_scoped
, MDOC_PARSED
}, /* It */
88 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ad */
89 { macro_text
, MDOC_PARSED
}, /* An */
90 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ar */
91 { macro_constant
, 0 }, /* Cd */
92 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Cm */
93 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dv */
94 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Er */
95 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ev */
96 { macro_constant
, 0 }, /* Ex */
97 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fa */
98 { macro_constant
, 0 }, /* Fd */
99 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fl */
100 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fn */
101 { macro_text
, MDOC_PARSED
}, /* Ft */
102 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ic */
103 { macro_constant
, 0 }, /* In */
104 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Li */
105 { macro_constant
, 0 }, /* Nd */
106 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nm */
107 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Op */
108 { macro_obsolete
, 0 }, /* Ot */
109 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pa */
110 { macro_constant
, 0 }, /* Rv */
111 /* XXX - .St supposed to be (but isn't) callable. */
112 { macro_constant_delimited
, MDOC_PARSED
}, /* St */
113 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Va */
114 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Vt */
115 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Xr */
116 { macro_constant
, 0 }, /* %A */
117 { macro_constant
, 0 }, /* %B */
118 { macro_constant
, 0 }, /* %D */
119 { macro_constant
, 0 }, /* %I */
120 { macro_constant
, 0 }, /* %J */
121 { macro_constant
, 0 }, /* %N */
122 { macro_constant
, 0 }, /* %O */
123 { macro_constant
, 0 }, /* %P */
124 { macro_constant
, 0 }, /* %R */
125 { macro_constant
, 0 }, /* %T */
126 { macro_constant
, 0 }, /* %V */
127 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ac */
128 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Ao */
129 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Aq */
130 { macro_constant_delimited
, 0 }, /* At */
131 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Bc */
132 { macro_scoped
, MDOC_EXPLICIT
}, /* Bf */
133 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bo */
134 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bq */
135 { macro_constant_delimited
, MDOC_PARSED
}, /* Bsx */
136 { macro_constant_delimited
, MDOC_PARSED
}, /* Bx */
137 { macro_constant
, 0 }, /* Db */
138 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Dc */
139 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Do */
140 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dq */
141 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ec */
142 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Ef */
143 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Em */
144 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Eo */
145 { macro_constant_delimited
, MDOC_PARSED
}, /* Fx */
146 { macro_text
, MDOC_PARSED
}, /* Ms */
147 { macro_constant_delimited
, MDOC_CALLABLE
| MDOC_PARSED
}, /* No */
148 { macro_constant_delimited
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ns */
149 { macro_constant_delimited
, MDOC_PARSED
}, /* Nx */
150 { macro_constant_delimited
, MDOC_PARSED
}, /* Ox */
151 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Pc */
152 { macro_constant_delimited
, MDOC_PARSED
}, /* Pf */
153 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Po */
154 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pq */
155 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Qc */
156 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ql */
157 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Qo */
158 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Qq */
159 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Re */
160 { macro_scoped
, MDOC_EXPLICIT
}, /* Rs */
161 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Sc */
162 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* So */
163 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sq */
164 { macro_constant
, 0 }, /* Sm */
165 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sx */
166 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sy */
167 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Tn */
168 { macro_constant_delimited
, MDOC_PARSED
}, /* Ux */
169 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Xc */
170 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Xo */
171 /* XXX - .Fo supposed to be (but isn't) callable. */
172 { macro_scoped
, MDOC_EXPLICIT
}, /* Fo */
173 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Fc */
174 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Oo */
175 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Oc */
176 { macro_scoped
, MDOC_EXPLICIT
}, /* Bk */
177 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Ek */
178 { macro_constant
, 0 }, /* Bt */
179 { macro_constant
, 0 }, /* Hf */
180 { macro_obsolete
, 0 }, /* Fr */
181 { macro_constant
, 0 }, /* Ud */
184 const struct mdoc_macro
* const mdoc_macros
= __mdoc_macros
;
188 perr(struct mdoc
*mdoc
, int line
, int pos
, int type
)
194 c
= mdoc_perr(mdoc
, line
, pos
,
195 "closing macro has prior context");
198 c
= mdoc_perr(mdoc
, line
, pos
,
199 "macro doesn't expect parameters");
202 c
= mdoc_perr(mdoc
, line
, pos
,
203 "argument hard-limit %d reached",
214 pwarn(struct mdoc
*mdoc
, int line
, int pos
, int type
)
220 c
= mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
,
221 "macro-like parameter");
224 c
= mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
,
225 "macro is marked obsolete");
236 lookup(struct mdoc
*mdoc
, int line
, int pos
, int from
, const char *p
)
240 res
= mdoc_find(mdoc
, p
);
241 if (MDOC_PARSED
& mdoc_macros
[from
].flags
)
245 if ( ! pwarn(mdoc
, line
, pos
, WMACPARM
))
252 rewind_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
256 mdoc
->next
= MDOC_NEXT_SIBLING
;
259 while (mdoc
->last
!= to
) {
260 if ( ! mdoc_valid_post(mdoc
))
262 if ( ! mdoc_action_post(mdoc
))
264 mdoc
->last
= mdoc
->last
->parent
;
268 if ( ! mdoc_valid_post(mdoc
))
270 return(mdoc_action_post(mdoc
));
317 rewind_dohalt(int tok
, enum mdoc_type type
, const struct mdoc_node
*p
)
320 if (MDOC_ROOT
== p
->type
)
322 if (MDOC_VALID
& p
->flags
)
323 return(REWIND_NOHALT
);
326 /* One-liner implicit-scope. */
346 assert(MDOC_HEAD
!= type
);
347 assert(MDOC_TAIL
!= type
);
348 if (type
== p
->type
&& tok
== p
->tok
)
349 return(REWIND_REWIND
);
352 /* Multi-line implicit-scope. */
354 assert(MDOC_TAIL
!= type
);
355 if (type
== p
->type
&& tok
== p
->tok
)
356 return(REWIND_REWIND
);
357 if (MDOC_BODY
== p
->type
&& MDOC_Bl
== p
->tok
)
361 if (type
== p
->type
&& tok
== p
->tok
)
362 return(REWIND_REWIND
);
365 assert(MDOC_TAIL
!= type
);
366 if (type
== p
->type
&& tok
== p
->tok
)
367 return(REWIND_REWIND
);
368 if (MDOC_BODY
== p
->type
&& MDOC_Sh
== p
->tok
)
372 /* Multi-line explicit scope start. */
402 if (type
== p
->type
&& tok
== p
->tok
)
403 return(REWIND_REWIND
);
406 /* Multi-line explicit scope close. */
436 if (type
== p
->type
&& rewind_alt(tok
) == p
->tok
)
437 return(REWIND_REWIND
);
444 return(REWIND_NOHALT
);
449 rewind_dobreak(int tok
, const struct mdoc_node
*p
)
452 assert(MDOC_ROOT
!= p
->type
);
453 if (MDOC_ELEM
== p
->type
)
455 if (MDOC_TEXT
== p
->type
)
457 if (MDOC_VALID
& p
->flags
)
461 /* Implicit rules. */
463 return(MDOC_It
== p
->tok
);
465 return(MDOC_Ss
== p
->tok
);
467 if (MDOC_Ss
== p
->tok
)
469 return(MDOC_Sh
== p
->tok
);
471 /* Extra scope rules. */
473 if (MDOC_It
== p
->tok
)
480 if (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)
481 return(p
->tok
== rewind_alt(tok
));
482 else if (MDOC_BLOCK
== p
->type
)
485 return(tok
== p
->tok
);
490 rewind_elem(struct mdoc
*mdoc
, int tok
)
495 if (MDOC_ELEM
!= n
->type
)
497 assert(MDOC_ELEM
== n
->type
);
498 assert(tok
== n
->tok
);
500 return(rewind_last(mdoc
, n
));
505 rewind_subblock(enum mdoc_type type
, struct mdoc
*mdoc
,
506 int tok
, int line
, int ppos
)
512 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
513 c
= rewind_dohalt(tok
, type
, n
);
514 if (REWIND_HALT
== c
)
516 if (REWIND_REWIND
== c
)
518 else if (rewind_dobreak(tok
, n
))
520 return(mdoc_perr(mdoc
, line
, ppos
, "scope breaks prior %s", mdoc_node2a(n
)));
524 return(rewind_last(mdoc
, n
));
529 rewind_expblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
535 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
536 c
= rewind_dohalt(tok
, MDOC_BLOCK
, n
);
537 if (REWIND_HALT
== c
)
538 return(perr(mdoc
, line
, ppos
, ENOCTX
));
539 if (REWIND_REWIND
== c
)
541 else if (rewind_dobreak(tok
, n
))
543 return(mdoc_perr(mdoc
, line
, ppos
,
544 "scope breaks prior %s",
549 return(rewind_last(mdoc
, n
));
554 rewind_impblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
560 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
561 c
= rewind_dohalt(tok
, MDOC_BLOCK
, n
);
562 if (REWIND_HALT
== c
)
564 else if (REWIND_REWIND
== c
)
566 else if (rewind_dobreak(tok
, n
))
568 return(mdoc_perr(mdoc
, line
, ppos
,
569 "scope breaks prior %s",
574 return(rewind_last(mdoc
, n
));
579 append_delims(struct mdoc
*mdoc
, int line
, int *pos
, char *buf
)
589 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
590 assert(ARGS_PHRASE
!= c
);
594 else if (ARGS_EOLN
== c
)
596 assert(mdoc_isdelim(p
));
597 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
599 mdoc
->next
= MDOC_NEXT_SIBLING
;
607 * Close out an explicit scope. This optionally parses a TAIL type with
608 * a set number of TEXT children.
611 macro_scoped_close(MACRO_PROT_ARGS
)
613 int tt
, j
, c
, lastarg
, maxargs
, flushed
;
625 tt
= rewind_alt(tok
);
627 mdoc_msg(mdoc
, "parse: %s closing %s",
628 mdoc_macronames
[tok
], mdoc_macronames
[tt
]);
630 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
631 if (0 == buf
[*pos
]) {
632 if ( ! rewind_subblock(MDOC_BODY
, mdoc
,
635 return(rewind_expblock(mdoc
, tok
, line
, ppos
));
637 return(perr(mdoc
, line
, ppos
, ENOPARMS
));
640 if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
647 if ( ! mdoc_tail_alloc(mdoc
, line
, ppos
, tt
))
649 mdoc
->next
= MDOC_NEXT_CHILD
;
652 for (j
= 0; /* No sentinel. */; j
++) {
655 if (j
== maxargs
&& ! flushed
) {
656 if ( ! rewind_expblock(mdoc
, tok
, line
, ppos
))
661 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
662 assert(ARGS_PHRASE
!= c
);
671 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
673 else if (MDOC_MAX
!= c
) {
675 if ( ! rewind_expblock(mdoc
, tok
,
680 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
685 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
687 mdoc
->next
= MDOC_NEXT_SIBLING
;
690 if ( ! flushed
&& ! rewind_expblock(mdoc
, tok
, line
, ppos
))
695 return(append_delims(mdoc
, line
, pos
, buf
));
700 * A general text macro. This is a complex case because of punctuation.
701 * If a text macro is followed by words, then punctuation, the macro is
702 * "stopped" and "reopened" following the punctuation. Thus, the
713 * This must handle the following situations:
724 macro_text(MACRO_PROT_ARGS
)
726 int la
, lastpunct
, c
, w
, argc
;
727 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
733 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
735 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
738 if (ARGV_WORD
== c
) {
741 } else if (ARGV_ARG
== c
)
744 mdoc_argv_free(argc
, argv
);
748 if (MDOC_LINEARG_MAX
== argc
) {
749 mdoc_argv_free(argc
- 1, argv
);
750 return(perr(mdoc
, line
, ppos
, EARGVLIM
));
753 c
= mdoc_elem_alloc(mdoc
, line
, ppos
,
754 tok
, (size_t)argc
, argv
);
757 mdoc_argv_free(argc
, argv
);
761 mdoc
->next
= MDOC_NEXT_CHILD
;
766 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
767 assert(ARGS_PHRASE
!= c
);
769 if (ARGS_ERROR
== w
) {
770 mdoc_argv_free(argc
, argv
);
779 c
= ARGS_QWORD
== w
? MDOC_MAX
:
780 lookup(mdoc
, line
, la
, tok
, p
);
782 if (MDOC_MAX
!= c
&& -1 != c
) {
783 if (0 == lastpunct
&& ! rewind_elem(mdoc
, tok
)) {
784 mdoc_argv_free(argc
, argv
);
787 mdoc_argv_free(argc
, argv
);
788 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
793 return(append_delims(mdoc
, line
, pos
, buf
));
794 } else if (-1 == c
) {
795 mdoc_argv_free(argc
, argv
);
799 if (ARGS_QWORD
!= w
&& mdoc_isdelim(p
)) {
800 if (0 == lastpunct
&& ! rewind_elem(mdoc
, tok
)) {
801 mdoc_argv_free(argc
, argv
);
805 } else if (lastpunct
) {
806 c
= mdoc_elem_alloc(mdoc
, line
, ppos
,
807 tok
, (size_t)argc
, argv
);
809 mdoc_argv_free(argc
, argv
);
812 mdoc
->next
= MDOC_NEXT_CHILD
;
816 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
818 mdoc
->next
= MDOC_NEXT_SIBLING
;
821 mdoc_argv_free(argc
, argv
);
823 if (0 == lastpunct
&& ! rewind_elem(mdoc
, tok
))
827 return(append_delims(mdoc
, line
, pos
, buf
));
832 * Handle explicit-scope (having a different closure token) and implicit
833 * scope (closing out prior scopes when re-invoked) macros. These
834 * constitute the BLOCK type and usually span multiple lines. These
835 * always have HEAD and sometimes have BODY types. In the multi-line
852 * Note that the `.It' macro, possibly the most difficult (as it has
853 * embedded scope, etc.) is handled by this routine.
856 macro_scoped(MACRO_PROT_ARGS
)
858 int c
, lastarg
, argc
;
859 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
862 assert ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
));
864 /* First rewind extant implicit scope. */
866 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)) {
867 if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
869 if ( ! rewind_impblock(mdoc
, tok
, line
, ppos
))
873 /* Parse arguments. */
875 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
877 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
880 if (ARGV_WORD
== c
) {
883 } else if (ARGV_ARG
== c
)
885 mdoc_argv_free(argc
, argv
);
889 if (MDOC_LINEARG_MAX
== argc
) {
890 mdoc_argv_free(argc
- 1, argv
);
891 return(perr(mdoc
, line
, ppos
, EARGVLIM
));
894 c
= mdoc_block_alloc(mdoc
, line
, ppos
,
895 tok
, (size_t)argc
, argv
);
896 mdoc_argv_free(argc
, argv
);
901 mdoc
->next
= MDOC_NEXT_CHILD
;
903 if (0 == buf
[*pos
]) {
904 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
906 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
,
909 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
911 mdoc
->next
= MDOC_NEXT_CHILD
;
915 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
917 mdoc
->next
= MDOC_NEXT_CHILD
;
921 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
927 if (ARGS_PHRASE
== c
) {
929 if ( ! mdoc_phrase(mdoc, line, lastarg, buf))
935 /* FIXME: if .It -column, the lookup must be for a
936 * sub-line component. BLAH. */
938 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
942 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
944 mdoc
->next
= MDOC_NEXT_SIBLING
;
948 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
953 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
955 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
958 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
960 mdoc
->next
= MDOC_NEXT_CHILD
;
967 * This handles a case of implicitly-scoped macro (BLOCK) limited to a
968 * single line. Instead of being closed out by a subsequent call to
969 * another macro, the scope is closed at the end of line. These don't
970 * have BODY or TAIL types. Notice that the punctuation falls outside
973 * .Qq a Fl b Ar d ; ;
986 macro_scoped_line(MACRO_PROT_ARGS
)
991 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, 0, NULL
))
993 mdoc
->next
= MDOC_NEXT_CHILD
;
995 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
997 mdoc
->next
= MDOC_NEXT_SIBLING
;
998 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1000 mdoc
->next
= MDOC_NEXT_CHILD
;
1002 /* XXX - no known argument macros. */
1007 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1008 assert(ARGS_PHRASE
!= c
);
1010 if (ARGS_ERROR
== c
)
1012 if (ARGS_PUNCT
== c
)
1017 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1019 else if (MDOC_MAX
== c
) {
1020 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1022 mdoc
->next
= MDOC_NEXT_SIBLING
;
1026 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1032 if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
1034 if ( ! append_delims(mdoc
, line
, pos
, buf
))
1036 } else if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
1038 return(rewind_impblock(mdoc
, tok
, line
, ppos
));
1043 * A constant-scoped macro is like a simple-scoped macro (mdoc_scoped)
1044 * except that it doesn't handle implicit scopes and explicit ones have
1045 * a fixed number of TEXT children to the BODY.
1058 macro_constant_scoped(MACRO_PROT_ARGS
)
1060 int lastarg
, flushed
, j
, c
, maxargs
;
1075 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, 0, NULL
))
1077 mdoc
->next
= MDOC_NEXT_CHILD
;
1080 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1082 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1084 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1087 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1090 mdoc
->next
= MDOC_NEXT_CHILD
;
1092 for (j
= 0; /* No sentinel. */; j
++) {
1095 if (j
== maxargs
&& ! flushed
) {
1096 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1099 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1101 mdoc
->next
= MDOC_NEXT_CHILD
;
1104 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1105 assert(ARGS_PHRASE
!= c
);
1107 if (ARGS_ERROR
== c
)
1109 if (ARGS_PUNCT
== c
)
1114 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1116 else if (MDOC_MAX
!= c
) {
1118 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
,
1122 if ( ! mdoc_body_alloc(mdoc
, line
,
1125 mdoc
->next
= MDOC_NEXT_CHILD
;
1127 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
,
1133 if ( ! flushed
&& mdoc_isdelim(p
)) {
1134 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
,
1138 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1140 mdoc
->next
= MDOC_NEXT_CHILD
;
1143 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1145 mdoc
->next
= MDOC_NEXT_SIBLING
;
1149 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1151 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1153 mdoc
->next
= MDOC_NEXT_CHILD
;
1158 return(append_delims(mdoc
, line
, pos
, buf
));
1163 * A delimited constant is very similar to the macros parsed by
1164 * macro_text except that, in the event of punctuation, the macro isn't
1165 * "re-opened" as it is in macro_text. Also, these macros have a fixed
1166 * number of parameters.
1176 macro_constant_delimited(MACRO_PROT_ARGS
)
1178 int lastarg
, flushed
, j
, c
, maxargs
, argc
,
1180 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
1210 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
1212 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
1215 if (ARGV_WORD
== c
) {
1218 } else if (ARGV_ARG
== c
)
1220 mdoc_argv_free(argc
, argv
);
1224 if (MDOC_LINEARG_MAX
== argc
) {
1225 mdoc_argv_free(argc
- 1, argv
);
1226 return(perr(mdoc
, line
, ppos
, EARGVLIM
));
1229 c
= mdoc_elem_alloc(mdoc
, line
, ppos
,
1230 tok
, (size_t)argc
, argv
);
1232 mdoc_argv_free(argc
, argv
);
1237 mdoc
->next
= MDOC_NEXT_CHILD
;
1239 for (j
= 0; /* No sentinel. */; j
++) {
1242 if (j
== maxargs
&& ! flushed
) {
1243 if ( ! rewind_elem(mdoc
, tok
))
1248 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1249 assert(ARGS_PHRASE
!= c
);
1251 if (ARGS_ERROR
== c
)
1253 if (ARGS_PUNCT
== c
)
1258 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1260 else if (MDOC_MAX
!= c
) {
1261 if ( ! flushed
&& ! rewind_elem(mdoc
, tok
))
1264 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1269 if ( ! flushed
&& mdoc_isdelim(p
) && ! igndelim
) {
1270 if ( ! rewind_elem(mdoc
, tok
))
1275 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1277 mdoc
->next
= MDOC_NEXT_SIBLING
;
1280 if ( ! flushed
&& ! rewind_elem(mdoc
, tok
))
1285 return(append_delims(mdoc
, line
, pos
, buf
));
1290 * A constant macro is the simplest classification. It spans an entire
1294 macro_constant(MACRO_PROT_ARGS
)
1297 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
1300 assert( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
));
1302 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
1304 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
1307 if (ARGV_WORD
== c
) {
1310 } else if (ARGV_ARG
== c
)
1313 mdoc_argv_free(argc
, argv
);
1317 if (MDOC_LINEARG_MAX
== argc
) {
1318 mdoc_argv_free(argc
- 1, argv
);
1319 return(perr(mdoc
, line
, ppos
, EARGVLIM
));
1322 c
= mdoc_elem_alloc(mdoc
, line
, ppos
,
1323 tok
, (size_t)argc
, argv
);
1325 mdoc_argv_free(argc
, argv
);
1330 mdoc
->next
= MDOC_NEXT_CHILD
;
1334 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1335 assert(ARGS_PHRASE
!= c
);
1337 if (ARGS_ERROR
== w
)
1342 c
= ARGS_QWORD
== w
? MDOC_MAX
:
1343 lookup(mdoc
, line
, la
, tok
, p
);
1345 if (MDOC_MAX
!= c
&& -1 != c
) {
1346 if ( ! rewind_elem(mdoc
, tok
))
1348 return(mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
));
1352 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1354 mdoc
->next
= MDOC_NEXT_SIBLING
;
1357 return(rewind_elem(mdoc
, tok
));
1363 macro_obsolete(MACRO_PROT_ARGS
)
1366 return(pwarn(mdoc
, line
, ppos
, WOBS
));
1371 * This is called at the end of parsing. It must traverse up the tree,
1372 * closing out open [implicit] scopes. Obviously, open explicit scopes
1376 macro_end(struct mdoc
*mdoc
)
1378 struct mdoc_node
*n
;
1380 assert(mdoc
->first
);
1383 /* Scan for open explicit scopes. */
1385 n
= MDOC_VALID
& mdoc
->last
->flags
?
1386 mdoc
->last
->parent
: mdoc
->last
;
1388 for ( ; n
; n
= n
->parent
) {
1389 if (MDOC_BLOCK
!= n
->type
)
1391 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[n
->tok
].flags
))
1393 return(mdoc_nerr(mdoc
, n
,
1394 "macro scope still open on exit"));
1397 return(rewind_last(mdoc
, mdoc
->first
));