[BACK]Return to apropos_db.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

Diff for /src/usr.bin/mandoc/Attic/apropos_db.c between version 1.7 and 1.8

version 1.7, 2011/11/18 01:10:03 version 1.8, 2011/11/26 16:41:35
Line 34 
Line 34 
 #include "apropos_db.h"  #include "apropos_db.h"
 #include "mandoc.h"  #include "mandoc.h"
   
 struct  rectree {  
         struct rec      *node;  
         int              len;  
 };  
   
 struct  rec {  struct  rec {
         struct res       res; /* resulting record info */          struct res       res; /* resulting record info */
         /*          /*
Line 70 
Line 65 
         const char      *name;          const char      *name;
 };  };
   
   struct  rectree {
           struct rec      *node; /* record array for dir tree */
           int              len; /* length of record array */
   };
   
 static  const struct type types[] = {  static  const struct type types[] = {
         { TYPE_An, "An" },          { TYPE_An, "An" },
         { TYPE_Ar, "Ar" },          { TYPE_Ar, "Ar" },
Line 125 
Line 125 
 static  struct expr *exprexpr(int, char *[], int *, int *, size_t *);  static  struct expr *exprexpr(int, char *[], int *, int *, size_t *);
 static  struct expr *exprterm(char *, int);  static  struct expr *exprterm(char *, int);
 static  DB      *index_open(void);  static  DB      *index_open(void);
 static  int      index_read(const DBT *, const DBT *,  static  int      index_read(const DBT *, const DBT *, int,
                         const struct mchars *, struct rec *);                          const struct mchars *, struct rec *);
 static  void     norm_string(const char *,  static  void     norm_string(const char *,
                         const struct mchars *, char **);                          const struct mchars *, char **);
Line 133 
Line 133 
 static  void     recfree(struct rec *);  static  void     recfree(struct rec *);
 static  int      single_search(struct rectree *, const struct opts *,  static  int      single_search(struct rectree *, const struct opts *,
                         const struct expr *, size_t terms,                          const struct expr *, size_t terms,
                         struct mchars *);                          struct mchars *, int);
   
 /*  /*
  * Open the keyword mandoc-db database.   * Open the keyword mandoc-db database.
Line 148 
Line 148 
         info.flags = R_DUP;          info.flags = R_DUP;
   
         db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info);          db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info);
         if (NULL != db)          if (NULL != db)
                 return(db);                  return(db);
   
         return(NULL);          return(NULL);
Line 165 
Line 165 
         /* Sanity: are we nil-terminated? */          /* Sanity: are we nil-terminated? */
   
         assert(v->size > 0);          assert(v->size > 0);
   
         if ('\0' != ((char *)v->data)[(int)v->size - 1])          if ('\0' != ((char *)v->data)[(int)v->size - 1])
                 return(0);                  return(0);
   
Line 175 
Line 176 
 /*  /*
  * Take a Unicode codepoint and produce its UTF-8 encoding.   * Take a Unicode codepoint and produce its UTF-8 encoding.
  * This isn't the best way to do this, but it works.   * This isn't the best way to do this, but it works.
  * The magic numbers are from the UTF-8 packaging.   * The magic numbers are from the UTF-8 packaging.
  * They're not as scary as they seem: read the UTF-8 spec for details.   * They're not as scary as they seem: read the UTF-8 spec for details.
  */   */
 static size_t  static size_t
Line 240 
Line 241 
         const char       *seq, *cpp;          const char       *seq, *cpp;
         int               len, u, pos;          int               len, u, pos;
         enum mandoc_esc   esc;          enum mandoc_esc   esc;
         static const char res[] = { '\\', '\t',          static const char res[] = { '\\', '\t',
                                 ASCII_NBRSP, ASCII_HYPH, '\0' };                                  ASCII_NBRSP, ASCII_HYPH, '\0' };
   
         /* Pre-allocate by the length of the input */          /* Pre-allocate by the length of the input */
Line 286 
Line 287 
                 if (ESCAPE_ERROR == esc)                  if (ESCAPE_ERROR == esc)
                         break;                          break;
   
                 /*                  /*
                  * XXX - this just does UTF-8, but we need to know                   * XXX - this just does UTF-8, but we need to know
                  * beforehand whether we should do text substitution.                   * beforehand whether we should do text substitution.
                  */                   */
Line 344 
Line 345 
  * Returns 1 if an entry was unpacked, 0 if the database is insane.   * Returns 1 if an entry was unpacked, 0 if the database is insane.
  */   */
 static int  static int
 index_read(const DBT *key, const DBT *val,  index_read(const DBT *key, const DBT *val, int index,
                 const struct mchars *mc, struct rec *rec)                  const struct mchars *mc, struct rec *rec)
 {  {
         size_t           left;          size_t           left;
Line 363 
Line 364 
         cp = (char *)val->data;          cp = (char *)val->data;
   
         rec->res.rec = *(recno_t *)key->data;          rec->res.rec = *(recno_t *)key->data;
           rec->res.volume = index;
   
         INDEX_BREAD(rec->res.file);          INDEX_BREAD(rec->res.file);
         INDEX_BREAD(rec->res.cat);          INDEX_BREAD(rec->res.cat);
Line 373 
Line 375 
 }  }
   
 /*  /*
  * Search the mandocdb database for the expression "expr".   * Search mandocdb databases in paths for expression "expr".
  * Filter out by "opts".   * Filter out by "opts".
  * Call "res" with the results, which may be zero.   * Call "res" with the results, which may be zero.
  * Return 0 if there was a database error, else return 1.   * Return 0 if there was a database error, else return 1.
  */   */
 int  int
 apropos_search(int argc, char *argv[], const struct opts *opts,  apropos_search(int pathsz, char **paths, const struct opts *opts,
                 const struct expr *expr, size_t terms, void *arg,                  const struct expr *expr, size_t terms, void *arg,
                 void (*res)(struct res *, size_t, void *))                  void (*res)(struct res *, size_t, void *))
 {  {
         struct rectree   tree;          struct rectree   tree;
Line 390 
Line 392 
   
         memset(&tree, 0, sizeof(struct rectree));          memset(&tree, 0, sizeof(struct rectree));
   
           rc = 0;
         mc = mchars_alloc();          mc = mchars_alloc();
         rc = 1;  
   
         for (i = 0; i < argc; i++) {          /*
                 if (chdir(argv[i]))           * Main loop.  Change into the directory containing manpage
            * databases.  Run our expession over each database in the set.
            */
   
           for (i = 0; i < pathsz; i++) {
                   if (chdir(paths[i]))
                         continue;                          continue;
                 if (0 == single_search(&tree, opts, expr, terms, mc))                  if ( ! single_search(&tree, opts, expr, terms, mc, i))
                         rc = 0;                          goto out;
         }          }
   
         /*          /*
          * Count the matching files           * Count matching files, transfer to a "clean" array, then feed
          * and feed them to the output handler.           * them to the output handler.
          */           */
   
         for (mlen = i = 0; i < tree.len; i++)          for (mlen = i = 0; i < tree.len; i++)
                 if (tree.node[i].matched)                  if (tree.node[i].matched)
                         mlen++;                          mlen++;
   
         ress = mandoc_malloc(mlen * sizeof(struct res));          ress = mandoc_malloc(mlen * sizeof(struct res));
   
         for (mlen = i = 0; i < tree.len; i++)          for (mlen = i = 0; i < tree.len; i++)
                 if (tree.node[i].matched)                  if (tree.node[i].matched)
                         memcpy(&ress[mlen++], &tree.node[i].res,                          memcpy(&ress[mlen++], &tree.node[i].res,
                                         sizeof(struct res));                                          sizeof(struct res));
   
         (*res)(ress, mlen, arg);          (*res)(ress, mlen, arg);
         free(ress);          free(ress);
   
           rc = 1;
   out:
         for (i = 0; i < tree.len; i++)          for (i = 0; i < tree.len; i++)
                 recfree(&tree.node[i]);                  recfree(&tree.node[i]);
   
         if (mc)          free(tree.node);
                 mchars_free(mc);          mchars_free(mc);
   
         return(rc);          return(rc);
 }  }
   
 static int  static int
 single_search(struct rectree *tree, const struct opts *opts,  single_search(struct rectree *tree, const struct opts *opts,
                 const struct expr *expr, size_t terms,                  const struct expr *expr, size_t terms,
                 struct mchars *mc)                  struct mchars *mc, int vol)
 {  {
         int              root, leaf, rc;          int              root, leaf, ch;
           uint64_t         mask;
         DBT              key, val;          DBT              key, val;
         DB              *btree, *idx;          DB              *btree, *idx;
         char            *buf;          char            *buf;
Line 445 
Line 457 
         idx     = NULL;          idx     = NULL;
         buf     = NULL;          buf     = NULL;
         rs      = tree->node;          rs      = tree->node;
         rc      = 0;  
   
         memset(&r, 0, sizeof(struct rec));          memset(&r, 0, sizeof(struct rec));
   
         /* XXX: return fact that we've errored? */          if (NULL == (btree = btree_open()))
                   return(1);
   
         if (NULL == (btree = btree_open()))          if (NULL == (idx = index_open())) {
                 goto out;                  (*btree->close)(btree);
         if (NULL == (idx = index_open()))                  return(1);
                 goto out;          }
   
         while (0 == (*btree->seq)(btree, &key, &val, R_NEXT)) {          while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) {
                 /*                  if (key.size < 2 || sizeof(struct db_val) != val.size)
                  * Low-water mark for key and value.                          break;
                  * The key must have something in it, and the value must  
                  * have the correct tags/recno mix.  
                  */  
                 if (key.size < 2 || sizeof(struct db_val) != val.size)  
                         goto out;  
                 if ( ! btree_read(&key, mc, &buf))                  if ( ! btree_read(&key, mc, &buf))
                         goto out;                          break;
   
                   vbuf = val.data;
                   rec = vbuf->rec;
                   mask = vbuf->mask;
   
                 /*                  /*
                  * See if this keyword record matches any of the                   * See if this keyword record matches any of the
                  * expressions we have stored.                   * expressions we have stored.
                  */                   */
                 vbuf = val.data;                  if ( ! exprmark(expr, buf, mask, NULL))
                 if ( ! exprmark(expr, buf, vbuf->mask, NULL))  
                         continue;                          continue;
                 rec = vbuf->rec;  
   
                 /*                  /*
                  * O(log n) scan for prior records.  Since a record                   * O(log n) scan for prior records.  Since a record
Line 489 
Line 498 
                         else if (rec < rs[leaf].res.rec &&                          else if (rec < rs[leaf].res.rec &&
                                         rs[leaf].lhs >= 0)                                          rs[leaf].lhs >= 0)
                                 leaf = rs[leaf].lhs;                                  leaf = rs[leaf].lhs;
                         else                          else
                                 break;                                  break;
   
                 /*                  /*
Line 500 
Line 509 
   
                 if (leaf >= 0 && rs[leaf].res.rec == rec) {                  if (leaf >= 0 && rs[leaf].res.rec == rec) {
                         if (0 == rs[leaf].matched)                          if (0 == rs[leaf].matched)
                                 exprexec(expr, buf, vbuf->mask, &rs[leaf]);                                  exprexec(expr, buf, mask, &rs[leaf]);
                         continue;                          continue;
                 }                  }
   
Line 514 
Line 523 
                 key.size = sizeof(recno_t);                  key.size = sizeof(recno_t);
   
                 if (0 != (*idx->get)(idx, &key, &val, 0))                  if (0 != (*idx->get)(idx, &key, &val, 0))
                         goto out;                          break;
   
                 r.lhs = r.rhs = -1;                  r.lhs = r.rhs = -1;
                 if ( ! index_read(&key, &val, mc, &r))                  if ( ! index_read(&key, &val, vol, mc, &r))
                         goto out;                          break;
   
                 /* XXX: this should be elsewhere, I guess? */                  /* XXX: this should be elsewhere, I guess? */
   
                 if (opts->cat && strcasecmp(opts->cat, r.res.cat))                  if (opts->cat && strcasecmp(opts->cat, r.res.cat))
                         continue;                          continue;
                 if (opts->arch && strcasecmp(opts->arch, r.res.arch))                  if (opts->arch && strcasecmp(opts->arch, r.res.arch))
Line 530 
Line 540 
                         (rs, (tree->len + 1) * sizeof(struct rec));                          (rs, (tree->len + 1) * sizeof(struct rec));
   
                 memcpy(&rs[tree->len], &r, sizeof(struct rec));                  memcpy(&rs[tree->len], &r, sizeof(struct rec));
                 rs[tree->len].matches = mandoc_calloc(terms, sizeof(int));                  rs[tree->len].matches =
                           mandoc_calloc(terms, sizeof(int));
   
                 exprexec(expr, buf, vbuf->mask, &rs[tree->len]);                  exprexec(expr, buf, mask, &rs[tree->len]);
   
                 /* Append to our tree. */                  /* Append to our tree. */
   
Line 543 
Line 554 
                                 rs[leaf].lhs = tree->len;                                  rs[leaf].lhs = tree->len;
                 } else                  } else
                         root = tree->len;                          root = tree->len;
   
                 memset(&r, 0, sizeof(struct rec));                  memset(&r, 0, sizeof(struct rec));
                 tree->len++;                  tree->len++;
         }          }
         rc = 1;  
   
 out:          (*btree->close)(btree);
         recfree(&r);          (*idx->close)(idx);
   
         if (btree)  
                 (*btree->close)(btree);  
         if (idx)  
                 (*idx->close)(idx);  
   
         free(buf);          free(buf);
           return(1 == ch);
         return(rc);  
 }  }
   
 static void  static void
