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

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

version 1.37, 2014/06/20 02:24:40 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 93  static void   exprfree(struct expr *);
Line 97  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 330  mansearch(const struct mansearch *search,
Line 335  mansearch(const struct mansearch *search,
                                     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 346  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 359  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 391  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 561  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 702  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 711  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.

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

CVSweb