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

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

version 1.49, 2014/11/11 19:04:55 version 1.53, 2015/01/20 18:21:18
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 21 
Line 21 
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <assert.h>  #include <assert.h>
   #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <getopt.h>  #include <getopt.h>
 #include <limits.h>  #include <limits.h>
Line 79  struct expr {
Line 80  struct expr {
   
 struct  match {  struct  match {
         uint64_t         pageid; /* identifier in database */          uint64_t         pageid; /* identifier in database */
           uint64_t         bits; /* name type mask */
         char            *desc; /* manual page description */          char            *desc; /* manual page description */
         int              form; /* bit field: formatted, zipped? */          int              form; /* bit field: formatted, zipped? */
 };  };
   
 static  void             buildnames(struct manpage *, sqlite3 *,  static  void             buildnames(const struct mansearch *,
                                   struct manpage *, sqlite3 *,
                                 sqlite3_stmt *, uint64_t,                                  sqlite3_stmt *, uint64_t,
                                 const char *, int form);                                  const char *, int form);
 static  char            *buildoutput(sqlite3 *, sqlite3_stmt *,  static  char            *buildoutput(sqlite3 *, sqlite3_stmt *,
Line 94  static void  *hash_calloc(size_t, size_t, void *);
Line 97  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,  
                                  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  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,
Line 245  mansearch(const struct mansearch *search,
Line 246  mansearch(const struct mansearch *search,
                     SQLITE_OPEN_READONLY, NULL);                      SQLITE_OPEN_READONLY, NULL);
   
                 if (SQLITE_OK != c) {                  if (SQLITE_OK != c) {
                         perror(MANDOC_DB);                          fprintf(stderr, "%s/%s: %s\n",
                               paths->paths[i], MANDOC_DB, strerror(errno));
                         sqlite3_close(db);                          sqlite3_close(db);
                         continue;                          continue;
                 }                  }
Line 301  mansearch(const struct mansearch *search,
Line 303  mansearch(const struct mansearch *search,
                         mp = mandoc_calloc(1, sizeof(struct match));                          mp = mandoc_calloc(1, sizeof(struct match));
                         mp->pageid = pageid;                          mp->pageid = pageid;
                         mp->form = sqlite3_column_int(s, 1);                          mp->form = sqlite3_column_int(s, 1);
                           mp->bits = sqlite3_column_int64(s, 3);
                         if (TYPE_Nd == outbit)                          if (TYPE_Nd == outbit)
                                 mp->desc = mandoc_strdup((const char *)                                  mp->desc = mandoc_strdup((const char *)
                                     sqlite3_column_text(s, 0));                                      sqlite3_column_text(s, 0));
Line 336  mansearch(const struct mansearch *search,
Line 339  mansearch(const struct mansearch *search,
                         }                          }
                         mpage = *res + cur;                          mpage = *res + cur;
                         mpage->ipath = i;                          mpage->ipath = i;
                           mpage->bits = mp->bits;
                         mpage->sec = 10;                          mpage->sec = 10;
                         mpage->form = mp->form;                          mpage->form = mp->form;
                         buildnames(mpage, db, s, mp->pageid,                          buildnames(search, mpage, db, s, mp->pageid,
                             paths->paths[i], mp->form);                              paths->paths[i], mp->form);
                         mpage->output = TYPE_Nd & outbit ?                          if (mpage->names != NULL) {
                             mp->desc : outbit ?                                  mpage->output = TYPE_Nd & outbit ?
                             buildoutput(db, s2, mp->pageid, outbit) : NULL;                                      mp->desc : outbit ?
                                       buildoutput(db, s2, mp->pageid, outbit) :
                                       NULL;
                                   cur++;
                           }
                         free(mp);                          free(mp);
                         cur++;  
                 }                  }
   
                 sqlite3_finalize(s);                  sqlite3_finalize(s);
Line 396  manpage_compare(const void *vp1, const void *vp2)
Line 402  manpage_compare(const void *vp1, const void *vp2)
   
         mp1 = vp1;          mp1 = vp1;
         mp2 = vp2;          mp2 = vp2;
         diff = mp1->sec - mp2->sec;          return( (diff = mp2->bits - mp1->bits) ? diff :
         return(diff ? diff : strcasecmp(mp1->names, mp2->names));                  (diff = mp1->sec - mp2->sec) ? diff :
                   strcasecmp(mp1->names, mp2->names));
 }  }
   
 static void  static void
 buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,  buildnames(const struct mansearch *search, struct manpage *mpage,
                   sqlite3 *db, sqlite3_stmt *s,
                 uint64_t pageid, const char *path, int form)                  uint64_t pageid, const char *path, int form)
 {  {
         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 427  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
Line 434  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
                         sep1 = ", ";                          sep1 = ", ";
                 }                  }
   
                 /* Fetch the next name. */                  /* Fetch the next name, rejecting sec/arch mismatches. */
   
                 sec = (const char *)sqlite3_column_text(s, 0);                  sec = (const char *)sqlite3_column_text(s, 0);
                   if (search->sec != NULL && strcasecmp(sec, search->sec))
                           continue;
                 arch = (const char *)sqlite3_column_text(s, 1);                  arch = (const char *)sqlite3_column_text(s, 1);
                   if (search->arch != NULL && *arch != '\0' &&
                       strcasecmp(arch, search->arch))
                           continue;
                 name = (const char *)sqlite3_column_text(s, 2);                  name = (const char *)sqlite3_column_text(s, 2);
   
                 /* Remember the first section found. */                  /* Remember the first section found. */
Line 469  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
Line 481  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
   
                 /* Also save the first file name encountered. */                  /* Also save the first file name encountered. */
   
                 if (NULL != mpage->file)                  if (mpage->file != NULL)
                         continue;                          continue;
   
                 if (form & FORM_SRC) {                  if (form & FORM_SRC) {
Line 479  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
Line 491  buildnames(struct manpage *mpage, sqlite3 *db, sqlite3
                         sep1 = "cat";                          sep1 = "cat";
                         fsec = "0";                          fsec = "0";
                 }                  }
                 if (form & FORM_GZ)                  sep2 = *arch == '\0' ? "" : "/";
                         gzip = ".gz";                  mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
                 else                      path, sep1, sec, sep2, arch, name, fsec);
                         gzip = "";  
                 sep2 = '\0' == *arch ? "" : "/";  
                 mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s%s",  
                     path, sep1, sec, sep2, arch, name, fsec, gzip);  
         }          }
         if (SQLITE_DONE != c)          if (c != SQLITE_DONE)
                 fprintf(stderr, "%s\n", sqlite3_errmsg(db));                  fprintf(stderr, "%s\n", sqlite3_errmsg(db));
         sqlite3_reset(s);          sqlite3_reset(s);
   
         /* Append one final section to the names. */          /* Append one final section to the names. */
   
         if (NULL != prevsec) {          if (prevsec != NULL) {
                 sep2 = '\0' == *prevarch ? "" : "/";                  sep2 = *prevarch == '\0' ? "" : "/";
                 mandoc_asprintf(&newnames, "%s(%s%s%s)",                  mandoc_asprintf(&newnames, "%s(%s%s%s)",
                     mpage->names, prevsec, sep2, prevarch);                      mpage->names, prevsec, sep2, prevarch);
                 free(mpage->names);                  free(mpage->names);
Line 592  sql_statement(const struct expr *e)
Line 600  sql_statement(const struct expr *e)
         size_t           sz;          size_t           sz;
         int              needop;          int              needop;
   
         sql = mandoc_strdup(          sql = mandoc_strdup(e->equal ?
             "SELECT desc, form, pageid FROM mpages WHERE ");              "SELECT desc, form, pageid, bits "
                   "FROM mpages NATURAL JOIN names WHERE " :
               "SELECT desc, form, pageid, 0 FROM mpages WHERE ");
         sz = strlen(sql);          sz = strlen(sql);
   
         for (needop = 0; NULL != e; e = e->next) {          for (needop = 0; NULL != e; e = e->next) {
Line 613  sql_statement(const struct expr *e)
Line 623  sql_statement(const struct expr *e)
                         ? "pageid IN (SELECT pageid FROM names "                          ? "pageid IN (SELECT pageid FROM names "
                           "WHERE name REGEXP ?)"                            "WHERE name REGEXP ?)"
                         : e->equal                          : e->equal
                         ? "pageid IN (SELECT pageid FROM names "                          ? "name = ? "
                           "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 643  exprcomp(const struct mansearch *search, int argc, cha
Line 652  exprcomp(const struct mansearch *search, int argc, cha
         struct expr     *first, *prev, *cur, *next;          struct expr     *first, *prev, *cur, *next;
   
         first = cur = NULL;          first = cur = NULL;
         logic = igncase = toclose = 0;          logic = igncase = toopen = toclose = 0;
         toopen = NULL != search->sec || NULL != search->arch;  
   
         for (i = 0; i < argc; i++) {          for (i = 0; i < argc; i++) {
                 if (0 == strcmp("(", argv[i])) {                  if (0 == strcmp("(", argv[i])) {
Line 710  exprcomp(const struct mansearch *search, int argc, cha
Line 718  exprcomp(const struct mansearch *search, int argc, cha
   
                 toopen = logic = igncase = 0;                  toopen = logic = igncase = 0;
         }          }
         if (toopen || logic || igncase || toclose)          if ( ! (toopen || logic || igncase || toclose))
                 goto fail;                  return(first);
   
         if (NULL != search->sec || NULL != search->arch)  
                 cur->close++;  
         if (NULL != search->arch)  
                 cur = exprspec(cur, TYPE_arch, search->arch, "^(%s|any)$");  
         if (NULL != search->sec)  
                 exprspec(cur, TYPE_sec, search->sec, "^%s$");  
   
         return(first);  
   
 fail:  fail:
         if (NULL != first)          if (NULL != first)
                 exprfree(first);                  exprfree(first);
         return(NULL);          return(NULL);
 }  
   
 static struct expr *  
 exprspec(struct expr *cur, uint64_t key, const char *value,  
                 const char *format)  
 {  
         char     errbuf[BUFSIZ];  
         char    *cp;  
         int      irc;  
   
         mandoc_asprintf(&cp, format, value);  
         cur->next = mandoc_calloc(1, sizeof(struct expr));  
         cur = cur->next;  
         cur->and = 1;  
         cur->bits = key;  
         if (0 != (irc = regcomp(&cur->regexp, cp,  
             REG_EXTENDED | REG_NOSUB | REG_ICASE))) {  
                 regerror(irc, &cur->regexp, errbuf, sizeof(errbuf));  
                 fprintf(stderr, "regcomp: %s\n", errbuf);  
                 cur->substr = value;  
         }  
         free(cp);  
         return(cur);  
 }  }
   
 static struct expr *  static struct expr *

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

CVSweb