Line 629 
Line 633 
                 log = 0;                  log = 0;
   
                 if (NULL != e && 0 == strcmp("-a", argv[*pos]))                  if (NULL != e && 0 == strcmp("-a", argv[*pos]))
                         log = 1;                          log = 1;
                 else if (NULL != e && 0 == strcmp("-o", argv[*pos]))                  else if (NULL != e && 0 == strcmp("-o", argv[*pos]))
                         log = 2;                          log = 2;
   
Line 741 
Line 745 
 exprfree(struct expr *p)  exprfree(struct expr *p)
 {  {
         struct expr     *pp;          struct expr     *pp;
   
         while (NULL != p) {          while (NULL != p) {
                 if (p->subexpr)                  if (p->subexpr)
                         exprfree(p->subexpr);                          exprfree(p->subexpr);
Line 755 
Line 759 
 }  }
   
 static int  static int
 exprmark(const struct expr *p, const char *cp, uint64_t mask, int *ms)  exprmark(const struct expr *p, const char *cp,
                   uint64_t mask, int *ms)
 {  {
   
         for ( ; p; p = p->next) {          for ( ; p; p = p->next) {
Line 782 
Line 787 
                 else                  else
                         ms[p->index] = 1;                          ms[p->index] = 1;
         }          }
   
           return(0);
 }  }
   
 static int  static int
Line 824 
Line 831 
  * If this evaluates to true, mark the expression as satisfied.   * If this evaluates to true, mark the expression as satisfied.
  */   */
 static void  static void
 exprexec(const struct expr *e, const char *cp, uint64_t mask, struct rec *r)  exprexec(const struct expr *e, const char *cp,
                   uint64_t mask, struct rec *r)
 {  {
   
         assert(0 == r->matched);          assert(0 == r->matched);

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8