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

Diff for /mandoc/mandocdb.c between version 1.82 and 1.84

version 1.82, 2013/12/27 03:06:17 version 1.84, 2013/12/27 15:39:03
Line 76  enum op {
Line 76  enum op {
 };  };
   
 enum    form {  enum    form {
         FORM_SRC, /* format is -man or -mdoc */          FORM_NONE,  /* format is unknown */
         FORM_CAT, /* format is cat */          FORM_SRC,   /* format is -man or -mdoc */
         FORM_NONE /* format is unknown */          FORM_CAT    /* format is cat */
 };  };
   
 struct  str {  struct  str {
Line 106  struct mpage {
Line 106  struct mpage {
 struct  mlink {  struct  mlink {
         char             file[PATH_MAX]; /* filename rel. to manpath */          char             file[PATH_MAX]; /* filename rel. to manpath */
         enum form        dform;   /* format from directory */          enum form        dform;   /* format from directory */
         enum form        sform;   /* format from file name suffix */          enum form        fform;   /* format from file name suffix */
         char            *dsec;    /* section from directory */          char            *dsec;    /* section from directory */
         char            *arch;    /* architecture from directory */          char            *arch;    /* architecture from directory */
         char            *name;    /* name from file name (not empty) */          char            *name;    /* name from file name (not empty) */
Line 137  static void  dbclose(int);
Line 137  static void  dbclose(int);
 static  void     dbindex(const struct mpage *, struct mchars *);  static  void     dbindex(const struct mpage *, struct mchars *);
 static  int      dbopen(int);  static  int      dbopen(int);
 static  void     dbprune(void);  static  void     dbprune(void);
 static  void     fileadd(struct mlink *);  
 static  int      filecheck(const char *);  
 static  void     filescan(const char *);  static  void     filescan(const char *);
 static  void    *hash_alloc(size_t, void *);  static  void    *hash_alloc(size_t, void *);
 static  void     hash_free(void *, size_t, void *);  static  void     hash_free(void *, size_t, void *);
 static  void    *hash_halloc(size_t, void *);  static  void    *hash_halloc(size_t, void *);
 static  void     inoadd(const struct stat *, struct mpage *);  
 static  int      inocheck(const struct stat *);  static  int      inocheck(const struct stat *);
 static  void     ofadd(int, const char *, const char *, const char *,  static  void     mlink_add(struct mlink *, const struct stat *);
                         const char *, const char *, const struct stat *);  
 static  void     mlink_free(struct mlink *);  static  void     mlink_free(struct mlink *);
 static  void     mpages_free(void);  static  void     mpages_free(void);
 static  void     mpages_merge(struct mchars *, struct mparse *, int);  static  void     mpages_merge(struct mchars *, struct mparse *, int);
Line 184  static int   exitcode; /* to be returned by main */
Line 180  static int   exitcode; /* to be returned by main */
 static  enum op          op; /* operational mode */  static  enum op          op; /* operational mode */
 static  char             basedir[PATH_MAX]; /* current base directory */  static  char             basedir[PATH_MAX]; /* current base directory */
 static  struct ohash     mpages; /* table of distinct manual pages */  static  struct ohash     mpages; /* table of distinct manual pages */
 static  struct ohash     filenames; /* table of filenames */  static  struct ohash     mlinks; /* table of directory entries */
 static  struct ohash     strings; /* table of all strings */  static  struct ohash     strings; /* table of all strings */
 static  sqlite3         *db = NULL; /* current database */  static  sqlite3         *db = NULL; /* current database */
 static  sqlite3_stmt    *stmts[STMT__MAX]; /* current statements */  static  sqlite3_stmt    *stmts[STMT__MAX]; /* current statements */
Line 323  main(int argc, char *argv[])
Line 319  main(int argc, char *argv[])
         struct mchars    *mc;          struct mchars    *mc;
         struct manpaths   dirs;          struct manpaths   dirs;
         struct mparse    *mp;          struct mparse    *mp;
         struct ohash_info mpages_info, filename_info;          struct ohash_info mpages_info, mlinks_info;
   
         memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *));          memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *));
         memset(&dirs, 0, sizeof(struct manpaths));          memset(&dirs, 0, sizeof(struct manpaths));
   
         mpages_info.alloc  = filename_info.alloc  = hash_alloc;          mpages_info.alloc  = mlinks_info.alloc  = hash_alloc;
         mpages_info.halloc = filename_info.halloc = hash_halloc;          mpages_info.halloc = mlinks_info.halloc = hash_halloc;
         mpages_info.hfree  = filename_info.hfree  = hash_free;          mpages_info.hfree  = mlinks_info.hfree  = hash_free;
   
         mpages_info.key_offset = offsetof(struct mpage, inodev);          mpages_info.key_offset = offsetof(struct mpage, inodev);
         filename_info.key_offset = offsetof(struct mlink, file);          mlinks_info.key_offset = offsetof(struct mlink, file);
   
         progname = strrchr(argv[0], '/');          progname = strrchr(argv[0], '/');
         if (progname == NULL)          if (progname == NULL)
Line 408  main(int argc, char *argv[])
Line 404  main(int argc, char *argv[])
         mc = mchars_alloc();          mc = mchars_alloc();
   
         ohash_init(&mpages, 6, &mpages_info);          ohash_init(&mpages, 6, &mpages_info);
         ohash_init(&filenames, 6, &filename_info);          ohash_init(&mlinks, 6, &mlinks_info);
   
         if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) {          if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) {
                 /*                  /*
Line 462  main(int argc, char *argv[])
Line 458  main(int argc, char *argv[])
   
                         if (j) {                          if (j) {
                                 ohash_init(&mpages, 6, &mpages_info);                                  ohash_init(&mpages, 6, &mpages_info);
                                 ohash_init(&filenames, 6, &filename_info);                                  ohash_init(&mlinks, 6, &mlinks_info);
                         }                          }
   
                         if (0 == set_basedir(dirs.paths[j]))                          if (0 == set_basedir(dirs.paths[j]))
Line 480  main(int argc, char *argv[])
Line 476  main(int argc, char *argv[])
                         if (j + 1 < dirs.sz) {                          if (j + 1 < dirs.sz) {
                                 mpages_free();                                  mpages_free();
                                 ohash_delete(&mpages);                                  ohash_delete(&mpages);
                                 ohash_delete(&filenames);                                  ohash_delete(&mlinks);
                         }                          }
                 }                  }
         }          }
Line 491  out:
Line 487  out:
         mparse_free(mp);          mparse_free(mp);
         mpages_free();          mpages_free();
         ohash_delete(&mpages);          ohash_delete(&mpages);
         ohash_delete(&filenames);          ohash_delete(&mlinks);
         return(exitcode);          return(exitcode);
 usage:  usage:
         fprintf(stderr, "usage: %s [-anvW] [-C file]\n"          fprintf(stderr, "usage: %s [-anvW] [-C file]\n"
Line 524  treescan(void)
Line 520  treescan(void)
 {  {
         FTS             *f;          FTS             *f;
         FTSENT          *ff;          FTSENT          *ff;
           struct mlink    *mlink;
         int              dform;          int              dform;
         char            *sec;          char            *fsec;
         const char      *dsec, *arch, *cp, *path;          const char      *dsec, *arch, *cp, *path;
         const char      *argv[2];          const char      *argv[2];
   
Line 549  treescan(void)
Line 546  treescan(void)
         while (NULL != (ff = fts_read(f))) {          while (NULL != (ff = fts_read(f))) {
                 path = ff->fts_path + 2;                  path = ff->fts_path + 2;
                 /*                  /*
                  * If we're a regular file, add an mpage by using the                   * If we're a regular file, add an mlink by using the
                  * stored directory data and handling the filename.                   * stored directory data and handling the filename.
                  * Disallow duplicate (hard-linked) files.                   * Disallow duplicate (hard-linked) files.
                  */                   */
Line 564  treescan(void)
Line 561  treescan(void)
                                 if (warnings)                                  if (warnings)
                                         say(path, "Duplicate file");                                          say(path, "Duplicate file");
                                 continue;                                  continue;
                         } else if (NULL == (sec =                          } else if (NULL == (fsec =
                                         strrchr(ff->fts_name, '.'))) {                                          strrchr(ff->fts_name, '.'))) {
                                 if ( ! use_all) {                                  if ( ! use_all) {
                                         if (warnings)                                          if (warnings)
Line 572  treescan(void)
Line 569  treescan(void)
                                                     "No filename suffix");                                                      "No filename suffix");
                                         continue;                                          continue;
                                 }                                  }
                         } else if (0 == strcmp(++sec, "html")) {                          } else if (0 == strcmp(++fsec, "html")) {
                                 if (warnings)                                  if (warnings)
                                         say(path, "Skip html");                                          say(path, "Skip html");
                                 continue;                                  continue;
                         } else if (0 == strcmp(sec, "gz")) {                          } else if (0 == strcmp(fsec, "gz")) {
                                 if (warnings)                                  if (warnings)
                                         say(path, "Skip gz");                                          say(path, "Skip gz");
                                 continue;                                  continue;
                         } else if (0 == strcmp(sec, "ps")) {                          } else if (0 == strcmp(fsec, "ps")) {
                                 if (warnings)                                  if (warnings)
                                         say(path, "Skip ps");                                          say(path, "Skip ps");
                                 continue;                                  continue;
                         } else if (0 == strcmp(sec, "pdf")) {                          } else if (0 == strcmp(fsec, "pdf")) {
                                 if (warnings)                                  if (warnings)
                                         say(path, "Skip pdf");                                          say(path, "Skip pdf");
                                 continue;                                  continue;
                         } else if ( ! use_all &&                          } else if ( ! use_all &&
                             ((FORM_SRC == dform && strcmp(sec, dsec)) ||                              ((FORM_SRC == dform && strcmp(fsec, dsec)) ||
                              (FORM_CAT == dform && strcmp(sec, "0")))) {                               (FORM_CAT == dform && strcmp(fsec, "0")))) {
                                 if (warnings)                                  if (warnings)
                                         say(path, "Wrong filename suffix");                                          say(path, "Wrong filename suffix");
                                 continue;                                  continue;
                         } else                          } else
                                 sec[-1] = '\0';                                  fsec[-1] = '\0';
                         ofadd(dform, path, ff->fts_name, dsec, sec,                          mlink = mandoc_calloc(1, sizeof(struct mlink));
                                         arch, ff->fts_statp);                          strlcpy(mlink->file, path, sizeof(mlink->file));
                           mlink->dform = dform;
                           if (NULL != dsec)
                                   mlink->dsec = mandoc_strdup(dsec);
                           if (NULL != arch)
                                   mlink->arch = mandoc_strdup(arch);
                           mlink->name = mandoc_strdup(ff->fts_name);
                           if (NULL != fsec)
                                   mlink->fsec = mandoc_strdup(fsec);
                           mlink_add(mlink, ff->fts_statp);
                         continue;                          continue;
                 } else if (FTS_D != ff->fts_info &&                  } else if (FTS_D != ff->fts_info &&
                                 FTS_DP != ff->fts_info) {                                  FTS_DP != ff->fts_info) {
                         if (warnings)                          if (warnings)
                                 say(path, "Not a regular file");                                  say(path, "Not a regular file");
Line 672  treescan(void)
Line 678  treescan(void)
  *   or   *   or
  *   [./]cat<section>[/<arch>]/<name>.0   *   [./]cat<section>[/<arch>]/<name>.0
  *   *
  * Stuff this information directly into the mpage vector.   * Stuff this information directly into the mlink vector.
  * See treescan() for the fts(3) version of this.   * See treescan() for the fts(3) version of this.
  */   */
 static void  static void
 filescan(const char *file)  filescan(const char *file)
 {  {
         char             buf[PATH_MAX];          char             buf[PATH_MAX];
         const char      *sec, *arch, *name, *dsec;  
         char            *p, *start;  
         int              dform;  
         struct stat      st;          struct stat      st;
           struct mlink    *mlink;
           char            *p, *start;
   
         assert(use_all);          assert(use_all);
   
Line 711  filescan(const char *file)
Line 716  filescan(const char *file)
                 return;                  return;
         }          }
         start = buf + strlen(basedir);          start = buf + strlen(basedir);
         sec = arch = name = dsec = NULL;          mlink = mandoc_calloc(1, sizeof(struct mlink));
         dform = FORM_NONE;          strlcpy(mlink->file, start, sizeof(mlink->file));
   
         /*          /*
          * First try to guess our directory structure.           * First try to guess our directory structure.
Line 723  filescan(const char *file)
Line 728  filescan(const char *file)
         if (NULL != (p = strchr(start, '/'))) {          if (NULL != (p = strchr(start, '/'))) {
                 *p++ = '\0';                  *p++ = '\0';
                 if (0 == strncmp(start, "man", 3)) {                  if (0 == strncmp(start, "man", 3)) {
                         dform = FORM_SRC;                          mlink->dform = FORM_SRC;
                         dsec = start + 3;                          mlink->dsec = mandoc_strdup(start + 3);
                 } else if (0 == strncmp(start, "cat", 3)) {                  } else if (0 == strncmp(start, "cat", 3)) {
                         dform = FORM_CAT;                          mlink->dform = FORM_CAT;
                         dsec = start + 3;                          mlink->dsec = mandoc_strdup(start + 3);
                 }                  }
   
                 start = p;                  start = p;
                 if (NULL != dsec && NULL != (p = strchr(start, '/'))) {                  if (NULL != mlink->dsec && NULL != (p = strchr(start, '/'))) {
                         *p++ = '\0';                          *p++ = '\0';
                         arch = start;                          mlink->arch = mandoc_strdup(start);
                         start = p;                          start = p;
                 }                  }
         }          }
   
         /*          /*
Line 748  filescan(const char *file)
Line 753  filescan(const char *file)
   
         if ('.' == *p) {          if ('.' == *p) {
                 *p++ = '\0';                  *p++ = '\0';
                 sec = p;                  mlink->fsec = mandoc_strdup(p);
         }          }
   
         /*          /*
          * Now try to parse the name.           * Now try to parse the name.
          * Use the filename portion of the path.           * Use the filename portion of the path.
          */           */
         name = start;          mlink->name = start;
         if (NULL != (p = strrchr(start, '/'))) {          if (NULL != (p = strrchr(start, '/'))) {
                 name = p + 1;                  mlink->name = p + 1;
                 *p = '\0';                  *p = '\0';
         }          }
           mlink->name = mandoc_strdup(mlink->name);
   
         ofadd(dform, file, name, dsec, sec, arch, &st);          mlink_add(mlink, &st);
 }  }
   
 /*  
  * See fileadd().  
  */  
 static int  static int
 filecheck(const char *name)  
 {  
   
         return(NULL != ohash_find(&filenames,  
                         ohash_qlookup(&filenames, name)));  
 }  
   
 /*  
  * Use the standard hashing mechanism (K&R) to see if the given filename  
  * already exists.  
  */  
 static void  
 fileadd(struct mlink *mlink)  
 {  
         unsigned int     slot;  
   
         slot = ohash_qlookup(&filenames, mlink->file);  
         assert(NULL == ohash_find(&filenames, slot));  
         ohash_insert(&filenames, slot, mlink);  
 }  
   
 /*  
  * See inoadd().  
  */  
 static int  
 inocheck(const struct stat *st)  inocheck(const struct stat *st)
 {  {
         struct inodev    inodev;          struct inodev    inodev;
Line 806  inocheck(const struct stat *st)
Line 784  inocheck(const struct stat *st)
                         &mpages, (char *)&inodev, sizeof(inodev), hash)));                          &mpages, (char *)&inodev, sizeof(inodev), hash)));
 }  }
   
 /*  
  * The hashing function used here is quite simple: simply take the inode  
  * and use uint32_t of its bits.  
  * Then when we do the lookup, use both the inode and device identifier.  
  */  
 static void  static void
 inoadd(const struct stat *st, struct mpage *mpage)  mlink_add(struct mlink *mlink, const struct stat *st)
 {  {
           struct inodev    inodev;
           struct mpage    *mpage;
         unsigned int     slot;          unsigned int     slot;
   
         mpage->inodev.st_ino = st->st_ino;          assert(NULL != mlink->file);
         mpage->inodev.st_dev = st->st_dev;  
         slot = ohash_lookup_memory(&mpages, (char *)&mpage->inodev,  
             sizeof(struct inodev), st->st_ino);  
   
         assert(NULL == ohash_find(&mpages, slot));          if (NULL == mlink->dsec)
         ohash_insert(&mpages, slot, mpage);                  mlink->dsec = mandoc_strdup("");
 }          if (NULL == mlink->arch)
                   mlink->arch = mandoc_strdup("");
           if (NULL == mlink->name)
                   mlink->name = mandoc_strdup("");
           if (NULL == mlink->fsec)
                   mlink->fsec = mandoc_strdup("");
   
 static void          if ('0' == *mlink->fsec) {
 ofadd(int dform, const char *file, const char *name, const char *dsec,                  free(mlink->fsec);
         const char *sec, const char *arch, const struct stat *st)                  mlink->fsec = mandoc_strdup(mlink->dsec);
 {                  mlink->fform = FORM_CAT;
         struct mpage    *mpage;          } else if ('1' <= *mlink->fsec && '9' >= *mlink->fsec)
         struct mlink    *mlink;                  mlink->fform = FORM_SRC;
         int              sform;  
   
         assert(NULL != file);  
   
         if (NULL == name)  
                 name = "";  
         if (NULL == sec)  
                 sec = "";  
         if (NULL == dsec)  
                 dsec = "";  
         if (NULL == arch)  
                 arch = "";  
   
         if ('0' == *sec) {  
                 sec = dsec;  
                 sform = FORM_CAT;  
         } else if ('1' <= *sec && '9' >= *sec)  
                 sform = FORM_SRC;  
         else          else
                 sform = FORM_NONE;                  mlink->fform = FORM_NONE;
   
         mlink = mandoc_calloc(1, sizeof(struct mlink));          slot = ohash_qlookup(&mlinks, mlink->file);
         strlcpy(mlink->file, file, PATH_MAX);          assert(NULL == ohash_find(&mlinks, slot));
         mlink->dform = dform;          ohash_insert(&mlinks, slot, mlink);
         mlink->sform = sform;  
         mlink->dsec = mandoc_strdup(dsec);  
         mlink->arch = mandoc_strdup(arch);  
         mlink->name = mandoc_strdup(name);  
         mlink->fsec = mandoc_strdup(sec);  
   
         mpage = mandoc_calloc(1, sizeof(struct mpage));          inodev.st_ino = st->st_ino;
           inodev.st_dev = st->st_dev;
           slot = ohash_lookup_memory(&mpages, (char *)&inodev,
               sizeof(struct inodev), inodev.st_ino);
           mpage = ohash_find(&mpages, slot);
           if (NULL == mpage) {
                   mpage = mandoc_calloc(1, sizeof(struct mpage));
                   mpage->inodev.st_ino = inodev.st_ino;
                   mpage->inodev.st_dev = inodev.st_dev;
                   ohash_insert(&mpages, slot, mpage);
           } else
                   abort();
         mpage->mlinks = mlink;          mpage->mlinks = mlink;
   
         /*  
          * Add to unique identifier hash.  
          * Then if it's a source manual and we're going to use source in  
          * favour of catpages, add it to that hash.  
          */  
         inoadd(st, mpage);  
         fileadd(mpage->mlinks);  
 }  }
   
 static void  static void
