]>
git.cameronkatri.com Git - mandoc.git/blob - mdoc_macro.c
1 /* $Id: mdoc_macro.c,v 1.30 2009/08/13 11:43:24 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
*); /* FIXME: make const */
49 static int append_delims(struct mdoc
*, int, int *, char *);
50 static int lookup(struct mdoc
*, int, const char *);
51 static int lookup_raw(struct mdoc
*, const char *);
52 static int swarn(struct mdoc
*, enum mdoc_type
, int, int,
53 const struct mdoc_node
*);
55 /* Central table of library: who gets parsed how. */
57 const struct mdoc_macro __mdoc_macros
[MDOC_MAX
] = {
58 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ap */
59 { in_line_eoln
, MDOC_PROLOGUE
}, /* Dd */
60 { in_line_eoln
, MDOC_PROLOGUE
}, /* Dt */
61 { in_line_eoln
, MDOC_PROLOGUE
}, /* Os */
62 { blk_full
, 0 }, /* Sh */
63 { blk_full
, 0 }, /* Ss */
64 { in_line_eoln
, 0 }, /* Pp */
65 { blk_part_imp
, MDOC_PARSED
}, /* D1 */
66 { blk_part_imp
, MDOC_PARSED
}, /* Dl */
67 { blk_full
, MDOC_EXPLICIT
}, /* Bd */
68 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ed */
69 { blk_full
, MDOC_EXPLICIT
}, /* Bl */
70 { blk_exp_close
, MDOC_EXPLICIT
}, /* El */
71 { blk_full
, MDOC_PARSED
}, /* It */
72 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ad */
73 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* An */
74 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ar */
75 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Cd */
76 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Cm */
77 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dv */
78 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Er */
79 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ev */
80 { in_line_eoln
, 0 }, /* Ex */
81 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fa */
82 { in_line_eoln
, 0 }, /* Fd */
83 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fl */
84 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fn */
85 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ft */
86 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ic */
87 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* In */
88 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Li */
89 { blk_full
, 0 }, /* Nd */
90 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nm */
91 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Op */
92 { obsolete
, 0 }, /* Ot */
93 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pa */
94 { in_line_eoln
, 0 }, /* Rv */
95 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* St */
96 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Va */
97 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Vt */
98 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Xr */
99 { in_line_eoln
, 0 }, /* %A */
100 { in_line_eoln
, 0 }, /* %B */
101 { in_line_eoln
, 0 }, /* %D */
102 { in_line_eoln
, 0 }, /* %I */
103 { in_line_eoln
, 0 }, /* %J */
104 { in_line_eoln
, 0 }, /* %N */
105 { in_line_eoln
, 0 }, /* %O */
106 { in_line_eoln
, 0 }, /* %P */
107 { in_line_eoln
, 0 }, /* %R */
108 { in_line_eoln
, 0 }, /* %T */
109 { in_line_eoln
, 0 }, /* %V */
110 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ac */
111 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Ao */
112 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Aq */
113 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* At */
114 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Bc */
115 { blk_full
, MDOC_EXPLICIT
}, /* Bf */
116 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bo */
117 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bq */
118 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bsx */
119 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Bx */
120 { in_line_eoln
, 0 }, /* Db */
121 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Dc */
122 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Do */
123 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dq */
124 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Ec */
125 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ef */
126 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Em */
127 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Eo */
128 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Fx */
129 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ms */
130 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* No */
131 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ns */
132 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Nx */
133 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ox */
134 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Pc */
135 { in_line_argn
, MDOC_PARSED
| MDOC_IGNDELIM
}, /* Pf */
136 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Po */
137 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Pq */
138 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Qc */
139 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ql */
140 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Qo */
141 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Qq */
142 { blk_exp_close
, MDOC_EXPLICIT
}, /* Re */
143 { blk_full
, MDOC_EXPLICIT
}, /* Rs */
144 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Sc */
145 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* So */
146 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sq */
147 { in_line_eoln
, 0 }, /* Sm */
148 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sx */
149 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Sy */
150 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Tn */
151 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Ux */
152 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Xc */
153 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Xo */
154 { blk_full
, MDOC_EXPLICIT
| MDOC_CALLABLE
}, /* Fo */
155 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Fc */
156 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Oo */
157 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Oc */
158 { blk_full
, MDOC_EXPLICIT
}, /* Bk */
159 { blk_exp_close
, MDOC_EXPLICIT
}, /* Ek */
160 { in_line_eoln
, 0 }, /* Bt */
161 { in_line_eoln
, 0 }, /* Hf */
162 { obsolete
, 0 }, /* Fr */
163 { in_line_eoln
, 0 }, /* Ud */
164 { in_line_eoln
, 0 }, /* Lb */
165 { in_line_eoln
, 0 }, /* Lp */
166 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Lk */
167 { in_line
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Mt */
168 { blk_part_imp
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Brq */
169 { blk_part_exp
, MDOC_CALLABLE
| MDOC_PARSED
| MDOC_EXPLICIT
}, /* Bro */
170 { blk_exp_close
, MDOC_EXPLICIT
| MDOC_CALLABLE
| MDOC_PARSED
}, /* Brc */
171 { in_line_eoln
, 0 }, /* %C */
172 { obsolete
, 0 }, /* Es */
173 { obsolete
, 0 }, /* En */
174 { in_line_argn
, MDOC_CALLABLE
| MDOC_PARSED
}, /* Dx */
175 { in_line_eoln
, 0 }, /* %Q */
176 { in_line_eoln
, 0 }, /* br */
177 { in_line_eoln
, 0 }, /* sp */
180 const struct mdoc_macro
* const mdoc_macros
= __mdoc_macros
;
184 swarn(struct mdoc
*mdoc
, enum mdoc_type type
,
185 int line
, int pos
, const struct mdoc_node
*p
)
187 const char *n
, *t
, *tt
;
205 n
= mdoc_macronames
[p
->tok
];
209 n
= mdoc_macronames
[p
->tok
];
213 n
= mdoc_macronames
[p
->tok
];
220 if ( ! (MDOC_IGN_SCOPE
& mdoc
->pflags
))
221 return(mdoc_verr(mdoc
, line
, pos
,
222 "%s scope breaks %s scope of %s",
224 return(mdoc_vwarn(mdoc
, line
, pos
,
225 "%s scope breaks %s scope of %s",
231 * This is called at the end of parsing. It must traverse up the tree,
232 * closing out open [implicit] scopes. Obviously, open explicit scopes
236 mdoc_macroend(struct mdoc
*mdoc
)
240 /* Scan for open explicit scopes. */
242 n
= MDOC_VALID
& mdoc
->last
->flags
?
243 mdoc
->last
->parent
: mdoc
->last
;
245 for ( ; n
; n
= n
->parent
) {
246 if (MDOC_BLOCK
!= n
->type
)
248 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[n
->tok
].flags
))
250 return(mdoc_nerr(mdoc
, n
, EOPEN
));
253 return(rew_last(mdoc
, mdoc
->first
));
257 lookup(struct mdoc
*mdoc
, int from
, const char *p
)
260 if ( ! (MDOC_PARSED
& mdoc_macros
[from
].flags
))
262 return(lookup_raw(mdoc
, p
));
267 lookup_raw(struct mdoc
*mdoc
, const char *p
)
271 if (MDOC_MAX
== (res
= mdoc_hash_find(mdoc
->htab
, p
)))
273 if (MDOC_CALLABLE
& mdoc_macros
[res
].flags
)
280 rew_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
284 mdoc
->next
= MDOC_NEXT_SIBLING
;
287 while (mdoc
->last
!= to
) {
288 if ( ! mdoc_valid_post(mdoc
))
290 if ( ! mdoc_action_post(mdoc
))
292 mdoc
->last
= mdoc
->last
->parent
;
296 if ( ! mdoc_valid_post(mdoc
))
298 return(mdoc_action_post(mdoc
));
347 * Rewind rules. This indicates whether to stop rewinding
348 * (REWIND_HALT) without touching our current scope, stop rewinding and
349 * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
350 * The scope-closing and so on occurs in the various rew_* routines.
353 rew_dohalt(int tok
, enum mdoc_type type
, const struct mdoc_node
*p
)
356 if (MDOC_ROOT
== p
->type
)
358 if (MDOC_VALID
& p
->flags
)
359 return(REWIND_NOHALT
);
383 assert(MDOC_HEAD
!= type
);
384 assert(MDOC_TAIL
!= type
);
385 if (type
== p
->type
&& tok
== p
->tok
)
386 return(REWIND_REWIND
);
389 assert(MDOC_TAIL
!= type
);
390 if (type
== p
->type
&& tok
== p
->tok
)
391 return(REWIND_REWIND
);
392 if (MDOC_BODY
== p
->type
&& MDOC_Bl
== p
->tok
)
396 if (type
== p
->type
&& tok
== p
->tok
)
397 return(REWIND_REWIND
);
402 assert(MDOC_TAIL
!= type
);
403 if (type
== p
->type
&& tok
== p
->tok
)
404 return(REWIND_REWIND
);
405 if (MDOC_BODY
== p
->type
&& MDOC_Sh
== p
->tok
)
439 if (type
== p
->type
&& tok
== p
->tok
)
440 return(REWIND_REWIND
);
443 /* Multi-line explicit scope close. */
475 if (type
== p
->type
&& rew_alt(tok
) == p
->tok
)
476 return(REWIND_REWIND
);
483 return(REWIND_NOHALT
);
488 * See if we can break an encountered scope (the rew_dohalt has returned
492 rew_dobreak(int tok
, const struct mdoc_node
*p
)
495 assert(MDOC_ROOT
!= p
->type
);
496 if (MDOC_ELEM
== p
->type
)
498 if (MDOC_TEXT
== p
->type
)
500 if (MDOC_VALID
& p
->flags
)
505 return(MDOC_It
== p
->tok
);
507 return(MDOC_Nd
== p
->tok
);
509 return(MDOC_Ss
== p
->tok
);
511 if (MDOC_Nd
== p
->tok
)
513 if (MDOC_Ss
== p
->tok
)
515 return(MDOC_Sh
== p
->tok
);
517 if (MDOC_It
== p
->tok
)
521 /* XXX - experimental! */
522 if (MDOC_Op
== p
->tok
)
529 if (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)
530 return(p
->tok
== rew_alt(tok
));
531 else if (MDOC_BLOCK
== p
->type
)
534 return(tok
== p
->tok
);
539 rew_elem(struct mdoc
*mdoc
, int tok
)
544 if (MDOC_ELEM
!= n
->type
)
546 assert(MDOC_ELEM
== n
->type
);
547 assert(tok
== n
->tok
);
549 return(rew_last(mdoc
, n
));
554 rew_subblock(enum mdoc_type type
, struct mdoc
*mdoc
,
555 int tok
, int line
, int ppos
)
561 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
562 c
= rew_dohalt(tok
, type
, n
);
563 if (REWIND_HALT
== c
)
565 if (REWIND_REWIND
== c
)
567 else if (rew_dobreak(tok
, n
))
569 if ( ! swarn(mdoc
, type
, line
, ppos
, n
))
574 return(rew_last(mdoc
, n
));
579 rew_expblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
585 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
586 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
587 if (REWIND_HALT
== c
)
588 return(mdoc_perr(mdoc
, line
, ppos
, ENOCTX
));
589 if (REWIND_REWIND
== c
)
591 else if (rew_dobreak(tok
, n
))
593 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
598 return(rew_last(mdoc
, n
));
602 /* FIXME: can this be merged with subblock? */
604 rew_impblock(struct mdoc
*mdoc
, int tok
, int line
, int ppos
)
610 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
611 c
= rew_dohalt(tok
, MDOC_BLOCK
, n
);
612 if (REWIND_HALT
== c
)
614 else if (REWIND_REWIND
== c
)
616 else if (rew_dobreak(tok
, n
))
618 if ( ! swarn(mdoc
, MDOC_BLOCK
, line
, ppos
, n
))
623 return(rew_last(mdoc
, n
));
628 append_delims(struct mdoc
*mdoc
, int line
, int *pos
, char *buf
)
638 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
639 assert(ARGS_PHRASE
!= c
);
643 else if (ARGS_EOLN
== c
)
645 assert(mdoc_isdelim(p
));
646 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
648 mdoc
->next
= MDOC_NEXT_SIBLING
;
656 * Close out block partial/full explicit.
659 blk_exp_close(MACRO_PROT_ARGS
)
661 int j
, c
, lastarg
, maxargs
, flushed
;
673 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
675 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, ENOLINE
))
678 if ( ! rew_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
680 return(rew_expblock(mdoc
, tok
, line
, ppos
));
683 if ( ! rew_subblock(MDOC_BODY
, mdoc
, tok
, line
, ppos
))
687 if ( ! mdoc_tail_alloc(mdoc
, line
,
690 mdoc
->next
= MDOC_NEXT_CHILD
;
693 for (flushed
= j
= 0; ; j
++) {
696 if (j
== maxargs
&& ! flushed
) {
697 if ( ! rew_expblock(mdoc
, tok
, line
, ppos
))
702 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
711 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
713 if ( ! rew_expblock(mdoc
, tok
,
718 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
723 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
725 mdoc
->next
= MDOC_NEXT_SIBLING
;
728 if ( ! flushed
&& ! rew_expblock(mdoc
, tok
, line
, ppos
))
733 return(append_delims(mdoc
, line
, pos
, buf
));
738 * In-line macros where reserved words cause scope close-reopen.
741 in_line(MACRO_PROT_ARGS
)
743 int la
, lastpunct
, c
, w
, cnt
, d
, nc
;
744 struct mdoc_arg
*arg
;
748 * Whether we allow ignored elements (those without content,
749 * usually because of reserved words) to squeak by.
770 for (arg
= NULL
;; ) {
772 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
774 if (ARGV_WORD
== c
) {
787 for (cnt
= 0, lastpunct
= 1;; ) {
789 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
798 /* Quoted words shouldn't be looked-up. */
800 c
= ARGS_QWORD
== w
? MDOC_MAX
: lookup(mdoc
, tok
, p
);
803 * In this case, we've located a submacro and must
804 * execute it. Close out scope, if open. If no
805 * elements have been generated, either create one (nc)
806 * or raise a warning.
810 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
812 if (nc
&& 0 == cnt
) {
813 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
,
816 if ( ! rew_last(mdoc
, mdoc
->last
))
818 } else if ( ! nc
&& 0 == cnt
) {
820 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, EIGNE
))
823 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
828 return(append_delims(mdoc
, line
, pos
, buf
));
832 * Non-quote-enclosed punctuation. Set up our scope, if
833 * a word; rewind the scope, if a delimiter; then append
839 if (ARGS_QWORD
!= w
&& d
) {
840 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
843 } else if (lastpunct
) {
844 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
847 mdoc
->next
= MDOC_NEXT_CHILD
;
853 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
855 mdoc
->next
= MDOC_NEXT_SIBLING
;
858 if (0 == lastpunct
&& ! rew_elem(mdoc
, tok
))
862 * If no elements have been collected and we're allowed to have
863 * empties (nc), open a scope and close it out. Otherwise,
867 if (nc
&& 0 == cnt
) {
868 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
);
871 if ( ! rew_last(mdoc
, mdoc
->last
))
873 } else if ( ! nc
&& 0 == cnt
) {
875 if ( ! mdoc_pwarn(mdoc
, line
, ppos
, EIGNE
))
881 return(append_delims(mdoc
, line
, pos
, buf
));
886 * Block full-explicit and full-implicit.
889 blk_full(MACRO_PROT_ARGS
)
891 int c
, lastarg
, reopen
, dohead
;
892 struct mdoc_arg
*arg
;
896 * Whether to process a block-head section. If this is
897 * non-zero, then a head will be opened for all line arguments.
898 * If not, then the head will always be empty and only a body
899 * will be opened, which will stay open at the eoln.
911 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
)) {
912 if ( ! rew_subblock(MDOC_BODY
, mdoc
,
915 if ( ! rew_impblock(mdoc
, tok
, line
, ppos
))
919 for (arg
= NULL
;; ) {
921 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
923 if (ARGV_WORD
== c
) {
937 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, arg
))
939 mdoc
->next
= MDOC_NEXT_CHILD
;
941 if (0 == buf
[*pos
]) {
942 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
944 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
947 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
949 mdoc
->next
= MDOC_NEXT_CHILD
;
953 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
956 /* Immediately close out head and enter body, if applicable. */
959 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
961 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
965 mdoc
->next
= MDOC_NEXT_CHILD
;
967 for (reopen
= 0;; ) {
969 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
975 if (ARGS_PHRASE
== c
) {
977 if (reopen
&& ! mdoc_head_alloc
978 (mdoc
, line
, ppos
, tok
))
980 mdoc
->next
= MDOC_NEXT_CHILD
;
982 * Phrases are self-contained macro phrases used
983 * in the columnar output of a macro. They need
986 if ( ! phrase(mdoc
, line
, lastarg
, buf
))
988 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
996 if (MDOC_MAX
== (c
= lookup(mdoc
, tok
, p
))) {
997 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
999 mdoc
->next
= MDOC_NEXT_SIBLING
;
1003 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1008 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1011 /* If the body's already open, then just return. */
1015 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1017 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1019 mdoc
->next
= MDOC_NEXT_CHILD
;
1026 * Block partial-imnplicit scope.
1029 blk_part_imp(MACRO_PROT_ARGS
)
1033 struct mdoc_node
*blk
, *body
, *n
;
1035 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1037 mdoc
->next
= MDOC_NEXT_CHILD
;
1040 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1042 mdoc
->next
= MDOC_NEXT_SIBLING
;
1044 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1046 mdoc
->next
= MDOC_NEXT_CHILD
;
1049 /* XXX - no known argument macros. */
1053 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1054 assert(ARGS_PHRASE
!= c
);
1056 if (ARGS_ERROR
== c
)
1058 if (ARGS_PUNCT
== c
)
1063 if (MDOC_MAX
== (c
= lookup(mdoc
, tok
, p
))) {
1064 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1066 mdoc
->next
= MDOC_NEXT_SIBLING
;
1070 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1076 * Since we know what our context is, we can rewind directly to
1077 * it. This allows us to accomodate for our scope being
1078 * violated by another token.
1081 for (n
= mdoc
->last
; n
; n
= n
->parent
)
1085 if (NULL
== n
&& ! mdoc_nwarn(mdoc
, body
, EIMPBRK
))
1088 if (n
&& ! rew_last(mdoc
, body
))
1091 if (1 == ppos
&& ! append_delims(mdoc
, line
, pos
, buf
))
1094 if (n
&& ! rew_last(mdoc
, blk
))
1102 * Block partial-explicit macros.
1105 blk_part_exp(MACRO_PROT_ARGS
)
1107 int lastarg
, flushed
, j
, c
, maxargs
;
1113 * Number of arguments (head arguments). Only `Eo' has these,
1125 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, NULL
))
1127 mdoc
->next
= MDOC_NEXT_CHILD
;
1130 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1132 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1135 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1138 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
1141 mdoc
->next
= MDOC_NEXT_CHILD
;
1143 for (j
= 0; ; j
++) {
1145 if (j
== maxargs
&& ! flushed
) {
1146 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1150 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1152 mdoc
->next
= MDOC_NEXT_CHILD
;
1155 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1156 assert(ARGS_PHRASE
!= c
);
1158 if (ARGS_ERROR
== c
)
1160 if (ARGS_PUNCT
== c
)
1165 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
1167 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1171 if ( ! mdoc_body_alloc(mdoc
, line
,
1174 mdoc
->next
= MDOC_NEXT_CHILD
;
1176 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
,
1182 if ( ! flushed
&& mdoc_isdelim(p
)) {
1183 if ( ! rew_subblock(MDOC_HEAD
, mdoc
,
1187 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1189 mdoc
->next
= MDOC_NEXT_CHILD
;
1192 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1194 mdoc
->next
= MDOC_NEXT_SIBLING
;
1198 if ( ! rew_subblock(MDOC_HEAD
, mdoc
, tok
, line
, ppos
))
1200 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
1202 mdoc
->next
= MDOC_NEXT_CHILD
;
1207 return(append_delims(mdoc
, line
, pos
, buf
));
1212 * In-line macros where reserved words signal closure of the macro.
1213 * Macros also have a fixed number of arguments.
1216 in_line_argn(MACRO_PROT_ARGS
)
1218 int lastarg
, flushed
, j
, c
, maxargs
;
1219 struct mdoc_arg
*arg
;
1224 * Fixed maximum arguments per macro. Some of these have none
1225 * and close as soon as the invocation is parsed.
1243 for (arg
= NULL
;; ) {
1245 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1247 if (ARGV_WORD
== c
) {
1257 mdoc_argv_free(arg
);
1261 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1263 mdoc
->next
= MDOC_NEXT_CHILD
;
1265 for (flushed
= j
= 0; ; j
++) {
1268 if (j
== maxargs
&& ! flushed
) {
1269 if ( ! rew_elem(mdoc
, tok
))
1274 c
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1276 if (ARGS_ERROR
== c
)
1278 if (ARGS_PUNCT
== c
)
1283 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
1284 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1287 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
1292 if ( ! (MDOC_IGNDELIM
& mdoc_macros
[tok
].flags
) &&
1293 ! flushed
&& mdoc_isdelim(p
)) {
1294 if ( ! rew_elem(mdoc
, tok
))
1299 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
1301 mdoc
->next
= MDOC_NEXT_SIBLING
;
1304 if ( ! flushed
&& ! rew_elem(mdoc
, tok
))
1309 return(append_delims(mdoc
, line
, pos
, buf
));
1314 * In-line macro that spans an entire line. May be callable, but has no
1315 * subsequent parsed arguments.
1318 in_line_eoln(MACRO_PROT_ARGS
)
1321 struct mdoc_arg
*arg
;
1324 assert( ! (MDOC_PARSED
& mdoc_macros
[tok
].flags
));
1330 c
= mdoc_argv(mdoc
, line
, tok
, &arg
, pos
, buf
);
1332 if (ARGV_WORD
== c
) {
1341 mdoc_argv_free(arg
);
1345 if ( ! mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, arg
))
1348 mdoc
->next
= MDOC_NEXT_CHILD
;
1352 w
= mdoc_args(mdoc
, line
, pos
, buf
, tok
, &p
);
1354 if (ARGS_ERROR
== w
)
1359 c
= ARGS_QWORD
== w
? MDOC_MAX
: lookup(mdoc
, tok
, p
);
1361 if (MDOC_MAX
!= c
) {
1362 if ( ! rew_elem(mdoc
, tok
))
1364 return(mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
));
1367 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1369 mdoc
->next
= MDOC_NEXT_SIBLING
;
1372 return(rew_elem(mdoc
, tok
));
1378 obsolete(MACRO_PROT_ARGS
)
1381 return(mdoc_pwarn(mdoc
, line
, ppos
, EOBS
));
1386 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1387 * They're unusual because they're basically free-form text until a
1388 * macro is encountered.
1391 phrase(struct mdoc
*mdoc
, int line
, int ppos
, char *buf
)
1396 for (pos
= ppos
; ; ) {
1399 /* Note: no calling context! */
1400 w
= mdoc_zargs(mdoc
, line
, &pos
, buf
, &p
);
1402 if (ARGS_ERROR
== w
)
1407 c
= ARGS_QWORD
== w
? MDOC_MAX
: lookup_raw(mdoc
, p
);
1409 if (MDOC_MAX
!= c
) {
1410 if ( ! mdoc_macro(mdoc
, c
, line
, la
, &pos
, buf
))
1412 return(append_delims(mdoc
, line
, &pos
, buf
));
1415 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
1417 mdoc
->next
= MDOC_NEXT_SIBLING
;