summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-03-23 15:20:51 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-03-23 15:20:51 +0000
commit858ffa5feefe929dcf0dabf5d771106577f1d9e7 (patch)
treec7c60626c127f411298f6b68e1e41c01f8f1df40
parentaab08c4fa94c384767d1d5da68aa283ced4004bd (diff)
downloadmandoc-858ffa5feefe929dcf0dabf5d771106577f1d9e7.tar.gz
-man printing linked to -Ttree.
-rw-r--r--Makefile4
-rw-r--r--libman.h19
-rw-r--r--main.c17
-rw-r--r--man.c148
-rw-r--r--man.h9
-rw-r--r--man_macro.c144
-rw-r--r--mdoc.c46
-rw-r--r--term.h1
-rw-r--r--terminal.c6
-rw-r--r--tree.c64
10 files changed, 255 insertions, 203 deletions
diff --git a/Makefile b/Makefile
index 8dfebce4..53e24981 100644
--- a/Makefile
+++ b/Makefile
@@ -9,8 +9,8 @@ INSTALL_DATA = install -m 0444
INSTALL_LIB = install -m 0644
INSTALL_MAN = $(INSTALL_DATA)
-VERSION = 1.6.10
-VDATE = 22 March 2009
+VERSION = 1.7.1
+VDATE = 23 March 2009
VFLAGS = -DVERSION=\"$(VERSION)\"
CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -g
diff --git a/libman.h b/libman.h
index e4aa9d5e..e2a5261a 100644
--- a/libman.h
+++ b/libman.h
@@ -29,35 +29,22 @@ enum man_next {
struct man {
void *htab;
int flags;
-#define MAN_LITERAL (1 << 1)
+#define MAN_HALT (1 << 0)
enum man_next next;
struct man_node *last;
struct man_node *first;
struct man_meta meta;
};
-
-#define MACRO_PROT_ARGS struct man *man, int tok, int line, \
- int ppos, int *pos, char *buf
-
-struct man_macro {
- int (*fp)(MACRO_PROT_ARGS);
- int flags;
-#define MDOC_PROLOGUE (1 << 0)
-};
-
-extern const struct man_macro *const man_macros;
-
__BEGIN_DECLS
int man_word_alloc(struct man *, int, int, const char *);
int man_elem_alloc(struct man *, int, int, int);
-int man_block_alloc(struct man *, int, int, int);
-int man_head_alloc(struct man *, int, int, int);
-int man_body_alloc(struct man *, int, int, int);
void man_node_free(struct man_node *);
void man_node_freelist(struct man_node *);
void *man_hash_alloc(void);
+int man_macro(struct man *, int,
+ int, int, int *, char *);
int man_hash_find(const void *, const char *);
void man_hash_free(void *);
diff --git a/main.c b/main.c
index bf7d03fe..1016e31d 100644
--- a/main.c
+++ b/main.c
@@ -67,7 +67,8 @@ enum outt {
OUTT_LINT
};
-typedef int (*out_run)(void *, const struct mdoc *);
+typedef int (*out_run)(void *, const struct man *,
+ const struct mdoc *);
typedef void (*out_free)(void *);
extern char *__progname;
@@ -75,8 +76,10 @@ extern char *__progname;
extern void *ascii_alloc(void);
extern void *latin1_alloc(void);
extern void *utf8_alloc(void);
-extern int terminal_run(void *, const struct mdoc *);
-extern int tree_run(void *, const struct mdoc *);
+extern int terminal_run(void *, const struct man *,
+ const struct mdoc *);
+extern int tree_run(void *, const struct man *,
+ const struct mdoc *);
extern void terminal_free(void *);
static int foptions(int *, char *);
@@ -219,20 +222,16 @@ main(int argc, char *argv[])
if (c && NULL == outrun)
rc = 1;
-#if 0
- else if (c && outrun && (*outrun)(outdata, mdoc))
+ else if (c && outrun && (*outrun)(outdata, man, mdoc))
rc = 1;
-#endif
} else {
while (*argv) {
curp.file = *argv;
c = file(&blk, &ln, *argv, man, mdoc);
if ( ! c)
break;
-#if 0
- if (outrun && ! (*outrun)(outdata, mdoc))
+ if (outrun && ! (*outrun)(outdata, man, mdoc))
break;
-#endif
if (man)
man_reset(man);
if (mdoc)
diff --git a/man.c b/man.c
index 1cdbb9c3..48e26619 100644
--- a/man.c
+++ b/man.c
@@ -31,7 +31,7 @@ const char *const __man_macronames[MAN_MAX] = {
"TP", "LP", "PP", "P",
"IP", "HP", "SM", "SB",
"BI", "IB", "BR", "RB",
- "R", "B", "I"
+ "R", "B", "I", "IR"
};
const char * const *man_macronames = __man_macronames;
@@ -41,21 +41,23 @@ static int man_node_append(struct man *,
struct man_node *);
static int man_ptext(struct man *, int, char *);
static int man_pmacro(struct man *, int, char *);
+static void man_free1(struct man *);
+static void man_alloc1(struct man *);
const struct man_node *
-man_node(const struct man *man)
+man_node(const struct man *m)
{
- return(man->first);
+ return(MAN_HALT & m->flags ? NULL : m->first);
}
const struct man_meta *
-man_meta(const struct man *man)
+man_meta(const struct man *m)
{
- return(&man->meta);
+ return(MAN_HALT & m->flags ? NULL : &m->meta);
}
@@ -63,22 +65,8 @@ void
man_reset(struct man *man)
{
- if (man->first)
- man_node_freelist(man->first);
- if (man->meta.title)
- free(man->meta.title);
- if (man->meta.os)
- free(man->meta.os);
- if (man->meta.vol)
- free(man->meta.vol);
-
- bzero(&man->meta, sizeof(struct man_meta));
- man->flags = 0;
- if (NULL == (man->last = calloc(1, sizeof(struct man_node))))
- err(1, "malloc");
- man->first = man->last;
- man->last->type = MAN_ROOT;
- man->next = MAN_NEXT_CHILD;
+ man_free1(man);
+ man_alloc1(man);
}
@@ -86,14 +74,8 @@ void
man_free(struct man *man)
{
- if (man->first)
- man_node_freelist(man->first);
- if (man->meta.title)
- free(man->meta.title);
- if (man->meta.os)
- free(man->meta.os);
- if (man->meta.vol)
- free(man->meta.vol);
+ man_free1(man);
+
if (man->htab)
man_hash_free(man->htab);
free(man);
@@ -105,14 +87,12 @@ man_alloc(void)
{
struct man *p;
- if (NULL == (p = calloc(1, sizeof(struct man))))
- err(1, "malloc");
- if (NULL == (p->last = calloc(1, sizeof(struct man_node))))
- err(1, "malloc");
+ p = calloc(1, sizeof(struct man));
+ if (NULL == p)
+ err(1, "calloc");
+
+ man_alloc1(p);
- p->first = p->last;
- p->last->type = MAN_ROOT;
- p->next = MAN_NEXT_CHILD;
p->htab = man_hash_alloc();
return(p);
}
@@ -122,6 +102,7 @@ int
man_endparse(struct man *m)
{
+ /* FIXME. */
return(1);
}
@@ -136,6 +117,36 @@ man_parseln(struct man *m, int ln, char *buf)
}
+static void
+man_free1(struct man *man)
+{
+
+ if (man->first)
+ man_node_freelist(man->first);
+ if (man->meta.title)
+ free(man->meta.title);
+ if (man->meta.os)
+ free(man->meta.os);
+ if (man->meta.vol)
+ free(man->meta.vol);
+}
+
+
+static void
+man_alloc1(struct man *m)
+{
+
+ bzero(&m->meta, sizeof(struct man_meta));
+ m->flags = 0;
+ m->last = calloc(1, sizeof(struct man_node));
+ if (NULL == m->last)
+ err(1, "calloc");
+ m->first = m->last;
+ m->last->type = MAN_ROOT;
+ m->next = MAN_NEXT_CHILD;
+}
+
+
static int
man_node_append(struct man *man, struct man_node *p)
{
@@ -166,20 +177,21 @@ man_node_append(struct man *man, struct man_node *p)
return(0);
#endif
+ man->last = p;
+
switch (p->type) {
- case (MAN_HEAD):
- assert(MAN_BLOCK == p->parent->type);
- p->parent->head = p;
- break;
- case (MAN_BODY):
- assert(MAN_BLOCK == p->parent->type);
- p->parent->body = p;
+ case (MAN_TEXT):
+#if 0
+ if ( ! man_valid_post(man))
+ return(0);
+ if ( ! man_action_post(man))
+ return(0);
+#endif
break;
default:
break;
}
- man->last = p;
return(1);
}
@@ -200,42 +212,6 @@ man_node_alloc(int line, int pos, enum man_type type)
int
-man_head_alloc(struct man *man, int line, int pos, int tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_HEAD);
- p->tok = tok;
-
- return(man_node_append(man, p));
-}
-
-
-int
-man_body_alloc(struct man *man, int line, int pos, int tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_BODY);
- p->tok = tok;
-
- return(man_node_append(man, p));
-}
-
-
-int
-man_block_alloc(struct man *man, int line, int pos, int tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_BLOCK);
- p->tok = tok;
-
- return(man_node_append(man, p));
-}
-
-
-int
man_elem_alloc(struct man *man, int line, int pos, int tok)
{
struct man_node *p;
@@ -288,14 +264,8 @@ static int
man_ptext(struct man *m, int line, char *buf)
{
- if (0 == buf[0]) {
- warnx("blank line!");
- return(1);
- }
-
if ( ! man_word_alloc(m, line, 0, buf))
return(0);
-
m->next = MAN_NEXT_SIBLING;
return(1);
}
@@ -354,15 +324,13 @@ man_pmacro(struct man *m, int ln, char *buf)
/* Begin recursive parse sequence. */
- if ( ! (*man_macros[c].fp)(m, c, ln, 1, &i, buf))
+ if ( ! man_macro(m, c, ln, 1, &i, buf))
goto err;
return(1);
err: /* Error out. */
-#if 0
- m->flags |= MDOC_HALT;
-#endif
+ m->flags |= MAN_HALT;
return(0);
}
diff --git a/man.h b/man.h
index de276836..da242898 100644
--- a/man.h
+++ b/man.h
@@ -40,14 +40,12 @@
#define MAN_R 16
#define MAN_B 17
#define MAN_I 18
-#define MAN_MAX 19
+#define MAN_IR 19
+#define MAN_MAX 20
enum man_type {
MAN_TEXT,
MAN_ELEM,
- MAN_HEAD,
- MAN_BODY,
- MAN_BLOCK,
MAN_ROOT
};
@@ -71,9 +69,6 @@ struct man_node {
#define MAN_VALID (1 << 0)
#define MAN_ACTED (1 << 1)
enum man_type type;
-
- struct man_node *head;
- struct man_node *body;
char *string;
};
diff --git a/man_macro.c b/man_macro.c
index 7291454a..2bea77a8 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -18,79 +18,119 @@
*/
#include <assert.h>
#include <ctype.h>
+#include <err.h> /* XXX */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libman.h"
-static int in_line_eoln(MACRO_PROT_ARGS);
-
-const struct man_macro __man_macros[MAN_MAX] = {
- { in_line_eoln, 0 }, /* MAN___ */
- { in_line_eoln, 0 }, /* MAN_TH */
- { in_line_eoln, 0 }, /* MAN_SH */
- { in_line_eoln, 0 }, /* MAN_SS */
- { in_line_eoln, 0 }, /* MAN_TP */
- { in_line_eoln, 0 }, /* MAN_LP */
- { in_line_eoln, 0 }, /* MAN_PP */
- { in_line_eoln, 0 }, /* MAN_P */
- { in_line_eoln, 0 }, /* MAN_IP */
- { in_line_eoln, 0 }, /* MAN_HP */
- { in_line_eoln, 0 }, /* MAN_SM */
- { in_line_eoln, 0 }, /* MAN_SB */
- { in_line_eoln, 0 }, /* MAN_BI */
- { in_line_eoln, 0 }, /* MAN_IB */
- { in_line_eoln, 0 }, /* MAN_BR */
- { in_line_eoln, 0 }, /* MAN_RB */
- { in_line_eoln, 0 }, /* MAN_R */
- { in_line_eoln, 0 }, /* MAN_B */
- { in_line_eoln, 0 }, /* MAN_I */
-};
-
-const struct man_macro * const man_macros = __man_macros;
+static int man_args(struct man *, int,
+ int *, char *, char **);
-/*
- * In-line macro that spans an entire line. May be callable, but has no
- * subsequent parsed arguments.
- */
-static int
-in_line_eoln(MACRO_PROT_ARGS)
+int
+man_macro(struct man *man, int tok, int line,
+ int ppos, int *pos, char *buf)
{
-#if 0
- int c, w, la;
- char *p;
+ int w, la;
+ char *p;
+ struct man_node *n;
- if ( ! man_elem_alloc(man, line, ppos, tok, arg))
+ if ( ! man_elem_alloc(man, line, ppos, tok))
return(0);
- man->next = MDOC_NEXT_SIBLING;
+ n = man->last;
+ man->next = MAN_NEXT_CHILD;
for (;;) {
la = *pos;
- w = man_args(man, line, pos, buf, tok, &p);
+ w = man_args(man, line, pos, buf, &p);
- if (ARGS_ERROR == w)
+ if (-1 == w)
return(0);
- if (ARGS_EOLN == w)
+ if (0 == w)
break;
- c = ARGS_QWORD == w ? MAN_MAX :
- lookup(man, line, la, tok, p);
-
- if (MDOC_MAX != c && -1 != c) {
- if ( ! rew_elem(mdoc, tok))
- return(0);
- return(mdoc_macro(mdoc, c, line, la, pos, buf));
- } else if (-1 == c)
- return(0);
-
- if ( ! mdoc_word_alloc(mdoc, line, la, p))
+ if ( ! man_word_alloc(man, line, la, p))
return(0);
+ man->next = MAN_NEXT_SIBLING;
}
- return(rew_elem(mdoc, tok));
-#endif
+ /* TODO: validate. */
+ /* TODO: validate. */
+
+ man->last = n;
+ man->next = MAN_NEXT_SIBLING;
+
return(1);
}
+
+/* ARGSUSED */
+int
+man_args(struct man *man, int line,
+ int *pos, char *buf, char **v)
+{
+
+ if (0 == buf[*pos])
+ return(0);
+
+ /* First parse non-quoted strings. */
+
+ if ('\"' != buf[*pos]) {
+ *v = &buf[*pos];
+
+ while (buf[*pos]) {
+ if (' ' == buf[*pos])
+ if ('\\' != buf[*pos - 1])
+ break;
+ (*pos)++;
+ }
+
+ if (0 == buf[*pos])
+ return(1);
+
+ buf[(*pos)++] = 0;
+
+ if (0 == buf[*pos])
+ return(1);
+
+ while (buf[*pos] && ' ' == buf[*pos])
+ (*pos)++;
+
+ if (buf[*pos])
+ return(1);
+
+ warnx("tail whitespace");
+ return(-1);
+ }
+
+ /*
+ * If we're a quoted string (and quoted strings are allowed),
+ * then parse ahead to the next quote. If none's found, it's an
+ * error. After, parse to the next word.
+ */
+
+ *v = &buf[++(*pos)];
+
+ while (buf[*pos] && '\"' != buf[*pos])
+ (*pos)++;
+
+ if (0 == buf[*pos]) {
+ warnx("unterminated quotation");
+ return(-1);
+ }
+
+ buf[(*pos)++] = 0;
+ if (0 == buf[*pos])
+ return(1);
+
+ while (buf[*pos] && ' ' == buf[*pos])
+ (*pos)++;
+
+ if (buf[*pos])
+ return(1);
+
+ warnx("tail whitespace");
+ return(-1);
+}
diff --git a/mdoc.c b/mdoc.c
index 9781ecbe..3c6735a6 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -32,16 +32,6 @@
* in macro.c, validate.c and action.c.
*/
-/* FIXME: have this accept line/pos/tok. */
-static struct mdoc_node *mdoc_node_alloc(const struct mdoc *);
-static int mdoc_node_append(struct mdoc *,
- struct mdoc_node *);
-
-static int parsetext(struct mdoc *, int, char *);
-static int parsemacro(struct mdoc *, int, char *);
-static int macrowarn(struct mdoc *, int, const char *);
-
-
const char *const __mdoc_macronames[MDOC_MAX] = {
"\\\"", "Dd", "Dt", "Os",
"Sh", "Ss", "Pp", "D1",
@@ -95,29 +85,33 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
const char * const *mdoc_macronames = __mdoc_macronames;
const char * const *mdoc_argnames = __mdoc_argnames;
+/* FIXME: have this accept line/pos/tok. */
+/* FIXME: mdoc_alloc1 and mdoc_free1 like in man.c. */
+static struct mdoc_node *mdoc_node_alloc(const struct mdoc *);
+static int mdoc_node_append(struct mdoc *,
+ struct mdoc_node *);
+
+static int parsetext(struct mdoc *, int, char *);
+static int parsemacro(struct mdoc *, int, char *);
+static int macrowarn(struct mdoc *, int, const char *);
+
/*
* Get the first (root) node of the parse tree.
*/
const struct mdoc_node *
-mdoc_node(const struct mdoc *mdoc)
+mdoc_node(const struct mdoc *m)
{
- if (MDOC_HALT & mdoc->flags)
- return(NULL);
- if (mdoc->first)
- assert(MDOC_ROOT == mdoc->first->type);
- return(mdoc->first);
+ return(MDOC_HALT & m->flags ? NULL : m->first);
}
const struct mdoc_meta *
-mdoc_meta(const struct mdoc *mdoc)
+mdoc_meta(const struct mdoc *m)
{
- if (MDOC_HALT & mdoc->flags)
- return(NULL);
- return(&mdoc->meta);
+ return(MDOC_HALT & m->flags ? NULL : &m->meta);
}
@@ -366,6 +360,18 @@ mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *p)
}
mdoc->last = p;
+
+ switch (p->type) {
+ case (MDOC_TEXT):
+ if ( ! mdoc_valid_post(mdoc))
+ return(0);
+ if ( ! mdoc_action_post(mdoc))
+ return(0);
+ break;
+ default:
+ break;
+ }
+
return(1);
}
diff --git a/term.h b/term.h
index a3b374de..53bd4231 100644
--- a/term.h
+++ b/term.h
@@ -20,6 +20,7 @@
#define TERM_H
#include "mdoc.h"
+#include "man.h"
/* FIXME - clean up tabs. */
diff --git a/terminal.c b/terminal.c
index f7bfd301..0dd3bad3 100644
--- a/terminal.c
+++ b/terminal.c
@@ -76,10 +76,14 @@ ascii_alloc(void)
int
-terminal_run(void *arg, const struct mdoc *mdoc)
+terminal_run(void *arg, const struct man *man,
+ const struct mdoc *mdoc)
{
struct termp *p;
+ if (NULL == mdoc)
+ return(1);
+
p = (struct termp *)arg;
if (NULL == p->symtab)
diff --git a/tree.c b/tree.c
index 5be7af5d..bfd164f7 100644
--- a/tree.c
+++ b/tree.c
@@ -22,22 +22,28 @@
#include <stdlib.h>
#include "mdoc.h"
+#include "man.h"
-static void tree_body(const struct mdoc_node *, int);
+static void tree_mdoc(const struct mdoc_node *, int);
+static void tree_man(const struct man_node *, int);
/* ARGSUSED */
int
-tree_run(void *arg, const struct mdoc *mdoc)
+tree_run(void *arg, const struct man *man,
+ const struct mdoc *mdoc)
{
- tree_body(mdoc_node(mdoc), 0);
+ if (man)
+ tree_man(man_node(man), 0);
+ if (mdoc)
+ tree_mdoc(mdoc_node(mdoc), 0);
return(1);
}
static void
-tree_body(const struct mdoc_node *n, int indent)
+tree_mdoc(const struct mdoc_node *n, int indent)
{
const char *p, *t;
int i, j;
@@ -131,8 +137,54 @@ tree_body(const struct mdoc_node *n, int indent)
(void)printf(" %d:%d\n", n->line, n->pos);
if (n->child)
- tree_body(n->child, indent + 1);
+ tree_mdoc(n->child, indent + 1);
if (n->next)
- tree_body(n->next, indent);
+ tree_mdoc(n->next, indent);
}
+
+static void
+tree_man(const struct man_node *n, int indent)
+{
+ const char *p, *t;
+ int i;
+
+ switch (n->type) {
+ case (MAN_ROOT):
+ t = "root";
+ break;
+ case (MAN_ELEM):
+ t = "elem";
+ break;
+ case (MAN_TEXT):
+ t = "text";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ switch (n->type) {
+ case (MAN_TEXT):
+ p = n->string;
+ break;
+ case (MAN_ELEM):
+ p = man_macronames[n->tok];
+ break;
+ case (MAN_ROOT):
+ p = "root";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ for (i = 0; i < indent; i++)
+ (void)printf(" ");
+ (void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
+
+ if (n->child)
+ tree_man(n->child, indent + 1);
+ if (n->next)
+ tree_man(n->next, indent);
+}