Annotation of mandoc/action.c, Revision 1.5
1.5 ! kristaps 1: /* $Id: action.c,v 1.4 2009/01/08 15:05:50 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:
162: assert(MDOC_Sh == mdoc->last->data.head.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);
! 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);
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);
! 226: /* TODO: have 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);
! 239: assert(MDOC_Os == mdoc->last->data.elem.tok);
! 240: assert(0 == mdoc->meta.os[0]);
1.4 kristaps 241:
1.5 ! kristaps 242: sz = META_OS_SZ;
! 243: (void)xstrlcpy(mdoc->meta.os, "LOCAL", sz);
1.4 kristaps 244:
1.5 ! kristaps 245: for (n = mdoc->last->child; n; n = n->next) {
! 246: assert(MDOC_TEXT == n->type);
! 247: p = n->data.text.string;
! 248:
! 249: if ( ! xstrlcat(mdoc->meta.os, p, sz))
! 250: return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
! 251: if ( ! xstrlcat(mdoc->meta.os, " ", sz))
! 252: return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
1.4 kristaps 253: }
1.5 ! kristaps 254:
! 255: mdoc_msg(mdoc, "parsed operating system (entering document body)");
! 256: mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
1.4 kristaps 257: return(1);
258: }
259:
260:
261: static int
262: post_dd(struct mdoc *mdoc)
263: {
1.5 ! kristaps 264: char date[64];
! 265: size_t sz;
! 266: char *p;
! 267: struct mdoc_node *n;
1.4 kristaps 268:
1.5 ! kristaps 269: assert(MDOC_ELEM == mdoc->last->type);
! 270: assert(MDOC_Dd == mdoc->last->data.elem.tok);
! 271:
! 272: n = mdoc->last->child;
! 273: assert(0 == mdoc->meta.date);
1.4 kristaps 274: date[0] = 0;
275:
1.5 ! kristaps 276: sz = 64;
! 277:
! 278: for ( ; 0 == mdoc->meta.date && n; n = n->next) {
! 279: assert(MDOC_TEXT == n->type);
! 280: p = n->data.text.string;
! 281:
! 282: if (xstrcmp(p, "$Mdocdate$")) {
! 283: mdoc->meta.date = time(NULL);
! 284: continue;
! 285: } else if (xstrcmp(p, "$")) {
! 286: mdoc->meta.date = mdoc_atotime(date);
! 287: continue;
! 288: } else if (xstrcmp(p, "$Mdocdate:"))
! 289: continue;
! 290:
! 291: if ( ! xstrlcat(date, n->data.text.string, sz))
! 292: return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
! 293: if ( ! xstrlcat(date, " ", sz))
! 294: return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
! 295: }
! 296:
! 297: if (mdoc->meta.date && NULL == n) {
! 298: mdoc_msg(mdoc, "parsed time: %u since epoch",
! 299: mdoc->meta.date);
! 300: return(1);
1.4 kristaps 301: }
1.5 ! kristaps 302:
! 303: return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
1.4 kristaps 304: }
305:
306:
1.3 kristaps 307: int
1.4 kristaps 308: mdoc_action_pre(struct mdoc *mdoc, struct mdoc_node *node)
309: {
310:
311: return(1);
312: }
313:
314:
315: int
316: mdoc_action_post(struct mdoc *mdoc)
1.3 kristaps 317: {
318: int t;
319:
320: switch (mdoc->last->type) {
321: case (MDOC_BODY):
322: t = mdoc->last->data.body.tok;
323: break;
324: case (MDOC_ELEM):
325: t = mdoc->last->data.elem.tok;
326: break;
327: case (MDOC_BLOCK):
328: t = mdoc->last->data.block.tok;
329: break;
330: case (MDOC_HEAD):
331: t = mdoc->last->data.head.tok;
1.1 kristaps 332: break;
333: default:
1.3 kristaps 334: return(1);
1.1 kristaps 335: }
1.2 kristaps 336:
1.4 kristaps 337: if (NULL == mdoc_actions[t].post)
1.3 kristaps 338: return(1);
339: /* TODO: MDOC_Nm... ? */
1.4 kristaps 340: return((*mdoc_actions[t].post)(mdoc));
1.3 kristaps 341: }
CVSweb