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

Diff for /mandoc/mandocdb.c between version 1.30 and 1.36

version 1.30, 2011/12/09 01:21:10 version 1.36, 2011/12/16 12:06:35
Line 21 
Line 21 
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/stat.h>  
   
 #include <assert.h>  #include <assert.h>
 #include <dirent.h>  #include <dirent.h>
Line 110  static void    index_prune(const struct of *, DB *, 
Line 109  static void    index_prune(const struct of *, DB *, 
                                 recno_t *, recno_t **, size_t *,                                  recno_t *, recno_t **, size_t *,
                                 size_t *);                                  size_t *);
 static  void              ofile_argbuild(int, char *[], struct of **);  static  void              ofile_argbuild(int, char *[], struct of **);
 static  int               ofile_dirbuild(const char *, const char *,  static  void              ofile_dirbuild(const char *, const char *,
                                 const char *, int, struct of **);                                  const char *, int, struct of **);
 static  void              ofile_free(struct of *);  static  void              ofile_free(struct of *);
 static  void              pformatted(DB *, struct buf *, struct buf *,  static  void              pformatted(DB *, struct buf *, struct buf *,
Line 273  main(int argc, char *argv[])
Line 272  main(int argc, char *argv[])
         struct manpaths  dirs;          struct manpaths  dirs;
         enum op          op; /* current operation */          enum op          op; /* current operation */
         const char      *dir;          const char      *dir;
           char            *conf_file;
         char            *cp;          char            *cp;
         char             pbuf[PATH_MAX],          char             pbuf[PATH_MAX],
                          ibuf[MAXPATHLEN], /* index fname */                           ibuf[MAXPATHLEN], /* index fname */
Line 312  main(int argc, char *argv[])
Line 312  main(int argc, char *argv[])
         maxrec = 0;          maxrec = 0;
         op = OP_NEW;          op = OP_NEW;
         dir = NULL;          dir = NULL;
           conf_file = NULL;
   
         while (-1 != (ch = getopt(argc, argv, "ad:u:v")))          while (-1 != (ch = getopt(argc, argv, "aC:d:u:v")))
                 switch (ch) {                  switch (ch) {
                 case ('a'):                  case ('a'):
                         use_all = 1;                          use_all = 1;
                         break;                          break;
                   case ('C'):
                           conf_file = optarg;
                           break;
                 case ('d'):                  case ('d'):
                         dir = optarg;                          dir = optarg;
                         op = OP_UPDATE;                          op = OP_UPDATE;
Line 379  main(int argc, char *argv[])
Line 383  main(int argc, char *argv[])
                         exit((int)MANDOCLEVEL_SYSERR);                          exit((int)MANDOCLEVEL_SYSERR);
                 }                  }
   
                 if (verb > 2) {  
                         printf("%s: Opened\n", fbuf);  
                         printf("%s: Opened\n", ibuf);  
                 }  
   
                 ofile_argbuild(argc, argv, &of);                  ofile_argbuild(argc, argv, &of);
   
                 if (NULL == of)                  if (NULL == of)
                         goto out;                          goto out;
   
Line 394  main(int argc, char *argv[])
Line 394  main(int argc, char *argv[])
                                 &maxrec, &recs, &recsz, &reccur);                                  &maxrec, &recs, &recsz, &reccur);
   
                 /*                  /*
                  * Go to the root of the respective manual tree                   * Go to the root of the respective manual tree.
                  * such that .so links work.  In case of failure,                   * This must work or no manuals may be found (they're
                  * just prod on, even though .so links won't work.                   * indexed relative to the root).
                  */                   */
   
                 if (OP_UPDATE == op) {                  if (OP_UPDATE == op) {
                         chdir(dir);                          if (-1 == chdir(dir)) {
                                   perror(dir);
                                   exit((int)MANDOCLEVEL_SYSERR);
                           }
                         index_merge(of, mp, &dbuf, &buf, hash,                          index_merge(of, mp, &dbuf, &buf, hash,
                                         db, fbuf, idx, ibuf,                                          db, fbuf, idx, ibuf,
                                         maxrec, recs, reccur);                                          maxrec, recs, reccur);
Line 426  main(int argc, char *argv[])
Line 429  main(int argc, char *argv[])
                         dirs.paths[i] = mandoc_strdup(cp);                          dirs.paths[i] = mandoc_strdup(cp);
                 }                  }
         } else          } else
                 manpath_parse(&dirs, NULL, NULL);                  manpath_parse(&dirs, conf_file, NULL, NULL);
   
         for (i = 0; i < dirs.sz; i++) {          for (i = 0; i < dirs.sz; i++) {
                 ibuf[0] = fbuf[0] = '\0';                  ibuf[0] = fbuf[0] = '\0';
Line 461  main(int argc, char *argv[])
Line 464  main(int argc, char *argv[])
                         exit((int)MANDOCLEVEL_SYSERR);                          exit((int)MANDOCLEVEL_SYSERR);
                 }                  }
   
                 if (verb > 2) {  
                         printf("%s: Truncated\n", fbuf);  
                         printf("%s: Truncated\n", ibuf);  
                 }  
   
                 ofile_free(of);                  ofile_free(of);
                 of = NULL;                  of = NULL;
   
                 if ( ! ofile_dirbuild(dirs.paths[i], NULL, NULL,                  if (-1 == chdir(dirs.paths[i])) {
                                         0, &of))                          perror(dirs.paths[i]);
                         exit((int)MANDOCLEVEL_SYSERR);                          exit((int)MANDOCLEVEL_SYSERR);
                   }
   
                   ofile_dirbuild(".", NULL, NULL, 0, &of);
   
                 if (NULL == of)                  if (NULL == of)
                         continue;                          continue;
   
                 of = of->first;                  of = of->first;
   
                 /*                  /*
                  * Go to the root of the respective manual tree                   * Go to the root of the respective manual tree.
                  * such that .so links work.  In case of failure,                   * This must work or no manuals may be found (they're
                  * just prod on, even though .so links won't work.                   * indexed relative to the root).
                  */                   */
   
                 chdir(dirs.paths[i]);                  if (-1 == chdir(dirs.paths[i])) {
                           perror(dirs.paths[i]);
                           exit((int)MANDOCLEVEL_SYSERR);
                   }
   
                 index_merge(of, mp, &dbuf, &buf, hash, db, fbuf,                  index_merge(of, mp, &dbuf, &buf, hash, db, fbuf,
                                 idx, ibuf, maxrec, recs, reccur);                                  idx, ibuf, maxrec, recs, reccur);
         }          }
