]>
git.cameronkatri.com Git - mandoc.git/blob - action.c
1 /* $Id: action.c,v 1.12 2009/01/19 17:02:58 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.
27 int (*post
)(struct mdoc
*);
30 /* Per-macro action routines. */
32 static int post_sh(struct mdoc
*);
33 static int post_os(struct mdoc
*);
34 static int post_dt(struct mdoc
*);
35 static int post_dd(struct mdoc
*);
36 static int post_nm(struct mdoc
*);
38 /* Array of macro action routines. */
40 const struct actions mdoc_actions
[MDOC_MAX
] = {
151 post_nm(struct mdoc
*mdoc
)
155 assert(MDOC_ELEM
== mdoc
->last
->type
);
156 assert(MDOC_Nm
== mdoc
->last
->tok
);
161 if (xstrlcats(buf
, mdoc
->last
->child
, 64)) {
162 mdoc
->meta
.name
= xstrdup(buf
);
166 return(mdoc_err(mdoc
, "macro parameters too long"));
171 post_sh(struct mdoc
*mdoc
)
176 if (MDOC_HEAD
!= mdoc
->last
->type
)
178 if (xstrlcats(buf
, mdoc
->last
->child
, 64)) {
179 if (SEC_CUSTOM
!= (sec
= mdoc_atosec(buf
)))
180 mdoc
->sec_lastn
= sec
;
181 mdoc
->sec_last
= sec
;
185 return(mdoc_err(mdoc
, "macro parameters too long"));
190 post_dt(struct mdoc
*mdoc
)
196 assert(MDOC_ELEM
== mdoc
->last
->type
);
197 assert(MDOC_Dt
== mdoc
->last
->tok
);
199 assert(NULL
== mdoc
->meta
.title
);
201 for (i
= 0, n
= mdoc
->last
->child
; n
; n
= n
->next
, i
++) {
202 assert(MDOC_TEXT
== n
->type
);
203 p
= n
->data
.text
.string
;
207 mdoc
->meta
.title
= xstrdup(p
);
210 mdoc
->meta
.msec
= mdoc_atomsec(p
);
211 if (MSEC_DEFAULT
!= mdoc
->meta
.msec
)
213 return(mdoc_nerr(mdoc
, n
, "invalid parameter syntax"));
215 mdoc
->meta
.vol
= mdoc_atovol(p
);
216 if (VOL_DEFAULT
!= mdoc
->meta
.vol
)
218 mdoc
->meta
.arch
= mdoc_atoarch(p
);
219 if (ARCH_DEFAULT
!= mdoc
->meta
.arch
)
221 return(mdoc_nerr(mdoc
, n
, "invalid parameter syntax"));
223 return(mdoc_nerr(mdoc
, n
, "too many parameters"));
227 if (NULL
== mdoc
->meta
.title
)
228 mdoc
->meta
.title
= xstrdup("untitled");
234 post_os(struct mdoc
*mdoc
)
238 assert(MDOC_ELEM
== mdoc
->last
->type
);
239 assert(MDOC_Os
== mdoc
->last
->tok
);
240 assert(NULL
== mdoc
->meta
.os
);
242 if ( ! xstrlcats(buf
, mdoc
->last
->child
, 64))
243 return(mdoc_err(mdoc
, "macro parameters too long"));
245 mdoc
->meta
.os
= xstrdup(buf
[0] ? buf
: "local");
246 mdoc
->sec_lastn
= mdoc
->sec_last
= SEC_BODY
;
252 post_dd(struct mdoc
*mdoc
)
259 assert(MDOC_ELEM
== mdoc
->last
->type
);
260 assert(MDOC_Dd
== mdoc
->last
->tok
);
262 n
= mdoc
->last
->child
;
263 assert(0 == mdoc
->meta
.date
);
268 for ( ; 0 == mdoc
->meta
.date
&& n
; n
= n
->next
) {
269 assert(MDOC_TEXT
== n
->type
);
270 p
= n
->data
.text
.string
;
272 if (xstrcmp(p
, "$Mdocdate: January 19 2009 $")) {
273 mdoc
->meta
.date
= time(NULL
);
275 } else if (xstrcmp(p
, "$")) {
276 mdoc
->meta
.date
= mdoc_atotime(date
);
278 } else if (xstrcmp(p
, "$Mdocdate:"))
281 if ( ! xstrlcat(date
, n
->data
.text
.string
, sz
))
282 return(mdoc_nerr(mdoc
, n
, "invalid parameter syntax"));
283 if (n
->next
&& ! xstrlcat(date
, " ", sz
))
284 return(mdoc_nerr(mdoc
, n
, "invalid parameter syntax"));
287 if (mdoc
->meta
.date
&& NULL
== n
)
290 return(mdoc_err(mdoc
, "invalid parameter syntax"));
291 if ((mdoc
->meta
.date
= mdoc_atotime(date
)))
293 return(mdoc_err(mdoc
, "invalid parameter syntax"));
298 mdoc_action_post(struct mdoc
*mdoc
)
301 if (MDOC_ACTED
& mdoc
->last
->flags
)
303 mdoc
->last
->flags
|= MDOC_ACTED
;
305 if (MDOC_TEXT
== mdoc
->last
->type
)
307 if (MDOC_ROOT
== mdoc
->last
->type
)
309 if (NULL
== mdoc_actions
[mdoc
->last
->tok
].post
)
311 return((*mdoc_actions
[mdoc
->last
->tok
].post
)(mdoc
));