]> git.cameronkatri.com Git - mandoc.git/commitdiff
termact.c -> term.c
authorKristaps Dzonsons <kristaps@bsd.lv>
Mon, 23 Feb 2009 07:09:13 +0000 (07:09 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Mon, 23 Feb 2009 07:09:13 +0000 (07:09 +0000)
term.c -> mdocterm.c
tree.c -> mdoctree.c
Fixed/finished mmain.h.

Makefile
mdocterm.c
mdoctree.c
mmain.c
mmain.h
termact.c [deleted file]
tree.c [deleted file]

index 9277ff59abe09ea63a09bbc4cfb0a113f0a1283a..1ef8946528c777c8bd3580400f25f73b643f118c 100644 (file)
--- 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 
 
 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)
 
 
 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
 
 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 \
 
 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
 
 
 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
 
 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
 
 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
 
 strings.ln: strings.c private.h
 strings.o: strings.c private.h
 
index 58350fec495a5cbfea6ebecc30b5356166ce8066..faa06717ea7053bcd5ede42d37c701fad507f4cb 100644 (file)
@@ -1,4 +1,4 @@
-       /* $Id: mdocterm.c,v 1.2 2009/02/22 22:58:39 kristaps Exp $ */
+       /* $Id: mdocterm.c,v 1.3 2009/02/23 07:09:13 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
  * PERFORMANCE OF THIS SOFTWARE.
  */
 #include <assert.h>
  * PERFORMANCE OF THIS SOFTWARE.
  */
 #include <assert.h>
+#include <ctype.h>
 #include <err.h>
 #include <getopt.h>
 #include <err.h>
 #include <getopt.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "mmain.h"
 #include "term.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
 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();
 
 
        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);
 
                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);
 
        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 */
 }
 
 
        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);
+}
index 2c62359c39327b5646f2584b716845598e71d49d..444dde48211f4a3ff2efc2eab7d112850acf9c2e 100644 (file)
@@ -1,4 +1,4 @@
-       /* $Id: mdoctree.c,v 1.2 2009/02/22 22:58:39 kristaps Exp $ */
+       /* $Id: mdoctree.c,v 1.3 2009/02/23 07:09:13 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 #include <assert.h>
 #include <err.h>
 #include <getopt.h>
 #include <assert.h>
 #include <err.h>
 #include <getopt.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "mmain.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
 main(int argc, char *argv[])
 {
        struct mmain    *p;
        const struct mdoc *mdoc;
-       int              c;
 
        extern int       optreset;
        extern int       optind;
 
        p = mmain_alloc();
 
 
        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);
 
                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);
 
        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 */
 }
 
 
        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 5e41683a0dfbefe9388e9cc3f77f81437146fc9a..370d23f8b615d929e33f79339a688cfa5cb27054 100644 (file)
--- a/mmain.c
+++ b/mmain.c
@@ -1,4 +1,4 @@
-       /* $Id: mmain.c,v 1.1 2009/02/22 22:58:39 kristaps Exp $ */
+       /* $Id: mmain.c,v 1.2 2009/02/23 07:09:13 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -42,7 +42,7 @@ struct        mmain {
        struct mdoc      *mdoc;         /* Active parser. */
        char             *buf;          /* Input buffer. */
        u_long            bufsz;        /* Input buffer size. */
        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. */
 };
 
        int               fdin;         /* Input file desc. */
 };
 
@@ -60,6 +60,9 @@ extern        int               getsubopt(char **, char *const *, char **);
 #endif
 
 
 #endif
 
 
+/*
+ * Print our and our caller's usage message.
+ */
 void
 mmain_usage(const char *help)
 {
 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)
 {
 struct mmain *
 mmain_alloc(void)
 {
@@ -77,36 +83,41 @@ mmain_alloc(void)
        if (NULL == (p = calloc(1, sizeof(struct mmain))))
                err(1, "malloc");
 
        if (NULL == (p = calloc(1, sizeof(struct mmain))))
                err(1, "malloc");
 
-       (void)strlcpy(p->in, "-", MAXPATHLEN);
+       p->in = "-";
        p->fdin = STDIN_FILENO;
 
        return(p);
 }
 
 
        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
 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++;
                switch (c) {
                case ('v'):
                        p->dbg++;
@@ -116,23 +127,20 @@ mmain_getopt(struct mmain *p, int argc,
                                return(0);
                        break;
                case ('?'):
                                return(0);
                        break;
                case ('?'):
-                       break;
-               default:
                        mmain_usage(help);
                        return(0);
                        mmain_usage(help);
                        return(0);
+               default:
+                       assert(getopt_cb);
+                       if ((*getopt_cb)(arg, c, optarg))
+                               break;
+                       return(0);
                }
 
        argv += optind;
                }
 
        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 eb90ff7d547727a5d97ce4b17cca8118b3171959..af907531dd13d7bcc047676d991127a2a29a36d2 100644 (file)
--- a/mmain.h
+++ b/mmain.h
@@ -1,4 +1,4 @@
-/* $Id: mmain.h,v 1.1 2009/02/22 22:58:39 kristaps Exp $ */
+/* $Id: mmain.h,v 1.2 2009/02/23 07:09:13 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -22,8 +22,8 @@
 /* 
  * This is a convenience library for utilities implementing mdoc(3)
  * accepting a similar set of command-line patterns.  mmain handles
 /* 
  * 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"
  */
 
 #include "mdoc.h"
@@ -34,9 +34,9 @@ struct        mmain;
 
 struct mmain           *mmain_alloc(void);
 __dead void             mmain_exit(struct mmain *, int);
 
 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 *);
 
 struct mdoc            *mmain_mdoc(struct mmain *);
 void                    mmain_usage(const char *);
 
diff --git a/termact.c b/termact.c
deleted file mode 100644 (file)
index 0151dfc..0000000
--- a/termact.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/* $Id: termact.c,v 1.6 2009/02/22 19:23:48 kristaps Exp $ */
-/*
- * 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 (file)
index b62c2ad..0000000
--- a/tree.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $Id: tree.c,v 1.6 2009/02/21 21:00:06 kristaps Exp $ */
-/*
- * 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);
-}