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

Annotation of mandoc/libmdocml.c, Revision 1.3

1.3     ! kristaps    1: /* $Id: libmdocml.c,v 1.2 2008/11/22 18:34:06 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:  */
1.2       kristaps   19: #include <assert.h>
                     20: #include <fcntl.h>
                     21: #include <err.h>
                     22: #include <stdio.h>
1.1       kristaps   23: #include <stdlib.h>
1.2       kristaps   24: #include <string.h>
                     25: #include <unistd.h>
1.1       kristaps   26:
                     27: #include "libmdocml.h"
1.2       kristaps   28:
                     29: #define        BUFFER_LINE      BUFSIZ
                     30:
1.3     ! kristaps   31: struct md_rbuf {
        !            32:        int              fd;
        !            33:        char            *name;
        !            34:        char            *buf;
        !            35:        size_t           bufsz;
        !            36:        size_t           line;
        !            37: };
        !            38:
        !            39: struct md_mbuf {
        !            40:        int              fd;
        !            41:        char            *name;
        !            42:        char            *buf;
        !            43:        size_t           bufsz;
        !            44:        size_t           pos;
        !            45: };
        !            46:
        !            47: typedef int (*md_line) (const struct md_args *, struct md_mbuf *,
        !            48:                                const struct md_rbuf *,
        !            49:                                const char *, size_t);
        !            50: typedef int (*md_init) (const struct md_args *, struct md_mbuf *);
        !            51: typedef int (*md_exit) (const struct md_args *, struct md_mbuf *);
        !            52:
        !            53: static int              md_line_dummy(const struct md_args *,
        !            54:                                struct md_mbuf *,
        !            55:                                const struct md_rbuf *,
1.2       kristaps   56:                                const char *, size_t);
                     57:
1.3     ! kristaps   58: static int              md_line_html4_strict(const struct md_args *,
        !            59:                                struct md_mbuf *,
1.2       kristaps   60:                                const struct md_rbuf *,
                     61:                                const char *, size_t);
1.3     ! kristaps   62: static int              md_init_html4_strict(const struct md_args *,
        !            63:                                struct md_mbuf *);
        !            64: static int              md_exit_html4_strict(const struct md_args *,
        !            65:                                struct md_mbuf *);
        !            66:
        !            67: static int              md_run_enter(const struct md_args *,
        !            68:                                struct md_mbuf *, struct md_rbuf *);
        !            69: static int              md_run_leave(const struct md_args *,
        !            70:                                struct md_mbuf *,
        !            71:                                struct md_rbuf *, int);
        !            72:
1.2       kristaps   73: static ssize_t          md_buf_fill(struct md_rbuf *);
                     74: static int              md_buf_flush(struct md_mbuf *);
                     75: static int              md_buf_putchar(struct md_mbuf *, char);
                     76: static int              md_buf_puts(struct md_mbuf *,
                     77:                                const char *, size_t);
                     78:
                     79:
1.3     ! kristaps   80: static ssize_t
1.2       kristaps   81: md_buf_fill(struct md_rbuf *in)
                     82: {
                     83:        ssize_t          ssz;
                     84:
                     85:        assert(in);
                     86:        assert(in->buf);
                     87:        assert(in->bufsz > 0);
                     88:        assert(in->name);
                     89:
                     90:        if (-1 == (ssz = read(in->fd, in->buf, in->bufsz)))
                     91:                warn("%s", in->name);
                     92:
                     93:        return(ssz);
                     94: }
                     95:
                     96:
1.3     ! kristaps   97: static int
1.2       kristaps   98: md_buf_flush(struct md_mbuf *buf)
                     99: {
                    100:        ssize_t          sz;
                    101:
                    102:        assert(buf);
                    103:        assert(buf->buf);
                    104:        assert(buf->name);
                    105:
                    106:        if (0 == buf->pos)
                    107:                return(1);
                    108:
                    109:        sz = write(buf->fd, buf->buf, buf->pos);
                    110:
                    111:        if (-1 == sz) {
                    112:                warn("%s", buf->name);
                    113:                return(0);
                    114:        } else if ((size_t)sz != buf->pos) {
                    115:                warnx("%s: short write", buf->name);
                    116:                return(0);
                    117:        }
                    118:
                    119:        buf->pos = 0;
                    120:        return(1);
                    121: }
                    122:
                    123:
