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

Diff for /mandoc/Attic/apropos.c between version 1.2 and 1.7

version 1.2, 2011/10/07 13:22:33 version 1.7, 2011/10/09 10:46:38
Line 103  struct res {
Line 103  struct res {
         char            *title; /* manual section */          char            *title; /* manual section */
         char            *uri; /* formatted uri of file */          char            *uri; /* formatted uri of file */
         recno_t          rec; /* unique id of underlying manual */          recno_t          rec; /* unique id of underlying manual */
           /*
            * Maintain a binary tree for checking the uniqueness of `rec'
            * when adding elements to the results array.
            * Since the results array is dynamic, use offset in the array
            * instead of a pointer to the structure.
            */
           int              lhs;
           int              rhs;
 };  };
   
 struct  state {  struct  state {
Line 144  static int  sort_title(const void *, const void *);
Line 152  static int  sort_title(const void *, const void *);
 static  int      state_getrecord(struct state *,  static  int      state_getrecord(struct state *,
                         recno_t, struct rec *);                          recno_t, struct rec *);
 static  void     state_output(const struct res *, int);  static  void     state_output(const struct res *, int);
 static  void     state_search(struct state *,  static  int      state_search(struct state *,
                         const struct opts *, char *);                          const struct opts *, char *);
 static  void     usage(void);  static  void     usage(void);
   
Line 267  main(int argc, char *argv[])
Line 275  main(int argc, char *argv[])
   
         /* Main search function. */          /* Main search function. */
   
         state_search(&state, &opts, q);          rc = state_search(&state, &opts, q) ?
                   EXIT_SUCCESS : EXIT_FAILURE;
         rc = EXIT_SUCCESS;  
 out:  out:
         if (state.db)          if (state.db)
                 (*state.db->close)(state.db);                  (*state.db->close)(state.db);
Line 279  out:
Line 286  out:
         return(rc);          return(rc);
 }  }
   
 static void  static int
 state_search(struct state *p, const struct opts *opts, char *q)  state_search(struct state *p, const struct opts *opts, char *q)
 {  {
         int              i, len, ch, rflags, dflag;          int              leaf, root, len, ch, dflag, rc;
         struct mchars   *mc;          struct mchars   *mc;
         char            *buf;          char            *buf;
         size_t           bufsz;          size_t           bufsz;
         recno_t          rec;          recno_t          rec;
         uint32_t         fl;          uint32_t         fl;
         DBT              key, val;          DBT              key, val;
         struct res       res[MAXRESULTS];          struct res      *res;
         regex_t          reg;          regex_t          reg;
         regex_t         *regp;          regex_t         *regp;
         char             filebuf[10];          char             filebuf[10];
         struct rec       record;          struct rec       record;
   
           rc = 0;
           root = leaf = -1;
           res = NULL;
         len = 0;          len = 0;
         buf = NULL;          buf = NULL;
         bufsz = 0;          bufsz = 0;
         ch = 0;  
         regp = NULL;          regp = NULL;
   
         /*          /*
Line 308  state_search(struct state *p, const struct opts *opts,
Line 317  state_search(struct state *p, const struct opts *opts,
   
         switch (opts->match) {          switch (opts->match) {
         case (MATCH_REGEX):          case (MATCH_REGEX):
                 rflags = REG_EXTENDED | REG_NOSUB |                  ch = REG_EXTENDED | REG_NOSUB |
                         (opts->insens ? REG_ICASE : 0);                          (opts->insens ? REG_ICASE : 0);
   
                 if (0 != regcomp(&reg, q, rflags)) {                  if (0 != regcomp(&reg, q, ch)) {
                         fprintf(stderr, "%s: Bad pattern\n", q);                          fprintf(stderr, "%s: Bad pattern\n", q);
                         return;                          return(0);
                 }                  }
   
                 regp = ®                  regp = ®
Line 329  state_search(struct state *p, const struct opts *opts,
Line 338  state_search(struct state *p, const struct opts *opts,
                 break;                  break;
         }          }
   
         if (NULL == (mc = mchars_alloc())) {          mc = mchars_alloc();
                 perror(NULL);  
                 exit(EXIT_FAILURE);  
         }  
   
         /*          /*
          * Iterate over the entire keyword database.           * Iterate over the entire keyword database.
Line 341  state_search(struct state *p, const struct opts *opts,
Line 347  state_search(struct state *p, const struct opts *opts,
          * Lastly, add it to the available records.           * Lastly, add it to the available records.
          */           */
   
         while (len < MAXRESULTS) {          while (0 == (ch = (*p->db->seq)(p->db, &key, &val, dflag))) {
                 if ((ch = (*p->db->seq)(p->db, &key, &val, dflag)))  
                         break;  
   
                 dflag = R_NEXT;                  dflag = R_NEXT;
   
                 /*                  /*
Line 355  state_search(struct state *p, const struct opts *opts,
Line 358  state_search(struct state *p, const struct opts *opts,
                  */                   */
   
                 if (key.size < 2 || 8 != val.size) {                  if (key.size < 2 || 8 != val.size) {
                         fprintf(stderr, "%s: Corrupt database\n", p->dbf);                          fprintf(stderr, "%s: Bad database\n", p->dbf);
                         exit(EXIT_FAILURE);                          goto out;
                 }                  }
   
                 buf_redup(mc, &buf, &bufsz, (char *)key.data);                  buf_redup(mc, &buf, &bufsz, (char *)key.data);
Line 393  state_search(struct state *p, const struct opts *opts,
Line 396  state_search(struct state *p, const struct opts *opts,
                 memcpy(&rec, val.data + 4, sizeof(recno_t));                  memcpy(&rec, val.data + 4, sizeof(recno_t));
   
                 if ( ! state_getrecord(p, rec, &record))                  if ( ! state_getrecord(p, rec, &record))
                         exit(EXIT_FAILURE);                          goto out;
   
                 /* If we're in a different section, skip... */                  /* If we're in a different section, skip... */
   
Line 402  state_search(struct state *p, const struct opts *opts,
Line 405  state_search(struct state *p, const struct opts *opts,
                 if (opts->arch && strcasecmp(opts->arch, record.arch))                  if (opts->arch && strcasecmp(opts->arch, record.arch))
                         continue;                          continue;
   
                 /* FIXME: this needs to be changed.  Ugh.  Linear. */                  /*
                    * Do a binary search to dedupe the results tree of the
                    * same record: we don't print the same file.
                    */
   
                 for (i = 0; i < len; i++)                  for (leaf = root; leaf >= 0; )
                         if (res[i].rec == record.rec)                          if (rec > res[leaf].rec && res[leaf].rhs >= 0)
                                   leaf = res[leaf].rhs;
                           else if (rec < res[leaf].rec && res[leaf].lhs >= 0)
                                   leaf = res[leaf].lhs;
                           else
                                 break;                                  break;
   
                 if (i < len)                  if (leaf >= 0 && res[leaf].rec == rec)
                         continue;                          continue;
   
                   res = mandoc_realloc
                           (res, (len + 1) * sizeof(struct res));
   
                 /*                  /*
                  * Now we have our filename, keywords, types, and all                   * Now we have our filename, keywords, types, and all
                  * other necessary information.                   * other necessary information.
Line 423  state_search(struct state *p, const struct opts *opts,
Line 436  state_search(struct state *p, const struct opts *opts,
   
                 res[len].rec = record.rec;                  res[len].rec = record.rec;
                 res[len].types = fl;                  res[len].types = fl;
                   res[len].lhs = res[len].rhs = -1;
   
                 buf_dup(mc, &res[len].keyword, buf);                  buf_dup(mc, &res[len].keyword, buf);
                 buf_dup(mc, &res[len].uri, filebuf);                  buf_dup(mc, &res[len].uri, filebuf);
Line 430  state_search(struct state *p, const struct opts *opts,
Line 444  state_search(struct state *p, const struct opts *opts,
                 buf_dup(mc, &res[len].arch, record.arch);                  buf_dup(mc, &res[len].arch, record.arch);
                 buf_dup(mc, &res[len].title, record.title);                  buf_dup(mc, &res[len].title, record.title);
                 buf_dup(mc, &res[len].desc, record.desc);                  buf_dup(mc, &res[len].desc, record.desc);
   
                   if (leaf >= 0) {
                           if (record.rec > res[leaf].rec)
                                   res[leaf].rhs = len;
                           else
                                   res[leaf].lhs = len;
                   } else
                           root = len;
   
                 len++;                  len++;
         }          }
   
 send:  
         if (ch < 0) {          if (ch < 0) {
                 perror(p->dbf);                  perror(p->dbf);
                 exit(EXIT_FAILURE);                  goto out;
         }          }
   send:
           /* Sort our results. */
   
         /*          if (SORT_CAT == opts->sort)
          * Sort our results.  
          * We do this post-scan (instead of an in-line sort) because  
          * it's more or less the same in terms of run-time.  Assuming we  
          * sort in-line with a tree versus post:  
          *  
          *  In-place: n * O(lg n)  
          *  After: n + O(n lg n)  
          *  
          * Whatever.  This also buys us simplicity.  
          */  
   
         switch (opts->sort) {  
         case (SORT_CAT):  
                 qsort(res, len, sizeof(struct res), sort_cat);                  qsort(res, len, sizeof(struct res), sort_cat);
                 break;          else
         default:  
                 qsort(res, len, sizeof(struct res), sort_title);                  qsort(res, len, sizeof(struct res), sort_title);
                 break;  
         }  
   
         state_output(res, len);          state_output(res, len);
           rc = 1;
   out:
         for (len-- ; len >= 0; len--) {          for (len-- ; len >= 0; len--) {
                 free(res[len].keyword);                  free(res[len].keyword);
                 free(res[len].title);                  free(res[len].title);
Line 471  send:
Line 480  send:
                 free(res[len].uri);                  free(res[len].uri);
         }          }
   
           free(res);
         free(buf);          free(buf);
         mchars_free(mc);          mchars_free(mc);
   
         if (regp)          if (regp)
                 regfree(regp);                  regfree(regp);
   
           return(rc);
 }  }
   
 /*  /*
Line 489  buf_alloc(char **buf, size_t *bufsz, size_t sz)
Line 501  buf_alloc(char **buf, size_t *bufsz, size_t sz)
                 return;                  return;
   
         *bufsz = sz + 1024;          *bufsz = sz + 1024;
         if (NULL == (*buf = realloc(*buf, *bufsz))) {          *buf = mandoc_realloc(*buf, *bufsz);
                 perror(NULL);  
                 exit(EXIT_FAILURE);  
         }  
 }  }
   
 /*  /*

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

CVSweb