version 1.3, 2008/11/30 12:41:45 |
version 1.6, 2008/11/30 20:53:34 |
|
|
#include "private.h" |
#include "private.h" |
|
|
#define INDENT 4 |
#define INDENT 4 |
|
#define COLUMNS 72 |
|
|
#ifdef __linux__ /* FIXME */ |
#ifdef __linux__ /* FIXME */ |
#define strlcat strncat |
#define strlcat strncat |
#endif |
#endif |
|
|
|
enum md_tok { |
|
MD_BLKIN, |
|
MD_BLKOUT, |
|
MD_IN, |
|
MD_OUT, |
|
MD_TEXT |
|
}; |
|
|
struct md_valid { |
struct md_valid { |
const struct md_args *args; |
const struct md_args *args; |
const struct md_rbuf *rbuf; |
const struct md_rbuf *rbuf; |
|
|
struct md_mbuf *mbuf; |
struct md_mbuf *mbuf; |
struct rofftree *tree; |
struct rofftree *tree; |
|
|
size_t indent; |
size_t indent; |
size_t pos; |
size_t pos; |
|
enum md_tok last; |
int flags; |
int flags; |
#define MD_LITERAL (1 << 0) |
#define MD_LITERAL (1 << 0) /* FIXME */ |
}; |
}; |
|
|
static void roffmsg(void *arg, enum roffmsg, |
static void roffmsg(void *arg, enum roffmsg, |
const char *, const char *, char *); |
const char *, const char *, char *); |
static int roffhead(void *); |
static int roffhead(void *); |
static int rofftail(void *); |
static int rofftail(void *); |
static int roffin(void *, int, int *, char **); |
static int roffin(void *, int, int, int *, char **); |
static int roffdata(void *, char *); |
static int roffdata(void *, int, char *); |
static int roffout(void *, int); |
static int roffout(void *, int); |
static int roffblkin(void *, int, int *, char **); |
static int roffblkin(void *, int, int *, char **); |
static int roffblkout(void *, int); |
static int roffblkout(void *, int); |
Line 60 static int roffspecial(void *, int); |
|
Line 69 static int roffspecial(void *, int); |
|
|
|
static int mbuf_newline(struct md_valid *); |
static int mbuf_newline(struct md_valid *); |
static int mbuf_indent(struct md_valid *); |
static int mbuf_indent(struct md_valid *); |
static int mbuf_data(struct md_valid *, char *); |
static int mbuf_data(struct md_valid *, int, char *); |
|
static int mbuf_putstring(struct md_valid *, |
|
const char *); |
|
static int mbuf_nputstring(struct md_valid *, |
|
const char *, size_t); |
|
|
|
|
static int |
static int |
|
mbuf_putstring(struct md_valid *p, const char *buf) |
|
{ |
|
|
|
return(mbuf_nputstring(p, buf, strlen(buf))); |
|
} |
|
|
|
|
|
static int |
|
mbuf_nputstring(struct md_valid *p, const char *buf, size_t sz) |
|
{ |
|
|
|
p->pos += sz; |
|
return(md_buf_puts(p->mbuf, buf, sz)); |
|
} |
|
|
|
|
|
static int |
mbuf_indent(struct md_valid *p) |
mbuf_indent(struct md_valid *p) |
{ |
{ |
size_t i; |
size_t i; |
|
|
assert(p->pos == 0); |
assert(p->pos == 0); |
|
|
|
/* LINTED */ |
for (i = 0; i < MIN(p->indent, INDENT); i++) |
for (i = 0; i < MIN(p->indent, INDENT); i++) |
if ( ! md_buf_putstring(p->mbuf, " ")) |
if ( ! md_buf_putstring(p->mbuf, " ")) |
return(0); |
return(0); |
Line 92 mbuf_newline(struct md_valid *p) |
|
Line 123 mbuf_newline(struct md_valid *p) |
|
|
|
|
|
static int |
static int |
mbuf_data(struct md_valid *p, char *buf) |
mbuf_data(struct md_valid *p, int space, char *buf) |
{ |
{ |
int space; |
|
size_t sz; |
size_t sz; |
char *bufp; |
char *bufp; |
|
|
space = 1; /* FIXME */ |
|
|
|
assert(p->mbuf); |
assert(p->mbuf); |
assert(0 != p->indent); |
assert(0 != p->indent); |
|
|
|
/* |
|
* FIXME: punctuation/no-space stuff shouldn't have a newline |
|
* before it. |
|
*/ |
|
|
if (MD_LITERAL & p->flags) |
if (MD_LITERAL & p->flags) |
return(md_buf_putstring(p->mbuf, buf)); |
return(mbuf_putstring(p, buf)); |
|
|
while (*buf) { |
while (*buf) { |
while (*buf && isspace(*buf)) |
while (*buf && isspace(*buf)) |
Line 120 mbuf_data(struct md_valid *p, char *buf) |
|
Line 153 mbuf_data(struct md_valid *p, char *buf) |
|
if (0 != *buf) |
if (0 != *buf) |
*buf++ = 0; |
*buf++ = 0; |
|
|
/* Process word. */ |
|
|
|
sz = strlen(bufp); |
sz = strlen(bufp); |
|
|
if (0 == p->pos) { |
if (0 == p->pos) { |
if ( ! mbuf_indent(p)) |
if ( ! mbuf_indent(p)) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, bufp)) |
if ( ! mbuf_nputstring(p, bufp, sz)) |
return(0); |
return(0); |
|
if (p->indent * INDENT + sz >= COLUMNS) { |
if (p->indent * INDENT + sz >= 72) { |
|
if ( ! mbuf_newline(p)) |
if ( ! mbuf_newline(p)) |
return(0); |
return(0); |
continue; |
continue; |
} |
} |
|
|
p->pos += sz; |
|
continue; |
continue; |
} |
} |
|
|
if (sz + p->pos >= 72) { |
if (sz + p->pos >= COLUMNS) { |
if ( ! mbuf_newline(p)) |
if ( ! mbuf_newline(p)) |
return(0); |
return(0); |
if ( ! mbuf_indent(p)) |
if ( ! mbuf_indent(p)) |
return(0); |
return(0); |
} else if (space) |
} else if (space) |
if ( ! md_buf_putchar(p->mbuf, ' ')) |
if ( ! mbuf_nputstring(p, " ", 1)) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putstring(p->mbuf, bufp)) |
if ( ! mbuf_nputstring(p, bufp, sz)) |
return(0); |
return(0); |
|
|
p->pos += sz + (space ? 1 : 0); |
|
} |
} |
|
|
return(1); |
return(1); |
Line 227 roffhead(void *arg) |
|
Line 253 roffhead(void *arg) |
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
|
|
if ( ! md_buf_putstring(p->mbuf, "BEGIN")) |
if ( ! mbuf_putstring(p, "<?xml version=\"1.0\" " |
|
"encoding=\"UTF-8\"?>\n")) |
return(0); |
return(0); |
p->indent++; |
if ( ! mbuf_nputstring(p, "<mdoc>", 6)) |
if ( ! mbuf_newline(p)) |
|
return(0); |
return(0); |
|
|
return(1); |
p->indent++; |
|
return(mbuf_newline(p)); |
} |
} |
|
|
|
|
Line 248 rofftail(void *arg) |
|
Line 275 rofftail(void *arg) |
|
if (0 != p->pos && ! mbuf_newline(p)) |
if (0 != p->pos && ! mbuf_newline(p)) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putstring(p->mbuf, "END\n")) |
if ( ! mbuf_nputstring(p, "</mdoc>", 7)) |
return(0); |
return(0); |
return(1); |
return(mbuf_newline(p)); |
} |
} |
|
|
|
|
|
/* ARGSUSED */ |
static int |
static int |
roffspecial(void *arg, int tok) |
roffspecial(void *arg, int tok) |
{ |
{ |
|
|
roffblkin(void *arg, int tok, int *argc, char **argv) |
roffblkin(void *arg, int tok, int *argc, char **argv) |
{ |
{ |
struct md_valid *p; |
struct md_valid *p; |
|
int i; |
|
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
Line 278 roffblkin(void *arg, int tok, int *argc, char **argv) |
|
Line 307 roffblkin(void *arg, int tok, int *argc, char **argv) |
|
} else if ( ! mbuf_indent(p)) |
} else if ( ! mbuf_indent(p)) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putchar(p->mbuf, '<')) |
if ( ! mbuf_nputstring(p, "<", 1)) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
if ( ! mbuf_putstring(p, toknames[tok])) |
return(0); |
return(0); |
if ( ! md_buf_putchar(p->mbuf, '>')) |
|
|
for (i = 0; ROFF_ARGMAX != argc[i]; i++) { |
|
if ( ! mbuf_nputstring(p, " ", 1)) |
|
return(0); |
|
if ( ! mbuf_putstring(p, tokargnames[argc[i]])) |
|
return(0); |
|
if ( ! mbuf_nputstring(p, "=\"", 2)) |
|
return(0); |
|
if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) |
|
return(0); |
|
if ( ! mbuf_nputstring(p, "\"", 1)) |
|
return(0); |
|
} |
|
|
|
if ( ! mbuf_nputstring(p, ">", 1)) |
return(0); |
return(0); |
if ( ! mbuf_newline(p)) |
if ( ! mbuf_newline(p)) |
return(0); |
return(0); |
Line 310 roffblkout(void *arg, int tok) |
|
Line 353 roffblkout(void *arg, int tok) |
|
} else if ( ! mbuf_indent(p)) |
} else if ( ! mbuf_indent(p)) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putstring(p->mbuf, "</")) |
if ( ! mbuf_nputstring(p, "</", 2)) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
if ( ! mbuf_putstring(p, toknames[tok])) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, ">")) |
if ( ! mbuf_nputstring(p, ">", 1)) |
return(0); |
return(0); |
if ( ! mbuf_newline(p)) |
if ( ! mbuf_newline(p)) |
return(0); |
return(0); |
Line 324 roffblkout(void *arg, int tok) |
|
Line 367 roffblkout(void *arg, int tok) |
|
|
|
|
|
static int |
static int |
roffin(void *arg, int tok, int *argcp, char **argvp) |
roffin(void *arg, int tok, int space, int *argc, char **argv) |
{ |
{ |
struct md_valid *p; |
struct md_valid *p; |
|
int i; |
|
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
Line 334 roffin(void *arg, int tok, int *argcp, char **argvp) |
|
Line 378 roffin(void *arg, int tok, int *argcp, char **argvp) |
|
if (0 == p->pos && ! mbuf_indent(p)) |
if (0 == p->pos && ! mbuf_indent(p)) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putstring(p->mbuf, " <")) |
/* |
|
* FIXME: put into a buffer before writing (check line length). |
|
*/ |
|
|
|
if (space && ! mbuf_nputstring(p, " ", 1)) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
if ( ! mbuf_nputstring(p, "<", 1)) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, ">")) |
if ( ! mbuf_putstring(p, toknames[tok])) |
return(0); |
return(0); |
|
|
p->pos += strlen(toknames[tok]) + 3; |
for (i = 0; ROFF_ARGMAX != argc[i]; i++) { |
|
if ( ! mbuf_nputstring(p, " ", 1)) |
|
return(0); |
|
if ( ! mbuf_putstring(p, tokargnames[argc[i]])) |
|
return(0); |
|
if ( ! mbuf_nputstring(p, "=\"", 2)) |
|
return(0); |
|
if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) |
|
return(0); |
|
if ( ! mbuf_nputstring(p, "\"", 1)) |
|
return(0); |
|
} |
|
|
return(1); |
return(mbuf_nputstring(p, ">", 1)); |
} |
} |
|
|
|
|
Line 358 roffout(void *arg, int tok) |
|
Line 417 roffout(void *arg, int tok) |
|
if (0 == p->pos && ! mbuf_indent(p)) |
if (0 == p->pos && ! mbuf_indent(p)) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putstring(p->mbuf, "</")) |
if ( ! mbuf_nputstring(p, "</", 2)) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
if ( ! mbuf_putstring(p, toknames[tok])) |
return(0); |
return(0); |
if ( ! md_buf_putstring(p->mbuf, ">")) |
return(mbuf_nputstring(p, ">", 1)); |
return(0); |
|
|
|
p->pos += strlen(toknames[tok]) + 2; |
|
|
|
return(1); |
|
} |
} |
|
|
|
|
|
|
static void |
static void |
roffmsg(void *arg, enum roffmsg lvl, |
roffmsg(void *arg, enum roffmsg lvl, |
const char *buf, const char *pos, char *msg) |
const char *buf, const char *pos, char *msg) |
Line 396 roffmsg(void *arg, enum roffmsg lvl, |
|
Line 449 roffmsg(void *arg, enum roffmsg lvl, |
|
} |
} |
|
|
if (pos) |
if (pos) |
(void)fprintf(stderr, "%s:%zu: %s: %s\n", |
(void)fprintf(stderr, "%s:%zu: %s: %s (column %zu)\n", |
p->rbuf->name, p->rbuf->line, level, msg); |
p->rbuf->name, p->rbuf->line, level, |
|
msg, pos - buf); |
else |
else |
(void)fprintf(stderr, "%s: %s: %s\n", |
(void)fprintf(stderr, "%s: %s: %s\n", |
p->rbuf->name, level, msg); |
p->rbuf->name, level, msg); |
Line 406 roffmsg(void *arg, enum roffmsg lvl, |
|
Line 460 roffmsg(void *arg, enum roffmsg lvl, |
|
|
|
|
|
static int |
static int |
roffdata(void *arg, char *buf) |
roffdata(void *arg, int space, char *buf) |
{ |
{ |
struct md_valid *p; |
struct md_valid *p; |
|
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
return(mbuf_data(p, buf)); |
return(mbuf_data(p, space, buf)); |
} |
} |