=================================================================== RCS file: /cvs/mandoc/mansearch.c,v retrieving revision 1.47 retrieving revision 1.50 diff -u -p -r1.47 -r1.50 --- mandoc/mansearch.c 2014/09/01 22:45:53 1.47 +++ mandoc/mansearch.c 2014/11/18 01:15:21 1.50 @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.47 2014/09/01 22:45:53 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.50 2014/11/18 01:15:21 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -79,8 +79,9 @@ struct expr { struct match { uint64_t pageid; /* identifier in database */ + uint64_t bits; /* name type mask */ char *desc; /* manual page description */ - int form; /* 0 == catpage */ + int form; /* bit field: formatted, zipped? */ }; static void buildnames(struct manpage *, sqlite3 *, @@ -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,6 +410,7 @@ 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; @@ -463,16 +476,20 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3 if (NULL != mpage->file) continue; - if (form) { + if (form & FORM_SRC) { sep1 = "man"; fsec = sec; } else { 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", - path, sep1, sec, sep2, arch, name, fsec); + mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s%s", + path, sep1, sec, sep2, arch, name, fsec, gzip); } if (SQLITE_DONE != c) fprintf(stderr, "%s\n", sqlite3_errmsg(db)); @@ -579,8 +596,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) { @@ -600,8 +619,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