[BACK]Return to man_action.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

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: }