]>
git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.19 2009/07/12 16:34:16 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 #define REWIND_REWIND (1 << 0)
26 #define REWIND_NOHALT (1 << 1)
27 #define REWIND_HALT (1 << 2)
29 static int obsolete(MACRO_PROT_ARGS
);
30 static int blk_part_exp(MACRO_PROT_ARGS
);
31 static int in_line_eoln(MACRO_PROT_ARGS
);
32 static int in_line_argn(MACRO_PROT_ARGS
);
33 static int in_line(MACRO_PROT_ARGS
);
34 static int blk_full(MACRO_PROT_ARGS
);
35 static int blk_exp_close(MACRO_PROT_ARGS
);
36 static int blk_part_imp(MACRO_PROT_ARGS
);
38 static int phrase(struct mdoc
*, int, int, char *);
39 static int rew_dohalt(int, enum mdoc_type
,
40 const struct mdoc_node
*);
41 static int rew_alt(int);
42 static int rew_dobreak(int, const struct mdoc_node
*);
43 static int rew_elem(struct mdoc
*, int);
44 static int rew_impblock(struct mdoc
*, int, int, int);
45 static int rew_expblock(struct mdoc
*, int, int, int);
46 static int rew_subblock(enum mdoc_type
,
47 struct mdoc
*, int, int, int);
48 static int rew_last(struct mdoc
*, struct mdoc_node
*);
49 static int append_delims(struct mdoc
*, int, int *, char *);
50 static int lookup(struct mdoc
*, int, int, int, const char *);
51 static int swarn(struct mdoc
*, enum mdoc_type
, int, int,
52 const struct mdoc_node
*);
54 /* Central table of library: who gets parsed how. */
56 const struct mdoc_macro __mdoc_macros
[MDOC_MAX
] = {
57 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ap */
58 { in_line_eoln
, MDOC_PROLOGUE
}, /* Dd */
59 { in_line_eoln
, MDOC_PROLOGUE
}, /* Dt */
60 { in_line_eoln
, MDOC_PROLOGUE
}, /* Os */
61 { blk_full
, 0 }, /* Sh */
62 { blk_full
, 0 }, /* Ss */
63 { in_line
, 0 }, /* Pp */
64 { blk_part_imp
, MDOC_PARSED
}, /* D1 */
65 { blk_part_imp
, MDOC_PARSED
}, /* Dl */
66 { blk_full
, MDOC_EXPLICIT
}, /* Bd */
67 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ed */
68 { blk_full
, MDOC_EXPLICIT
}, /* Bl */
69 { blk_exp_close
, MDOC_EXPLICIT
}, /* El */
70 { blk_full
, MDOC_PARSED
}, /* It */
71 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ad */
72 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* An */
73 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ar */
74 { in_line_eoln
, MDOC_CALLABLE
}, /* Cd */
75 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Cm */
76 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dv */
77 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Er */
78 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ev */
79 { in_line_eoln
, 0 }, /* Ex */
80 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fa */
81 { in_line_eoln
, 0 }, /* Fd */
82 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fl */
83 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fn */
84 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ft */
85 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ic */
86 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* In */
87 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Li */
88 { blk_full
, 0 }, /* Nd */
89 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nm */
90 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Op */
91 { obsolete
, 0 }, /* Ot */
92 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pa */
93 { in_line_eoln
, 0 }, /* Rv */
94 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* St */
95 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Va */
96 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Vt */
97 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Xr */
98 { in_line_eoln
, 0 }, /* %A */
99 { in_line_eoln
, 0 }, /* %B */
100 { in_line_eoln
, 0 }, /* %D */
101 { in_line_eoln
, 0 }, /* %I */
102 { in_line_eoln
, 0 }, /* %J */
103 { in_line_eoln
, 0 }, /* %N */
104 { in_line_eoln
, 0 }, /* %O */
105 { in_line_eoln
, 0 }, /* %P */
106 { in_line_eoln
, 0 }, /* %R */
107 { in_line_eoln
, 0 }, /* %T */
108 { in_line_eoln
, 0 }, /* %V */
109 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ac */
110 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Ao */
111 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Aq */
112 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* At */
113 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Bc */
114 { blk_full
, MDOC_EXPLICIT
}, /* Bf */
115 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bo */
116 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bq */
117 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bsx */
118 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bx */
119 { in_line_eoln
, 0 }, /* Db */
120 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Dc */
121 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Do */
122 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dq */
123 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ec */
124 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ef */
125 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Em */
126 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Eo */
127 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fx */
128 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ms */
129 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* No */
130 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ns */
131 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nx */
132 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ox */
133 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Pc */
134 { in_line_argn
, MDOC_PARSED
| MDOC_IGNDELIM
}, /* Pf */
135 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Po */
136 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pq */
137 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Qc */
138 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ql */
139 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Qo */
140 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Qq */
141 { blk_exp_close
, MDOC_EXPLICIT
}, /* Re */
142 { blk_full
, MDOC_EXPLICIT
}, /* Rs */
143 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Sc */
144 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* So */
145 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sq */
146 { in_line_eoln
, 0 }, /* Sm */
147 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sx */
148 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sy */
149 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Tn */
150 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ux */
151 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Xc */
152 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Xo */
153 { blk_full
, MDOC_EXPLICIT
| MDOC_CALLABLE
}, /* Fo */
154 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Fc */
155 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Oo */
156 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Oc */
157 { blk_full
, MDOC_EXPLICIT
}, /* Bk */
158 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ek */
159 { in_line_eoln
, 0 }, /* Bt */
160 { in_line_eoln
, 0 }, /* Hf */
161 { obsolete
, 0 }, /* Fr */
162 { in_line_eoln
, 0 }, /* Ud */
163 { in_line_eoln
, 0 }, /* Lb */
164 { in_line
, 0 }, /* Lp */
165 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Lk */
166 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Mt */
167 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Brq */
168 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bro */
169 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Brc */
170 { in_line_eoln
, 0 }, /* %C */
171 { obsolete
, 0 }, /* Es */
172 { obsolete
, 0 }, /* En */
173 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dx */
174 { in_line_eoln
, 0 }, /* %Q */
177 const struct mdoc_macro
* const mdoc_macros
= __mdoc_macros
;
181 swarn(struct mdoc
*mdoc
, enum mdoc_type type
,
182 int line
, int pos
, const struct mdoc_node
*p
)
184 const char *n
, *t
, *tt
;
202 n
= mdoc_macronames
[p
->tok
];
206 n
= mdoc_macronames
[p
->tok
];
210 n
= mdoc_macronames
[p
->tok
];
217 if ( ! (MDOC_IGN_SCOPE
& mdoc
->pflags
))
218 return(mdoc_verr(mdoc
, line
, pos
,
219 "%s scope breaks %s scope of %s",
221 return(mdoc_vwarn(mdoc
, line
, pos
,
222 "%s scope breaks %s scope of %s",
228 * This is called at the end of parsing. It must traverse up the tree,
229 * closing out open [implicit] scopes. Obviously, open explicit scopes
233 mdoc_macroend(struct mdoc
*mdoc
)
237 /* Scan for open explicit scopes. */
239 n
= MDOC_VALID
& mdoc
->last
->flags
?
240 mdoc
->last
->parent
: mdoc
->last
;
242 for ( ; n
; n
= n
->parent
) {
243 if (MDOC_BLOCK
!= n
->type
)
245 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[n
->tok
].flags
))
247 return(mdoc_nerr(mdoc
, n
, EOPEN
));
250 return(rew_last(mdoc
, mdoc
->first
));
254 lookup(struct mdoc
*mdoc
, int line
, int pos
, int from
, const char *p
)
258 res
= mdoc_hash_find(mdoc
->htab
, p
);
259 if (MDOC_PARSED
& mdoc_macros
[from
].flags
)
263 if ( ! mdoc_pwarn(mdoc
, line
, pos
, EMACPARM
))
270 rew_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
274 mdoc
->next
= MDOC_NEXT_SIBLING
;
277 while (mdoc
->last
!= to
) {
278 if ( ! mdoc_valid_post(mdoc
))
280 if ( ! mdoc_action_post(mdoc
))
282 mdoc
->last
= mdoc
->last
->parent
;
286 if ( ! mdoc_valid_post(mdoc
))
288 return(mdoc_action_post(mdoc
));
337 * Rewind rules. This indicates whether to stop rewinding
338 * (REWIND_HALT) without touching our current scope, stop rewinding and
339 * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
340 * The scope-closing and so on occurs in the various rew_* routines.
343 rew_dohalt(int tok
, enum mdoc_type type
, const struct mdoc_node
*p
)
346 if (MDOC_ROOT
== p
->type
)
348 if (MDOC_VALID
& p
->flags
)
349 return(REWIND_NOHALT
);
373 assert(MDOC_HEAD
!= type
);
374 assert(MDOC_TAIL
!= type
);
375 if (type
== p
->type
&& tok
== p
->tok
)
376 return(REWIND_REWIND
);
379 assert(MDOC_TAIL
!= type
);
380 if (type
== p
->type
&& tok
== p
->tok
)
381 return(REWIND_REWIND
);
382 if (MDOC_BODY
== p
->type
&& MDOC_Bl
== p
->tok
)
386 if (type
== p
->type
&& tok
== p
->tok
)
387 return(REWIND_REWIND
);
392 assert(MDOC_TAIL
!= type
);
393 if (type
== p
->type
&& tok
== p
->tok
)
394 return(REWIND_REWIND
);
395 if (MDOC_BODY
== p
->type
&& MDOC_Sh
== p
->tok
)
429 if (type
== p
->type
&& tok
== p
->tok
)
430 return(REWIND_REWIND
);
433 /* Multi-line explicit scope close. */
465 if (type
== p
->type
&& rew_alt(tok
) == p
->tok
)
466 return(REWIND_REWIND
);
473 return(REWIND_NOHALT
);
478 * See if we can break an encountered scope (the rew_dohalt has returned
482 rew_dobreak(int tok
, const struct mdoc_node
*p
)
485 assert(MDOC_ROOT
!= p
->type
);
486 if (MDOC_ELEM
== p
->type
)
488 if (MDOC_TEXT
== p
->type
)
490 if (MDOC_VALID
& p
->flags
)
495 return(MDOC_It
== p
->tok
);
497 return(MDOC_Nd
== p
->tok
);
499 return(MDOC_Ss
== p
->tok
);
501 if (MDOC_Nd
== p
->tok
)
503 if (MDOC_Ss
== p
->tok
)
505 return(MDOC_Sh
== p
->tok
);
507 if (MDOC_It
== p
->tok
)
511 /* XXX - experimental! */
512 if (MDOC_Op
== p
->tok
)
519 if (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)
520 return(p
->tok
== rew_alt(tok
));
521 else if (MDOC_BLOCK
== p
->type
)
524 return(tok
== p
->tok
);
529 rew_elem(struct mdoc
*mdoc
, int tok
)
534 if (MDOC_ELEM
!= n
->type
)
536 assert(MDOC_ELEM
== n
->type
);
537 assert(tok
== n
->tok
);
539 return(rew_last(mdoc
, n
));
544 rew_subblock(enum mdoc_type type
, struct mdoc
*mdoc
,
545 int tok
, int line
, int ppos
)
551 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
552 c
= rew_dohalt(tok
, type
, n
);
553 if (REWIND_HALT
== c
)
555 if (REWIND_REWIND
== c
)
557 else if (rew_dobreak(tok
, n
))
559 if ( ! swarn(mdoc
, type
, line
, ppos
, n
))
564 return(rew_last(mdoc
, n
));
569 rew_expblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
575 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
576 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
577 if (REWIND_HALT
== c
)
578 return(mdoc_perr(mdoc
, line
, ppos
, ENOCTX
));
579 if (REWIND_REWIND
== c
)
581 else if (rew_dobreak(tok
, n
))
583 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
588 return(rew_last(mdoc
, n
));
593 rew_impblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
599 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
600 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
601 if (REWIND_HALT
== c
)
603 else if (REWIND_REWIND
== c
)
605 else if (rew_dobreak(tok
, n
))
607 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
612 return(rew_last(mdoc
, n
));
617 append_delims(struct mdoc
*mdoc
, int line
, int *pos
, char *buf
)
627 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
628 assert(ARGS_PHRASE
!= c
);
632 else if (ARGS_EOLN
== c
)
634 assert(mdoc_isdelim(p
));
635 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
637 mdoc
->next
= MDOC_NEXT_SIBLING
;
645 * Close out block partial/full explicit.
648 blk_exp_close(MACRO_PROT_ARGS
)
650 int j
, c
, lastarg
, maxargs
, flushed
;
662 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
663 if (0 == buf
[*pos
]) {
664 if ( ! rew_subblock(MDOC_BODY
, mdoc
,
667 return(rew_expblock(mdoc
, tok
, line
, ppos
));
669 return(mdoc_perr(mdoc
, line
, ppos
, ENOLINE
));
672 if ( ! rew_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
676 if ( ! mdoc_tail_alloc(mdoc
, line
,
679 mdoc
->next
= MDOC_NEXT_CHILD
;
682 for (lastarg
= ppos
, flushed
= j
= 0; ; j
++) {
685 if (j
== maxargs
&& ! flushed
) {
686 if ( ! rew_expblock(mdoc
, tok
, line
, ppos
))
691 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
700 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
702 else if (MDOC_MAX
!= c
) {
704 if ( ! rew_expblock(mdoc
, tok
,
709 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
714 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
716 mdoc
->next
= MDOC_NEXT_SIBLING
;
719 if ( ! flushed
&& ! rew_expblock(mdoc
, tok
, line
, ppos
))
724 return(append_delims(mdoc
, line
, pos
, buf
));
729 * In-line macros where reserved words cause scope close-reopen.
732 in_line(MACRO_PROT_ARGS
)
734 int la
, lastpunct
, c
, w
, cnt
, d
, nc
;
735 struct mdoc_arg
*arg
;
739 * Whether we allow ignored elements (those without content,
740 * usually because of reserved words) to squeak by.
761 for (la
= ppos
, arg
= NULL
;; ) {
763 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
765 if (ARGV_WORD
== c
) {
778 for (cnt
= 0, lastpunct
= 1;; ) {
780 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
789 /* Quoted words shouldn't be looked-up. */
791 c
= ARGS_QWORD
== w
? MDOC_MAX
:
792 lookup(mdoc
, line
, la
, tok
, p
);
795 * In this case, we've located a submacro and must
796 * execute it. Close out scope, if open. If no
797 * elements have been generated, either create one (nc)
798 * or raise a warning.
801 if (MDOC_MAX
!= c
&& -1 != c
) {
802 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
804 if (nc
&& 0 == cnt
) {
805 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
,
808 if ( ! rew_last(mdoc
, mdoc
->last
))
810 } else if ( ! nc
&& 0 == cnt
) {
812 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, EIGNE
))
815 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
820 return(append_delims(mdoc
, line
, pos
, buf
));
825 * Non-quote-enclosed punctuation. Set up our scope, if
826 * a word; rewind the scope, if a delimiter; then append
832 if (ARGS_QWORD
!= w
&& d
) {
833 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
836 } else if (lastpunct
) {
837 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
840 mdoc
->next
= MDOC_NEXT_CHILD
;
846 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
848 mdoc
->next
= MDOC_NEXT_SIBLING
;
851 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
855 * If no elements have been collected and we're allowed to have
856 * empties (nc), open a scope and close it out. Otherwise,
860 if (nc
&& 0 == cnt
) {
861 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
864 if ( ! rew_last(mdoc
, mdoc
->last
))
866 } else if ( ! nc
&& 0 == cnt
) {
868 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, EIGNE
))
874 return(append_delims(mdoc
, line
, pos
, buf
));
879 * Block full-explicit and full-implicit.
882 blk_full(MACRO_PROT_ARGS
)
884 int c
, lastarg
, reopen
, dohead
;
885 struct mdoc_arg
*arg
;
889 * Whether to process a block-head section. If this is
890 * non-zero, then a head will be opened for all line arguments.
891 * If not, then the head will always be empty and only a body
892 * will be opened, which will stay open at the eoln.
904 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)) {
905 if ( ! rew_subblock(MDOC_BODY
, mdoc
,
908 if ( ! rew_impblock(mdoc
, tok
, line
, ppos
))
912 for (arg
= NULL
;; ) {
914 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
916 if (ARGV_WORD
== c
) {
930 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, arg
))
932 mdoc
->next
= MDOC_NEXT_CHILD
;
934 if (0 == buf
[*pos
]) {
935 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
937 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
940 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
942 mdoc
->next
= MDOC_NEXT_CHILD
;
946 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
949 /* Immediately close out head and enter body, if applicable. */
952 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
954 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
958 mdoc
->next
= MDOC_NEXT_CHILD
;
960 for (reopen
= 0;; ) {
962 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
968 if (ARGS_PHRASE
== c
) {
970 if (reopen
&& ! mdoc_head_alloc
971 (mdoc
, line
, ppos
, tok
))
973 mdoc
->next
= MDOC_NEXT_CHILD
;
975 * Phrases are self-contained macro phrases used
976 * in the columnar output of a macro. They need
979 if ( ! phrase(mdoc
, line
, lastarg
, buf
))
981 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
989 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
993 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
995 mdoc
->next
= MDOC_NEXT_SIBLING
;
999 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1004 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1007 /* If the body's already open, then just return. */
1011 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1013 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1015 mdoc
->next
= MDOC_NEXT_CHILD
;
1022 * Block partial-imnplicit scope.
1025 blk_part_imp(MACRO_PROT_ARGS
)
1029 struct mdoc_node
*blk
, *body
, *n
;
1031 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1033 mdoc
->next
= MDOC_NEXT_CHILD
;
1036 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1038 mdoc
->next
= MDOC_NEXT_SIBLING
;
1040 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1042 mdoc
->next
= MDOC_NEXT_CHILD
;
1045 /* XXX - no known argument macros. */
1047 for (lastarg
= ppos
;; ) {
1049 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1050 assert(ARGS_PHRASE
!= c
);
1052 if (ARGS_ERROR
== c
)
1054 if (ARGS_PUNCT
== c
)
1059 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1061 else if (MDOC_MAX
== c
) {
1062 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1064 mdoc
->next
= MDOC_NEXT_SIBLING
;
1068 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1074 * Since we know what our context is, we can rewind directly to
1075 * it. This allows us to accomodate for our scope being
1076 * violated by another token.
1079 for (n
= mdoc
->last
; n
; n
= n
->parent
)
1083 if (NULL
== n
&& ! mdoc_nwarn(mdoc
, body
, EIMPBRK
))
1086 if (n
&& ! rew_last(mdoc
, body
))
1089 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1092 if (n
&& ! rew_last(mdoc
, blk
))
1100 * Block partial-explicit macros.
1103 blk_part_exp(MACRO_PROT_ARGS
)
1105 int lastarg
, flushed
, j
, c
, maxargs
;
1112 * Number of arguments (head arguments). Only `Eo' has these,
1124 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1126 mdoc
->next
= MDOC_NEXT_CHILD
;
1129 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1131 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1134 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1137 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1140 mdoc
->next
= MDOC_NEXT_CHILD
;
1142 for (j
= 0; ; j
++) {
1144 if (j
== maxargs
&& ! flushed
) {
1145 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1149 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1151 mdoc
->next
= MDOC_NEXT_CHILD
;
1154 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1155 assert(ARGS_PHRASE
!= c
);
1157 if (ARGS_ERROR
== c
)
1159 if (ARGS_PUNCT
== c
)
1164 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1166 else if (MDOC_MAX
!= c
) {
1168 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1172 if ( ! mdoc_body_alloc(mdoc
, line
,
1175 mdoc
->next
= MDOC_NEXT_CHILD
;
1177 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
,
1183 if ( ! flushed
&& mdoc_isdelim(p
)) {
1184 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1188 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1190 mdoc
->next
= MDOC_NEXT_CHILD
;
1193 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1195 mdoc
->next
= MDOC_NEXT_SIBLING
;
1199 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1201 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1203 mdoc
->next
= MDOC_NEXT_CHILD
;
1208 return(append_delims(mdoc
, line
, pos
, buf
));
1213 * In-line macros where reserved words signal closure of the macro.
1214 * Macros also have a fixed number of arguments.
1217 in_line_argn(MACRO_PROT_ARGS
)
1219 int lastarg
, flushed
, j
, c
, maxargs
;
1220 struct mdoc_arg
*arg
;
1225 * Fixed maximum arguments per macro. Some of these have none
1226 * and close as soon as the invocation is parsed.
1244 for (lastarg
= ppos
, arg
= NULL
;; ) {
1246 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1248 if (ARGV_WORD
== c
) {
1258 mdoc_argv_free(arg
);
1262 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1264 mdoc
->next
= MDOC_NEXT_CHILD
;
1266 for (flushed
= j
= 0; ; j
++) {
1269 if (j
== maxargs
&& ! flushed
) {
1270 if ( ! rew_elem(mdoc
, tok
))
1275 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1277 if (ARGS_ERROR
== c
)
1279 if (ARGS_PUNCT
== c
)
1284 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1286 else if (MDOC_MAX
!= c
) {
1287 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1290 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1295 if ( ! (MDOC_IGNDELIM
& mdoc_macros
[tok
].flags
) &&
1296 ! flushed
&& mdoc_isdelim(p
)) {
1297 if ( ! rew_elem(mdoc
, tok
))
1302 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1304 mdoc
->next
= MDOC_NEXT_SIBLING
;
1307 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1312 return(append_delims(mdoc
, line
, pos
, buf
));
1317 * In-line macro that spans an entire line. May be callable, but has no
1318 * subsequent parsed arguments.
1321 in_line_eoln(MACRO_PROT_ARGS
)
1324 struct mdoc_arg
*arg
;
1327 assert( ! (MDOC_PARSED
& mdoc_macros
[tok
].flags
));
1333 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1335 if (ARGV_WORD
== c
) {
1344 mdoc_argv_free(arg
);
1348 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1351 mdoc
->next
= MDOC_NEXT_CHILD
;
1355 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1357 if (ARGS_ERROR
== w
)
1362 c
= ARGS_QWORD
== w
? MDOC_MAX
:
1363 lookup(mdoc
, line
, la
, tok
, p
);
1365 if (MDOC_MAX
!= c
&& -1 != c
) {
1366 if ( ! rew_elem(mdoc
, tok
))
1368 return(mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
));
1372 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1374 mdoc
->next
= MDOC_NEXT_SIBLING
;
1377 return(rew_elem(mdoc
, tok
));
1383 obsolete(MACRO_PROT_ARGS
)
1386 return(mdoc_pwarn(mdoc
, line
, ppos
, EOBS
));
1391 phrase(struct mdoc
*mdoc
, int line
, int ppos
, char *buf
)
1393 int i
, la
, c
, quoted
;
1396 * Parse over words in a phrase. We have to handle this
1397 * specially because we assume no calling context -- in normal
1398 * circumstances, we switch argument parsing based on whether
1399 * the parent macro accepts quotes, tabs, etc. Here, anything
1403 for (i
= ppos
; buf
[i
]; ) {
1404 assert(' ' != buf
[i
]);
1409 * Read to next token. If quoted (check not escaped),
1410 * scan ahead to next unescaped quote. If not quoted or
1411 * escape-quoted, then scan ahead to next space.
1414 if ((i
&& '\"' == buf
[i
] && '\\' != buf
[i
- 1]) ||
1415 (0 == i
&& '\"' == buf
[i
])) {
1416 for (la
= ++i
; buf
[i
]; i
++)
1419 else if ('\\' != buf
[i
- 1])
1422 return(mdoc_perr(mdoc
, line
, la
, EQUOTPHR
));
1425 for ( ; buf
[i
]; i
++)
1426 if (i
&& ' ' == buf
[i
]) {
1427 if ('\\' != buf
[i
- 1])
1429 } else if (' ' == buf
[i
])
1432 /* If not end-of-line, terminate argument. */
1437 /* Read to next argument. */
1439 for ( ; buf
[i
] && ' ' == buf
[i
]; i
++)
1443 * If we're a non-quoted string, try to look up the
1444 * value as a macro and execute it, if found.
1447 c
= quoted
? MDOC_MAX
:
1448 mdoc_hash_find(mdoc
->htab
, &buf
[la
]);
1450 if (MDOC_MAX
!= c
) {
1451 if ( ! mdoc_macro(mdoc
, c
, line
, la
, &i
, buf
))
1453 return(append_delims(mdoc
, line
, &i
, buf
));
1456 /* A regular word or quoted string. */
1458 if ( ! mdoc_word_alloc(mdoc
, line
, la
, &buf
[la
]))
1460 mdoc
->next
= MDOC_NEXT_SIBLING
;