]> git.cameronkatri.com Git - mandoc.git/blob - action.c
*** empty log message ***
[mandoc.git] / action.c
1 /* $Id: action.c,v 1.6 2009/01/09 14:45:44 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
4 *
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
8 * copies.
9 *
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.
18 */
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <time.h>
22
23 #include "private.h"
24
25 typedef int (*a_pre)(struct mdoc *, struct mdoc_node *);
26 typedef int (*a_post)(struct mdoc *);
27
28
29 struct actions {
30 a_pre pre;
31 a_post post;
32 };
33
34
35 static int post_sh(struct mdoc *);
36 static int post_os(struct mdoc *);
37 static int post_dt(struct mdoc *);
38 static int post_dd(struct mdoc *);
39
40
41 const struct actions mdoc_actions[MDOC_MAX] = {
42 { NULL, NULL }, /* \" */
43 { NULL, post_dd }, /* Dd */
44 { NULL, post_dt }, /* Dt */
45 { NULL, post_os }, /* Os */
46 { NULL, post_sh }, /* Sh */
47 { NULL, NULL }, /* Ss */
48 { NULL, NULL }, /* Pp */
49 { NULL, NULL }, /* D1 */
50 { NULL, NULL }, /* Dl */
51 { NULL, NULL }, /* Bd */
52 { NULL, NULL }, /* Ed */
53 { NULL, NULL }, /* Bl */
54 { NULL, NULL }, /* El */
55 { NULL, NULL }, /* It */
56 { NULL, NULL }, /* Ad */
57 { NULL, NULL }, /* An */
58 { NULL, NULL }, /* Ar */
59 { NULL, NULL }, /* Cd */
60 { NULL, NULL }, /* Cm */
61 { NULL, NULL }, /* Dv */
62 { NULL, NULL }, /* Er */
63 { NULL, NULL }, /* Ev */
64 { NULL, NULL }, /* Ex */
65 { NULL, NULL }, /* Fa */
66 { NULL, NULL }, /* Fd */
67 { NULL, NULL }, /* Fl */
68 { NULL, NULL }, /* Fn */
69 { NULL, NULL }, /* Ft */
70 { NULL, NULL }, /* Ic */
71 { NULL, NULL }, /* In */
72 { NULL, NULL }, /* Li */
73 { NULL, NULL }, /* Nd */
74 { NULL, NULL }, /* Nm */
75 { NULL, NULL }, /* Op */
76 { NULL, NULL }, /* Ot */
77 { NULL, NULL }, /* Pa */
78 { NULL, NULL }, /* Rv */
79 { NULL, NULL }, /* St */
80 { NULL, NULL }, /* Va */
81 { NULL, NULL }, /* Vt */
82 { NULL, NULL }, /* Xr */
83 { NULL, NULL }, /* %A */
84 { NULL, NULL }, /* %B */
85 { NULL, NULL }, /* %D */
86 { NULL, NULL }, /* %I */
87 { NULL, NULL }, /* %J */
88 { NULL, NULL }, /* %N */
89 { NULL, NULL }, /* %O */
90 { NULL, NULL }, /* %P */
91 { NULL, NULL }, /* %R */
92 { NULL, NULL }, /* %T */
93 { NULL, NULL }, /* %V */
94 { NULL, NULL }, /* Ac */
95 { NULL, NULL }, /* Ao */
96 { NULL, NULL }, /* Aq */
97 { NULL, NULL }, /* At */
98 { NULL, NULL }, /* Bc */
99 { NULL, NULL }, /* Bf */
100 { NULL, NULL }, /* Bo */
101 { NULL, NULL }, /* Bq */
102 { NULL, NULL }, /* Bsx */
103 { NULL, NULL }, /* Bx */
104 { NULL, NULL }, /* Db */
105 { NULL, NULL }, /* Dc */
106 { NULL, NULL }, /* Do */
107 { NULL, NULL }, /* Dq */
108 { NULL, NULL }, /* Ec */
109 { NULL, NULL }, /* Ef */
110 { NULL, NULL }, /* Em */
111 { NULL, NULL }, /* Eo */
112 { NULL, NULL }, /* Fx */
113 { NULL, NULL }, /* Ms */
114 { NULL, NULL }, /* No */
115 { NULL, NULL }, /* Ns */
116 { NULL, NULL }, /* Nx */
117 { NULL, NULL }, /* Ox */
118 { NULL, NULL }, /* Pc */
119 { NULL, NULL }, /* Pf */
120 { NULL, NULL }, /* Po */
121 { NULL, NULL }, /* Pq */
122 { NULL, NULL }, /* Qc */
123 { NULL, NULL }, /* Ql */
124 { NULL, NULL }, /* Qo */
125 { NULL, NULL }, /* Qq */
126 { NULL, NULL }, /* Re */
127 { NULL, NULL }, /* Rs */
128 { NULL, NULL }, /* Sc */
129 { NULL, NULL }, /* So */
130 { NULL, NULL }, /* Sq */
131 { NULL, NULL }, /* Sm */
132 { NULL, NULL }, /* Sx */
133 { NULL, NULL }, /* Sy */
134 { NULL, NULL }, /* Tn */
135 { NULL, NULL }, /* Ux */
136 { NULL, NULL }, /* Xc */
137 { NULL, NULL }, /* Xo */
138 { NULL, NULL }, /* Fo */
139 { NULL, NULL }, /* Fc */
140 { NULL, NULL }, /* Oo */
141 { NULL, NULL }, /* Oc */
142 { NULL, NULL }, /* Bk */
143 { NULL, NULL }, /* Ek */
144 { NULL, NULL }, /* Bt */
145 { NULL, NULL }, /* Hf */
146 { NULL, NULL }, /* Fr */
147 { NULL, NULL }, /* Ud */
148 };
149
150
151 static int
152 post_sh(struct mdoc *mdoc)
153 {
154 enum mdoc_sec sec;
155 int i;
156 struct mdoc_node *n;
157 char *args[MDOC_LINEARG_MAX];
158
159 if (MDOC_HEAD != mdoc->last->type)
160 return(1);
161
162 assert(MDOC_Sh == mdoc->last->data.head.tok);
163
164 n = mdoc->last->child;
165 assert(n);
166
167 for (i = 0; n && i < MDOC_LINEARG_MAX; n = n->next, i++) {
168 assert(MDOC_TEXT == n->type);
169 assert(NULL == n->child);
170 assert(n->data.text.string);
171 args[i] = n->data.text.string;
172 }
173
174 sec = mdoc_atosec((size_t)i, (const char **)args);
175 if (SEC_CUSTOM != sec)
176 mdoc->sec_lastn = sec;
177 mdoc->sec_last = sec;
178
179 return(1);
180 }
181
182
183 static int
184 post_dt(struct mdoc *mdoc)
185 {
186 int i;
187 char *p;
188 size_t sz;
189 struct mdoc_node *n;
190
191 assert(MDOC_ELEM == mdoc->last->type);
192 assert(MDOC_Dt == mdoc->last->data.elem.tok);
193 assert(0 == mdoc->meta.title[0]);
194
195 sz = META_TITLE_SZ;
196 (void)xstrlcpy(mdoc->meta.title, "UNTITLED", sz);
197
198 for (i = 0, n = mdoc->last->child; n; n = n->next, i++) {
199 assert(MDOC_TEXT == n->type);
200 p = n->data.text.string;
201
202 switch (i) {
203 case (0):
204 if (xstrlcpy(mdoc->meta.title, p, sz))
205 break;
206 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
207 case (1):
208 mdoc->meta.msec = mdoc_atomsec(p);
209 if (MSEC_DEFAULT != mdoc->meta.msec)
210 break;
211 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
212 case (2):
213 mdoc->meta.vol = mdoc_atovol(p);
214 if (VOL_DEFAULT != mdoc->meta.vol)
215 break;
216 mdoc->meta.arch = mdoc_atoarch(p);
217 if (ARCH_DEFAULT != mdoc->meta.arch)
218 break;
219 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
220 default:
221 return(mdoc_err(mdoc, ERR_ARGS_MANY));
222 }
223 }
224
225 mdoc_msg(mdoc, "parsed title: %s", mdoc->meta.title);
226 /* TODO: print vol2a functions. */
227 return(1);
228 }
229
230
231 static int
232 post_os(struct mdoc *mdoc)
233 {
234 char *p;
235 size_t sz;
236 struct mdoc_node *n;
237
238 assert(MDOC_ELEM == mdoc->last->type);
239 assert(MDOC_Os == mdoc->last->data.elem.tok);
240 assert(0 == mdoc->meta.os[0]);
241
242 sz = META_OS_SZ;
243
244 for (n = mdoc->last->child; n; n = n->next) {
245 assert(MDOC_TEXT == n->type);
246 p = n->data.text.string;
247
248 if ( ! xstrlcat(mdoc->meta.os, p, sz))
249 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
250 if ( ! xstrlcat(mdoc->meta.os, " ", sz))
251 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
252 }
253
254 if (0 == mdoc->meta.os[0])
255 (void)xstrlcpy(mdoc->meta.os, "LOCAL", sz);
256
257 mdoc_msg(mdoc, "parsed operating system: %s", mdoc->meta.os);
258 mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
259 return(1);
260 }
261
262
263 static int
264 post_dd(struct mdoc *mdoc)
265 {
266 char date[64];
267 size_t sz;
268 char *p;
269 struct mdoc_node *n;
270
271 assert(MDOC_ELEM == mdoc->last->type);
272 assert(MDOC_Dd == mdoc->last->data.elem.tok);
273
274 n = mdoc->last->child;
275 assert(0 == mdoc->meta.date);
276 date[0] = 0;
277
278 sz = 64;
279
280 for ( ; 0 == mdoc->meta.date && n; n = n->next) {
281 assert(MDOC_TEXT == n->type);
282 p = n->data.text.string;
283
284 if (xstrcmp(p, "$Mdocdate: January 9 2009 $")) {
285 mdoc->meta.date = time(NULL);
286 continue;
287 } else if (xstrcmp(p, "$")) {
288 mdoc->meta.date = mdoc_atotime(date);
289 continue;
290 } else if (xstrcmp(p, "$Mdocdate:"))
291 continue;
292
293 if ( ! xstrlcat(date, n->data.text.string, sz))
294 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
295 if ( ! xstrlcat(date, " ", sz))
296 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
297 }
298
299 if (mdoc->meta.date && NULL == n) {
300 mdoc_msg(mdoc, "parsed time: %u since epoch",
301 mdoc->meta.date);
302 return(1);
303 }
304
305 return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
306 }
307
308
309 int
310 mdoc_action_pre(struct mdoc *mdoc, struct mdoc_node *node)
311 {
312
313 return(1);
314 }
315
316
317 int
318 mdoc_action_post(struct mdoc *mdoc)
319 {
320 int t;
321
322 switch (mdoc->last->type) {
323 case (MDOC_BODY):
324 t = mdoc->last->data.body.tok;
325 break;
326 case (MDOC_ELEM):
327 t = mdoc->last->data.elem.tok;
328 break;
329 case (MDOC_BLOCK):
330 t = mdoc->last->data.block.tok;
331 break;
332 case (MDOC_HEAD):
333 t = mdoc->last->data.head.tok;
334 break;
335 default:
336 return(1);
337 }
338
339 if (NULL == mdoc_actions[t].post)
340 return(1);
341 /* TODO: MDOC_Nm... ? */
342 return((*mdoc_actions[t].post)(mdoc));
343 }