From 04d794422a19264dc0a985a9b145b3748fc69862 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Thu, 6 Oct 2011 22:29:12 +0000 Subject: If -Tman is specified and input is -man, echo the preprocessed (`so' replaced by file) input. This replaces earlier behaviour of doing nothing, which I found unexpected (mandoc should always output). This requires a buffer in read.c that saves the input lines before being parsed, with a special hook if `so' is invoked. This buffer is just flushed to output if -mman is the input. While mucking around doing this, I also alpha-ordered the mandoc.h functions. Ok schwarze@, with no screaming when the polished patch was published. --- main.c | 9 ++++++++- main.h | 3 ++- man.c | 10 +++++++++- man.h | 3 ++- mandoc.1 | 32 ++++++++++++++++++++++++++------ mandoc.3 | 30 ++++++++++++++++++++++++++++-- mandoc.h | 35 ++++++++++++++++++----------------- mdoc_man.c | 10 +++++++++- read.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 152 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index b76a6047..fec83fba 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.164 2011/09/17 15:00:51 schwarze Exp $ */ +/* $Id: main.c,v 1.165 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -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 da84d5c7..79dcf489 100644 --- a/main.h +++ b/main.h @@ -1,4 +1,4 @@ -/* $Id: main.h,v 1.14 2011/09/18 14:14:15 schwarze Exp $ */ +/* $Id: main.h,v 1.15 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -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 52592d4a..17e002b4 100644 --- a/man.c +++ b/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.111 2011/07/28 14:17:11 kristaps Exp $ */ +/* $Id: man.c,v 1.112 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -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 1b0bb687..beb406f6 100644 --- a/man.h +++ b/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.58 2011/03/23 12:33:01 kristaps Exp $ */ +/* $Id: man.h,v 1.59 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -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 b629e833..f090917a 100644 --- a/mandoc.1 +++ b/mandoc.1 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.1,v 1.94 2011/10/05 21:35:17 kristaps Exp $ +.\" $Id: mandoc.1,v 1.95 2011/10/06 22:29:12 kristaps Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 5 2011 $ +.Dd $Mdocdate: October 6 2011 $ .Dt MANDOC 1 .Os .Sh NAME @@ -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 1adb1d0b..3d52f3e3 100644 --- a/mandoc.3 +++ b/mandoc.3 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.3,v 1.13 2011/08/18 08:58:44 kristaps Exp $ +.\" $Id: mandoc.3,v 1.14 2011/10/06 22:29:12 kristaps Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010 Ingo Schwarze @@ -15,13 +15,14 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 18 2011 $ +.Dd $Mdocdate: October 6 2011 $ .Dt MANDOC 3 .Os .Sh NAME .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 44b259db..d80098e3 100644 --- a/mandoc.h +++ b/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.95 2011/07/23 18:44:42 kristaps Exp $ */ +/* $Id: mandoc.h,v 1.96 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * @@ -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 99485507..c6849b1f 100644 --- a/mdoc_man.c +++ b/mdoc_man.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_man.c,v 1.3 2011/09/30 00:13:28 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.4 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2011 Ingo Schwarze * @@ -18,6 +18,7 @@ #include #include "mandoc.h" +#include "man.h" #include "mdoc.h" #include "main.h" @@ -218,6 +219,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) { diff --git a/read.c b/read.c index 33450152..8c1da44a 100644 --- a/read.c +++ b/read.c @@ -1,4 +1,4 @@ -/* $Id: read.c,v 1.23 2011/07/23 18:41:18 kristaps Exp $ */ +/* $Id: read.c,v 1.24 2011/10/06 22:29:12 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -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); +} -- cgit v1.2.3-56-ge451