]>
git.cameronkatri.com Git - mandoc.git/blob - macro.c
1 /* $Id: macro.c,v 1.28 2009/01/08 14:55:59 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
30 /* FIXME: maxlineargs should be per LINE, no per TOKEN. */
32 static int rewind_elem(struct mdoc
*, int);
33 static int rewind_impblock(struct mdoc
*, int);
34 static int rewind_expblock(struct mdoc
*, int);
35 static int rewind_head(struct mdoc
*, int);
36 static int rewind_body(struct mdoc
*, int);
37 static int rewind_last(struct mdoc
*, struct mdoc_node
*);
38 static int append_delims(struct mdoc
*,
39 int, int, int *, char *);
40 static int lookup(struct mdoc
*, int, const char *);
44 lookup(struct mdoc
*mdoc
, int from
, const char *p
)
47 if ( ! (MDOC_PARSED
& mdoc_macros
[from
].flags
))
49 return(mdoc_find(mdoc
, p
));
54 rewind_last(struct mdoc
*mdoc
, struct mdoc_node
*to
)
58 while (mdoc
->last
!= to
) {
59 if ( ! mdoc_valid_post(mdoc
))
61 if ( ! mdoc_action_post(mdoc
))
63 mdoc
->last
= mdoc
->last
->parent
;
67 mdoc
->next
= MDOC_NEXT_SIBLING
;
68 if ( ! mdoc_valid_post(mdoc
))
70 return(mdoc_action_post(mdoc
));
75 rewind_elem(struct mdoc
*mdoc
, int tok
)
80 if (MDOC_ELEM
!= n
->type
)
82 assert(MDOC_ELEM
== n
->type
);
83 assert(tok
== n
->data
.elem
.tok
);
85 return(rewind_last(mdoc
, n
));
90 rewind_body(struct mdoc
*mdoc
, int tok
)
98 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
99 if (MDOC_BODY
!= n
->type
)
101 if (tok
== (t
= n
->data
.head
.tok
))
103 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[t
].flags
))
105 return(mdoc_verr(mdoc
, n
, ERR_SCOPE_BREAK
));
109 return(rewind_last(mdoc
, n
));
114 rewind_head(struct mdoc
*mdoc
, int tok
)
122 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
123 if (MDOC_HEAD
!= n
->type
)
125 if (tok
== (t
= n
->data
.head
.tok
))
127 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[t
].flags
))
129 return(mdoc_verr(mdoc
, n
, ERR_SCOPE_BREAK
));
133 return(rewind_last(mdoc
, n
));
138 rewind_expblock(struct mdoc
*mdoc
, int tok
)
146 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
147 if (MDOC_BLOCK
!= n
->type
)
149 if (tok
== (t
= n
->data
.block
.tok
))
151 if (MDOC_NESTED
& mdoc_macros
[t
].flags
)
153 return(mdoc_verr(mdoc
, n
, ERR_SCOPE_BREAK
));
157 return(rewind_last(mdoc
, n
));
162 rewind_impblock(struct mdoc
*mdoc
, int tok
)
167 n
= mdoc
->last
? mdoc
->last
->parent
: NULL
;
170 for ( ; n
; n
= n
->parent
) {
171 if (MDOC_BLOCK
!= n
->type
)
173 if (tok
== (t
= n
->data
.block
.tok
))
175 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[t
].flags
))
177 if (MDOC_NESTED
& mdoc_macros
[t
].flags
)
179 return(mdoc_verr(mdoc
, n
, ERR_SCOPE_BREAK
));
184 return(rewind_last(mdoc
, n
));
189 append_delims(struct mdoc
*mdoc
, int tok
,
190 int line
, int *pos
, char *buf
)
200 c
= mdoc_args(mdoc
, line
, pos
, buf
, 0, &p
);
203 else if (ARGS_EOLN
== c
)
205 assert(mdoc_isdelim(p
));
206 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
208 mdoc
->next
= MDOC_NEXT_SIBLING
;
217 macro_close_explicit(MACRO_PROT_ARGS
)
219 int tt
, j
, c
, lastarg
, maxargs
, flushed
;
282 if ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
)) {
284 return(rewind_expblock(mdoc
, tt
));
285 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_EQ0
));
288 if ( ! rewind_body(mdoc
, tt
))
295 if ( ! mdoc_tail_alloc(mdoc
, line
, ppos
, tt
))
297 mdoc
->next
= MDOC_NEXT_CHILD
;
300 for (j
= 0; j
< MDOC_LINEARG_MAX
; j
++) {
303 if (j
== maxargs
&& ! flushed
) {
304 if ( ! rewind_expblock(mdoc
, tt
))
309 c
= mdoc_args(mdoc
, line
, pos
, buf
, ARGS_DELIM
, &p
);
317 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
319 if ( ! rewind_expblock(mdoc
, tt
))
323 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
328 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
330 mdoc
->next
= MDOC_NEXT_SIBLING
;
333 if (MDOC_LINEARG_MAX
== j
)
334 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
336 if ( ! flushed
&& ! rewind_expblock(mdoc
, tt
))
341 return(append_delims(mdoc
, tok
, line
, pos
, buf
));
346 * A general text domain macro. When invoked, this opens a scope that
347 * accepts words until either end-of-line, only-punctuation, or a
348 * callable macro. If the word is punctuation (not only-punctuation),
349 * then the scope is closed out, the punctuation appended, then the
350 * scope opened again. If any terminating conditions are met, the scope
351 * is closed out. If this is the first macro in the line and
352 * only-punctuation remains, this punctuation is flushed.
355 macro_text(MACRO_PROT_ARGS
)
357 int la
, lastpunct
, c
, sz
, fl
, argc
;
358 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
364 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
367 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
368 if (ARGV_EOLN
== c
|| ARGV_WORD
== c
)
370 else if (ARGV_ARG
== c
)
372 mdoc_argv_free(argc
, argv
);
376 if (MDOC_LINEARG_MAX
== argc
) {
377 mdoc_argv_free(argc
, argv
);
378 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
381 c
= mdoc_elem_alloc(mdoc
, line
, la
, tok
, argc
, argv
);
384 mdoc_argv_free(argc
, argv
);
388 mdoc
->next
= MDOC_NEXT_CHILD
;
391 if (MDOC_QUOTABLE
& mdoc_macros
[tok
].flags
)
394 for (lastpunct
= sz
= 0; sz
+ argc
< MDOC_LINEARG_MAX
; sz
++) {
398 c
= mdoc_elem_alloc(mdoc
, line
,
399 la
, tok
, argc
, argv
);
401 mdoc_argv_free(argc
, argv
);
404 mdoc
->next
= MDOC_NEXT_CHILD
;
408 c
= mdoc_args(mdoc
, line
, pos
, buf
, fl
, &p
);
409 if (ARGS_ERROR
== c
) {
410 mdoc_argv_free(argc
, argv
);
419 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
420 if ( ! rewind_elem(mdoc
, tok
)) {
421 mdoc_argv_free(argc
, argv
);
424 mdoc_argv_free(argc
, argv
);
426 c
= mdoc_macro(mdoc
, c
, line
, la
, pos
, buf
);
431 return(append_delims(mdoc
, tok
, line
, pos
, buf
));
434 if (mdoc_isdelim(p
)) {
435 if ( ! rewind_elem(mdoc
, tok
)) {
436 mdoc_argv_free(argc
, argv
);
441 if ( ! mdoc_word_alloc(mdoc
, line
, la
, p
))
443 mdoc
->next
= MDOC_NEXT_SIBLING
;
446 mdoc_argv_free(argc
, argv
);
448 if (sz
== MDOC_LINEARG_MAX
)
449 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
451 if ( ! rewind_elem(mdoc
, tok
))
455 return(append_delims(mdoc
, tok
, line
, pos
, buf
));
460 * Implicit- or explicit-end multi-line scoped macro.
463 macro_scoped(MACRO_PROT_ARGS
)
465 int c
, lastarg
, argc
, j
;
466 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
469 assert ( ! (MDOC_CALLABLE
& mdoc_macros
[tok
].flags
));
471 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
))
472 if ( ! rewind_impblock(mdoc
, tok
))
475 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
477 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
478 if (ARGV_EOLN
== c
|| ARGV_WORD
== c
)
480 else if (ARGV_ARG
== c
)
482 mdoc_argv_free(argc
, argv
);
486 if (MDOC_LINEARG_MAX
== argc
) {
487 mdoc_argv_free(argc
, argv
);
488 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
491 c
= mdoc_block_alloc(mdoc
, line
, ppos
,
492 tok
, (size_t)argc
, argv
);
493 mdoc_argv_free(argc
, argv
);
498 mdoc
->next
= MDOC_NEXT_CHILD
;
500 if (0 == buf
[*pos
]) {
501 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
503 if ( ! rewind_head(mdoc
, tok
))
505 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
507 mdoc
->next
= MDOC_NEXT_CHILD
;
511 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
513 mdoc
->next
= MDOC_NEXT_CHILD
;
515 for (j
= 0; j
< MDOC_LINEARG_MAX
; j
++) {
517 c
= mdoc_args(mdoc
, line
, pos
, buf
, ARGS_DELIM
, &p
);
526 if (MDOC_MAX
== (c
= lookup(mdoc
, tok
, p
))) {
527 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
529 mdoc
->next
= MDOC_NEXT_SIBLING
;
533 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
538 if (j
== MDOC_LINEARG_MAX
)
539 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
541 if ( ! rewind_head(mdoc
, tok
))
543 if (1 == ppos
&& ! append_delims(mdoc
, tok
, line
, pos
, buf
))
546 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
548 mdoc
->next
= MDOC_NEXT_CHILD
;
555 * When scoped to a line, a macro encompasses all of the contents. This
556 * differs from constants or text macros, where a new macro will
557 * terminate the existing context.
560 macro_scoped_line(MACRO_PROT_ARGS
)
565 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, 0, NULL
))
567 mdoc
->next
= MDOC_NEXT_CHILD
;
569 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
571 mdoc
->next
= MDOC_NEXT_CHILD
;
573 /* XXX - no known argument macros. */
575 for (lastarg
= ppos
, j
= 0; j
< MDOC_LINEARG_MAX
; j
++) {
577 c
= mdoc_args(mdoc
, line
, pos
, buf
, ARGS_DELIM
, &p
);
586 if (MDOC_MAX
== (c
= lookup(mdoc
, tok
, p
))) {
587 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
589 mdoc
->next
= MDOC_NEXT_SIBLING
;
593 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
598 if (j
== MDOC_LINEARG_MAX
)
599 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
602 if ( ! rewind_head(mdoc
, tok
))
604 if ( ! append_delims(mdoc
, tok
, line
, pos
, buf
))
607 return(rewind_impblock(mdoc
, tok
));
612 * Constant-scope macros accept a fixed number of arguments and behave
613 * like constant macros except that they're scoped across lines.
616 macro_constant_scoped(MACRO_PROT_ARGS
)
618 int lastarg
, flushed
, j
, c
, maxargs
;
633 if ( ! mdoc_block_alloc(mdoc
, line
, ppos
, tok
, 0, NULL
))
635 mdoc
->next
= MDOC_NEXT_CHILD
;
638 if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
640 if ( ! rewind_head(mdoc
, tok
))
642 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
645 } else if ( ! mdoc_head_alloc(mdoc
, line
, ppos
, tok
))
648 mdoc
->next
= MDOC_NEXT_CHILD
;
650 for (j
= 0; j
< MDOC_LINEARG_MAX
; j
++) {
653 if (j
== maxargs
&& ! flushed
) {
654 if ( ! rewind_head(mdoc
, tok
))
657 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
659 mdoc
->next
= MDOC_NEXT_CHILD
;
662 c
= mdoc_args(mdoc
, line
, pos
, buf
, ARGS_DELIM
, &p
);
670 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
672 if ( ! rewind_head(mdoc
, tok
))
675 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
677 mdoc
->next
= MDOC_NEXT_CHILD
;
679 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
684 if ( ! flushed
&& mdoc_isdelim(p
)) {
685 if ( ! rewind_head(mdoc
, tok
))
688 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
690 mdoc
->next
= MDOC_NEXT_CHILD
;
693 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
695 mdoc
->next
= MDOC_NEXT_SIBLING
;
698 if (MDOC_LINEARG_MAX
== j
)
699 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
702 if ( ! rewind_head(mdoc
, tok
))
704 if ( ! mdoc_body_alloc(mdoc
, line
, ppos
, tok
))
706 mdoc
->next
= MDOC_NEXT_CHILD
;
711 return(append_delims(mdoc
, tok
, line
, pos
, buf
));
716 * Delimited macros are like text macros except that, should punctuation
717 * be encountered, the macro isn't re-started with remaining tokens
718 * (it's only emitted once). Delimited macros can have a maximum number
722 macro_constant_delimited(MACRO_PROT_ARGS
)
724 int lastarg
, flushed
, j
, c
, maxargs
, argc
;
725 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
746 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
748 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
749 if (ARGV_EOLN
== c
|| ARGV_WORD
== c
)
751 else if (ARGV_ARG
== c
)
753 mdoc_argv_free(argc
, argv
);
757 c
= mdoc_elem_alloc(mdoc
, line
, lastarg
, tok
, argc
, argv
);
758 mdoc_argv_free(argc
, argv
);
763 mdoc
->next
= MDOC_NEXT_CHILD
;
765 for (j
= 0; j
< MDOC_LINEARG_MAX
; j
++) {
768 if (j
== maxargs
&& ! flushed
) {
769 if ( ! rewind_elem(mdoc
, tok
))
774 c
= mdoc_args(mdoc
, line
, pos
, buf
, ARGS_DELIM
, &p
);
782 if (MDOC_MAX
!= (c
= lookup(mdoc
, tok
, p
))) {
783 if ( ! flushed
&& ! rewind_elem(mdoc
, tok
))
786 if ( ! mdoc_macro(mdoc
, c
, line
, lastarg
, pos
, buf
))
791 if ( ! flushed
&& mdoc_isdelim(p
)) {
792 if ( ! rewind_elem(mdoc
, tok
))
797 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
799 mdoc
->next
= MDOC_NEXT_SIBLING
;
802 if (MDOC_LINEARG_MAX
== j
)
803 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
805 if ( ! flushed
&& rewind_elem(mdoc
, tok
))
810 return(append_delims(mdoc
, tok
, line
, pos
, buf
));
815 * Constant macros span an entire line: they constitute a macro and all
816 * of its arguments and child data.
819 macro_constant(MACRO_PROT_ARGS
)
821 int c
, lastarg
, argc
, sz
, fl
;
822 struct mdoc_arg argv
[MDOC_LINEARG_MAX
];
825 /* FIXME: parsing macros! */
828 if (MDOC_QUOTABLE
& mdoc_macros
[tok
].flags
)
831 for (argc
= 0; argc
< MDOC_LINEARG_MAX
; argc
++) {
833 c
= mdoc_argv(mdoc
, line
, tok
, &argv
[argc
], pos
, buf
);
836 else if (ARGV_ARG
== c
)
838 else if (ARGV_WORD
== c
)
841 mdoc_argv_free(argc
, argv
);
845 c
= mdoc_elem_alloc(mdoc
, line
, ppos
, tok
, argc
, argv
);
846 mdoc_argv_free(argc
, argv
);
851 mdoc
->next
= MDOC_NEXT_CHILD
;
853 if (MDOC_LINEARG_MAX
== argc
)
854 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
856 for (sz
= 0; sz
+ argc
< MDOC_LINEARG_MAX
; sz
++) {
858 c
= mdoc_args(mdoc
, line
, pos
, buf
, fl
, &p
);
864 if ( ! mdoc_word_alloc(mdoc
, line
, lastarg
, p
))
866 mdoc
->next
= MDOC_NEXT_SIBLING
;
869 if (MDOC_LINEARG_MAX
== sz
+ argc
)
870 return(mdoc_perr(mdoc
, line
, ppos
, ERR_ARGS_MANY
));
872 return(rewind_elem(mdoc
, tok
));
878 macro_obsolete(MACRO_PROT_ARGS
)
881 return(mdoc_pwarn(mdoc
, line
, ppos
, WARN_IGN_OBSOLETE
));
886 macro_end(struct mdoc
*mdoc
)
891 return(rewind_last(mdoc
, mdoc
->first
));