Line 523  index_merge(const struct of *of, struct mparse *mp,
Line 528  index_merge(const struct of *of, struct mparse *mp,
         size_t           sv;          size_t           sv;
         unsigned         seq;          unsigned         seq;
         struct db_val    vbuf;          struct db_val    vbuf;
           char             type;
   
         for (rec = 0; of; of = of->next) {          for (rec = 0; of; of = of->next) {
                 fn = of->fname;                  fn = of->fname;
   
                 /*                  /*
                  * Reclaim an empty index record, if available.                   * Try interpreting the file as mdoc(7) or man(7)
                    * source code, unless it is already known to be
                    * formatted.  Fall back to formatted mode.
                  */                   */
   
                 if (reccur > 0) {  
                         --reccur;  
                         rec = recs[(int)reccur];  
                 } else if (maxrec > 0) {  
                         rec = maxrec;  
                         maxrec = 0;  
                 } else  
                         rec++;  
   
                 mparse_reset(mp);                  mparse_reset(mp);
                 hash_reset(&hash);  
                 mdoc = NULL;                  mdoc = NULL;
                 man = NULL;                  man = NULL;
   
                 /*  
                  * Try interpreting the file as mdoc(7) or man(7)  
                  * source code, unless it is already known to be  
                  * formatted.  Fall back to formatted mode.  
                  */  
   
                 if ((MANDOC_SRC & of->src_form ||                  if ((MANDOC_SRC & of->src_form ||
                     ! (MANDOC_FORM & of->src_form)) &&                      ! (MANDOC_FORM & of->src_form)) &&
                     MANDOCLEVEL_FATAL > mparse_readfd(mp, -1, fn))                      MANDOCLEVEL_FATAL > mparse_readfd(mp, -1, fn))
Line 579  index_merge(const struct of *of, struct mparse *mp,
Line 571  index_merge(const struct of *of, struct mparse *mp,
                 if (0 == use_all) {                  if (0 == use_all) {
                         assert(of->sec);                          assert(of->sec);
                         assert(msec);                          assert(msec);
                         if (strcmp(msec, of->sec))                          if (strcasecmp(msec, of->sec))
                                 continue;                                  continue;
   
                         if (NULL == arch) {                          if (NULL == arch) {
                                 if (NULL != of->arch)                                  if (NULL != of->arch)
                                         continue;                                          continue;
                         } else if (NULL == of->arch ||                          } else if (NULL == of->arch ||
                                         strcmp(arch, of->arch))                                          strcasecmp(arch, of->arch))
                                 continue;                                  continue;
                 }                  }
   
Line 617  index_merge(const struct of *of, struct mparse *mp,
Line 609  index_merge(const struct of *of, struct mparse *mp,
                  */                   */
   
                 dbuf->len = 0;                  dbuf->len = 0;
                 buf_append(dbuf, mdoc ? "mdoc" : (man ? "man" : "cat"));                  type = mdoc ? 'd' : (man ? 'a' : 'c');
                   buf_appendb(dbuf, &type, 1);
                 buf_appendb(dbuf, fn, strlen(fn) + 1);                  buf_appendb(dbuf, fn, strlen(fn) + 1);
                 buf_appendb(dbuf, msec, strlen(msec) + 1);                  buf_appendb(dbuf, msec, strlen(msec) + 1);
                 buf_appendb(dbuf, mtitle, strlen(mtitle) + 1);                  buf_appendb(dbuf, mtitle, strlen(mtitle) + 1);
Line 625  index_merge(const struct of *of, struct mparse *mp,
Line 618  index_merge(const struct of *of, struct mparse *mp,
   
                 sv = dbuf->len;                  sv = dbuf->len;
   
                 /* Fix the record number in the btree value. */                  /*
                    * Collect keyword/mask pairs.
                    * Each pair will become a new btree node.
                    */
   
                   hash_reset(&hash);
                 if (mdoc)                  if (mdoc)
                         pmdoc_node(hash, buf, dbuf,                          pmdoc_node(hash, buf, dbuf,
                                 mdoc_node(mdoc), mdoc_meta(mdoc));                                  mdoc_node(mdoc), mdoc_meta(mdoc));
Line 636  index_merge(const struct of *of, struct mparse *mp,
Line 633  index_merge(const struct of *of, struct mparse *mp,
                         pformatted(hash, buf, dbuf, of);                          pformatted(hash, buf, dbuf, of);
   
                 /*                  /*
                  * Copy from the in-memory hashtable of pending keywords                   * Reclaim an empty index record, if available.
                  * into the database.                   * Use its record number for all new btree nodes.
                  */                   */
   
                   if (reccur > 0) {
                           --reccur;
                           rec = recs[(int)reccur];
                   } else if (maxrec > 0) {
                           rec = maxrec;
                           maxrec = 0;
                   } else
                           rec++;
                 vbuf.rec = htobe32(rec);                  vbuf.rec = htobe32(rec);
   
                   /*
                    * Copy from the in-memory hashtable of pending
                    * keyword/mask pairs into the database.
                    */
   
                 seq = R_FIRST;                  seq = R_FIRST;
                 while (0 == (ch = (*hash->seq)(hash, &key, &val, seq))) {                  while (0 == (ch = (*hash->seq)(hash, &key, &val, seq))) {
                         seq = R_NEXT;                          seq = R_NEXT;
Line 687  index_prune(const struct of *ofile, DB *db, const char
Line 698  index_prune(const struct of *ofile, DB *db, const char
                 recno_t **recs, size_t *recsz, size_t *reccur)                  recno_t **recs, size_t *recsz, size_t *reccur)
 {  {
         const struct of *of;          const struct of *of;
         const char      *fn, *cp;          const char      *fn;
         struct db_val   *vbuf;          struct db_val   *vbuf;
         unsigned         seq, sseq;          unsigned         seq, sseq;
         DBT              key, val;          DBT              key, val;
Line 698  index_prune(const struct of *ofile, DB *db, const char
Line 709  index_prune(const struct of *ofile, DB *db, const char
         while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) {          while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) {
                 seq = R_NEXT;                  seq = R_NEXT;
                 *maxrec = *(recno_t *)key.data;                  *maxrec = *(recno_t *)key.data;
                 cp = val.data;  
   
                 /* Deleted records are zero-sized.  Skip them. */                  /* Deleted records are zero-sized.  Skip them. */
   
Line 712  index_prune(const struct of *ofile, DB *db, const char
Line 722  index_prune(const struct of *ofile, DB *db, const char
                  * Failing any of these, we go into our error handler.                   * Failing any of these, we go into our error handler.
                  */                   */
   
                 if (NULL == (fn = memchr(cp, '\0', val.size)))                  fn = (char *)val.data + 1;
                   if (NULL == memchr(fn, '\0', val.size - 1))
                         break;                          break;
                 if (++fn - cp >= (int)val.size)  
                         break;  
                 if (NULL == memchr(fn, '\0', val.size - (fn - cp)))  
                         break;  
   
                 /*                  /*
                  * Search for the file in those we care about.                   * Search for the file in those we care about.
Line 1288  pformatted(DB *hash, struct buf *buf, struct buf *dbuf
Line 1295  pformatted(DB *hash, struct buf *buf, struct buf *dbuf
         buf_append(buf, of->title);          buf_append(buf, of->title);
         hash_put(hash, buf, TYPE_Nm);          hash_put(hash, buf, TYPE_Nm);
   
         /* Skip to first blank line. */          /* Skip to first blank line. */
   
         while (NULL != (line = fgetln(stream, &len)))          while (NULL != (line = fgetln(stream, &len)))
                 if (len && '\n' == *line)                  if ('\n' == *line)
                         break;                          break;
   
         /*          /*
          * Skip to first section header.           * Assume the first line that is not indented
          * This happens when text is flush-left.           * is the first section header.  Skip to it.
          */           */
   
         while (NULL != (line = fgetln(stream, &len)))          while (NULL != (line = fgetln(stream, &len)))
                 if (len && '\n' != *line && ' ' != *line)                  if ('\n' != *line && ' ' != *line)
                         break;                          break;
   
         /*          /*
          * If no page content can be found or the input line is           * If no page content can be found, or the input line
          * malformed (zer-length or has no trailing newline), reuse the           * is already the next section header, or there is no
          * page title as the page description.           * trailing newline, reuse the page title as the page
            * description.
          */           */
   
         line = fgetln(stream, &len);          line = fgetln(stream, &len);
         if (NULL == line || len == 0 || '\n' != line[(int)len - 1]) {          if (NULL == line || ' ' != *line || '\n' != line[(int)len - 1]) {
                 buf_appendb(dbuf, buf->cp, buf->size);                  buf_appendb(dbuf, buf->cp, buf->size);
                 hash_put(hash, buf, TYPE_Nd);                  hash_put(hash, buf, TYPE_Nd);
                 fclose(stream);                  fclose(stream);
Line 1319  pformatted(DB *hash, struct buf *buf, struct buf *dbuf
Line 1327  pformatted(DB *hash, struct buf *buf, struct buf *dbuf
   
         line[(int)--len] = '\0';          line[(int)--len] = '\0';
   
         /*          /*
          * Skip to the last dash.           * Skip to the first dash.
          * Use the remaining line as the description (no more than 70           * Use the remaining line as the description (no more than 70
          * bytes).           * bytes).
          */           */
Line 1424  ofile_argbuild(int argc, char *argv[], struct of **of)
Line 1432  ofile_argbuild(int argc, char *argv[], struct of **of)
                  * Add the structure to the list.                   * Add the structure to the list.
                  */                   */
   
                 if (verb > 2)  
                         printf("%s: Scheduling\n", argv[i]);  
                 if (NULL == *of) {                  if (NULL == *of) {
                         *of = nof;                          *of = nof;
                         (*of)->first = nof;                          (*of)->first = nof;
Line 1445  ofile_argbuild(int argc, char *argv[], struct of **of)
Line 1451  ofile_argbuild(int argc, char *argv[], struct of **of)
  * everything else is a manual.   * everything else is a manual.
  * Pass in a pointer to a NULL structure for the first invocation.   * Pass in a pointer to a NULL structure for the first invocation.
  */   */
 static int  static void
 ofile_dirbuild(const char *dir, const char* psec, const char *parch,  ofile_dirbuild(const char *dir, const char* psec, const char *parch,
                 int p_src_form, struct of **of)                  int p_src_form, struct of **of)
 {  {
         char             buf[MAXPATHLEN];          char             buf[MAXPATHLEN];
         struct stat      sb;  
         size_t           sz;          size_t           sz;
         DIR             *d;          DIR             *d;
         const char      *fn, *sec, *arch;          const char      *fn, *sec, *arch;
Line 1461  ofile_dirbuild(const char *dir, const char* psec, cons
Line 1466  ofile_dirbuild(const char *dir, const char* psec, cons
   
         if (NULL == (d = opendir(dir))) {          if (NULL == (d = opendir(dir))) {
                 perror(dir);                  perror(dir);
                 return(0);                  exit((int)MANDOCLEVEL_SYSERR);
         }          }
   
         while (NULL != (dp = readdir(d))) {          while (NULL != (dp = readdir(d))) {
Line 1506  ofile_dirbuild(const char *dir, const char* psec, cons
Line 1511  ofile_dirbuild(const char *dir, const char* psec, cons
   
                         if (MAXPATHLEN <= sz) {                          if (MAXPATHLEN <= sz) {
                                 fprintf(stderr, "%s: Path too long\n", dir);                                  fprintf(stderr, "%s: Path too long\n", dir);
                                 return(0);                                  exit((int)MANDOCLEVEL_SYSERR);
                         }                          }
   
                         if (verb > 2)                          ofile_dirbuild(buf, sec, arch, src_form, of);
                                 printf("%s: Scanning\n", buf);  
   
                         if ( ! ofile_dirbuild(buf, sec, arch,  
                                         src_form, of))  
                                 return(0);  
                 }                  }
   
                 if (DT_REG != dp->d_type ||                  if (DT_REG != dp->d_type ||
                     (NULL == psec && !use_all) ||                                  (NULL == psec && !use_all) ||
                     !strcmp(MANDOC_DB, fn) ||                                  ! strcmp(MANDOC_DB, fn) ||
                     !strcmp(MANDOC_IDX, fn))                                  ! strcmp(MANDOC_IDX, fn))
                         continue;                          continue;
   
                 /*                  /*
Line 1558  ofile_dirbuild(const char *dir, const char* psec, cons
Line 1559  ofile_dirbuild(const char *dir, const char* psec, cons
                         buf[0] = '\0';                          buf[0] = '\0';
                         strlcat(buf, dir, MAXPATHLEN);                          strlcat(buf, dir, MAXPATHLEN);
                         p = strrchr(buf, '/');                          p = strrchr(buf, '/');
                           if (NULL != parch && NULL != p)
                                   for (p--; p > buf; p--)
                                           if ('/' == *p)
                                                   break;
                         if (NULL == p)                          if (NULL == p)
                                 p = buf;                                  p = buf;
                         else                          else
Line 1579  ofile_dirbuild(const char *dir, const char* psec, cons
Line 1584  ofile_dirbuild(const char *dir, const char* psec, cons
                                             "%s: Path too long\n", buf);                                              "%s: Path too long\n", buf);
                                         continue;                                          continue;
                                 }                                  }
                                 if (0 == stat(buf, &sb))                                  if (0 == access(buf, R_OK))
                                         continue;                                          continue;
                         }                          }
                 }                  }
   
                   assert('.' == dir[0]);
                   assert('/' == dir[1]);
                 buf[0] = '\0';                  buf[0] = '\0';
                 strlcat(buf, dir, MAXPATHLEN);                  strlcat(buf, dir + 2, MAXPATHLEN);
                 strlcat(buf, "/", MAXPATHLEN);                  strlcat(buf, "/", MAXPATHLEN);
                 sz = strlcat(buf, fn, MAXPATHLEN);                  sz = strlcat(buf, fn, MAXPATHLEN);
                 if (sz >= MAXPATHLEN) {                  if (sz >= MAXPATHLEN) {
Line 1614  ofile_dirbuild(const char *dir, const char* psec, cons
Line 1621  ofile_dirbuild(const char *dir, const char* psec, cons
                  * Add the structure to the list.                   * Add the structure to the list.
                  */                   */
   
                 if (verb > 2)  
                         printf("%s: Scheduling\n", buf);  
                 if (NULL == *of) {                  if (NULL == *of) {
                         *of = nof;                          *of = nof;
                         (*of)->first = nof;                          (*of)->first = nof;
Line 1627  ofile_dirbuild(const char *dir, const char* psec, cons
Line 1632  ofile_dirbuild(const char *dir, const char* psec, cons
         }          }
   
         closedir(d);          closedir(d);
         return(1);  
 }  }
   
 static void  static void
Line 1651  usage(void)
Line 1655  usage(void)
 {  {
   
         fprintf(stderr, "usage: %s [-v] "          fprintf(stderr, "usage: %s [-v] "
                         "[-d dir [files...] |"                          "[-C file] |"
                         " -u dir [files...] |"                          " dir ... |"
                         " dir...]\n", progname);                          " -d dir [file ...] |"
                           " -u dir [file ...]\n", progname);
 }  }

Legend:
Removed from v.1.30  
changed lines
  Added in v.1.36

CVSweb