=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/read.c,v retrieving revision 1.169 retrieving revision 1.170 diff -u -r1.169 -r1.170 --- src/usr.bin/mandoc/read.c 2018/08/23 14:16:12 1.169 +++ src/usr.bin/mandoc/read.c 2018/08/23 19:32:03 1.170 @@ -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 * Copyright (c) 2010-2018 Ingo Schwarze @@ -46,7 +46,7 @@ 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 @@ }; 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, @@ -288,6 +289,19 @@ } 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) { char *cp, *ep; @@ -344,19 +358,23 @@ 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 @@ /* * 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 @@ ln.buf[pos++] = blk.buf[i++]; } + ln.buf[pos] = '\0'; - if (pos + 1 >= ln.sz) - resize_buf(&ln, 256); + /* + * Maintain a lookaside buffer of all lines. + * parsed from this input source. + */ - if (i == blk.sz || blk.buf[i] == '\0') + 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; + } + + /* XXX Ugly hack to mark the end of the input. */ + + 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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ } void -mparse_keep(struct mparse *p) +mparse_copy(const struct mparse *p) { + struct buf *buf; - 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; + for (buf = p->secondary; buf != NULL; buf = buf->next) + puts(buf->buf); }