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

Diff for /mandoc/mansearch.c between version 1.41 and 1.49

version 1.41, 2014/08/05 14:43:10 version 1.49, 2014/11/11 19:04:55
Line 15 
Line 15 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
 #ifdef HAVE_CONFIG_H  
 #include "config.h"  #include "config.h"
 #endif  
   
 #include <sys/mman.h>  #include <sys/mman.h>
   #include <sys/types.h>
   
 #include <assert.h>  #include <assert.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <getopt.h>  #include <getopt.h>
Line 32 
Line 32 
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   
 #ifdef HAVE_OHASH  #if HAVE_OHASH
 #include <ohash.h>  #include <ohash.h>
 #else  #else
 #include "compat_ohash.h"  #include "compat_ohash.h"
Line 80  struct expr {
Line 80  struct expr {
 struct  match {  struct  match {
         uint64_t         pageid; /* identifier in database */          uint64_t         pageid; /* identifier in database */
         char            *desc; /* manual page description */          char            *desc; /* manual page description */
         int              form; /* 0 == catpage */          int              form; /* bit field: formatted, zipped? */
 };  };
   
 static  void             buildnames(struct manpage *, sqlite3 *,  static  void             buildnames(struct manpage *, sqlite3 *,
Line 123  mansearch_setup(int start)
Line 123  mansearch_setup(int start)
                 }                  }
   
                 pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES,                  pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES,
                     PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);                      PROT_READ | PROT_WRITE,
                       MAP_SHARED | MAP_ANON, -1, 0);
   
                 if (MAP_FAILED == pagecache) {                  if (MAP_FAILED == pagecache) {
                         perror("mmap");                          perror("mmap");
Line 158  int
Line 159  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[],
                 const char *outkey,  
                 struct manpage **res, size_t *sz)                  struct manpage **res, size_t *sz)
 {  {
         int              fd, rc, c, indexbit;          int              fd, rc, c, indexbit;
Line 194  mansearch(const struct mansearch *search,
Line 194  mansearch(const struct mansearch *search,
                 goto out;                  goto out;
   
         outbit = 0;          outbit = 0;
         if (NULL != outkey) {          if (NULL != search->outkey) {
                 for (indexbit = 0, iterbit = 1;                  for (indexbit = 0, iterbit = 1;
                      indexbit < mansearch_keymax;                       indexbit < mansearch_keymax;
                      indexbit++, iterbit <<= 1) {                       indexbit++, iterbit <<= 1) {
                         if (0 == strcasecmp(outkey,                          if (0 == strcasecmp(search->outkey,
                             mansearch_keynames[indexbit])) {                              mansearch_keynames[indexbit])) {
                                 outbit = iterbit;                                  outbit = iterbit;
                                 break;                                  break;
Line 335  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->ipath = i;
                         mpage->sec = 10;                          mpage->sec = 10;
                         mpage->form = mp->form;                          mpage->form = mp->form;
                         buildnames(mpage, db, s, mp->pageid,                          buildnames(mpage, db, s, mp->pageid,
Line 351  mansearch(const struct mansearch *search,
Line 352  mansearch(const struct mansearch *search,
                 sqlite3_finalize(s2);                  sqlite3_finalize(s2);
                 sqlite3_close(db);                  sqlite3_close(db);
                 ohash_delete(&htab);                  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);          qsort(*res, cur, sizeof(struct manpage), manpage_compare);
         rc = 1;          rc = 1;
Line 366  out:
Line 375  out:
         return(rc);          return(rc);
 }  }
   
   void
   mansearch_free(struct manpage *res, size_t sz)
   {
           size_t   i;
   
           for (i = 0; i < sz; i++) {
                   free(res[i].file);
                   free(res[i].names);
                   free(res[i].output);
           }
           free(res);
   }
   
 static int  static int
 manpage_compare(const void *vp1, const void *vp2)  manpage_compare(const void *vp1, const void *vp2)
 {  {
Line 384  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
Line 406  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
 {  {
         char            *newnames, *prevsec, *prevarch;          char            *newnames, *prevsec, *prevarch;
         const char      *oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec;          const char      *oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec;
           const char      *gzip;
         size_t           i;          size_t           i;
         int              c;          int              c;
   
Line 449  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
Line 472  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
                 if (NULL != mpage->file)                  if (NULL != mpage->file)
                         continue;                          continue;
   
                 if (form) {                  if (form & FORM_SRC) {
                         sep1 = "man";                          sep1 = "man";
                         fsec = sec;                          fsec = sec;
                 } else {                  } else {
                         sep1 = "cat";                          sep1 = "cat";
                         fsec = "0";                          fsec = "0";
                 }                  }
                   if (form & FORM_GZ)
                           gzip = ".gz";
                   else
                           gzip = "";
                 sep2 = '\0' == *arch ? "" : "/";                  sep2 = '\0' == *arch ? "" : "/";
                 mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",                  mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s%s",
                     path, sep1, sec, sep2, arch, name, fsec);                      path, sep1, sec, sep2, arch, name, fsec, gzip);
         }          }
         if (SQLITE_DONE != c)          if (SQLITE_DONE != c)
                 fprintf(stderr, "%s\n", sqlite3_errmsg(db));                  fprintf(stderr, "%s\n", sqlite3_errmsg(db));
Line 738  exprterm(const struct mansearch *search, char *buf, in
Line 765  exprterm(const struct mansearch *search, char *buf, in
   
         e = mandoc_calloc(1, sizeof(struct expr));          e = mandoc_calloc(1, sizeof(struct expr));
   
         if (MANSEARCH_MAN & search->flags) {          if (search->argmode == ARG_NAME) {
                 e->bits = search->deftype;                  e->bits = TYPE_Nm;
                 e->substr = buf;                  e->substr = buf;
                 e->equal = 1;                  e->equal = 1;
                 return(e);                  return(e);
         }          }
   
         /*          /*
          * Look for an '=' or '~' operator,           * Separate macro keys from search string.
          * unless forced to some fixed macro keys.           * If needed, request regular expression handling
            * by setting e->substr to NULL.
          */           */
   
         if (MANSEARCH_WHATIS & search->flags)          if (search->argmode == ARG_WORD) {
                 val = NULL;                  e->bits = TYPE_Nm;
         else                  e->substr = NULL;
                 val = strpbrk(buf, "=~");                  mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
                   cs = 0;
         if (NULL == val) {          } else if ((val = strpbrk(buf, "=~")) == NULL) {
                 e->bits = search->deftype;                  e->bits = TYPE_Nm | TYPE_Nd;
                 e->substr = buf;                  e->substr = buf;
   
         /*  
          * Found an operator.  
          * Regexp search is requested by !e->substr.  
          */  
   
         } else {          } else {
                 if (val == buf)                  if (val == buf)
                         e->bits = search->deftype;                          e->bits = TYPE_Nm | TYPE_Nd;
                 if ('=' == *val)                  if ('=' == *val)
                         e->substr = val + 1;                          e->substr = val + 1;
                 *val++ = '\0';                  *val++ = '\0';
Line 776  exprterm(const struct mansearch *search, char *buf, in
Line 798  exprterm(const struct mansearch *search, char *buf, in
   
         /* Compile regular expressions. */          /* Compile regular expressions. */
   
         if (MANSEARCH_WHATIS & search->flags) {  
                 e->substr = NULL;  
                 mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);  
         }  
   
         if (NULL == e->substr) {          if (NULL == e->substr) {
                 irc = regcomp(&e->regexp, val,                  irc = regcomp(&e->regexp, val,
                     REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));                      REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
                 if (MANSEARCH_WHATIS & search->flags)                  if (search->argmode == ARG_WORD)
                         free(val);                          free(val);
                 if (irc) {                  if (irc) {
                         regerror(irc, &e->regexp, errbuf, sizeof(errbuf));                          regerror(irc, &e->regexp, errbuf, sizeof(errbuf));

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.49

CVSweb