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