summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.c7
-rw-r--r--main.h1
-rw-r--r--man.c8
-rw-r--r--man.h1
-rw-r--r--mandoc.128
-rw-r--r--mandoc.326
-rw-r--r--mandoc.h33
-rw-r--r--mdoc_man.c8
-rw-r--r--read.c49
9 files changed, 141 insertions, 20 deletions
diff --git a/main.c b/main.c
index 1316fdf7..36d02e3a 100644
--- a/main.c
+++ b/main.c
@@ -127,6 +127,12 @@ main(int argc, char *argv[])
curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp);
+ /*
+ * Conditionally start up the lookaside buffer before parsing.
+ */
+ if (OUTT_MAN == curp.outtype)
+ mparse_keep(curp.mp);
+
argc -= optind;
argv += optind;
@@ -252,6 +258,7 @@ parse(struct curparse *curp, int fd,
break;
case (OUTT_MAN):
curp->outmdoc = man_mdoc;
+ curp->outman = man_man;
break;
case (OUTT_PDF):
/* FALLTHROUGH */
diff --git a/main.h b/main.h
index c652bb53..d08c609b 100644
--- a/main.h
+++ b/main.h
@@ -42,6 +42,7 @@ void tree_mdoc(void *, const struct mdoc *);
void tree_man(void *, const struct man *);
void man_mdoc(void *, const struct mdoc *);
+void man_man(void *, const struct man *);
void *locale_alloc(char *);
void *utf8_alloc(char *);
diff --git a/man.c b/man.c
index 3321bf63..70ec1e64 100644
--- a/man.c
+++ b/man.c
@@ -648,3 +648,11 @@ man_node_unlink(struct man *m, struct man_node *n)
if (m && m->first == n)
m->first = NULL;
}
+
+const struct mparse *
+man_mparse(const struct man *m)
+{
+
+ assert(m && m->parse);
+ return(m->parse);
+}
diff --git a/man.h b/man.h
index 3cf3e766..5096a611 100644
--- a/man.h
+++ b/man.h
@@ -105,6 +105,7 @@ struct man;
const struct man_node *man_node(const struct man *);
const struct man_meta *man_meta(const struct man *);
+const struct mparse *man_mparse(const struct man *);
__END_DECLS
diff --git a/mandoc.1 b/mandoc.1
index 8f842e96..cfe230f3 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -176,11 +176,11 @@ Encode output using the current locale.
See
.Sx Locale Output .
.It Fl T Ns Cm man
-Produce output in
+Produce
.Xr man 7
-format; only useful when applied to
-.Fl m Ns Cm doc
-input.
+format output.
+See
+.Sx Man Output .
.It Fl T Ns Cm pdf
Produce PDF output.
See
@@ -311,6 +311,26 @@ will fall back to
See
.Sx ASCII Output
for font style specification and available command-line arguments.
+.Ss Man Output
+Translate input format into
+.Xr man 7
+output format.
+This is useful for distributing manual sources to legancy systems
+lacking
+.Xr mdoc 7
+formatters.
+.Pp
+If
+.Xr mdoc 7
+is passed as input, it is translated into
+.Xr man 7 ;
+if the input format is
+.Xr man 7 ,
+it is parsed and re-outputted.
+In either case, the
+.Xr roff 7
+.Sq so
+macros are processed prior to producing output.
.Ss PDF Output
PDF-1.1 output may be generated by
.Fl T Ns Cm pdf .
diff --git a/mandoc.3 b/mandoc.3
index 602e0543..70d592c3 100644
--- a/mandoc.3
+++ b/mandoc.3
@@ -22,6 +22,7 @@
.Nm mandoc ,
.Nm mandoc_escape ,
.Nm man_meta ,
+.Nm man_mparse ,
.Nm man_node ,
.Nm mchars_alloc ,
.Nm mchars_free ,
@@ -33,6 +34,8 @@
.Nm mdoc_node ,
.Nm mparse_alloc ,
.Nm mparse_free ,
+.Nm mparse_getkeep ,
+.Nm mparse_keep ,
.Nm mparse_readfd ,
.Nm mparse_reset ,
.Nm mparse_result ,
@@ -55,6 +58,10 @@
.Fo man_meta
.Fa "const struct man *man"
.Fc
+.Ft "const struct mparse *"
+.Fo man_mparse
+.Fa "const struct man *man"
+.Fc
.Ft "const struct man_node *"
.Fo man_node
.Fa "const struct man *man"
@@ -100,6 +107,14 @@
.Fo mparse_free
.Fa "struct mparse *parse"
.Fc
+.Ft void
+.Fo mparse_getkeep
+.Fa "const struct mparse *parse"
+.Fc
+.Ft void
+.Fo mparse_keep
+.Fa "struct mparse *parse"
+.Fc
.Ft "enum mandoclevel"
.Fo mparse_readfd
.Fa "struct mparse *parse"
@@ -244,6 +259,8 @@ may be
Obtain the meta-data of a successful parse.
This may only be used on a pointer returned by
.Fn mparse_result .
+.It Fn man_mparse
+Get the parser used for the current output.
.It Fn man_node
Obtain the root node of a successful parse.
This may only be used on a pointer returned by
@@ -294,6 +311,15 @@ must be called to free the memory allocated by this function.
.It Fn mparse_free
Free all memory allocated by
.Fn mparse_alloc .
+.It Fn mparse_getkeep
+Acquire the keep buffer.
+Must follow a call of
+.Fn mparse_keep .
+.It Fn mparse_keep
+Instruct the parser to retain a copy of its parsed input.
+This can be acquired with subsequent
+.Fn mparse_getkeep
+calls.
.It Fn mparse_readfd
Parse a file or file descriptor.
If
diff --git a/mandoc.h b/mandoc.h
index 1c8bc9f6..b3e9ca6e 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -400,30 +400,31 @@ struct man;
__BEGIN_DECLS
-void mparse_free(struct mparse *);
-void mparse_reset(struct mparse *);
-struct mparse *mparse_alloc(enum mparset,
- enum mandoclevel, mandocmsg, void *);
-enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
-void mparse_result(struct mparse *, struct mdoc **, struct man **);
-const char *mparse_strerror(enum mandocerr);
-const char *mparse_strlevel(enum mandoclevel);
-
void *mandoc_calloc(size_t, size_t);
+enum mandoc_esc mandoc_escape(const char **, const char **, int *);
void *mandoc_malloc(size_t);
void *mandoc_realloc(void *, size_t);
char *mandoc_strdup(const char *);
char *mandoc_strndup(const char *, size_t);
-
-enum mandoc_esc mandoc_escape(const char **, const char **, int *);
-
struct mchars *mchars_alloc(void);
+void mchars_free(struct mchars *);
char mchars_num2char(const char *, size_t);
int mchars_num2uc(const char *, size_t);
-const char *mchars_spec2str(struct mchars *, const char *, size_t, size_t *);
-int mchars_spec2cp(struct mchars *, const char *, size_t);
-void mchars_free(struct mchars *);
-
+int mchars_spec2cp(struct mchars *,
+ const char *, size_t);
+const char *mchars_spec2str(struct mchars *,
+ const char *, size_t, size_t *);
+struct mparse *mparse_alloc(enum mparset,
+ enum mandoclevel, mandocmsg, void *);
+void mparse_free(struct mparse *);
+void mparse_keep(struct mparse *);
+enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
+void mparse_reset(struct mparse *);
+void mparse_result(struct mparse *,
+ struct mdoc **, struct man **);
+const char *mparse_getkeep(const struct mparse *);
+const char *mparse_strerror(enum mandocerr);
+const char *mparse_strlevel(enum mandoclevel);
__END_DECLS
diff --git a/mdoc_man.c b/mdoc_man.c
index 4f67753c..b025f563 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -18,6 +18,7 @@
#include <string.h>
#include "mandoc.h"
+#include "man.h"
#include "mdoc.h"
#include "main.h"
@@ -219,6 +220,13 @@ print_word(const char *s)
}
void
+man_man(void *arg, const struct man *man)
+{
+
+ fputs(mparse_getkeep(man_mparse(man)), stdout);
+}
+
+void
man_mdoc(void *arg, const struct mdoc *mdoc)
{
const struct mdoc_meta *m;
diff --git a/read.c b/read.c
index a5a860a6..29ee4682 100644
--- a/read.c
+++ b/read.c
@@ -63,6 +63,7 @@ struct mparse {
mandocmsg mmsg; /* warning/error message handler */
void *arg; /* argument to mmsg */
const char *file;
+ struct buf *secondary;
};
static void resize_buf(struct buf *, size_t);
@@ -411,6 +412,27 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
of = 0;
+ /*
+ * Maintain a lookaside buffer of all parsed lines. We
+ * only do this if mparse_keep() has been invoked (the
+ * buffer may be accessed with mparse_getkeep()).
+ */
+
+ if (curp->secondary) {
+ curp->secondary->buf =
+ mandoc_realloc
+ (curp->secondary->buf,
+ curp->secondary->sz + pos + 2);
+ memcpy(curp->secondary->buf +
+ curp->secondary->sz,
+ ln.buf, pos);
+ curp->secondary->sz += pos;
+ curp->secondary->buf
+ [curp->secondary->sz] = '\n';
+ curp->secondary->sz++;
+ curp->secondary->buf
+ [curp->secondary->sz] = '\0';
+ }
rerun:
rr = roff_parseln
(curp->roff, curp->line,
@@ -437,6 +459,12 @@ rerun:
assert(MANDOCLEVEL_FATAL <= curp->file_status);
break;
case (ROFF_SO):
+ /*
+ * We remove `so' clauses from our lookaside
+ * buffer because we're going to descend into
+ * the file recursively.
+ */
+ curp->secondary->sz -= pos + 1;
mparse_readfd_r(curp, -1, ln.buf + of, 1);
if (MANDOCLEVEL_FATAL <= curp->file_status)
break;
@@ -704,6 +732,8 @@ mparse_reset(struct mparse *curp)
mdoc_reset(curp->mdoc);
if (curp->man)
man_reset(curp->man);
+ if (curp->secondary)
+ curp->secondary->sz = 0;
curp->file_status = MANDOCLEVEL_OK;
curp->mdoc = NULL;
@@ -720,7 +750,10 @@ mparse_free(struct mparse *curp)
man_free(curp->pman);
if (curp->roff)
roff_free(curp->roff);
+ if (curp->secondary)
+ free(curp->secondary->buf);
+ free(curp->secondary);
free(curp);
}
@@ -780,3 +813,19 @@ mparse_strlevel(enum mandoclevel lvl)
{
return(mandoclevels[lvl]);
}
+
+void
+mparse_keep(struct mparse *p)
+{
+
+ assert(NULL == p->secondary);
+ p->secondary = mandoc_calloc(1, sizeof(struct buf));
+}
+
+const char *
+mparse_getkeep(const struct mparse *p)
+{
+
+ assert(p->secondary);
+ return(p->secondary->sz ? p->secondary->buf : NULL);
+}