diff options
Diffstat (limited to 'mansearch.c')
-rw-r--r-- | mansearch.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/mansearch.c b/mansearch.c index d3d88ce8..a4348d64 100644 --- a/mansearch.c +++ b/mansearch.c @@ -221,7 +221,7 @@ mansearch(const struct mansearch *search, SQL_BIND_BLOB(db, s, j, ep->regexp); } else SQL_BIND_TEXT(db, s, j, ep->substr); - if (0 == (TYPE_Nd & ep->bits)) + if (0 == ((TYPE_Nd | TYPE_Nm) & ep->bits)) SQL_BIND_INT64(db, s, j, ep->bits); } @@ -504,6 +504,12 @@ sql_statement(const struct expr *e) ? (NULL == e->substr ? "desc REGEXP ?" : "desc MATCH ?") + : TYPE_Nm == e->bits + ? (NULL == e->substr + ? "id IN (SELECT pageid FROM names " + "WHERE name REGEXP ?)" + : "id IN (SELECT pageid FROM names " + "WHERE name MATCH ?)") : (NULL == e->substr ? "id IN (SELECT pageid FROM keys " "WHERE key REGEXP ? AND bits & ?)" @@ -525,8 +531,9 @@ sql_statement(const struct expr *e) static struct expr * exprcomp(const struct mansearch *search, int argc, char *argv[]) { + uint64_t mask; int i, toopen, logic, igncase, toclose; - struct expr *first, *next, *cur; + struct expr *first, *prev, *cur, *next; first = cur = NULL; logic = igncase = toclose = 0; @@ -569,6 +576,7 @@ exprcomp(const struct mansearch *search, int argc, char *argv[]) first = next; else cur->next = next; + prev = cur = next; /* * Searching for descriptions must be split out @@ -576,18 +584,23 @@ exprcomp(const struct mansearch *search, int argc, char *argv[]) * not in the keys table. */ - if (TYPE_Nd & next->bits && ~TYPE_Nd & next->bits) { - cur = mandoc_calloc(1, sizeof(struct expr)); - memcpy(cur, next, sizeof(struct expr)); - next->open = 1; - next->bits = TYPE_Nd; - next->next = cur; - cur->bits &= ~TYPE_Nd; + for (mask = TYPE_Nm; mask <= TYPE_Nd; mask <<= 1) { + if (mask & cur->bits && ~mask & cur->bits) { + next = mandoc_calloc(1, + sizeof(struct expr)); + memcpy(next, cur, sizeof(struct expr)); + prev->open = 1; + cur->bits = mask; + cur->next = next; + cur = next; + cur->bits &= ~mask; + } + } + prev->and = (1 == logic); + prev->open += toopen; + if (cur != prev) cur->close = 1; - } else - cur = next; - next->and = (1 == logic); - next->open += toopen; + toopen = logic = igncase = 0; } if (toopen || logic || igncase || toclose) |