]>
git.cameronkatri.com Git - mandoc.git/blob - man_macro.c
1 /* $Id: man_macro.c,v 1.13 2009/04/05 16:34:22 kristaps Exp $ */
3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
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.
26 #define FL_NLINE (1 << 0)
27 #define FL_TLINE (1 << 1)
29 static int man_args(struct man
*, int,
30 int *, char *, char **);
32 static int man_flags
[MAN_MAX
] = {
60 man_macro(struct man
*man
, int tok
, int line
,
61 int ppos
, int *pos
, char *buf
)
67 if ( ! man_elem_alloc(man
, line
, ppos
, tok
))
70 man
->next
= MAN_NEXT_CHILD
;
74 w
= man_args(man
, line
, pos
, buf
, &p
);
81 if ( ! man_word_alloc(man
, line
, la
, p
))
83 man
->next
= MAN_NEXT_SIBLING
;
86 if (n
== man
->last
&& (FL_NLINE
& man_flags
[tok
])) {
87 if (MAN_NLINE
& man
->flags
)
88 return(man_verr(man
, line
, ppos
,
89 "next-line scope already open"));
90 man
->flags
|= MAN_NLINE
;
94 if (FL_TLINE
& man_flags
[tok
]) {
95 if (MAN_NLINE
& man
->flags
)
96 return(man_verr(man
, line
, ppos
,
97 "next-line scope already open"));
98 man
->flags
|= MAN_NLINE
;
103 * Note that when TH is pruned, we'll be back at the root, so
104 * make sure that we don't clobber as its sibling.
107 for ( ; man
->last
; man
->last
= man
->last
->parent
) {
110 if (man
->last
->type
== MAN_ROOT
)
112 if ( ! man_valid_post(man
))
114 if ( ! man_action_post(man
))
121 * Same here regarding whether we're back at the root.
124 if (man
->last
->type
!= MAN_ROOT
&& ! man_valid_post(man
))
126 if (man
->last
->type
!= MAN_ROOT
&& ! man_action_post(man
))
128 if (man
->last
->type
!= MAN_ROOT
)
129 man
->next
= MAN_NEXT_SIBLING
;
136 man_macroend(struct man
*m
)
139 for ( ; m
->last
&& m
->last
!= m
->first
;
140 m
->last
= m
->last
->parent
) {
141 if ( ! man_valid_post(m
))
143 if ( ! man_action_post(m
))
146 assert(m
->last
== m
->first
);
148 if ( ! man_valid_post(m
))
150 if ( ! man_action_post(m
))
159 man_args(struct man
*m
, int line
,
160 int *pos
, char *buf
, char **v
)
166 /* First parse non-quoted strings. */
168 if ('\"' != buf
[*pos
]) {
172 if (' ' == buf
[*pos
])
173 if ('\\' != buf
[*pos
- 1])
186 while (buf
[*pos
] && ' ' == buf
[*pos
])
192 if ( ! man_vwarn(m
, line
, *pos
, "trailing spaces"))
199 * If we're a quoted string (and quoted strings are allowed),
200 * then parse ahead to the next quote. If none's found, it's an
201 * error. After, parse to the next word.
206 while (buf
[*pos
] && '\"' != buf
[*pos
])
209 if (0 == buf
[*pos
]) {
210 if ( ! man_vwarn(m
, line
, *pos
, "unterminated quote"))
219 while (buf
[*pos
] && ' ' == buf
[*pos
])
225 if ( ! man_vwarn(m
, line
, *pos
, "trailing spaces"))