From: schwarze@mandoc.bsd.lv
To: source@mandoc.bsd.lv
Subject: mandoc: In the fallback code to look for manual pages without using
Date: Sat, 4 Sep 2021 07:53:27 -0500 (EST) [thread overview]
Message-ID: <c2aab0f69a22ffba@mandoc.bsd.lv> (raw)
Log Message:
-----------
In the fallback code to look for manual pages without using mandoc.db(5),
accept files "man<one-digit-section>/<name>.<full-section>"
in addition to the already supported "man<full-section>/name.[01-9]*".
Needed for example on Alpine Linux which puts its Perl manuals
into "man3/<name>.3pm" and the POSIX manuals into "man3/<name>.3p".
While here, allow the glob(3) at the end of fs_lookup() to add multiple
matches to the result set. This improves man -w output and may also
help some cases of plain man(1), allowing main() to prioritize properly
rather than fs_lookup() picking a random match.
Issue reported and patch tested
by Soeren Tempel <soeren at soeren hyphen tempel dot net>.
Modified Files:
--------------
mandoc:
main.c
Revision Data
-------------
Index: main.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/main.c,v
retrieving revision 1.356
retrieving revision 1.357
diff -Lmain.c -Lmain.c -u -p -r1.356 -r1.357
--- main.c
+++ main.c
@@ -94,9 +94,11 @@ struct outstate {
int mandocdb(int, char *[]);
static void check_xr(struct manpaths *);
-static int fs_lookup(const struct manpaths *,
- size_t ipath, const char *,
- const char *, const char *,
+static void fs_append(char **, size_t, int,
+ size_t, const char *, enum form,
+ struct manpage **, size_t *);
+static int fs_lookup(const struct manpaths *, size_t,
+ const char *, const char *, const char *,
struct manpage **, size_t *);
static int fs_search(const struct mansearch *,
const struct manpaths *, const char *,
@@ -700,6 +702,30 @@ glob_esc(char **dst, const char *src, co
*(*dst)++ = *suffix++;
}
+static void
+fs_append(char **file, size_t filesz, int copy, size_t ipath,
+ const char *sec, enum form form, struct manpage **res, size_t *ressz)
+{
+ struct manpage *page;
+
+ *res = mandoc_reallocarray(*res, *ressz + filesz, sizeof(**res));
+ page = *res + *ressz;
+ *ressz += filesz;
+ for (;;) {
+ page->file = copy ? mandoc_strdup(*file) : *file;
+ page->names = NULL;
+ page->output = NULL;
+ page->bits = NAME_FILE & NAME_MASK;
+ page->ipath = ipath;
+ page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
+ page->form = form;
+ if (--filesz == 0)
+ break;
+ file++;
+ page++;
+ }
+}
+
static int
fs_lookup(const struct manpaths *paths, size_t ipath,
const char *sec, const char *arch, const char *name,
@@ -707,16 +733,19 @@ fs_lookup(const struct manpaths *paths,
{
struct stat sb;
glob_t globinfo;
- struct manpage *page;
- char *file, *cp;
+ char *file, *cp, secnum[2];
int globres;
enum form form;
const char *const slman = "/man";
const char *const slash = "/";
const char *const sglob = ".[01-9]*";
+ const char *const dot = ".";
+ const char *const aster = "*";
+ memset(&globinfo, 0, sizeof(globinfo));
form = FORM_SRC;
+
mandoc_asprintf(&file, "%s/man%s/%s.%s",
paths->paths[ipath], sec, name, sec);
if (stat(file, &sb) != -1)
@@ -751,14 +780,34 @@ fs_lookup(const struct manpaths *paths,
mandoc_msg(MANDOCERR_GLOB, 0, 0,
"%s: %s", file, strerror(errno));
free(file);
+ file = NULL;
if (globres == 0)
- file = mandoc_strdup(*globinfo.gl_pathv);
+ goto found;
globfree(&globinfo);
- if (globres == 0) {
- if (stat(file, &sb) != -1)
- goto found;
+
+ if (sec[1] != '\0' && *ressz == 0) {
+ secnum[0] = sec[0];
+ secnum[1] = '\0';
+ cp = file = mandoc_malloc(strlen(paths->paths[ipath]) * 2 +
+ strlen(slman) + strlen(secnum) * 2 + strlen(slash) +
+ strlen(name) * 2 + strlen(dot) +
+ strlen(sec) * 2 + strlen(aster) + 1);
+ glob_esc(&cp, paths->paths[ipath], slman);
+ glob_esc(&cp, secnum, slash);
+ glob_esc(&cp, name, dot);
+ glob_esc(&cp, sec, aster);
+ *cp = '\0';
+ globres = glob(file, 0, NULL, &globinfo);
+ if (globres != 0 && globres != GLOB_NOMATCH)
+ mandoc_msg(MANDOCERR_GLOB, 0, 0,
+ "%s: %s", file, strerror(errno));
free(file);
+ file = NULL;
+ if (globres == 0)
+ goto found;
+ globfree(&globinfo);
}
+
if (res != NULL || ipath + 1 != paths->sz)
return -1;
@@ -770,19 +819,14 @@ fs_lookup(const struct manpaths *paths,
found:
warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
- if (res == NULL) {
+ if (res == NULL)
free(file);
- return 0;
- }
- *res = mandoc_reallocarray(*res, ++*ressz, sizeof(**res));
- page = *res + (*ressz - 1);
- page->file = file;
- page->names = NULL;
- page->output = NULL;
- page->bits = NAME_FILE & NAME_MASK;
- page->ipath = ipath;
- page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
- page->form = form;
+ else if (file == NULL)
+ fs_append(globinfo.gl_pathv, globinfo.gl_pathc, 1,
+ ipath, sec, form, res, ressz);
+ else
+ fs_append(&file, 1, 0, ipath, sec, form, res, ressz);
+ globfree(&globinfo);
return 0;
}
--
To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv
reply other threads:[~2021-09-04 12:53 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c2aab0f69a22ffba@mandoc.bsd.lv \
--to=schwarze@mandoc.bsd.lv \
--cc=source@mandoc.bsd.lv \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).