source@mandoc.bsd.lv
 help / color / mirror / Atom feed
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).