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

Annotation of mandoc/term.c, Revision 1.1

1.1     ! kristaps    1: /* $Id: tree.c,v 1.2 2009/01/17 14:04:25 kristaps Exp $ */
        !             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 <curses.h>
        !            21: #include <err.h>
        !            22: #include <stdlib.h>
        !            23: #include <stdio.h>
        !            24: #include <string.h>
        !            25: #include <term.h>
        !            26: #include <unistd.h>
        !            27:
        !            28: #include "mdoc.h"
        !            29:
        !            30:
        !            31: static int              termprint_r(size_t, size_t,
        !            32:                                const struct mdoc_node *);
        !            33: static void             termprint_head(size_t,
        !            34:                                const struct mdoc_meta *);
        !            35: static void             termprint_tail(size_t,
        !            36:                                const struct mdoc_meta *);
        !            37:
        !            38: static char            *arch2a(enum mdoc_arch);
        !            39: static char            *vol2a(enum mdoc_vol);
        !            40: static char            *msec2a(enum mdoc_msec);
        !            41:
        !            42: static size_t           ttitle2a(char *, enum mdoc_vol, enum mdoc_msec,
        !            43:                                enum mdoc_arch, size_t);
        !            44:
        !            45:
        !            46: static char *
        !            47: arch2a(enum mdoc_arch arch)
        !            48: {
        !            49:
        !            50:        switch (arch) {
        !            51:        case (ARCH_alpha):
        !            52:                return("Alpha");
        !            53:        case (ARCH_amd64):
        !            54:                return("AMD64");
        !            55:        case (ARCH_amiga):
        !            56:                return("Amiga");
        !            57:        case (ARCH_arc):
        !            58:                return("ARC");
        !            59:        case (ARCH_arm):
        !            60:                return("ARM");
        !            61:        case (ARCH_armish):
        !            62:                return("ARMISH");
        !            63:        case (ARCH_aviion):
        !            64:                return("AViion");
        !            65:        case (ARCH_hp300):
        !            66:                return("HP300");
        !            67:        case (ARCH_hppa):
        !            68:                return("HPPA");
        !            69:        case (ARCH_hppa64):
        !            70:                return("HPPA64");
        !            71:        case (ARCH_i386):
        !            72:                return("i386");
        !            73:        case (ARCH_landisk):
        !            74:                return("LANDISK");
        !            75:        case (ARCH_luna88k):
        !            76:                return("Luna88k");
        !            77:        case (ARCH_mac68k):
        !            78:                return("Mac68k");
        !            79:        case (ARCH_macppc):
        !            80:                return("MacPPC");
        !            81:        case (ARCH_mvme68k):
        !            82:                return("MVME68k");
        !            83:        case (ARCH_mvme88k):
        !            84:                return("MVME88k");
        !            85:        case (ARCH_mvmeppc):
        !            86:                return("MVMEPPC");
        !            87:        case (ARCH_pmax):
        !            88:                return("PMAX");
        !            89:        case (ARCH_sgi):
        !            90:                return("SGI");
        !            91:        case (ARCH_socppc):
        !            92:                return("SOCPPC");
        !            93:        case (ARCH_sparc):
        !            94:                return("SPARC");
        !            95:        case (ARCH_sparc64):
        !            96:                return("SPARC64");
        !            97:        case (ARCH_sun3):
        !            98:                return("Sun3");
        !            99:        case (ARCH_vax):
        !           100:                return("VAX");
        !           101:        case (ARCH_zaurus):
        !           102:                return("Zaurus");
        !           103:        default:
        !           104:                break;
        !           105:        }
        !           106:
        !           107:        return(NULL);
        !           108: }
        !           109:
        !           110:
        !           111: static char *
        !           112: vol2a(enum mdoc_vol vol)
        !           113: {
        !           114:
        !           115:        switch (vol) {
        !           116:        case (VOL_AMD):
        !           117:                return("OpenBSD Ancestral Manual Documents");
        !           118:        case (VOL_IND):
        !           119:                return("OpenBSD Manual Master Index");
        !           120:        case (VOL_KM):
        !           121:                return("OpenBSD Kernel Manual");
        !           122:        case (VOL_LOCAL):
        !           123:                return("OpenBSD Local Manual");
        !           124:        case (VOL_PRM):
        !           125:                return("OpenBSD Programmer's Manual");
        !           126:        case (VOL_PS1):
        !           127:                return("OpenBSD Programmer's Supplementary Documents");
        !           128:        case (VOL_SMM):
        !           129:                return("OpenBSD System Manager's Manual");
        !           130:        case (VOL_URM):
        !           131:                return("OpenBSD Reference Manual");
        !           132:        case (VOL_USD):
        !           133:                return("OpenBSD User's Supplementary Documents");
        !           134:        default:
        !           135:                break;
        !           136:        }
        !           137:
        !           138:        return(NULL);
        !           139: }
        !           140:
        !           141:
        !           142: static char *
        !           143: msec2a(enum mdoc_msec msec)
        !           144: {
        !           145:
        !           146:        switch (msec) {
        !           147:        case(MSEC_1):
        !           148:                return("1");
        !           149:        case(MSEC_2):
        !           150:                return("2");
        !           151:        case(MSEC_3):
        !           152:                return("3");
        !           153:        case(MSEC_3f):
        !           154:                return("3f");
        !           155:        case(MSEC_3p):
        !           156:                return("3p");
        !           157:        case(MSEC_4):
        !           158:                return("4");
        !           159:        case(MSEC_5):
        !           160:                return("5");
        !           161:        case(MSEC_6):
        !           162:                return("6");
        !           163:        case(MSEC_7):
        !           164:                return("7");
        !           165:        case(MSEC_8):
        !           166:                return("8");
        !           167:        case(MSEC_9):
        !           168:                return("9");
        !           169:        case(MSEC_X11):
        !           170:                return("X11");
        !           171:        case(MSEC_X11R6):
        !           172:                return("X11R6");
        !           173:        case(MSEC_local):
        !           174:                return("local");
        !           175:        case(MSEC_n):
        !           176:                return("n");
        !           177:        case(MSEC_unass):
        !           178:                /* FALLTHROUGH */
        !           179:        case(MSEC_draft):
        !           180:                return("draft");
        !           181:        case(MSEC_paper):
        !           182:                return("paper");
        !           183:        default:
        !           184:                break;
        !           185:        }
        !           186:        return(NULL);
        !           187: }
        !           188:
        !           189:
        !           190: static size_t
        !           191: ttitle2a(char *dst, enum mdoc_vol vol, enum mdoc_msec msec,
        !           192:                enum mdoc_arch arch, size_t sz)
        !           193: {
        !           194:        char            *p;
        !           195:        size_t           ssz;
        !           196:
        !           197:        if (NULL == (p = vol2a(vol)))
        !           198:                switch (msec) {
        !           199:                case (MSEC_1):
        !           200:                        /* FALLTHROUGH */
        !           201:                case (MSEC_6):
        !           202:                        /* FALLTHROUGH */
        !           203:                case (MSEC_7):
        !           204:                        p = vol2a(VOL_URM);
        !           205:                        break;
        !           206:                case (MSEC_8):
        !           207:                        p = vol2a(VOL_SMM);
        !           208:                        break;
        !           209:                case (MSEC_2):
        !           210:                        /* FALLTHROUGH */
        !           211:                case (MSEC_3):
        !           212:                        /* FALLTHROUGH */
        !           213:                case (MSEC_4):
        !           214:                        /* FALLTHROUGH */
        !           215:                case (MSEC_5):
        !           216:                        p = vol2a(VOL_PRM);
        !           217:                        break;
        !           218:                case (MSEC_9):
        !           219:                        p = vol2a(VOL_KM);
        !           220:                        break;
        !           221:                default:
        !           222:                        /* FIXME: capitalise. */
        !           223:                        if (NULL == (p = msec2a(msec)))
        !           224:                                p = msec2a(MSEC_local);
        !           225:                        break;
        !           226:                }
        !           227:        assert(p);
        !           228:
        !           229:        if ((ssz = strlcpy(dst, p, sz)) >= sz)
        !           230:                return(ssz);
        !           231:
        !           232:        if ((p = arch2a(arch))) {
        !           233:                if ((ssz = strlcat(dst, " (", sz)) >= sz)
        !           234:                        return(ssz);
        !           235:                if ((ssz = strlcat(dst, p, sz)) >= sz)
        !           236:                        return(ssz);
        !           237:                if ((ssz = strlcat(dst, ")", sz)) >= sz)
        !           238:                        return(ssz);
        !           239:        }
        !           240:
        !           241:        return(ssz);
        !           242: }
        !           243:
        !           244:
        !           245: static int
        !           246: termprint_r(size_t cols, size_t indent, const struct mdoc_node *node)
        !           247: {
        !           248:
        !           249:        return(1);
        !           250: }
        !           251:
        !           252:
        !           253: static void
        !           254: termprint_tail(size_t cols, const struct mdoc_meta *meta)
        !           255: {
        !           256:        struct tm       *tm;
        !           257:        char            *buf, *os;
        !           258:        size_t           sz, osz, ssz, i;
        !           259:
        !           260:        if (NULL == (buf = malloc(cols)))
        !           261:                err(1, "malloc");
        !           262:        if (NULL == (os = malloc(cols)))
        !           263:                err(1, "malloc");
        !           264:
        !           265:        tm = localtime(&meta->date);
        !           266:        if (NULL == strftime(buf, cols, "%B %d, %Y", tm))
        !           267:                err(1, "strftime");
        !           268:
        !           269:        osz = strlcpy(os, meta->os, cols);
        !           270:
        !           271:        sz = strlen(buf);
        !           272:        ssz = sz + osz + 1;
        !           273:
        !           274:        if (ssz > cols) {
        !           275:                ssz -= cols;
        !           276:                assert(ssz <= osz);
        !           277:                os[osz - ssz] = 0;
        !           278:                ssz = 1;
        !           279:        } else
        !           280:                ssz = cols - ssz + 1;
        !           281:
        !           282:        printf("%s", os);
        !           283:        for (i = 0; i < ssz; i++)
        !           284:                printf(" ");
        !           285:
        !           286:        printf("%s\n", buf);
        !           287:
        !           288:        free(buf);
        !           289:        free(os);
        !           290: }
        !           291:
        !           292:
        !           293: static void
        !           294: termprint_head(size_t cols, const struct mdoc_meta *meta)
        !           295: {
        !           296:        char            *msec, *buf, *title;
        !           297:        size_t           ssz, tsz, ttsz, i;
        !           298:
        !           299:        if (NULL == (buf = malloc(cols)))
        !           300:                err(1, "malloc");
        !           301:        if (NULL == (title = malloc(cols)))
        !           302:                err(1, "malloc");
        !           303:
        !           304:        /* Format the manual page header. */
        !           305:
        !           306:        tsz = ttitle2a(buf, meta->vol, meta->msec, meta->arch, cols);
        !           307:        ttsz = strlcpy(title, meta->title, cols);
        !           308:
        !           309:        if (NULL == (msec = msec2a(meta->msec)))
        !           310:                msec = "";
        !           311:
        !           312:        ssz = (2 * (ttsz + 2 + strlen(msec))) + tsz + 2;
        !           313:
        !           314:        if (ssz > cols) {
        !           315:                if ((ssz -= cols) % 2)
        !           316:                        ssz++;
        !           317:                ssz /= 2;
        !           318:
        !           319:                assert(ssz <= ttsz);
        !           320:                title[ttsz - ssz] = 0;
        !           321:                ssz = 1;
        !           322:        } else
        !           323:                ssz = ((cols - ssz) / 2) + 1;
        !           324:
        !           325:        printf("%s(%s)", title, msec);
        !           326:
        !           327:        for (i = 0; i < ssz; i++)
        !           328:                printf(" ");
        !           329:
        !           330:        printf("%s", buf);
        !           331:
        !           332:        for (i = 0; i < ssz; i++)
        !           333:                printf(" ");
        !           334:
        !           335:        printf("%s(%s)\n\n", title, msec);
        !           336:
        !           337:        free(title);
        !           338:        free(buf);
        !           339: }
        !           340:
        !           341:
        !           342: int
        !           343: termprint(const struct mdoc_node *node,
        !           344:                const struct mdoc_meta *meta)
        !           345: {
        !           346:        size_t           cols;
        !           347:
        !           348:        if (ERR == setupterm(NULL, STDOUT_FILENO, NULL))
        !           349:                return(0);
        !           350:
        !           351:        cols = columns < 60 ? 60 : (size_t)columns;
        !           352:
        !           353:        termprint_head(cols, meta);
        !           354:        if ( ! termprint_r(cols, 0, node))
        !           355:                return(0);
        !           356:        termprint_tail(cols, meta);
        !           357:        return(1);
        !           358: }
        !           359:
        !           360:

CVSweb