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