version 1.236, 2017/01/10 23:36:34 |
version 1.246, 2017/04/24 23:06:18 |
Line 162 static void putmdockey(const struct mpage *, |
|
Line 162 static void putmdockey(const struct mpage *, |
|
const struct roff_node *, uint64_t, int); |
const struct roff_node *, uint64_t, int); |
static int render_string(char **, size_t *); |
static int render_string(char **, size_t *); |
static void say(const char *, const char *, ...) |
static void say(const char *, const char *, ...) |
__attribute__((__format__ (printf, 2, 3))); |
__attribute__((__format__ (__printf__, 2, 3))); |
static int set_basedir(const char *, int); |
static int set_basedir(const char *, int); |
static int treescan(void); |
static int treescan(void); |
static size_t utf8(unsigned int, char [7]); |
static size_t utf8(unsigned int, char [7]); |
Line 183 static struct ohash names; /* table of all names */ |
|
Line 183 static struct ohash names; /* table of all names */ |
|
static struct ohash strings; /* table of all strings */ |
static struct ohash strings; /* table of all strings */ |
static uint64_t name_mask; |
static uint64_t name_mask; |
|
|
static const struct mdoc_handler mdocs[MDOC_MAX] = { |
static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = { |
{ NULL, 0, 0 }, /* Ap */ |
|
{ NULL, 0, NODE_NOPRT }, /* Dd */ |
{ NULL, 0, NODE_NOPRT }, /* Dd */ |
{ NULL, 0, NODE_NOPRT }, /* Dt */ |
{ NULL, 0, NODE_NOPRT }, /* Dt */ |
{ NULL, 0, NODE_NOPRT }, /* Os */ |
{ NULL, 0, NODE_NOPRT }, /* Os */ |
Line 200 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
Line 199 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
{ NULL, 0, 0 }, /* It */ |
{ NULL, 0, 0 }, /* It */ |
{ NULL, 0, 0 }, /* Ad */ |
{ NULL, 0, 0 }, /* Ad */ |
{ NULL, TYPE_An, 0 }, /* An */ |
{ NULL, TYPE_An, 0 }, /* An */ |
|
{ NULL, 0, 0 }, /* Ap */ |
{ NULL, TYPE_Ar, 0 }, /* Ar */ |
{ NULL, TYPE_Ar, 0 }, /* Ar */ |
{ NULL, TYPE_Cd, 0 }, /* Cd */ |
{ NULL, TYPE_Cd, 0 }, /* Cd */ |
{ NULL, TYPE_Cm, 0 }, /* Cm */ |
{ NULL, TYPE_Cm, 0 }, /* Cm */ |
Line 239 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
Line 239 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
{ NULL, 0, 0 }, /* Ac */ |
{ NULL, 0, 0 }, /* Ac */ |
{ NULL, 0, 0 }, /* Ao */ |
{ NULL, 0, 0 }, /* Ao */ |
{ NULL, 0, 0 }, /* Aq */ |
{ NULL, 0, 0 }, /* Aq */ |
{ NULL, TYPE_At, NODE_NOSRC }, /* At */ |
{ NULL, TYPE_At, 0 }, /* At */ |
{ NULL, 0, 0 }, /* Bc */ |
{ NULL, 0, 0 }, /* Bc */ |
{ NULL, 0, 0 }, /* Bf */ |
{ NULL, 0, 0 }, /* Bf */ |
{ NULL, 0, 0 }, /* Bo */ |
{ NULL, 0, 0 }, /* Bo */ |
Line 290 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
Line 290 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
{ NULL, 0, 0 }, /* Hf */ |
{ NULL, 0, 0 }, /* Hf */ |
{ NULL, 0, 0 }, /* Fr */ |
{ NULL, 0, 0 }, /* Fr */ |
{ NULL, 0, 0 }, /* Ud */ |
{ NULL, 0, 0 }, /* Ud */ |
{ NULL, TYPE_Lb, 0 }, /* Lb */ |
{ NULL, TYPE_Lb, NODE_NOSRC }, /* Lb */ |
{ NULL, 0, 0 }, /* Lp */ |
{ NULL, 0, 0 }, /* Lp */ |
{ NULL, TYPE_Lk, 0 }, /* Lk */ |
{ NULL, TYPE_Lk, 0 }, /* Lk */ |
{ NULL, TYPE_Mt, NODE_NOSRC }, /* Mt */ |
{ NULL, TYPE_Mt, NODE_NOSRC }, /* Mt */ |
Line 308 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
Line 308 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
{ NULL, 0, 0 }, /* Ta */ |
{ NULL, 0, 0 }, /* Ta */ |
{ NULL, 0, 0 }, /* ll */ |
{ NULL, 0, 0 }, /* ll */ |
}; |
}; |
|
static const struct mdoc_handler *const mdocs = __mdocs - MDOC_Dd; |
|
|
|
|
int |
int |
|
|
const char *argv[2]; |
const char *argv[2]; |
|
|
argv[0] = "."; |
argv[0] = "."; |
argv[1] = (char *)NULL; |
argv[1] = NULL; |
|
|
f = fts_open((char * const *)argv, FTS_PHYSICAL | FTS_NOCHDIR, |
f = fts_open((char * const *)argv, FTS_PHYSICAL | FTS_NOCHDIR, |
fts_compare); |
fts_compare); |
Line 872 filescan(const char *file) |
|
Line 873 filescan(const char *file) |
|
} |
} |
|
|
/* |
/* |
|
* In test mode or when the original name is absolute |
|
* but outside our tree, guess the base directory. |
|
*/ |
|
|
|
if (op == OP_TEST || (start == buf && *start == '/')) { |
|
if (strncmp(buf, "man/", 4) == 0) |
|
start = buf + 4; |
|
else if ((start = strstr(buf, "/man/")) != NULL) |
|
start += 5; |
|
else |
|
start = buf; |
|
} |
|
|
|
/* |
* First try to guess our directory structure. |
* First try to guess our directory structure. |
* If we find a separator, try to look for man* or cat*. |
* If we find a separator, try to look for man* or cat*. |
* If we find one of these and what's underneath is a directory, |
* If we find one of these and what's underneath is a directory, |
Line 1139 mpages_merge(struct dba *dba, struct mparse *mp) |
|
Line 1154 mpages_merge(struct dba *dba, struct mparse *mp) |
|
if (mlink->dform != FORM_CAT || mlink->fform != FORM_CAT) { |
if (mlink->dform != FORM_CAT || mlink->fform != FORM_CAT) { |
mparse_readfd(mp, fd, mlink->file); |
mparse_readfd(mp, fd, mlink->file); |
close(fd); |
close(fd); |
|
fd = -1; |
mparse_result(mp, &man, &sodest); |
mparse_result(mp, &man, &sodest); |
} |
} |
|
|
Line 1195 mpages_merge(struct dba *dba, struct mparse *mp) |
|
Line 1211 mpages_merge(struct dba *dba, struct mparse *mp) |
|
mpage->title = mandoc_strdup(man->meta.title); |
mpage->title = mandoc_strdup(man->meta.title); |
} else if (man != NULL && man->macroset == MACROSET_MAN) { |
} else if (man != NULL && man->macroset == MACROSET_MAN) { |
man_validate(man); |
man_validate(man); |
mpage->form = FORM_SRC; |
if (*man->meta.msec != '\0' || |
mpage->sec = mandoc_strdup(man->meta.msec); |
*man->meta.title != '\0') { |
mpage->arch = mandoc_strdup(mlink->arch); |
mpage->form = FORM_SRC; |
mpage->title = mandoc_strdup(man->meta.title); |
mpage->sec = mandoc_strdup(man->meta.msec); |
} else { |
mpage->arch = mandoc_strdup(mlink->arch); |
|
mpage->title = mandoc_strdup(man->meta.title); |
|
} else |
|
man = NULL; |
|
} |
|
|
|
assert(mpage->desc == NULL); |
|
if (man == NULL) { |
mpage->form = FORM_CAT; |
mpage->form = FORM_CAT; |
mpage->sec = mandoc_strdup(mlink->dsec); |
mpage->sec = mandoc_strdup(mlink->dsec); |
mpage->arch = mandoc_strdup(mlink->arch); |
mpage->arch = mandoc_strdup(mlink->arch); |
mpage->title = mandoc_strdup(mlink->name); |
mpage->title = mandoc_strdup(mlink->name); |
} |
parse_cat(mpage, fd); |
|
} else if (man->macroset == MACROSET_MDOC) |
assert(mpage->desc == NULL); |
|
if (man != NULL && man->macroset == MACROSET_MDOC) |
|
parse_mdoc(mpage, &man->meta, man->first); |
parse_mdoc(mpage, &man->meta, man->first); |
else if (man != NULL) |
|
parse_man(mpage, &man->meta, man->first); |
|
else |
else |
parse_cat(mpage, fd); |
parse_man(mpage, &man->meta, man->first); |
if (mpage->desc == NULL) |
if (mpage->desc == NULL) { |
mpage->desc = mandoc_strdup(mpage->mlinks->name); |
mpage->desc = mandoc_strdup(mlink->name); |
|
if (warnings) |
|
say(mlink->file, "No one-line description, " |
|
"using filename \"%s\"", mlink->name); |
|
} |
|
|
if (warnings && !use_all) |
for (mlink = mpage->mlinks; |
for (mlink = mpage->mlinks; mlink; |
mlink != NULL; |
mlink = mlink->next) |
mlink = mlink->next) { |
|
putkey(mpage, mlink->name, NAME_FILE); |
|
if (warnings && !use_all) |
mlink_check(mpage, mlink); |
mlink_check(mpage, mlink); |
|
} |
|
|
dbadd(dba, mpage); |
dbadd(dba, mpage); |
mlink = mpage->mlinks; |
|
|
|
nextpage: |
nextpage: |
ohash_delete(&strings); |
ohash_delete(&strings); |
|
|
parse_cat(struct mpage *mpage, int fd) |
parse_cat(struct mpage *mpage, int fd) |
{ |
{ |
FILE *stream; |
FILE *stream; |
char *line, *p, *title; |
struct mlink *mlink; |
|
char *line, *p, *title, *sec; |
size_t linesz, plen, titlesz; |
size_t linesz, plen, titlesz; |
ssize_t len; |
ssize_t len; |
int offs; |
int offs; |
|
|
stream = (-1 == fd) ? |
mlink = mpage->mlinks; |
fopen(mpage->mlinks->file, "r") : |
stream = fd == -1 ? fopen(mlink->file, "r") : fdopen(fd, "r"); |
fdopen(fd, "r"); |
if (stream == NULL) { |
if (NULL == stream) { |
if (fd != -1) |
if (-1 != fd) |
|
close(fd); |
close(fd); |
if (warnings) |
if (warnings) |
say(mpage->mlinks->file, "&fopen"); |
say(mlink->file, "&fopen"); |
return; |
return; |
} |
} |
|
|
line = NULL; |
line = NULL; |
linesz = 0; |
linesz = 0; |
|
|
/* Skip to first blank line. */ |
/* Parse the section number from the header line. */ |
|
|
while (getline(&line, &linesz, stream) != -1) |
while (getline(&line, &linesz, stream) != -1) { |
if (*line == '\n') |
if (*line == '\n') |
|
continue; |
|
if ((sec = strchr(line, '(')) == NULL) |
break; |
break; |
|
if ((p = strchr(++sec, ')')) == NULL) |
|
break; |
|
free(mpage->sec); |
|
mpage->sec = mandoc_strndup(sec, p - sec); |
|
if (warnings && *mlink->dsec != '\0' && |
|
strcasecmp(mpage->sec, mlink->dsec)) |
|
say(mlink->file, |
|
"Section \"%s\" manual in %s directory", |
|
mpage->sec, mlink->dsec); |
|
break; |
|
} |
|
|
|
/* Skip to first blank line. */ |
|
|
|
while (line == NULL || *line != '\n') |
|
if (getline(&line, &linesz, stream) == -1) |
|
break; |
|
|
/* |
/* |
* Assume the first line that is not indented |
* Assume the first line that is not indented |
* is the first section header. Skip to it. |
* is the first section header. Skip to it. |
Line 1302 parse_cat(struct mpage *mpage, int fd) |
|
Line 1346 parse_cat(struct mpage *mpage, int fd) |
|
|
|
if (NULL == title || '\0' == *title) { |
if (NULL == title || '\0' == *title) { |
if (warnings) |
if (warnings) |
say(mpage->mlinks->file, |
say(mlink->file, "Cannot find NAME section"); |
"Cannot find NAME section"); |
|
fclose(stream); |
fclose(stream); |
free(title); |
free(title); |
return; |
return; |
Line 1322 parse_cat(struct mpage *mpage, int fd) |
|
Line 1365 parse_cat(struct mpage *mpage, int fd) |
|
/* Skip to next word. */ ; |
/* Skip to next word. */ ; |
} else { |
} else { |
if (warnings) |
if (warnings) |
say(mpage->mlinks->file, |
say(mlink->file, "No dash in title line, " |
"No dash in title line"); |
"reusing \"%s\" as one-line description", title); |
p = title; |
p = title; |
} |
} |
|
|
Line 1503 parse_mdoc(struct mpage *mpage, const struct roff_meta |
|
Line 1546 parse_mdoc(struct mpage *mpage, const struct roff_meta |
|
const struct roff_node *n) |
const struct roff_node *n) |
{ |
{ |
|
|
assert(NULL != n); |
for (n = n->child; n != NULL; n = n->next) { |
for (n = n->child; NULL != n; n = n->next) { |
if (n->tok == TOKEN_NONE || n->flags & mdocs[n->tok].taboo) |
if (n->flags & mdocs[n->tok].taboo) |
|
continue; |
continue; |
switch (n->type) { |
switch (n->type) { |
case ROFFT_ELEM: |
case ROFFT_ELEM: |
Line 1513 parse_mdoc(struct mpage *mpage, const struct roff_meta |
|
Line 1555 parse_mdoc(struct mpage *mpage, const struct roff_meta |
|
case ROFFT_HEAD: |
case ROFFT_HEAD: |
case ROFFT_BODY: |
case ROFFT_BODY: |
case ROFFT_TAIL: |
case ROFFT_TAIL: |
if (NULL != mdocs[n->tok].fp) |
if (mdocs[n->tok].fp != NULL && |
if (0 == (*mdocs[n->tok].fp)(mpage, meta, n)) |
(*mdocs[n->tok].fp)(mpage, meta, n) == 0) |
break; |
break; |
if (mdocs[n->tok].mask) |
if (mdocs[n->tok].mask) |
putmdockey(mpage, n->child, |
putmdockey(mpage, n->child, |
mdocs[n->tok].mask, mdocs[n->tok].taboo); |
mdocs[n->tok].mask, mdocs[n->tok].taboo); |
break; |
break; |
default: |
default: |
assert(n->type != ROFFT_ROOT); |
|
continue; |
continue; |
} |
} |
if (NULL != n->child) |
if (NULL != n->child) |