summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile19
-rw-r--r--libman.h2
-rw-r--r--man.c7
-rw-r--r--man_action.c196
-rw-r--r--man_macro.c23
-rw-r--r--mdoc_action.c (renamed from action.c)23
6 files changed, 244 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index d6e3a04d..84400ff1 100644
--- a/Makefile
+++ b/Makefile
@@ -18,18 +18,21 @@ LINTFLAGS += $(VFLAGS)
CFLAGS += $(VFLAGS)
MDOCLNS = mdoc_macro.ln mdoc.ln mdoc_hash.ln strings.ln xstd.ln \
- argv.ln mdoc_validate.ln action.ln lib.ln att.ln \
+ argv.ln mdoc_validate.ln mdoc_action.ln lib.ln att.ln \
arch.ln vol.ln msec.ln st.ln
MDOCOBJS = mdoc_macro.o mdoc.o mdoc_hash.o strings.o xstd.o argv.o \
- mdoc_validate.o action.o lib.o att.o arch.o vol.o \
+ mdoc_validate.o mdoc_action.o lib.o att.o arch.o vol.o \
msec.o st.o
MDOCSRCS = mdoc_macro.c mdoc.c mdoc_hash.c strings.c xstd.c argv.c \
- mdoc_validate.c action.c lib.c att.c arch.c vol.c \
+ mdoc_validate.c mdoc_action.c lib.c att.c arch.c vol.c \
msec.c st.c
-MANLNS = man_macro.ln man.ln man_hash.ln man_validate.ln
-MANOBJS = man_macro.o man.o man_hash.o man_validate.o
-MANSRCS = man_macro.c man.c man_hash.c man_validate.c
+MANLNS = man_macro.ln man.ln man_hash.ln man_validate.ln \
+ man_action.ln
+MANOBJS = man_macro.o man.o man_hash.o man_validate.o \
+ man_action.o
+MANSRCS = man_macro.c man.c man_hash.c man_validate.c \
+ man_action.c
MAINLNS = main.ln term.ln ascii.ln terminal.ln tree.ln compat.ln
MAINOBJS = main.o term.o ascii.o terminal.o tree.o compat.o
@@ -162,8 +165,8 @@ man_validate.o: man_validate.c libman.h
mdoc_validate.ln: mdoc_validate.c libmdoc.h
mdoc_validate.o: mdoc_validate.c libmdoc.h
-action.ln: action.c libmdoc.h
-action.o: action.c libmdoc.h
+mdoc_action.ln: mdoc_action.c libmdoc.h
+mdoc_action.o: mdoc_action.c libmdoc.h
libmdoc.h: mdoc.h
diff --git a/libman.h b/libman.h
index 91effa0f..eb75c322 100644
--- a/libman.h
+++ b/libman.h
@@ -52,6 +52,8 @@ void man_hash_free(void *);
int man_macroend(struct man *);
int man_vwarn(struct man *, int, int, const char *, ...);
int man_verr(struct man *, int, int, const char *, ...);
+int man_valid_post(struct man *);
+int man_action_post(struct man *);
__END_DECLS
diff --git a/man.c b/man.c
index 27976280..62251b52 100644
--- a/man.c
+++ b/man.c
@@ -178,21 +178,14 @@ man_node_append(struct man *man, struct man_node *p)
/* NOTREACHED */
}
-#if 0
- if ( ! man_action_pre(man, p))
- return(0);
-#endif
-
man->last = p;
switch (p->type) {
case (MAN_TEXT):
if ( ! man_valid_post(man))
return(0);
-#if 0
if ( ! man_action_post(man))
return(0);
-#endif
break;
default:
break;
diff --git a/man_action.c b/man_action.c
new file mode 100644
index 00000000..fdeef50e
--- /dev/null
+++ b/man_action.c
@@ -0,0 +1,196 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
+ *
+ * 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 <sys/utsname.h>
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libman.h"
+
+
+struct actions {
+ int (*post)(struct man *);
+};
+
+
+const struct actions man_actions[MAN_MAX] = {
+ { NULL }, /* __ */
+ { NULL }, /* TH */
+ { NULL }, /* SH */
+ { NULL }, /* SS */
+ { NULL }, /* TP */
+ { NULL }, /* LP */
+ { NULL }, /* PP */
+ { NULL }, /* P */
+ { NULL }, /* IP */
+ { NULL }, /* HP */
+ { NULL }, /* SM */
+ { NULL }, /* SB */
+ { NULL }, /* BI */
+ { NULL }, /* IB */
+ { NULL }, /* BR */
+ { NULL }, /* RB */
+ { NULL }, /* R */
+ { NULL }, /* B */
+ { NULL }, /* I */
+ { NULL }, /* IR */
+};
+
+
+int
+man_action_post(struct man *m)
+{
+
+ if (MAN_ACTED & m->last->flags)
+ return(1);
+ m->last->flags |= MAN_ACTED;
+
+ switch (m->last->type) {
+ case (MAN_TEXT):
+ break;
+ case (MAN_ROOT):
+ break;
+ default:
+ if (NULL == man_actions[m->last->tok].post)
+ break;
+ return((*man_actions[m->last->tok].post)(m));
+ }
+ return(1);
+}
+
+#if 0
+static int
+post_dt(POST_ARGS)
+{
+ struct mdoc_node *n;
+ const char *cp;
+ char *ep;
+ long lval;
+
+ if (m->meta.title)
+ free(m->meta.title);
+ if (m->meta.vol)
+ free(m->meta.vol);
+ if (m->meta.arch)
+ free(m->meta.arch);
+
+ m->meta.title = m->meta.vol = m->meta.arch = NULL;
+ m->meta.msec = 0;
+
+ /* Handles: `.Dt'
+ * --> title = unknown, volume = local, msec = 0, arch = NULL
+ */
+
+ if (NULL == (n = m->last->child)) {
+ m->meta.title = xstrdup("unknown");
+ m->meta.vol = xstrdup("local");
+ return(post_prol(m));
+ }
+
+ /* Handles: `.Dt TITLE'
+ * --> title = TITLE, volume = local, msec = 0, arch = NULL
+ */
+
+ m->meta.title = xstrdup(n->string);
+
+ if (NULL == (n = n->next)) {
+ m->meta.vol = xstrdup("local");
+ return(post_prol(m));
+ }
+
+ /* Handles: `.Dt TITLE SEC'
+ * --> title = TITLE, volume = SEC is msec ?
+ * format(msec) : SEC,
+ * msec = SEC is msec ? atoi(msec) : 0,
+ * arch = NULL
+ */
+
+ cp = mdoc_a2msec(n->string);
+ if (cp) {
+ m->meta.vol = xstrdup(cp);
+ errno = 0;
+ lval = strtol(n->string, &ep, 10);
+ if (n->string[0] != '\0' && *ep == '\0')
+ m->meta.msec = (int)lval;
+ } else
+ m->meta.vol = xstrdup(n->string);
+
+ if (NULL == (n = n->next))
+ return(post_prol(m));
+
+ /* Handles: `.Dt TITLE SEC VOL'
+ * --> title = TITLE, volume = VOL is vol ?
+ * format(VOL) :
+ * VOL is arch ? format(arch) :
+ * VOL
+ */
+
+ cp = mdoc_a2vol(n->string);
+ if (cp) {
+ free(m->meta.vol);
+ m->meta.vol = xstrdup(cp);
+ n = n->next;
+ } else {
+ cp = mdoc_a2arch(n->string);
+ if (NULL == cp) {
+ free(m->meta.vol);
+ m->meta.vol = xstrdup(n->string);
+ } else
+ m->meta.arch = xstrdup(cp);
+ }
+
+ /* Ignore any subsequent parameters... */
+
+ return(post_prol(m));
+}
+
+static int
+post_prol(POST_ARGS)
+{
+ struct mdoc_node *n;
+
+ /*
+ * The end document shouldn't have the prologue macros as part
+ * of the syntax tree (they encompass only meta-data).
+ */
+
+ if (m->last->parent->child == m->last)
+ m->last->parent->child = m->last->prev;
+ if (m->last->prev)
+ m->last->prev->next = NULL;
+
+ n = m->last;
+ assert(NULL == m->last->next);
+
+ if (m->last->prev) {
+ m->last = m->last->prev;
+ m->next = MDOC_NEXT_SIBLING;
+ } else {
+ m->last = m->last->parent;
+ m->next = MDOC_NEXT_CHILD;
+ }
+
+ mdoc_node_freelist(n);
+ return(1);
+}
+#endif
diff --git a/man_macro.c b/man_macro.c
index 651b7503..4431e1b0 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -57,13 +57,20 @@ man_macro(struct man *man, int tok, int line,
}
for ( ; man->last && man->last != n;
- man->last = man->last->parent)
+ man->last = man->last->parent) {
if ( ! man_valid_post(man))
return(0);
+ if ( ! man_action_post(man))
+ return(0);
+ }
assert(man->last);
+
if ( ! man_valid_post(man))
return(0);
+ if ( ! man_action_post(man))
+ return(0);
+
man->next = MAN_NEXT_SIBLING;
return(1);
@@ -74,7 +81,19 @@ int
man_macroend(struct man *m)
{
- /* TODO: validate & actions. */
+ for ( ; m->last && m->last != m->first;
+ m->last = m->last->parent) {
+ if ( ! man_valid_post(m))
+ return(0);
+ if ( ! man_action_post(m))
+ return(0);
+ }
+
+ if ( ! man_valid_post(m))
+ return(0);
+ if ( ! man_action_post(m))
+ return(0);
+
return(1);
}
diff --git a/action.c b/mdoc_action.c
index 2b58d867..b8592c0d 100644
--- a/action.c
+++ b/mdoc_action.c
@@ -467,7 +467,12 @@ post_bl_tagwidth(struct mdoc *m)
* width if a macro.
*/
- n = m->last->head->child;
+ if ((n = m->last->body->child)) {
+ assert(MDOC_BLOCK == n->type);
+ assert(MDOC_It == n->tok);
+ n = n->head->child;
+ }
+
sz = 10; /* Default size. */
if (n) {
@@ -489,18 +494,18 @@ post_bl_tagwidth(struct mdoc *m)
n = m->last;
assert(n->args);
- (n->args->argc)++;
+ sz = (int)(n->args->argc)++;
n->args->argv = xrealloc(n->args->argv,
n->args->argc * sizeof(struct mdoc_argv));
- n->args->argv[n->args->argc - 1].arg = MDOC_Width;
- n->args->argv[n->args->argc - 1].line = m->last->line;
- n->args->argv[n->args->argc - 1].pos = m->last->pos;
- n->args->argv[n->args->argc - 1].sz = 1;
- n->args->argv[n->args->argc - 1].value = calloc(1, sizeof(char *));
- if (NULL == n->args->argv[n->args->argc - 1].value)
+ n->args->argv[sz].arg = MDOC_Width;
+ n->args->argv[sz].line = m->last->line;
+ n->args->argv[sz].pos = m->last->pos;
+ n->args->argv[sz].sz = 1;
+ n->args->argv[sz].value = calloc(1, sizeof(char *));
+ if (NULL == n->args->argv[sz].value)
err(1, "calloc");
- n->args->argv[n->args->argc - 1].value[0] = xstrdup(buf);
+ n->args->argv[sz].value[0] = xstrdup(buf);
return(1);
}