Annotation of mandoc/mdoc_state.c, Revision 1.1
1.1 ! schwarze 1: /* $Id$ */
! 2: /*
! 3: * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
! 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 above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17: #include <sys/types.h>
! 18:
! 19: #include <stdlib.h>
! 20: #include <string.h>
! 21:
! 22: #include "mandoc.h"
! 23: #include "roff.h"
! 24: #include "mdoc.h"
! 25: #include "libmandoc.h"
! 26: #include "libmdoc.h"
! 27:
! 28: #define STATE_ARGS struct roff_man *mdoc, struct roff_node *n
! 29:
! 30: typedef void (*state_handler)(STATE_ARGS);
! 31:
! 32: static void state_bd(STATE_ARGS);
! 33: static void state_dl(STATE_ARGS);
! 34: static void state_sh(STATE_ARGS);
! 35: static void state_sm(STATE_ARGS);
! 36:
! 37: static const state_handler state_handlers[MDOC_MAX] = {
! 38: NULL, /* Ap */
! 39: NULL, /* Dd */
! 40: NULL, /* Dt */
! 41: NULL, /* Os */
! 42: state_sh, /* Sh */
! 43: NULL, /* Ss */
! 44: NULL, /* Pp */
! 45: NULL, /* D1 */
! 46: state_dl, /* Dl */
! 47: state_bd, /* Bd */
! 48: NULL, /* Ed */
! 49: NULL, /* Bl */
! 50: NULL, /* El */
! 51: NULL, /* It */
! 52: NULL, /* Ad */
! 53: NULL, /* An */
! 54: NULL, /* Ar */
! 55: NULL, /* Cd */
! 56: NULL, /* Cm */
! 57: NULL, /* Dv */
! 58: NULL, /* Er */
! 59: NULL, /* Ev */
! 60: NULL, /* Ex */
! 61: NULL, /* Fa */
! 62: NULL, /* Fd */
! 63: NULL, /* Fl */
! 64: NULL, /* Fn */
! 65: NULL, /* Ft */
! 66: NULL, /* Ic */
! 67: NULL, /* In */
! 68: NULL, /* Li */
! 69: NULL, /* Nd */
! 70: NULL, /* Nm */
! 71: NULL, /* Op */
! 72: NULL, /* Ot */
! 73: NULL, /* Pa */
! 74: NULL, /* Rv */
! 75: NULL, /* St */
! 76: NULL, /* Va */
! 77: NULL, /* Vt */
! 78: NULL, /* Xr */
! 79: NULL, /* %A */
! 80: NULL, /* %B */
! 81: NULL, /* %D */
! 82: NULL, /* %I */
! 83: NULL, /* %J */
! 84: NULL, /* %N */
! 85: NULL, /* %O */
! 86: NULL, /* %P */
! 87: NULL, /* %R */
! 88: NULL, /* %T */
! 89: NULL, /* %V */
! 90: NULL, /* Ac */
! 91: NULL, /* Ao */
! 92: NULL, /* Aq */
! 93: NULL, /* At */
! 94: NULL, /* Bc */
! 95: NULL, /* Bf */
! 96: NULL, /* Bo */
! 97: NULL, /* Bq */
! 98: NULL, /* Bsx */
! 99: NULL, /* Bx */
! 100: NULL, /* Db */
! 101: NULL, /* Dc */
! 102: NULL, /* Do */
! 103: NULL, /* Dq */
! 104: NULL, /* Ec */
! 105: NULL, /* Ef */
! 106: NULL, /* Em */
! 107: NULL, /* Eo */
! 108: NULL, /* Fx */
! 109: NULL, /* Ms */
! 110: NULL, /* No */
! 111: NULL, /* Ns */
! 112: NULL, /* Nx */
! 113: NULL, /* Ox */
! 114: NULL, /* Pc */
! 115: NULL, /* Pf */
! 116: NULL, /* Po */
! 117: NULL, /* Pq */
! 118: NULL, /* Qc */
! 119: NULL, /* Ql */
! 120: NULL, /* Qo */
! 121: NULL, /* Qq */
! 122: NULL, /* Re */
! 123: NULL, /* Rs */
! 124: NULL, /* Sc */
! 125: NULL, /* So */
! 126: NULL, /* Sq */
! 127: state_sm, /* Sm */
! 128: NULL, /* Sx */
! 129: NULL, /* Sy */
! 130: NULL, /* Tn */
! 131: NULL, /* Ux */
! 132: NULL, /* Xc */
! 133: NULL, /* Xo */
! 134: NULL, /* Fo */
! 135: NULL, /* Fc */
! 136: NULL, /* Oo */
! 137: NULL, /* Oc */
! 138: NULL, /* Bk */
! 139: NULL, /* Ek */
! 140: NULL, /* Bt */
! 141: NULL, /* Hf */
! 142: NULL, /* Fr */
! 143: NULL, /* Ud */
! 144: NULL, /* Lb */
! 145: NULL, /* Lp */
! 146: NULL, /* Lk */
! 147: NULL, /* Mt */
! 148: NULL, /* Brq */
! 149: NULL, /* Bro */
! 150: NULL, /* Brc */
! 151: NULL, /* %C */
! 152: NULL, /* Es */
! 153: NULL, /* En */
! 154: NULL, /* Dx */
! 155: NULL, /* %Q */
! 156: NULL, /* br */
! 157: NULL, /* sp */
! 158: NULL, /* %U */
! 159: NULL, /* Ta */
! 160: NULL, /* ll */
! 161: };
! 162:
! 163:
! 164: void
! 165: mdoc_state(struct roff_man *mdoc, struct roff_node *n)
! 166: {
! 167: state_handler handler;
! 168:
! 169: if (n->tok == TOKEN_NONE)
! 170: return;
! 171:
! 172: if ( ! (mdoc_macros[n->tok].flags & MDOC_PROLOGUE))
! 173: mdoc->flags |= MDOC_PBODY;
! 174:
! 175: handler = state_handlers[n->tok];
! 176: if (*handler)
! 177: (*handler)(mdoc, n);
! 178: }
! 179:
! 180: void
! 181: mdoc_state_reset(struct roff_man *mdoc)
! 182: {
! 183:
! 184: roff_setreg(mdoc->roff, "nS", 0, '=');
! 185: mdoc->flags = 0;
! 186: }
! 187:
! 188: static void
! 189: state_bd(STATE_ARGS)
! 190: {
! 191: enum mdocargt arg;
! 192:
! 193: if (n->type != ROFFT_HEAD &&
! 194: (n->type != ROFFT_BODY || n->end != ENDBODY_NOT))
! 195: return;
! 196:
! 197: arg = n->parent->args->argv[0].arg;
! 198: if (arg != MDOC_Literal && arg != MDOC_Unfilled)
! 199: return;
! 200:
! 201: state_dl(mdoc, n);
! 202: }
! 203:
! 204: static void
! 205: state_dl(STATE_ARGS)
! 206: {
! 207:
! 208: switch (n->type) {
! 209: case ROFFT_HEAD:
! 210: mdoc->flags |= MDOC_LITERAL;
! 211: break;
! 212: case ROFFT_BODY:
! 213: mdoc->flags &= ~MDOC_LITERAL;
! 214: break;
! 215: default:
! 216: break;
! 217: }
! 218: }
! 219:
! 220: static void
! 221: state_sh(STATE_ARGS)
! 222: {
! 223: struct roff_node *nch;
! 224: char *secname;
! 225:
! 226: if (n->type != ROFFT_HEAD)
! 227: return;
! 228:
! 229: if ( ! (n->flags & MDOC_VALID)) {
! 230: secname = NULL;
! 231: deroff(&secname, n);
! 232:
! 233: /*
! 234: * Set the section attribute for the BLOCK, HEAD,
! 235: * and HEAD children; the latter can only be TEXT
! 236: * nodes, so no recursion is needed. For other
! 237: * nodes, including the .Sh BODY, this is done
! 238: * when allocating the node data structures, but
! 239: * for .Sh BLOCK and HEAD, the section is still
! 240: * unknown at that time.
! 241: */
! 242:
! 243: n->sec = n->parent->sec = secname == NULL ?
! 244: SEC_CUSTOM : mdoc_a2sec(secname);
! 245: for (nch = n->child; nch != NULL; nch = nch->next)
! 246: nch->sec = n->sec;
! 247: free(secname);
! 248: }
! 249:
! 250: if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
! 251: roff_setreg(mdoc->roff, "nS", 1, '=');
! 252: mdoc->flags |= MDOC_SYNOPSIS;
! 253: } else {
! 254: roff_setreg(mdoc->roff, "nS", 0, '=');
! 255: mdoc->flags &= ~MDOC_SYNOPSIS;
! 256: }
! 257: }
! 258:
! 259: static void
! 260: state_sm(STATE_ARGS)
! 261: {
! 262:
! 263: if (n->child == NULL)
! 264: mdoc->flags ^= MDOC_SMOFF;
! 265: else if ( ! strcmp(n->child->string, "on"))
! 266: mdoc->flags &= ~MDOC_SMOFF;
! 267: else if ( ! strcmp(n->child->string, "off"))
! 268: mdoc->flags |= MDOC_SMOFF;
! 269: }
CVSweb