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

Annotation of mandoc/xml.c, Revision 1.1

1.1     ! kristaps    1: /* $Id: validate.c,v 1.6 2008/11/30 20:53:34 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 <sys/param.h>
        !            20:
        !            21: #include <assert.h>
        !            22: #include <ctype.h>
        !            23: #include <err.h>
        !            24: #include <stdio.h>
        !            25: #include <stdlib.h>
        !            26: #include <string.h>
        !            27:
        !            28: #include "libmdocml.h"
        !            29: #include "private.h"
        !            30:
        !            31: #define        INDENT           4
        !            32: #define        COLUMNS          60
        !            33:
        !            34: #ifdef __linux__ /* FIXME */
        !            35: #define        strlcat          strncat
        !            36: #endif
        !            37:
        !            38: enum   md_tok {
        !            39:        MD_BLKIN,
        !            40:        MD_BLKOUT,
        !            41:        MD_IN,
        !            42:        MD_OUT,
        !            43:        MD_TEXT
        !            44: };
        !            45:
        !            46: struct md_xml {
        !            47:        const struct md_args    *args;
        !            48:        const struct md_rbuf    *rbuf;
        !            49:
        !            50:        struct md_mbuf  *mbuf;
        !            51:        struct rofftree *tree;
        !            52:        size_t           indent;
        !            53:        size_t           pos;
        !            54:        enum md_tok      last;
        !            55:        int              flags;
        !            56: #define        MD_LITERAL      (1 << 0) /* FIXME */
        !            57: };
        !            58:
        !            59: static void             roffmsg(void *arg, enum roffmsg,
        !            60:                                const char *, const char *, char *);
        !            61: static int              roffhead(void *);
        !            62: static int              rofftail(void *);
        !            63: static int              roffin(void *, int, int *, char **);
        !            64: static int              roffdata(void *, int, char *);
        !            65: static int              roffout(void *, int);
        !            66: static int              roffblkin(void *, int, int *, char **);
        !            67: static int              roffblkout(void *, int);
        !            68: static int              roffspecial(void *, int);
        !            69:
        !            70: static int              mbuf_newline(struct md_xml *);
        !            71: static int              mbuf_indent(struct md_xml *);
        !            72: static int              mbuf_data(struct md_xml *, int, char *);
        !            73: static int              mbuf_putstring(struct md_xml *,
        !            74:                                const char *);
        !            75: static int              mbuf_nputstring(struct md_xml *,
        !            76:                                const char *, size_t);
        !            77:
        !            78:
        !            79: static int
        !            80: mbuf_putstring(struct md_xml *p, const char *buf)
        !            81: {
        !            82:
        !            83:        return(mbuf_nputstring(p, buf, strlen(buf)));
        !            84: }
        !            85:
        !            86:
        !            87: static int
        !            88: mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz)
        !            89: {
        !            90:
        !            91:        p->pos += sz;
        !            92:        return(md_buf_puts(p->mbuf, buf, sz));
        !            93: }
        !            94:
        !            95:
        !            96: static int
        !            97: mbuf_indent(struct md_xml *p)
        !            98: {
        !            99:        size_t           i;
        !           100:
        !           101:        assert(p->pos == 0);
        !           102:
        !           103:        /* LINTED */
        !           104:        for (i = 0; i < MIN(p->indent, INDENT); i++)
        !           105:                if ( ! md_buf_putstring(p->mbuf, "    "))
        !           106:                        return(0);
        !           107:
        !           108:        p->pos += i * INDENT;
        !           109:        return(1);
        !           110: }
        !           111:
        !           112:
        !           113: static int
        !           114: mbuf_newline(struct md_xml *p)
        !           115: {
        !           116:
        !           117:        if ( ! md_buf_putchar(p->mbuf, '\n'))
        !           118:                return(0);
        !           119:
        !           120:        p->pos = 0;
        !           121:        return(1);
        !           122: }
        !           123:
        !           124:
        !           125: static int
        !           126: mbuf_data(struct md_xml *p, int space, char *buf)
        !           127: {
        !           128:        size_t           sz;
        !           129:        char            *bufp;
        !           130:
        !           131:        assert(p->mbuf);
        !           132:        assert(0 != p->indent);
        !           133:
        !           134:        if (MD_LITERAL & p->flags)
        !           135:                return(mbuf_putstring(p, buf));
        !           136:
        !           137:        while (*buf) {
        !           138:                while (*buf && isspace(*buf))
        !           139:                        buf++;
        !           140:
        !           141:                if (0 == *buf)
        !           142:                        break;
        !           143:
        !           144:                bufp = buf;
        !           145:                while (*buf && ! isspace(*buf))
        !           146:                        buf++;
        !           147:
        !           148:                if (0 != *buf)
        !           149:                        *buf++ = 0;
        !           150:
        !           151:                sz = strlen(bufp);
        !           152:
        !           153:                if (0 == p->pos) {
        !           154:                        if ( ! mbuf_indent(p))
        !           155:                                return(0);
        !           156:                        if ( ! mbuf_nputstring(p, bufp, sz))
        !           157:                                return(0);
        !           158:                        if (p->indent * INDENT + sz >= COLUMNS) {
        !           159:                                if ( ! mbuf_newline(p))
        !           160:                                        return(0);
        !           161:                                continue;
        !           162:                        }
        !           163:                        continue;
        !           164:                }
        !           165:
        !           166:                if (space && sz + p->pos >= COLUMNS) {
        !           167:                        if ( ! mbuf_newline(p))
        !           168:                                return(0);
        !           169:                        if ( ! mbuf_indent(p))
        !           170:                                return(0);
        !           171:                } else if (space) {
        !           172:                        if ( ! mbuf_nputstring(p, " ", 1))
        !           173:                                return(0);
        !           174:                }
        !           175:
        !           176:                if ( ! mbuf_nputstring(p, bufp, sz))
        !           177:                        return(0);
        !           178:
        !           179:                if ( ! space && p->pos >= COLUMNS)
        !           180:                        if ( ! mbuf_newline(p))
        !           181:                                return(0);
        !           182:        }
        !           183:
        !           184:        return(1);
        !           185: }
        !           186:
        !           187:
        !           188: int
        !           189: md_line_xml(void *arg, char *buf)
        !           190: {
        !           191:        struct md_xml   *p;
        !           192:
        !           193:        p = (struct md_xml *)arg;
        !           194:        return(roff_engine(p->tree, buf));
        !           195: }
        !           196:
        !           197:
        !           198: int
        !           199: md_exit_xml(void *data, int flush)
        !           200: {
        !           201:        int              c;
        !           202:        struct md_xml   *p;
        !           203:
        !           204:        p = (struct md_xml *)data;
        !           205:        c = roff_free(p->tree, flush);
        !           206:        free(p);
        !           207:
        !           208:        return(c);
        !           209: }
        !           210:
        !           211:
        !           212: void *
        !           213: md_init_xml(const struct md_args *args,
        !           214:                struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
        !           215: {
        !           216:        struct roffcb    cb;
        !           217:        struct md_xml   *p;
        !           218:
        !           219:        cb.roffhead = roffhead;
        !           220:        cb.rofftail = rofftail;
        !           221:        cb.roffin = roffin;
        !           222:        cb.roffout = roffout;
        !           223:        cb.roffblkin = roffblkin;
        !           224:        cb.roffblkout = roffblkout;
        !           225:        cb.roffspecial = roffspecial;
        !           226:        cb.roffmsg = roffmsg;
        !           227:        cb.roffdata = roffdata;
        !           228:
        !           229:        if (NULL == (p = calloc(1, sizeof(struct md_xml))))
        !           230:                err(1, "malloc");
        !           231:
        !           232:        p->args = args;
        !           233:        p->mbuf = mbuf;
        !           234:        p->rbuf = rbuf;
        !           235:
        !           236:        assert(mbuf);
        !           237:
        !           238:        if (NULL == (p->tree = roff_alloc(&cb, p))) {
        !           239:                free(p);
        !           240:                return(NULL);
        !           241:        }
        !           242:
        !           243:        return(p);
        !           244: }
        !           245:
        !           246:
        !           247: /* ARGSUSED */
        !           248: static int
        !           249: roffhead(void *arg)
        !           250: {
        !           251:        struct md_xml   *p;
        !           252:
        !           253:        assert(arg);
        !           254:        p = (struct md_xml *)arg;
        !           255:
        !           256:        if ( ! mbuf_putstring(p, "<?xml version=\"1.0\" "
        !           257:                                "encoding=\"UTF-8\"?>\n"))
        !           258:                return(0);
        !           259:        if ( ! mbuf_nputstring(p, "<block:mdoc>", 12))
        !           260:                return(0);
        !           261:
        !           262:        p->indent++;
        !           263:        p->last = MD_BLKIN;
        !           264:        return(mbuf_newline(p));
        !           265: }
        !           266:
        !           267:
        !           268: static int
        !           269: rofftail(void *arg)
        !           270: {
        !           271:        struct md_xml   *p;
        !           272:
        !           273:        assert(arg);
        !           274:        p = (struct md_xml *)arg;
        !           275:
        !           276:        if (0 != p->pos && ! mbuf_newline(p))
        !           277:                return(0);
        !           278:
        !           279:        if ( ! mbuf_nputstring(p, "</block:mdoc>", 13))
        !           280:                return(0);
        !           281:
        !           282:        p->last = MD_BLKOUT;
        !           283:        return(mbuf_newline(p));
        !           284: }
        !           285:
        !           286:
        !           287: /* ARGSUSED */
        !           288: static int
        !           289: roffspecial(void *arg, int tok)
        !           290: {
        !           291:
        !           292:        /* FIXME */
        !           293:        return(1);
        !           294: }
        !           295:
        !           296:
        !           297: static int
        !           298: roffblkin(void *arg, int tok, int *argc, char **argv)
        !           299: {
        !           300:        struct md_xml   *p;
        !           301:        int              i;
        !           302:
        !           303:        assert(arg);
        !           304:        p = (struct md_xml *)arg;
        !           305:
        !           306:        if (0 != p->pos) {
        !           307:                if ( ! mbuf_newline(p))
        !           308:                        return(0);
        !           309:                if ( ! mbuf_indent(p))
        !           310:                        return(0);
        !           311:        } else if ( ! mbuf_indent(p))
        !           312:                return(0);
        !           313:
        !           314:        if ( ! mbuf_nputstring(p, "<", 1))
        !           315:                return(0);
        !           316:        if ( ! mbuf_nputstring(p, "block:", 6))
        !           317:                return(0);
        !           318:        if ( ! mbuf_putstring(p, toknames[tok]))
        !           319:                return(0);
        !           320:
        !           321:        for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
        !           322:                if ( ! mbuf_nputstring(p, " ", 1))
        !           323:                        return(0);
        !           324:                if ( ! mbuf_putstring(p, tokargnames[argc[i]]))
        !           325:                        return(0);
        !           326:                if ( ! mbuf_nputstring(p, "=\"", 2))
        !           327:                        return(0);
        !           328:                if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))
        !           329:                        return(0);
        !           330:                if ( ! mbuf_nputstring(p, "\"", 1))
        !           331:                        return(0);
        !           332:        }
        !           333:
        !           334:        if ( ! mbuf_nputstring(p, ">", 1))
        !           335:                return(0);
        !           336:
        !           337:        p->last = MD_BLKIN;
        !           338:        p->indent++;
        !           339:        return(mbuf_newline(p));
        !           340: }
        !           341:
        !           342:
        !           343: static int
        !           344: roffblkout(void *arg, int tok)
        !           345: {
        !           346:        struct md_xml   *p;
        !           347:
        !           348:        assert(arg);
        !           349:        p = (struct md_xml *)arg;
        !           350:
        !           351:        p->indent--;
        !           352:
        !           353:        if (0 != p->pos) {
        !           354:                if ( ! mbuf_newline(p))
        !           355:                        return(0);
        !           356:                if ( ! mbuf_indent(p))
        !           357:                        return(0);
        !           358:        } else if ( ! mbuf_indent(p))
        !           359:                return(0);
        !           360:
        !           361:        if ( ! mbuf_nputstring(p, "</", 2))
        !           362:                return(0);
        !           363:        if ( ! mbuf_nputstring(p, "block:", 6))
        !           364:                return(0);
        !           365:        if ( ! mbuf_putstring(p, toknames[tok]))
        !           366:                return(0);
        !           367:        if ( ! mbuf_nputstring(p, ">", 1))
        !           368:                return(0);
        !           369:
        !           370:        p->last = MD_BLKOUT;
        !           371:        return(mbuf_newline(p));
        !           372: }
        !           373:
        !           374:
        !           375: static int
        !           376: roffin(void *arg, int tok, int *argc, char **argv)
        !           377: {
        !           378:        struct md_xml   *p;
        !           379:        int              i;
        !           380:
        !           381:        assert(arg);
        !           382:        p = (struct md_xml *)arg;
        !           383:
        !           384:        /*
        !           385:         * FIXME: put all of this in a buffer, then check the buffer
        !           386:         * length versus the column width for nicer output.  This is a
        !           387:         * bit hacky.
        !           388:         */
        !           389:
        !           390:        if (p->pos + 11 > COLUMNS)
        !           391:                if ( ! mbuf_newline(p))
        !           392:                        return(0);
        !           393:
        !           394:        if (0 != p->pos) {
        !           395:                switch (p->last) {
        !           396:                case (MD_TEXT):
        !           397:                        /* FALLTHROUGH */
        !           398:                case (MD_OUT):
        !           399:                        if ( ! mbuf_nputstring(p, " ", 1))
        !           400:                                return(0);
        !           401:                        break;
        !           402:                default:
        !           403:                        break;
        !           404:                }
        !           405:        } else if ( ! mbuf_indent(p))
        !           406:                return(0);
        !           407:
        !           408:        p->last = MD_IN;
        !           409:
        !           410:        if ( ! mbuf_nputstring(p, "<", 1))
        !           411:                return(0);
        !           412:        if ( ! mbuf_nputstring(p, "inline:", 7))
        !           413:                return(0);
        !           414:        if ( ! mbuf_putstring(p, toknames[tok]))
        !           415:                return(0);
        !           416:
        !           417:        for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
        !           418:                if ( ! mbuf_nputstring(p, " ", 1))
        !           419:                        return(0);
        !           420:                if ( ! mbuf_putstring(p, tokargnames[argc[i]]))
        !           421:                        return(0);
        !           422:                if ( ! mbuf_nputstring(p, "=\"", 2))
        !           423:                        return(0);
        !           424:                if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))
        !           425:                        return(0);
        !           426:                if ( ! mbuf_nputstring(p, "\"", 1))
        !           427:                        return(0);
        !           428:        }
        !           429:        return(mbuf_nputstring(p, ">", 1));
        !           430: }
        !           431:
        !           432:
        !           433: static int
        !           434: roffout(void *arg, int tok)
        !           435: {
        !           436:        struct md_xml   *p;
        !           437:
        !           438:        assert(arg);
        !           439:        p = (struct md_xml *)arg;
        !           440:
        !           441:        if (0 == p->pos && ! mbuf_indent(p))
        !           442:                return(0);
        !           443:
        !           444:        p->last = MD_OUT;
        !           445:
        !           446:        if ( ! mbuf_nputstring(p, "</", 2))
        !           447:                return(0);
        !           448:        if ( ! mbuf_nputstring(p, "inline:", 7))
        !           449:                return(0);
        !           450:        if ( ! mbuf_putstring(p, toknames[tok]))
        !           451:                return(0);
        !           452:        return(mbuf_nputstring(p, ">", 1));
        !           453: }
        !           454:
        !           455:
        !           456: static void
        !           457: roffmsg(void *arg, enum roffmsg lvl,
        !           458:                const char *buf, const char *pos, char *msg)
        !           459: {
        !           460:        char            *level;
        !           461:        struct md_xml   *p;
        !           462:
        !           463:        assert(arg);
        !           464:        p = (struct md_xml *)arg;
        !           465:
        !           466:        switch (lvl) {
        !           467:        case (ROFF_WARN):
        !           468:                if ( ! (MD_WARN_ALL & p->args->warnings))
        !           469:                        return;
        !           470:                level = "warning";
        !           471:                break;
        !           472:        case (ROFF_ERROR):
        !           473:                level = "error";
        !           474:                break;
        !           475:        default:
        !           476:                abort();
        !           477:        }
        !           478:
        !           479:        if (pos)
        !           480:                (void)fprintf(stderr, "%s:%zu: %s: %s (column %zu)\n",
        !           481:                                p->rbuf->name, p->rbuf->line, level,
        !           482:                                msg, pos - buf);
        !           483:        else
        !           484:                (void)fprintf(stderr, "%s: %s: %s\n",
        !           485:                                p->rbuf->name, level, msg);
        !           486:
        !           487: }
        !           488:
        !           489:
        !           490: static int
        !           491: roffdata(void *arg, int space, char *buf)
        !           492: {
        !           493:        struct md_xml   *p;
        !           494:
        !           495:        assert(arg);
        !           496:        p = (struct md_xml *)arg;
        !           497:        if ( ! mbuf_data(p, space, buf))
        !           498:                return(0);
        !           499:
        !           500:        p->last = MD_TEXT;
        !           501:        return(1);
        !           502: }

CVSweb