summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-02-23 07:09:13 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-02-23 07:09:13 +0000
commit63967ed8bf5ca40c3477ce83deda9051e813afd4 (patch)
tree61c0a4f1c37784718cf9b93f23bb2e604a69f63f
parentaa3451385251d0974ed07962c800a38fe4287a2b (diff)
downloadmandoc-63967ed8bf5ca40c3477ce83deda9051e813afd4.tar.gz
termact.c -> term.c
term.c -> mdocterm.c tree.c -> mdoctree.c Fixed/finished mmain.h.
-rw-r--r--Makefile17
-rw-r--r--mdocterm.c520
-rw-r--r--mdoctree.c127
-rw-r--r--mmain.c70
-rw-r--r--mmain.h10
-rw-r--r--termact.c1042
-rw-r--r--tree.c132
7 files changed, 657 insertions, 1261 deletions
diff --git a/Makefile b/Makefile
index 9277ff59..1ef89465 100644
--- a/Makefile
+++ b/Makefile
@@ -5,9 +5,9 @@ CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -g
LIBLNS = macro.ln mdoc.ln hash.ln strings.ln xstd.ln argv.ln \
validate.ln action.ln
-TREELNS = mdoctree.ln mmain.ln tree.ln
+TREELNS = mdoctree.ln mmain.ln
-TERMLNS = mdoctree.ln mmain.ln term.ln termact.ln
+TERMLNS = mdoctree.ln mmain.ln term.ln
LNS = $(LIBLNS) $(TREELNS) $(TERMLNS)
@@ -18,15 +18,14 @@ LIBS = libmdoc.a
LIBOBJS = macro.o mdoc.o hash.o strings.o xstd.o argv.o \
validate.o action.o
-TERMOBJS= mdocterm.o mmain.o term.o termact.o
+TERMOBJS= mdocterm.o mmain.o term.o
-TREEOBJS= mdoctree.o mmain.o tree.o
+TREEOBJS= mdoctree.o mmain.o
OBJS = $(LIBOBJS) $(TERMOBJS) $(TREEOBJS)
SRCS = macro.c mdoc.c hash.c strings.c xstd.c argv.c validate.c \
- action.c term.c tree.c termact.c mdoctree.c mdocterm.c \
- mmain.c
+ action.c term.c mdoctree.c mdocterm.c mmain.c
HEADS = mdoc.h private.h term.h mmain.h
@@ -140,15 +139,9 @@ uninstall:
macro.ln: macro.c private.h
macro.o: macro.c private.h
-tree.ln: tree.c mdoc.h
-tree.o: tree.c mdoc.h
-
term.ln: term.c term.h
term.o: term.c term.h
-termact.ln: termact.c term.h
-termact.o: termact.c term.h
-
strings.ln: strings.c private.h
strings.o: strings.c private.h
diff --git a/mdocterm.c b/mdocterm.c
index 33c147fc..7e1370ed 100644
--- a/mdocterm.c
+++ b/mdocterm.c
@@ -17,44 +17,538 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
+#include <ctype.h>
#include <err.h>
#include <getopt.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "mmain.h"
#include "term.h"
+enum termstyle {
+ STYLE_CLEAR,
+ STYLE_BOLD,
+ STYLE_UNDERLINE
+};
+
+static void body(struct termp *,
+ const struct mdoc_meta *,
+ const struct mdoc_node *);
+static void header(struct termp *,
+ const struct mdoc_meta *);
+static void footer(struct termp *,
+ const struct mdoc_meta *);
+
+static void pword(struct termp *, const char *, size_t);
+static void pescape(struct termp *,
+ const char *, size_t *, size_t);
+static void chara(struct termp *, char);
+static void style(struct termp *, enum termstyle);
+
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+#endif
+
+
int
main(int argc, char *argv[])
{
struct mmain *p;
const struct mdoc *mdoc;
- int c;
+ struct termp termp;
extern int optreset;
extern int optind;
p = mmain_alloc();
- if ( ! mmain_getopt(p, argc, argv, ""))
+ if ( ! mmain_getopt(p, argc, argv, NULL, NULL, NULL, NULL))
mmain_exit(p, 1);
- optreset = optind = 1;
-
- while (-1 != (c = getopt(argc, argv, "")))
- switch (c) {
- default:
- mmain_usage("");
- mmain_exit(p, 1);
- /* NOTREACHED */
- }
-
if (NULL == (mdoc = mmain_mdoc(p)))
mmain_exit(p, 1);
- termprint(mdoc_node(mdoc), mdoc_meta(mdoc));
+ termp.maxrmargin = 80; /* XXX */
+ termp.rmargin = termp.maxrmargin;
+ termp.maxcols = 1024;
+ termp.offset = termp.col = 0;
+ termp.flags = TERMP_NOSPACE;
+
+ if (NULL == (termp.buf = malloc(termp.maxcols)))
+ err(1, "malloc");
+
+ header(&termp, mdoc_meta(mdoc));
+ body(&termp, mdoc_meta(mdoc), mdoc_node(mdoc));
+ footer(&termp, mdoc_meta(mdoc));
+
+ free(termp.buf);
+
mmain_exit(p, 0);
/* NOTREACHED */
}
+void
+flushln(struct termp *p)
+{
+ size_t i, j, vsz, vis, maxvis;
+
+ /*
+ * First, establish the maximum columns of "visible" content.
+ * This is usually the difference between the right-margin and
+ * an indentation, but can be, for tagged lists or columns, a
+ * small set of values.
+ */
+
+ assert(p->offset < p->rmargin);
+ maxvis = p->rmargin - p->offset;
+ vis = 0;
+
+ /*
+ * If in the standard case (left-justified), then begin with our
+ * indentation, otherwise (columns, etc.) just start spitting
+ * out text.
+ */
+
+ if ( ! (p->flags & TERMP_NOLPAD))
+ /* LINTED */
+ for (j = 0; j < p->offset; j++)
+ putchar(' ');
+
+ /*
+ * If we're literal, print out verbatim.
+ */
+ if (p->flags & TERMP_LITERAL) {
+ /* FIXME: count non-printing chars. */
+ for (i = 0; i < p->col; i++)
+ putchar(p->buf[i]);
+ putchar('\n');
+ p->col = 0;
+ return;
+ }
+
+ for (i = 0; i < p->col; i++) {
+ /*
+ * Count up visible word characters. Control sequences
+ * (starting with the CSI) aren't counted.
+ */
+ assert( ! isspace(p->buf[i]));
+
+ /* LINTED */
+ for (j = i, vsz = 0; j < p->col; j++) {
+ if (isspace(p->buf[j]))
+ break;
+ else if (27 == p->buf[j]) {
+ assert(j + 4 <= p->col);
+ j += 3;
+ } else
+ vsz++;
+ }
+ assert(vsz > 0);
+
+ /*
+ * If a word is too long and we're within a line, put it
+ * on the next line. Puke if we're being asked to write
+ * something that will exceed the right margin (i.e.,
+ * from a fresh line or when we're not allowed to break
+ * the line with TERMP_NOBREAK).
+ */
+
+ if (vis && vis + vsz >= maxvis) {
+ /* FIXME */
+ if (p->flags & TERMP_NOBREAK)
+ errx(1, "word breaks right margin");
+ putchar('\n');
+ for (j = 0; j < p->offset; j++)
+ putchar(' ');
+ vis = 0;
+ } else if (vis + vsz >= maxvis) {
+ /* FIXME */
+ errx(1, "word breaks right margin");
+ }
+
+ /*
+ * Write out the word and a trailing space. Omit the
+ * space if we're the last word in the line.
+ */
+
+ for ( ; i < p->col; i++) {
+ if (isspace(p->buf[i]))
+ break;
+ putchar(p->buf[i]);
+ }
+ vis += vsz;
+ if (i < p->col) {
+ putchar(' ');
+ vis++;
+ }
+ }
+
+ /*
+ * If we're not to right-marginalise it (newline), then instead
+ * pad to the right margin and stay off.
+ */
+
+ if (p->flags & TERMP_NOBREAK) {
+ for ( ; vis <= maxvis; vis++)
+ putchar(' ');
+ } else
+ putchar('\n');
+
+ p->col = 0;
+}
+
+
+void
+newln(struct termp *p)
+{
+
+ /*
+ * A newline only breaks an existing line; it won't assert
+ * vertical space.
+ */
+ p->flags |= TERMP_NOSPACE;
+ if (0 == p->col)
+ return;
+ flushln(p);
+}
+
+
+void
+vspace(struct termp *p)
+{
+
+ /*
+ * Asserts a vertical space (a full, empty line-break between
+ * lines).
+ */
+ newln(p);
+ putchar('\n');
+}
+
+
+static void
+chara(struct termp *p, char c)
+{
+
+ /* TODO: dynamically expand the buffer. */
+ if (p->col + 1 >= p->maxcols)
+ errx(1, "line overrun");
+ p->buf[(p->col)++] = c;
+}
+
+
+static void
+style(struct termp *p, enum termstyle esc)
+{
+
+ if (p->col + 4 >= p->maxcols)
+ errx(1, "line overrun");
+
+ p->buf[(p->col)++] = 27;
+ p->buf[(p->col)++] = '[';
+ switch (esc) {
+ case (STYLE_CLEAR):
+ p->buf[(p->col)++] = '0';
+ break;
+ case (STYLE_BOLD):
+ p->buf[(p->col)++] = '1';
+ break;
+ case (STYLE_UNDERLINE):
+ p->buf[(p->col)++] = '4';
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ p->buf[(p->col)++] = 'm';
+}
+
+
+static void
+pescape(struct termp *p, const char *word, size_t *i, size_t len)
+{
+
+ (*i)++;
+ assert(*i < len);
+
+ if ('(' == word[*i]) {
+ /* Two-character escapes. */
+ (*i)++;
+ assert(*i + 1 < len);
+
+ if ('r' == word[*i] && 'B' == word[*i + 1])
+ chara(p, ']');
+ else if ('l' == word[*i] && 'B' == word[*i + 1])
+ chara(p, '[');
+
+ (*i)++;
+ return;
+
+ } else if ('[' != word[*i]) {
+ /* One-character escapes. */
+ switch (word[*i]) {
+ case ('\\'):
+ /* FALLTHROUGH */
+ case ('\''):
+ /* FALLTHROUGH */
+ case ('`'):
+ /* FALLTHROUGH */
+ case ('-'):
+ /* FALLTHROUGH */
+ case ('.'):
+ chara(p, word[*i]);
+ default:
+ break;
+ }
+ return;
+ }
+ /* n-character escapes. */
+}
+
+
+static void
+pword(struct termp *p, const char *word, size_t len)
+{
+ size_t i;
+
+ /*assert(len > 0);*/ /* Can be, if literal. */
+
+ if ( ! (p->flags & TERMP_NOSPACE) &&
+ ! (p->flags & TERMP_LITERAL))
+ chara(p, ' ');
+
+ p->flags &= ~TERMP_NOSPACE;
+
+ if (p->flags & TERMP_BOLD)
+ style(p, STYLE_BOLD);
+ if (p->flags & TERMP_UNDERLINE)
+ style(p, STYLE_UNDERLINE);
+
+ for (i = 0; i < len; i++) {
+ if ('\\' == word[i]) {
+ pescape(p, word, &i, len);
+ continue;
+ }
+ chara(p, word[i]);
+ }
+
+ if (p->flags & TERMP_BOLD ||
+ p->flags & TERMP_UNDERLINE)
+ style(p, STYLE_CLEAR);
+}
+
+
+void
+word(struct termp *p, const char *word)
+{
+ size_t i, j, len;
+
+ if (p->flags & TERMP_LITERAL) {
+ pword(p, word, strlen(word));
+ return;
+ }
+
+ len = strlen(word);
+ assert(len > 0);
+
+ if (mdoc_isdelim(word)) {
+ if ( ! (p->flags & TERMP_IGNDELIM))
+ p->flags |= TERMP_NOSPACE;
+ p->flags &= ~TERMP_IGNDELIM;
+ }
+
+ /* LINTED */
+ for (j = i = 0; i < len; i++) {
+ if ( ! isspace(word[i])) {
+ j++;
+ continue;
+ }
+ if (0 == j)
+ continue;
+ assert(i >= j);
+ pword(p, &word[i - j], j);
+ j = 0;
+ }
+ if (j > 0) {
+ assert(i >= j);
+ pword(p, &word[i - j], j);
+ }
+}
+
+
+static void
+body(struct termp *p, const struct mdoc_meta *meta,
+ const struct mdoc_node *node)
+{
+ int dochild;
+
+ /* Pre-processing. */
+
+ dochild = 1;
+
+ if (MDOC_TEXT != node->type) {
+ if (termacts[node->tok].pre)
+ if ( ! (*termacts[node->tok].pre)(p, meta, node))
+ dochild = 0;
+ } else /* MDOC_TEXT == node->type */
+ word(p, node->data.text.string);
+
+ /* Children. */
+
+ if (dochild && node->child)
+ body(p, meta, node->child);
+
+ /* Post-processing. */
+
+ if (MDOC_TEXT != node->type)
+ if (termacts[node->tok].post)
+ (*termacts[node->tok].post)(p, meta, node);
+
+ /* Siblings. */
+
+ if (node->next)
+ body(p, meta, node->next);
+}
+
+
+static void
+footer(struct termp *p, const struct mdoc_meta *meta)
+{
+ struct tm *tm;
+ char *buf, *os;
+ size_t sz, osz, ssz, i;
+
+ if (NULL == (buf = malloc(p->rmargin)))
+ err(1, "malloc");
+ if (NULL == (os = malloc(p->rmargin)))
+ err(1, "malloc");
+
+ tm = localtime(&meta->date);
+
+#ifdef __linux__
+ if (0 == strftime(buf, p->rmargin, "%B %d, %Y", tm))
+#else
+ if (NULL == strftime(buf, p->rmargin, "%B %d, %Y", tm))
+#endif
+ err(1, "strftime");
+
+ osz = strlcpy(os, meta->os, p->rmargin);
+
+ sz = strlen(buf);
+ ssz = sz + osz + 1;
+
+ if (ssz > p->rmargin) {
+ ssz -= p->rmargin;
+ assert(ssz <= osz);
+ os[osz - ssz] = 0;
+ ssz = 1;
+ } else
+ ssz = p->rmargin - ssz + 1;
+
+ printf("\n");
+ printf("%s", os);
+ for (i = 0; i < ssz; i++)
+ printf(" ");
+
+ printf("%s\n", buf);
+ fflush(stdout);
+
+ free(buf);
+ free(os);
+}
+
+
+static void
+header(struct termp *p, const struct mdoc_meta *meta)
+{
+ char *buf, *title;
+ const char *pp, *msec;
+ size_t ssz, tsz, ttsz, i;;
+
+ if (NULL == (buf = malloc(p->rmargin)))
+ err(1, "malloc");
+ if (NULL == (title = malloc(p->rmargin)))
+ err(1, "malloc");
+
+ if (NULL == (pp = mdoc_vol2a(meta->vol)))
+ switch (meta->msec) {
+ case (MSEC_1):
+ /* FALLTHROUGH */
+ case (MSEC_6):
+ /* FALLTHROUGH */
+ case (MSEC_7):
+ pp = mdoc_vol2a(VOL_URM);
+ break;
+ case (MSEC_8):
+ pp = mdoc_vol2a(VOL_SMM);
+ break;
+ case (MSEC_2):
+ /* FALLTHROUGH */
+ case (MSEC_3):
+ /* FALLTHROUGH */
+ case (MSEC_4):
+ /* FALLTHROUGH */
+ case (MSEC_5):
+ pp = mdoc_vol2a(VOL_PRM);
+ break;
+ case (MSEC_9):
+ pp = mdoc_vol2a(VOL_KM);
+ break;
+ default:
+ /* FIXME: capitalise. */
+ if (NULL == (pp = mdoc_msec2a(meta->msec)))
+ pp = mdoc_msec2a(MSEC_local);
+ break;
+ }
+ assert(pp);
+
+ tsz = strlcpy(buf, pp, p->rmargin);
+ assert(tsz < p->rmargin);
+
+ if ((pp = mdoc_arch2a(meta->arch))) {
+ tsz = strlcat(buf, " (", p->rmargin);
+ assert(tsz < p->rmargin);
+ tsz = strlcat(buf, pp, p->rmargin);
+ assert(tsz < p->rmargin);
+ tsz = strlcat(buf, ")", p->rmargin);
+ assert(tsz < p->rmargin);
+ }
+
+ ttsz = strlcpy(title, meta->title, p->rmargin);
+
+ if (NULL == (msec = mdoc_msec2a(meta->msec)))
+ msec = "";
+
+ ssz = (2 * (ttsz + 2 + strlen(msec))) + tsz + 2;
+
+ if (ssz > p->rmargin) {
+ if ((ssz -= p->rmargin) % 2)
+ ssz++;
+ ssz /= 2;
+
+ assert(ssz <= ttsz);
+ title[ttsz - ssz] = 0;
+ ssz = 1;
+ } else
+ ssz = ((p->rmargin - ssz) / 2) + 1;
+
+ printf("%s(%s)", title, msec);
+
+ for (i = 0; i < ssz; i++)
+ printf(" ");
+
+ printf("%s", buf);
+
+ for (i = 0; i < ssz; i++)
+ printf(" ");
+
+ printf("%s(%s)\n", title, msec);
+ fflush(stdout);
+
+ free(title);
+ free(buf);
+}
diff --git a/mdoctree.c b/mdoctree.c
index 1b72ee25..eff84633 100644
--- a/mdoctree.c
+++ b/mdoctree.c
@@ -19,55 +19,130 @@
#include <assert.h>
#include <err.h>
#include <getopt.h>
+#include <stdio.h>
#include <stdlib.h>
#include "mmain.h"
-extern void treeprint(const struct mdoc_node *,
- const struct mdoc_meta *);
+#define xprintf (void)printf
+
+static void doprint(const struct mdoc_node *, int);
int
main(int argc, char *argv[])
{
struct mmain *p;
const struct mdoc *mdoc;
- int c;
extern int optreset;
extern int optind;
p = mmain_alloc();
- if ( ! mmain_getopt(p, argc, argv, NULL))
+ if ( ! mmain_getopt(p, argc, argv, NULL, NULL, NULL, NULL))
mmain_exit(p, 1);
- optreset = optind = 1;
- printf("here\n");
-
- while (-1 != (c = getopt(argc, argv, "f:")))
- switch (c) {
- case ('f'):
- printf("%s\n", optarg);
- break;
- case ('?'):
- if (mmain_isopt(optopt)) {
- printf("ok: %d\n", optopt);
- break;
- }
- printf("bad: %d\n", optopt);
- /* FALLTHROUGH */
- default:
- mmain_usage(NULL);
- mmain_exit(p, 1);
- /* NOTREACHED */
- }
-
if (NULL == (mdoc = mmain_mdoc(p)))
mmain_exit(p, 1);
- treeprint(mdoc_node(mdoc), mdoc_meta(mdoc));
+ doprint(mdoc_node(mdoc), 0);
mmain_exit(p, 0);
/* NOTREACHED */
}
+static void
+doprint(const struct mdoc_node *n, int indent)
+{
+ const char *p, *t;
+ int i, j;
+ size_t argc, sz;
+ char **params;
+ struct mdoc_arg *argv;
+
+ argv = NULL;
+ argc = sz = 0;
+ params = NULL;
+
+ switch (n->type) {
+ case (MDOC_ROOT):
+ t = "root";
+ break;
+ case (MDOC_BLOCK):
+ t = "block";
+ break;
+ case (MDOC_HEAD):
+ t = "block-head";
+ break;
+ case (MDOC_BODY):
+ t = "block-body";
+ break;
+ case (MDOC_TAIL):
+ t = "block-tail";
+ break;
+ case (MDOC_ELEM):
+ t = "elem";
+ break;
+ case (MDOC_TEXT):
+ t = "text";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ switch (n->type) {
+ case (MDOC_TEXT):
+ p = n->data.text.string;
+ break;
+ case (MDOC_BODY):
+ p = mdoc_macronames[n->tok];
+ break;
+ case (MDOC_HEAD):
+ p = mdoc_macronames[n->tok];
+ break;
+ case (MDOC_TAIL):
+ p = mdoc_macronames[n->tok];
+ break;
+ case (MDOC_ELEM):
+ p = mdoc_macronames[n->tok];
+ argv = n->data.elem.argv;
+ argc = n->data.elem.argc;
+ break;
+ case (MDOC_BLOCK):
+ p = mdoc_macronames[n->tok];
+ argv = n->data.block.argv;
+ argc = n->data.block.argc;
+ break;
+ case (MDOC_ROOT):
+ p = "root";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ for (i = 0; i < indent; i++)
+ xprintf(" ");
+ xprintf("%s (%s)", p, t);
+
+ for (i = 0; i < (int)argc; i++) {
+ xprintf(" -%s", mdoc_argnames[argv[i].arg]);
+ if (argv[i].sz > 0)
+ xprintf(" [");
+ for (j = 0; j < (int)argv[i].sz; j++)
+ xprintf(" [%s]", argv[i].value[j]);
+ if (argv[i].sz > 0)
+ xprintf(" ]");
+ }
+
+ for (i = 0; i < (int)sz; i++)
+ xprintf(" [%s]", params[i]);
+
+ xprintf(" %d:%d\n", n->line, n->pos);
+
+ if (n->child)
+ doprint(n->child, indent + 1);
+ if (n->next)
+ doprint(n->next, indent);
+}
diff --git a/mmain.c b/mmain.c
index 38f5ab81..b652b5c1 100644
--- a/mmain.c
+++ b/mmain.c
@@ -42,7 +42,7 @@ struct mmain {
struct mdoc *mdoc; /* Active parser. */
char *buf; /* Input buffer. */
u_long bufsz; /* Input buffer size. */
- char in[MAXPATHLEN]; /* Input file name. */
+ char *in; /* Input file name. */
int fdin; /* Input file desc. */
};
@@ -60,6 +60,9 @@ extern int getsubopt(char **, char *const *, char **);
#endif
+/*
+ * Print our and our caller's usage message.
+ */
void
mmain_usage(const char *help)
{
@@ -69,6 +72,9 @@ mmain_usage(const char *help)
}
+/*
+ * Allocate the convenience library and initialise some values.
+ */
struct mmain *
mmain_alloc(void)
{
@@ -77,36 +83,41 @@ mmain_alloc(void)
if (NULL == (p = calloc(1, sizeof(struct mmain))))
err(1, "malloc");
- (void)strlcpy(p->in, "-", MAXPATHLEN);
+ p->in = "-";
p->fdin = STDIN_FILENO;
return(p);
}
+/*
+ * Parse command-line options. Accepts a small (<28 char) opstring "u"
+ * parameter (e.g. "ho:") or NULL, a corresponding "help" string (e.g.
+ * "[-h] [-o output]" or NULL, a callback function for parsed arguments
+ * and an opaque pointer argument for that function.
+ */
int
-mmain_isopt(int c)
+mmain_getopt(struct mmain *p, int argc, char *argv[],
+ const char *help, const char *u, void *arg,
+ int (*getopt_cb)(void *, int, const char *))
{
-
- switch (c) {
- case ('v'):
- /* FALLTHROUGH */
- case ('W'):
- return(1);
- default:
- break;
- }
- return(0);
-}
+ int c;
+ char opts[32]; /* XXX */
+ size_t sz;
+ extern int optind;
+ extern int optreset;
-int
-mmain_getopt(struct mmain *p, int argc,
- char *argv[], const char *help)
-{
- int c;
+ sz = strlcpy(opts, "vW:", 32);
+ assert(sz < 32);
+
+ if (u) {
+ sz = strlcat(opts, u, 32);
+ assert(sz < 32);
+ }
- while (-1 != (c = getopt(argc, argv, ":vW:")))
+ /* LINTED */
+ while (-1 != (c = getopt(argc, argv, opts)))
switch (c) {
case ('v'):
p->dbg++;
@@ -116,23 +127,20 @@ mmain_getopt(struct mmain *p, int argc,
return(0);
break;
case ('?'):
- break;
- default:
mmain_usage(help);
return(0);
+ default:
+ assert(getopt_cb);
+ if ((*getopt_cb)(arg, c, optarg))
+ break;
+ return(0);
}
argv += optind;
- argc -= optind;
+ if ((argc -= optind) > 0)
+ p->in = *argv++;
- if (0 == argc)
- return(1);
-
- if (strlcpy(p->in, *argv++, MAXPATHLEN) < MAXPATHLEN)
- return(1);
-
- warnx("filename too long");
- return(0);
+ return(1);
}
diff --git a/mmain.h b/mmain.h
index 6cb6ea39..99206279 100644
--- a/mmain.h
+++ b/mmain.h
@@ -22,8 +22,8 @@
/*
* This is a convenience library for utilities implementing mdoc(3)
* accepting a similar set of command-line patterns. mmain handles
- * error reporting (to the terminal), preparing and reading the input
- * file, and enacting the parse itself.
+ * error reporting (to the terminal), command-line parsing, preparing
+ * and reading the input file, and enacting the parse itself.
*/
#include "mdoc.h"
@@ -34,9 +34,9 @@ struct mmain;
struct mmain *mmain_alloc(void);
__dead void mmain_exit(struct mmain *, int);
-int mmain_getopt(struct mmain *, int,
- char *[], const char *);
-int mmain_isopt(int);
+int mmain_getopt(struct mmain *, int, char *[],
+ const char *, const char *, void *,
+ int (*)(void *, int, const char *));
struct mdoc *mmain_mdoc(struct mmain *);
void mmain_usage(const char *);
diff --git a/termact.c b/termact.c
deleted file mode 100644
index ec4fa099..00000000
--- a/termact.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "term.h"
-
-#define INDENT 4
-
-/*
- * Performs actions on nodes of the abstract syntax tree. Both pre- and
- * post-fix operations are defined here.
- */
-
-#define TTYPE_PROG 0
-#define TTYPE_CMD_FLAG 1
-#define TTYPE_CMD_ARG 2
-#define TTYPE_SECTION 3
-#define TTYPE_FUNC_DECL 4
-#define TTYPE_VAR_DECL 5
-#define TTYPE_FUNC_TYPE 6
-#define TTYPE_FUNC_NAME 7
-#define TTYPE_FUNC_ARG 8
-#define TTYPE_LINK 9
-#define TTYPE_NMAX 10
-
-/*
- * These define "styles" for element types, like command arguments or
- * executable names. This is useful when multiple macros must decorate
- * the same thing (like .Ex -std cmd and .Nm cmd).
- */
-
-const int ttypes[TTYPE_NMAX] = {
- TERMP_BOLD, /* TTYPE_PROG */
- TERMP_BOLD, /* TTYPE_CMD_FLAG */
- TERMP_UNDERLINE, /* TTYPE_CMD_ARG */
- TERMP_BOLD, /* TTYPE_SECTION */
- TERMP_BOLD, /* TTYPE_FUNC_DECL */
- TERMP_UNDERLINE, /* TTYPE_VAR_DECL */
- TERMP_UNDERLINE, /* TTYPE_FUNC_TYPE */
- TERMP_BOLD, /* TTYPE_FUNC_NAME */
- TERMP_UNDERLINE, /* TTYPE_FUNC_ARG */
- TERMP_UNDERLINE /* TTYPE_LINK */
-};
-
-static int arg_hasattr(int, size_t,
- const struct mdoc_arg *);
-static int arg_getattr(int, size_t,
- const struct mdoc_arg *);
-static size_t arg_offset(const char *);
-
-/*
- * What follows describes prefix and postfix operations for the abstract
- * syntax tree descent.
- */
-
-#define DECL_ARGS \
- struct termp *p, \
- const struct mdoc_meta *meta, \
- const struct mdoc_node *node
-
-#define DECL_PRE(name) \
-static int name##_pre(DECL_ARGS)
-#define DECL_POST(name) \
-static void name##_post(DECL_ARGS)
-
-DECL_PRE(termp_aq);
-DECL_PRE(termp_ar);
-DECL_PRE(termp_bd);
-DECL_PRE(termp_d1);
-DECL_PRE(termp_dq);
-DECL_PRE(termp_ex);
-DECL_PRE(termp_fa);
-DECL_PRE(termp_fd);
-DECL_PRE(termp_fl);
-DECL_PRE(termp_fn);
-DECL_PRE(termp_ft);
-DECL_PRE(termp_it);
-DECL_PRE(termp_nd);
-DECL_PRE(termp_nm);
-DECL_PRE(termp_ns);
-DECL_PRE(termp_nx);
-DECL_PRE(termp_op);
-DECL_PRE(termp_ox);
-DECL_PRE(termp_pf);
-DECL_PRE(termp_pp);
-DECL_PRE(termp_qq);
-DECL_PRE(termp_sh);
-DECL_PRE(termp_sq);
-DECL_PRE(termp_sx);
-DECL_PRE(termp_ud);
-DECL_PRE(termp_va);
-DECL_PRE(termp_vt);
-DECL_PRE(termp_xr);
-
-DECL_POST(termp_aq);
-DECL_POST(termp_ar);
-DECL_POST(termp_bl);
-DECL_POST(termp_d1);
-DECL_POST(termp_dq);
-DECL_POST(termp_fa);
-DECL_POST(termp_fd);
-DECL_POST(termp_fl);
-DECL_POST(termp_fn);
-DECL_POST(termp_ft);
-DECL_POST(termp_it);
-DECL_POST(termp_nm);
-DECL_POST(termp_op);
-DECL_POST(termp_pf);
-DECL_POST(termp_qq);
-DECL_POST(termp_sh);
-DECL_POST(termp_sq);
-DECL_POST(termp_sx);
-DECL_POST(termp_va);
-DECL_POST(termp_vt);
-
-const struct termact __termacts[MDOC_MAX] = {
- { NULL, NULL }, /* \" */
- { NULL, NULL }, /* Dd */
- { NULL, NULL }, /* Dt */
- { NULL, NULL }, /* Os */
- { termp_sh_pre, termp_sh_post }, /* Sh */
- { NULL, NULL }, /* Ss */
- { termp_pp_pre, NULL }, /* Pp */
- { termp_d1_pre, termp_d1_post }, /* D1 */
- { NULL, NULL }, /* Dl */
- { termp_bd_pre, NULL }, /* Bd */
- { NULL, NULL }, /* Ed */
- { NULL, termp_bl_post }, /* Bl */
- { NULL, NULL }, /* El */
- { termp_it_pre, termp_it_post }, /* It */
- { NULL, NULL }, /* Ad */
- { NULL, NULL }, /* An */
- { termp_ar_pre, termp_ar_post }, /* Ar */
- { NULL, NULL }, /* Cd */
- { NULL, NULL }, /* Cm */
- { NULL, NULL }, /* Dv */
- { NULL, NULL }, /* Er */
- { NULL, NULL }, /* Ev */
- { termp_ex_pre, NULL }, /* Ex */
- { termp_fa_pre, termp_fa_post }, /* Fa */
- { termp_fd_pre, termp_fd_post }, /* Fd */
- { termp_fl_pre, termp_fl_post }, /* Fl */
- { termp_fn_pre, termp_fn_post }, /* Fn */
- { termp_ft_pre, termp_ft_post }, /* Ft */
- { NULL, NULL }, /* Ic */
- { NULL, NULL }, /* In */
- { NULL, NULL }, /* Li */
- { termp_nd_pre, NULL }, /* Nd */
- { termp_nm_pre, termp_nm_post }, /* Nm */
- { termp_op_pre, termp_op_post }, /* Op */
- { NULL, NULL }, /* Ot */
- { NULL, NULL }, /* Pa */
- { NULL, NULL }, /* Rv */
- { NULL, NULL }, /* St */
- { termp_va_pre, termp_va_post }, /* Va */
- { termp_vt_pre, termp_vt_post }, /* Vt */
- { termp_xr_pre, NULL }, /* Xr */
- { NULL, NULL }, /* %A */
- { NULL, NULL }, /* %B */
- { NULL, NULL }, /* %D */
- { NULL, NULL }, /* %I */
- { NULL, NULL }, /* %J */
- { NULL, NULL }, /* %N */
- { NULL, NULL }, /* %O */
- { NULL, NULL }, /* %P */
- { NULL, NULL }, /* %R */
- { NULL, NULL }, /* %T */
- { NULL, NULL }, /* %V */
- { NULL, NULL }, /* Ac */
- { NULL, NULL }, /* Ao */
- { termp_aq_pre, termp_aq_post }, /* Aq */
- { NULL, NULL }, /* At */
- { NULL, NULL }, /* Bc */
- { NULL, NULL }, /* Bf */
- { NULL, NULL }, /* Bo */
- { NULL, NULL }, /* Bq */
- { NULL, NULL }, /* Bsx */
- { NULL, NULL }, /* Bx */
- { NULL, NULL }, /* Db */
- { NULL, NULL }, /* Dc */
- { NULL, NULL }, /* Do */
- { termp_dq_pre, termp_dq_post }, /* Dq */
- { NULL, NULL }, /* Ec */
- { NULL, NULL }, /* Ef */
- { NULL, NULL }, /* Em */
- { NULL, NULL }, /* Eo */
- { NULL, NULL }, /* Fx */
- { NULL, NULL }, /* Ms */
- { NULL, NULL }, /* No */
- { termp_ns_pre, NULL }, /* Ns */
- { termp_nx_pre, NULL }, /* Nx */
- { termp_ox_pre, NULL }, /* Ox */
- { NULL, NULL }, /* Pc */
- { termp_pf_pre, termp_pf_post }, /* Pf */
- { NULL, NULL }, /* Po */
- { NULL, NULL }, /* Pq */
- { NULL, NULL }, /* Qc */
- { NULL, NULL }, /* Ql */
- { NULL, NULL }, /* Qo */
- { termp_qq_pre, termp_qq_post }, /* Qq */
- { NULL, NULL }, /* Re */
- { NULL, NULL }, /* Rs */
- { NULL, NULL }, /* Sc */
- { NULL, NULL }, /* So */
- { termp_sq_pre, termp_sq_post }, /* Sq */
- { NULL, NULL }, /* Sm */
- { termp_sx_pre, termp_sx_post }, /* Sx */
- { NULL, NULL }, /* Sy */
- { NULL, NULL }, /* Tn */
- { NULL, NULL }, /* Ux */
- { NULL, NULL }, /* Xc */
- { NULL, NULL }, /* Xo */
- { NULL, NULL }, /* Fo */
- { NULL, NULL }, /* Fc */
- { NULL, NULL }, /* Oo */
- { NULL, NULL }, /* Oc */
- { NULL, NULL }, /* Bk */
- { NULL, NULL }, /* Ek */
- { NULL, NULL }, /* Bt */
- { NULL, NULL }, /* Hf */
- { NULL, NULL }, /* Fr */
- { termp_ud_pre, NULL }, /* Ud */
-};
-
-const struct termact *termacts = __termacts;
-
-
-static size_t
-arg_offset(const char *v)
-{
- if (0 == strcmp(v, "indent"))
- return(INDENT);
- if (0 == strcmp(v, "indent-two"))
- return(INDENT * 2);
-
- /* TODO */
- return(0);
-}
-
-
-static int
-arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
-{
-
- return(-1 != arg_getattr(arg, argc, argv));
-}
-
-
-static int
-arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
-{
- int i;
-
- for (i = 0; i < (int)argc; i++)
- if (argv[i].arg == arg)
- return(i);
- return(-1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_dq_pre(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return(1);
-
- word(p, "``");
- p->flags |= TERMP_NOSPACE;
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_dq_post(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return;
-
- p->flags |= TERMP_NOSPACE;
- word(p, "''");
-}
-
-
-/* ARGSUSED */
-static void
-termp_it_post(DECL_ARGS)
-{
- const struct mdoc_node *n, *it;
- const struct mdoc_block *bl;
- int i;
- size_t width;
-
- /*
- * This (and termp_it_pre()) are the most complicated functions
- * here. They must account for a considerable number of
- * switches that completely change the output behaviour, like
- * -tag versus -column. Yech.
- */
-
- switch (node->type) {
- case (MDOC_BODY):
- /* FALLTHROUGH */
- case (MDOC_HEAD):
- break;
- default:
- return;
- }
-
- it = node->parent;
- assert(MDOC_BLOCK == it->type);
- assert(MDOC_It == it->tok);
-
- n = it->parent;
- assert(MDOC_BODY == n->type);
- assert(MDOC_Bl == n->tok);
- n = n->parent;
- bl = &n->data.block;
-
- /* If `-tag', adjust our margins accordingly. */
-
- if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
- i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
- assert(i >= 0);
- assert(1 == bl->argv[i].sz);
- width = strlen(*bl->argv[i].value); /* XXX */
-
- if (MDOC_HEAD == node->type) {
- flushln(p);
- /* FIXME: nested lists. */
- p->rmargin = p->maxrmargin;
- p->flags &= ~TERMP_NOBREAK;
- } else {
- flushln(p);
- p->offset -= width + 1;
- p->flags &= ~TERMP_NOLPAD;
- }
- return;
- }
-
- if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
- i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
- assert(i >= 0);
- assert(1 == bl->argv[i].sz);
- width = arg_offset(*bl->argv[i].value);
-
- flushln(p);
- p->offset -= width + 1;
- return;
- }
-}
-
-
-/* ARGSUSED */
-static int
-termp_it_pre(DECL_ARGS)
-{
- const struct mdoc_node *n, *it;
- const struct mdoc_block *bl;
- int i;
- size_t width;
-
- /*
- * Also see termp_it_post() for general comments.
- */
-
- switch (node->type) {
- case (MDOC_BODY):
- /* FALLTHROUGH */
- case (MDOC_HEAD):
- it = node->parent;
- break;
- case (MDOC_BLOCK):
- it = node;
- break;
- default:
- return(1);
- }
-
- assert(MDOC_BLOCK == it->type);
- assert(MDOC_It == it->tok);
-
- n = it->parent;
- assert(MDOC_BODY == n->type);
- assert(MDOC_Bl == n->tok);
- n = n->parent;
- bl = &n->data.block;
-
- /* If `-compact', don't assert vertical space. */
-
- if (MDOC_BLOCK == node->type) {
- if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
- newln(p);
- else
- vspace(p);
- return(1);
- }
-
- assert(MDOC_HEAD == node->type
- || MDOC_BODY == node->type);
-
- /* If `-tag', adjust our margins accordingly. */
-
- if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
- i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
- assert(i >= 0); /* XXX */
- assert(1 == bl->argv[i].sz);
- width = strlen(*bl->argv[i].value); /* XXX */
-
- /* FIXME: nested lists. */
-
- if (MDOC_HEAD == node->type) {
- p->flags |= TERMP_NOBREAK;
- p->flags |= TERMP_NOSPACE;
- p->rmargin = p->offset + width;
- } else {
- p->flags |= TERMP_NOSPACE;
- p->flags |= TERMP_NOLPAD;
- p->offset += width + 1;
- }
- return(1);
- }
-
- /* If `-ohang', adjust left-margin. */
-
- if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
- i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
- assert(i >= 0);
- assert(1 == bl->argv[i].sz);
- width = arg_offset(*bl->argv[i].value);
-
- p->flags |= TERMP_NOSPACE;
- p->offset += width + 1;
- return(1);
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_nm_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_PROG];
-}
-
-
-/* ARGSUSED */
-static void
-termp_fl_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_CMD_FLAG];
-}
-
-
-/* ARGSUSED */
-static int
-termp_ar_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_CMD_ARG];
- if (NULL == node->child)
- word(p, "...");
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_nm_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_PROG];
- if (NULL == node->child)
- word(p, meta->name);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_ns_pre(DECL_ARGS)
-{
-
- p->flags |= TERMP_NOSPACE;
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_pp_pre(DECL_ARGS)
-{
-
- vspace(p);
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_ar_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_CMD_ARG];
-}
-
-
-/* ARGSUSED */
-static int
-termp_ex_pre(DECL_ARGS)
-{
- int i;
-
- i = arg_getattr(MDOC_Std, node->data.elem.argc,
- node->data.elem.argv);
- assert(i >= 0);
-
- word(p, "The");
- p->flags |= ttypes[TTYPE_PROG];
- word(p, *node->data.elem.argv[i].value);
- p->flags &= ~ttypes[TTYPE_PROG];
- word(p, "utility exits 0 on success, and >0 if an error occurs.");
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_nd_pre(DECL_ARGS)
-{
-
- word(p, "\\-");
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_bl_post(DECL_ARGS)
-{
-
- if (MDOC_BLOCK == node->type)
- newln(p);
-}
-
-
-/* ARGSUSED */
-static void
-termp_op_post(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return;
- p->flags |= TERMP_NOSPACE;
- word(p, "\\(rB");
-}
-
-
-/* ARGSUSED */
-static void
-termp_sh_post(DECL_ARGS)
-{
-
- switch (node->type) {
- case (MDOC_HEAD):
- p->flags &= ~ttypes[TTYPE_SECTION];
- newln(p);
- break;
- case (MDOC_BODY):
- newln(p);
- p->offset -= INDENT;
- break;
- default:
- break;
- }
-}
-
-
-/* ARGSUSED */
-static int
-termp_xr_pre(DECL_ARGS)
-{
- const struct mdoc_node *n;
-
- n = node->child;
- assert(n);
-
- assert(MDOC_TEXT == n->type);
- word(p, n->data.text.string);
-
- if (NULL == (n = n->next))
- return(0);
-
- assert(MDOC_TEXT == n->type);
- p->flags |= TERMP_NOSPACE;
- word(p, "(");
- p->flags |= TERMP_NOSPACE;
- word(p, n->data.text.string);
- p->flags |= TERMP_NOSPACE;
- word(p, ")");
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-termp_vt_pre(DECL_ARGS)
-{
-
- /* FIXME: this can be "type name". */
- p->flags |= ttypes[TTYPE_VAR_DECL];
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_vt_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_VAR_DECL];
- if (node->sec == SEC_SYNOPSIS)
- vspace(p);
-}
-
-
-/* ARGSUSED */
-static int
-termp_fd_pre(DECL_ARGS)
-{
-
- /*
- * FIXME: this naming is bad. This value is used, in general,
- * for the #include header or other preprocessor statement.
- */
- p->flags |= ttypes[TTYPE_FUNC_DECL];
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_fd_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_FUNC_DECL];
- if (node->sec == SEC_SYNOPSIS)
- vspace(p);
-
-}
-
-
-/* ARGSUSED */
-static int
-termp_sh_pre(DECL_ARGS)
-{
-
- switch (node->type) {
- case (MDOC_HEAD):
- vspace(p);
- p->flags |= ttypes[TTYPE_SECTION];
- break;
- case (MDOC_BODY):
- p->offset += INDENT;
- break;
- default:
- break;
- }
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_op_pre(DECL_ARGS)
-{
-
- switch (node->type) {
- case (MDOC_BODY):
- word(p, "\\(lB");
- p->flags |= TERMP_NOSPACE;
- break;
- default:
- break;
- }
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_ud_pre(DECL_ARGS)
-{
-
- word(p, "currently under development.");
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_fl_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_CMD_FLAG];
- word(p, "\\-");
- p->flags |= TERMP_NOSPACE;
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_d1_pre(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return(1);
- newln(p);
- p->offset += INDENT;
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_d1_post(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return;
- newln(p);
- p->offset -= INDENT;
-}
-
-
-/* ARGSUSED */
-static int
-termp_aq_pre(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return(1);
- word(p, "<");
- p->flags |= TERMP_NOSPACE;
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_aq_post(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return;
- p->flags |= TERMP_NOSPACE;
- word(p, ">");
-}
-
-
-/* ARGSUSED */
-static int
-termp_ft_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_FUNC_TYPE];
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_ft_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_FUNC_TYPE];
- if (node->sec == SEC_SYNOPSIS)
- newln(p);
-
-}
-
-
-/* ARGSUSED */
-static int
-termp_fn_pre(DECL_ARGS)
-{
- const struct mdoc_node *n;
-
- assert(node->child);
- assert(MDOC_TEXT == node->child->type);
-
- /* FIXME: can be "type funcname" "type varname"... */
-
- p->flags |= ttypes[TTYPE_FUNC_NAME];
- word(p, node->child->data.text.string);
- p->flags &= ~ttypes[TTYPE_FUNC_NAME];
-
- p->flags |= TERMP_NOSPACE;
- word(p, "(");
-
- p->flags |= TERMP_NOSPACE;
- for (n = node->child->next; n; n = n->next) {
- assert(MDOC_TEXT == n->type);
- p->flags |= ttypes[TTYPE_FUNC_ARG];
- word(p, n->data.text.string);
- p->flags &= ~ttypes[TTYPE_FUNC_ARG];
- if ((n->next))
- word(p, ",");
- }
-
- p->flags |= TERMP_NOSPACE;
- word(p, ")");
-
- if (SEC_SYNOPSIS == node->sec)
- word(p, ";");
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static void
-termp_fn_post(DECL_ARGS)
-{
-
- if (node->sec == SEC_SYNOPSIS)
- vspace(p);
-
-}
-
-
-/* ARGSUSED */
-static int
-termp_sx_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_LINK];
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_sx_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_LINK];
-}
-
-
-/* ARGSUSED */
-static int
-termp_fa_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_FUNC_ARG];
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_fa_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_FUNC_ARG];
-}
-
-
-/* ARGSUSED */
-static int
-termp_va_pre(DECL_ARGS)
-{
-
- p->flags |= ttypes[TTYPE_VAR_DECL];
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_va_post(DECL_ARGS)
-{
-
- p->flags &= ~ttypes[TTYPE_VAR_DECL];
-}
-
-
-/* ARGSUSED */
-static int
-termp_bd_pre(DECL_ARGS)
-{
- const struct mdoc_block *bl;
- const struct mdoc_node *n;
-
- if (MDOC_BLOCK == node->type) {
- vspace(p);
- return(1);
- } else if (MDOC_BODY != node->type)
- return(1);
-
- assert(MDOC_BLOCK == node->parent->type);
-
- bl = &node->parent->data.block;
- if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
- return(1);
-
- p->flags |= TERMP_LITERAL;
-
- for (n = node->child; n; n = n->next) {
- assert(MDOC_TEXT == n->type); /* FIXME */
- if ((*n->data.text.string)) {
- word(p, n->data.text.string);
- flushln(p);
- } else
- vspace(p);
-
- }
-
- p->flags &= ~TERMP_LITERAL;
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-termp_qq_pre(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return(1);
- word(p, "\"");
- p->flags |= TERMP_NOSPACE;
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_qq_post(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return;
- p->flags |= TERMP_NOSPACE;
- word(p, "\"");
-}
-
-
-/* ARGSUSED */
-static int
-termp_ox_pre(DECL_ARGS)
-{
-
- word(p, "OpenBSD");
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_nx_pre(DECL_ARGS)
-{
-
- word(p, "NetBSD");
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-termp_sq_pre(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return(1);
- word(p, "`");
- p->flags |= TERMP_NOSPACE;
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_sq_post(DECL_ARGS)
-{
-
- if (MDOC_BODY != node->type)
- return;
- p->flags |= TERMP_NOSPACE;
- word(p, "\'");
-}
-
-
-/* ARGSUSED */
-static int
-termp_pf_pre(DECL_ARGS)
-{
-
- p->flags |= TERMP_IGNDELIM;
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-termp_pf_post(DECL_ARGS)
-{
-
- p->flags &= ~TERMP_IGNDELIM;
- p->flags |= TERMP_NOSPACE;
-}
-
-
diff --git a/tree.c b/tree.c
deleted file mode 100644
index aa3e4c44..00000000
--- a/tree.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "mdoc.h"
-
-#define xprintf (void)printf
-
-static void treeprint_r(const struct mdoc_node *, int);
-
-static void
-treeprint_r(const struct mdoc_node *n, int indent)
-{
- const char *p, *t;
- int i, j;
- size_t argc, sz;
- char **params;
- struct mdoc_arg *argv;
-
- argv = NULL;
- argc = sz = 0;
- params = NULL;
-
- switch (n->type) {
- case (MDOC_ROOT):
- t = "root";
- break;
- case (MDOC_BLOCK):
- t = "block";
- break;
- case (MDOC_HEAD):
- t = "block-head";
- break;
- case (MDOC_BODY):
- t = "block-body";
- break;
- case (MDOC_TAIL):
- t = "block-tail";
- break;
- case (MDOC_ELEM):
- t = "elem";
- break;
- case (MDOC_TEXT):
- t = "text";
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- switch (n->type) {
- case (MDOC_TEXT):
- p = n->data.text.string;
- break;
- case (MDOC_BODY):
- p = mdoc_macronames[n->tok];
- break;
- case (MDOC_HEAD):
- p = mdoc_macronames[n->tok];
- break;
- case (MDOC_TAIL):
- p = mdoc_macronames[n->tok];
- break;
- case (MDOC_ELEM):
- p = mdoc_macronames[n->tok];
- argv = n->data.elem.argv;
- argc = n->data.elem.argc;
- break;
- case (MDOC_BLOCK):
- p = mdoc_macronames[n->tok];
- argv = n->data.block.argv;
- argc = n->data.block.argc;
- break;
- case (MDOC_ROOT):
- p = "root";
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- for (i = 0; i < indent; i++)
- xprintf(" ");
- xprintf("%s (%s)", p, t);
-
- for (i = 0; i < (int)argc; i++) {
- xprintf(" -%s", mdoc_argnames[argv[i].arg]);
- if (argv[i].sz > 0)
- xprintf(" [");
- for (j = 0; j < (int)argv[i].sz; j++)
- xprintf(" [%s]", argv[i].value[j]);
- if (argv[i].sz > 0)
- xprintf(" ]");
- }
-
- for (i = 0; i < (int)sz; i++)
- xprintf(" [%s]", params[i]);
-
- xprintf(" %d:%d\n", n->line, n->pos);
-
- if (n->child)
- treeprint_r(n->child, indent + 1);
- if (n->next)
- treeprint_r(n->next, indent);
-}
-
-
-/* ARGSUSED */
-void
-treeprint(const struct mdoc_node *node,
- const struct mdoc_meta *meta)
-{
-
- treeprint_r(node, 0);
-}