Annotation of mandoc/action.c, Revision 1.7
1.7 ! kristaps 1: /* $Id: action.c,v 1.6 2009/01/09 14:45:44 kristaps Exp $ */
1.1 kristaps 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>
1.5 kristaps 21: #include <time.h>
1.1 kristaps 22:
23: #include "private.h"
24:
1.4 kristaps 25: typedef int (*a_pre)(struct mdoc *, struct mdoc_node *);
26: typedef int (*a_post)(struct mdoc *);
1.1 kristaps 27:
28:
29: struct actions {
1.4 kristaps 30: a_pre pre;
31: a_post post;
1.1 kristaps 32: };
33:
34:
1.4 kristaps 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 *);
1.3 kristaps 39:
40:
1.1 kristaps 41: const struct actions mdoc_actions[MDOC_MAX] = {
1.4 kristaps 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 */
1.1 kristaps 148: };
149:
150:
1.3 kristaps 151: static int
1.4 kristaps 152: post_sh(struct mdoc *mdoc)
1.1 kristaps 153: {
1.3 kristaps 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);
1.4 kristaps 161:
1.7 ! kristaps 162: assert(MDOC_Sh == mdoc->last->tok);
1.3 kristaps 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;
1.1 kristaps 178:
179: return(1);
180: }
181:
1.3 kristaps 182:
1.4 kristaps 183: static int
184: post_dt(struct mdoc *mdoc)
185: {
1.5 kristaps 186: int i;
187: char *p;
188: size_t sz;
189: struct mdoc_node *n;
190:
191: assert(MDOC_ELEM == mdoc->last->type);
1.7 ! kristaps 192: assert(MDOC_Dt == mdoc->last->tok);
1.5 kristaps 193: assert(0 == mdoc->meta.title[0]);
194:
195: sz = META_TITLE_SZ;
196: (void)xstrlcpy(mdoc->meta.title, "UNTITLED", sz);
1.4 kristaps 197:
1.5 kristaps 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;
1.4 kristaps 201:
1.5 kristaps 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: }
1.4 kristaps 223: }
224:
1.5 kristaps 225: mdoc_msg(mdoc, "parsed title: %s", mdoc->meta.title);
1.6 kristaps 226: /* TODO: print vol2a functions. */
1.4 kristaps 227: return(1);
228: }
229:
230:
231: static int
232: post_os(struct mdoc *mdoc)
233: {
1.5 kristaps 234: char *p;
235: size_t sz;
236: struct mdoc_node *n;
237:
238: assert(MDOC_ELEM == mdoc->last->type);
1.7 ! kristaps 239: assert(MDOC_Os == mdoc->last->tok);
1.5 kristaps 240: assert(0 == mdoc->meta.os[0]);
1.4 kristaps 241:
1.5 kristaps 242: sz = META_OS_SZ;
1.4 kristaps 243:
1.5 kristaps 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));
1.4 kristaps 252: }
1.5 kristaps 253:
1.6 kristaps 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);
1.5 kristaps 258: mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
1.4 kristaps 259: return(1);
260: }
261:
262:
263: static int
264: post_dd(struct mdoc *mdoc)
265: {
1.5 kristaps 266: char date[64];
267: size_t sz;
268: char *p;
269: struct mdoc_node *n;
1.4 kristaps 270:
1.5 kristaps 271: assert(MDOC_ELEM == mdoc->last->type);
1.7 ! kristaps 272: assert(MDOC_Dd == mdoc->last->tok);
1.5 kristaps 273:
274: n = mdoc->last->child;
275: assert(0 == mdoc->meta.date);
1.4 kristaps 276: date[0] = 0;
277:
1.5 kristaps 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$")) {
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);
1.4 kristaps 303: }
1.5 kristaps 304:
305: return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
1.4 kristaps 306: }
307:
308:
1.3 kristaps 309: int
1.4 kristaps 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)
1.3 kristaps 319: {
320:
1.7 ! kristaps 321: if (MDOC_TEXT == mdoc->last->type)
! 322: return(1);
! 323: if (MDOC_ROOT == mdoc->last->type)
1.3 kristaps 324: return(1);
1.2 kristaps 325:
1.7 ! kristaps 326: if (NULL == mdoc_actions[mdoc->last->tok].post)
1.3 kristaps 327: return(1);
328: /* TODO: MDOC_Nm... ? */
1.7 ! kristaps 329: return((*mdoc_actions[mdoc->last->tok].post)(mdoc));
1.3 kristaps 330: }
CVSweb