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

Diff for /mandoc/mandocdb.c between version 1.54 and 1.58

version 1.54, 2012/06/09 11:21:12 version 1.58, 2013/06/05 02:00:26
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 19 
Line 19 
 #include "config.h"  #include "config.h"
 #endif  #endif
   
 #include <sys/param.h>  
 #include <sys/stat.h>  #include <sys/stat.h>
   
 #include <assert.h>  #include <assert.h>
Line 28 
Line 27 
 #include <fcntl.h>  #include <fcntl.h>
 #include <fts.h>  #include <fts.h>
 #include <getopt.h>  #include <getopt.h>
   #include <limits.h>
 #include <stddef.h>  #include <stddef.h>
 #include <stdint.h>  #include <stdint.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 44 
Line 44 
 #include "mdoc.h"  #include "mdoc.h"
 #include "man.h"  #include "man.h"
 #include "mandoc.h"  #include "mandoc.h"
 #include "mandocdb.h"  
 #include "manpath.h"  #include "manpath.h"
   #include "mansearch.h"
   
 /* Post a warning to stderr. */  
 #define WARNING(_f, _b, _fmt, _args...) \  
         do if (warnings) { \  
                 fprintf(stderr, "%s: ", (_b)); \  
                 fprintf(stderr, (_fmt), ##_args); \  
                 if ('\0' != *(_f)) \  
                         fprintf(stderr, ": %s", (_f)); \  
                 fprintf(stderr, "\n"); \  
         } while (/* CONSTCOND */ 0)  
 /* Post a "verbose" message to stderr. */  
 #define DEBUG(_f, _b, _fmt, _args...) \  
         do if (verb) { \  
                 fprintf(stderr, "%s: ", (_b)); \  
                 fprintf(stderr, (_fmt), ##_args); \  
                 fprintf(stderr, ": %s\n", (_f)); \  
         } while (/* CONSTCOND */ 0)  
   
 #define SQL_EXEC(_v) \  #define SQL_EXEC(_v) \
         if (SQLITE_OK != sqlite3_exec(db, (_v), NULL, NULL, NULL)) \          if (SQLITE_OK != sqlite3_exec(db, (_v), NULL, NULL, NULL)) \
                 fprintf(stderr, "%s\n", sqlite3_errmsg(db))                  fprintf(stderr, "%s\n", sqlite3_errmsg(db))
Line 115  struct of {
Line 98  struct of {
         struct of       *next; /* next in ofs */          struct of       *next; /* next in ofs */
         enum form        dform; /* path-cued form */          enum form        dform; /* path-cued form */
         enum form        sform; /* suffix-cued form */          enum form        sform; /* suffix-cued form */
         char             file[MAXPATHLEN]; /* filename rel. to manpath */          char             file[PATH_MAX]; /* filename rel. to manpath */
         const char      *desc; /* parsed description */          const char      *desc; /* parsed description */
         const char      *sec; /* suffix-cued section (or empty) */          const char      *sec; /* suffix-cued section (or empty) */
         const char      *dsec; /* path-cued section (or empty) */          const char      *dsec; /* path-cued section (or empty) */
Line 179  static void  putkeys(const struct of *, 
Line 162  static void  putkeys(const struct of *, 
                         const char *, int, uint64_t);                          const char *, int, uint64_t);
 static  void     putmdockey(const struct of *,  static  void     putmdockey(const struct of *,
                         const struct mdoc_node *, uint64_t);                          const struct mdoc_node *, uint64_t);
   static  void     say(const char *, const char *, const char *, ...);
 static  char    *stradd(const char *);  static  char    *stradd(const char *);
 static  char    *straddbuf(const char *, size_t);  static  char    *straddbuf(const char *, size_t);
 static  int      treescan(const char *);  static  int      treescan(const char *);
Line 329  static const struct mdoc_handler mdocs[MDOC_MAX] = {
Line 313  static const struct mdoc_handler mdocs[MDOC_MAX] = {
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         char              cwd[MAXPATHLEN];          char              cwd[PATH_MAX];
         int               ch, rc, fd, i;          int               ch, rc, fd, i;
         unsigned int      index;          unsigned int      index;
         size_t            j, sz;          size_t            j, sz;
Line 366  main(int argc, char *argv[])
Line 350  main(int argc, char *argv[])
          * handle relative paths, and by doing this, we can return to           * handle relative paths, and by doing this, we can return to
          * the starting point.           * the starting point.
          */           */
         if (NULL == getcwd(cwd, MAXPATHLEN)) {          if (NULL == getcwd(cwd, PATH_MAX)) {
                 perror(NULL);                  perror(NULL);
                 return(EXIT_FAILURE);                  return(EXIT_FAILURE);
         } else if (-1 == (fd = open(cwd, O_RDONLY, 0))) {          } else if (-1 == (fd = open(cwd, O_RDONLY, 0))) {
Line 600  treescan(const char *base)
Line 584  treescan(const char *base)
                  */                   */
                 if (FTS_F == ff->fts_info) {                  if (FTS_F == ff->fts_info) {
                         if ( ! use_all && ff->fts_level < 2) {                          if ( ! use_all && ff->fts_level < 2) {
                                 WARNING(path, base, "Extraneous file");                                  if (warnings)
                                           say(base, path, "Extraneous file");
                                 continue;                                  continue;
                         } else if (inocheck(ff->fts_statp)) {                          } else if (inocheck(ff->fts_statp)) {
                                 WARNING(path, base, "Duplicate file");                                  if (warnings)
                                           say(base, path, "Duplicate file");
                                 continue;                                  continue;
                         }                          }
   
                         cp = ff->fts_name;                          cp = ff->fts_name;
   
                         if (0 == strcmp(cp, "mandocdb.db")) {                          if (0 == strcmp(cp, "mandocdb.db")) {
                                 WARNING(path, base, "Skip database");                                  if (warnings)
                                           say(base, path, "Skip database");
                                 continue;                                  continue;
                         } else if (NULL != (cp = strrchr(cp, '.'))) {                          } else if (NULL != (cp = strrchr(cp, '.'))) {
                                 if (0 == strcmp(cp + 1, "html")) {                                  if (0 == strcmp(cp + 1, "html")) {
                                         WARNING(path, base, "Skip html");                                          if (warnings)
                                                   say(base, path, "Skip html");
                                         continue;                                          continue;
                                 } else if (0 == strcmp(cp + 1, "gz")) {                                  } else if (0 == strcmp(cp + 1, "gz")) {
                                         WARNING(path, base, "Skip gz");                                          if (warnings)
                                                   say(base, path, "Skip gz");
                                         continue;                                          continue;
                                 } else if (0 == strcmp(cp + 1, "ps")) {                                  } else if (0 == strcmp(cp + 1, "ps")) {
                                         WARNING(path, base, "Skip ps");                                          if (warnings)
                                                   say(base, path, "Skip ps");
                                         continue;                                          continue;
                                 } else if (0 == strcmp(cp + 1, "pdf")) {                                  } else if (0 == strcmp(cp + 1, "pdf")) {
                                         WARNING(path, base, "Skip pdf");                                          if (warnings)
                                                   say(base, path, "Skip pdf");
                                         continue;                                          continue;
                                 }                                  }
                         }                          }
Line 667  treescan(const char *base)
Line 658  treescan(const char *base)
                         if (NULL != dsec || use_all)                          if (NULL != dsec || use_all)
                                 break;                                  break;
   
                         WARNING(path, base, "Unknown directory part");                          if (warnings)
                                   say(base, path, "Unknown directory part");
                         fts_set(f, ff, FTS_SKIP);                          fts_set(f, ff, FTS_SKIP);
                         break;                          break;
                 case (2):                  case (2):
Line 682  treescan(const char *base)
Line 674  treescan(const char *base)
                 default:                  default:
                         if (FTS_DP == ff->fts_info || use_all)                          if (FTS_DP == ff->fts_info || use_all)
                                 break;                                  break;
                         WARNING(path, base, "Extraneous directory part");                          if (warnings)
                                   say(base, path, "Extraneous directory part");
                         fts_set(f, ff, FTS_SKIP);                          fts_set(f, ff, FTS_SKIP);
                         break;                          break;
                 }                  }
Line 721  filescan(const char *file, const char *base)
Line 714  filescan(const char *file, const char *base)
                 file += 2;                  file += 2;
   
         if (-1 == stat(file, &st)) {          if (-1 == stat(file, &st)) {
                 WARNING(file, base, "%s", strerror(errno));                  if (warnings)
                           say(base, file, "%s", strerror(errno));
                 return;                  return;
         } else if ( ! (S_IFREG & st.st_mode)) {          } else if ( ! (S_IFREG & st.st_mode)) {
                 WARNING(file, base, "Not a regular file");                  if (warnings)
                           say(base, file, "Not a regular file");
                 return;                  return;
         } else if (inocheck(&st)) {          } else if (inocheck(&st)) {
                 WARNING(file, base, "Duplicate file");                  if (warnings)
                           say(base, file, "Duplicate file");
                 return;                  return;
         }          }
   
Line 880  ofadd(const char *base, int dform, const char *file, 
Line 876  ofadd(const char *base, int dform, const char *file, 
         }          }
   
         of = mandoc_calloc(1, sizeof(struct of));          of = mandoc_calloc(1, sizeof(struct of));
         strlcpy(of->file, file, MAXPATHLEN);          strlcpy(of->file, file, PATH_MAX);
         of->name = name;          of->name = name;
         of->sec = sec;          of->sec = sec;
         of->dsec = dsec;          of->dsec = dsec;
Line 924  ofmerge(struct mchars *mc, struct mparse *mp, const ch
Line 920  ofmerge(struct mchars *mc, struct mparse *mp, const ch
         size_t           sz;          size_t           sz;
         struct mdoc     *mdoc;          struct mdoc     *mdoc;
         struct man      *man;          struct man      *man;
         char             buf[MAXPATHLEN];          char             buf[PATH_MAX];
         char            *bufp;          char            *bufp;
         const char      *msec, *march, *mtitle, *cp;          const char      *msec, *march, *mtitle, *cp;
         struct of       *of;          struct of       *of;
Line 939  ofmerge(struct mchars *mc, struct mparse *mp, const ch
Line 935  ofmerge(struct mchars *mc, struct mparse *mp, const ch
                  * own.                   * own.
                  */                   */
                 if ( ! use_all && FORM_CAT == of->dform) {                  if ( ! use_all && FORM_CAT == of->dform) {
                         sz = strlcpy(buf, of->file, MAXPATHLEN);                          sz = strlcpy(buf, of->file, PATH_MAX);
                         if (sz >= MAXPATHLEN) {                          if (sz >= PATH_MAX) {
                                 WARNING(of->file, base,                                  if (warnings)
                                         "Filename too long");                                          say(base, of->file,
                                               "Filename too long");
                                 continue;                                  continue;
                         }                          }
                         bufp = strstr(buf, "cat");                          bufp = strstr(buf, "cat");
Line 950  ofmerge(struct mchars *mc, struct mparse *mp, const ch
Line 947  ofmerge(struct mchars *mc, struct mparse *mp, const ch
                         memcpy(bufp, "man", 3);                          memcpy(bufp, "man", 3);
                         if (NULL != (bufp = strrchr(buf, '.')))                          if (NULL != (bufp = strrchr(buf, '.')))
                                 *++bufp = '\0';                                  *++bufp = '\0';
                         strlcat(buf, of->dsec, MAXPATHLEN);                          strlcat(buf, of->dsec, PATH_MAX);
                         if (filecheck(buf)) {                          if (filecheck(buf)) {
                                 WARNING(of->file, base, "Man "                                  if (warnings)
                                         "source exists: %s", buf);                                          say(base, of->file, "Man "
                                               "source exists: %s", buf);
                                 continue;                                  continue;
                         }                          }
                 }                  }
Line 1006  ofmerge(struct mchars *mc, struct mparse *mp, const ch
Line 1004  ofmerge(struct mchars *mc, struct mparse *mp, const ch
                  * section, like encrypt(1) = makekey(8).  Do not skip                   * section, like encrypt(1) = makekey(8).  Do not skip
                  * manuals for such reasons.                   * manuals for such reasons.
                  */                   */
                 if ( ! use_all && form && strcasecmp(msec, of->dsec))                  if (warnings && !use_all && form &&
                         WARNING(of->file, base, "Section \"%s\" "                                  strcasecmp(msec, of->dsec))
                           say(base, of->file, "Section \"%s\" "
                                 "manual in %s directory",                                  "manual in %s directory",
                                 msec, of->dsec);                                  msec, of->dsec);
   
Line 1025  ofmerge(struct mchars *mc, struct mparse *mp, const ch
Line 1024  ofmerge(struct mchars *mc, struct mparse *mp, const ch
                  * Thus, warn about architecture mismatches,                   * Thus, warn about architecture mismatches,
                  * but don't skip manuals for this reason.                   * but don't skip manuals for this reason.
                  */                   */
                 if ( ! use_all && strcasecmp(march, of->arch))                  if (warnings && !use_all && strcasecmp(march, of->arch))
                         WARNING(of->file, base, "Architecture \"%s\" "                          say(base, of->file, "Architecture \"%s\" "
                                 "manual in \"%s\" directory",                                  "manual in \"%s\" directory",
                                 march, of->arch);                                  march, of->arch);
   
Line 1055  parse_catpage(struct of *of, const char *base)
Line 1054  parse_catpage(struct of *of, const char *base)
         size_t           len, plen, titlesz;          size_t           len, plen, titlesz;
   
         if (NULL == (stream = fopen(of->file, "r"))) {          if (NULL == (stream = fopen(of->file, "r"))) {
                 WARNING(of->file, base, "%s", strerror(errno));                  if (warnings)
                           say(base, of->file, "%s", strerror(errno));
                 return;                  return;
         }          }
   
Line 1107  parse_catpage(struct of *of, const char *base)
Line 1107  parse_catpage(struct of *of, const char *base)
          */           */
   
         if (NULL == title || '\0' == *title) {          if (NULL == title || '\0' == *title) {
                 WARNING(of->file, base, "Cannot find NAME section");                  if (warnings)
                           say(base, of->file, "Cannot find NAME section");
                 fclose(stream);                  fclose(stream);
                 free(title);                  free(title);
                 return;                  return;
Line 1126  parse_catpage(struct of *of, const char *base)
Line 1127  parse_catpage(struct of *of, const char *base)
                 for (p += 2; ' ' == *p || '\b' == *p; p++)                  for (p += 2; ' ' == *p || '\b' == *p; p++)
                         /* Skip to next word. */ ;                          /* Skip to next word. */ ;
         } else {          } else {
                 WARNING(of->file, base, "No dash in title line");                  if (warnings)
                           say(base, of->file, "No dash in title line");
                 p = title;                  p = title;
         }          }
   
Line 1804  dbindex(struct mchars *mc, int form, 
Line 1806  dbindex(struct mchars *mc, int form, 
         int64_t          recno;          int64_t          recno;
         size_t           i;          size_t           i;
   
         DEBUG(of->file, base, "Adding to index");          if (verb)
                   say(base, of->file, "Adding to index");
   
         if (nodb)          if (nodb)
                 return;                  return;
Line 1859  dbprune(const char *base)
Line 1862  dbprune(const char *base)
                 SQL_BIND_TEXT(stmts[STMT_DELETE], i, of->file);                  SQL_BIND_TEXT(stmts[STMT_DELETE], i, of->file);
                 SQL_STEP(stmts[STMT_DELETE]);                  SQL_STEP(stmts[STMT_DELETE]);
                 sqlite3_reset(stmts[STMT_DELETE]);                  sqlite3_reset(stmts[STMT_DELETE]);
                 DEBUG(of->file, base, "Deleted from index");                  if (verb)
                           say(base, of->file, "Deleted from index");
         }          }
 }  }
   
Line 1871  static void
Line 1875  static void
 dbclose(const char *base, int real)  dbclose(const char *base, int real)
 {  {
         size_t           i;          size_t           i;
         char             file[MAXPATHLEN];          char             file[PATH_MAX];
   
         if (nodb)          if (nodb)
                 return;                  return;
Line 1887  dbclose(const char *base, int real)
Line 1891  dbclose(const char *base, int real)
         if (real)          if (real)
                 return;                  return;
   
         strlcpy(file, MANDOC_DB, MAXPATHLEN);          strlcpy(file, MANDOC_DB, PATH_MAX);
         strlcat(file, "~", MAXPATHLEN);          strlcat(file, "~", PATH_MAX);
         if (-1 == rename(file, MANDOC_DB))          if (-1 == rename(file, MANDOC_DB))
                 perror(MANDOC_DB);                  perror(MANDOC_DB);
 }  }
Line 1904  dbclose(const char *base, int real)
Line 1908  dbclose(const char *base, int real)
 static int  static int
 dbopen(const char *base, int real)  dbopen(const char *base, int real)
 {  {
         char             file[MAXPATHLEN];          char             file[PATH_MAX];
         const char      *sql;          const char      *sql;
         int              rc, ofl;          int              rc, ofl;
         size_t           sz;          size_t           sz;
Line 1912  dbopen(const char *base, int real)
Line 1916  dbopen(const char *base, int real)
         if (nodb)          if (nodb)
                 return(1);                  return(1);
   
         sz = strlcpy(file, MANDOC_DB, MAXPATHLEN);          sz = strlcpy(file, MANDOC_DB, PATH_MAX);
         if ( ! real)          if ( ! real)
                 sz = strlcat(file, "~", MAXPATHLEN);                  sz = strlcat(file, "~", PATH_MAX);
   
         if (sz >= MAXPATHLEN) {          if (sz >= PATH_MAX) {
                 fprintf(stderr, "%s: Path too long\n", file);                  fprintf(stderr, "%s: Path too long\n", file);
                 return(0);                  return(0);
         }          }
Line 1929  dbopen(const char *base, int real)
Line 1933  dbopen(const char *base, int real)
   
         rc = sqlite3_open_v2(file, &db, ofl, NULL);          rc = sqlite3_open_v2(file, &db, ofl, NULL);
         if (SQLITE_OK == rc)          if (SQLITE_OK == rc)
                 return(1);                  goto prepare_statements;
         if (SQLITE_CANTOPEN != rc) {          if (SQLITE_CANTOPEN != rc) {
                 perror(file);                  perror(file);
                 return(0);                  return(0);
Line 1967  dbopen(const char *base, int real)
Line 1971  dbopen(const char *base, int real)
                 return(0);                  return(0);
         }          }
   
   prepare_statements:
           SQL_EXEC("PRAGMA foreign_keys = ON");
         sql = "DELETE FROM docs where file=?";          sql = "DELETE FROM docs where file=?";
         sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE], NULL);          sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE], NULL);
         sql = "INSERT INTO docs "          sql = "INSERT INTO docs "
Line 2011  path_reset(const char *cwd, int fd, const char *base)
Line 2017  path_reset(const char *cwd, int fd, const char *base)
                 return(0);                  return(0);
         }          }
         return(1);          return(1);
   }
   
   static void
   say(const char *dir, const char *file, const char *format, ...)
   {
           va_list          ap;
   
           fprintf(stderr, "%s", dir);
           if ('\0' != *file)
                   fprintf(stderr, "//%s", file);
           fputs(": ", stderr);
   
           va_start(ap, format);
           vfprintf(stderr, format, ap);
           va_end(ap);
   
           fputc('\n', stderr);
 }  }

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.58

CVSweb