]> git.cameronkatri.com Git - mandoc.git/blobdiff - apropos_db.c
In apropos_db.c, move all btree reading (and safety checks) into the
[mandoc.git] / apropos_db.c
index 4a83a3bb879877312b16acf7b0d628477eab195e..4d9ae874601f577466a3e6d99652908080debc97 100644 (file)
@@ -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.17 2011/12/01 23:46:26 kristaps Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -24,6 +24,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <arpa/inet.h>
+
 #ifdef __linux__
 # include <db_185.h>
 #else
@@ -52,7 +54,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 */
@@ -115,8 +116,9 @@ static      const struct type types[] = {
 };
 
 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 +161,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)
 {
+       const struct db_val *vp;
 
-       /* Sanity: are we nil-terminated? */
-
-       assert(v->size > 0);
+       /* Are our sizes sane? */
+       if (k->size < 2 || sizeof(struct db_val) != v->size)
+               return(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);
+       vp = v->data;
+       norm_string((const char *)k->data, mc, buf);
+       dbv->rec = ntohl(vp->rec);
+       dbv->mask = vp->mask;
        return(1);
 }
 
@@ -443,14 +452,12 @@ single_search(struct rectree *tree, const struct opts *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 +477,14 @@ single_search(struct rectree *tree, const struct opts *opts,
        }
 
        while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) {
-               if (key.size < 2 || sizeof(struct db_val) != val.size)
-                       break;
-               if ( ! btree_read(&key, mc, &buf))
+               if ( ! btree_read(&key, &val, mc, &vb, &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 +494,10 @@ single_search(struct rectree *tree, const struct opts *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 +509,9 @@ 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].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 +521,7 @@ single_search(struct rectree *tree, const struct opts *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))
@@ -544,12 +545,12 @@ single_search(struct rectree *tree, const struct opts *opts,
                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;
@@ -571,6 +572,7 @@ static void
 recfree(struct rec *rec)
 {
 
+       free(rec->res.type);
        free(rec->res.file);
        free(rec->res.cat);
        free(rec->res.title);
@@ -599,10 +601,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 +612,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 +696,6 @@ exprexpr(int argc, char *argv[], int *pos, int *lvl, size_t *tt)
                        ++(*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 +746,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 +817,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);