]>
git.cameronkatri.com Git - mandoc.git/blob - libmdocml.c
1 /* $Id: libmdocml.c,v 1.16 2008/11/30 21:41:35 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
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
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.
28 #include "libmdocml.h"
31 #define BUFFER_LINE BUFSIZ /* Default line-buffer size. */
33 static int md_run_enter(const struct md_args
*,
34 struct md_mbuf
*, struct md_rbuf
*, void *);
35 static int md_run_leave(const struct md_args
*, struct md_mbuf
*,
36 struct md_rbuf
*, int, void *);
38 static ssize_t
md_buf_fill(struct md_rbuf
*);
39 static int md_buf_flush(struct md_mbuf
*);
43 md_buf_fill(struct md_rbuf
*in
)
49 assert(in
->bufsz
> 0);
52 if (-1 == (ssz
= read(in
->fd
, in
->buf
, in
->bufsz
)))
59 static int md_buf_flush(struct md_mbuf
*buf
)
70 sz
= write(buf
->fd
, buf
->buf
, buf
->pos
);
73 warn("%s", buf
->name
);
75 } else if ((size_t)sz
!= buf
->pos
) {
76 warnx("%s: short write", buf
->name
);
86 md_buf_putchar(struct md_mbuf
*buf
, char c
)
90 return(md_buf_puts(buf
, &c
, 1));
95 md_buf_putstring(struct md_mbuf
*buf
, const char *p
)
99 return(md_buf_puts(buf
, p
, strlen(p
)));
104 md_buf_puts(struct md_mbuf
*buf
, const char *p
, size_t sz
)
113 while (buf
->pos
+ sz
> buf
->bufsz
) {
114 ssz
= buf
->bufsz
- buf
->pos
;
115 (void)memcpy(/* LINTED */
116 buf
->buf
+ buf
->pos
, p
, ssz
);
121 if ( ! md_buf_flush(buf
))
125 (void)memcpy(/* LINTED */
126 buf
->buf
+ buf
->pos
, p
, sz
);
133 md_run_leave(const struct md_args
*args
, struct md_mbuf
*mbuf
,
134 struct md_rbuf
*rbuf
, int c
, void *data
)
141 switch (args
->type
) {
142 case (MD_HTML4_STRICT
):
143 if ( ! md_exit_html4_strict(data
, -1 == c
? 0 : 1))
147 if ( ! md_exit_xml(data
, -1 == c
? 0 : 1))
152 /* Make final flush of buffer. */
153 if ( ! md_buf_flush(mbuf
))
161 md_run_enter(const struct md_args
*args
, struct md_mbuf
*mbuf
,
162 struct md_rbuf
*rbuf
, void *p
)
165 char line
[BUFFER_LINE
];
173 /* Function ptrs to line-parsers. */
174 switch (args
->type
) {
175 case (MD_HTML4_STRICT
):
176 fp
= md_line_html4_strict
;
186 if (-1 == (sz
= md_buf_fill(rbuf
))) {
187 return(md_run_leave(args
, mbuf
, rbuf
, -1, p
));
188 } else if (0 == sz
&& 0 != pos
) {
189 warnx("%s: no newline at end of file", rbuf
->name
);
190 return(md_run_leave(args
, mbuf
, rbuf
, -1, p
));
192 return(md_run_leave(args
, mbuf
, rbuf
, 0, p
));
194 for (i
= 0; i
< sz
; i
++) {
196 if ( ! isascii(rbuf->buf[i])) {
197 warnx("%s: non-ascii char (line %zu, col %zu)",
198 rbuf->name, rbuf->line, pos);
199 return(md_run_leave(args, mbuf, rbuf, -1, p));
202 if ('\n' != rbuf
->buf
[i
]) {
203 if (pos
< BUFFER_LINE
) {
205 line
[pos
++] = rbuf
->buf
[i
];
208 warnx("%s: line %zu too long",
209 rbuf
->name
, rbuf
->line
);
210 return(md_run_leave(args
, mbuf
, rbuf
, -1, p
));
214 if ( ! (*fp
)(p
, line
))
215 return(md_run_leave(args
, mbuf
, rbuf
, -1, p
));
226 md_run(const struct md_args
*args
,
227 const struct md_buf
*out
, const struct md_buf
*in
)
237 (void)memcpy(&mbuf
, out
, sizeof(struct md_buf
));
238 (void)memcpy(&rbuf
, in
, sizeof(struct md_buf
));
243 /* Run initialisers. */
244 switch (args
->type
) {
245 case (MD_HTML4_STRICT
):
246 data
= md_init_html4_strict
247 (args
, &mbuf
, &rbuf
);
250 data
= md_init_xml(args
, &mbuf
, &rbuf
);
254 /* Go into mainline. */
255 return(md_run_enter(args
, &mbuf
, &rbuf
, data
));