[BACK]Return to mansearch.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/mansearch.c between version 1.25 and 1.28

version 1.25, 2014/03/28 19:17:12 version 1.28, 2014/04/11 15:46:52
Line 19 
Line 19 
 #include "config.h"  #include "config.h"
 #endif  #endif
   
   #include <sys/mman.h>
 #include <assert.h>  #include <assert.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <getopt.h>  #include <getopt.h>
Line 74  struct expr {
Line 75  struct expr {
   
 struct  match {  struct  match {
         uint64_t         id; /* identifier in database */          uint64_t         id; /* identifier in database */
           char            *desc; /* manual page description */
         int              form; /* 0 == catpage */          int              form; /* 0 == catpage */
 };  };
   
Line 100  static void   sql_regexp(sqlite3_context *context,
Line 102  static void   sql_regexp(sqlite3_context *context,
 static  char            *sql_statement(const struct expr *);  static  char            *sql_statement(const struct expr *);
   
 int  int
   mansearch_setup(int start)
   {
           static void     *pagecache;
           int              c;
   
   #define PC_PAGESIZE     1280
   #define PC_NUMPAGES     256
   
           if (start) {
                   if (NULL != pagecache) {
                           fprintf(stderr, "pagecache already enabled\n");
                           return((int)MANDOCLEVEL_BADARG);
                   }
   
                   pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES,
                       PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
   
                   if (MAP_FAILED == pagecache) {
                           perror("mmap");
                           pagecache = NULL;
                           return((int)MANDOCLEVEL_SYSERR);
                   }
   
                   c = sqlite3_config(SQLITE_CONFIG_PAGECACHE,
                       pagecache, PC_PAGESIZE, PC_NUMPAGES);
   
                   if (SQLITE_OK == c)
                           return((int)MANDOCLEVEL_OK);
   
                   fprintf(stderr, "pagecache: %s\n", sqlite3_errstr(c));
   
           } else if (NULL == pagecache) {
                   fprintf(stderr, "pagecache missing\n");
                   return((int)MANDOCLEVEL_BADARG);
           }
   
           if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) {
                   perror("munmap");
                   pagecache = NULL;
                   return((int)MANDOCLEVEL_SYSERR);
           }
   
           pagecache = NULL;
           return((int)MANDOCLEVEL_OK);
   }
   
   int
 mansearch(const struct mansearch *search,  mansearch(const struct mansearch *search,
                 const struct manpaths *paths,                  const struct manpaths *paths,
                 int argc, char *argv[],                  int argc, char *argv[],
Line 220  mansearch(const struct mansearch *search,
Line 269  mansearch(const struct mansearch *search,
                                 SQL_BIND_BLOB(db, s, j, ep->regexp);                                  SQL_BIND_BLOB(db, s, j, ep->regexp);
                         } else                          } else
                                 SQL_BIND_TEXT(db, s, j, ep->substr);                                  SQL_BIND_TEXT(db, s, j, ep->substr);
                         SQL_BIND_INT64(db, s, j, ep->bits);                          if (0 == ((TYPE_Nd | TYPE_Nm) & ep->bits))
                                   SQL_BIND_INT64(db, s, j, ep->bits);
                 }                  }
   
                 memset(&htab, 0, sizeof(struct ohash));                  memset(&htab, 0, sizeof(struct ohash));
Line 235  mansearch(const struct mansearch *search,
Line 285  mansearch(const struct mansearch *search,
                  * distribution of buckets in the table.                   * distribution of buckets in the table.
                  */                   */
                 while (SQLITE_ROW == (c = sqlite3_step(s))) {                  while (SQLITE_ROW == (c = sqlite3_step(s))) {
                         id = sqlite3_column_int64(s, 1);                          id = sqlite3_column_int64(s, 2);
                         idx = ohash_lookup_memory                          idx = ohash_lookup_memory
                                 (&htab, (char *)&id,                                  (&htab, (char *)&id,
                                  sizeof(uint64_t), (uint32_t)id);                                   sizeof(uint64_t), (uint32_t)id);
   
                         if (NULL != ohash_find(&htab, idx))                          if (NULL != ohash_find(&htab, idx))
Line 245  mansearch(const struct mansearch *search,
Line 295  mansearch(const struct mansearch *search,
   
                         mp = mandoc_calloc(1, sizeof(struct match));                          mp = mandoc_calloc(1, sizeof(struct match));
                         mp->id = id;                          mp->id = id;
                         mp->form = sqlite3_column_int(s, 0);                          mp->form = sqlite3_column_int(s, 1);
                           if (TYPE_Nd == outbit)
                                   mp->desc = mandoc_strdup(
                                       sqlite3_column_text(s, 0));
                         ohash_insert(&htab, idx, mp);                          ohash_insert(&htab, idx, mp);
                 }                  }
   
Line 279  mansearch(const struct mansearch *search,
Line 332  mansearch(const struct mansearch *search,
                         mpage->form = mp->form;                          mpage->form = mp->form;
                         buildnames(mpage, db, s, mp->id,                          buildnames(mpage, db, s, mp->id,
                             paths->paths[i], mp->form);                              paths->paths[i], mp->form);
                         mpage->output = outbit ?                          mpage->output = TYPE_Nd & outbit ?
                               mp->desc : outbit ?
                             buildoutput(db, s2, mp->id, outbit) : NULL;                              buildoutput(db, s2, mp->id, outbit) : NULL;
   
                         free(mp);                          free(mp);
Line 493  sql_statement(const struct expr *e)
Line 547  sql_statement(const struct expr *e)
                         sql_append(&sql, &sz, " OR ", 1);                          sql_append(&sql, &sz, " OR ", 1);
                 if (e->open)                  if (e->open)
                         sql_append(&sql, &sz, "(", e->open);                          sql_append(&sql, &sz, "(", e->open);
                 sql_append(&sql, &sz, NULL == e->substr ?                  sql_append(&sql, &sz,
                     "id IN (SELECT pageid FROM keys "                      TYPE_Nd & e->bits
                     "WHERE key REGEXP ? AND bits & ?)" :                      ? (NULL == e->substr
                     "id IN (SELECT pageid FROM keys "                          ? "desc REGEXP ?"
                     "WHERE key MATCH ? AND bits & ?)", 1);                          : "desc MATCH ?")
                       : TYPE_Nm == e->bits
                       ? (NULL == e->substr
                           ? "id IN (SELECT pageid FROM names "
                             "WHERE name REGEXP ?)"
                           : "id IN (SELECT pageid FROM names "
                             "WHERE name MATCH ?)")
                       : (NULL == e->substr
                           ? "id IN (SELECT pageid FROM keys "
                             "WHERE key REGEXP ? AND bits & ?)"
                           : "id IN (SELECT pageid FROM keys "
                             "WHERE key MATCH ? AND bits & ?)"), 1);
                 if (e->close)                  if (e->close)
                         sql_append(&sql, &sz, ")", e->close);                          sql_append(&sql, &sz, ")", e->close);
                 needop = 1;                  needop = 1;
Line 514  sql_statement(const struct expr *e)
Line 579  sql_statement(const struct expr *e)
 static struct expr *  static struct expr *
 exprcomp(const struct mansearch *search, int argc, char *argv[])  exprcomp(const struct mansearch *search, int argc, char *argv[])
 {  {
           uint64_t         mask;
         int              i, toopen, logic, igncase, toclose;          int              i, toopen, logic, igncase, toclose;
         struct expr     *first, *next, *cur;          struct expr     *first, *prev, *cur, *next;
   
         first = cur = NULL;          first = cur = NULL;
         logic = igncase = toclose = 0;          logic = igncase = toclose = 0;
Line 554  exprcomp(const struct mansearch *search, int argc, cha
Line 620  exprcomp(const struct mansearch *search, int argc, cha
                 next = exprterm(search, argv[i], !igncase);                  next = exprterm(search, argv[i], !igncase);
                 if (NULL == next)                  if (NULL == next)
                         goto fail;                          goto fail;
                 next->open = toopen;                  if (NULL == first)
                 next->and = (1 == logic);                          first = next;
                 if (NULL != first) {                  else
                         cur->next = next;                          cur->next = next;
                         cur = next;                  prev = cur = next;
                 } else  
                         cur = first = next;                  /*
                    * Searching for descriptions must be split out
                    * because they are stored in the mpages table,
                    * not in the keys table.
                    */
   
                   for (mask = TYPE_Nm; mask <= TYPE_Nd; mask <<= 1) {
                           if (mask & cur->bits && ~mask & cur->bits) {
                                   next = mandoc_calloc(1,
                                       sizeof(struct expr));
                                   memcpy(next, cur, sizeof(struct expr));
                                   prev->open = 1;
                                   cur->bits = mask;
                                   cur->next = next;
                                   cur = next;
                                   cur->bits &= ~mask;
                           }
                   }
                   prev->and = (1 == logic);
                   prev->open += toopen;
                   if (cur != prev)
                           cur->close = 1;
   
                 toopen = logic = igncase = 0;                  toopen = logic = igncase = 0;
         }          }
         if (toopen || logic || igncase || toclose)          if (toopen || logic || igncase || toclose)

Legend:
Removed from v.1.25  
changed lines
  Added in v.1.28

CVSweb