]>
git.cameronkatri.com Git - mandoc.git/blob - macro.c
1 /* $Id: macro.c,v 1.60 2009/03/08 19:32:03 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);
63 static int scopewarn(struct mdoc
*, enum mdoc_type
, int, int,
64 const struct mdoc_node
*);
72 /* Central table of library: who gets parsed how. */
74 const struct mdoc_macro __mdoc_macros
[MDOC_MAX
] = {
76 { macro_constant
, MDOC_PROLOGUE
}, /* Dd */
77 { macro_constant
, MDOC_PROLOGUE
}, /* Dt */
78 { macro_constant
, MDOC_PROLOGUE
}, /* Os */
79 { macro_scoped
, 0 }, /* Sh */
80 { macro_scoped
, 0 }, /* Ss */
81 { macro_text
, 0 }, /* Pp */
82 { macro_scoped_line
, MDOC_PARSED
}, /* D1 */
83 { macro_scoped_line
, MDOC_PARSED
}, /* Dl */
84 { macro_scoped
, MDOC_EXPLICIT
}, /* Bd */
85 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Ed */
86 { macro_scoped
, MDOC_EXPLICIT
}, /* Bl */
87 { macro_scoped_close
, MDOC_EXPLICIT
}, /* El */
88 { macro_scoped
, MDOC_PARSED
}, /* It */
89 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ad */
90 { macro_text
, MDOC_PARSED
}, /* An */
91 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ar */
92 { macro_constant
, 0 }, /* Cd */
93 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Cm */
94 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dv */
95 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Er */
96 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ev */
97 { macro_constant
, 0 }, /* Ex */
98 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fa */
99 { macro_constant
, 0 }, /* Fd */
100 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fl */
101 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fn */
102 { macro_text
, MDOC_PARSED
}, /* Ft */
103 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ic */
104 { macro_constant
, 0 }, /* In */
105 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Li */
106 { macro_constant
, 0 }, /* Nd */
107 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nm */
108 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Op */
109 { macro_obsolete
, 0 }, /* Ot */
110 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pa */
111 { macro_constant
, 0 }, /* Rv */
112 /* XXX - .St supposed to be (but isn't) callable. */
113 { macro_constant_delimited
, MDOC_PARSED
}, /* St */
114 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Va */
115 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Vt */
116 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Xr */
117 { macro_constant
, 0 }, /* %A */
118 { macro_constant
, 0 }, /* %B */
119 { macro_constant
, 0 }, /* %D */
120 { macro_constant
, 0 }, /* %I */
121 { macro_constant
, 0 }, /* %J */
122 { macro_constant
, 0 }, /* %N */
123 { macro_constant
, 0 }, /* %O */
124 { macro_constant
, 0 }, /* %P */
125 { macro_constant
, 0 }, /* %R */
126 { macro_constant
, 0 }, /* %T */
127 { macro_constant
, 0 }, /* %V */
128 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ac */
129 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Ao */
130 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Aq */
131 { macro_constant_delimited
, 0 }, /* At */
132 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Bc */
133 { macro_scoped
, MDOC_EXPLICIT
}, /* Bf */
134 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bo */
135 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bq */
136 { macro_constant_delimited
, MDOC_PARSED
}, /* Bsx */
137 { macro_constant_delimited
, MDOC_PARSED
}, /* Bx */
138 { macro_constant
, 0 }, /* Db */
139 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Dc */
140 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Do */
141 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dq */
142 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ec */
143 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Ef */
144 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Em */
145 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Eo */
146 { macro_constant_delimited
, MDOC_PARSED
}, /* Fx */
147 { macro_text
, MDOC_PARSED
}, /* Ms */
148 { macro_constant_delimited
, MDOC_CALLABLE
| MDOC_PARSED
}, /* No */
149 { macro_constant_delimited
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ns */
150 { macro_constant_delimited
, MDOC_PARSED
}, /* Nx */
151 { macro_constant_delimited
, MDOC_PARSED
}, /* Ox */
152 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Pc */
153 { macro_constant_delimited
, MDOC_PARSED
}, /* Pf */
154 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Po */
155 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pq */
156 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Qc */
157 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ql */
158 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Qo */
159 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Qq */
160 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Re */
161 { macro_scoped
, MDOC_EXPLICIT
}, /* Rs */
162 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Sc */
163 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* So */
164 { macro_scoped_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sq */
165 { macro_constant
, 0 }, /* Sm */
166 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sx */
167 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sy */
168 { macro_text
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Tn */
169 { macro_constant_delimited
, MDOC_PARSED
}, /* Ux */
170 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Xc */
171 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Xo */
172 /* XXX - .Fo supposed to be (but isn't) callable. */
173 { macro_scoped
, MDOC_EXPLICIT
}, /* Fo */
174 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Fc */
175 { macro_constant_scoped
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Oo */
176 { macro_scoped_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Oc */
177 { macro_scoped
, MDOC_EXPLICIT
}, /* Bk */
178 { macro_scoped_close
, MDOC_EXPLICIT
}, /* Ek */
179 { macro_constant
, 0 }, /* Bt */
180 { macro_constant
, 0 }, /* Hf */
181 { macro_obsolete
, 0 }, /* Fr */
182 { macro_constant
, 0 }, /* Ud */
183 { macro_constant
, 0 }, /* Lb */
186 const struct mdoc_macro
* const mdoc_macros
= __mdoc_macros
;
190 perr(struct mdoc
*mdoc
, int line
, int pos
, int type
)
196 c
= mdoc_perr(mdoc
, line
, pos
,
197 "closing macro has no prior context");
200 c
= mdoc_perr(mdoc
, line
, pos
,
201 "macro doesn't expect parameters");
211 pwarn(struct mdoc
*mdoc
, int line
, int pos
, int type
)
217 c
= mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
,
218 "macro-like parameter");
221 c
= mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
,
222 "macro is marked obsolete");
233 scopewarn(struct mdoc
*mdoc
, enum mdoc_type type
,
234 int line
, int pos
, const struct mdoc_node
*p
)
236 const char *n
, *t
, *tt
;
254 n
= mdoc_macronames
[p
->tok
];
258 n
= mdoc_macronames
[p
->tok
];
262 n
= mdoc_macronames
[p
->tok
];
269 if ( ! (MDOC_IGN_SCOPE
& mdoc
->pflags
))
270 return(mdoc_perr(mdoc
, line
, pos
,
271 "%s scope breaks %s scope of %s",
273 return(mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
,
274 "%s scope breaks %s scope of %s",
280 lookup(struct mdoc
*mdoc
, int line
, int pos
, int from
, const char *p
)
284 res
= mdoc_tokhash_find(mdoc
->htab
, p
);
285 if (MDOC_PARSED
& mdoc_macros
[from
].flags
)
289 if ( ! pwarn(mdoc
, line
, pos
, WMACPARM
))
296 rewind_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
300 mdoc
->next
= MDOC_NEXT_SIBLING
;
303 while (mdoc
->last
!= to
) {
304 if ( ! mdoc_valid_post(mdoc
))
306 if ( ! mdoc_action_post(mdoc
))
308 mdoc
->last
= mdoc
->last
->parent
;
312 if ( ! mdoc_valid_post(mdoc
))
314 return(mdoc_action_post(mdoc
));
361 rewind_dohalt(int tok
, enum mdoc_type type
, const struct mdoc_node
*p
)
364 if (MDOC_ROOT
== p
->type
)
366 if (MDOC_VALID
& p
->flags
)
367 return(REWIND_NOHALT
);
370 /* One-liner implicit-scope. */
390 assert(MDOC_HEAD
!= type
);
391 assert(MDOC_TAIL
!= type
);
392 if (type
== p
->type
&& tok
== p
->tok
)
393 return(REWIND_REWIND
);
396 /* Multi-line implicit-scope. */
398 assert(MDOC_TAIL
!= type
);
399 if (type
== p
->type
&& tok
== p
->tok
)
400 return(REWIND_REWIND
);
401 if (MDOC_BODY
== p
->type
&& MDOC_Bl
== p
->tok
)
405 if (type
== p
->type
&& tok
== p
->tok
)
406 return(REWIND_REWIND
);
409 assert(MDOC_TAIL
!= type
);
410 if (type
== p
->type
&& tok
== p
->tok
)
411 return(REWIND_REWIND
);
412 if (MDOC_BODY
== p
->type
&& MDOC_Sh
== p
->tok
)
416 /* Multi-line explicit scope start. */
446 if (type
== p
->type
&& tok
== p
->tok
)
447 return(REWIND_REWIND
);
450 /* Multi-line explicit scope close. */
480 if (type
== p
->type
&& rewind_alt(tok
) == p
->tok
)
481 return(REWIND_REWIND
);
488 return(REWIND_NOHALT
);
493 rewind_dobreak(int tok
, const struct mdoc_node
*p
)
496 assert(MDOC_ROOT
!= p
->type
);
497 if (MDOC_ELEM
== p
->type
)
499 if (MDOC_TEXT
== p
->type
)
501 if (MDOC_VALID
& p
->flags
)
505 /* Implicit rules. */
507 return(MDOC_It
== p
->tok
);
509 return(MDOC_Ss
== p
->tok
);
511 if (MDOC_Ss
== p
->tok
)
513 return(MDOC_Sh
== p
->tok
);
515 /* Extra scope rules. */
517 if (MDOC_It
== p
->tok
)
524 if (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)
525 return(p
->tok
== rewind_alt(tok
));
526 else if (MDOC_BLOCK
== p
->type
)
529 return(tok
== p
->tok
);
534 rewind_elem(struct mdoc
*mdoc
, int tok
)
539 if (MDOC_ELEM
!= n
->type
)
541 assert(MDOC_ELEM
== n
->type
);
542 assert(tok
== n
->tok
);
544 return(rewind_last(mdoc
, n
));
549 rewind_subblock(enum mdoc_type type
, struct mdoc
*mdoc
,
550 int tok
, int line
, int ppos
)
556 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
557 c
= rewind_dohalt(tok
, type
, n
);
558 if (REWIND_HALT
== c
)
560 if (REWIND_REWIND
== c
)
562 else if (rewind_dobreak(tok
, n
))
564 if ( ! scopewarn(mdoc
, type
, line
, ppos
, n
))
569 return(rewind_last(mdoc
, n
));
574 rewind_expblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
580 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
581 c
= rewind_dohalt(tok
, MDOC_BLOCK
, n
);
582 if (REWIND_HALT
== c
)
583 return(perr(mdoc
, line
, ppos
, ENOCTX
));
584 if (REWIND_REWIND
== c
)
586 else if (rewind_dobreak(tok
, n
))
588 if ( ! scopewarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
593 return(rewind_last(mdoc
, n
));
598 rewind_impblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
604 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
605 c
= rewind_dohalt(tok
, MDOC_BLOCK
, n
);
606 if (REWIND_HALT
== c
)
608 else if (REWIND_REWIND
== c
)
610 else if (rewind_dobreak(tok
, n
))
612 if ( ! scopewarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
617 return(rewind_last(mdoc
, n
));
622 append_delims(struct mdoc
*mdoc
, int line
, int *pos
, char *buf
)
632 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
633 assert(ARGS_PHRASE
!= c
);
637 else if (ARGS_EOLN
== c
)
639 assert(mdoc_isdelim(p
));
640 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
642 mdoc
->next
= MDOC_NEXT_SIBLING
;
650 * Close out an explicit scope. This optionally parses a TAIL type with
651 * a set number of TEXT children.
654 macro_scoped_close(MACRO_PROT_ARGS
)
656 int tt
, j
, c
, lastarg
, maxargs
, flushed
;
668 tt
= rewind_alt(tok
);
670 mdoc_msg(mdoc
, "parse: %s closing %s",
671 mdoc_macronames
[tok
], mdoc_macronames
[tt
]);
673 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
674 if (0 == buf
[*pos
]) {
675 if ( ! rewind_subblock(MDOC_BODY
, mdoc
,
678 return(rewind_expblock(mdoc
, tok
, line
, ppos
));
680 return(perr(mdoc
, line
, ppos
, ENOPARMS
));
683 if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
690 if ( ! mdoc_tail_alloc(mdoc
, line
, ppos
, tt
))
692 mdoc
->next
= MDOC_NEXT_CHILD
;
695 for (j
= 0; /* No sentinel. */; j
++) {
698 if (j
== maxargs
&& ! flushed
) {
699 if ( ! rewind_expblock(mdoc
, tok
, line
, ppos
))
704 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
705 assert(ARGS_PHRASE
!= c
);
714 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
716 else if (MDOC_MAX
!= c
) {
718 if ( ! rewind_expblock(mdoc
, tok
,
723 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
728 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
730 mdoc
->next
= MDOC_NEXT_SIBLING
;
733 if ( ! flushed
&& ! rewind_expblock(mdoc
, tok
, line
, ppos
))
738 return(append_delims(mdoc
, line
, pos
, buf
));
743 * A general text macro. This is a complex case because of punctuation.
744 * If a text macro is followed by words, then punctuation, the macro is
745 * "stopped" and "reopened" following the punctuation. Thus, the
756 * This must handle the following situations:
767 macro_text(MACRO_PROT_ARGS
)
769 int la
, lastpunct
, c
, w
;
770 struct mdoc_arg
*arg
;
779 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
782 if (ARGV_WORD
== c
) {
785 } else if (ARGV_ARG
== c
)
791 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
794 mdoc
->next
= MDOC_NEXT_CHILD
;
799 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
800 assert(ARGS_PHRASE
!= c
);
809 c
= ARGS_QWORD
== w
? MDOC_MAX
:
810 lookup(mdoc
, line
, la
, tok
, p
);
812 if (MDOC_MAX
!= c
&& -1 != c
) {
813 if (0 == lastpunct
&& ! rewind_elem(mdoc
, tok
))
815 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
820 return(append_delims(mdoc
, line
, pos
, buf
));
824 /* FIXME: .Fl and .Ar handling of `|'. */
826 if (ARGS_QWORD
!= w
&& mdoc_isdelim(p
)) {
827 if (0 == lastpunct
&& ! rewind_elem(mdoc
, tok
))
830 } else if (lastpunct
) {
831 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
836 mdoc
->next
= MDOC_NEXT_CHILD
;
840 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
842 mdoc
->next
= MDOC_NEXT_SIBLING
;
845 if (0 == lastpunct
&& ! rewind_elem(mdoc
, tok
))
849 return(append_delims(mdoc
, line
, pos
, buf
));
854 * Handle explicit-scope (having a different closure token) and implicit
855 * scope (closing out prior scopes when re-invoked) macros. These
856 * constitute the BLOCK type and usually span multiple lines. These
857 * always have HEAD and sometimes have BODY types. In the multi-line
874 * Note that the `.It' macro, possibly the most difficult (as it has
875 * embedded scope, etc.) is handled by this routine.
878 macro_scoped(MACRO_PROT_ARGS
)
881 struct mdoc_arg
*arg
;
884 assert ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
));
886 /* First rewind extant implicit scope. */
888 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)) {
889 if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
891 if ( ! rewind_impblock(mdoc
, tok
, line
, ppos
))
895 /* Parse arguments. */
901 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
904 if (ARGV_WORD
== c
) {
907 } else if (ARGV_ARG
== c
)
913 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, arg
))
916 mdoc
->next
= MDOC_NEXT_CHILD
;
918 if (0 == buf
[*pos
]) {
919 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
921 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
,
924 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
926 mdoc
->next
= MDOC_NEXT_CHILD
;
930 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
932 mdoc
->next
= MDOC_NEXT_CHILD
;
936 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
942 if (ARGS_PHRASE
== c
) {
944 if ( ! mdoc_phrase(mdoc, line, lastarg, buf))
950 /* FIXME: if .It -column, the lookup must be for a
951 * sub-line component. BLAH. */
953 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
957 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
959 mdoc
->next
= MDOC_NEXT_SIBLING
;
963 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
968 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
970 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
973 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
975 mdoc
->next
= MDOC_NEXT_CHILD
;
982 * This handles a case of implicitly-scoped macro (BLOCK) limited to a
983 * single line. Instead of being closed out by a subsequent call to
984 * another macro, the scope is closed at the end of line. These don't
985 * have BODY or TAIL types. Notice that the punctuation falls outside
988 * .Qq a Fl b Ar d ; ;
1001 macro_scoped_line(MACRO_PROT_ARGS
)
1006 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1008 mdoc
->next
= MDOC_NEXT_CHILD
;
1010 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1012 mdoc
->next
= MDOC_NEXT_SIBLING
;
1013 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1015 mdoc
->next
= MDOC_NEXT_CHILD
;
1017 /* XXX - no known argument macros. */
1022 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1023 assert(ARGS_PHRASE
!= c
);
1025 if (ARGS_ERROR
== c
)
1027 if (ARGS_PUNCT
== c
)
1032 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1034 else if (MDOC_MAX
== c
) {
1035 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1037 mdoc
->next
= MDOC_NEXT_SIBLING
;
1041 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1047 if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
1049 if ( ! append_delims(mdoc
, line
, pos
, buf
))
1051 } else if ( ! rewind_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
1053 return(rewind_impblock(mdoc
, tok
, line
, ppos
));
1058 * A constant-scoped macro is like a simple-scoped macro (mdoc_scoped)
1059 * except that it doesn't handle implicit scopes and explicit ones have
1060 * a fixed number of TEXT children to the BODY.
1073 macro_constant_scoped(MACRO_PROT_ARGS
)
1075 int lastarg
, flushed
, j
, c
, maxargs
;
1090 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1092 mdoc
->next
= MDOC_NEXT_CHILD
;
1095 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1097 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1099 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1102 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1105 mdoc
->next
= MDOC_NEXT_CHILD
;
1107 for (j
= 0; /* No sentinel. */; j
++) {
1110 if (j
== maxargs
&& ! flushed
) {
1111 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1114 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1116 mdoc
->next
= MDOC_NEXT_CHILD
;
1119 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1120 assert(ARGS_PHRASE
!= c
);
1122 if (ARGS_ERROR
== c
)
1124 if (ARGS_PUNCT
== c
)
1129 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1131 else if (MDOC_MAX
!= c
) {
1133 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
,
1137 if ( ! mdoc_body_alloc(mdoc
, line
,
1140 mdoc
->next
= MDOC_NEXT_CHILD
;
1142 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
,
1148 if ( ! flushed
&& mdoc_isdelim(p
)) {
1149 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
,
1153 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1155 mdoc
->next
= MDOC_NEXT_CHILD
;
1158 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1160 mdoc
->next
= MDOC_NEXT_SIBLING
;
1164 if ( ! rewind_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1166 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1168 mdoc
->next
= MDOC_NEXT_CHILD
;
1173 return(append_delims(mdoc
, line
, pos
, buf
));
1178 * A delimited constant is very similar to the macros parsed by
1179 * macro_text except that, in the event of punctuation, the macro isn't
1180 * "re-opened" as it is in macro_text. Also, these macros have a fixed
1181 * number of parameters.
1191 macro_constant_delimited(MACRO_PROT_ARGS
)
1193 int lastarg
, flushed
, j
, c
, maxargs
,
1195 struct mdoc_arg
*arg
;
1202 * Maximum arguments per macro. Some of these have none and
1203 * exit as soon as they're parsed.
1220 * Whether to ignore delimiter characters. `Pf' accepts its
1221 * first token as a parameter no matter what it looks like (if
1235 * Whether to ignore arguments: `St', for example, handles its
1236 * argument-like parameters as regular parameters.
1253 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1256 if (ARGV_WORD
== c
) {
1259 } else if (ARGV_ARG
== c
)
1261 mdoc_argv_free(arg
);
1265 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1268 mdoc
->next
= MDOC_NEXT_CHILD
;
1270 for (j
= 0; /* No sentinel. */; j
++) {
1273 if (j
== maxargs
&& ! flushed
) {
1274 if ( ! rewind_elem(mdoc
, tok
))
1279 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1280 assert(ARGS_PHRASE
!= c
);
1282 if (ARGS_ERROR
== c
)
1284 if (ARGS_PUNCT
== c
)
1289 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1291 else if (MDOC_MAX
!= c
) {
1292 if ( ! flushed
&& ! rewind_elem(mdoc
, tok
))
1295 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1300 if ( ! flushed
&& mdoc_isdelim(p
) && ! igndelim
) {
1301 if ( ! rewind_elem(mdoc
, tok
))
1306 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1308 mdoc
->next
= MDOC_NEXT_SIBLING
;
1311 if ( ! flushed
&& ! rewind_elem(mdoc
, tok
))
1316 return(append_delims(mdoc
, line
, pos
, buf
));
1321 * A constant macro is the simplest classification. It spans an entire
1325 macro_constant(MACRO_PROT_ARGS
)
1328 struct mdoc_arg
*arg
;
1331 assert( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
));
1337 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1340 if (ARGV_WORD
== c
) {
1343 } else if (ARGV_ARG
== c
)
1345 mdoc_argv_free(arg
);
1349 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1352 mdoc
->next
= MDOC_NEXT_CHILD
;
1356 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1357 assert(ARGS_PHRASE
!= c
);
1359 if (ARGS_ERROR
== w
)
1364 c
= ARGS_QWORD
== w
? MDOC_MAX
:
1365 lookup(mdoc
, line
, la
, tok
, p
);
1367 if (MDOC_MAX
!= c
&& -1 != c
) {
1368 if ( ! rewind_elem(mdoc
, tok
))
1370 return(mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
));
1374 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1376 mdoc
->next
= MDOC_NEXT_SIBLING
;
1379 return(rewind_elem(mdoc
, tok
));
1385 macro_obsolete(MACRO_PROT_ARGS
)
1388 return(pwarn(mdoc
, line
, ppos
, WOBS
));
1393 * This is called at the end of parsing. It must traverse up the tree,
1394 * closing out open [implicit] scopes. Obviously, open explicit scopes
1398 macro_end(struct mdoc
*mdoc
)
1400 struct mdoc_node
*n
;
1402 assert(mdoc
->first
);
1405 /* Scan for open explicit scopes. */
1407 n
= MDOC_VALID
& mdoc
->last
->flags
?
1408 mdoc
->last
->parent
: mdoc
->last
;
1410 for ( ; n
; n
= n
->parent
) {
1411 if (MDOC_BLOCK
!= n
->type
)
1413 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[n
->tok
].flags
))
1415 return(mdoc_nerr(mdoc
, n
,
1416 "macro scope still open on exit"));
1419 return(rewind_last(mdoc
, mdoc
->first
));