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

Diff for /mandoc/mandocdb.c between version 1.124 and 1.132

version 1.124, 2014/03/26 21:39:38 version 1.132, 2014/04/09 21:50:08
Line 147  static void *hash_alloc(size_t, void *);
Line 147  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     mlink_add(struct mlink *, const struct stat *);  static  void     mlink_add(struct mlink *, const struct stat *);
 static  int      mlink_check(struct mpage *, struct mlink *);  static  void     mlink_check(struct mpage *, struct mlink *);
 static  void     mlink_free(struct mlink *);  static  void     mlink_free(struct mlink *);
 static  void     mlinks_undupe(struct mpage *);  static  void     mlinks_undupe(struct mpage *);
 static  void     mpages_free(void);  static  void     mpages_free(void);
 static  void     mpages_merge(struct mchars *, struct mparse *);  static  void     mpages_merge(struct mchars *, struct mparse *);
   static  void     names_check(void);
 static  void     parse_cat(struct mpage *, int);  static  void     parse_cat(struct mpage *, int);
 static  void     parse_man(struct mpage *, const struct man_node *);  static  void     parse_man(struct mpage *, const struct man_node *);
 static  void     parse_mdoc(struct mpage *, const struct mdoc_node *);  static  void     parse_mdoc(struct mpage *, const struct mdoc_node *);
Line 179  static char  *progname;
Line 180  static char  *progname;
 static  int              nodb; /* no database changes */  static  int              nodb; /* no database changes */
 static  int              mparse_options; /* abort the parse early */  static  int              mparse_options; /* abort the parse early */
 static  int              use_all; /* use all found files */  static  int              use_all; /* use all found files */
 static  int              verb; /* print what we're doing */  static  int              debug; /* print what we're doing */
 static  int              warnings; /* warn about crap */  static  int              warnings; /* warn about crap */
 static  int              write_utf8; /* write UTF-8 output; else ASCII */  static  int              write_utf8; /* write UTF-8 output; else ASCII */
 static  int              exitcode; /* to be returned by main */  static  int              exitcode; /* to be returned by main */
Line 223  static const struct mdoc_handler mdocs[MDOC_MAX] = {
Line 224  static const struct mdoc_handler mdocs[MDOC_MAX] = {
         { NULL, TYPE_Ic },  /* Ic */          { NULL, TYPE_Ic },  /* Ic */
         { NULL, TYPE_In },  /* In */          { NULL, TYPE_In },  /* In */
         { NULL, TYPE_Li },  /* Li */          { NULL, TYPE_Li },  /* Li */
         { parse_mdoc_Nd, TYPE_Nd },  /* Nd */          { parse_mdoc_Nd, 0 },  /* Nd */
         { parse_mdoc_Nm, TYPE_Nm },  /* Nm */          { parse_mdoc_Nm, 0 },  /* Nm */
         { NULL, 0 },  /* Op */          { NULL, 0 },  /* Op */
         { NULL, 0 },  /* Ot */          { NULL, 0 },  /* Ot */
         { NULL, TYPE_Pa },  /* Pa */          { NULL, TYPE_Pa },  /* Pa */
Line 357  main(int argc, char *argv[])
Line 358  main(int argc, char *argv[])
         path_arg = NULL;          path_arg = NULL;
         op = OP_DEFAULT;          op = OP_DEFAULT;
   
         while (-1 != (ch = getopt(argc, argv, "aC:d:nQT:tu:vW")))          while (-1 != (ch = getopt(argc, argv, "aC:Dd:npQT:tu:v")))
                 switch (ch) {                  switch (ch) {
                 case ('a'):                  case ('a'):
                         use_all = 1;                          use_all = 1;
Line 367  main(int argc, char *argv[])
Line 368  main(int argc, char *argv[])
                         path_arg = optarg;                          path_arg = optarg;
                         op = OP_CONFFILE;                          op = OP_CONFFILE;
                         break;                          break;
                   case ('D'):
                           debug++;
                           break;
                 case ('d'):                  case ('d'):
                         CHECKOP(op, ch);                          CHECKOP(op, ch);
                         path_arg = optarg;                          path_arg = optarg;
Line 375  main(int argc, char *argv[])
Line 379  main(int argc, char *argv[])
                 case ('n'):                  case ('n'):
                         nodb = 1;                          nodb = 1;
                         break;                          break;
                   case ('p'):
                           warnings = 1;
                           break;
                 case ('Q'):                  case ('Q'):
                         mparse_options |= MPARSE_QUICK;                          mparse_options |= MPARSE_QUICK;
                         break;                          break;
Line 398  main(int argc, char *argv[])
Line 405  main(int argc, char *argv[])
                         op = OP_DELETE;                          op = OP_DELETE;
                         break;                          break;
                 case ('v'):                  case ('v'):
                         verb++;                          /* Compatibility with espie@'s makewhatis. */
                         break;                          break;
                 case ('W'):  
                         warnings = 1;  
                         break;  
                 default:                  default:
                         goto usage;                          goto usage;
                 }                  }
Line 459  main(int argc, char *argv[])
Line 463  main(int argc, char *argv[])
                 } else                  } else
                         manpath_parse(&dirs, path_arg, NULL, NULL);                          manpath_parse(&dirs, path_arg, NULL, NULL);
   
                   if (0 == dirs.sz) {
                           exitcode = (int)MANDOCLEVEL_BADARG;
                           say("", "Empty manpath");
                   }
   
                 /*                  /*
                  * First scan the tree rooted at a base directory, then                   * First scan the tree rooted at a base directory, then
                  * build a new database and finally move it into place.                   * build a new database and finally move it into place.
Line 487  main(int argc, char *argv[])
Line 496  main(int argc, char *argv[])
                                 goto out;                                  goto out;
   
                         mpages_merge(mc, mp);                          mpages_merge(mc, mp);
                           if (warnings &&
                               ! (MPARSE_QUICK & mparse_options))
                                   names_check();
                         dbclose(0);                          dbclose(0);
   
                         if (j + 1 < dirs.sz) {                          if (j + 1 < dirs.sz) {
Line 506  out:
Line 518  out:
         ohash_delete(&mlinks);          ohash_delete(&mlinks);
         return(exitcode);          return(exitcode);
 usage:  usage:
         fprintf(stderr, "usage: %s [-anQvW] [-C file] [-Tutf8]\n"          fprintf(stderr, "usage: %s [-aDnpQ] [-C file] [-Tutf8]\n"
                         "       %s [-anQvW] [-Tutf8] dir ...\n"                          "       %s [-aDnpQ] [-Tutf8] dir ...\n"
                         "       %s [-nQvW] [-Tutf8] -d dir [file ...]\n"                          "       %s [-DnpQ] [-Tutf8] -d dir [file ...]\n"
                         "       %s [-nvW] -u dir [file ...]\n"                          "       %s [-Dnp] -u dir [file ...]\n"
                         "       %s [-Q] -t file ...\n",                          "       %s [-Q] -t file ...\n",
                        progname, progname, progname,                         progname, progname, progname,
                        progname, progname);                         progname, progname);
Line 912  nextlink:
Line 924  nextlink:
         }          }
 }  }
   
 static int  static void
 mlink_check(struct mpage *mpage, struct mlink *mlink)  mlink_check(struct mpage *mpage, struct mlink *mlink)
 {  {
         int      match;          struct str      *str;
           unsigned int     slot;
   
         match = 1;  
   
         /*          /*
          * Check whether the manual section given in a file           * Check whether the manual section given in a file
          * agrees with the directory where the file is located.           * agrees with the directory where the file is located.
Line 929  mlink_check(struct mpage *mpage, struct mlink *mlink)
Line 940  mlink_check(struct mpage *mpage, struct mlink *mlink)
          */           */
   
         if (FORM_SRC == mpage->form &&          if (FORM_SRC == mpage->form &&
             strcasecmp(mpage->sec, mlink->dsec)) {              strcasecmp(mpage->sec, mlink->dsec))
                 match = 0;  
                 say(mlink->file, "Section \"%s\" manual in %s directory",                  say(mlink->file, "Section \"%s\" manual in %s directory",
                     mpage->sec, mlink->dsec);                      mpage->sec, mlink->dsec);
         }  
   
         /*          /*
          * Manual page directories exist for each kernel           * Manual page directories exist for each kernel
Line 948  mlink_check(struct mpage *mpage, struct mlink *mlink)
Line 957  mlink_check(struct mpage *mpage, struct mlink *mlink)
          * on amd64, i386, sparc, and sparc64.           * on amd64, i386, sparc, and sparc64.
          */           */
   
         if (strcasecmp(mpage->arch, mlink->arch)) {          if (strcasecmp(mpage->arch, mlink->arch))
                 match = 0;  
                 say(mlink->file, "Architecture \"%s\" manual in "                  say(mlink->file, "Architecture \"%s\" manual in "
                     "\"%s\" directory", mpage->arch, mlink->arch);                      "\"%s\" directory", mpage->arch, mlink->arch);
         }  
   
         if (strcasecmp(mpage->title, mlink->name))          /*
                 match = 0;           * XXX
            * parse_cat() doesn't set TYPE_Nm and TYPE_NAME yet.
            */
   
         return(match);          if (FORM_CAT == mpage->form)
                   return;
   
           /*
            * Check whether this mlink
            * appears as a name in the NAME section.
            */
   
           slot = ohash_qlookup(&strings, mlink->name);
           str = ohash_find(&strings, slot);
           assert(NULL != str);
           if ( ! (TYPE_NAME & str->mask))
                   say(mlink->file, "Name missing in NAME section");
 }  }
   
 /*  /*
Line 980  mpages_merge(struct mchars *mc, struct mparse *mp)
Line 1001  mpages_merge(struct mchars *mc, struct mparse *mp)
         char                    *sodest;          char                    *sodest;
         char                    *cp;          char                    *cp;
         pid_t                    child_pid;          pid_t                    child_pid;
         int                      match, status;          int                      status;
         unsigned int             pslot;          unsigned int             pslot;
         enum mandoclevel         lvl;          enum mandoclevel         lvl;
   
Line 1128  mpages_merge(struct mchars *mc, struct mparse *mp)
Line 1149  mpages_merge(struct mchars *mc, struct mparse *mp)
                         putkey(mpage, mlink->name, TYPE_Nm);                          putkey(mpage, mlink->name, TYPE_Nm);
                 }                  }
   
                 if (warnings && !use_all) {  
                         match = 0;  
                         for (mlink = mpage->mlinks; mlink;  
                              mlink = mlink->next)  
                                 if (mlink_check(mpage, mlink))  
                                         match = 1;  
                 } else  
                         match = 1;  
   
                 if (NULL != mdoc) {                  if (NULL != mdoc) {
                         if (NULL != (cp = mdoc_meta(mdoc)->name))                          if (NULL != (cp = mdoc_meta(mdoc)->name))
                                 putkey(mpage, cp, TYPE_Nm);                                  putkey(mpage, cp, TYPE_Nm);
                         assert(NULL == mpage->desc);                          assert(NULL == mpage->desc);
                         parse_mdoc(mpage, mdoc_node(mdoc));                          parse_mdoc(mpage, mdoc_node(mdoc));
                         putkey(mpage, NULL != mpage->desc ?                          if (NULL == mpage->desc)
                             mpage->desc : mpage->mlinks->name, TYPE_Nd);                                  mpage->desc = mandoc_strdup(
                                       mpage->mlinks->name);
                 } else if (NULL != man)                  } else if (NULL != man)
                         parse_man(mpage, man_node(man));                          parse_man(mpage, man_node(man));
                 else                  else
                         parse_cat(mpage, fd[0]);                          parse_cat(mpage, fd[0]);
   
                   if (warnings && !use_all)
                           for (mlink = mpage->mlinks; mlink;
                                mlink = mlink->next)
                                   mlink_check(mpage, mlink);
   
                 dbadd(mpage, mc);                  dbadd(mpage, mc);
   
 nextpage:  nextpage:
Line 1177  nextpage:
Line 1195  nextpage:
 }  }
   
 static void  static void
   names_check(void)
   {
           sqlite3_stmt    *stmt;
           const char      *name, *sec, *arch, *key;
           size_t           i;
           int              irc;
   
           sqlite3_prepare_v2(db,
             "SELECT name, sec, arch, key FROM ("
               "SELECT key, pageid FROM keys "
               "WHERE bits & ? AND NOT EXISTS ("
                 "SELECT pageid FROM mlinks "
                 "WHERE mlinks.pageid == keys.pageid "
                 "AND mlinks.name == keys.key"
               ")"
             ") JOIN ("
               "SELECT * FROM mlinks GROUP BY pageid"
             ") USING (pageid);",
             -1, &stmt, NULL);
   
           i = 1;
           SQL_BIND_INT64(stmt, i, TYPE_NAME);
   
           while (SQLITE_ROW == (irc = sqlite3_step(stmt))) {
                   name = sqlite3_column_text(stmt, 0);
                   sec  = sqlite3_column_text(stmt, 1);
                   arch = sqlite3_column_text(stmt, 2);
                   key  = sqlite3_column_text(stmt, 3);
                   say("", "%s(%s%s%s) lacks mlink \"%s\"", name, sec,
                       '\0' == *arch ? "" : "/",
                       '\0' == *arch ? "" : arch, key);
           }
           sqlite3_finalize(stmt);
   }
   
   static void
 parse_cat(struct mpage *mpage, int fd)  parse_cat(struct mpage *mpage, int fd)
 {  {
         FILE            *stream;          FILE            *stream;
Line 1245  parse_cat(struct mpage *mpage, int fd)
Line 1299  parse_cat(struct mpage *mpage, int fd)
                             "Cannot find NAME section");                              "Cannot find NAME section");
                 assert(NULL == mpage->desc);                  assert(NULL == mpage->desc);
                 mpage->desc = mandoc_strdup(mpage->mlinks->name);                  mpage->desc = mandoc_strdup(mpage->mlinks->name);
                 putkey(mpage, mpage->mlinks->name, TYPE_Nd);  
                 fclose(stream);                  fclose(stream);
                 free(title);                  free(title);
                 return;                  return;
Line 1286  parse_cat(struct mpage *mpage, int fd)
Line 1339  parse_cat(struct mpage *mpage, int fd)
   
         assert(NULL == mpage->desc);          assert(NULL == mpage->desc);
         mpage->desc = mandoc_strdup(p);          mpage->desc = mandoc_strdup(p);
         putkey(mpage, mpage->desc, TYPE_Nd);  
         fclose(stream);          fclose(stream);
         free(title);          free(title);
 }  }
Line 1389  parse_man(struct mpage *mpage, const struct man_node *
Line 1441  parse_man(struct mpage *mpage, const struct man_node *
                                     ('\\' == start[0] && '-' == start[1]))                                      ('\\' == start[0] && '-' == start[1]))
                                         break;                                          break;
   
                                 putkey(mpage, start, TYPE_Nm);                                  putkey(mpage, start, TYPE_NAME | TYPE_Nm);
   
                                 if (' ' == byte) {                                  if (' ' == byte) {
                                         start += sz + 1;                                          start += sz + 1;
Line 1403  parse_man(struct mpage *mpage, const struct man_node *
Line 1455  parse_man(struct mpage *mpage, const struct man_node *
                         }                          }
   
                         if (start == title) {                          if (start == title) {
                                 putkey(mpage, start, TYPE_Nm);                                  putkey(mpage, start, TYPE_NAME | TYPE_Nm);
                                 free(title);                                  free(title);
                                 return;                                  return;
                         }                          }
Line 1427  parse_man(struct mpage *mpage, const struct man_node *
Line 1479  parse_man(struct mpage *mpage, const struct man_node *
   
                         assert(NULL == mpage->desc);                          assert(NULL == mpage->desc);
                         mpage->desc = mandoc_strdup(start);                          mpage->desc = mandoc_strdup(start);
                         putkey(mpage, mpage->desc, TYPE_Nd);  
                         free(title);                          free(title);
                         return;                          return;
                 }                  }
Line 1580  static int
Line 1631  static int
 parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_node *n)  parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_node *n)
 {  {
   
         return(SEC_NAME == n->sec ||          if (SEC_NAME == n->sec)
             (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type));                  putmdockey(mpage, n->child, TYPE_NAME | TYPE_Nm);
           else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type)
                   putmdockey(mpage, n->child, TYPE_Nm);
           return(0);
 }  }
   
 static int  static int
Line 1623  putkeys(const struct mpage *mpage,
Line 1677  putkeys(const struct mpage *mpage,
         if (0 == sz)          if (0 == sz)
                 return;                  return;
   
         if (verb > 1) {          if (debug > 1) {
                 for (i = 0, mask = 1;                  for (i = 0, mask = 1;
                      i < mansearch_keymax;                       i < mansearch_keymax;
                      i++, mask <<= 1)                       i++, mask <<= 1)
Line 1850  dbadd(struct mpage *mpage, struct mchars *mc)
Line 1904  dbadd(struct mpage *mpage, struct mchars *mc)
         size_t           i;          size_t           i;
         unsigned int     slot;          unsigned int     slot;
   
         if (verb)          mlink = mpage->mlinks;
                 say(mpage->mlinks->file, "Adding to database");  
   
         if (nodb)          if (nodb) {
                   while (NULL != mlink) {
                           fputs(mlink->name, stdout);
                           if (NULL == mlink->next ||
                               strcmp(mlink->dsec, mlink->next->dsec) ||
                               strcmp(mlink->fsec, mlink->next->fsec) ||
                               strcmp(mlink->arch, mlink->next->arch)) {
                                   putchar('(');
                                   if ('\0' == *mlink->dsec)
                                           fputs(mlink->fsec, stdout);
                                   else
                                           fputs(mlink->dsec, stdout);
                                   if ('\0' != *mlink->arch)
                                           printf("/%s", mlink->arch);
                                   putchar(')');
                           }
                           mlink = mlink->next;
                           if (NULL != mlink)
                                   fputs(", ", stdout);
                   }
                   printf(" - %s\n", mpage->desc);
                 return;                  return;
           }
   
           if (debug)
                   say(mlink->file, "Adding to database");
   
         i = 1;          i = 1;
           SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, mpage->desc);
         SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, FORM_SRC == mpage->form);          SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, FORM_SRC == mpage->form);
         SQL_STEP(stmts[STMT_INSERT_PAGE]);          SQL_STEP(stmts[STMT_INSERT_PAGE]);
         mpage->recno = sqlite3_last_insert_rowid(db);          mpage->recno = sqlite3_last_insert_rowid(db);
         sqlite3_reset(stmts[STMT_INSERT_PAGE]);          sqlite3_reset(stmts[STMT_INSERT_PAGE]);
   
         for (mlink = mpage->mlinks; mlink; mlink = mlink->next)          while (NULL != mlink) {
                 dbadd_mlink(mlink);                  dbadd_mlink(mlink);
                   mlink = mlink->next;
           }
   
         for (key = ohash_first(&strings, &slot); NULL != key;          for (key = ohash_first(&strings, &slot); NULL != key;
              key = ohash_next(&strings, &slot)) {               key = ohash_next(&strings, &slot)) {
Line 1896  dbprune(void)
Line 1976  dbprune(void)
         for (mpage = ohash_first(&mpages, &slot); NULL != mpage;          for (mpage = ohash_first(&mpages, &slot); NULL != mpage;
              mpage = ohash_next(&mpages, &slot)) {               mpage = ohash_next(&mpages, &slot)) {
                 mlink = mpage->mlinks;                  mlink = mpage->mlinks;
                 if (verb)                  if (debug)
                         say(mlink->file, "Deleting from database");                          say(mlink->file, "Deleting from database");
                 if (nodb)                  if (nodb)
                         continue;                          continue;
Line 2067  dbopen(int real)
Line 2147  dbopen(int real)
   
 create_tables:  create_tables:
         sql = "CREATE TABLE \"mpages\" (\n"          sql = "CREATE TABLE \"mpages\" (\n"
                 " \"desc\" TEXT NOT NULL,\n"
               " \"form\" INTEGER NOT NULL,\n"                " \"form\" INTEGER NOT NULL,\n"
               " \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n"                " \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n"
               ");\n"                ");\n"
Line 2099  prepare_statements:
Line 2180  prepare_statements:
                 "sec=? AND arch=? AND name=?)";                  "sec=? AND arch=? AND name=?)";
         sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE_PAGE], NULL);          sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE_PAGE], NULL);
         sql = "INSERT INTO mpages "          sql = "INSERT INTO mpages "
                 "(form) VALUES (?)";                  "(desc,form) VALUES (?,?)";
         sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_PAGE], NULL);          sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_PAGE], NULL);
         sql = "INSERT INTO mlinks "          sql = "INSERT INTO mlinks "
                 "(sec,arch,name,pageid) VALUES (?,?,?,?)";                  "(sec,arch,name,pageid) VALUES (?,?,?,?)";

Legend:
Removed from v.1.124  
changed lines
  Added in v.1.132

CVSweb