=================================================================== RCS file: /cvs/mandoc/mansearch.c,v retrieving revision 1.48 retrieving revision 1.51 diff -u -p -r1.48 -r1.51 --- mandoc/mansearch.c 2014/09/03 18:09:14 1.48 +++ mandoc/mansearch.c 2014/11/27 01:58:21 1.51 @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.48 2014/09/03 18:09:14 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.51 2014/11/27 01:58:21 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -79,6 +79,7 @@ struct expr { struct match { uint64_t pageid; /* identifier in database */ + uint64_t bits; /* name type mask */ char *desc; /* manual page description */ int form; /* bit field: formatted, zipped? */ }; @@ -301,6 +302,7 @@ mansearch(const struct mansearch *search, mp = mandoc_calloc(1, sizeof(struct match)); mp->pageid = pageid; mp->form = sqlite3_column_int(s, 1); + mp->bits = sqlite3_column_int64(s, 3); if (TYPE_Nd == outbit) mp->desc = mandoc_strdup((const char *) sqlite3_column_text(s, 0)); @@ -336,6 +338,7 @@ mansearch(const struct mansearch *search, } mpage = *res + cur; mpage->ipath = i; + mpage->bits = mp->bits; mpage->sec = 10; mpage->form = mp->form; buildnames(mpage, db, s, mp->pageid, @@ -352,6 +355,14 @@ mansearch(const struct mansearch *search, sqlite3_finalize(s2); sqlite3_close(db); ohash_delete(&htab); + + /* + * In man(1) mode, prefer matches in earlier trees + * over matches in later trees. + */ + + if (cur && search->firstmatch) + break; } qsort(*res, cur, sizeof(struct manpage), manpage_compare); rc = 1; @@ -388,8 +399,9 @@ manpage_compare(const void *vp1, const void *vp2) mp1 = vp1; mp2 = vp2; - diff = mp1->sec - mp2->sec; - return(diff ? diff : strcasecmp(mp1->names, mp2->names)); + return( (diff = mp2->bits - mp1->bits) ? diff : + (diff = mp1->sec - mp2->sec) ? diff : + strcasecmp(mp1->names, mp2->names)); } static void @@ -398,7 +410,6 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3 { char *newnames, *prevsec, *prevarch; const char *oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec; - const char *gzip; size_t i; int c; @@ -461,7 +472,7 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3 /* Also save the first file name encountered. */ - if (NULL != mpage->file) + if (mpage->file != NULL) continue; if (form & FORM_SRC) { @@ -471,22 +482,18 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3 sep1 = "cat"; fsec = "0"; } - if (form & FORM_GZ) - gzip = ".gz"; - else - gzip = ""; - sep2 = '\0' == *arch ? "" : "/"; - mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s%s", - path, sep1, sec, sep2, arch, name, fsec, gzip); + sep2 = *arch == '\0' ? "" : "/"; + mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s", + path, sep1, sec, sep2, arch, name, fsec); } - if (SQLITE_DONE != c) + if (c != SQLITE_DONE) fprintf(stderr, "%s\n", sqlite3_errmsg(db)); sqlite3_reset(s); /* Append one final section to the names. */ - if (NULL != prevsec) { - sep2 = '\0' == *prevarch ? "" : "/"; + if (prevsec != NULL) { + sep2 = *prevarch == '\0' ? "" : "/"; mandoc_asprintf(&newnames, "%s(%s%s%s)", mpage->names, prevsec, sep2, prevarch); free(mpage->names); @@ -584,8 +591,10 @@ sql_statement(const struct expr *e) size_t sz; int needop; - sql = mandoc_strdup( - "SELECT desc, form, pageid FROM mpages WHERE "); + sql = mandoc_strdup(e->equal ? + "SELECT desc, form, pageid, bits " + "FROM mpages NATURAL JOIN names WHERE " : + "SELECT desc, form, pageid, 0 FROM mpages WHERE "); sz = strlen(sql); for (needop = 0; NULL != e; e = e->next) { @@ -605,8 +614,7 @@ sql_statement(const struct expr *e) ? "pageid IN (SELECT pageid FROM names " "WHERE name REGEXP ?)" : e->equal - ? "pageid IN (SELECT pageid FROM names " - "WHERE name = ?)" + ? "name = ? " : "pageid IN (SELECT pageid FROM names " "WHERE name MATCH ?)") : (NULL == e->substr