=================================================================== RCS file: /cvs/mandoc/Attic/apropos_db.c,v retrieving revision 1.14 retrieving revision 1.27 diff -u -p -r1.14 -r1.27 --- mandoc/Attic/apropos_db.c 2011/11/27 23:11:37 1.14 +++ mandoc/Attic/apropos_db.c 2011/12/20 21:41:11 1.27 @@ -1,4 +1,4 @@ -/* $Id: apropos_db.c,v 1.14 2011/11/27 23:11:37 schwarze Exp $ */ +/* $Id: apropos_db.c,v 1.27 2011/12/20 21:41:11 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -15,6 +15,10 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -24,8 +28,12 @@ #include #include -#ifdef __linux__ +#if defined(__linux__) +# include # include +#elif defined(__APPLE__) +# include +# include #else # include #endif @@ -52,7 +60,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 */ @@ -110,13 +117,14 @@ static const struct type types[] = { { TYPE_Va, "Va" }, { TYPE_Va, "Vt" }, { TYPE_Xr, "Xr" }, - { INT_MAX, "any" }, + { UINT64_MAX, "any" }, { 0, NULL } }; static DB *btree_open(void); -static int btree_read(const DBT *, - const struct mchars *, char **); +static int btree_read(const DBT *, const DBT *, + const struct mchars *, + struct db_val *, char **); static int expreval(const struct expr *, int *); static void exprexec(const struct expr *, const char *, uint64_t, struct rec *); @@ -159,17 +167,24 @@ btree_open(void) * Return 0 if the database is insane, else 1. */ static int -btree_read(const DBT *v, const struct mchars *mc, char **buf) +btree_read(const DBT *k, const DBT *v, + const struct mchars *mc, + struct db_val *dbv, char **buf) { + struct db_val raw_dbv; - /* Sanity: are we nil-terminated? */ + /* Are our sizes sane? */ + if (k->size < 2 || sizeof(struct db_val) != v->size) + return(0); - assert(v->size > 0); - - if ('\0' != ((char *)v->data)[(int)v->size - 1]) + /* Is our string nil-terminated? */ + if ('\0' != ((const char *)k->data)[(int)k->size - 1]) return(0); - norm_string((char *)v->data, mc, buf); + norm_string((const char *)k->data, mc, buf); + memcpy(&raw_dbv, v->data, v->size); + dbv->rec = betoh32(raw_dbv.rec); + dbv->mask = betoh64(raw_dbv.mask); return(1); } @@ -182,7 +197,7 @@ btree_read(const DBT *v, const struct mchars *mc, char static size_t norm_utf8(unsigned int cp, char out[7]) { - size_t rc; + int rc; rc = 0; @@ -223,7 +238,7 @@ norm_utf8(unsigned int cp, char out[7]) return(0); out[rc] = '\0'; - return(rc); + return((size_t)rc); } /* @@ -350,6 +365,7 @@ index_read(const DBT *key, const DBT *val, int index, { size_t left; char *np, *cp; + char type; #define INDEX_BREAD(_dst) \ do { \ @@ -360,13 +376,24 @@ index_read(const DBT *key, const DBT *val, int index, cp = np + 1; \ } while (/* CONSTCOND */ 0) - left = val->size; - cp = (char *)val->data; + if (0 == (left = val->size)) + return(0); - rec->res.rec = *(recno_t *)key->data; + cp = val->data; + assert(sizeof(recno_t) == key->size); + memcpy(&rec->res.rec, key->data, key->size); rec->res.volume = index; - INDEX_BREAD(rec->res.type); + if ('d' == (type = *cp++)) + rec->res.type = RESTYPE_MDOC; + else if ('a' == type) + rec->res.type = RESTYPE_MAN; + else if ('c' == type) + rec->res.type = RESTYPE_CAT; + else + return(0); + + left--; INDEX_BREAD(rec->res.file); INDEX_BREAD(rec->res.cat); INDEX_BREAD(rec->res.title); @@ -443,14 +470,12 @@ single_search(struct rectree *tree, const struct opts struct mchars *mc, int vol) { int root, leaf, ch; - uint64_t mask; DBT key, val; DB *btree, *idx; char *buf; - recno_t rec; struct rec *rs; struct rec r; - struct db_val *vbuf; + struct db_val vb; root = -1; leaf = -1; @@ -470,20 +495,14 @@ single_search(struct rectree *tree, const struct opts } while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) { - if (key.size < 2 || sizeof(struct db_val) != val.size) + if ( ! btree_read(&key, &val, mc, &vb, &buf)) break; - if ( ! btree_read(&key, mc, &buf)) - break; - vbuf = val.data; - rec = vbuf->rec; - mask = vbuf->mask; - /* * See if this keyword record matches any of the * expressions we have stored. */ - if ( ! exprmark(expr, buf, mask, NULL)) + if ( ! exprmark(expr, buf, vb.mask, NULL)) continue; /* @@ -493,10 +512,10 @@ single_search(struct rectree *tree, const struct opts */ for (leaf = root; leaf >= 0; ) - if (rec > rs[leaf].res.rec && + if (vb.rec > rs[leaf].res.rec && rs[leaf].rhs >= 0) leaf = rs[leaf].rhs; - else if (rec < rs[leaf].res.rec && + else if (vb.rec < rs[leaf].res.rec && rs[leaf].lhs >= 0) leaf = rs[leaf].lhs; else @@ -508,9 +527,9 @@ single_search(struct rectree *tree, const struct opts * try to evaluate it now and continue anyway. */ - if (leaf >= 0 && rs[leaf].res.rec == rec) { + if (leaf >= 0 && rs[leaf].res.rec == vb.rec) { if (0 == rs[leaf].matched) - exprexec(expr, buf, mask, &rs[leaf]); + exprexec(expr, buf, vb.mask, &rs[leaf]); continue; } @@ -520,7 +539,7 @@ single_search(struct rectree *tree, const struct opts * database, then begin partial evaluation. */ - key.data = &rec; + key.data = &vb.rec; key.size = sizeof(recno_t); if (0 != (*idx->get)(idx, &key, &val, 0)) @@ -534,29 +553,31 @@ single_search(struct rectree *tree, const struct opts if (opts->cat && strcasecmp(opts->cat, r.res.cat)) continue; - if (opts->arch && strcasecmp(opts->arch, r.res.arch)) - continue; + if (opts->arch && *r.res.arch) + if (strcasecmp(opts->arch, r.res.arch)) + continue; + tree->node = rs = mandoc_realloc (rs, (tree->len + 1) * sizeof(struct rec)); memcpy(&rs[tree->len], &r, sizeof(struct rec)); + memset(&r, 0, sizeof(struct rec)); rs[tree->len].matches = mandoc_calloc(terms, sizeof(int)); - exprexec(expr, buf, mask, &rs[tree->len]); + exprexec(expr, buf, vb.mask, &rs[tree->len]); /* Append to our tree. */ if (leaf >= 0) { - if (rec > rs[leaf].res.rec) + if (vb.rec > rs[leaf].res.rec) rs[leaf].rhs = tree->len; else rs[leaf].lhs = tree->len; } else root = tree->len; - memset(&r, 0, sizeof(struct rec)); tree->len++; } @@ -564,6 +585,7 @@ single_search(struct rectree *tree, const struct opts (*idx->close)(idx); free(buf); + recfree(&r); return(1 == ch); } @@ -599,10 +621,10 @@ termcomp(int argc, char *argv[], size_t *tt) e = NULL; *tt = 0; - for (pos = 0; pos < argc; pos++) { - sz = strlen(argv[pos]) + 16; + for (pos = argc - 1; pos >= 0; pos--) { + sz = strlen(argv[pos]) + 18; buf = mandoc_realloc(buf, sz); - strlcpy(buf, "~[[:<:]]", sz); + strlcpy(buf, "Nm~[[:<:]]", sz); strlcat(buf, argv[pos], sz); strlcat(buf, "[[:>:]]", sz); if (NULL == (next = exprterm(buf, 0))) { @@ -610,8 +632,7 @@ termcomp(int argc, char *argv[], size_t *tt) exprfree(e); return(NULL); } - if (NULL != e) - e->next = next; + next->next = e; e = next; (*tt)++; } @@ -695,7 +716,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); @@ -746,8 +766,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, "=~"))) { @@ -819,13 +837,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);