[BACK]Return to action.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/action.c, Revision 1.10

1.10    ! kristaps    1: /* $Id: action.c,v 1.9 2009/01/16 12:23:25 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:
                     30:
1.4       kristaps   31: static int      post_sh(struct mdoc *);
                     32: static int      post_os(struct mdoc *);
                     33: static int      post_dt(struct mdoc *);
                     34: static int      post_dd(struct mdoc *);
1.10    ! kristaps   35: static int      post_nm(struct mdoc *);
1.3       kristaps   36:
1.1       kristaps   37: const  struct actions mdoc_actions[MDOC_MAX] = {
1.10    ! kristaps   38:        { NULL }, /* \" */
        !            39:        { post_dd }, /* Dd */
        !            40:        { post_dt }, /* Dt */
        !            41:        { post_os }, /* Os */
        !            42:        { post_sh }, /* Sh */
        !            43:        { NULL }, /* Ss */
        !            44:        { NULL }, /* Pp */
        !            45:        { NULL }, /* D1 */
        !            46:        { NULL }, /* Dl */
        !            47:        { NULL }, /* 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:        { post_nm }, /* 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:        { NULL }, /* 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 */
1.1       kristaps  144: };
                    145:
                    146:
1.3       kristaps  147: static int
1.10    ! kristaps  148: post_nm(struct mdoc *mdoc)
        !           149: {
        !           150:        char             buf[64];
        !           151:
        !           152:        assert(MDOC_ELEM == mdoc->last->type);
        !           153:        assert(MDOC_Nm == mdoc->last->tok);
        !           154:
        !           155:        if (mdoc->meta.name)
        !           156:                return(1);
        !           157:
        !           158:        if ( ! xstrlcats(buf, mdoc->last->child, 64))
        !           159:                return(mdoc_err(mdoc, "macro parameters too long"));
        !           160:
        !           161:        mdoc->meta.name = xstrdup(buf);
        !           162:        mdoc_msg(mdoc, "parsed name: %s", mdoc->meta.name);
        !           163:        return(1);
        !           164: }
        !           165:
        !           166:
        !           167: static int
1.4       kristaps  168: post_sh(struct mdoc *mdoc)
1.1       kristaps  169: {
1.10    ! kristaps  170:        enum mdoc_sec    sec;
        !           171:        char             buf[64];
1.3       kristaps  172:
                    173:        if (MDOC_HEAD != mdoc->last->type)
                    174:                return(1);
1.10    ! kristaps  175:        if ( ! xstrlcats(buf, mdoc->last->child, 64))
        !           176:                return(mdoc_err(mdoc, "macro parameters too long"));
1.3       kristaps  177:
1.10    ! kristaps  178:        if (SEC_CUSTOM != (sec = mdoc_atosec(buf)))
1.3       kristaps  179:                mdoc->sec_lastn = sec;
                    180:        mdoc->sec_last = sec;
1.1       kristaps  181:
                    182:        return(1);
                    183: }
                    184:
