diff options
Diffstat (limited to 'apropos_db.c')
-rw-r--r-- | apropos_db.c | 140 |
1 files changed, 58 insertions, 82 deletions
diff --git a/apropos_db.c b/apropos_db.c index 68eb5bba..78c2b118 100644 --- a/apropos_db.c +++ b/apropos_db.c @@ -42,19 +42,15 @@ #include "apropos_db.h" #include "mandoc.h" -struct rec { - struct res res; /* resulting record info */ - /* - * Maintain a binary tree for checking the uniqueness of `rec' - * when adding elements to the results array. - * Since the results array is dynamic, use offset in the array - * instead of a pointer to the structure. - */ - int lhs; - int rhs; - int matched; /* expression is true */ - int *matches; /* partial truth evaluations */ -}; +#define RESFREE(_x) \ + do { \ + free((_x)->file); \ + free((_x)->cat); \ + free((_x)->title); \ + free((_x)->arch); \ + free((_x)->desc); \ + free((_x)->matches); \ + } while (/*CONSTCOND*/0) struct expr { int regex; /* is regex? */ @@ -73,7 +69,7 @@ struct type { }; struct rectree { - struct rec *node; /* record array for dir tree */ + struct res *node; /* record array for dir tree */ int len; /* length of record array */ }; @@ -127,18 +123,17 @@ static int btree_read(const DBT *, const DBT *, uint64_t *, recno_t *, char **); static int expreval(const struct expr *, int *); static void exprexec(const struct expr *, - const char *, uint64_t, struct rec *); + const char *, uint64_t, struct res *); static int exprmark(const struct expr *, const char *, uint64_t, int *); static struct expr *exprexpr(int, char *[], int *, int *, size_t *); static struct expr *exprterm(char *, int); static DB *index_open(void); static int index_read(const DBT *, const DBT *, int, - const struct mchars *, struct rec *); + const struct mchars *, struct res *); static void norm_string(const char *, const struct mchars *, char **); static size_t norm_utf8(unsigned int, char[7]); -static void recfree(struct rec *); static int single_search(struct rectree *, const struct opts *, const struct expr *, size_t terms, struct mchars *, int); @@ -361,7 +356,7 @@ index_open(void) */ static int index_read(const DBT *key, const DBT *val, int index, - const struct mchars *mc, struct rec *rec) + const struct mchars *mc, struct res *rec) { size_t left; char *np, *cp; @@ -381,24 +376,24 @@ index_read(const DBT *key, const DBT *val, int index, cp = val->data; assert(sizeof(recno_t) == key->size); - memcpy(&rec->res.rec, key->data, key->size); - rec->res.volume = index; + memcpy(&rec->rec, key->data, key->size); + rec->volume = index; if ('d' == (type = *cp++)) - rec->res.type = RESTYPE_MDOC; + rec->type = RESTYPE_MDOC; else if ('a' == type) - rec->res.type = RESTYPE_MAN; + rec->type = RESTYPE_MAN; else if ('c' == type) - rec->res.type = RESTYPE_CAT; + rec->type = RESTYPE_CAT; else return(0); left--; - INDEX_BREAD(rec->res.file); - INDEX_BREAD(rec->res.cat); - INDEX_BREAD(rec->res.title); - INDEX_BREAD(rec->res.arch); - INDEX_BREAD(rec->res.desc); + INDEX_BREAD(rec->file); + INDEX_BREAD(rec->cat); + INDEX_BREAD(rec->title); + INDEX_BREAD(rec->arch); + INDEX_BREAD(rec->desc); return(1); } @@ -411,17 +406,19 @@ index_read(const DBT *key, const DBT *val, int index, int apropos_search(int pathsz, char **paths, const struct opts *opts, const struct expr *expr, size_t terms, void *arg, + size_t *sz, struct res **resp, void (*res)(struct res *, size_t, void *)) { struct rectree tree; struct mchars *mc; - struct res *ress; - int i, mlen, rc; + int i, rc; memset(&tree, 0, sizeof(struct rectree)); rc = 0; mc = mchars_alloc(); + *sz = 0; + *resp = NULL; /* * Main loop. Change into the directory containing manpage @@ -431,37 +428,19 @@ apropos_search(int pathsz, char **paths, const struct opts *opts, for (i = 0; i < pathsz; i++) { if (chdir(paths[i])) continue; - if ( ! single_search(&tree, opts, expr, terms, mc, i)) - goto out; - } - - /* - * Count matching files, transfer to a "clean" array, then feed - * them to the output handler. - */ - - for (mlen = i = 0; i < tree.len; i++) - if (tree.node[i].matched) - mlen++; - - ress = mandoc_malloc(mlen * sizeof(struct res)); - - for (mlen = i = 0; i < tree.len; i++) - if (tree.node[i].matched) - memcpy(&ress[mlen++], &tree.node[i].res, - sizeof(struct res)); - - (*res)(ress, mlen, arg); - free(ress); + if (single_search(&tree, opts, expr, terms, mc, i)) + continue; - rc = 1; -out: - for (i = 0; i < tree.len; i++) - recfree(&tree.node[i]); + resfree(tree.node, tree.len); + mchars_free(mc); + return(0); + } - free(tree.node); + (*res)(tree.node, tree.len, arg); + *sz = tree.len; + *resp = tree.node; mchars_free(mc); - return(rc); + return(1); } static int @@ -473,8 +452,8 @@ single_search(struct rectree *tree, const struct opts *opts, DBT key, val; DB *btree, *idx; char *buf; - struct rec *rs; - struct rec r; + struct res *rs; + struct res r; uint64_t mask; recno_t rec; @@ -485,7 +464,7 @@ single_search(struct rectree *tree, const struct opts *opts, buf = NULL; rs = tree->node; - memset(&r, 0, sizeof(struct rec)); + memset(&r, 0, sizeof(struct res)); if (NULL == (btree = btree_open())) return(1); @@ -513,10 +492,10 @@ single_search(struct rectree *tree, const struct opts *opts, */ for (leaf = root; leaf >= 0; ) - if (rec > rs[leaf].res.rec && + if (rec > rs[leaf].rec && rs[leaf].rhs >= 0) leaf = rs[leaf].rhs; - else if (rec < rs[leaf].res.rec && + else if (rec < rs[leaf].rec && rs[leaf].lhs >= 0) leaf = rs[leaf].lhs; else @@ -528,7 +507,7 @@ single_search(struct rectree *tree, const struct opts *opts, * try to evaluate it now and continue anyway. */ - if (leaf >= 0 && rs[leaf].res.rec == rec) { + if (leaf >= 0 && rs[leaf].rec == rec) { if (0 == rs[leaf].matched) exprexec(expr, buf, mask, &rs[leaf]); continue; @@ -552,18 +531,18 @@ single_search(struct rectree *tree, const struct opts *opts, /* XXX: this should be elsewhere, I guess? */ - if (opts->cat && strcasecmp(opts->cat, r.res.cat)) + if (opts->cat && strcasecmp(opts->cat, r.cat)) continue; - if (opts->arch && *r.res.arch) - if (strcasecmp(opts->arch, r.res.arch)) + if (opts->arch && *r.arch) + if (strcasecmp(opts->arch, r.arch)) continue; tree->node = rs = mandoc_realloc - (rs, (tree->len + 1) * sizeof(struct rec)); + (rs, (tree->len + 1) * sizeof(struct res)); - memcpy(&rs[tree->len], &r, sizeof(struct rec)); - memset(&r, 0, sizeof(struct rec)); + memcpy(&rs[tree->len], &r, sizeof(struct res)); + memset(&r, 0, sizeof(struct res)); rs[tree->len].matches = mandoc_calloc(terms, sizeof(int)); @@ -572,7 +551,7 @@ single_search(struct rectree *tree, const struct opts *opts, /* Append to our tree. */ if (leaf >= 0) { - if (rec > rs[leaf].res.rec) + if (rec > rs[leaf].rec) rs[leaf].rhs = tree->len; else rs[leaf].lhs = tree->len; @@ -586,21 +565,18 @@ single_search(struct rectree *tree, const struct opts *opts, (*idx->close)(idx); free(buf); - recfree(&r); + RESFREE(&r); return(1 == ch); } -static void -recfree(struct rec *rec) +void +resfree(struct res *rec, size_t sz) { + size_t i; - free(rec->res.file); - free(rec->res.cat); - free(rec->res.title); - free(rec->res.arch); - free(rec->res.desc); - - free(rec->matches); + for (i = 0; i < sz; i++) + RESFREE(&rec[i]); + free(rec); } /* @@ -891,7 +867,7 @@ expreval(const struct expr *p, int *ms) */ static void exprexec(const struct expr *e, const char *cp, - uint64_t mask, struct rec *r) + uint64_t mask, struct res *r) { assert(0 == r->matched); |