Index: main.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v retrieving revision 1.164 diff -u -r1.164 main.c --- main.c 17 Sep 2011 15:00:51 -0000 1.164 +++ main.c 5 Oct 2011 09:34:15 -0000 @@ -127,6 +127,12 @@ 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 @@ break; case (OUTT_MAN): curp->outmdoc = man_mdoc; + curp->outman = man_man; break; case (OUTT_PDF): /* FALLTHROUGH */ Index: main.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.h,v retrieving revision 1.14 diff -u -r1.14 main.h --- main.h 18 Sep 2011 14:14:15 -0000 1.14 +++ main.h 5 Oct 2011 09:34:15 -0000 @@ -42,6 +42,7 @@ 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 *); Index: man.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man.c,v retrieving revision 1.111 diff -u -r1.111 man.c --- man.c 28 Jul 2011 14:17:11 -0000 1.111 +++ man.c 5 Oct 2011 09:34:15 -0000 @@ -648,3 +648,11 @@ if (m && m->first == n) m->first = NULL; } + +const struct mparse * +man_mparse(const struct man *m) +{ + + assert(m && m->parse); + return(m->parse); +} Index: man.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man.h,v retrieving revision 1.58 diff -u -r1.58 man.h --- man.h 23 Mar 2011 12:33:01 -0000 1.58 +++ man.h 5 Oct 2011 09:34:15 -0000 @@ -105,6 +105,7 @@ 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 Index: mandoc.1 =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.1,v retrieving revision 1.93 diff -u -r1.93 mandoc.1 --- mandoc.1 26 Sep 2011 20:47:23 -0000 1.93 +++ mandoc.1 5 Oct 2011 09:34:15 -0000 @@ -176,11 +176,11 @@ 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 @@ -305,6 +305,26 @@ 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 . Index: mandoc.3 =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.3,v retrieving revision 1.13 diff -u -r1.13 mandoc.3 --- mandoc.3 18 Aug 2011 08:58:44 -0000 1.13 +++ mandoc.3 5 Oct 2011 09:34:15 -0000 @@ -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 @@ 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 @@ .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 Index: mandoc.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v retrieving revision 1.95 diff -u -r1.95 mandoc.h --- mandoc.h 23 Jul 2011 18:44:42 -0000 1.95 +++ mandoc.h 5 Oct 2011 09:34:15 -0000 @@ -400,30 +400,31 @@ __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 Index: mdoc_man.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_man.c,v retrieving revision 1.3 diff -u -r1.3 mdoc_man.c --- mdoc_man.c 30 Sep 2011 00:13:28 -0000 1.3 +++ mdoc_man.c 5 Oct 2011 09:34:15 -0000 @@ -18,6 +18,7 @@ #include #include "mandoc.h" +#include "man.h" #include "mdoc.h" #include "main.h" @@ -216,6 +217,13 @@ break; } } +} + +void +man_man(void *arg, const struct man *man) +{ + + fputs(mparse_getkeep(man_mparse(man)), stdout); } void Index: read.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/read.c,v retrieving revision 1.23 diff -u -r1.23 read.c --- read.c 23 Jul 2011 18:41:18 -0000 1.23 +++ read.c 5 Oct 2011 09:34:16 -0000 @@ -63,6 +63,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ man_free(curp->pman); if (curp->roff) roff_free(curp->roff); + if (curp->secondary) + free(curp->secondary->buf); + free(curp->secondary); free(curp); } @@ -779,4 +812,20 @@ 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); }