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