]>
git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.9 2009/06/10 20:18:43 kristaps Exp $ */
3 * Copyright (c) 2008, 2009 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 above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 /* FIXME: .Fl, .Ar, .Cd handling of `|'. */
41 #define REWIND_REWIND (1 << 0)
42 #define REWIND_NOHALT (1 << 1)
43 #define REWIND_HALT (1 << 2)
45 static int obsolete(MACRO_PROT_ARGS
);
46 static int blk_part_exp(MACRO_PROT_ARGS
);
47 static int in_line_eoln(MACRO_PROT_ARGS
);
48 static int in_line_argn(MACRO_PROT_ARGS
);
49 static int in_line(MACRO_PROT_ARGS
);
50 static int blk_full(MACRO_PROT_ARGS
);
51 static int blk_exp_close(MACRO_PROT_ARGS
);
52 static int blk_part_imp(MACRO_PROT_ARGS
);
54 static int phrase(struct mdoc
*, int, int, char *);
55 static int rew_dohalt(int, enum mdoc_type
,
56 const struct mdoc_node
*);
57 static int rew_alt(int);
58 static int rew_dobreak(int, const struct mdoc_node
*);
59 static int rew_elem(struct mdoc
*, int);
60 static int rew_impblock(struct mdoc
*, int, int, int);
61 static int rew_expblock(struct mdoc
*, int, int, int);
62 static int rew_subblock(enum mdoc_type
,
63 struct mdoc
*, int, int, int);
64 static int rew_last(struct mdoc
*, struct mdoc_node
*);
65 static int append_delims(struct mdoc
*, int, int *, char *);
66 static int lookup(struct mdoc
*, int, int, int, const char *);
67 static int pwarn(struct mdoc
*, int, int, enum mwarn
);
68 static int perr(struct mdoc
*, int, int, enum merr
);
69 static int swarn(struct mdoc
*, enum mdoc_type
, int, int,
70 const struct mdoc_node
*);
72 #define nerr(m, n, t) perr((m), (n)->line, (n)->pos, (t))
74 /* Central table of library: who gets parsed how. */
76 const struct mdoc_macro __mdoc_macros
[MDOC_MAX
] = {
78 { in_line_eoln
, MDOC_PROLOGUE
}, /* Dd */
79 { in_line_eoln
, MDOC_PROLOGUE
}, /* Dt */
80 { in_line_eoln
, MDOC_PROLOGUE
}, /* Os */
81 { blk_full
, 0 }, /* Sh */
82 { blk_full
, 0 }, /* Ss */
83 { in_line
, 0 }, /* Pp */
84 { blk_part_imp
, MDOC_PARSED
}, /* D1 */
85 { blk_part_imp
, MDOC_PARSED
}, /* Dl */
86 { blk_full
, MDOC_EXPLICIT
}, /* Bd */
87 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ed */
88 { blk_full
, MDOC_EXPLICIT
}, /* Bl */
89 { blk_exp_close
, MDOC_EXPLICIT
}, /* El */
90 { blk_full
, MDOC_PARSED
}, /* It */
91 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ad */
92 { in_line
, MDOC_PARSED
}, /* An */
93 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ar */
94 { in_line_eoln
, MDOC_CALLABLE
}, /* Cd */
95 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Cm */
96 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dv */
97 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Er */
98 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ev */
99 { in_line_eoln
, 0 }, /* Ex */
100 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fa */
101 { in_line_eoln
, 0 }, /* Fd */
102 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fl */
103 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fn */
104 { in_line
, MDOC_PARSED
}, /* Ft */
105 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ic */
106 { in_line_eoln
, 0 }, /* In */
107 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Li */
108 { in_line_eoln
, 0 }, /* Nd */
109 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nm */
110 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Op */
111 { obsolete
, 0 }, /* Ot */
112 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pa */
113 { in_line_eoln
, 0 }, /* Rv */
114 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* St */
115 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Va */
116 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Vt */
117 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Xr */
118 { in_line_eoln
, 0 }, /* %A */
119 { in_line_eoln
, 0 }, /* %B */
120 { in_line_eoln
, 0 }, /* %D */
121 { in_line_eoln
, 0 }, /* %I */
122 { in_line_eoln
, 0 }, /* %J */
123 { in_line_eoln
, 0 }, /* %N */
124 { in_line_eoln
, 0 }, /* %O */
125 { in_line_eoln
, 0 }, /* %P */
126 { in_line_eoln
, 0 }, /* %R */
127 { in_line_eoln
, 0 }, /* %T */
128 { in_line_eoln
, 0 }, /* %V */
129 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ac */
130 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Ao */
131 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Aq */
132 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* At */
133 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Bc */
134 { blk_full
, MDOC_EXPLICIT
}, /* Bf */
135 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bo */
136 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bq */
137 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bsx */
138 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bx */
139 { in_line_eoln
, 0 }, /* Db */
140 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Dc */
141 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Do */
142 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dq */
143 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ec */
144 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ef */
145 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Em */
146 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Eo */
147 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fx */
148 { in_line
, MDOC_PARSED
}, /* Ms */
149 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* No */
150 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ns */
151 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nx */
152 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ox */
153 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Pc */
154 { in_line_argn
, MDOC_PARSED
| MDOC_IGNDELIM
}, /* Pf */
155 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Po */
156 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pq */
157 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Qc */
158 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ql */
159 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Qo */
160 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Qq */
161 { blk_exp_close
, MDOC_EXPLICIT
}, /* Re */
162 { blk_full
, MDOC_EXPLICIT
}, /* Rs */
163 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Sc */
164 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* So */
165 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sq */
166 { in_line_eoln
, 0 }, /* Sm */
167 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sx */
168 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sy */
169 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Tn */
170 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ux */
171 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Xc */
172 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Xo */
173 { blk_full
, MDOC_EXPLICIT
| MDOC_CALLABLE
}, /* Fo */
174 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Fc */
175 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Oo */
176 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Oc */
177 { blk_full
, MDOC_EXPLICIT
}, /* Bk */
178 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ek */
179 { in_line_eoln
, 0 }, /* Bt */
180 { in_line_eoln
, 0 }, /* Hf */
181 { obsolete
, 0 }, /* Fr */
182 { in_line_eoln
, 0 }, /* Ud */
183 { in_line_eoln
, 0 }, /* Lb */
184 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ap */
185 { in_line
, 0 }, /* Lp */
186 { in_line
, MDOC_PARSED
}, /* Lk */
187 { in_line
, MDOC_PARSED
}, /* Mt */
188 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Brq */
189 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bro */
190 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Brc */
191 { in_line_eoln
, 0 }, /* %C */
192 { obsolete
, 0 }, /* Es */
193 { obsolete
, 0 }, /* En */
194 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dx */
195 { in_line_eoln
, 0 }, /* %Q */
198 const struct mdoc_macro
* const mdoc_macros
= __mdoc_macros
;
202 perr(struct mdoc
*mdoc
, int line
, int pos
, enum merr type
)
209 p
= "explicit scope still open on exit";
212 p
= "unterminated quotation";
215 p
= "closure has no prior context";
218 p
= "unexpect line arguments";
222 return(mdoc_perr(mdoc
, line
, pos
, p
));
227 pwarn(struct mdoc
*mdoc
, int line
, int pos
, enum mwarn type
)
234 p
= "ignoring empty element";
237 p
= "crufty end-of-line scope violation";
240 p
= "macro-like parameter";
243 p
= "macro marked obsolete";
247 return(mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
, p
));
252 swarn(struct mdoc
*mdoc
, enum mdoc_type type
,
253 int line
, int pos
, const struct mdoc_node
*p
)
255 const char *n
, *t
, *tt
;
273 n
= mdoc_macronames
[p
->tok
];
277 n
= mdoc_macronames
[p
->tok
];
281 n
= mdoc_macronames
[p
->tok
];
288 if ( ! (MDOC_IGN_SCOPE
& mdoc
->pflags
))
289 return(mdoc_perr(mdoc
, line
, pos
,
290 "%s scope breaks %s scope of %s",
292 return(mdoc_pwarn(mdoc
, line
, pos
, WARN_SYNTAX
,
293 "%s scope breaks %s scope of %s",
299 * This is called at the end of parsing. It must traverse up the tree,
300 * closing out open [implicit] scopes. Obviously, open explicit scopes
304 mdoc_macroend(struct mdoc
*mdoc
)
308 /* Scan for open explicit scopes. */
310 n
= MDOC_VALID
& mdoc
->last
->flags
?
311 mdoc
->last
->parent
: mdoc
->last
;
313 for ( ; n
; n
= n
->parent
) {
314 if (MDOC_BLOCK
!= n
->type
)
316 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[n
->tok
].flags
))
318 return(nerr(mdoc
, n
, EOPEN
));
321 return(rew_last(mdoc
, mdoc
->first
));
325 lookup(struct mdoc
*mdoc
, int line
, int pos
, int from
, const char *p
)
329 res
= mdoc_hash_find(mdoc
->htab
, p
);
330 if (MDOC_PARSED
& mdoc_macros
[from
].flags
)
334 if ( ! pwarn(mdoc
, line
, pos
, WMACPARM
))
341 rew_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
345 mdoc
->next
= MDOC_NEXT_SIBLING
;
348 while (mdoc
->last
!= to
) {
349 if ( ! mdoc_valid_post(mdoc
))
351 if ( ! mdoc_action_post(mdoc
))
353 mdoc
->last
= mdoc
->last
->parent
;
357 if ( ! mdoc_valid_post(mdoc
))
359 return(mdoc_action_post(mdoc
));
408 * Rewind rules. This indicates whether to stop rewinding
409 * (REWIND_HALT) without touching our current scope, stop rewinding and
410 * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
411 * The scope-closing and so on occurs in the various rew_* routines.
414 rew_dohalt(int tok
, enum mdoc_type type
, const struct mdoc_node
*p
)
417 if (MDOC_ROOT
== p
->type
)
419 if (MDOC_VALID
& p
->flags
)
420 return(REWIND_NOHALT
);
444 assert(MDOC_HEAD
!= type
);
445 assert(MDOC_TAIL
!= type
);
446 if (type
== p
->type
&& tok
== p
->tok
)
447 return(REWIND_REWIND
);
450 assert(MDOC_TAIL
!= type
);
451 if (type
== p
->type
&& tok
== p
->tok
)
452 return(REWIND_REWIND
);
453 if (MDOC_BODY
== p
->type
&& MDOC_Bl
== p
->tok
)
457 if (type
== p
->type
&& tok
== p
->tok
)
458 return(REWIND_REWIND
);
461 assert(MDOC_TAIL
!= type
);
462 if (type
== p
->type
&& tok
== p
->tok
)
463 return(REWIND_REWIND
);
464 if (MDOC_BODY
== p
->type
&& MDOC_Sh
== p
->tok
)
498 if (type
== p
->type
&& tok
== p
->tok
)
499 return(REWIND_REWIND
);
502 /* Multi-line explicit scope close. */
534 if (type
== p
->type
&& rew_alt(tok
) == p
->tok
)
535 return(REWIND_REWIND
);
542 return(REWIND_NOHALT
);
547 * See if we can break an encountered scope (the rew_dohalt has returned
551 rew_dobreak(int tok
, const struct mdoc_node
*p
)
554 assert(MDOC_ROOT
!= p
->type
);
555 if (MDOC_ELEM
== p
->type
)
557 if (MDOC_TEXT
== p
->type
)
559 if (MDOC_VALID
& p
->flags
)
564 return(MDOC_It
== p
->tok
);
566 return(MDOC_Ss
== p
->tok
);
568 if (MDOC_Ss
== p
->tok
)
570 return(MDOC_Sh
== p
->tok
);
572 if (MDOC_It
== p
->tok
)
576 /* XXX - experimental! */
577 if (MDOC_Op
== p
->tok
)
584 if (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)
585 return(p
->tok
== rew_alt(tok
));
586 else if (MDOC_BLOCK
== p
->type
)
589 return(tok
== p
->tok
);
594 rew_elem(struct mdoc
*mdoc
, int tok
)
599 if (MDOC_ELEM
!= n
->type
)
601 assert(MDOC_ELEM
== n
->type
);
602 assert(tok
== n
->tok
);
604 return(rew_last(mdoc
, n
));
609 rew_subblock(enum mdoc_type type
, struct mdoc
*mdoc
,
610 int tok
, int line
, int ppos
)
616 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
617 c
= rew_dohalt(tok
, type
, n
);
618 if (REWIND_HALT
== c
)
620 if (REWIND_REWIND
== c
)
622 else if (rew_dobreak(tok
, n
))
624 if ( ! swarn(mdoc
, type
, line
, ppos
, n
))
629 return(rew_last(mdoc
, n
));
634 rew_expblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
640 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
641 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
642 if (REWIND_HALT
== c
)
643 return(perr(mdoc
, line
, ppos
, ENOCTX
));
644 if (REWIND_REWIND
== c
)
646 else if (rew_dobreak(tok
, n
))
648 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
653 return(rew_last(mdoc
, n
));
658 rew_impblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
664 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
665 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
666 if (REWIND_HALT
== c
)
668 else if (REWIND_REWIND
== c
)
670 else if (rew_dobreak(tok
, n
))
672 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
677 return(rew_last(mdoc
, n
));
682 append_delims(struct mdoc
*mdoc
, int line
, int *pos
, char *buf
)
692 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
693 assert(ARGS_PHRASE
!= c
);
697 else if (ARGS_EOLN
== c
)
699 assert(mdoc_isdelim(p
));
700 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
702 mdoc
->next
= MDOC_NEXT_SIBLING
;
710 * Close out block partial/full explicit.
713 blk_exp_close(MACRO_PROT_ARGS
)
715 int j
, c
, lastarg
, maxargs
, flushed
;
727 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
728 if (0 == buf
[*pos
]) {
729 if ( ! rew_subblock(MDOC_BODY
, mdoc
,
732 return(rew_expblock(mdoc
, tok
, line
, ppos
));
734 return(perr(mdoc
, line
, ppos
, ENOPARMS
));
737 if ( ! rew_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
741 if ( ! mdoc_tail_alloc(mdoc
, line
,
744 mdoc
->next
= MDOC_NEXT_CHILD
;
747 for (lastarg
= ppos
, flushed
= j
= 0; ; j
++) {
750 if (j
== maxargs
&& ! flushed
) {
751 if ( ! rew_expblock(mdoc
, tok
, line
, ppos
))
756 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
765 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
767 else if (MDOC_MAX
!= c
) {
769 if ( ! rew_expblock(mdoc
, tok
,
774 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
779 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
781 mdoc
->next
= MDOC_NEXT_SIBLING
;
784 if ( ! flushed
&& ! rew_expblock(mdoc
, tok
, line
, ppos
))
789 return(append_delims(mdoc
, line
, pos
, buf
));
794 * In-line macros where reserved words cause scope close-reopen.
797 in_line(MACRO_PROT_ARGS
)
799 int la
, lastpunct
, c
, w
, cnt
, d
, nc
;
800 struct mdoc_arg
*arg
;
804 * Whether we allow ignored elements (those without content,
805 * usually because of reserved words) to squeak by.
824 for (la
= ppos
, arg
= NULL
;; ) {
826 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
828 if (ARGV_WORD
== c
) {
841 for (cnt
= 0, lastpunct
= 1;; ) {
843 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
852 /* Quoted words shouldn't be looked-up. */
854 c
= ARGS_QWORD
== w
? MDOC_MAX
:
855 lookup(mdoc
, line
, la
, tok
, p
);
858 * In this case, we've located a submacro and must
859 * execute it. Close out scope, if open. If no
860 * elements have been generated, either create one (nc)
861 * or raise a warning.
864 if (MDOC_MAX
!= c
&& -1 != c
) {
865 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
867 if (nc
&& 0 == cnt
) {
868 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
,
871 mdoc
->next
= MDOC_NEXT_SIBLING
;
872 } else if ( ! nc
&& 0 == cnt
) {
874 if ( ! pwarn(mdoc
, line
, ppos
, WIGNE
))
877 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
882 return(append_delims(mdoc
, line
, pos
, buf
));
887 * Non-quote-enclosed punctuation. Set up our scope, if
888 * a word; rewind the scope, if a delimiter; then append
894 if (ARGS_QWORD
!= w
&& d
) {
895 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
898 } else if (lastpunct
) {
899 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
902 mdoc
->next
= MDOC_NEXT_CHILD
;
908 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
910 mdoc
->next
= MDOC_NEXT_SIBLING
;
913 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
917 * If no elements have been collected and we're allowed to have
918 * empties (nc), open a scope and close it out. Otherwise,
922 if (nc
&& 0 == cnt
) {
923 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
926 mdoc
->next
= MDOC_NEXT_SIBLING
;
927 } else if ( ! nc
&& 0 == cnt
) {
929 if ( ! pwarn(mdoc
, line
, ppos
, WIGNE
))
935 return(append_delims(mdoc
, line
, pos
, buf
));
940 * Block full-explicit and full-implicit.
943 blk_full(MACRO_PROT_ARGS
)
945 int c
, lastarg
, reopen
;
946 struct mdoc_arg
*arg
;
949 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)) {
950 if ( ! rew_subblock(MDOC_BODY
, mdoc
,
953 if ( ! rew_impblock(mdoc
, tok
, line
, ppos
))
957 for (arg
= NULL
;; ) {
959 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
961 if (ARGV_WORD
== c
) {
975 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, arg
))
977 mdoc
->next
= MDOC_NEXT_CHILD
;
979 if (0 == buf
[*pos
]) {
980 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
982 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
985 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
987 mdoc
->next
= MDOC_NEXT_CHILD
;
991 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
993 mdoc
->next
= MDOC_NEXT_CHILD
;
995 for (reopen
= 0;; ) {
997 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1003 if (ARGS_PHRASE
== c
) {
1004 if (reopen
&& ! mdoc_head_alloc
1005 (mdoc
, line
, ppos
, tok
))
1007 mdoc
->next
= MDOC_NEXT_CHILD
;
1009 * Phrases are self-contained macro phrases used
1010 * in the columnar output of a macro. They need
1013 if ( ! phrase(mdoc
, line
, lastarg
, buf
))
1015 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1023 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1026 if (MDOC_MAX
== c
) {
1027 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1029 mdoc
->next
= MDOC_NEXT_SIBLING
;
1033 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1038 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1040 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1043 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1045 mdoc
->next
= MDOC_NEXT_CHILD
;
1052 * Block partial-imnplicit scope.
1055 blk_part_imp(MACRO_PROT_ARGS
)
1059 struct mdoc_node
*blk
, *body
, *n
;
1061 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1063 mdoc
->next
= MDOC_NEXT_CHILD
;
1066 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1068 mdoc
->next
= MDOC_NEXT_SIBLING
;
1070 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1072 mdoc
->next
= MDOC_NEXT_CHILD
;
1075 /* XXX - no known argument macros. */
1077 for (lastarg
= ppos
;; ) {
1079 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1080 assert(ARGS_PHRASE
!= c
);
1082 if (ARGS_ERROR
== c
)
1084 if (ARGS_PUNCT
== c
)
1089 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1091 else if (MDOC_MAX
== c
) {
1092 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1094 mdoc
->next
= MDOC_NEXT_SIBLING
;
1098 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1104 * Since we know what our context is, we can rewind directly to
1105 * it. This allows us to accomodate for our scope being
1106 * violated by another token.
1109 for (n
= mdoc
->last
; n
; n
= n
->parent
)
1113 if (NULL
== n
&& ! pwarn(mdoc
, body
->line
, body
->pos
, WIMPBRK
))
1116 if (n
&& ! rew_last(mdoc
, body
))
1119 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1122 if (n
&& ! rew_last(mdoc
, blk
))
1130 * Block partial-explicit macros.
1133 blk_part_exp(MACRO_PROT_ARGS
)
1135 int lastarg
, flushed
, j
, c
, maxargs
;
1142 * Number of arguments (head arguments). Only `Eo' has these,
1154 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1156 mdoc
->next
= MDOC_NEXT_CHILD
;
1159 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1161 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1164 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1167 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1170 mdoc
->next
= MDOC_NEXT_CHILD
;
1172 for (j
= 0; ; j
++) {
1174 if (j
== maxargs
&& ! flushed
) {
1175 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1179 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1181 mdoc
->next
= MDOC_NEXT_CHILD
;
1184 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1185 assert(ARGS_PHRASE
!= c
);
1187 if (ARGS_ERROR
== c
)
1189 if (ARGS_PUNCT
== c
)
1194 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1196 else if (MDOC_MAX
!= c
) {
1198 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1202 if ( ! mdoc_body_alloc(mdoc
, line
,
1205 mdoc
->next
= MDOC_NEXT_CHILD
;
1207 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
,
1213 if ( ! flushed
&& mdoc_isdelim(p
)) {
1214 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1218 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1220 mdoc
->next
= MDOC_NEXT_CHILD
;
1223 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1225 mdoc
->next
= MDOC_NEXT_SIBLING
;
1229 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1231 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1233 mdoc
->next
= MDOC_NEXT_CHILD
;
1238 return(append_delims(mdoc
, line
, pos
, buf
));
1243 * In-line macros where reserved words signal closure of the macro.
1244 * Macros also have a fixed number of arguments.
1247 in_line_argn(MACRO_PROT_ARGS
)
1249 int lastarg
, flushed
, j
, c
, maxargs
;
1250 struct mdoc_arg
*arg
;
1255 * Fixed maximum arguments per macro. Some of these have none
1256 * and close as soon as the invocation is parsed.
1274 for (lastarg
= ppos
, arg
= NULL
;; ) {
1276 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1278 if (ARGV_WORD
== c
) {
1288 mdoc_argv_free(arg
);
1292 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1294 mdoc
->next
= MDOC_NEXT_CHILD
;
1296 for (flushed
= j
= 0; ; j
++) {
1299 if (j
== maxargs
&& ! flushed
) {
1300 if ( ! rew_elem(mdoc
, tok
))
1305 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1307 if (ARGS_ERROR
== c
)
1309 if (ARGS_PUNCT
== c
)
1314 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1316 else if (MDOC_MAX
!= c
) {
1317 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1320 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1325 if ( ! (MDOC_IGNDELIM
& mdoc_macros
[tok
].flags
) &&
1326 ! flushed
&& mdoc_isdelim(p
)) {
1327 if ( ! rew_elem(mdoc
, tok
))
1332 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1334 mdoc
->next
= MDOC_NEXT_SIBLING
;
1337 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1342 return(append_delims(mdoc
, line
, pos
, buf
));
1347 * In-line macro that spans an entire line. May be callable, but has no
1348 * subsequent parsed arguments.
1351 in_line_eoln(MACRO_PROT_ARGS
)
1354 struct mdoc_arg
*arg
;
1357 assert( ! (MDOC_PARSED
& mdoc_macros
[tok
].flags
));
1363 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1365 if (ARGV_WORD
== c
) {
1374 mdoc_argv_free(arg
);
1378 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1381 mdoc
->next
= MDOC_NEXT_CHILD
;
1385 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1387 if (ARGS_ERROR
== w
)
1392 c
= ARGS_QWORD
== w
? MDOC_MAX
:
1393 lookup(mdoc
, line
, la
, tok
, p
);
1395 if (MDOC_MAX
!= c
&& -1 != c
) {
1396 if ( ! rew_elem(mdoc
, tok
))
1398 return(mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
));
1402 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1404 mdoc
->next
= MDOC_NEXT_SIBLING
;
1407 return(rew_elem(mdoc
, tok
));
1413 obsolete(MACRO_PROT_ARGS
)
1416 return(pwarn(mdoc
, line
, ppos
, WOBS
));
1421 phrase(struct mdoc
*mdoc
, int line
, int ppos
, char *buf
)
1423 int i
, la
, c
, quoted
;
1426 * Parse over words in a phrase. We have to handle this
1427 * specially because we assume no calling context -- in normal
1428 * circumstances, we switch argument parsing based on whether
1429 * the parent macro accepts quotes, tabs, etc. Here, anything
1433 for (i
= ppos
; buf
[i
]; ) {
1434 assert(' ' != buf
[i
]);
1439 * Read to next token. If quoted (check not escaped),
1440 * scan ahead to next unescaped quote. If not quoted or
1441 * escape-quoted, then scan ahead to next space.
1444 if ((i
&& '\"' == buf
[i
] && '\\' != buf
[i
- 1]) ||
1445 (0 == i
&& '\"' == buf
[i
])) {
1446 for (la
= ++i
; buf
[i
]; i
++)
1449 else if ('\\' != buf
[i
- 1])
1452 return(perr(mdoc
, line
, la
, EQUOT
));
1455 for ( ; buf
[i
]; i
++)
1456 if (i
&& ' ' == buf
[i
]) {
1457 if ('\\' != buf
[i
- 1])
1459 } else if (' ' == buf
[i
])
1462 /* If not end-of-line, terminate argument. */
1467 /* Read to next argument. */
1469 for ( ; buf
[i
] && ' ' == buf
[i
]; i
++)
1473 * If we're a non-quoted string, try to look up the
1474 * value as a macro and execute it, if found.
1477 c
= quoted
? MDOC_MAX
:
1478 mdoc_hash_find(mdoc
->htab
, &buf
[la
]);
1480 if (MDOC_MAX
!= c
) {
1481 if ( ! mdoc_macro(mdoc
, c
, line
, la
, &i
, buf
))
1483 return(append_delims(mdoc
, line
, &i
, buf
));
1486 /* A regular word or quoted string. */
1488 if ( ! mdoc_word_alloc(mdoc
, line
, la
, &buf
[la
]))
1490 mdoc
->next
= MDOC_NEXT_SIBLING
;