=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.86 retrieving revision 1.90 diff -u -p -r1.86 -r1.90 --- mandoc/mandocdb.c 2013/12/27 16:17:32 1.86 +++ mandoc/mandocdb.c 2013/12/27 23:41:55 1.90 @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.86 2013/12/27 16:17:32 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.90 2013/12/27 23:41:55 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013 Ingo Schwarze @@ -144,6 +144,7 @@ static void hash_free(void *, size_t, void *); static void *hash_halloc(size_t, void *); static void mlink_add(struct mlink *, const struct stat *); static void mlink_free(struct mlink *); +static void mlinks_undupe(struct mpage *); static void mpages_free(void); static void mpages_merge(struct mchars *, struct mparse *, int); static void parse_cat(struct mpage *); @@ -548,7 +549,6 @@ treescan(void) /* * If we're a regular file, add an mlink by using the * stored directory data and handling the filename. - * Disallow duplicate (hard-linked) files. */ if (FTS_F == ff->fts_info) { if (0 == strcmp(path, MANDOC_DB)) @@ -663,7 +663,7 @@ treescan(void) } /* - * Add a file to the file vector. + * Add a file to the mlinks table. * Do not verify that it's a "valid" looking manpage (we'll do that * later). * @@ -674,7 +674,6 @@ treescan(void) * or * [./]cat
[/]/.0 * - * Stuff this information directly into the mlink vector. * See treescan() for the fts(3) version of this. */ static void @@ -842,6 +841,53 @@ mpages_free(void) } /* + * For each mlink to the mpage, check whether the path looks like + * it is formatted, and if it does, check whether a source manual + * exists by the same name, ignoring the suffix. + * If both conditions hold, drop the mlink. + */ +static void +mlinks_undupe(struct mpage *mpage) +{ + char buf[PATH_MAX]; + struct mlink **prev; + struct mlink *mlink; + char *bufp; + + mpage->form = FORM_CAT; + prev = &mpage->mlinks; + while (NULL != (mlink = *prev)) { + if (FORM_CAT != mlink->dform) { + mpage->form = FORM_NONE; + goto nextlink; + } + if (strlcpy(buf, mlink->file, PATH_MAX) >= PATH_MAX) { + if (warnings) + say(mlink->file, "Filename too long"); + goto nextlink; + } + bufp = strstr(buf, "cat"); + assert(NULL != bufp); + memcpy(bufp, "man", 3); + if (NULL != (bufp = strrchr(buf, '.'))) + *++bufp = '\0'; + strlcat(buf, mlink->dsec, PATH_MAX); + if (NULL == ohash_find(&mlinks, + ohash_qlookup(&mlinks, buf))) + goto nextlink; + if (warnings) + say(mlink->file, "Man source exists: %s", buf); + if (use_all) + goto nextlink; + *prev = mlink->next; + mlink_free(mlink); + continue; +nextlink: + prev = &(*prev)->next; + } +} + +/* * Run through the files in the global vector "mpages" * and add them to the database specified in "basedir". * @@ -853,14 +899,12 @@ mpages_merge(struct mchars *mc, struct mparse *mp, int { struct ohash title_table; struct ohash_info title_info, str_info; - char buf[PATH_MAX]; struct mpage *mpage; struct mdoc *mdoc; struct man *man; struct title *title_entry; - char *bufp, *title_str; + char *title_str; const char *cp; - size_t sz; int match; unsigned int pslot, tslot; enum mandoclevel lvl; @@ -880,36 +924,10 @@ mpages_merge(struct mchars *mc, struct mparse *mp, int mpage = ohash_first(&mpages, &pslot); while (NULL != mpage) { - /* - * If we're a catpage (as defined by our path), then see - * if a manpage exists by the same name (ignoring the - * suffix). - * If it does, then we want to use it instead of our - * own. - */ - if ( ! use_all && FORM_CAT == mpage->mlinks->dform) { - sz = strlcpy(buf, mpage->mlinks->file, PATH_MAX); - if (sz >= PATH_MAX) { - if (warnings) - say(mpage->mlinks->file, - "Filename too long"); - mpage = ohash_next(&mpages, &pslot); - continue; - } - bufp = strstr(buf, "cat"); - assert(NULL != bufp); - memcpy(bufp, "man", 3); - if (NULL != (bufp = strrchr(buf, '.'))) - *++bufp = '\0'; - strlcat(buf, mpage->mlinks->dsec, PATH_MAX); - if (NULL != ohash_find(&mlinks, - ohash_qlookup(&mlinks, buf))) { - if (warnings) - say(mpage->mlinks->file, "Man " - "source exists: %s", buf); - mpage = ohash_next(&mpages, &pslot); - continue; - } + mlinks_undupe(mpage); + if (NULL == mpage->mlinks) { + mpage = ohash_next(&mpages, &pslot); + continue; } ohash_init(&strings, 6, &str_info); @@ -1764,6 +1782,7 @@ utf8key(struct mchars *mc, struct str *key) static void dbindex(const struct mpage *mpage, struct mchars *mc) { + struct mlink *mlink; struct str *key; const char *desc; int64_t recno; @@ -1803,13 +1822,16 @@ dbindex(const struct mpage *mpage, struct mchars *mc) recno = sqlite3_last_insert_rowid(db); sqlite3_reset(stmts[STMT_INSERT_PAGE]); - i = 1; - SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mpage->mlinks->dsec); - SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mpage->mlinks->arch); - SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mpage->mlinks->file); - SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, recno); - SQL_STEP(stmts[STMT_INSERT_LINK]); - sqlite3_reset(stmts[STMT_INSERT_LINK]); + for (mlink = mpage->mlinks; mlink; mlink = mlink->next) { + i = 1; + SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->file); + SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->dsec); + SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->arch); + SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->name); + SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, recno); + SQL_STEP(stmts[STMT_INSERT_LINK]); + sqlite3_reset(stmts[STMT_INSERT_LINK]); + } for (key = ohash_first(&strings, &slot); NULL != key; key = ohash_next(&strings, &slot)) { @@ -1945,6 +1967,7 @@ dbopen(int real) ");\n" "\n" "CREATE TABLE \"mlinks\" (\n" + " \"file\" TEXT NOT NULL,\n" " \"sec\" TEXT NOT NULL,\n" " \"arch\" TEXT NOT NULL,\n" " \"name\" TEXT NOT NULL,\n" @@ -1977,7 +2000,7 @@ prepare_statements: "(file,sec,arch,desc,form) VALUES (?,?,?,?,?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_PAGE], NULL); sql = "INSERT INTO mlinks " - "(sec,arch,name,pageid) VALUES (?,?,?,?)"; + "(file,sec,arch,name,pageid) VALUES (?,?,?,?,?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_LINK], NULL); sql = "INSERT INTO keys " "(bits,key,pageid) VALUES (?,?,?)";