The upcoming .while request will have to re-execute roff(7) lines
authorschwarze <schwarze@openbsd.org>
Thu, 23 Aug 2018 19:32:03 +0000 (19:32 +0000)
committerschwarze <schwarze@openbsd.org>
Thu, 23 Aug 2018 19:32:03 +0000 (19:32 +0000)
parsed earlier, so they will have to be saved for reuse - but the
read.c preparser does not know yet whether a line contains a .while
request before passing it to the roff parser.  To cope with that,
save all parsed lines for now.  Even shortens the code by 20 lines.

usr.bin/mandoc/libmandoc.h
usr.bin/mandoc/main.c
usr.bin/mandoc/main.h
usr.bin/mandoc/man.c
usr.bin/mandoc/man.h
usr.bin/mandoc/mandoc.h
usr.bin/mandoc/mdoc_man.c
usr.bin/mandoc/read.c

index ba69e4d..336614c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: libmandoc.h,v 1.57 2018/08/23 14:16:12 schwarze Exp $ */
+/*     $OpenBSD: libmandoc.h,v 1.58 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -28,8 +28,9 @@ enum  rofferr {
 };
 
 struct buf {
-       char    *buf;
-       size_t   sz;
+       char            *buf;
+       size_t           sz;
+       struct buf      *next;
 };
 
 
index d9b67f5..03fc058 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.210 2018/08/09 17:23:21 schwarze Exp $ */
+/*     $OpenBSD: main.c,v 1.211 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -456,12 +456,6 @@ main(int argc, char *argv[])
        curp.mp = mparse_alloc(options, curp.mmin, mmsg,
            curp.os_e, curp.os_s);
 
-       /*
-        * Conditionally start up the lookaside buffer before parsing.
-        */
-       if (OUTT_MAN == curp.outtype)
-               mparse_keep(curp.mp);
-
        if (argc < 1) {
                if (use_pager)
                        tag_files = tag_init();
@@ -848,7 +842,7 @@ parse(struct curparse *curp, int fd, const char *file)
                        tree_man(curp->outdata, man);
                        break;
                case OUTT_MAN:
-                       man_man(curp->outdata, man);
+                       mparse_copy(curp->mp);
                        break;
                case OUTT_PDF:
                case OUTT_ASCII:
index 6051116..f23bb9e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.h,v 1.22 2017/03/03 14:21:41 schwarze Exp $ */
+/*     $OpenBSD: main.h,v 1.23 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -35,7 +35,6 @@ void            tree_mdoc(void *, const struct roff_man *);
 void             tree_man(void *, const struct roff_man *);
 
 void             man_mdoc(void *, const struct roff_man *);
-void             man_man(void *, const struct roff_man *);
 
 void            *locale_alloc(const struct manoutput *);
 void            *utf8_alloc(const struct manoutput *);
index acba306..7700248 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: man.c,v 1.125 2018/08/17 20:31:52 schwarze Exp $ */
+/*     $OpenBSD: man.c,v 1.126 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -337,14 +337,6 @@ man_breakscope(struct roff_man *man, int tok)
        }
 }
 
-const struct mparse *
-man_mparse(const struct roff_man *man)
-{
-
-       assert(man && man->parse);
-       return man->parse;
-}
-
 void
 man_state(struct roff_man *man, struct roff_node *n)
 {
index b18da39..eda8c6c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: man.h,v 1.58 2017/04/24 23:06:09 schwarze Exp $ */
+/*     $OpenBSD: man.h,v 1.59 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -18,5 +18,4 @@
 
 struct roff_man;
 
-const struct mparse    *man_mparse(const struct roff_man *);
 void                    man_validate(struct roff_man *);
index c57a60f..fad9c87 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mandoc.h,v 1.192 2018/08/23 14:16:12 schwarze Exp $ */
+/*     $OpenBSD: mandoc.h,v 1.193 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -462,13 +462,12 @@ const char         *mchars_spec2str(const char *, size_t, size_t *);
 struct mparse   *mparse_alloc(int, enum mandocerr, mandocmsg,
                        enum mandoc_os, const char *);
 void             mparse_free(struct mparse *);
-void             mparse_keep(struct mparse *);
 int              mparse_open(struct mparse *, const char *);
 enum mandoclevel  mparse_readfd(struct mparse *, int, const char *);
 void             mparse_reset(struct mparse *);
 void             mparse_result(struct mparse *,
                        struct roff_man **, char **);
-const char      *mparse_getkeep(const struct mparse *);
+void             mparse_copy(const struct mparse *);
 const char      *mparse_strerror(enum mandocerr);
 const char      *mparse_strlevel(enum mandoclevel);
 void             mparse_updaterc(struct mparse *, enum mandoclevel *);
index 321eb3f..85d3542 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdoc_man.c,v 1.125 2018/08/17 20:31:52 schwarze Exp $ */
+/*     $OpenBSD: mdoc_man.c,v 1.126 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org>
  *
@@ -597,19 +597,6 @@ print_count(int *count)
        print_word(buf);
 }
 
-void
-man_man(void *arg, const struct roff_man *man)
-{
-
-       /*
-        * Dump the keep buffer.
-        * We're guaranteed by now that this exists (is non-NULL).
-        * Flush stdout afterward, just in case.
-        */
-       fputs(mparse_getkeep(man_mparse(man)), stdout);
-       fflush(stdout);
-}
-
 void
 man_mdoc(void *arg, const struct roff_man *mdoc)
 {
index 079bce1..0041570 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: read.c,v 1.169 2018/08/23 14:16:12 schwarze Exp $ */
+/*     $OpenBSD: read.c,v 1.170 2018/08/23 19:32:03 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -46,7 +46,7 @@ struct        mparse {
        char             *sodest; /* filename pointed to by .so */
        const char       *file; /* filename of current input file */
        struct buf       *primary; /* buffer currently being parsed */
-       struct buf       *secondary; /* preprocessed copy of input */
+       struct buf       *secondary; /* copy of top level input */
        const char       *os_s; /* default operating system */
        mandocmsg         mmsg; /* warning/error message handler */
        enum mandoclevel  file_status; /* status of current parse */
@@ -59,6 +59,7 @@ struct        mparse {
 };
 
 static void      choose_parser(struct mparse *);
+static void      free_buf_list(struct buf *);
 static void      resize_buf(struct buf *, size_t);
 static enum rofferr mparse_buf_r(struct mparse *, struct buf, size_t, int);
 static int       read_whole_file(struct mparse *, const char *, int,
@@ -287,6 +288,19 @@ resize_buf(struct buf *buf, size_t initial)
        buf->buf = mandoc_realloc(buf->buf, buf->sz);
 }
 
+static void
+free_buf_list(struct buf *buf)
+{
+       struct buf *tmp;
+
+       while (buf != NULL) {
+               tmp = buf;
+               buf = tmp->next;
+               free(tmp->buf);
+               free(tmp);
+       }
+}
+
 static void
 choose_parser(struct mparse *curp)
 {
@@ -344,19 +358,23 @@ static enum rofferr
 mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
 {
        struct buf       ln;
+       struct buf      *firstln, *lastln, *thisln;
        const char      *save_file;
        char            *cp;
        size_t           pos; /* byte number in the ln buffer */
-       enum rofferr     line_result, sub_result;
+       enum rofferr     line_result, result;
        int              of;
        int              lnn; /* line number in the real file */
        int              fd;
        unsigned char    c;
 
-       memset(&ln, 0, sizeof(ln));
-
+       ln.sz = 256;
+       ln.buf = mandoc_malloc(ln.sz);
+       ln.next = NULL;
+       firstln = NULL;
        lnn = curp->line;
        pos = 0;
+       result = ROFF_CONT;
 
        while (i < blk.sz) {
                if (0 == pos && '\0' == blk.buf[i])
@@ -391,10 +409,10 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
 
                        /*
                         * Make sure we have space for the worst
-                        * case of 11 bytes: "\\[u10ffff]\0"
+                        * case of 12 bytes: "\\[u10ffff]\n\0"
                         */
 
-                       if (pos + 11 > ln.sz)
+                       if (pos + 12 > ln.sz)
                                resize_buf(&ln, 256);
 
                        /*
@@ -430,13 +448,32 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
 
                        ln.buf[pos++] = blk.buf[i++];
                }
+               ln.buf[pos] = '\0';
+
+               /*
+                * Maintain a lookaside buffer of all lines.
+                * parsed from this input source.
+                */
+
+               thisln = mandoc_malloc(sizeof(*thisln));
+               thisln->buf = mandoc_strdup(ln.buf);
+               thisln->sz = strlen(ln.buf) + 1;
+               thisln->next = NULL;
+               if (firstln == NULL) {
+                       firstln = lastln = thisln;
+                       if (curp->secondary == NULL)
+                               curp->secondary = firstln;
+               } else {
+                       lastln->next = thisln;
+                       lastln = thisln;
+               }
 
-               if (pos + 1 >= ln.sz)
-                       resize_buf(&ln, 256);
+               /* XXX Ugly hack to mark the end of the input. */
 
-               if (i == blk.sz || blk.buf[i] == '\0')
+               if (i == blk.sz || blk.buf[i] == '\0') {
                        ln.buf[pos++] = '\n';
-               ln.buf[pos] = '\0';
+                       ln.buf[pos] = '\0';
+               }
 
                /*
                 * A significant amount of complexity is contained by
@@ -448,27 +485,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, 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:
                line_result = roff_parseln(curp->roff, curp->line, &ln, &of);
 
@@ -476,30 +492,29 @@ rerun:
                case ROFF_REPARSE:
                case ROFF_USERCALL:
                        if (++curp->reparse_count > REPARSE_LIMIT) {
-                               sub_result = ROFF_IGN;
+                               result = ROFF_IGN;
                                mandoc_msg(MANDOCERR_ROFFLOOP, curp,
                                    curp->line, pos, NULL);
                        } else {
-                               sub_result = mparse_buf_r(curp, ln, of, 0);
+                               result = mparse_buf_r(curp, ln, of, 0);
                                if (line_result == ROFF_USERCALL) {
-                                       if (sub_result == ROFF_USERRET)
-                                               sub_result = ROFF_CONT;
+                                       if (result == ROFF_USERRET)
+                                               result = ROFF_CONT;
                                        roff_userret(curp->roff);
                                }
-                               if (start || sub_result == ROFF_CONT) {
+                               if (start || result == ROFF_CONT) {
                                        pos = 0;
                                        continue;
                                }
                        }
-                       free(ln.buf);
-                       return sub_result;
+                       goto out;
                case ROFF_USERRET:
                        if (start) {
                                pos = 0;
                                continue;
                        }
-                       free(ln.buf);
-                       return ROFF_USERRET;
+                       result = ROFF_USERRET;
+                       goto out;
                case ROFF_APPEND:
                        pos = strlen(ln.buf);
                        continue;
@@ -512,16 +527,8 @@ rerun:
                        if ( ! (curp->options & MPARSE_SO) &&
                            (i >= blk.sz || blk.buf[i] == '\0')) {
                                curp->sodest = mandoc_strdup(ln.buf + of);
-                               free(ln.buf);
-                               return ROFF_CONT;
+                               goto out;
                        }
-                       /*
-                        * We remove `so' clauses from our lookaside
-                        * buffer because we're going to descend into
-                        * the file recursively.
-                        */
-                       if (curp->secondary)
-                               curp->secondary->sz -= pos + 1;
                        save_file = curp->file;
                        if ((fd = mparse_open(curp, ln.buf + of)) != -1) {
                                mparse_readfd(curp, fd, ln.buf + of);
@@ -563,9 +570,11 @@ rerun:
 
                pos = 0;
        }
-
+out:
        free(ln.buf);
-       return ROFF_CONT;
+       if (firstln != curp->secondary)
+               free_buf_list(firstln);
+       return result;
 }
 
 static int
@@ -822,13 +831,12 @@ mparse_reset(struct mparse *curp)
 {
        roff_reset(curp->roff);
        roff_man_reset(curp->man);
+       free_buf_list(curp->secondary);
+       curp->secondary = NULL;
 
        free(curp->sodest);
        curp->sodest = NULL;
 
-       if (curp->secondary)
-               curp->secondary->sz = 0;
-
        curp->file_status = MANDOCLEVEL_OK;
        curp->gzip = 0;
 }
@@ -836,15 +844,11 @@ mparse_reset(struct mparse *curp)
 void
 mparse_free(struct mparse *curp)
 {
-
        roffhash_free(curp->man->mdocmac);
        roffhash_free(curp->man->manmac);
        roff_man_free(curp->man);
        roff_free(curp->roff);
-       if (curp->secondary)
-               free(curp->secondary->buf);
-
-       free(curp->secondary);
+       free_buf_list(curp->secondary);
        free(curp->sodest);
        free(curp);
 }
@@ -917,17 +921,10 @@ mparse_strlevel(enum mandoclevel 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)
+mparse_copy(const struct mparse *p)
 {
+       struct buf      *buf;
 
-       assert(p->secondary);
-       return p->secondary->sz ? p->secondary->buf : NULL;
+       for (buf = p->secondary; buf != NULL; buf = buf->next)
+               puts(buf->buf);
 }