Line 967  mpages_merge(struct mchars *mc, struct mparse *mp, int
Line 924  mpages_merge(struct mchars *mc, struct mparse *mp, int
                         if (NULL != (bufp = strrchr(buf, '.')))                          if (NULL != (bufp = strrchr(buf, '.')))
                                 *++bufp = '\0';                                  *++bufp = '\0';
                         strlcat(buf, mpage->mlinks->dsec, PATH_MAX);                          strlcat(buf, mpage->mlinks->dsec, PATH_MAX);
                         if (filecheck(buf)) {                          if (NULL != ohash_find(&mlinks,
                                           ohash_qlookup(&mlinks, buf))) {
                                 if (warnings)                                  if (warnings)
                                         say(mpage->mlinks->file, "Man "                                          say(mpage->mlinks->file, "Man "
                                             "source exists: %s", buf);                                              "source exists: %s", buf);
Line 988  mpages_merge(struct mchars *mc, struct mparse *mp, int
Line 946  mpages_merge(struct mchars *mc, struct mparse *mp, int
                  * formatted.  Fall back to formatted mode.                   * formatted.  Fall back to formatted mode.
                  */                   */
                 if (FORM_CAT != mpage->mlinks->dform ||                  if (FORM_CAT != mpage->mlinks->dform ||
                     FORM_CAT != mpage->mlinks->sform) {                      FORM_CAT != mpage->mlinks->fform) {
                         lvl = mparse_readfd(mp, -1, mpage->mlinks->file);                          lvl = mparse_readfd(mp, -1, mpage->mlinks->file);
                         if (lvl < MANDOCLEVEL_FATAL)                          if (lvl < MANDOCLEVEL_FATAL)
                                 mparse_result(mp, &mdoc, &man);                                  mparse_result(mp, &mdoc, &man);
Line 999  mpages_merge(struct mchars *mc, struct mparse *mp, int
Line 957  mpages_merge(struct mchars *mc, struct mparse *mp, int
                         mpage->sec =                          mpage->sec =
                             mandoc_strdup(mdoc_meta(mdoc)->msec);                              mandoc_strdup(mdoc_meta(mdoc)->msec);
                         mpage->arch = mdoc_meta(mdoc)->arch;                          mpage->arch = mdoc_meta(mdoc)->arch;
                         if (NULL == mpage->arch)                          mpage->arch = mandoc_strdup(
                                 mpage->arch = "";                              NULL == mpage->arch ? "" : mpage->arch);
                         mpage->arch = mandoc_strdup(mpage->arch);  
                         mpage->title =                          mpage->title =
                             mandoc_strdup(mdoc_meta(mdoc)->title);                              mandoc_strdup(mdoc_meta(mdoc)->title);
                 } else if (NULL != man) {                  } else if (NULL != man) {

Legend:
Removed from v.1.82  
changed lines
  Added in v.1.84

CVSweb