summaryrefslogtreecommitdiffstatshomepage
path: root/mdocml.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-02-20 07:43:15 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-02-20 07:43:15 +0000
commitc8d42afcb393f8cff8de9a02ec56bede23b8e05c (patch)
tree2239eeed9ede05840b0b55b35f31b7108a1649e7 /mdocml.c
parent06244c71f6b136a42451cafaf08d697f02b51bf1 (diff)
downloadmandoc-c8d42afcb393f8cff8de9a02ec56bede23b8e05c.tar.gz
mandoc-c8d42afcb393f8cff8de9a02ec56bede23b8e05c.tar.zst
mandoc-c8d42afcb393f8cff8de9a02ec56bede23b8e05c.zip
Removed tree-writing capability (for now, only validates and exits).
Diffstat (limited to 'mdocml.c')
-rw-r--r--mdocml.c222
1 files changed, 122 insertions, 100 deletions
diff --git a/mdocml.c b/mdocml.c
index 8d0433ab..84665dbb 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -1,4 +1,4 @@
- /* $Id: mdocml.c,v 1.50 2009/01/20 12:51:28 kristaps Exp $ */
+ /* $Id: mdocml.c,v 1.51 2009/02/20 07:43:15 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -30,15 +30,8 @@
#include "mdoc.h"
-#define xfprintf (void)fprintf
-
#define MD_LINE_SZ (256) /* Max input line size. */
-/* TODO: have a struct for each transformer. */
-
-typedef int (*mdocprint)(const struct mdoc_node *);
-
-
struct md_parse {
int warn; /* Warning flags. */
#define MD_WARN_SYNTAX (1 << 0) /* Show syntax warnings. */
@@ -49,17 +42,17 @@ struct md_parse {
struct mdoc *mdoc; /* Active parser. */
char *buf; /* Input buffer. */
u_long bufsz; /* Input buffer size. */
- char *name; /* Input file name. */
- int fd; /* Input file desc. */
- mdocprint print; /* Node-print function. */
+ char *in; /* Input file name. */
+ int fdin; /* Input file desc. */
};
extern char *__progname;
-extern int treeprint(const struct mdoc_node *);
-
static void usage(void);
+static int parse_opts(struct md_parse *, int, char *[]);
+static int parse_subopts(struct md_parse *, char *);
+
static int parse_begin(struct md_parse *);
static int parse_leave(struct md_parse *, int);
static int io_begin(struct md_parse *);
@@ -79,69 +72,12 @@ extern int getsubopt(char **, char *const *, char **);
int
main(int argc, char *argv[])
{
- int c;
struct md_parse parser;
- char *opts, *v, *filter;
-#define ALL 0
-#define COMPAT 1
-#define SYNTAX 2
-#define ERROR 3
- char *toks[] = { "all", "compat", "syntax",
- "error", NULL };
-
- extern char *optarg;
- extern int optind;
-
- filter = NULL;
(void)memset(&parser, 0, sizeof(struct md_parse));
- while (-1 != (c = getopt(argc, argv, "f:vW:")))
- switch (c) {
- case ('f'):
- filter = optarg;
- break;
- case ('v'):
- parser.dbg++;
- break;
- case ('W'):
- opts = optarg;
- while (*opts)
- switch (getsubopt(&opts, toks, &v)) {
- case (ALL):
- parser.warn |= MD_WARN_ALL;
- break;
- case (COMPAT):
- parser.warn |= MD_WARN_COMPAT;
- break;
- case (SYNTAX):
- parser.warn |= MD_WARN_SYNTAX;
- break;
- case (ERROR):
- parser.warn |= MD_WARN_ERR;
- break;
- default:
- usage();
- return(1);
- }
- break;
- default:
- usage();
- return(1);
- }
-
- argv += optind;
- argc -= optind;
-
- parser.name = "-";
- if (1 == argc)
- parser.name = *argv++;
-
- if (filter) {
- if (0 == strcmp(filter, "tree"))
- parser.print = treeprint;
- }
-
+ if ( ! parse_opts(&parser, argc, argv))
+ return(EXIT_FAILURE);
if ( ! io_begin(&parser))
return(EXIT_FAILURE);
@@ -153,11 +89,11 @@ static int
io_leave(struct md_parse *p, int code)
{
- if (-1 == p->fd || STDIN_FILENO == p->fd)
+ if (-1 == p->fdin || STDIN_FILENO == p->fdin)
return(code);
- if (-1 == close(p->fd)) {
- warn("%s", p->name);
+ if (-1 == close(p->fdin)) {
+ warn("%s", p->in);
code = 0;
}
return(code);
@@ -165,13 +101,82 @@ io_leave(struct md_parse *p, int code)
static int
+parse_subopts(struct md_parse *p, char *arg)
+{
+ char *v;
+ char *toks[] = { "all", "compat",
+ "syntax", "error", NULL };
+
+ /*
+ * Future -Wxxx levels and so on should be here. For now we
+ * only recognise syntax and compat warnings as categories,
+ * beyond the usually "all" and "error" (make warn error out).
+ */
+
+ while (*arg)
+ switch (getsubopt(&arg, toks, &v)) {
+ case (0):
+ p->warn |= MD_WARN_ALL;
+ break;
+ case (1):
+ p->warn |= MD_WARN_COMPAT;
+ break;
+ case (2):
+ p->warn |= MD_WARN_SYNTAX;
+ break;
+ case (3):
+ p->warn |= MD_WARN_ERR;
+ break;
+ default:
+ usage();
+ return(0);
+ }
+
+ return(1);
+}
+
+
+static int
+parse_opts(struct md_parse *p, int argc, char *argv[])
+{
+ int c;
+
+ extern char *optarg;
+ extern int optind;
+
+ p->in = "-";
+
+ while (-1 != (c = getopt(argc, argv, "vW:")))
+ switch (c) {
+ case ('v'):
+ p->dbg++;
+ break;
+ case ('W'):
+ if ( ! parse_subopts(p, optarg))
+ return(0);
+ break;
+ default:
+ usage();
+ return(0);
+ }
+
+ argv += optind;
+ if (0 == (argc -= optind))
+ return(1);
+
+ p->in = *argv++;
+ return(1);
+}
+
+
+static int
io_begin(struct md_parse *p)
{
- p->fd = STDIN_FILENO;
- if (0 != strncmp(p->name, "-", 1))
- if (-1 == (p->fd = open(p->name, O_RDONLY, 0))) {
- warn("%s", p->name);
+ p->fdin = STDIN_FILENO;
+ if (0 != strncmp(p->in, "-", 1))
+ if (-1 == (p->fdin = open(p->in, O_RDONLY, 0))) {
+ warn("%s", p->in);
return(io_leave(p, 0));
}
@@ -194,11 +199,17 @@ buf_begin(struct md_parse *p)
{
struct stat st;
- if (-1 == fstat(p->fd, &st)) {
- warn("%s", p->name);
- return(1);
+ if (-1 == fstat(p->fdin, &st)) {
+ warn("%s", p->in);
+ return(0);
}
+ /*
+ * Try to intuit the fastest way of sucking down buffered data
+ * by using either the block buffer size or the hard-coded one.
+ * This is inspired by bin/cat.c.
+ */
+
p->bufsz = MAX(st.st_blksize, BUFSIZ);
if (NULL == (p->buf = malloc(p->bufsz))) {
@@ -213,18 +224,22 @@ buf_begin(struct md_parse *p)
static int
parse_leave(struct md_parse *p, int code)
{
- const struct mdoc_node *n;
if (NULL == p->mdoc)
return(code);
if ( ! mdoc_endparse(p->mdoc))
code = 0;
- if (p->print && (n = mdoc_node(p->mdoc)))
- (*p->print)(n);
- mdoc_free(p->mdoc);
+#if 0
+ /* TODO */
+ if (code && ! mdoc_write(p->out, mdoc_node(p->mdoc))) {
+ warnx("%s: write error", p->out);
+ code = 0;
+ }
+#endif
+ mdoc_free(p->mdoc);
return(code);
}
@@ -245,9 +260,19 @@ parse_begin(struct md_parse *p)
if (NULL == (p->mdoc = mdoc_alloc(p, &cb)))
return(parse_leave(p, 0));
+ /*
+ * This is a little more complicated than fgets. TODO: have
+ * some benchmarks that show it's faster (note that I want to
+ * check many, many manuals simultaneously, so speed is
+ * important). Fill a buffer (sized to the block size) with a
+ * single read, then parse \n-terminated lines into a line
+ * buffer, which is passed to the parser. Hard-code the line
+ * buffer to a particular size -- a reasonable assumption.
+ */
+
for (lnn = 1, pos = 0; ; ) {
- if (-1 == (sz = read(p->fd, p->buf, p->bufsz))) {
- warn("%s", p->name);
+ if (-1 == (sz = read(p->fdin, p->buf, p->bufsz))) {
+ warn("%s", p->in);
return(parse_leave(p, 0));
} else if (0 == sz)
break;
@@ -258,8 +283,7 @@ parse_begin(struct md_parse *p)
line[(int)pos++] = p->buf[(int)i];
continue;
}
- warnx("%s: line %d too long",
- p->name, lnn);
+ warnx("%s: line %d too long", p->in, lnn);
return(parse_leave(p, 0));
}
@@ -283,8 +307,8 @@ msg_err(void *arg, int line, int col, const char *msg)
p = (struct md_parse *)arg;
- xfprintf(stderr, "%s:%d: error: %s (column %d)\n",
- p->name, line, msg, col);
+ warnx("%s:%d: error: %s (column %d)",
+ p->in, line, msg, col);
return(0);
}
@@ -299,8 +323,8 @@ msg_msg(void *arg, int line, int col, const char *msg)
if (0 == p->dbg)
return;
- xfprintf(stderr, "%s:%d: debug: %s (column %d)\n",
- p->name, line, msg, col);
+ warnx("%s:%d: debug: %s (column %d)",
+ p->in, line, msg, col);
}
@@ -323,14 +347,13 @@ msg_warn(void *arg, int line, int col,
return(1);
}
- xfprintf(stderr, "%s:%d: warning: %s (column %d)\n",
- p->name, line, msg, col);
+ warnx("%s:%d: warning: %s (column %d)",
+ p->in, line, msg, col);
if ( ! (p->warn & MD_WARN_ERR))
return(1);
- xfprintf(stderr, "%s: considering warnings as errors\n",
- __progname);
+ warnx("%s: considering warnings as errors", __progname);
return(0);
}
@@ -339,7 +362,6 @@ static void
usage(void)
{
- xfprintf(stderr, "usage: %s [-v] [-Wwarn...] [-ffilter] "
- "[infile]\n", __progname);
+ warnx("usage: %s [-v] [-Wwarn...] [infile]", __progname);
}