version 1.59, 2015/10/11 21:12:55 |
version 1.65, 2016/07/09 15:24:19 |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
#include <assert.h> |
#include <assert.h> |
|
#if HAVE_ERR |
#include <err.h> |
#include <err.h> |
|
#endif |
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <getopt.h> |
|
#include <glob.h> |
#include <glob.h> |
#include <limits.h> |
#include <limits.h> |
#include <regex.h> |
#include <regex.h> |
|
|
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
#if HAVE_OHASH |
|
#include <ohash.h> |
|
#else |
|
#include "compat_ohash.h" |
|
#endif |
|
#include <sqlite3.h> |
#include <sqlite3.h> |
#ifndef SQLITE_DETERMINISTIC |
#ifndef SQLITE_DETERMINISTIC |
#define SQLITE_DETERMINISTIC 0 |
#define SQLITE_DETERMINISTIC 0 |
|
|
|
|
#include "mandoc.h" |
#include "mandoc.h" |
#include "mandoc_aux.h" |
#include "mandoc_aux.h" |
|
#include "mandoc_ohash.h" |
#include "manconf.h" |
#include "manconf.h" |
#include "mansearch.h" |
#include "mansearch.h" |
|
|
Line 56 extern const char *const mansearch_keynames[]; |
|
Line 53 extern const char *const mansearch_keynames[]; |
|
#define SQL_BIND_TEXT(_db, _s, _i, _v) \ |
#define SQL_BIND_TEXT(_db, _s, _i, _v) \ |
do { if (SQLITE_OK != sqlite3_bind_text \ |
do { if (SQLITE_OK != sqlite3_bind_text \ |
((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \ |
((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \ |
warnx("%s", sqlite3_errmsg((_db))); \ |
errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \ |
} while (0) |
} while (0) |
#define SQL_BIND_INT64(_db, _s, _i, _v) \ |
#define SQL_BIND_INT64(_db, _s, _i, _v) \ |
do { if (SQLITE_OK != sqlite3_bind_int64 \ |
do { if (SQLITE_OK != sqlite3_bind_int64 \ |
((_s), (_i)++, (_v))) \ |
((_s), (_i)++, (_v))) \ |
warnx("%s", sqlite3_errmsg((_db))); \ |
errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \ |
} while (0) |
} while (0) |
#define SQL_BIND_BLOB(_db, _s, _i, _v) \ |
#define SQL_BIND_BLOB(_db, _s, _i, _v) \ |
do { if (SQLITE_OK != sqlite3_bind_blob \ |
do { if (SQLITE_OK != sqlite3_bind_blob \ |
((_s), (_i)++, (&_v), sizeof(_v), SQLITE_STATIC)) \ |
((_s), (_i)++, (&_v), sizeof(_v), SQLITE_STATIC)) \ |
warnx("%s", sqlite3_errmsg((_db))); \ |
errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \ |
} while (0) |
} while (0) |
|
|
struct expr { |
struct expr { |
Line 93 static void buildnames(const struct mansearch *, |
|
Line 90 static void buildnames(const struct mansearch *, |
|
const char *, int form); |
const char *, int form); |
static char *buildoutput(sqlite3 *, sqlite3_stmt *, |
static char *buildoutput(sqlite3 *, sqlite3_stmt *, |
uint64_t, uint64_t); |
uint64_t, uint64_t); |
static void *hash_alloc(size_t, void *); |
|
static void hash_free(void *, void *); |
|
static void *hash_calloc(size_t, size_t, void *); |
|
static struct expr *exprcomp(const struct mansearch *, |
static struct expr *exprcomp(const struct mansearch *, |
int, char *[]); |
int, char *[]); |
static void exprfree(struct expr *); |
static void exprfree(struct expr *); |
Line 130 mansearch_setup(int start) |
|
Line 124 mansearch_setup(int start) |
|
MAP_SHARED | MAP_ANON, -1, 0); |
MAP_SHARED | MAP_ANON, -1, 0); |
|
|
if (MAP_FAILED == pagecache) { |
if (MAP_FAILED == pagecache) { |
perror("mmap"); |
warn("mmap"); |
pagecache = NULL; |
pagecache = NULL; |
return (int)MANDOCLEVEL_SYSERR; |
return (int)MANDOCLEVEL_SYSERR; |
} |
} |
Line 149 mansearch_setup(int start) |
|
Line 143 mansearch_setup(int start) |
|
} |
} |
|
|
if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) { |
if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) { |
perror("munmap"); |
warn("munmap"); |
pagecache = NULL; |
pagecache = NULL; |
return (int)MANDOCLEVEL_SYSERR; |
return (int)MANDOCLEVEL_SYSERR; |
} |
} |
Line 173 mansearch(const struct mansearch *search, |
|
Line 167 mansearch(const struct mansearch *search, |
|
sqlite3 *db; |
sqlite3 *db; |
sqlite3_stmt *s, *s2; |
sqlite3_stmt *s, *s2; |
struct match *mp; |
struct match *mp; |
struct ohash_info info; |
|
struct ohash htab; |
struct ohash htab; |
unsigned int idx; |
unsigned int idx; |
size_t i, j, cur, maxres; |
size_t i, j, cur, maxres; |
Line 184 mansearch(const struct mansearch *search, |
|
Line 177 mansearch(const struct mansearch *search, |
|
return 0; |
return 0; |
} |
} |
|
|
info.calloc = hash_calloc; |
|
info.alloc = hash_alloc; |
|
info.free = hash_free; |
|
info.key_offset = offsetof(struct match, pageid); |
|
|
|
cur = maxres = 0; |
cur = maxres = 0; |
*res = NULL; |
*res = NULL; |
|
|
Line 237 mansearch(const struct mansearch *search, |
|
Line 225 mansearch(const struct mansearch *search, |
|
warnx("%s: getcwd: %s", paths->paths[i], buf); |
warnx("%s: getcwd: %s", paths->paths[i], buf); |
continue; |
continue; |
} else if (chdir(buf) == -1) { |
} else if (chdir(buf) == -1) { |
perror(buf); |
warn("%s", buf); |
continue; |
continue; |
} |
} |
} |
} |
if (chdir(paths->paths[i]) == -1) { |
if (chdir(paths->paths[i]) == -1) { |
perror(paths->paths[i]); |
warn("%s", paths->paths[i]); |
continue; |
continue; |
} |
} |
chdir_status = 1; |
chdir_status = 1; |
Line 273 mansearch(const struct mansearch *search, |
|
Line 261 mansearch(const struct mansearch *search, |
|
j = 1; |
j = 1; |
c = sqlite3_prepare_v2(db, sql, -1, &s, NULL); |
c = sqlite3_prepare_v2(db, sql, -1, &s, NULL); |
if (SQLITE_OK != c) |
if (SQLITE_OK != c) |
warnx("%s", sqlite3_errmsg(db)); |
errx((int)MANDOCLEVEL_SYSERR, |
|
"%s", sqlite3_errmsg(db)); |
|
|
for (ep = e; NULL != ep; ep = ep->next) { |
for (ep = e; NULL != ep; ep = ep->next) { |
if (NULL == ep->substr) { |
if (NULL == ep->substr) { |
Line 284 mansearch(const struct mansearch *search, |
|
Line 273 mansearch(const struct mansearch *search, |
|
SQL_BIND_INT64(db, s, j, ep->bits); |
SQL_BIND_INT64(db, s, j, ep->bits); |
} |
} |
|
|
memset(&htab, 0, sizeof(struct ohash)); |
mandoc_ohash_init(&htab, 4, offsetof(struct match, pageid)); |
ohash_init(&htab, 4, &info); |
|
|
|
/* |
/* |
* Hash each entry on its [unique] document identifier. |
* Hash each entry on its [unique] document identifier. |
Line 324 mansearch(const struct mansearch *search, |
|
Line 312 mansearch(const struct mansearch *search, |
|
"WHERE pageid=? ORDER BY sec, arch, name", |
"WHERE pageid=? ORDER BY sec, arch, name", |
-1, &s, NULL); |
-1, &s, NULL); |
if (SQLITE_OK != c) |
if (SQLITE_OK != c) |
warnx("%s", sqlite3_errmsg(db)); |
errx((int)MANDOCLEVEL_SYSERR, |
|
"%s", sqlite3_errmsg(db)); |
|
|
c = sqlite3_prepare_v2(db, |
c = sqlite3_prepare_v2(db, |
"SELECT bits, key, pageid FROM keys " |
"SELECT bits, key, pageid FROM keys " |
"WHERE pageid=? AND bits & ?", |
"WHERE pageid=? AND bits & ?", |
-1, &s2, NULL); |
-1, &s2, NULL); |
if (SQLITE_OK != c) |
if (SQLITE_OK != c) |
warnx("%s", sqlite3_errmsg(db)); |
errx((int)MANDOCLEVEL_SYSERR, |
|
"%s", sqlite3_errmsg(db)); |
|
|
for (mp = ohash_first(&htab, &idx); |
for (mp = ohash_first(&htab, &idx); |
NULL != mp; |
NULL != mp; |
Line 373 mansearch(const struct mansearch *search, |
|
Line 363 mansearch(const struct mansearch *search, |
|
} |
} |
qsort(*res, cur, sizeof(struct manpage), manpage_compare); |
qsort(*res, cur, sizeof(struct manpage), manpage_compare); |
if (chdir_status && getcwd_status && chdir(buf) == -1) |
if (chdir_status && getcwd_status && chdir(buf) == -1) |
perror(buf); |
warn("%s", buf); |
exprfree(e); |
exprfree(e); |
free(sql); |
free(sql); |
*sz = cur; |
*sz = cur; |
Line 780 exprterm(const struct mansearch *search, char *buf, in |
|
Line 770 exprterm(const struct mansearch *search, char *buf, in |
|
if (search->argmode == ARG_WORD) { |
if (search->argmode == ARG_WORD) { |
e->bits = TYPE_Nm; |
e->bits = TYPE_Nm; |
e->substr = NULL; |
e->substr = NULL; |
|
#if HAVE_REWB_BSD |
mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf); |
mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf); |
|
#elif HAVE_REWB_SYSV |
|
mandoc_asprintf(&val, "\\<%s\\>", buf); |
|
#else |
|
mandoc_asprintf(&val, |
|
"(^|[^a-zA-Z01-9_])%s([^a-zA-Z01-9_]|$)", buf); |
|
#endif |
cs = 0; |
cs = 0; |
} else if ((val = strpbrk(buf, "=~")) == NULL) { |
} else if ((val = strpbrk(buf, "=~")) == NULL) { |
e->bits = TYPE_Nm | TYPE_Nd; |
e->bits = TYPE_Nm | TYPE_Nd; |
Line 852 exprfree(struct expr *p) |
|
Line 849 exprfree(struct expr *p) |
|
free(p); |
free(p); |
p = pp; |
p = pp; |
} |
} |
} |
|
|
|
static void * |
|
hash_calloc(size_t nmemb, size_t sz, void *arg) |
|
{ |
|
|
|
return mandoc_calloc(nmemb, sz); |
|
} |
|
|
|
static void * |
|
hash_alloc(size_t sz, void *arg) |
|
{ |
|
|
|
return mandoc_malloc(sz); |
|
} |
|
|
|
static void |
|
hash_free(void *p, void *arg) |
|
{ |
|
|
|
free(p); |
|
} |
} |