Annotation of src/usr.bin/mandoc/man_action.c, Revision 1.1
1.1 ! kristaps 1: /* $Id: man_action.c,v 1.9 2009/04/05 16:34:22 kristaps Exp $ */
! 2: /*
! 3: * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@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
! 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 <sys/utsname.h>
! 20:
! 21: #include <assert.h>
! 22: #include <errno.h>
! 23: #include <stdlib.h>
! 24: #include <string.h>
! 25:
! 26: #include "libman.h"
! 27:
! 28: struct actions {
! 29: int (*post)(struct man *);
! 30: };
! 31:
! 32:
! 33: static int post_TH(struct man *);
! 34: static time_t man_atotime(const char *);
! 35:
! 36: const struct actions man_actions[MAN_MAX] = {
! 37: { NULL }, /* __ */
! 38: { post_TH }, /* TH */
! 39: { NULL }, /* SH */
! 40: { NULL }, /* SS */
! 41: { NULL }, /* TP */
! 42: { NULL }, /* LP */
! 43: { NULL }, /* PP */
! 44: { NULL }, /* P */
! 45: { NULL }, /* IP */
! 46: { NULL }, /* HP */
! 47: { NULL }, /* SM */
! 48: { NULL }, /* SB */
! 49: { NULL }, /* BI */
! 50: { NULL }, /* IB */
! 51: { NULL }, /* BR */
! 52: { NULL }, /* RB */
! 53: { NULL }, /* R */
! 54: { NULL }, /* B */
! 55: { NULL }, /* I */
! 56: { NULL }, /* IR */
! 57: { NULL }, /* RI */
! 58: { NULL }, /* br */
! 59: { NULL }, /* na */
! 60: { NULL }, /* i */
! 61: };
! 62:
! 63:
! 64: int
! 65: man_action_post(struct man *m)
! 66: {
! 67:
! 68: if (MAN_ACTED & m->last->flags)
! 69: return(1);
! 70: m->last->flags |= MAN_ACTED;
! 71:
! 72: switch (m->last->type) {
! 73: case (MAN_TEXT):
! 74: break;
! 75: case (MAN_ROOT):
! 76: break;
! 77: default:
! 78: if (NULL == man_actions[m->last->tok].post)
! 79: break;
! 80: return((*man_actions[m->last->tok].post)(m));
! 81: }
! 82: return(1);
! 83: }
! 84:
! 85:
! 86: static int
! 87: post_TH(struct man *m)
! 88: {
! 89: struct man_node *n;
! 90: char *ep;
! 91: long lval;
! 92:
! 93: if (m->meta.title)
! 94: free(m->meta.title);
! 95: if (m->meta.vol)
! 96: free(m->meta.vol);
! 97: if (m->meta.source)
! 98: free(m->meta.source);
! 99:
! 100: m->meta.title = m->meta.vol = m->meta.source = NULL;
! 101: m->meta.msec = 0;
! 102: m->meta.date = 0;
! 103:
! 104: /* ->TITLE<- MSEC DATE SOURCE VOL */
! 105:
! 106: n = m->last->child;
! 107: assert(n);
! 108:
! 109: if (NULL == (m->meta.title = strdup(n->string)))
! 110: return(man_verr(m, n->line, n->pos,
! 111: "memory exhausted"));
! 112:
! 113: /* TITLE ->MSEC<- DATE SOURCE VOL */
! 114:
! 115: n = n->next;
! 116: assert(n);
! 117:
! 118: errno = 0;
! 119: lval = strtol(n->string, &ep, 10);
! 120: if (n->string[0] != '\0' && *ep == '\0')
! 121: m->meta.msec = (int)lval;
! 122: else if ( ! man_vwarn(m, n->line, n->pos, "invalid section"))
! 123: return(0);
! 124:
! 125: /* TITLE MSEC ->DATE<- SOURCE VOL */
! 126:
! 127: if (NULL == (n = n->next))
! 128: m->meta.date = time(NULL);
! 129: else if (0 == (m->meta.date = man_atotime(n->string))) {
! 130: if ( ! man_vwarn(m, n->line, n->pos, "invalid date"))
! 131: return(0);
! 132: m->meta.date = time(NULL);
! 133: }
! 134:
! 135: /* TITLE MSEC DATE ->SOURCE<- VOL */
! 136:
! 137: if (n && (n = n->next))
! 138: if (NULL == (m->meta.source = strdup(n->string)))
! 139: return(man_verr(m, n->line, n->pos,
! 140: "memory exhausted"));
! 141:
! 142: /* TITLE MSEC DATE SOURCE ->VOL<- */
! 143:
! 144: if (n && (n = n->next))
! 145: if (NULL == (m->meta.vol = strdup(n->string)))
! 146: return(man_verr(m, n->line, n->pos,
! 147: "memory exhausted"));
! 148:
! 149: /*
! 150: * The end document shouldn't have the prologue macros as part
! 151: * of the syntax tree (they encompass only meta-data).
! 152: */
! 153:
! 154: if (m->last->parent->child == m->last) {
! 155: assert(MAN_ROOT == m->last->parent->type);
! 156: m->last->parent->child = NULL;
! 157: n = m->last;
! 158: m->last = m->last->parent;
! 159: m->next = MAN_NEXT_CHILD;
! 160: assert(m->last == m->first);
! 161: } else {
! 162: assert(m->last->prev);
! 163: m->last->prev->next = NULL;
! 164: n = m->last;
! 165: m->last = m->last->prev;
! 166: m->next = MAN_NEXT_SIBLING;
! 167: }
! 168:
! 169: man_node_freelist(n);
! 170: return(1);
! 171: }
! 172:
! 173:
! 174: static time_t
! 175: man_atotime(const char *p)
! 176: {
! 177: struct tm tm;
! 178: char *pp;
! 179:
! 180: (void)memset(&tm, 0, sizeof(struct tm));
! 181:
! 182: if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
! 183: return(mktime(&tm));
! 184: if ((pp = strptime(p, "%d %b %Y", &tm)) && 0 == *pp)
! 185: return(mktime(&tm));
! 186: if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
! 187: return(mktime(&tm));
! 188: if ((pp = strptime(p, "%b %Y", &tm)) && 0 == *pp)
! 189: return(mktime(&tm));
! 190:
! 191: return(0);
! 192: }