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

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

version 1.1, 2011/10/06 23:00:54 version 1.2, 2011/10/07 13:22:33
Line 41 
Line 41 
   
 #include "mandoc.h"  #include "mandoc.h"
   
 #define MAXRESULTS       100  #define MAXRESULTS       256
   
 #define TYPE_NAME       0x01  /* Bit-fields.  See mandocdb.8. */
 #define TYPE_FUNCTION   0x02  
 #define TYPE_UTILITY    0x04  
 #define TYPE_INCLUDES   0x08  
 #define TYPE_VARIABLE   0x10  
 #define TYPE_STANDARD   0x20  
 #define TYPE_AUTHOR     0x40  
 #define TYPE_CONFIG     0x80  
 #define TYPE_DESC       0x100  
 #define TYPE_XREF       0x200  
 #define TYPE_PATH       0x400  
 #define TYPE_ENV        0x800  
 #define TYPE_ERR        0x1000  
   
   #define TYPE_NAME         0x01
   #define TYPE_FUNCTION     0x02
   #define TYPE_UTILITY      0x04
   #define TYPE_INCLUDES     0x08
   #define TYPE_VARIABLE     0x10
   #define TYPE_STANDARD     0x20
   #define TYPE_AUTHOR       0x40
   #define TYPE_CONFIG       0x80
   #define TYPE_DESC         0x100
   #define TYPE_XREF         0x200
   #define TYPE_PATH         0x400
   #define TYPE_ENV          0x800
   #define TYPE_ERR          0x1000
   
 enum    match {  enum    match {
         MATCH_SUBSTR = 0,          MATCH_SUBSTR = 0,
         MATCH_REGEX,          MATCH_REGEX,
Line 80  struct opts {
Line 82  struct opts {
   
 struct  type {  struct  type {
         int              mask;          int              mask;
         const char      *name;          const char      *name; /* command-line type name */
 };  };
   
 struct  rec {  struct  rec {
         char            *file;          char            *file; /* file in file-system */
         char            *cat;          char            *cat; /* category (3p, 3, etc.) */
         char            *title;          char            *title; /* title (FOO, etc.) */
         char            *arch;          char            *arch; /* arch (or empty string) */
         char            *desc;          char            *desc; /* description (from Nd) */
         recno_t          rec;          recno_t          rec; /* record in index */
 };  };
   
 struct  res {  struct  res {
Line 108  struct state {
Line 110  struct state {
         DB               *idx; /* index */          DB               *idx; /* index */
         const char       *dbf; /* database name */          const char       *dbf; /* database name */
         const char       *idxf; /* index name */          const char       *idxf; /* index name */
         void            (*err)(const char *);  
         void            (*errx)(const char *, ...);  
 };  };
   
 static  const char * const sorts[SORT__MAX] = {  static  const char * const sorts[SORT__MAX] = {
Line 139  static void  buf_alloc(char **, size_t *, size_t);
Line 139  static void  buf_alloc(char **, size_t *, size_t);
 static  void     buf_dup(struct mchars *, char **, const char *);  static  void     buf_dup(struct mchars *, char **, const char *);
 static  void     buf_redup(struct mchars *, char **,  static  void     buf_redup(struct mchars *, char **,
                         size_t *, const char *);                          size_t *, const char *);
 static  void     error(const char *, ...);  
 static  int      sort_cat(const void *, const void *);  static  int      sort_cat(const void *, const void *);
 static  int      sort_title(const void *, const void *);  static  int      sort_title(const void *, const void *);
 static  void     state_destroy(struct state *);  static  int      state_getrecord(struct state *,
 static  int      state_getrecord(struct state *, recno_t, struct rec *);                          recno_t, struct rec *);
 static  int      state_init(struct state *,  
                         const char *, const char *,  
                         void (*err)(const char *),  
                         void (*errx)(const char *, ...));  
 static  void     state_output(const struct res *, int);  static  void     state_output(const struct res *, int);
 static  void     state_search(struct state *,  static  void     state_search(struct state *,
                         const struct opts *, char *);                          const struct opts *, char *);
   
 static  void     usage(void);  static  void     usage(void);
   
 static  const char       *progname;  static  char    *progname;
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         int              ch, i;          BTREEINFO        info;
           int              ch, i, rc;
         const char      *dbf, *idxf;          const char      *dbf, *idxf;
         struct state     state;          struct state     state;
         char            *q, *v;          char            *q, *v;
Line 168  main(int argc, char *argv[])
Line 163  main(int argc, char *argv[])
         extern char     *optarg;          extern char     *optarg;
   
         memset(&opts, 0, sizeof(struct opts));          memset(&opts, 0, sizeof(struct opts));
           memset(&state, 0, sizeof(struct state));
   
         dbf = "mandoc.db";          dbf = "mandoc.db";
         idxf = "mandoc.index";          idxf = "mandoc.index";
         q = NULL;          q = NULL;
           rc = EXIT_FAILURE;
   
         progname = strrchr(argv[0], '/');          progname = strrchr(argv[0], '/');
         if (progname == NULL)          if (progname == NULL)
Line 209  main(int argc, char *argv[])
Line 206  main(int argc, char *argv[])
                         if (i < SORT__MAX)                          if (i < SORT__MAX)
                                 break;                                  break;
   
                         error("%s: Bad sort\n", optarg);                          fprintf(stderr, "%s: Bad sort\n", optarg);
                         return(EXIT_FAILURE);                          return(EXIT_FAILURE);
                 case ('t'):                  case ('t'):
                         while (NULL != (v = strsep(&optarg, ","))) {                          while (NULL != (v = strsep(&optarg, ","))) {
Line 227  main(int argc, char *argv[])
Line 224  main(int argc, char *argv[])
                         if (NULL == v)                          if (NULL == v)
                                 break;                                  break;
   
                         error("%s: Bad type\n", v);                          fprintf(stderr, "%s: Bad type\n", v);
                         return(EXIT_FAILURE);                          return(EXIT_FAILURE);
                 default:                  default:
                         usage();                          usage();
Line 239  main(int argc, char *argv[])
Line 236  main(int argc, char *argv[])
   
         if (0 == argc || '\0' == **argv) {          if (0 == argc || '\0' == **argv) {
                 usage();                  usage();
                 return(EXIT_FAILURE);                  goto out;
         } else          } else
                 q = *argv;                  q = *argv;
   
         if (0 == opts.types)          if (0 == opts.types)
                 opts.types = TYPE_NAME | TYPE_DESC;                  opts.types = TYPE_NAME | TYPE_DESC;
   
         if ( ! state_init(&state, dbf, idxf, perror, error)) {          /*
                 state_destroy(&state);           * Configure databases.
                 return(EXIT_FAILURE);           * The keyword database is a btree that allows for duplicate
            * entries.
            * The index database is a recno.
            */
   
           memset(&info, 0, sizeof(BTREEINFO));
           info.flags = R_DUP;
   
           state.db = dbopen(dbf, O_RDONLY, 0, DB_BTREE, &info);
           if (NULL == state.db) {
                   perror(dbf);
                   goto out;
         }          }
   
           state.idx = dbopen(idxf, O_RDONLY, 0, DB_RECNO, NULL);
           if (NULL == state.idx) {
                   perror(idxf);
                   goto out;
           }
   
           /* Main search function. */
   
         state_search(&state, &opts, q);          state_search(&state, &opts, q);
         state_destroy(&state);  
   
         return(EXIT_SUCCESS);          rc = EXIT_SUCCESS;
   out:
           if (state.db)
                   (*state.db->close)(state.db);
           if (state.idx)
                   (*state.idx->close)(state.idx);
   
           return(rc);
 }  }
   
 static void  static void
Line 279  state_search(struct state *p, const struct opts *opts,
Line 301  state_search(struct state *p, const struct opts *opts,
         ch = 0;          ch = 0;
         regp = NULL;          regp = NULL;
   
           /*
            * Configure how we scan through results to see if we match:
            * whether by regexp or exact matches.
            */
   
         switch (opts->match) {          switch (opts->match) {
         case (MATCH_REGEX):          case (MATCH_REGEX):
                 rflags = REG_EXTENDED | REG_NOSUB |                  rflags = 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, rflags)) {
                         error("%s: Bad pattern\n", q);                          fprintf(stderr, "%s: Bad pattern\n", q);
                         return;                          return;
                 }                  }
   
Line 328  state_search(struct state *p, const struct opts *opts,
Line 355  state_search(struct state *p, const struct opts *opts,
                  */                   */
   
                 if (key.size < 2 || 8 != val.size) {                  if (key.size < 2 || 8 != val.size) {
                         error("%s: Corrupt database\n", p->dbf);                          fprintf(stderr, "%s: Corrupt database\n", p->dbf);
                         exit(EXIT_FAILURE);                          exit(EXIT_FAILURE);
                 }                  }
   
Line 412  send:
Line 439  send:
                 exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
         }          }
   
           /*
            * 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) {          switch (opts->sort) {
         case (SORT_CAT):          case (SORT_CAT):
                 qsort(res, len, sizeof(struct res), sort_cat);                  qsort(res, len, sizeof(struct res), sort_cat);
Line 544  buf_redup(struct mchars *mc, char **buf, 
Line 583  buf_redup(struct mchars *mc, char **buf, 
 }  }
   
 static void  static void
 error(const char *fmt, ...)  
 {  
         va_list          ap;  
   
         va_start(ap, fmt);  
         vfprintf(stderr, fmt, ap);  
         va_end(ap);  
 }  
   
 static void  
 state_output(const struct res *res, int sz)  state_output(const struct res *res, int sz)
 {  {
         int              i;          int              i;
Line 580  usage(void)
Line 609  usage(void)
 }  }
   
 static int  static int
 state_init(struct state *p,  
                 const char *dbf, const char *idxf,  
                 void (*err)(const char *),  
                 void (*errx)(const char *, ...))  
 {  
         BTREEINFO        info;  
   
         memset(p, 0, sizeof(struct state));  
         memset(&info, 0, sizeof(BTREEINFO));  
   
         info.flags = R_DUP;  
   
         p->dbf = dbf;  
         p->idxf = idxf;  
         p->err = err;  
   
         p->db = dbopen(p->dbf, O_RDONLY, 0, DB_BTREE, &info);  
         if (NULL == p->db) {  
                 (*err)(p->dbf);  
                 return(0);  
         }  
   
         p->idx = dbopen(p->idxf, O_RDONLY, 0, DB_RECNO, NULL);  
         if (NULL == p->idx) {  
                 (*err)(p->idxf);  
                 return(0);  
         }  
   
         return(1);  
 }  
   
 static void  
 state_destroy(struct state *p)  
 {  
   
         if (p->db)  
                 (*p->db->close)(p->db);  
         if (p->idx)  
                 (*p->idx->close)(p->idx);  
 }  
   
 static int  
 state_getrecord(struct state *p, recno_t rec, struct rec *rp)  state_getrecord(struct state *p, recno_t rec, struct rec *rp)
 {  {
         DBT             key, val;          DBT             key, val;
Line 633  state_getrecord(struct state *p, recno_t rec, struct r
Line 620  state_getrecord(struct state *p, recno_t rec, struct r
   
         rc = (*p->idx->get)(p->idx, &key, &val, 0);          rc = (*p->idx->get)(p->idx, &key, &val, 0);
         if (rc < 0) {          if (rc < 0) {
                 (*p->err)(p->idxf);                  perror(p->idxf);
                 return(0);                  return(0);
         } else if (rc > 0) {          } else if (rc > 0)
                 (*p->errx)("%s: Corrupt index\n", p->idxf);                  goto err;
                 return(0);  
         }  
   
         rp->file = (char *)val.data;          rp->file = (char *)val.data;
         if ((sz = strlen(rp->file) + 1) >= val.size) {          if ((sz = strlen(rp->file) + 1) >= val.size)
                 (*p->errx)("%s: Corrupt index\n", p->idxf);                  goto err;
                 return(0);  
         }  
   
         rp->cat = (char *)val.data + (int)sz;          rp->cat = (char *)val.data + (int)sz;
         if ((sz += strlen(rp->cat) + 1) >= val.size) {          if ((sz += strlen(rp->cat) + 1) >= val.size)
                 (*p->errx)("%s: Corrupt index\n", p->idxf);                  goto err;
                 return(0);  
         }  
   
         rp->title = (char *)val.data + (int)sz;          rp->title = (char *)val.data + (int)sz;
         if ((sz += strlen(rp->title) + 1) >= val.size) {          if ((sz += strlen(rp->title) + 1) >= val.size)
                 (*p->errx)("%s: Corrupt index\n", p->idxf);                  goto err;
                 return(0);  
         }  
   
         rp->arch = (char *)val.data + (int)sz;          rp->arch = (char *)val.data + (int)sz;
         if ((sz += strlen(rp->arch) + 1) >= val.size) {          if ((sz += strlen(rp->arch) + 1) >= val.size)
                 (*p->errx)("%s: Corrupt index\n", p->idxf);                  goto err;
                 return(0);  
         }  
   
         rp->desc = (char *)val.data + (int)sz;          rp->desc = (char *)val.data + (int)sz;
         rp->rec = rec;          rp->rec = rec;
         return(1);          return(1);
   err:
           fprintf(stderr, "%s: Corrupt index\n", p->idxf);
           return(0);
 }  }
   
 static int  static int

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

CVSweb