Mimic OSX behaviour:
On OS X it is possible to specify the manpage filename with a full or relative path like this: man ./foo.5 or man /cd/foo/bar.1.gz This is really helpful to view the manpage quickly while editing it. patch presented on current-users@ and tech-userlevel@: http://mail-index.netbsd.org/current-users/2009/10/06/msg010767.html http://mail-index.netbsd.org/tech-userlevel/2009/10/06/msg002675.html No objections
This commit is contained in:
parent
8b451badf9
commit
656e85b2f1
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: man.1,v 1.20 2006/04/13 21:10:44 wiz Exp $
|
||||
.\" $NetBSD: man.1,v 1.21 2009/10/07 08:30:31 cegger 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 @@ option is not used, and the first argument is a valid section, then that
|
|||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: man.c,v 1.38 2009/10/06 06:43:15 cegger Exp $ */
|
||||
/* $NetBSD: man.c,v 1.39 2009/10/07 08:30:31 cegger Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994, 1995
|
||||
|
@ -40,7 +40,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994, 1995\
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)man.c 8.17 (Berkeley) 1/31/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: man.c,v 1.38 2009/10/06 06:43:15 cegger Exp $");
|
||||
__RCSID("$NetBSD: man.c,v 1.39 2009/10/07 08:30:31 cegger Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -472,6 +472,39 @@ main(int argc, char **argv)
|
|||
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.
|
||||
|
@ -510,6 +543,63 @@ manual(char *page, struct manstate *mp, glob_t *pg)
|
|||
|
||||
*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) {
|
||||
|
||||
|
@ -576,28 +666,8 @@ manual(char *page, struct manstate *mp, glob_t *pg)
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue