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

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

version 1.51, 2012/06/08 12:05:27 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>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   
   #ifdef HAVE_OHASH
 #include <ohash.h>  #include <ohash.h>
   #else
   #include "compat_ohash.h"
   #endif
 #include <sqlite3.h>  #include <sqlite3.h>
   
 #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 SQL_EXEC(_v) \
 #define WARNING(_f, _b, _fmt, _args...) \          if (SQLITE_OK != sqlite3_exec(db, (_v), NULL, NULL, NULL)) \
         do if (warnings) { \                  fprintf(stderr, "%s\n", sqlite3_errmsg(db))
                 fprintf(stderr, "%s: ", (_b)); \  #define SQL_BIND_TEXT(_s, _i, _v) \
                 fprintf(stderr, (_fmt), ##_args); \          if (SQLITE_OK != sqlite3_bind_text \
                 if ('\0' != *(_f)) \                  ((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \
                         fprintf(stderr, ": %s", (_f)); \                  fprintf(stderr, "%s\n", sqlite3_errmsg(db))
                 fprintf(stderr, "\n"); \  #define SQL_BIND_INT(_s, _i, _v) \
         } while (/* CONSTCOND */ 0)          if (SQLITE_OK != sqlite3_bind_int \
 /* Post a "verbose" message to stderr. */                  ((_s), (_i)++, (_v))) \
 #define DEBUG(_f, _b, _fmt, _args...) \                  fprintf(stderr, "%s\n", sqlite3_errmsg(db))
         do if (verb) { \  #define SQL_BIND_INT64(_s, _i, _v) \
                 fprintf(stderr, "%s: ", (_b)); \          if (SQLITE_OK != sqlite3_bind_int64 \
                 fprintf(stderr, (_fmt), ##_args); \                  ((_s), (_i)++, (_v))) \
                 fprintf(stderr, ": %s\n", (_f)); \                  fprintf(stderr, "%s\n", sqlite3_errmsg(db))
         } while (/* CONSTCOND */ 0)  #define SQL_STEP(_s) \
           if (SQLITE_DONE != sqlite3_step((_s))) \
                   fprintf(stderr, "%s\n", sqlite3_errmsg(db))
   
 enum    op {  enum    op {
         OP_DEFAULT = 0, /* new dbs from dir list or default config */          OP_DEFAULT = 0, /* new dbs from dir list or default config */
Line 92  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 156  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 306  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;
         size_t            j, sz;          size_t            j, sz;
         const char       *dir;          const char       *dir;
         struct str       *s;          struct str       *s;
Line 342  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 479  main(int argc, char *argv[])
Line 487  main(int argc, char *argv[])
                                 goto out;                                  goto out;
                         if (0 == dbopen(dirs.paths[j], 0))                          if (0 == dbopen(dirs.paths[j], 0))
                                 goto out;                                  goto out;
   
                           /*
                            * Since we're opening up a new database, we can
                            * turn off synchronous mode for much better
                            * performance.
                            */
   #ifndef __APPLE__
                           SQL_EXEC("PRAGMA synchronous = OFF");
   #endif
   
                         if (0 == ofmerge(mc, mp, dirs.paths[j]))                          if (0 == ofmerge(mc, mp, dirs.paths[j]))
                                 goto out;                                  goto out;
                         dbclose(dirs.paths[j], 0);                          dbclose(dirs.paths[j], 0);
Line 494  out:
Line 512  out:
         manpath_free(&dirs);          manpath_free(&dirs);
         mchars_free(mc);          mchars_free(mc);
         mparse_free(mp);          mparse_free(mp);
         for (s = ohash_first(&strings, &ch);          for (s = ohash_first(&strings, &index);
                         NULL != s; s = ohash_next(&strings, &ch)) {                          NULL != s; s = ohash_next(&strings, &index)) {
                 if (s->utf8 != s->key)                  if (s->utf8 != s->key)
                         free(s->utf8);                          free(s->utf8);
                 free(s);                  free(s);
Line 566  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 633  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 648  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 687  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 846  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 890  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 905  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 916  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 972  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 991  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 1021  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 1073  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 1092  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 1768  dbindex(struct mchars *mc, int form, 
Line 1804  dbindex(struct mchars *mc, int form, 
         struct str      *key;          struct str      *key;
         const char      *desc;          const char      *desc;
         int64_t          recno;          int64_t          recno;
           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 1783  dbindex(struct mchars *mc, int form, 
Line 1821  dbindex(struct mchars *mc, int form, 
                 desc = key->utf8;                  desc = key->utf8;
         }          }
   
         sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);          SQL_EXEC("BEGIN TRANSACTION");
   
         sqlite3_bind_text          i = 1;
                 (stmts[STMT_INSERT_DOC], 1,          SQL_BIND_TEXT(stmts[STMT_INSERT_DOC], i, of->file);
                  of->file, -1, SQLITE_STATIC);          SQL_BIND_TEXT(stmts[STMT_INSERT_DOC], i, of->sec);
         sqlite3_bind_text          SQL_BIND_TEXT(stmts[STMT_INSERT_DOC], i, of->arch);
                 (stmts[STMT_INSERT_DOC], 2,          SQL_BIND_TEXT(stmts[STMT_INSERT_DOC], i, desc);
                  of->sec, -1, SQLITE_STATIC);          SQL_BIND_INT(stmts[STMT_INSERT_DOC], i, form);
         sqlite3_bind_text          SQL_STEP(stmts[STMT_INSERT_DOC]);
                 (stmts[STMT_INSERT_DOC], 3,  
                  of->arch, -1, SQLITE_STATIC);  
         sqlite3_bind_text  
                 (stmts[STMT_INSERT_DOC], 4,  
                  desc, -1, SQLITE_STATIC);  
         sqlite3_bind_int  
                 (stmts[STMT_INSERT_DOC], 5, form);  
         sqlite3_step(stmts[STMT_INSERT_DOC]);  
         recno = sqlite3_last_insert_rowid(db);          recno = sqlite3_last_insert_rowid(db);
         sqlite3_reset(stmts[STMT_INSERT_DOC]);          sqlite3_reset(stmts[STMT_INSERT_DOC]);
   
Line 1807  dbindex(struct mchars *mc, int form, 
Line 1837  dbindex(struct mchars *mc, int form, 
                 assert(key->of == of);                  assert(key->of == of);
                 if (NULL == key->utf8)                  if (NULL == key->utf8)
                         utf8key(mc, key);                          utf8key(mc, key);
                 sqlite3_bind_int64                  i = 1;
                         (stmts[STMT_INSERT_KEY], 1, key->mask);                  SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask);
                 sqlite3_bind_text                  SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->utf8);
                         (stmts[STMT_INSERT_KEY], 2,                  SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, recno);
                          key->utf8, -1, SQLITE_STATIC);                  SQL_STEP(stmts[STMT_INSERT_KEY]);
                 sqlite3_bind_int64  
                         (stmts[STMT_INSERT_KEY], 3, recno);  
                 sqlite3_step(stmts[STMT_INSERT_KEY]);  
                 sqlite3_reset(stmts[STMT_INSERT_KEY]);                  sqlite3_reset(stmts[STMT_INSERT_KEY]);
         }          }
   
         sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL);          SQL_EXEC("END TRANSACTION");
   
 }  }
   
 static void  static void
 dbprune(const char *base)  dbprune(const char *base)
 {  {
         struct of       *of;          struct of       *of;
           size_t           i;
   
         if (nodb)          if (nodb)
                 return;                  return;
   
         for (of = ofs; NULL != of; of = of->next) {          for (of = ofs; NULL != of; of = of->next) {
                 sqlite3_bind_text                  i = 1;
                         (stmts[STMT_DELETE], 1,                  SQL_BIND_TEXT(stmts[STMT_DELETE], i, of->file);
                          of->file, -1, SQLITE_STATIC);                  SQL_STEP(stmts[STMT_DELETE]);
                 sqlite3_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 1848  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 1864  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 1881  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 1889  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 1901  dbopen(const char *base, int real)
Line 1928  dbopen(const char *base, int real)
         if ( ! real)          if ( ! real)
                 remove(file);                  remove(file);
   
         ofl = SQLITE_OPEN_PRIVATECACHE | SQLITE_OPEN_READWRITE |          ofl = SQLITE_OPEN_READWRITE |
                 (0 == real ? SQLITE_OPEN_EXCLUSIVE : 0);                  (0 == real ? SQLITE_OPEN_EXCLUSIVE : 0);
   
         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 1944  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 1988  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.51  
changed lines
  Added in v.1.58

CVSweb