diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2016-10-18 22:26:21 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2016-10-18 22:26:21 +0000 |
commit | 8b04b2749a34bf93001e1edea905d14fd732451a (patch) | |
tree | 0bb6bd47575e9099ae82588300f6c4068208cd97 /usr.bin | |
parent | 651616045275a7900a84ae956ac7551fb237d9e5 (diff) |
The termination condition of the iteration logic in page_bymacro()
was overzealous. Consequently, macro=substr and macro~regexp searches
only returned all pages containing the first matching macro value,
rather than all pages containing any of the matching macro values.
Bug reported by tb@ - thanks!
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/mandoc/dbm.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/usr.bin/mandoc/dbm.c b/usr.bin/mandoc/dbm.c index e4c707bcacc..729f5310016 100644 --- a/usr.bin/mandoc/dbm.c +++ b/usr.bin/mandoc/dbm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dbm.c,v 1.2 2016/08/30 21:58:59 schwarze Exp $ */ +/* $OpenBSD: dbm.c,v 1.3 2016/10/18 22:26:20 schwarze Exp $ */ /* * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org> * @@ -336,41 +336,45 @@ page_byarch(const struct dbm_match *arg_match) } static struct dbm_res -page_bymacro(int32_t im, const struct dbm_match *match) +page_bymacro(int32_t arg_im, const struct dbm_match *arg_match) { - static const int32_t *pp; - struct dbm_res res = {-1, 0}; - const char *cp; - int32_t iv; + static const struct dbm_match *match; + static const int32_t *pp; + static const char *cp; + static int32_t im, iv; + struct dbm_res res = {-1, 0}; assert(im >= 0); assert(im < MACRO_MAX); /* Initialize for a new iteration. */ - if (match != NULL) { + if (arg_match != NULL) { iteration = ITER_MACRO; + match = arg_match; + im = arg_im; cp = nvals[im] ? dbm_get(macros[im]->value) : NULL; - for (iv = 0; iv < nvals[im]; iv++) { - if (dbm_match(match, cp)) - break; - cp = strchr(cp, '\0') + 1; - } - pp = iv == nvals[im] ? NULL : dbm_get(macros[im][iv].pages); + pp = NULL; + iv = -1; return res; } if (iteration != ITER_MACRO) return res; - /* No more matches. */ + /* Find the next matching macro value. */ - if (pp == NULL || *pp == 0) { - iteration = ITER_NONE; - pp = NULL; - return res; + while (pp == NULL || *pp == 0) { + if (++iv == nvals[im]) { + iteration = ITER_NONE; + return res; + } + if (iv) + cp = strchr(cp, '\0') + 1; + if (dbm_match(match, cp)) + pp = dbm_get(macros[im][iv].pages); } - /* Found a match. */ + /* Found a matching page. */ res.page = (struct page *)dbm_get(*pp++) - pages; return res; |