version 1.82, 2013/12/27 03:06:17 |
version 1.83, 2013/12/27 14:29:28 |
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(int, const char *, const char *, const char *, |
const char *, const char *, 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); |
Line 184 static int exitcode; /* to be returned by main */ |
|
Line 181 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 320 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 405 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 459 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 477 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); |
} |
} |
} |
} |
} |
} |
|
|
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" |
|
|
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. |
*/ |
*/ |
|
|
continue; |
continue; |
} else |
} else |
sec[-1] = '\0'; |
sec[-1] = '\0'; |
ofadd(dform, path, ff->fts_name, dsec, sec, |
mlink_add(dform, path, ff->fts_name, dsec, sec, |
arch, ff->fts_statp); |
arch, ff->fts_statp); |
continue; |
continue; |
} else if (FTS_D != ff->fts_info && |
} else if (FTS_D != ff->fts_info && |
|
|
* 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 |
Line 761 filescan(const char *file) |
|
Line 758 filescan(const char *file) |
|
*p = '\0'; |
*p = '\0'; |
} |
} |
|
|
ofadd(dform, file, name, dsec, sec, arch, &st); |
mlink_add(dform, file, name, dsec, sec, arch, &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 775 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(int dform, const char *file, const char *name, const char *dsec, |
{ |
|
unsigned int slot; |
|
|
|
mpage->inodev.st_ino = st->st_ino; |
|
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)); |
|
ohash_insert(&mpages, slot, mpage); |
|
} |
|
|
|
static void |
|
ofadd(int dform, const char *file, const char *name, const char *dsec, |
|
const char *sec, const char *arch, const struct stat *st) |
const char *sec, const char *arch, const struct stat *st) |
{ |
{ |
|
struct inodev inodev; |
struct mpage *mpage; |
struct mpage *mpage; |
struct mlink *mlink; |
struct mlink *mlink; |
int sform; |
int sform; |
|
unsigned int slot; |
|
|
assert(NULL != file); |
assert(NULL != file); |
|
|
Line 861 ofadd(int dform, const char *file, const char *name, c |
|
Line 813 ofadd(int dform, const char *file, const char *name, c |
|
mlink->name = mandoc_strdup(name); |
mlink->name = mandoc_strdup(name); |
mlink->fsec = mandoc_strdup(sec); |
mlink->fsec = mandoc_strdup(sec); |
|
|
mpage = mandoc_calloc(1, sizeof(struct mpage)); |
slot = ohash_qlookup(&mlinks, mlink->file); |
mpage->mlinks = mlink; |
assert(NULL == ohash_find(&mlinks, slot)); |
|
ohash_insert(&mlinks, slot, mlink); |
|
|
/* |
inodev.st_ino = st->st_ino; |
* Add to unique identifier hash. |
inodev.st_dev = st->st_dev; |
* Then if it's a source manual and we're going to use source in |
slot = ohash_lookup_memory(&mpages, (char *)&inodev, |
* favour of catpages, add it to that hash. |
sizeof(struct inodev), inodev.st_ino); |
*/ |
mpage = ohash_find(&mpages, slot); |
inoadd(st, mpage); |
if (NULL == mpage) { |
fileadd(mpage->mlinks); |
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; |
} |
} |
|
|
static void |
static void |
Line 967 mpages_merge(struct mchars *mc, struct mparse *mp, int |
|
Line 926 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); |