]>
git.cameronkatri.com Git - mandoc.git/blob - libmdocml.c
1 /* $Id: libmdocml.c,v 1.4 2008/11/23 11:05:25 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.
27 #include "libmdocml.h"
29 #define BUFFER_LINE BUFSIZ
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
*);
53 static int md_line_dummy(const struct md_args
*,
55 const struct md_rbuf
*,
56 const char *, size_t);
58 static int md_line_html4_strict(const struct md_args
*,
60 const struct md_rbuf
*,
61 const char *, size_t);
62 static int md_init_html4_strict(const struct md_args
*,
64 static int md_exit_html4_strict(const struct md_args
*,
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
*,
71 struct md_rbuf
*, int);
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_putstring(struct md_mbuf
*,
78 static int md_buf_puts(struct md_mbuf
*,
79 const char *, size_t);
83 md_buf_fill(struct md_rbuf
*in
)
89 assert(in
->bufsz
> 0);
92 if (-1 == (ssz
= read(in
->fd
, in
->buf
, in
->bufsz
)))
100 md_buf_flush(struct md_mbuf
*buf
)
111 sz
= write(buf
->fd
, buf
->buf
, buf
->pos
);
114 warn("%s", buf
->name
);
116 } else if ((size_t)sz
!= buf
->pos
) {
117 warnx("%s: short write", buf
->name
);
127 md_buf_putchar(struct md_mbuf
*buf
, char c
)
129 return(md_buf_puts(buf
, &c
, 1));
134 md_buf_putstring(struct md_mbuf
*buf
, const char *p
)
136 return(md_buf_puts(buf
, p
, strlen(p
)));
141 md_buf_puts(struct md_mbuf
*buf
, const char *p
, size_t sz
)
150 while (buf
->pos
+ sz
> buf
->bufsz
) {
151 ssz
= buf
->bufsz
- buf
->pos
;
152 (void)memcpy(/* LINTED */
153 buf
->buf
+ buf
->pos
, p
, ssz
);
158 if ( ! md_buf_flush(buf
))
162 (void)memcpy(/* LINTED */
163 buf
->buf
+ buf
->pos
, p
, sz
);
170 md_run_leave(const struct md_args
*args
,
171 struct md_mbuf
*mbuf
, struct md_rbuf
*rbuf
, int c
)
178 switch (args
->type
) {
179 case (MD_HTML4_STRICT
):
180 if ( ! md_exit_html4_strict(args
, mbuf
))
189 /* Make final flush of buffer. */
190 if ( ! md_buf_flush(mbuf
))
198 md_run_enter(const struct md_args
*args
,
199 struct md_mbuf
*mbuf
, struct md_rbuf
*rbuf
)
202 char line
[BUFFER_LINE
];
210 /* Function ptrs to line-parsers. */
211 switch (args
->type
) {
212 case (MD_HTML4_STRICT
):
213 fp
= md_line_html4_strict
;
224 if (-1 == (sz
= md_buf_fill(rbuf
)))
229 for (i
= 0; i
< sz
; i
++) {
230 if ('\n' == rbuf
->buf
[i
]) {
231 if ( ! (*fp
)(args
, mbuf
, rbuf
, line
, pos
))
238 if (pos
< BUFFER_LINE
) {
240 line
[pos
++] = rbuf
->buf
[i
];
244 warnx("%s: line %zu too long",
245 rbuf
->name
, rbuf
->line
);
250 if (0 != pos
&& ! (*fp
)(args
, mbuf
, rbuf
, line
, pos
))
253 return(md_run_leave(args
, mbuf
, rbuf
, 0));
258 md_run(const struct md_args
*args
,
259 const struct md_buf
*out
, const struct md_buf
*in
)
268 (void)memcpy(&mbuf
, out
, sizeof(struct md_buf
));
269 (void)memcpy(&rbuf
, in
, sizeof(struct md_buf
));
274 /* Run initialisers. */
275 switch (args
->type
) {
276 case (MD_HTML4_STRICT
):
277 if ( ! md_init_html4_strict(args
, &mbuf
))
286 /* Go into mainline. */
287 return(md_run_enter(args
, &mbuf
, &rbuf
));
292 md_line_dummy(const struct md_args
*args
, struct md_mbuf
*out
,
293 const struct md_rbuf
*in
, const char *buf
, size_t sz
)
301 if ( ! md_buf_puts(out
, buf
, sz
))
303 if ( ! md_buf_putchar(out
, '\n'))
311 md_exit_html4_strict(const struct md_args
*args
, struct md_mbuf
*out
)
322 if ( ! md_buf_putstring(out
, tail
))
330 md_init_html4_strict(const struct md_args
*args
, struct md_mbuf
*out
)
339 " <title>Manual Page</title>\n"
344 if ( ! md_buf_putstring(out
, head
))
351 struct md_roff_macro
{
354 #define MD_PARSED (1 << 0)
355 #define MD_CALLABLE (1 << 1)
356 #define MD_TITLE (1 << 2)
359 struct md_roff_macro
[] = {
368 md_roff(struct md_mbuf
*out
, const struct md_rbuf
*in
,
369 const char *buf
, size_t sz
)
380 md_line_html4_strict(const struct md_args
*args
, struct md_mbuf
*out
,
381 const struct md_rbuf
*in
, const char *buf
, size_t sz
)
388 warnx("%s: blank line (line %zu)", in
->name
, in
->line
);
396 return(md_buf_puts(out
, buf
, sz
));