=================================================================== RCS file: /cvs/mandoc/Attic/apropos_db.c,v retrieving revision 1.29 retrieving revision 1.32.2.4 diff -u -p -r1.29 -r1.32.2.4 --- mandoc/Attic/apropos_db.c 2012/03/23 05:07:35 1.29 +++ mandoc/Attic/apropos_db.c 2014/01/22 21:02:54 1.32.2.4 @@ -1,7 +1,7 @@ -/* $Id: apropos_db.c,v 1.29 2012/03/23 05:07:35 kristaps Exp $ */ +/* $Id: apropos_db.c,v 1.32.2.4 2014/01/22 21:02:54 schwarze Exp $ */ /* - * Copyright (c) 2011 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2011, 2012 Kristaps Dzonsons + * Copyright (c) 2011, 2014 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,6 +19,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -28,12 +30,18 @@ #include #include -#if defined(__linux__) +#if defined(__APPLE__) +# include +#elif defined(__linux__) # include +#elif defined(__sun) +# include +#else +# include +#endif + +#if defined(__linux__) || defined(__sun) # include -#elif defined(__APPLE__) -# include -# include #else # include #endif @@ -42,19 +50,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 +77,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 +131,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); @@ -256,8 +259,8 @@ norm_string(const char *val, const struct mchars *mc, const char *seq, *cpp; int len, u, pos; enum mandoc_esc esc; - static const char res[] = { '\\', '\t', - ASCII_NBRSP, ASCII_HYPH, '\0' }; + static const char res[] = { '\\', '\t', ASCII_NBRSP, + ASCII_HYPH, ASCII_BREAK, '\0' }; /* Pre-allocate by the length of the input */ @@ -277,16 +280,24 @@ norm_string(const char *val, const struct mchars *mc, val += (int)sz; } - if (ASCII_HYPH == *val) { + switch (*val) { + case (ASCII_HYPH): (*buf)[pos++] = '-'; val++; continue; - } else if ('\t' == *val || ASCII_NBRSP == *val) { + case ('\t'): + /* FALLTHROUGH */ + case (ASCII_NBRSP): (*buf)[pos++] = ' '; val++; + /* FALLTHROUGH */ + case (ASCII_BREAK): continue; - } else if ('\\' != *val) + default: break; + } + if ('\\' != *val) + break; /* Read past the slash. */ @@ -361,7 +372,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 +392,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 +422,18 @@ 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; memset(&tree, 0, sizeof(struct rectree)); - rc = 0; mc = mchars_alloc(); + *sz = 0; + *resp = NULL; /* * Main loop. Change into the directory containing manpage @@ -429,39 +441,22 @@ apropos_search(int pathsz, char **paths, const struct */ for (i = 0; i < pathsz; i++) { + assert('/' == paths[i][0]); if (chdir(paths[i])) continue; - if ( ! single_search(&tree, opts, expr, terms, mc, i)) - goto out; + if (single_search(&tree, opts, expr, terms, mc, i)) + continue; + + resfree(tree.node, tree.len); + mchars_free(mc); + return(0); } - /* - * 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); - - rc = 1; -out: - for (i = 0; i < tree.len; i++) - recfree(&tree.node[i]); - - 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 +468,8 @@ single_search(struct rectree *tree, const struct 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 +480,7 @@ single_search(struct rectree *tree, const struct 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 +508,10 @@ single_search(struct rectree *tree, const struct 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 +523,7 @@ 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].rec == rec) { if (0 == rs[leaf].matched) exprexec(expr, buf, mask, &rs[leaf]); continue; @@ -552,18 +547,18 @@ single_search(struct rectree *tree, const struct 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 +567,7 @@ single_search(struct rectree *tree, const struct 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 +581,18 @@ single_search(struct rectree *tree, const struct 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 +883,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);