Module Name:    src
Committed By:   sborrill
Date:           Thu Oct  8 08:15:24 UTC 2009

Modified Files:
        src/usr.bin/man [netbsd-5]: man.1 man.c

Log Message:
Pull up the following revisions(s) (requested by cegger in ticket #1076):
        usr.bin/man/man.1:      revision 1.21
        usr.bin/man/man.c:      revision 1.39

Allow man(1) to accept a pathname to a man file (e.g. man ./man.1)


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.20.28.1 src/usr.bin/man/man.1
cvs rdiff -u -r1.37 -r1.37.4.1 src/usr.bin/man/man.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/man/man.1
diff -u src/usr.bin/man/man.1:1.20 src/usr.bin/man/man.1:1.20.28.1
--- src/usr.bin/man/man.1:1.20	Thu Apr 13 21:10:44 2006
+++ src/usr.bin/man/man.1	Thu Oct  8 08:15:24 2009
@@ -1,4 +1,4 @@
-.\"	$NetBSD: man.1,v 1.20 2006/04/13 21:10:44 wiz Exp $
+.\"	$NetBSD: man.1,v 1.20.28.1 2009/10/08 08:15:24 sborrill Exp $
 .\"
 .\" Copyright (c) 1989, 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)man.1	8.2 (Berkeley) 1/2/94
 .\"
-.Dd April 10, 2006
+.Dd October 6, 2009
 .Dt MAN 1
 .Os
 .Sh NAME
@@ -168,6 +168,17 @@
 argument will be used as if specified by the
 .Ql Fl s
 option.
+.Pp
+If
+.Ar name
+is given with a full or relative path then
+.Nm
+interprets it as a file specification, so that you can do
+.Nm
+.Cm ./foo.5
+or even
+.Nm
+.Cm /cd/foo/bar.1.gz .
 .Sh ENVIRONMENT
 .Bl -tag -width MANPATHX
 .It Ev MACHINE

Index: src/usr.bin/man/man.c
diff -u src/usr.bin/man/man.c:1.37 src/usr.bin/man/man.c:1.37.4.1
--- src/usr.bin/man/man.c:1.37	Mon Jul 21 14:19:24 2008
+++ src/usr.bin/man/man.c	Thu Oct  8 08:15:24 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: man.c,v 1.37 2008/07/21 14:19:24 lukem Exp $	*/
+/*	$NetBSD: man.c,v 1.37.4.1 2009/10/08 08:15:24 sborrill Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993, 1994, 1995
@@ -40,7 +40,7 @@
 #if 0
 static char sccsid[] = "@(#)man.c	8.17 (Berkeley) 1/31/95";
 #else
-__RCSID("$NetBSD: man.c,v 1.37 2008/07/21 14:19:24 lukem Exp $");
+__RCSID("$NetBSD: man.c,v 1.37.4.1 2009/10/08 08:15:24 sborrill Exp $");
 #endif
 #endif /* not lint */
 
@@ -473,6 +473,39 @@
 	exit(cleanup());
 }
 
+static int
+manual_find_buildkeyword(char *escpage, const char *fmt,
+	struct manstate *mp, glob_t *pg, size_t cnt)
+{
+	ENTRY *suffix;
+	int found;
+	char *p, buf[MAXPATHLEN];
+
+	found = 0;
+	/* Try the _build key words next. */
+	TAILQ_FOREACH(suffix, &mp->buildlist->entrylist, q) {
+		for (p = suffix->s;
+		    *p != '\0' && !isspace((unsigned char)*p);
+		    ++p)
+			continue;
+		if (*p == '\0')
+			continue;
+
+		*p = '\0';
+		(void)snprintf(buf, sizeof(buf), fmt, escpage, suffix->s);
+		if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) {
+			if (!mp->where)
+				build_page(p + 1, &pg->gl_pathv[cnt], mp);
+			*p = ' ';
+			found = 1;
+			break;
+		}      
+		*p = ' ';
+	}
+
+	return found;
+}
+
 /*
  * manual --
  *	Search the manuals for the pages.
@@ -511,6 +544,63 @@
 
 	*eptr = '\0';
 
+	/*
+	 * If 'page' is given with a full or relative path
+	 * then interpret it as a file specification.
+	 */
+	if ((page[0] == '/') || (page[0] == '.')) {
+		/* check if file actually exists */
+		(void)strlcpy(buf, escpage, sizeof(buf));
+		error = glob(buf, GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT, NULL, pg);
+		if (error != 0) {
+			if (error == GLOB_NOMATCH) {
+				goto notfound;
+			} else {
+				errx(EXIT_FAILURE, "glob failed");
+			}
+		}
+
+		if (pg->gl_matchc == 0)
+			goto notfound;
+
+		/* clip suffix for the suffix check below */
+		p = strrchr(escpage, '.');
+		if (p && p[0] == '.' && isdigit((unsigned char)p[1]))
+			p[0] = '\0';
+
+		found = 0;
+		for (cnt = pg->gl_pathc - pg->gl_matchc;
+		    cnt < pg->gl_pathc; ++cnt)
+		{
+			found = manual_find_buildkeyword(escpage, "%s%s",
+				mp, pg, cnt);
+			if (found) {
+				anyfound = 1;
+				if (!mp->all) {
+					/* Delete any other matches. */
+					while (++cnt< pg->gl_pathc)
+						pg->gl_pathv[cnt] = "";
+					break;
+				}
+				continue;
+			}
+
+			/* It's not a man page, forget about it. */
+			pg->gl_pathv[cnt] = "";
+		}
+
+  notfound:
+		if (!anyfound) {
+			if (addentry(mp->missinglist, page, 0) < 0) {
+				warn("malloc");
+				(void)cleanup();
+				exit(EXIT_FAILURE);
+			}
+		}
+		free(escpage);
+		return anyfound;
+	}
+
 	/* For each man directory in mymanpath ... */
 	TAILQ_FOREACH(mdir, &mp->mymanpath->entrylist, q) {
 
@@ -577,28 +667,8 @@
 				goto next;
 
 			/* Try the _build key words next. */
-			found = 0;
-			TAILQ_FOREACH(suffix, &mp->buildlist->entrylist, q) {
-				for (p = suffix->s;
-				    *p != '\0' && !isspace((unsigned char)*p);
-				    ++p)
-					continue;
-				if (*p == '\0')
-					continue;
-				*p = '\0';
-				(void)snprintf(buf,
-				     sizeof(buf), "*/%s%s", escpage,
-				     suffix->s);
-				if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) {
-					if (!mp->where)
-						build_page(p + 1,
-						    &pg->gl_pathv[cnt], mp);
-					*p = ' ';
-					found = 1;
-					break;
-				}
-				*p = ' ';
-			}
+			found = manual_find_buildkeyword(escpage, "*/%s%s",
+				mp, pg, cnt);
 			if (found) {
 next:				anyfound = 1;
 				if (!mp->all) {

Reply via email to