]>
git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.24 2009/07/19 21:26:27 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_eoln
, 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
, MDOC_CALLABLE
| MDOC_PARSED
}, /* 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_eoln
, 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 */
175 { in_line_eoln
, 0 }, /* br */
176 { in_line_eoln
, 0 }, /* sp */
179 const struct mdoc_macro
* const mdoc_macros
= __mdoc_macros
;
183 swarn(struct mdoc
*mdoc
, enum mdoc_type type
,
184 int line
, int pos
, const struct mdoc_node
*p
)
186 const char *n
, *t
, *tt
;
204 n
= mdoc_macronames
[p
->tok
];
208 n
= mdoc_macronames
[p
->tok
];
212 n
= mdoc_macronames
[p
->tok
];
219 if ( ! (MDOC_IGN_SCOPE
& mdoc
->pflags
))
220 return(mdoc_verr(mdoc
, line
, pos
,
221 "%s scope breaks %s scope of %s",
223 return(mdoc_vwarn(mdoc
, line
, pos
,
224 "%s scope breaks %s scope of %s",
230 * This is called at the end of parsing. It must traverse up the tree,
231 * closing out open [implicit] scopes. Obviously, open explicit scopes
235 mdoc_macroend(struct mdoc
*mdoc
)
239 /* Scan for open explicit scopes. */
241 n
= MDOC_VALID
& mdoc
->last
->flags
?
242 mdoc
->last
->parent
: mdoc
->last
;
244 for ( ; n
; n
= n
->parent
) {
245 if (MDOC_BLOCK
!= n
->type
)
247 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[n
->tok
].flags
))
249 return(mdoc_nerr(mdoc
, n
, EOPEN
));
252 return(rew_last(mdoc
, mdoc
->first
));
256 lookup(struct mdoc
*mdoc
, int line
, int pos
, int from
, const char *p
)
260 res
= mdoc_hash_find(mdoc
->htab
, p
);
261 if (MDOC_PARSED
& mdoc_macros
[from
].flags
)
265 if ( ! mdoc_pwarn(mdoc
, line
, pos
, EMACPARM
))
272 rew_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
276 mdoc
->next
= MDOC_NEXT_SIBLING
;
279 while (mdoc
->last
!= to
) {
280 if ( ! mdoc_valid_post(mdoc
))
282 if ( ! mdoc_action_post(mdoc
))
284 mdoc
->last
= mdoc
->last
->parent
;
288 if ( ! mdoc_valid_post(mdoc
))
290 return(mdoc_action_post(mdoc
));
339 * Rewind rules. This indicates whether to stop rewinding
340 * (REWIND_HALT) without touching our current scope, stop rewinding and
341 * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
342 * The scope-closing and so on occurs in the various rew_* routines.
345 rew_dohalt(int tok
, enum mdoc_type type
, const struct mdoc_node
*p
)
348 if (MDOC_ROOT
== p
->type
)
350 if (MDOC_VALID
& p
->flags
)
351 return(REWIND_NOHALT
);
375 assert(MDOC_HEAD
!= type
);
376 assert(MDOC_TAIL
!= type
);
377 if (type
== p
->type
&& tok
== p
->tok
)
378 return(REWIND_REWIND
);
381 assert(MDOC_TAIL
!= type
);
382 if (type
== p
->type
&& tok
== p
->tok
)
383 return(REWIND_REWIND
);
384 if (MDOC_BODY
== p
->type
&& MDOC_Bl
== p
->tok
)
388 if (type
== p
->type
&& tok
== p
->tok
)
389 return(REWIND_REWIND
);
394 assert(MDOC_TAIL
!= type
);
395 if (type
== p
->type
&& tok
== p
->tok
)
396 return(REWIND_REWIND
);
397 if (MDOC_BODY
== p
->type
&& MDOC_Sh
== p
->tok
)
431 if (type
== p
->type
&& tok
== p
->tok
)
432 return(REWIND_REWIND
);
435 /* Multi-line explicit scope close. */
467 if (type
== p
->type
&& rew_alt(tok
) == p
->tok
)
468 return(REWIND_REWIND
);
475 return(REWIND_NOHALT
);
480 * See if we can break an encountered scope (the rew_dohalt has returned
484 rew_dobreak(int tok
, const struct mdoc_node
*p
)
487 assert(MDOC_ROOT
!= p
->type
);
488 if (MDOC_ELEM
== p
->type
)
490 if (MDOC_TEXT
== p
->type
)
492 if (MDOC_VALID
& p
->flags
)
497 return(MDOC_It
== p
->tok
);
499 return(MDOC_Nd
== p
->tok
);
501 return(MDOC_Ss
== p
->tok
);
503 if (MDOC_Nd
== p
->tok
)
505 if (MDOC_Ss
== p
->tok
)
507 return(MDOC_Sh
== p
->tok
);
509 if (MDOC_It
== p
->tok
)
513 /* XXX - experimental! */
514 if (MDOC_Op
== p
->tok
)
521 if (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)
522 return(p
->tok
== rew_alt(tok
));
523 else if (MDOC_BLOCK
== p
->type
)
526 return(tok
== p
->tok
);
531 rew_elem(struct mdoc
*mdoc
, int tok
)
536 if (MDOC_ELEM
!= n
->type
)
538 assert(MDOC_ELEM
== n
->type
);
539 assert(tok
== n
->tok
);
541 return(rew_last(mdoc
, n
));
546 rew_subblock(enum mdoc_type type
, struct mdoc
*mdoc
,
547 int tok
, int line
, int ppos
)
553 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
554 c
= rew_dohalt(tok
, type
, n
);
555 if (REWIND_HALT
== c
)
557 if (REWIND_REWIND
== c
)
559 else if (rew_dobreak(tok
, n
))
561 if ( ! swarn(mdoc
, type
, line
, ppos
, n
))
566 return(rew_last(mdoc
, n
));
571 rew_expblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
577 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
578 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
579 if (REWIND_HALT
== c
)
580 return(mdoc_perr(mdoc
, line
, ppos
, ENOCTX
));
581 if (REWIND_REWIND
== c
)
583 else if (rew_dobreak(tok
, n
))
585 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
590 return(rew_last(mdoc
, n
));
595 rew_impblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
601 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
602 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
603 if (REWIND_HALT
== c
)
605 else if (REWIND_REWIND
== c
)
607 else if (rew_dobreak(tok
, n
))
609 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
614 return(rew_last(mdoc
, n
));
619 append_delims(struct mdoc
*mdoc
, int line
, int *pos
, char *buf
)
629 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
630 assert(ARGS_PHRASE
!= c
);
634 else if (ARGS_EOLN
== c
)
636 assert(mdoc_isdelim(p
));
637 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
639 mdoc
->next
= MDOC_NEXT_SIBLING
;
647 * Close out block partial/full explicit.
650 blk_exp_close(MACRO_PROT_ARGS
)
652 int j
, c
, lastarg
, maxargs
, flushed
;
664 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
666 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, ENOLINE
))
669 if ( ! rew_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
671 return(rew_expblock(mdoc
, tok
, line
, ppos
));
674 if ( ! rew_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
678 if ( ! mdoc_tail_alloc(mdoc
, line
,
681 mdoc
->next
= MDOC_NEXT_CHILD
;
684 for (lastarg
= ppos
, flushed
= j
= 0; ; j
++) {
687 if (j
== maxargs
&& ! flushed
) {
688 if ( ! rew_expblock(mdoc
, tok
, line
, ppos
))
693 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
702 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
704 else if (MDOC_MAX
!= c
) {
706 if ( ! rew_expblock(mdoc
, tok
,
711 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
716 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
718 mdoc
->next
= MDOC_NEXT_SIBLING
;
721 if ( ! flushed
&& ! rew_expblock(mdoc
, tok
, line
, ppos
))
726 return(append_delims(mdoc
, line
, pos
, buf
));
731 * In-line macros where reserved words cause scope close-reopen.
734 in_line(MACRO_PROT_ARGS
)
736 int la
, lastpunct
, c
, w
, cnt
, d
, nc
;
737 struct mdoc_arg
*arg
;
741 * Whether we allow ignored elements (those without content,
742 * usually because of reserved words) to squeak by.
759 for (la
= ppos
, arg
= NULL
;; ) {
761 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
763 if (ARGV_WORD
== c
) {
776 for (cnt
= 0, lastpunct
= 1;; ) {
778 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
787 /* Quoted words shouldn't be looked-up. */
789 c
= ARGS_QWORD
== w
? MDOC_MAX
:
790 lookup(mdoc
, line
, la
, tok
, p
);
793 * In this case, we've located a submacro and must
794 * execute it. Close out scope, if open. If no
795 * elements have been generated, either create one (nc)
796 * or raise a warning.
799 if (MDOC_MAX
!= c
&& -1 != c
) {
800 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
802 if (nc
&& 0 == cnt
) {
803 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
,
806 if ( ! rew_last(mdoc
, mdoc
->last
))
808 } else if ( ! nc
&& 0 == cnt
) {
810 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, EIGNE
))
813 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
818 return(append_delims(mdoc
, line
, pos
, buf
));
823 * Non-quote-enclosed punctuation. Set up our scope, if
824 * a word; rewind the scope, if a delimiter; then append
830 if (ARGS_QWORD
!= w
&& d
) {
831 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
834 } else if (lastpunct
) {
835 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
838 mdoc
->next
= MDOC_NEXT_CHILD
;
844 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
846 mdoc
->next
= MDOC_NEXT_SIBLING
;
849 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
853 * If no elements have been collected and we're allowed to have
854 * empties (nc), open a scope and close it out. Otherwise,
858 if (nc
&& 0 == cnt
) {
859 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
862 if ( ! rew_last(mdoc
, mdoc
->last
))
864 } else if ( ! nc
&& 0 == cnt
) {
866 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, EIGNE
))
872 return(append_delims(mdoc
, line
, pos
, buf
));
877 * Block full-explicit and full-implicit.
880 blk_full(MACRO_PROT_ARGS
)
882 int c
, lastarg
, reopen
, dohead
;
883 struct mdoc_arg
*arg
;
887 * Whether to process a block-head section. If this is
888 * non-zero, then a head will be opened for all line arguments.
889 * If not, then the head will always be empty and only a body
890 * will be opened, which will stay open at the eoln.
902 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)) {
903 if ( ! rew_subblock(MDOC_BODY
, mdoc
,
906 if ( ! rew_impblock(mdoc
, tok
, line
, ppos
))
910 for (arg
= NULL
;; ) {
912 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
914 if (ARGV_WORD
== c
) {
928 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, arg
))
930 mdoc
->next
= MDOC_NEXT_CHILD
;
932 if (0 == buf
[*pos
]) {
933 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
935 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
938 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
940 mdoc
->next
= MDOC_NEXT_CHILD
;
944 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
947 /* Immediately close out head and enter body, if applicable. */
950 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
952 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
956 mdoc
->next
= MDOC_NEXT_CHILD
;
958 for (reopen
= 0;; ) {
960 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
966 if (ARGS_PHRASE
== c
) {
968 if (reopen
&& ! mdoc_head_alloc
969 (mdoc
, line
, ppos
, tok
))
971 mdoc
->next
= MDOC_NEXT_CHILD
;
973 * Phrases are self-contained macro phrases used
974 * in the columnar output of a macro. They need
977 if ( ! phrase(mdoc
, line
, lastarg
, buf
))
979 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
987 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
991 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
993 mdoc
->next
= MDOC_NEXT_SIBLING
;
997 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1002 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1005 /* If the body's already open, then just return. */
1009 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1011 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1013 mdoc
->next
= MDOC_NEXT_CHILD
;
1020 * Block partial-imnplicit scope.
1023 blk_part_imp(MACRO_PROT_ARGS
)
1027 struct mdoc_node
*blk
, *body
, *n
;
1029 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1031 mdoc
->next
= MDOC_NEXT_CHILD
;
1034 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1036 mdoc
->next
= MDOC_NEXT_SIBLING
;
1038 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1040 mdoc
->next
= MDOC_NEXT_CHILD
;
1043 /* XXX - no known argument macros. */
1045 for (lastarg
= ppos
;; ) {
1047 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1048 assert(ARGS_PHRASE
!= c
);
1050 if (ARGS_ERROR
== c
)
1052 if (ARGS_PUNCT
== c
)
1057 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1059 else if (MDOC_MAX
== c
) {
1060 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1062 mdoc
->next
= MDOC_NEXT_SIBLING
;
1066 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1072 * Since we know what our context is, we can rewind directly to
1073 * it. This allows us to accomodate for our scope being
1074 * violated by another token.
1077 for (n
= mdoc
->last
; n
; n
= n
->parent
)
1081 if (NULL
== n
&& ! mdoc_nwarn(mdoc
, body
, EIMPBRK
))
1084 if (n
&& ! rew_last(mdoc
, body
))
1087 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1090 if (n
&& ! rew_last(mdoc
, blk
))
1098 * Block partial-explicit macros.
1101 blk_part_exp(MACRO_PROT_ARGS
)
1103 int lastarg
, flushed
, j
, c
, maxargs
;
1110 * Number of arguments (head arguments). Only `Eo' has these,
1122 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1124 mdoc
->next
= MDOC_NEXT_CHILD
;
1127 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1129 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1132 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1135 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1138 mdoc
->next
= MDOC_NEXT_CHILD
;
1140 for (j
= 0; ; j
++) {
1142 if (j
== maxargs
&& ! flushed
) {
1143 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1147 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1149 mdoc
->next
= MDOC_NEXT_CHILD
;
1152 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1153 assert(ARGS_PHRASE
!= c
);
1155 if (ARGS_ERROR
== c
)
1157 if (ARGS_PUNCT
== c
)
1162 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1164 else if (MDOC_MAX
!= c
) {
1166 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1170 if ( ! mdoc_body_alloc(mdoc
, line
,
1173 mdoc
->next
= MDOC_NEXT_CHILD
;
1175 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
,
1181 if ( ! flushed
&& mdoc_isdelim(p
)) {
1182 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1186 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1188 mdoc
->next
= MDOC_NEXT_CHILD
;
1191 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1193 mdoc
->next
= MDOC_NEXT_SIBLING
;
1197 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1199 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1201 mdoc
->next
= MDOC_NEXT_CHILD
;
1206 return(append_delims(mdoc
, line
, pos
, buf
));
1211 * In-line macros where reserved words signal closure of the macro.
1212 * Macros also have a fixed number of arguments.
1215 in_line_argn(MACRO_PROT_ARGS
)
1217 int lastarg
, flushed
, j
, c
, maxargs
;
1218 struct mdoc_arg
*arg
;
1223 * Fixed maximum arguments per macro. Some of these have none
1224 * and close as soon as the invocation is parsed.
1242 for (lastarg
= ppos
, arg
= NULL
;; ) {
1244 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1246 if (ARGV_WORD
== c
) {
1256 mdoc_argv_free(arg
);
1260 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1262 mdoc
->next
= MDOC_NEXT_CHILD
;
1264 for (flushed
= j
= 0; ; j
++) {
1267 if (j
== maxargs
&& ! flushed
) {
1268 if ( ! rew_elem(mdoc
, tok
))
1273 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1275 if (ARGS_ERROR
== c
)
1277 if (ARGS_PUNCT
== c
)
1282 if (-1 == (c
= lookup(mdoc
, line
, lastarg
, tok
, p
)))
1284 else if (MDOC_MAX
!= c
) {
1285 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1288 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1293 if ( ! (MDOC_IGNDELIM
& mdoc_macros
[tok
].flags
) &&
1294 ! flushed
&& mdoc_isdelim(p
)) {
1295 if ( ! rew_elem(mdoc
, tok
))
1300 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1302 mdoc
->next
= MDOC_NEXT_SIBLING
;
1305 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1310 return(append_delims(mdoc
, line
, pos
, buf
));
1315 * In-line macro that spans an entire line. May be callable, but has no
1316 * subsequent parsed arguments.
1319 in_line_eoln(MACRO_PROT_ARGS
)
1322 struct mdoc_arg
*arg
;
1325 assert( ! (MDOC_PARSED
& mdoc_macros
[tok
].flags
));
1331 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1333 if (ARGV_WORD
== c
) {
1342 mdoc_argv_free(arg
);
1346 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1349 mdoc
->next
= MDOC_NEXT_CHILD
;
1353 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1355 if (ARGS_ERROR
== w
)
1360 c
= ARGS_QWORD
== w
? MDOC_MAX
:
1361 lookup(mdoc
, line
, la
, tok
, p
);
1363 if (MDOC_MAX
!= c
&& -1 != c
) {
1364 if ( ! rew_elem(mdoc
, tok
))
1366 return(mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
));
1370 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1372 mdoc
->next
= MDOC_NEXT_SIBLING
;
1375 return(rew_elem(mdoc
, tok
));
1381 obsolete(MACRO_PROT_ARGS
)
1384 return(mdoc_pwarn(mdoc
, line
, ppos
, EOBS
));
1389 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1390 * They're unusual because they're basically free-form text until a
1391 * macro is encountered.
1394 phrase(struct mdoc
*mdoc
, int line
, int ppos
, char *buf
)
1399 for (pos
= ppos
; ; ) {
1402 /* Note: no calling context! */
1403 w
= mdoc_zargs(mdoc
, line
, &pos
, buf
, &p
);
1405 if (ARGS_ERROR
== w
)
1410 c
= ARGS_QWORD
== w
? MDOC_MAX
:
1411 mdoc_hash_find(mdoc
->htab
, p
);
1413 if (MDOC_MAX
!= c
&& -1 != c
) {
1414 if ( ! mdoc_macro(mdoc
, c
, line
, la
, &pos
, buf
))
1416 return(append_delims(mdoc
, line
, &pos
, buf
));
1420 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1422 mdoc
->next
= MDOC_NEXT_SIBLING
;