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

Annotation of mandoc/libmdocml.c, Revision 1.2

1.2     ! kristaps    1: /* $Id: libmdocml.c,v 1.1.1.1 2008/11/22 14:53:29 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:
        !            31: typedef int (*md_line) (struct md_mbuf *, const struct md_rbuf *,
        !            32:                                const char *, size_t);
        !            33:
        !            34: static int              md_line_dummy(struct md_mbuf *,
        !            35:                                const struct md_rbuf *,
        !            36:                                const char *, size_t);
        !            37: static ssize_t          md_buf_fill(struct md_rbuf *);
        !            38: static int              md_buf_flush(struct md_mbuf *);
        !            39: static int              md_buf_putchar(struct md_mbuf *, char);
        !            40: static int              md_buf_puts(struct md_mbuf *,
        !            41:                                const char *, size_t);
        !            42:
        !            43:
        !            44: ssize_t
        !            45: md_buf_fill(struct md_rbuf *in)
        !            46: {
        !            47:        ssize_t          ssz;
        !            48:
        !            49:        assert(in);
        !            50:        assert(in->buf);
        !            51:        assert(in->bufsz > 0);
        !            52:        assert(in->name);
        !            53:
        !            54:        if (-1 == (ssz = read(in->fd, in->buf, in->bufsz)))
        !            55:                warn("%s", in->name);
        !            56:
        !            57:        return(ssz);
        !            58: }
        !            59:
        !            60:
        !            61: int
        !            62: md_buf_flush(struct md_mbuf *buf)
        !            63: {
        !            64:        ssize_t          sz;
        !            65:
        !            66:        assert(buf);
        !            67:        assert(buf->buf);
        !            68:        assert(buf->name);
        !            69:
        !            70:        if (0 == buf->pos)
        !            71:                return(1);
        !            72:
        !            73:        sz = write(buf->fd, buf->buf, buf->pos);
        !            74:
        !            75:        if (-1 == sz) {
        !            76:                warn("%s", buf->name);
        !            77:                return(0);
        !            78:        } else if ((size_t)sz != buf->pos) {
        !            79:                warnx("%s: short write", buf->name);
        !            80:                return(0);
        !            81:        }
        !            82:
        !            83:        buf->pos = 0;
        !            84:        return(1);
        !            85: }
        !            86:
        !            87:
        !            88: int
        !            89: md_buf_putchar(struct md_mbuf *buf, char c)
        !            90: {
        !            91:        return(md_buf_puts(buf, &c, 1));
        !            92: }
        !            93:
        !            94:
        !            95: int
        !            96: md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)
        !            97: {
        !            98:        size_t           ssz;
        !            99:
        !           100:        assert(p);
        !           101:        assert(buf);
        !           102:        assert(buf->buf);
        !           103:
        !           104:        /* LINTED */
        !           105:        while (buf->pos + sz > buf->bufsz) {
        !           106:                ssz = buf->bufsz - buf->pos;
        !           107:                (void)memcpy(/* LINTED */
        !           108:                                buf->buf + buf->pos, p, ssz);
        !           109:                p += (long)ssz;
        !           110:                sz -= ssz;
        !           111:                buf->pos += ssz;
        !           112:
        !           113:                if ( ! md_buf_flush(buf))
        !           114:                        return(0);
        !           115:        }
        !           116:
        !           117:        (void)memcpy(/* LINTED */
        !           118:                        buf->buf + buf->pos, p, sz);
        !           119:        buf->pos += sz;
        !           120:        return(1);
        !           121: }
        !           122:
        !           123:
        !           124: int
        !           125: md_run(enum md_type type, struct md_mbuf *out, struct md_rbuf *in)
        !           126: {
        !           127:        ssize_t          sz, i;
        !           128:        char             line[BUFFER_LINE];
        !           129:        size_t           pos;
        !           130:        md_line          func;
        !           131:
        !           132:        assert(in);
        !           133:        assert(out);
        !           134:
        !           135:        out->pos = 0;
        !           136:        in->line = 1;
        !           137:
        !           138:        assert(MD_DUMMY == type);
        !           139:        func = md_line_dummy;
        !           140:
        !           141:        /* LINTED */
        !           142:        for (pos = 0; ; ) {
        !           143:                if (-1 == (sz = md_buf_fill(in)))
        !           144:                        return(1);
        !           145:                else if (0 == sz)
        !           146:                        break;
        !           147:
        !           148:                for (i = 0; i < sz; i++) {
        !           149:                        if ('\n' == in->buf[i]) {
        !           150:                                if ((*func)(out, in, line, pos))
        !           151:                                        return(1);
        !           152:                                in->line++;
        !           153:                                pos = 0;
        !           154:                                continue;
        !           155:                        }
        !           156:
        !           157:                        if (pos < BUFFER_LINE) {
        !           158:                                /* LINTED */
        !           159:                                line[pos++] = in->buf[i];
        !           160:                                continue;
        !           161:                        }
        !           162:
        !           163:                        warnx("%s: line %zu too long",
        !           164:                                        in->name, in->line);
        !           165:                        return(1);
        !           166:                }
        !           167:        }
        !           168:
        !           169:        if (0 != pos && (*func)(out, in, line, pos))
        !           170:                return(1);
        !           171:
        !           172:        return(md_buf_flush(out) ? 0 : 1);
        !           173: }
        !           174:
        !           175:
        !           176: static int
        !           177: md_line_dummy(struct md_mbuf *out, const struct md_rbuf *in,
        !           178:                const char *buf, size_t sz)
        !           179: {
        !           180:
        !           181:        assert(buf);
        !           182:        assert(out);
        !           183:        assert(in);
        !           184:
        !           185:        if ( ! md_buf_puts(out, buf, sz))
        !           186:                return(1);
        !           187:        if ( ! md_buf_putchar(out, '\n'))
        !           188:                return(1);
        !           189:
        !           190:        return(0);
        !           191: }
        !           192:
        !           193:

CVSweb