]> git.cameronkatri.com Git - mandoc.git/blob - action.c
Removed unnecessary test cases (most were for visual).
[mandoc.git] / action.c
1 /* $Id: action.c,v 1.12 2009/01/19 17:02:58 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
26 struct actions {
27 int (*post)(struct mdoc *);
28 };
29
30 /* Per-macro action routines. */
31
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 *);
37
38 /* Array of macro action routines. */
39
40 const struct actions mdoc_actions[MDOC_MAX] = {
41 { NULL }, /* \" */
42 { post_dd }, /* Dd */
43 { post_dt }, /* Dt */
44 { post_os }, /* Os */
45 { post_sh }, /* Sh */
46 { NULL }, /* Ss */
47 { NULL }, /* Pp */
48 { NULL }, /* D1 */
49 { NULL }, /* Dl */
50 { NULL }, /* Bd */
51 { NULL }, /* Ed */
52 { NULL }, /* Bl */
53 { NULL }, /* El */
54 { NULL }, /* It */
55 { NULL }, /* Ad */
56 { NULL }, /* An */
57 { NULL }, /* Ar */
58 { NULL }, /* Cd */
59 { NULL }, /* Cm */
60 { NULL }, /* Dv */
61 { NULL }, /* Er */
62 { NULL }, /* Ev */
63 { NULL }, /* Ex */
64 { NULL }, /* Fa */
65 { NULL }, /* Fd */
66 { NULL }, /* Fl */
67 { NULL }, /* Fn */
68 { NULL }, /* Ft */
69 { NULL }, /* Ic */
70 { NULL }, /* In */
71 { NULL }, /* Li */
72 { NULL }, /* Nd */
73 { post_nm }, /* Nm */
74 { NULL }, /* Op */
75 { NULL }, /* Ot */
76 { NULL }, /* Pa */
77 { NULL }, /* Rv */
78 { NULL }, /* St */
79 { NULL }, /* Va */
80 { NULL }, /* Vt */
81 { NULL }, /* Xr */
82 { NULL }, /* %A */
83 { NULL }, /* %B */
84 { NULL }, /* %D */
85 { NULL }, /* %I */
86 { NULL }, /* %J */
87 { NULL }, /* %N */
88 { NULL }, /* %O */
89 { NULL }, /* %P */
90 { NULL }, /* %R */
91 { NULL }, /* %T */
92 { NULL }, /* %V */
93 { NULL }, /* Ac */
94 { NULL }, /* Ao */
95 { NULL }, /* Aq */
96 { NULL }, /* At */
97 { NULL }, /* Bc */
98 { NULL }, /* Bf */
99 { NULL }, /* Bo */
100 { NULL }, /* Bq */
101 { NULL }, /* Bsx */
102 { NULL }, /* Bx */
103 { NULL }, /* Db */
104 { NULL }, /* Dc */
105 { NULL }, /* Do */
106 { NULL }, /* Dq */
107 { NULL }, /* Ec */
108 { NULL }, /* Ef */
109 { NULL }, /* Em */
110 { NULL }, /* Eo */
111 { NULL }, /* Fx */
112 { NULL }, /* Ms */
113 { NULL }, /* No */
114 { NULL }, /* Ns */
115 { NULL }, /* Nx */
116 { NULL }, /* Ox */
117 { NULL }, /* Pc */
118 { NULL }, /* Pf */
119 { NULL }, /* Po */
120 { NULL }, /* Pq */
121 { NULL }, /* Qc */
122 { NULL }, /* Ql */
123 { NULL }, /* Qo */
124 { NULL }, /* Qq */
125 { NULL }, /* Re */
126 { NULL }, /* Rs */
127 { NULL }, /* Sc */
128 { NULL }, /* So */
129 { NULL }, /* Sq */
130 { NULL }, /* Sm */
131 { NULL }, /* Sx */
132 { NULL }, /* Sy */
133 { NULL }, /* Tn */
134 { NULL }, /* Ux */
135 { NULL }, /* Xc */
136 { NULL }, /* Xo */
137 { NULL }, /* Fo */
138 { NULL }, /* Fc */
139 { NULL }, /* Oo */
140 { NULL }, /* Oc */
141 { NULL }, /* Bk */
142 { NULL }, /* Ek */
143 { NULL }, /* Bt */
144 { NULL }, /* Hf */
145 { NULL }, /* Fr */
146 { NULL }, /* Ud */
147 };
148
149
150 static int
151 post_nm(struct mdoc *mdoc)
152 {
153 char buf[64];
154
155 assert(MDOC_ELEM == mdoc->last->type);
156 assert(MDOC_Nm == mdoc->last->tok);
157
158 if (mdoc->meta.name)
159 return(1);
160
161 if (xstrlcats(buf, mdoc->last->child, 64)) {
162 mdoc->meta.name = xstrdup(buf);
163 return(1);
164 }
165
166 return(mdoc_err(mdoc, "macro parameters too long"));
167 }
168
169
170 static int
171 post_sh(struct mdoc *mdoc)
172 {
173 enum mdoc_sec sec;
174 char buf[64];
175
176 if (MDOC_HEAD != mdoc->last->type)
177 return(1);
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;
182 return(1);
183 }
184
185 return(mdoc_err(mdoc, "macro parameters too long"));
186 }
187
188
189 static int
190 post_dt(struct mdoc *mdoc)
191 {
192 int i;
193 char *p;
194 struct mdoc_node *n;
195
196 assert(MDOC_ELEM == mdoc->last->type);
197 assert(MDOC_Dt == mdoc->last->tok);
198
199 assert(NULL == mdoc->meta.title);
200
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;
204
205 switch (i) {
206 case (0):
207 mdoc->meta.title = xstrdup(p);
208 break;
209 case (1):
210 mdoc->meta.msec = mdoc_atomsec(p);
211 if (MSEC_DEFAULT != mdoc->meta.msec)
212 break;
213 return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
214 case (2):
215 mdoc->meta.vol = mdoc_atovol(p);
216 if (VOL_DEFAULT != mdoc->meta.vol)
217 break;
218 mdoc->meta.arch = mdoc_atoarch(p);
219 if (ARCH_DEFAULT != mdoc->meta.arch)
220 break;
221 return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
222 default:
223 return(mdoc_nerr(mdoc, n, "too many parameters"));
224 }
225 }
226
227 if (NULL == mdoc->meta.title)
228 mdoc->meta.title = xstrdup("untitled");
229 return(1);
230 }
231
232
233 static int
234 post_os(struct mdoc *mdoc)
235 {
236 char buf[64];
237
238 assert(MDOC_ELEM == mdoc->last->type);
239 assert(MDOC_Os == mdoc->last->tok);
240 assert(NULL == mdoc->meta.os);
241
242 if ( ! xstrlcats(buf, mdoc->last->child, 64))
243 return(mdoc_err(mdoc, "macro parameters too long"));
244
245 mdoc->meta.os = xstrdup(buf[0] ? buf : "local");
246 mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
247 return(1);
248 }
249
250
251 static int
252 post_dd(struct mdoc *mdoc)
253 {
254 char date[64];
255 size_t sz;
256 char *p;
257 struct mdoc_node *n;
258
259 assert(MDOC_ELEM == mdoc->last->type);
260 assert(MDOC_Dd == mdoc->last->tok);
261
262 n = mdoc->last->child;
263 assert(0 == mdoc->meta.date);
264 date[0] = 0;
265
266 sz = 64;
267
268 for ( ; 0 == mdoc->meta.date && n; n = n->next) {
269 assert(MDOC_TEXT == n->type);
270 p = n->data.text.string;
271
272 if (xstrcmp(p, "$Mdocdate: January 19 2009 $")) {
273 mdoc->meta.date = time(NULL);
274 continue;
275 } else if (xstrcmp(p, "$")) {
276 mdoc->meta.date = mdoc_atotime(date);
277 continue;
278 } else if (xstrcmp(p, "$Mdocdate:"))
279 continue;
280
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"));
285 }
286
287 if (mdoc->meta.date && NULL == n)
288 return(1);
289 else if (n)
290 return(mdoc_err(mdoc, "invalid parameter syntax"));
291 if ((mdoc->meta.date = mdoc_atotime(date)))
292 return(1);
293 return(mdoc_err(mdoc, "invalid parameter syntax"));
294 }
295
296
297 int
298 mdoc_action_post(struct mdoc *mdoc)
299 {
300
301 if (MDOC_ACTED & mdoc->last->flags)
302 return(1);
303 mdoc->last->flags |= MDOC_ACTED;
304
305 if (MDOC_TEXT == mdoc->last->type)
306 return(1);
307 if (MDOC_ROOT == mdoc->last->type)
308 return(1);
309 if (NULL == mdoc_actions[mdoc->last->tok].post)
310 return(1);
311 return((*mdoc_actions[mdoc->last->tok].post)(mdoc));
312 }