diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2014-07-12 13:59:55 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2014-07-12 13:59:55 +0000 |
commit | 699aae94639d80c9726203accd9dee668a79adcf (patch) | |
tree | ab0b8871ea00deb1a5915430d32e5ea54f3dea33 | |
parent | 48204d2a0e6a9238e910ce727770f98f84436a04 (diff) |
Fix whatis(1) to correctly match words instead of any substrings.
While here, also provide an internal mode (MANSEARCH_MAN) to match
complete names, to be used by man.cgi(8).
-rw-r--r-- | usr.bin/mandoc/mansearch.c | 74 | ||||
-rw-r--r-- | usr.bin/mandoc/mansearch.h | 5 |
2 files changed, 54 insertions, 25 deletions
diff --git a/usr.bin/mandoc/mansearch.c b/usr.bin/mandoc/mansearch.c index 87f43cf59b5..443c3a812f9 100644 --- a/usr.bin/mandoc/mansearch.c +++ b/usr.bin/mandoc/mansearch.c @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.27 2014/05/12 19:11:20 espie Exp $ */ +/* $Id: mansearch.c,v 1.28 2014/07/12 13:59:54 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -56,13 +56,14 @@ extern const char *const mansearch_keynames[]; } while (0) struct expr { - uint64_t bits; /* type-mask */ - const char *substr; /* to search for, if applicable */ regex_t regexp; /* compiled regexp, if applicable */ + const char *substr; /* to search for, if applicable */ + struct expr *next; /* next in sequence */ + uint64_t bits; /* type-mask */ + int equal; /* equality, not subsring match */ int open; /* opening parentheses before */ int and; /* logical AND before */ int close; /* closing parentheses after */ - struct expr *next; /* next in sequence */ }; struct match { @@ -553,6 +554,9 @@ sql_statement(const struct expr *e) ? (NULL == e->substr ? "pageid IN (SELECT pageid FROM names " "WHERE name REGEXP ?)" + : e->equal + ? "pageid IN (SELECT pageid FROM names " + "WHERE name = ?)" : "pageid IN (SELECT pageid FROM names " "WHERE name MATCH ?)") : (NULL == e->substr @@ -694,7 +698,7 @@ exprterm(const struct mansearch *search, char *buf, int cs) { char errbuf[BUFSIZ]; struct expr *e; - char *key, *v; + char *key, *val; uint64_t iterbit; int i, irc; @@ -703,40 +707,64 @@ exprterm(const struct mansearch *search, char *buf, int cs) e = mandoc_calloc(1, sizeof(struct expr)); - /*"whatis" mode uses an opaque string and default fields. */ - - if (MANSEARCH_WHATIS & search->flags) { - e->substr = buf; + if (MANSEARCH_MAN & search->flags) { e->bits = search->deftype; + e->substr = buf; + e->equal = 1; return(e); } /* - * If no =~ is specified, search with equality over names and - * descriptions. - * If =~ begins the phrase, use name and description fields. + * Look for an '=' or '~' operator, + * unless forced to some fixed macro keys. */ - if (NULL == (v = strpbrk(buf, "=~"))) { - e->substr = buf; - e->bits = search->deftype; - return(e); - } else if (v == buf) + if (MANSEARCH_WHATIS & search->flags) + val = NULL; + else + val = strpbrk(buf, "=~"); + + if (NULL == val) { e->bits = search->deftype; + e->substr = buf; - if ('~' == *v++) { + /* + * Found an operator. + * Regexp search is requested by !e->substr. + */ + + } else { + if (val == buf) + e->bits = search->deftype; + if ('=' == *val) + e->substr = val + 1; + *val++ = '\0'; if (NULL != strstr(buf, "arch")) cs = 0; - if (0 != (irc = regcomp(&e->regexp, v, - REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE)))) { + } + + /* Compile regular expressions. */ + + if (MANSEARCH_WHATIS & search->flags) { + e->substr = NULL; + mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf); + } + + if (NULL == e->substr) { + irc = regcomp(&e->regexp, val, + REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE)); + if (MANSEARCH_WHATIS & search->flags) + free(val); + if (irc) { regerror(irc, &e->regexp, errbuf, sizeof(errbuf)); fprintf(stderr, "regcomp: %s\n", errbuf); free(e); return(NULL); } - } else - e->substr = v; - v[-1] = '\0'; + } + + if (e->bits) + return(e); /* * Parse out all possible fields. diff --git a/usr.bin/mandoc/mansearch.h b/usr.bin/mandoc/mansearch.h index 9ec5d327276..4eee09c202d 100644 --- a/usr.bin/mandoc/mansearch.h +++ b/usr.bin/mandoc/mansearch.h @@ -1,4 +1,4 @@ -/* $Id: mansearch.h,v 1.9 2014/04/11 15:45:39 schwarze Exp $ */ +/* $Id: mansearch.h,v 1.10 2014/07/12 13:59:54 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -82,7 +82,8 @@ struct mansearch { const char *sec; /* mansection/NULL */ uint64_t deftype; /* type if no key */ int flags; -#define MANSEARCH_WHATIS 0x01 /* whatis mode: equality, no key */ +#define MANSEARCH_WHATIS 0x01 /* whatis(1) mode: whole words, no keys */ +#define MANSEARCH_MAN 0x02 /* man(1) mode: string equality, no keys */ }; int mansearch_setup(int); |