From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from scc-mailout.scc.kit.edu (scc-mailout.scc.kit.edu [129.13.185.202]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id pAGGQYau005228 for ; Wed, 16 Nov 2011 11:26:36 -0500 (EST) Received: from hekate.usta.de (asta-nat.asta.uni-karlsruhe.de [172.22.63.82]) by scc-mailout-02.scc.kit.edu with esmtp (Exim 4.72 #1) id 1RQiJl-0000FQ-CV; Wed, 16 Nov 2011 17:26:33 +0100 Received: from donnerwolke.usta.de ([172.24.96.3]) by hekate.usta.de with esmtp (Exim 4.72) (envelope-from ) id 1RQiJl-0003fE-Ge for tech@mdocml.bsd.lv; Wed, 16 Nov 2011 17:26:33 +0100 Received: from iris.usta.de ([172.24.96.5] helo=usta.de) by donnerwolke.usta.de with esmtp (Exim 4.72) (envelope-from ) id 1RQiJl-0005PC-F5 for tech@mdocml.bsd.lv; Wed, 16 Nov 2011 17:26:33 +0100 Received: from schwarze by usta.de with local (Exim 4.72) (envelope-from ) id 1RQiJk-0007aO-Vp for tech@mdocml.bsd.lv; Wed, 16 Nov 2011 17:26:33 +0100 Date: Wed, 16 Nov 2011 17:26:32 +0100 From: Ingo Schwarze To: tech@mdocml.bsd.lv Subject: Re: minimal use of man.conf for mandocdb and apropos Message-ID: <20111116162632.GM31182@iris.usta.de> References: <20111115135614.GA1100@iris.usta.de> X-Mailinglist: mdocml-tech Reply-To: tech@mdocml.bsd.lv MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20111115135614.GA1100@iris.usta.de> User-Agent: Mutt/1.5.21 (2010-09-15) Hi, > here is a first draft to use the _whatdb entry in man.conf(5) > for processing multiple manpage hierarchies during a single > call to mandocdb(8) or apropos(1). Updated after resolving the conflicts with kristaps@' recent work on logical operators. > Obviously, this is critical for getting apropos(1) usable in > practice; to replace makewhatis(8) with mandocdb, it's needed > there, too. > > A few remarks: > * For now, i have not copied the full man.conf parser from > /usr/src/usr.bin/man/config.c, but written a simpler one. > * Because apropos_search wants to sort the complete results - > usually spanning multiple databases - we have to pass the > pathes in and iterate inside apropos_search. > * Changing the directory into the manpage hierarchies > is required to handle .so files. Bleah. > * When processing multiple databases, mandocdb(8) needs to > close each database before opening the next one; there's > a leak right now, fixed here. > * Adjusting cgi.c is expected to be trivial. > * Simple adjustments are needed to the mandocdb(8) and apropos(1) > manuals. > * The handling of the apropos(1) -C, -M and -m options is still > missing, but not difficult to implement. An implementation of apropos -M and -m is now contained as well. OK? Ingo Index: Makefile =================================================================== RCS file: /cvs/src/usr.bin/mandoc/Makefile,v retrieving revision 1.63 diff -u -p -r1.63 Makefile --- Makefile 13 Nov 2011 09:58:21 -0000 1.63 +++ Makefile 16 Nov 2011 16:23:46 -0000 @@ -18,7 +18,7 @@ SRCS+= main.c mdoc_term.c chars.c term.c SRCS+= mdoc_man.c SRCS+= html.c mdoc_html.c man_html.c out.c eqn_html.c SRCS+= term_ps.c term_ascii.c tbl_term.c tbl_html.c -SRCS+= mandocdb.c apropos_db.c apropos.c +SRCS+= man_conf.c mandocdb.c apropos_db.c apropos.c PROG= mandoc Index: apropos.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/apropos.c,v retrieving revision 1.5 diff -u -p -r1.5 apropos.c --- apropos.c 16 Nov 2011 13:23:27 -0000 1.5 +++ apropos.c 16 Nov 2011 16:23:46 -0000 @@ -22,6 +22,7 @@ #include #include "apropos_db.h" +#include "man_conf.h" #include "mandoc.h" static int cmp(const void *, const void *); @@ -33,14 +34,17 @@ static char *progname; int apropos(int argc, char *argv[]) { - int ch; + struct man_conf dirs; + int ch, use_man_conf; size_t terms; struct opts opts; struct expr *e; extern int optind; extern char *optarg; + memset(&dirs, 0, sizeof(struct man_conf)); memset(&opts, 0, sizeof(struct opts)); + use_man_conf = 1; progname = strrchr(argv[0], '/'); if (progname == NULL) @@ -48,8 +52,14 @@ apropos(int argc, char *argv[]) else ++progname; - while (-1 != (ch = getopt(argc, argv, "S:s:"))) + while (-1 != (ch = getopt(argc, argv, "M:m:S:s:"))) switch (ch) { + case ('M'): + use_man_conf = 0; + /* FALLTHROUGH */ + case ('m'): + manpath_parse(&dirs, optarg); + break; case ('S'): opts.arch = optarg; break; @@ -79,7 +89,12 @@ apropos(int argc, char *argv[]) * The index database is a recno. */ - apropos_search(&opts, e, terms, NULL, list); + if (use_man_conf) + man_conf_parse(&dirs); + apropos_search(dirs.argc, dirs.argv, &opts, + e, terms, NULL, list); + + man_conf_free(&dirs); exprfree(e); return(EXIT_SUCCESS); } @@ -113,7 +128,8 @@ usage(void) { fprintf(stderr, "usage: %s " - "[-I] " + "[-M path] " + "[-m path] " "[-S arch] " "[-s section] " "EXPR\n", Index: apropos_db.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/apropos_db.c,v retrieving revision 1.4 diff -u -p -r1.4 apropos_db.c --- apropos_db.c 16 Nov 2011 13:23:27 -0000 1.4 +++ apropos_db.c 16 Nov 2011 16:23:46 -0000 @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef __linux__ # include @@ -32,6 +33,11 @@ #include "apropos_db.h" #include "mandoc.h" +struct rectree { + struct rec *node; + int len; +}; + struct expr { int regex; int index; @@ -79,6 +85,9 @@ 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 void single_search(struct rectree *, const struct opts *, + const struct expr *, size_t terms, + struct mchars *); /* * Open the keyword mandoc-db database. @@ -323,35 +332,73 @@ index_read(const DBT *key, const DBT *va * Call "res" with the results, which may be zero. */ void -apropos_search(const struct opts *opts, const struct expr *expr, - size_t terms, void *arg, +apropos_search(int argc, char *argv[], const struct opts *opts, + const struct expr *expr, size_t terms, void *arg, void (*res)(struct rec *, size_t, void *)) { - int i, len, root, leaf, mask, mlen; + struct rectree tree; + struct mchars *mc; + struct rec *recs; + int i, mlen; + + memset(&tree, 0, sizeof(struct rectree)); + + /* XXX: error out with bad regexp? */ + + mc = mchars_alloc(); + + for (i = 0; i < argc; i++) { + if (chdir(argv[i])) + continue; + single_search(&tree, opts, expr, terms, mc); + } + + /* + * Count the matching files + * and feed them to the output handler. + */ + + for (mlen = i = 0; i < tree.len; i++) + if (tree.node[i].matches[0]) + mlen++; + recs = mandoc_malloc(mlen * sizeof(struct rec)); + for (mlen = i = 0; i < tree.len; i++) + if (tree.node[i].matches[0]) + memcpy(&recs[mlen++], &tree.node[i], + sizeof(struct rec)); + (*res)(recs, mlen, arg); + free(recs); + + for (i = 0; i < tree.len; i++) + recfree(&tree.node[i]); + + if (mc) + mchars_free(mc); +} + +static void +single_search(struct rectree *tree, const struct opts *opts, + const struct expr *expr, size_t terms, + struct mchars *mc) +{ + int root, leaf, mask; DBT key, val; DB *btree, *idx; - struct mchars *mc; int ch; char *buf; recno_t rec; - struct rec *recs, *rrecs; + struct rec *recs; struct rec srec; root = -1; leaf = -1; btree = NULL; idx = NULL; - mc = NULL; buf = NULL; - recs = NULL; - len = 0; + recs = tree->node; memset(&srec, 0, sizeof(struct rec)); - /* XXX: error out with bad regexp? */ - - mc = mchars_alloc(); - /* XXX: return fact that we've errored? */ if (NULL == (btree = btree_open())) @@ -423,60 +470,42 @@ apropos_search(const struct opts *opts, if (opts->arch && strcasecmp(opts->arch, srec.arch)) continue; - recs = mandoc_realloc - (recs, (len + 1) * sizeof(struct rec)); + tree->node = recs = mandoc_realloc + (recs, (tree->len + 1) * sizeof(struct rec)); - memcpy(&recs[len], &srec, sizeof(struct rec)); - recs[len].matches = + memcpy(&recs[tree->len], &srec, sizeof(struct rec)); + recs[tree->len].matches = mandoc_calloc(terms + 1, sizeof(int)); exprexecpost (expr, buf, mask, - recs[len].matches, terms); + recs[tree->len].matches, terms); /* Append to our tree. */ if (leaf >= 0) { if (rec > recs[leaf].rec) - recs[leaf].rhs = len; + recs[leaf].rhs = tree->len; else - recs[leaf].lhs = len; + recs[leaf].lhs = tree->len; } else - root = len; + root = tree->len; memset(&srec, 0, sizeof(struct rec)); - len++; + tree->len++; } - if (1 == ch) { - for (mlen = i = 0; i < len; i++) - if (recs[i].matches[0]) - mlen++; - rrecs = mandoc_malloc(mlen * sizeof(struct rec)); - for (mlen = i = 0; i < len; i++) - if (recs[i].matches[0]) - memcpy(&rrecs[mlen++], &recs[i], - sizeof(struct rec)); - (*res)(rrecs, mlen, arg); - free(rrecs); - } + /* XXX handle database errors? */ - /* XXX: else? corrupt database error? */ out: - for (i = 0; i < len; i++) - recfree(&recs[i]); - recfree(&srec); - if (mc) - mchars_free(mc); if (btree) (*btree->close)(btree); if (idx) (*idx->close)(idx); free(buf); - free(recs); } static void Index: apropos_db.h =================================================================== RCS file: /cvs/src/usr.bin/mandoc/apropos_db.h,v retrieving revision 1.4 diff -u -p -r1.4 apropos_db.h --- apropos_db.h 16 Nov 2011 13:23:27 -0000 1.4 +++ apropos_db.h 16 Nov 2011 16:23:46 -0000 @@ -46,7 +46,7 @@ __BEGIN_DECLS struct expr; -void apropos_search(const struct opts *, +void apropos_search(int, char **, const struct opts *, const struct expr *, size_t, void *, void (*)(struct rec *, size_t, void *)); struct expr *exprcomp(int, char *[], size_t *); Index: mandocdb.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/mandocdb.c,v retrieving revision 1.6 diff -u -p -r1.6 mandocdb.c --- mandocdb.c 14 Nov 2011 18:52:05 -0000 1.6 +++ mandocdb.c 16 Nov 2011 16:23:46 -0000 @@ -24,12 +24,14 @@ #include #include #include +#include #include #include "man.h" #include "mdoc.h" #include "mandoc.h" #include "mandocdb.h" +#include "man_conf.h" #define MANDOC_BUFSZ BUFSIZ #define MANDOC_SLOP 1024 @@ -242,6 +244,7 @@ static const char *progname; int mandocdb(int argc, char *argv[]) { + struct man_conf dirs; struct mparse *mp; /* parse sequence */ enum op op; /* current operation */ const char *dir; @@ -307,6 +310,7 @@ mandocdb(int argc, char *argv[]) argc -= optind; argv += optind; + memset(&dirs, 0, sizeof(struct man_conf)); memset(&info, 0, sizeof(BTREEINFO)); info.flags = R_DUP; @@ -363,14 +367,22 @@ mandocdb(int argc, char *argv[]) index_prune(of, db, fbuf, idx, ibuf, verb, &maxrec, &recs, &recsz); - if (OP_UPDATE == op) + if (OP_UPDATE == op) { + chdir(dir); index_merge(of, mp, &dbuf, &buf, hash, db, fbuf, idx, ibuf, use_all, verb, maxrec, recs, reccur); + } goto out; } + if (0 == argc) { + man_conf_parse(&dirs); + argc = dirs.argc; + argv = dirs.argv; + } + for (i = 0; i < argc; i++) { ibuf[0] = fbuf[0] = '\0'; @@ -387,6 +399,11 @@ mandocdb(int argc, char *argv[]) exit((int)MANDOCLEVEL_BADARG); } + if (db) + (*db->close)(db); + if (idx) + (*idx->close)(idx); + db = dbopen(fbuf, flags, 0644, DB_BTREE, &info); idx = dbopen(ibuf, flags, 0644, DB_RECNO, NULL); @@ -415,6 +432,7 @@ mandocdb(int argc, char *argv[]) of = of->first; + chdir(argv[i]); index_merge(of, mp, &dbuf, &buf, hash, db, fbuf, idx, ibuf, use_all, verb, maxrec, recs, reccur); @@ -429,6 +447,8 @@ out: (*hash->close)(hash); if (mp) mparse_free(mp); + if (dirs.argc) + man_conf_free(&dirs); ofile_free(of); free(buf.cp); -- To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv