Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/man Mimic OSX behaviour:



details:   https://anonhg.NetBSD.org/src/rev/679186ee6edd
branches:  trunk
changeset: 747963:679186ee6edd
user:      cegger <cegger%NetBSD.org@localhost>
date:      Wed Oct 07 08:30:31 2009 +0000

description:
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

diffstat:

 usr.bin/man/man.1 |   15 +++++-
 usr.bin/man/man.c |  118 +++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 107 insertions(+), 26 deletions(-)

diffs (189 lines):

diff -r 81895942e060 -r 679186ee6edd usr.bin/man/man.1
--- a/usr.bin/man/man.1 Wed Oct 07 08:06:11 2009 +0000
+++ b/usr.bin/man/man.1 Wed Oct 07 08:30:31 2009 +0000
@@ -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 @@
 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
diff -r 81895942e060 -r 679186ee6edd usr.bin/man/man.c
--- a/usr.bin/man/man.c Wed Oct 07 08:06:11 2009 +0000
+++ b/usr.bin/man/man.c Wed Oct 07 08:30:31 2009 +0000
@@ -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 @@
 #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 @@
        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 @@
 
        *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 @@
                                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) {



Home | Main Index | Thread Index | Old Index