=================================================================== RCS file: /cvs/mandoc/mansearch.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -p -r1.37 -r1.38 --- mandoc/mansearch.c 2014/06/20 02:24:40 1.37 +++ mandoc/mansearch.c 2014/07/12 14:00:25 1.38 @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.37 2014/06/20 02:24:40 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.38 2014/07/12 14:00:25 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -64,13 +64,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 { @@ -561,6 +562,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 @@ -702,7 +706,7 @@ exprterm(const struct mansearch *search, char *buf, in { char errbuf[BUFSIZ]; struct expr *e; - char *key, *v; + char *key, *val; uint64_t iterbit; int i, irc; @@ -711,40 +715,64 @@ exprterm(const struct mansearch *search, char *buf, in 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; + if (MANSEARCH_WHATIS & search->flags) + val = NULL; + else + val = strpbrk(buf, "=~"); + + if (NULL == val) { e->bits = search->deftype; - return(e); - } else if (v == buf) - 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.