version 1.11, 2011/11/23 09:55:28 |
version 1.12, 2011/11/26 22:38:11 |
Line 115 static const struct type types[] = { |
|
Line 115 static const struct type types[] = { |
|
}; |
}; |
|
|
static DB *btree_open(void); |
static DB *btree_open(void); |
static int btree_read(const DBT *, |
static int btree_read(const DBT *, |
const struct mchars *, char **); |
const struct mchars *, char **); |
static int expreval(const struct expr *, int *); |
static int expreval(const struct expr *, int *); |
static void exprexec(const struct expr *, |
static void exprexec(const struct expr *, |
const char *, uint64_t, struct rec *); |
const char *, uint64_t, struct rec *); |
static int exprmark(const struct expr *, |
static int exprmark(const struct expr *, |
const char *, uint64_t, int *); |
const char *, uint64_t, int *); |
static struct expr *exprexpr(int, char *[], int *, int *, size_t *); |
static struct expr *exprexpr(int, char *[], int *, int *, size_t *); |
static struct expr *exprterm(char *, int); |
static struct expr *exprterm(char *, int); |
Line 148 btree_open(void) |
|
Line 148 btree_open(void) |
|
info.flags = R_DUP; |
info.flags = R_DUP; |
|
|
db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info); |
db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info); |
if (NULL != db) |
if (NULL != db) |
return(db); |
return(db); |
|
|
return(NULL); |
return(NULL); |
Line 176 btree_read(const DBT *v, const struct mchars *mc, char |
|
Line 176 btree_read(const DBT *v, const struct mchars *mc, char |
|
/* |
/* |
* Take a Unicode codepoint and produce its UTF-8 encoding. |
* Take a Unicode codepoint and produce its UTF-8 encoding. |
* This isn't the best way to do this, but it works. |
* This isn't the best way to do this, but it works. |
* The magic numbers are from the UTF-8 packaging. |
* The magic numbers are from the UTF-8 packaging. |
* They're not as scary as they seem: read the UTF-8 spec for details. |
* They're not as scary as they seem: read the UTF-8 spec for details. |
*/ |
*/ |
static size_t |
static size_t |
Line 241 norm_string(const char *val, const struct mchars *mc, |
|
Line 241 norm_string(const char *val, const struct mchars *mc, |
|
const char *seq, *cpp; |
const char *seq, *cpp; |
int len, u, pos; |
int len, u, pos; |
enum mandoc_esc esc; |
enum mandoc_esc esc; |
static const char res[] = { '\\', '\t', |
static const char res[] = { '\\', '\t', |
ASCII_NBRSP, ASCII_HYPH, '\0' }; |
ASCII_NBRSP, ASCII_HYPH, '\0' }; |
|
|
/* Pre-allocate by the length of the input */ |
/* Pre-allocate by the length of the input */ |
Line 287 norm_string(const char *val, const struct mchars *mc, |
|
Line 287 norm_string(const char *val, const struct mchars *mc, |
|
if (ESCAPE_ERROR == esc) |
if (ESCAPE_ERROR == esc) |
break; |
break; |
|
|
/* |
/* |
* XXX - this just does UTF-8, but we need to know |
* XXX - this just does UTF-8, but we need to know |
* beforehand whether we should do text substitution. |
* beforehand whether we should do text substitution. |
*/ |
*/ |
Line 382 index_read(const DBT *key, const DBT *val, int index, |
|
Line 382 index_read(const DBT *key, const DBT *val, int index, |
|
*/ |
*/ |
int |
int |
apropos_search(int pathsz, char **paths, const struct opts *opts, |
apropos_search(int pathsz, char **paths, const struct opts *opts, |
const struct expr *expr, size_t terms, void *arg, |
const struct expr *expr, size_t terms, void *arg, |
void (*res)(struct res *, size_t, void *)) |
void (*res)(struct res *, size_t, void *)) |
{ |
{ |
struct rectree tree; |
struct rectree tree; |
Line 420 apropos_search(int pathsz, char **paths, const struct |
|
Line 420 apropos_search(int pathsz, char **paths, const struct |
|
|
|
for (mlen = i = 0; i < tree.len; i++) |
for (mlen = i = 0; i < tree.len; i++) |
if (tree.node[i].matched) |
if (tree.node[i].matched) |
memcpy(&ress[mlen++], &tree.node[i].res, |
memcpy(&ress[mlen++], &tree.node[i].res, |
sizeof(struct res)); |
sizeof(struct res)); |
|
|
(*res)(ress, mlen, arg); |
(*res)(ress, mlen, arg); |
Line 460 single_search(struct rectree *tree, const struct opts |
|
Line 460 single_search(struct rectree *tree, const struct opts |
|
|
|
memset(&r, 0, sizeof(struct rec)); |
memset(&r, 0, sizeof(struct rec)); |
|
|
if (NULL == (btree = btree_open())) |
if (NULL == (btree = btree_open())) |
return(1); |
return(1); |
|
|
if (NULL == (idx = index_open())) { |
if (NULL == (idx = index_open())) { |
Line 469 single_search(struct rectree *tree, const struct opts |
|
Line 469 single_search(struct rectree *tree, const struct opts |
|
} |
} |
|
|
while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) { |
while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) { |
if (key.size < 2 || sizeof(struct db_val) != val.size) |
if (key.size < 2 || sizeof(struct db_val) != val.size) |
break; |
break; |
if ( ! btree_read(&key, mc, &buf)) |
if ( ! btree_read(&key, mc, &buf)) |
break; |
break; |
|
|
Line 492 single_search(struct rectree *tree, const struct opts |
|
Line 492 single_search(struct rectree *tree, const struct opts |
|
*/ |
*/ |
|
|
for (leaf = root; leaf >= 0; ) |
for (leaf = root; leaf >= 0; ) |
if (rec > rs[leaf].res.rec && |
if (rec > rs[leaf].res.rec && |
rs[leaf].rhs >= 0) |
rs[leaf].rhs >= 0) |
leaf = rs[leaf].rhs; |
leaf = rs[leaf].rhs; |
else if (rec < rs[leaf].res.rec && |
else if (rec < rs[leaf].res.rec && |
rs[leaf].lhs >= 0) |
rs[leaf].lhs >= 0) |
leaf = rs[leaf].lhs; |
leaf = rs[leaf].lhs; |
else |
else |
break; |
break; |
|
|
/* |
/* |
Line 540 single_search(struct rectree *tree, const struct opts |
|
Line 540 single_search(struct rectree *tree, const struct opts |
|
(rs, (tree->len + 1) * sizeof(struct rec)); |
(rs, (tree->len + 1) * sizeof(struct rec)); |
|
|
memcpy(&rs[tree->len], &r, sizeof(struct rec)); |
memcpy(&rs[tree->len], &r, sizeof(struct rec)); |
rs[tree->len].matches = |
rs[tree->len].matches = |
mandoc_calloc(terms, sizeof(int)); |
mandoc_calloc(terms, sizeof(int)); |
|
|
exprexec(expr, buf, mask, &rs[tree->len]); |
exprexec(expr, buf, mask, &rs[tree->len]); |
|
|
/* Append to our tree. */ |
/* Append to our tree. */ |
|
|
if (leaf >= 0) { |
if (leaf >= 0) { |
Line 553 single_search(struct rectree *tree, const struct opts |
|
Line 554 single_search(struct rectree *tree, const struct opts |
|
rs[leaf].lhs = tree->len; |
rs[leaf].lhs = tree->len; |
} else |
} else |
root = tree->len; |
root = tree->len; |
|
|
memset(&r, 0, sizeof(struct rec)); |
memset(&r, 0, sizeof(struct rec)); |
tree->len++; |
tree->len++; |
} |
} |
|
|
(*btree->close)(btree); |
(*btree->close)(btree); |
(*idx->close)(idx); |
(*idx->close)(idx); |
|
|
Line 632 exprexpr(int argc, char *argv[], int *pos, int *lvl, s |
|
Line 633 exprexpr(int argc, char *argv[], int *pos, int *lvl, s |
|
log = 0; |
log = 0; |
|
|
if (NULL != e && 0 == strcmp("-a", argv[*pos])) |
if (NULL != e && 0 == strcmp("-a", argv[*pos])) |
log = 1; |
log = 1; |
else if (NULL != e && 0 == strcmp("-o", argv[*pos])) |
else if (NULL != e && 0 == strcmp("-o", argv[*pos])) |
log = 2; |
log = 2; |
|
|
|
|
exprfree(struct expr *p) |
exprfree(struct expr *p) |
{ |
{ |
struct expr *pp; |
struct expr *pp; |
|
|
while (NULL != p) { |
while (NULL != p) { |
if (p->subexpr) |
if (p->subexpr) |
exprfree(p->subexpr); |
exprfree(p->subexpr); |
Line 758 exprfree(struct expr *p) |
|
Line 759 exprfree(struct expr *p) |
|
} |
} |
|
|
static int |
static int |
exprmark(const struct expr *p, const char *cp, |
exprmark(const struct expr *p, const char *cp, |
uint64_t mask, int *ms) |
uint64_t mask, int *ms) |
{ |
{ |
|
|
Line 813 expreval(const struct expr *p, int *ms) |
|
Line 814 expreval(const struct expr *p, int *ms) |
|
for ( ; p->next && p->next->and; p = p->next) { |
for ( ; p->next && p->next->and; p = p->next) { |
/* Evaluate a subexpression, if applicable. */ |
/* Evaluate a subexpression, if applicable. */ |
if (p->next->subexpr && ! ms[p->next->index]) |
if (p->next->subexpr && ! ms[p->next->index]) |
ms[p->next->index] = |
ms[p->next->index] = |
expreval(p->next->subexpr, ms); |
expreval(p->next->subexpr, ms); |
match = match && ms[p->next->index]; |
match = match && ms[p->next->index]; |
} |
} |
Line 830 expreval(const struct expr *p, int *ms) |
|
Line 831 expreval(const struct expr *p, int *ms) |
|
* If this evaluates to true, mark the expression as satisfied. |
* If this evaluates to true, mark the expression as satisfied. |
*/ |
*/ |
static void |
static void |
exprexec(const struct expr *p, const char *cp, |
exprexec(const struct expr *e, const char *cp, |
uint64_t mask, struct rec *r) |
uint64_t mask, struct rec *r) |
{ |
{ |
|
|
assert(0 == r->matched); |
assert(0 == r->matched); |
exprmark(p, cp, mask, r->matches); |
exprmark(e, cp, mask, r->matches); |
r->matched = expreval(p, r->matches); |
r->matched = expreval(e, r->matches); |
} |
} |