1.3       kristaps  185:
1.4       kristaps  186: static int
                    187: post_dt(struct mdoc *mdoc)
                    188: {
1.5       kristaps  189:        int               i;
                    190:        char             *p;
                    191:        struct mdoc_node *n;
                    192:
                    193:        assert(MDOC_ELEM == mdoc->last->type);
1.7       kristaps  194:        assert(MDOC_Dt == mdoc->last->tok);
1.5       kristaps  195:
1.10    ! kristaps  196:        assert(NULL == mdoc->meta.title);
1.4       kristaps  197:
1.5       kristaps  198:        for (i = 0, n = mdoc->last->child; n; n = n->next, i++) {
                    199:                assert(MDOC_TEXT == n->type);
                    200:                p = n->data.text.string;
1.4       kristaps  201:
1.5       kristaps  202:                switch (i) {
                    203:                case (0):
1.10    ! kristaps  204:                        mdoc->meta.title = xstrdup(p);
        !           205:                        break;
1.5       kristaps  206:                case (1):
                    207:                        mdoc->meta.msec = mdoc_atomsec(p);
                    208:                        if (MSEC_DEFAULT != mdoc->meta.msec)
                    209:                                break;
1.10    ! kristaps  210:                        return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
1.5       kristaps  211:                case (2):
                    212:                        mdoc->meta.vol = mdoc_atovol(p);
                    213:                        if (VOL_DEFAULT != mdoc->meta.vol)
                    214:                                break;
                    215:                        mdoc->meta.arch = mdoc_atoarch(p);
                    216:                        if (ARCH_DEFAULT != mdoc->meta.arch)
                    217:                                break;
1.10    ! kristaps  218:                        return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
1.5       kristaps  219:                default:
1.8       kristaps  220:                        return(mdoc_nerr(mdoc, n, "too many parameters"));
1.5       kristaps  221:                }
1.4       kristaps  222:        }
                    223:
1.10    ! kristaps  224:        if (NULL == mdoc->meta.title)
        !           225:                mdoc->meta.title = xstrdup("untitled");
        !           226:
1.5       kristaps  227:        mdoc_msg(mdoc, "parsed title: %s", mdoc->meta.title);
1.6       kristaps  228:        /* TODO: print vol2a functions. */
1.4       kristaps  229:        return(1);
                    230: }
                    231:
                    232:
                    233: static int
                    234: post_os(struct mdoc *mdoc)
                    235: {
1.10    ! kristaps  236:        char              buf[64];
1.5       kristaps  237:
                    238:        assert(MDOC_ELEM == mdoc->last->type);
1.7       kristaps  239:        assert(MDOC_Os == mdoc->last->tok);
1.10    ! kristaps  240:        assert(NULL == mdoc->meta.os);
1.5       kristaps  241:
1.10    ! kristaps  242:        if ( ! xstrlcats(buf, mdoc->last->child, 64))
        !           243:                return(mdoc_err(mdoc, "macro parameters too long"));
1.6       kristaps  244:
1.10    ! kristaps  245:        mdoc->meta.os = xstrdup(buf[0] ? buf : "local");
1.6       kristaps  246:        mdoc_msg(mdoc, "parsed operating system: %s", mdoc->meta.os);
1.5       kristaps  247:        mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
1.4       kristaps  248:        return(1);
                    249: }
                    250:
                    251:
                    252: static int
                    253: post_dd(struct mdoc *mdoc)
                    254: {
1.5       kristaps  255:        char              date[64];
                    256:        size_t            sz;
                    257:        char             *p;
                    258:        struct mdoc_node *n;
1.4       kristaps  259:
1.5       kristaps  260:        assert(MDOC_ELEM == mdoc->last->type);
1.7       kristaps  261:        assert(MDOC_Dd == mdoc->last->tok);
1.5       kristaps  262:
                    263:        n = mdoc->last->child;
                    264:        assert(0 == mdoc->meta.date);
1.4       kristaps  265:        date[0] = 0;
                    266:
1.5       kristaps  267:        sz = 64;
                    268:
                    269:        for ( ; 0 == mdoc->meta.date && n; n = n->next) {
                    270:                assert(MDOC_TEXT == n->type);
                    271:                p = n->data.text.string;
                    272:
                    273:                if (xstrcmp(p, "$Mdocdate$")) {
                    274:                        mdoc->meta.date = time(NULL);
                    275:                        continue;
                    276:                } else if (xstrcmp(p, "$")) {
                    277:                        mdoc->meta.date = mdoc_atotime(date);
                    278:                        continue;
                    279:                } else if (xstrcmp(p, "$Mdocdate:"))
                    280:                        continue;
                    281:
                    282:                if ( ! xstrlcat(date, n->data.text.string, sz))
1.10    ! kristaps  283:                        return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
1.9       kristaps  284:                if (n->next && ! xstrlcat(date, " ", sz))
1.10    ! kristaps  285:                        return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
1.5       kristaps  286:        }
                    287:
                    288:        if (mdoc->meta.date && NULL == n) {
                    289:                mdoc_msg(mdoc, "parsed time: %u since epoch",
                    290:                                mdoc->meta.date);
                    291:                return(1);
1.9       kristaps  292:        } else if (n)
1.10    ! kristaps  293:                return(mdoc_err(mdoc, "invalid parameter syntax"));
1.9       kristaps  294:
                    295:        if ((mdoc->meta.date = mdoc_atotime(date))) {
                    296:                mdoc_msg(mdoc, "parsed time: %u since epoch",
                    297:                                mdoc->meta.date);
                    298:                return(1);
1.4       kristaps  299:        }
1.5       kristaps  300:
1.10    ! kristaps  301:        return(mdoc_err(mdoc, "invalid parameter syntax"));
1.4       kristaps  302: }
                    303:
                    304:
                    305: int
                    306: mdoc_action_post(struct mdoc *mdoc)
1.3       kristaps  307: {
                    308:
1.7       kristaps  309:        if (MDOC_TEXT == mdoc->last->type)
                    310:                return(1);
                    311:        if (MDOC_ROOT == mdoc->last->type)
1.3       kristaps  312:                return(1);
1.7       kristaps  313:        if (NULL == mdoc_actions[mdoc->last->tok].post)
1.3       kristaps  314:                return(1);
1.7       kristaps  315:        return((*mdoc_actions[mdoc->last->tok].post)(mdoc));
1.3       kristaps  316: }

CVSweb