=================================================================== RCS file: /cvs/mandoc/Attic/apropos_db.c,v retrieving revision 1.12 retrieving revision 1.16 diff -u -p -r1.12 -r1.16 --- mandoc/Attic/apropos_db.c 2011/11/26 22:38:11 1.12 +++ mandoc/Attic/apropos_db.c 2011/11/29 10:53:42 1.16 @@ -1,4 +1,4 @@ -/* $Id: apropos_db.c,v 1.12 2011/11/26 22:38:11 schwarze Exp $ */ +/* $Id: apropos_db.c,v 1.16 2011/11/29 10:53:42 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -52,7 +52,6 @@ struct expr { int regex; /* is regex? */ int index; /* index in match array */ uint64_t mask; /* type-mask */ - int cs; /* is case-sensitive? */ int and; /* is rhs of logical AND? */ char *v; /* search value */ regex_t re; /* compiled re, if regex */ @@ -366,6 +365,7 @@ index_read(const DBT *key, const DBT *val, int index, rec->res.rec = *(recno_t *)key->data; rec->res.volume = index; + INDEX_BREAD(rec->res.type); INDEX_BREAD(rec->res.file); INDEX_BREAD(rec->res.cat); INDEX_BREAD(rec->res.title); @@ -579,7 +579,50 @@ recfree(struct rec *rec) free(rec->matches); } +/* + * Compile a list of straight-up terms. + * The arguments are re-written into ~[[:<:]]term[[:>:]], or "term" + * surrounded by word boundaries, then pumped through exprterm(). + * Terms are case-insensitive. + * This emulates whatis(1) behaviour. + */ struct expr * +termcomp(int argc, char *argv[], size_t *tt) +{ + char *buf; + int pos; + struct expr *e, *next; + size_t sz; + + buf = NULL; + e = NULL; + *tt = 0; + + for (pos = argc - 1; pos >= 0; pos--) { + sz = strlen(argv[pos]) + 18; + buf = mandoc_realloc(buf, sz); + strlcpy(buf, "Nm~[[:<:]]", sz); + strlcat(buf, argv[pos], sz); + strlcat(buf, "[[:>:]]", sz); + if (NULL == (next = exprterm(buf, 0))) { + free(buf); + exprfree(e); + return(NULL); + } + next->next = e; + e = next; + (*tt)++; + } + + free(buf); + return(e); +} + +/* + * Compile a sequence of logical expressions. + * See apropos.1 for a grammar of this sequence. + */ +struct expr * exprcomp(int argc, char *argv[], size_t *tt) { int pos, lvl; @@ -650,7 +693,6 @@ exprexpr(int argc, char *argv[], int *pos, int *lvl, s ++(*pos); ++(*lvl); next = mandoc_calloc(1, sizeof(struct expr)); - next->cs = 1; next->subexpr = exprexpr(argc, argv, pos, lvl, tt); if (NULL == next->subexpr) { free(next); @@ -701,8 +743,6 @@ exprterm(char *buf, int cs) memset(&e, 0, sizeof(struct expr)); - e.cs = cs; - /* Choose regex or substring match. */ if (NULL == (e.v = strpbrk(buf, "=~"))) { @@ -729,7 +769,7 @@ exprterm(char *buf, int cs) e.mask = TYPE_Nm | TYPE_Nd; if (e.regex) { - i = REG_EXTENDED | REG_NOSUB | cs ? 0 : REG_ICASE; + i = REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE); if (regcomp(&e.re, e.v, i)) return(NULL); } @@ -774,13 +814,8 @@ exprmark(const struct expr *p, const char *cp, if (p->regex) { if (regexec(&p->re, cp, 0, NULL, 0)) continue; - } else if (p->cs) { - if (NULL == strstr(cp, p->v)) - continue; - } else { - if (NULL == strcasestr(cp, p->v)) - continue; - } + } else if (NULL == strcasestr(cp, p->v)) + continue; if (NULL == ms) return(1);