version 1.230, 2016/09/02 14:03:30 |
version 1.233, 2016/10/20 16:31:00 |
|
|
/* |
/* |
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2011-2016 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2011-2016 Ingo Schwarze <schwarze@openbsd.org> |
|
* Copyright (c) 2016 Ed Maste <emaste@freebsd.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 |
|
|
char *arch; /* architecture from file content */ |
char *arch; /* architecture from file content */ |
char *title; /* title from file content */ |
char *title; /* title from file content */ |
char *desc; /* description from file content */ |
char *desc; /* description from file content */ |
|
struct mpage *next; /* singly linked list */ |
struct mlink *mlinks; /* singly linked list */ |
struct mlink *mlinks; /* singly linked list */ |
int name_head_done; |
int name_head_done; |
enum form form; /* format from file content */ |
enum form form; /* format from file content */ |
Line 118 static void dbadd_mlink(const struct mlink *mlink); |
|
Line 120 static void dbadd_mlink(const struct mlink *mlink); |
|
static void dbprune(struct dba *); |
static void dbprune(struct dba *); |
static void dbwrite(struct dba *); |
static void dbwrite(struct dba *); |
static void filescan(const char *); |
static void filescan(const char *); |
|
#if HAVE_FTS_COMPARE_CONST |
|
static int fts_compare(const FTSENT *const *, const FTSENT *const *); |
|
#else |
|
static int fts_compare(const FTSENT **, const FTSENT **); |
|
#endif |
static void mlink_add(struct mlink *, const struct stat *); |
static void mlink_add(struct mlink *, const struct stat *); |
static void 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 *); |
int mpages_compare(const void *, const void *); |
|
static void mpages_free(void); |
static void mpages_free(void); |
static void mpages_merge(struct dba *, struct mparse *); |
static void mpages_merge(struct dba *, struct mparse *); |
static void parse_cat(struct mpage *, int); |
static void parse_cat(struct mpage *, int); |
Line 169 static int write_utf8; /* write UTF-8 output; else A |
|
Line 175 static int write_utf8; /* write UTF-8 output; else A |
|
static int exitcode; /* to be returned by main */ |
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 mpage *mpage_head; /* list of distinct manual pages */ |
static struct ohash mpages; /* table of distinct manual pages */ |
static struct ohash mpages; /* table of distinct manual pages */ |
static struct ohash mlinks; /* table of directory entries */ |
static struct ohash mlinks; /* table of directory entries */ |
static struct ohash names; /* table of all names */ |
static struct ohash names; /* table of all names */ |
|
|
} |
} |
|
|
/* |
/* |
|
* To get a singly linked list in alpha order while inserting entries |
|
* at the beginning, process directory entries in reverse alpha order. |
|
*/ |
|
static int |
|
#if HAVE_FTS_COMPARE_CONST |
|
fts_compare(const FTSENT *const *a, const FTSENT *const *b) |
|
#else |
|
fts_compare(const FTSENT **a, const FTSENT **b) |
|
#endif |
|
{ |
|
return -strcmp((*a)->fts_name, (*b)->fts_name); |
|
} |
|
|
|
/* |
* Scan a directory tree rooted at "basedir" for manpages. |
* Scan a directory tree rooted at "basedir" for manpages. |
* We use fts(), scanning directory parts along the way for clues to our |
* We use fts(), scanning directory parts along the way for clues to our |
* section and architecture. |
* section and architecture. |
|
|
argv[0] = "."; |
argv[0] = "."; |
argv[1] = (char *)NULL; |
argv[1] = (char *)NULL; |
|
|
f = fts_open((char * const *)argv, |
f = fts_open((char * const *)argv, FTS_PHYSICAL | FTS_NOCHDIR, |
FTS_PHYSICAL | FTS_NOCHDIR, NULL); |
fts_compare); |
if (f == NULL) { |
if (f == NULL) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("", "&fts_open"); |
say("", "&fts_open"); |
Line 936 mlink_add(struct mlink *mlink, const struct stat *st) |
|
Line 957 mlink_add(struct mlink *mlink, const struct stat *st) |
|
mpage->inodev.st_ino = inodev.st_ino; |
mpage->inodev.st_ino = inodev.st_ino; |
mpage->inodev.st_dev = inodev.st_dev; |
mpage->inodev.st_dev = inodev.st_dev; |
mpage->form = FORM_NONE; |
mpage->form = FORM_NONE; |
|
mpage->next = mpage_head; |
|
mpage_head = mpage; |
ohash_insert(&mpages, slot, mpage); |
ohash_insert(&mpages, slot, mpage); |
} else |
} else |
mlink->next = mpage->mlinks; |
mlink->next = mpage->mlinks; |
Line 959 mpages_free(void) |
|
Line 982 mpages_free(void) |
|
{ |
{ |
struct mpage *mpage; |
struct mpage *mpage; |
struct mlink *mlink; |
struct mlink *mlink; |
unsigned int slot; |
|
|
|
mpage = ohash_first(&mpages, &slot); |
while ((mpage = mpage_head) != NULL) { |
while (NULL != mpage) { |
while ((mlink = mpage->mlinks) != NULL) { |
while (NULL != (mlink = mpage->mlinks)) { |
|
mpage->mlinks = mlink->next; |
mpage->mlinks = mlink->next; |
mlink_free(mlink); |
mlink_free(mlink); |
} |
} |
|
mpage_head = mpage->next; |
free(mpage->sec); |
free(mpage->sec); |
free(mpage->arch); |
free(mpage->arch); |
free(mpage->title); |
free(mpage->title); |
free(mpage->desc); |
free(mpage->desc); |
free(mpage); |
free(mpage); |
mpage = ohash_next(&mpages, &slot); |
|
} |
} |
} |
} |
|
|
Line 1086 mlink_check(struct mpage *mpage, struct mlink *mlink) |
|
Line 1107 mlink_check(struct mpage *mpage, struct mlink *mlink) |
|
static void |
static void |
mpages_merge(struct dba *dba, struct mparse *mp) |
mpages_merge(struct dba *dba, struct mparse *mp) |
{ |
{ |
struct mpage **mplist, *mpage, *mpage_dest; |
struct mpage *mpage, *mpage_dest; |
struct mlink *mlink, *mlink_dest; |
struct mlink *mlink, *mlink_dest; |
struct roff_man *man; |
struct roff_man *man; |
char *sodest; |
char *sodest; |
char *cp; |
char *cp; |
int fd; |
int fd; |
unsigned int ip, npages, pslot; |
|
|
|
npages = ohash_entries(&mpages); |
for (mpage = mpage_head; mpage != NULL; mpage = mpage->next) { |
mplist = mandoc_reallocarray(NULL, npages, sizeof(*mplist)); |
|
ip = 0; |
|
mpage = ohash_first(&mpages, &pslot); |
|
while (mpage != NULL) { |
|
mlinks_undupe(mpage); |
mlinks_undupe(mpage); |
if (mpage->mlinks != NULL) |
if ((mlink = mpage->mlinks) == NULL) |
mplist[ip++] = mpage; |
continue; |
mpage = ohash_next(&mpages, &pslot); |
|
} |
|
npages = ip; |
|
qsort(mplist, npages, sizeof(*mplist), mpages_compare); |
|
|
|
for (ip = 0; ip < npages; ip++) { |
|
mpage = mplist[ip]; |
|
mlink = mpage->mlinks; |
|
name_mask = NAME_MASK; |
name_mask = NAME_MASK; |
mandoc_ohash_init(&names, 4, offsetof(struct str, key)); |
mandoc_ohash_init(&names, 4, offsetof(struct str, key)); |
mandoc_ohash_init(&strings, 6, offsetof(struct str, key)); |
mandoc_ohash_init(&strings, 6, offsetof(struct str, key)); |
|
|
ohash_delete(&strings); |
ohash_delete(&strings); |
ohash_delete(&names); |
ohash_delete(&names); |
} |
} |
free(mplist); |
|
} |
} |
|
|
int |
|
mpages_compare(const void *vp1, const void *vp2) |
|
{ |
|
const struct mpage *mp1, *mp2; |
|
|
|
mp1 = *(const struct mpage **)vp1; |
|
mp2 = *(const struct mpage **)vp2; |
|
return strcmp(mp1->mlinks->file, mp2->mlinks->file); |
|
} |
|
|
|
static void |
static void |
parse_cat(struct mpage *mpage, int fd) |
parse_cat(struct mpage *mpage, int fd) |
{ |
{ |
Line 1741 putkeys(const struct mpage *mpage, char *cp, size_t sz |
|
Line 1739 putkeys(const struct mpage *mpage, char *cp, size_t sz |
|
name_mask &= ~NAME_FIRST; |
name_mask &= ~NAME_FIRST; |
if (debug > 1) |
if (debug > 1) |
say(mpage->mlinks->file, |
say(mpage->mlinks->file, |
"Adding name %*s, bits=0x%llu", (int)sz, cp, v); |
"Adding name %*s, bits=0x%llx", (int)sz, cp, v); |
} else { |
} else { |
htab = &strings; |
htab = &strings; |
if (debug > 1) |
if (debug > 1) |