1.3     ! kristaps  124: static int
1.2       kristaps  125: md_buf_putchar(struct md_mbuf *buf, char c)
                    126: {
                    127:        return(md_buf_puts(buf, &c, 1));
                    128: }
                    129:
                    130:
1.3     ! kristaps  131: static int
1.2       kristaps  132: md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)
                    133: {
                    134:        size_t           ssz;
                    135:
                    136:        assert(p);
                    137:        assert(buf);
                    138:        assert(buf->buf);
                    139:
                    140:        /* LINTED */
                    141:        while (buf->pos + sz > buf->bufsz) {
                    142:                ssz = buf->bufsz - buf->pos;
                    143:                (void)memcpy(/* LINTED */
                    144:                                buf->buf + buf->pos, p, ssz);
                    145:                p += (long)ssz;
                    146:                sz -= ssz;
                    147:                buf->pos += ssz;
                    148:
                    149:                if ( ! md_buf_flush(buf))
                    150:                        return(0);
                    151:        }
                    152:
                    153:        (void)memcpy(/* LINTED */
                    154:                        buf->buf + buf->pos, p, sz);
                    155:        buf->pos += sz;
                    156:        return(1);
                    157: }
                    158:
                    159:
1.3     ! kristaps  160: static int
        !           161: md_run_leave(const struct md_args *args,
        !           162:                struct md_mbuf *mbuf, struct md_rbuf *rbuf, int c)
        !           163: {
        !           164:        assert(args);
        !           165:        assert(mbuf);
        !           166:        assert(rbuf);
        !           167:
        !           168:        /* Run exiters. */
        !           169:        switch (args->type) {
        !           170:        case (MD_HTML4_STRICT):
        !           171:                if ( ! md_exit_html4_strict(args, mbuf))
        !           172:                        return(-1);
        !           173:                break;
        !           174:        case (MD_DUMMY):
        !           175:                break;
        !           176:        default:
        !           177:                abort();
        !           178:        }
        !           179:
        !           180:        /* Make final flush of buffer. */
        !           181:        if ( ! md_buf_flush(mbuf))
        !           182:                return(-1);
        !           183:
        !           184:        return(c);
        !           185: }
        !           186:
        !           187:
        !           188: static int
        !           189: md_run_enter(const struct md_args *args,
        !           190:                struct md_mbuf *mbuf, struct md_rbuf *rbuf)
