summaryrefslogtreecommitdiffstats
path: root/apropos_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'apropos_db.c')
-rw-r--r--apropos_db.c140
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);