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

Diff for /mandoc/mansearch.c between version 1.35 and 1.40

version 1.35, 2014/04/23 16:34:50 version 1.40, 2014/08/05 12:34:08
Line 38 
Line 38 
 #include "compat_ohash.h"  #include "compat_ohash.h"
 #endif  #endif
 #include <sqlite3.h>  #include <sqlite3.h>
   #ifndef SQLITE_DETERMINISTIC
   #define SQLITE_DETERMINISTIC 0
   #endif
   
 #include "mandoc.h"  #include "mandoc.h"
 #include "mandoc_aux.h"  #include "mandoc_aux.h"
Line 64  extern const char *const mansearch_keynames[];
Line 67  extern const char *const mansearch_keynames[];
         } while (0)          } while (0)
   
 struct  expr {  struct  expr {
         uint64_t         bits;    /* type-mask */  
         const char      *substr;  /* to search for, if applicable */  
         regex_t          regexp;  /* compiled regexp, if applicable */          regex_t          regexp;  /* compiled regexp, if applicable */
           const char      *substr;  /* to search for, if applicable */
           struct expr     *next;    /* next in sequence */
           uint64_t         bits;    /* type-mask */
           int              equal;   /* equality, not subsring match */
         int              open;    /* opening parentheses before */          int              open;    /* opening parentheses before */
         int              and;     /* logical AND before */          int              and;     /* logical AND before */
         int              close;   /* closing parentheses after */          int              close;   /* closing parentheses after */
         struct expr     *next;    /* next in sequence */  
 };  };
   
 struct  match {  struct  match {
Line 85  static void   buildnames(struct manpage *, sqlite3 *,
Line 89  static void   buildnames(struct manpage *, sqlite3 *,
 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_alloc(size_t, void *);
 static  void             hash_free(void *, size_t, void *);  static  void             hash_free(void *, void *);
 static  void            *hash_halloc(size_t, 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 *);
 static  struct expr     *exprspec(struct expr *, uint64_t,  static  struct expr     *exprspec(struct expr *, uint64_t,
                                  const char *, const char *);                                   const char *, const char *);
 static  struct expr     *exprterm(const struct mansearch *, char *, int);  static  struct expr     *exprterm(const struct mansearch *, char *, int);
   static  int              manpage_compare(const void *, const void *);
 static  void             sql_append(char **sql, size_t *sz,  static  void             sql_append(char **sql, size_t *sz,
                                 const char *newstr, int count);                                  const char *newstr, int count);
 static  void             sql_match(sqlite3_context *context,  static  void             sql_match(sqlite3_context *context,
Line 171  mansearch(const struct mansearch *search,
Line 176  mansearch(const struct mansearch *search,
         unsigned int     idx;          unsigned int     idx;
         size_t           i, j, cur, maxres;          size_t           i, j, cur, maxres;
   
         memset(&info, 0, sizeof(struct ohash_info));          info.calloc = hash_calloc;
   
         info.halloc = hash_halloc;  
         info.alloc = hash_alloc;          info.alloc = hash_alloc;
         info.hfree = hash_free;          info.free = hash_free;
         info.key_offset = offsetof(struct match, pageid);          info.key_offset = offsetof(struct match, pageid);
   
         *sz = cur = maxres = 0;          *sz = cur = maxres = 0;
Line 328  mansearch(const struct mansearch *search,
Line 331  mansearch(const struct mansearch *search,
                                 mp = ohash_next(&htab, &idx)) {                                  mp = ohash_next(&htab, &idx)) {
                         if (cur + 1 > maxres) {                          if (cur + 1 > maxres) {
                                 maxres += 1024;                                  maxres += 1024;
                                 *res = mandoc_realloc(*res,                                  *res = mandoc_reallocarray(*res,
                                     maxres * sizeof(struct manpage));                                      maxres, sizeof(struct manpage));
                         }                          }
                         mpage = *res + cur;                          mpage = *res + cur;
                           mpage->sec = 10;
                         mpage->form = mp->form;                          mpage->form = mp->form;
                         buildnames(mpage, db, s, mp->pageid,                          buildnames(mpage, db, s, mp->pageid,
                             paths->paths[i], mp->form);                              paths->paths[i], mp->form);
Line 348  mansearch(const struct mansearch *search,
Line 352  mansearch(const struct mansearch *search,
                 sqlite3_close(db);                  sqlite3_close(db);
                 ohash_delete(&htab);                  ohash_delete(&htab);
         }          }
           qsort(*res, cur, sizeof(struct manpage), manpage_compare);
         rc = 1;          rc = 1;
 out:  out:
         if (-1 != fd) {          if (-1 != fd) {
Line 361  out:
Line 366  out:
         return(rc);          return(rc);
 }  }
   
   static int
   manpage_compare(const void *vp1, const void *vp2)
   {
           const struct manpage    *mp1, *mp2;
           int                      diff;
   
           mp1 = vp1;
           mp2 = vp2;
           diff = mp1->sec - mp2->sec;
           return(diff ? diff : strcasecmp(mp1->names, mp2->names));
   }
   
 static void  static void
 buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
                 uint64_t pageid, const char *path, int form)                  uint64_t pageid, const char *path, int form)
Line 393  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
Line 410  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
                 arch = sqlite3_column_text(s, 1);                  arch = sqlite3_column_text(s, 1);
                 name = sqlite3_column_text(s, 2);                  name = sqlite3_column_text(s, 2);
   
                   /* Remember the first section found. */
   
                   if (9 < mpage->sec && '1' <= *sec && '9' >= *sec)
                           mpage->sec = (*sec - '1') + 1;
   
                 /* If the section changed, append the old one. */                  /* If the section changed, append the old one. */
   
                 if (NULL != prevsec &&                  if (NULL != prevsec &&
Line 563  sql_statement(const struct expr *e)
Line 585  sql_statement(const struct expr *e)
                     ? (NULL == e->substr                      ? (NULL == e->substr
                         ? "pageid IN (SELECT pageid FROM names "                          ? "pageid IN (SELECT pageid FROM names "
                           "WHERE name REGEXP ?)"                            "WHERE name REGEXP ?)"
                           : e->equal
                           ? "pageid IN (SELECT pageid FROM names "
                             "WHERE name = ?)"
                         : "pageid IN (SELECT pageid FROM names "                          : "pageid IN (SELECT pageid FROM names "
                           "WHERE name MATCH ?)")                            "WHERE name MATCH ?)")
                     : (NULL == e->substr                      : (NULL == e->substr
Line 704  exprterm(const struct mansearch *search, char *buf, in
Line 729  exprterm(const struct mansearch *search, char *buf, in
 {  {
         char             errbuf[BUFSIZ];          char             errbuf[BUFSIZ];
         struct expr     *e;          struct expr     *e;
         char            *key, *v;          char            *key, *val;
         uint64_t         iterbit;          uint64_t         iterbit;
         int              i, irc;          int              i, irc;
   
Line 713  exprterm(const struct mansearch *search, char *buf, in
Line 738  exprterm(const struct mansearch *search, char *buf, in
   
         e = mandoc_calloc(1, sizeof(struct expr));          e = mandoc_calloc(1, sizeof(struct expr));
   
         /*"whatis" mode uses an opaque string and default fields. */          if (MANSEARCH_MAN & search->flags) {
   
         if (MANSEARCH_WHATIS & search->flags) {  
                 e->substr = buf;  
                 e->bits = search->deftype;                  e->bits = search->deftype;
                   e->substr = buf;
                   e->equal = 1;
                 return(e);                  return(e);
         }          }
   
         /*          /*
          * If no =~ is specified, search with equality over names and           * Look for an '=' or '~' operator,
          * descriptions.           * unless forced to some fixed macro keys.
          * If =~ begins the phrase, use name and description fields.  
          */           */
   
         if (NULL == (v = strpbrk(buf, "=~"))) {          if (MANSEARCH_WHATIS & search->flags)
                 e->substr = buf;                  val = NULL;
           else
                   val = strpbrk(buf, "=~");
   
           if (NULL == val) {
                 e->bits = search->deftype;                  e->bits = search->deftype;
                 return(e);                  e->substr = buf;
         } else if (v == buf)  
                 e->bits = search->deftype;  
   
         if ('~' == *v++) {          /*
            * Found an operator.
            * Regexp search is requested by !e->substr.
            */
   
           } else {
                   if (val == buf)
                           e->bits = search->deftype;
                   if ('=' == *val)
                           e->substr = val + 1;
                   *val++ = '\0';
                 if (NULL != strstr(buf, "arch"))                  if (NULL != strstr(buf, "arch"))
                         cs = 0;                          cs = 0;
                 if (0 != (irc = regcomp(&e->regexp, v,          }
                     REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE)))) {  
           /* Compile regular expressions. */
   
           if (MANSEARCH_WHATIS & search->flags) {
                   e->substr = NULL;
                   mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
           }
   
           if (NULL == e->substr) {
                   irc = regcomp(&e->regexp, val,
                       REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
                   if (MANSEARCH_WHATIS & search->flags)
                           free(val);
                   if (irc) {
                         regerror(irc, &e->regexp, errbuf, sizeof(errbuf));                          regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
                         fprintf(stderr, "regcomp: %s\n", errbuf);                          fprintf(stderr, "regcomp: %s\n", errbuf);
                         free(e);                          free(e);
                         return(NULL);                          return(NULL);
                 }                  }
         } else          }
                 e->substr = v;  
         v[-1] = '\0';  
   
           if (e->bits)
                   return(e);
   
         /*          /*
          * Parse out all possible fields.           * Parse out all possible fields.
          * If the field doesn't resolve, bail.           * If the field doesn't resolve, bail.
Line 790  exprfree(struct expr *p)
Line 839  exprfree(struct expr *p)
 }  }
   
 static void *  static void *
 hash_halloc(size_t sz, void *arg)  hash_calloc(size_t nmemb, size_t sz, void *arg)
 {  {
   
         return(mandoc_calloc(sz, 1));          return(mandoc_calloc(nmemb, sz));
 }  }
   
 static void *  static void *
Line 804  hash_alloc(size_t sz, void *arg)
Line 853  hash_alloc(size_t sz, void *arg)
 }  }
   
 static void  static void
 hash_free(void *p, size_t sz, void *arg)  hash_free(void *p, void *arg)
 {  {
   
         free(p);          free(p);

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.40

CVSweb