diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2014-01-05 03:06:43 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2014-01-05 03:06:43 +0000 |
commit | 309ba0ab0e453acde16dc583e036874dbeb4a2a4 (patch) | |
tree | 0067eec7fed86caa37a21ad837513356c1ac5d68 /mansearch.c | |
parent | 54a35af24eafe969f6b7acd3eb923ffa75bfb0ab (diff) | |
download | mandoc-309ba0ab0e453acde16dc583e036874dbeb4a2a4.tar.gz |
Reimplement apropos -s NUM -S ARCH EXPR by internally converting it to
apropos \( EXPR \) -a 'sec~^NUM$' -a 'arch~^(ARCH|any)$'
in preparation for removal of sec and arch from the mpage table.
Almost no functional change except for the following bonus:
This also makes sure that for cross-section and cross-arch MLINKs,
all of the following work:
apropos -s 1 encrypt
apropos -s 8 encrypt
apropos -s 1 makekey
apropos -s 8 makekey
While here, print error messages about invalid regexps to stderr.
Diffstat (limited to 'mansearch.c')
-rw-r--r-- | mansearch.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/mansearch.c b/mansearch.c index 6db43e4e..a9c7a2d4 100644 --- a/mansearch.c +++ b/mansearch.c @@ -135,6 +135,8 @@ static void *hash_halloc(size_t, void *); static struct expr *exprcomp(const struct mansearch *, int, char *[]); static void exprfree(struct expr *); +static struct expr *exprspec(struct expr *, uint64_t, + const char *, const char *); static struct expr *exprterm(const struct mansearch *, char *, int); static void sql_append(char **sql, size_t *sz, const char *newstr, int count); @@ -142,8 +144,7 @@ static void sql_match(sqlite3_context *context, int argc, sqlite3_value **argv); static void sql_regexp(sqlite3_context *context, int argc, sqlite3_value **argv); -static char *sql_statement(const struct expr *, - const char *, const char *); +static char *sql_statement(const struct expr *); int mansearch(const struct mansearch *search, @@ -211,7 +212,7 @@ mansearch(const struct mansearch *search, goto out; } - sql = sql_statement(e, search->arch, search->sec); + sql = sql_statement(e); /* * Loop over the directories (containing databases) for us to @@ -258,11 +259,6 @@ mansearch(const struct mansearch *search, if (SQLITE_OK != c) fprintf(stderr, "%s\n", sqlite3_errmsg(db)); - if (NULL != search->arch) - SQL_BIND_TEXT(db, s, j, search->arch); - if (NULL != search->sec) - SQL_BIND_TEXT(db, s, j, search->sec); - for (ep = e; NULL != ep; ep = ep->next) { if (NULL == ep->substr) { SQL_BIND_BLOB(db, s, j, ep->regexp); @@ -480,7 +476,7 @@ sql_append(char **sql, size_t *sz, const char *newstr, int count) * Prepare the search SQL statement. */ static char * -sql_statement(const struct expr *e, const char *arch, const char *sec) +sql_statement(const struct expr *e) { char *sql; size_t sz; @@ -489,12 +485,6 @@ sql_statement(const struct expr *e, const char *arch, const char *sec) sql = mandoc_strdup("SELECT * FROM mpages WHERE "); sz = strlen(sql); - if (NULL != arch) - sql_append(&sql, &sz, "arch = ? AND ", 1); - if (NULL != sec) - sql_append(&sql, &sz, "sec = ? AND ", 1); - sql_append(&sql, &sz, "(", 1); - for (needop = 0; NULL != e; e = e->next) { if (e->and) sql_append(&sql, &sz, " AND ", 1); @@ -511,7 +501,6 @@ sql_statement(const struct expr *e, const char *arch, const char *sec) sql_append(&sql, &sz, ")", e->close); needop = 1; } - sql_append(&sql, &sz, ")", 1); return(sql); } @@ -528,7 +517,8 @@ exprcomp(const struct mansearch *search, int argc, char *argv[]) struct expr *first, *next, *cur; first = cur = NULL; - toopen = logic = igncase = toclose = 0; + logic = igncase = toclose = 0; + toopen = 1; for (i = 0; i < argc; i++) { if (0 == strcmp("(", argv[i])) { @@ -572,8 +562,15 @@ exprcomp(const struct mansearch *search, int argc, char *argv[]) cur = first = next; toopen = logic = igncase = 0; } - if ( ! (toopen || logic || igncase || toclose)) - return(first); + if (toopen || logic || igncase || toclose) + goto fail; + + cur->close++; + cur = exprspec(cur, TYPE_arch, search->arch, "^(%s|any)$"); + exprspec(cur, TYPE_sec, search->sec, "^%s$"); + + return(first); + fail: if (NULL != first) exprfree(first); @@ -581,11 +578,42 @@ fail: } static struct expr * +exprspec(struct expr *cur, uint64_t key, const char *value, + const char *format) +{ + char errbuf[BUFSIZ]; + char *cp; + int irc; + + if (NULL == value) + return(cur); + + if (-1 == asprintf(&cp, format, value)) { + perror(0); + exit((int)MANDOCLEVEL_SYSERR); + } + cur->next = mandoc_calloc(1, sizeof(struct expr)); + cur = cur->next; + cur->and = 1; + cur->bits = key; + if (0 != (irc = regcomp(&cur->regexp, cp, + REG_EXTENDED | REG_NOSUB | REG_ICASE))) { + regerror(irc, &cur->regexp, errbuf, sizeof(errbuf)); + fprintf(stderr, "regcomp: %s\n", errbuf); + cur->substr = value; + } + free(cp); + return(cur); +} + +static struct expr * exprterm(const struct mansearch *search, char *buf, int cs) { + char errbuf[BUFSIZ]; struct expr *e; char *key, *v; size_t i; + int irc; if ('\0' == *buf) return(NULL); @@ -614,8 +642,10 @@ exprterm(const struct mansearch *search, char *buf, int cs) e->bits = search->deftype; if ('~' == *v++) { - if (regcomp(&e->regexp, v, - REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE))) { + if (0 != (irc = regcomp(&e->regexp, v, + REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE)))) { + regerror(irc, &e->regexp, errbuf, sizeof(errbuf)); + fprintf(stderr, "regcomp: %s\n", errbuf); free(e); return(NULL); } |