1.2       kristaps  191: {
                    192:        ssize_t          sz, i;
                    193:        char             line[BUFFER_LINE];
                    194:        size_t           pos;
1.3     ! kristaps  195:        md_line          fp;
1.2       kristaps  196:
1.3     ! kristaps  197:        assert(args);
        !           198:        assert(mbuf);
        !           199:        assert(rbuf);
        !           200:
        !           201:        /* Function ptrs to line-parsers. */
        !           202:        switch (args->type) {
        !           203:        case (MD_HTML4_STRICT):
        !           204:                fp = md_line_html4_strict;
        !           205:                break;
        !           206:        case (MD_DUMMY):
        !           207:                fp = md_line_dummy;
        !           208:                break;
        !           209:        default:
        !           210:                abort();
        !           211:        }
1.2       kristaps  212:
                    213:        /* LINTED */
                    214:        for (pos = 0; ; ) {
1.3     ! kristaps  215:                if (-1 == (sz = md_buf_fill(rbuf)))
        !           216:                        return(-1);
1.2       kristaps  217:                else if (0 == sz)
                    218:                        break;
                    219:
                    220:                for (i = 0; i < sz; i++) {
1.3     ! kristaps  221:                        if ('\n' == rbuf->buf[i]) {
        !           222:                                if ( ! (*fp)(args, mbuf, rbuf, line, pos))
        !           223:                                        return(-1);
        !           224:                                rbuf->line++;
1.2       kristaps  225:                                pos = 0;
                    226:                                continue;
                    227:                        }
                    228:
                    229:                        if (pos < BUFFER_LINE) {
                    230:                                /* LINTED */
1.3     ! kristaps  231:                                line[pos++] = rbuf->buf[i];
1.2       kristaps  232:                                continue;
                    233:                        }
                    234:
                    235:                        warnx("%s: line %zu too long",
1.3     ! kristaps  236:                                        rbuf->name, rbuf->line);
        !           237:                        return(-1);
1.2       kristaps  238:                }
                    239:        }
                    240:
1.3     ! kristaps  241:        if (0 != pos && ! (*fp)(args, mbuf, rbuf, line, pos))
        !           242:                return(-1);
        !           243:
        !           244:        return(md_run_leave(args, mbuf, rbuf, 0));
        !           245: }
        !           246:
        !           247:
        !           248: int
        !           249: md_run(const struct md_args *args,
        !           250:                const struct md_buf *out, const struct md_buf *in)
        !           251: {
        !           252:        struct md_mbuf   mbuf;
        !           253:        struct md_rbuf   rbuf;
        !           254:
        !           255:        assert(args);
        !           256:        assert(in);
        !           257:        assert(out);
        !           258:
        !           259:        (void)memcpy(&mbuf, out, sizeof(struct md_buf));
        !           260:        (void)memcpy(&rbuf, in, sizeof(struct md_buf));
        !           261:
        !           262:        mbuf.pos = 0;
        !           263:        rbuf.line = 1;
        !           264:
        !           265:        /* Run initialisers. */
        !           266:        switch (args->type) {
        !           267:        case (MD_HTML4_STRICT):
        !           268:                if ( ! md_init_html4_strict(args, &mbuf))
        !           269:                        return(-1);
        !           270:                break;
        !           271:        case (MD_DUMMY):
        !           272:                break;
        !           273:        default:
        !           274:                abort();
        !           275:        }
1.2       kristaps  276:
1.3     ! kristaps  277:        /* Go into mainline. */
        !           278:        return(md_run_enter(args, &mbuf, &rbuf));
1.2       kristaps  279: }
                    280:
                    281:
                    282: static int
1.3     ! kristaps  283: md_line_dummy(const struct md_args *args, struct md_mbuf *out,
        !           284:                const struct md_rbuf *in, const char *buf, size_t sz)
1.2       kristaps  285: {
                    286:
                    287:        assert(buf);
                    288:        assert(out);
                    289:        assert(in);
1.3     ! kristaps  290:        assert(args);
1.2       kristaps  291:
                    292:        if ( ! md_buf_puts(out, buf, sz))
1.3     ! kristaps  293:                return(0);
1.2       kristaps  294:        if ( ! md_buf_putchar(out, '\n'))
1.3     ! kristaps  295:                return(0);
        !           296:
        !           297:        return(1);
        !           298: }
        !           299:
        !           300:
        !           301: static int
        !           302: md_exit_html4_strict(const struct md_args *args, struct md_mbuf *p)
        !           303: {
        !           304:
        !           305:        assert(p);
        !           306:        assert(args);
        !           307:        return(1);
        !           308: }
        !           309:
        !           310:
        !           311: static int
        !           312: md_init_html4_strict(const struct md_args *args, struct md_mbuf *p)
        !           313: {
1.2       kristaps  314:
1.3     ! kristaps  315:        assert(p);
        !           316:        assert(args);
        !           317:        return(1);
1.2       kristaps  318: }
                    319:
                    320:
1.3     ! kristaps  321: static int
        !           322: md_line_html4_strict(const struct md_args *args, struct md_mbuf *out,
        !           323:                const struct md_rbuf *in, const char *buf, size_t sz)
        !           324: {
        !           325:
        !           326:        assert(args);
        !           327:        assert(buf);
        !           328:        assert(out);
        !           329:        assert(in);
        !           330:        (void)sz;
        !           331:
        !           332:        return(1);
        !           333: }

CVSweb