From a73fa39e64827ca5dcdb7a737aab5af4732d4cf7 Mon Sep 17 00:00:00 2001 From: Eric Melville Date: Wed, 24 Apr 2002 20:07:06 +0000 Subject: [PATCH] When a compound section name is specified, search for pages that actually match the requested section. Previously, the section would be trimmed and every entry matching the page name would be displayed. Sponsored by: Apple --- gnu/usr.bin/man/man/man.c | 139 ++++++++++++++++++++++++++------------ 1 file changed, 95 insertions(+), 44 deletions(-) diff --git a/gnu/usr.bin/man/man/man.c b/gnu/usr.bin/man/man/man.c index 4c5b632a6c3..9ce35ac95d0 100644 --- a/gnu/usr.bin/man/man/man.c +++ b/gnu/usr.bin/man/man/man.c @@ -73,7 +73,8 @@ static char *pager; static char *machine; static char *manp; static char *manpathlist[MAXDIRS]; -static char *section; +static char *shortsec; +static char *longsec; static char *colon_sep_section_list; static char **section_list; static char *roff_directive; @@ -138,6 +139,7 @@ main (argc, argv) int man (); prognam = mkprogname (argv[0]); + longsec = NULL; unsetenv("IFS"); #ifdef __FreeBSD__ @@ -152,7 +154,7 @@ main (argc, argv) if (optind == argc - 1) { - tmp = is_section (argv[optind]); + tmp = is_section (argv[optind], manp); if (tmp != NULL) gripe_no_name (tmp); @@ -172,14 +174,14 @@ main (argc, argv) * See if this argument is a valid section name. If not, * is_section returns NULL. */ - tmp = is_section (nextarg); + tmp = is_section (nextarg, manp); if (tmp != NULL) { - section = tmp; + shortsec = tmp; if (debug) - fprintf (stderr, "\nsection: %s\n", section); + fprintf (stderr, "\nsection: %s\n", shortsec); continue; } @@ -197,7 +199,7 @@ main (argc, argv) status = man (nextarg); if (status == 0) - gripe_not_found (nextarg, section); + gripe_not_found (nextarg, longsec); } } return (status==0); /* status==1 --> exit(0), @@ -507,16 +509,55 @@ man_getopt (argc, argv) * named directories like .../man3f. Yuk. */ char * -is_section (name) - register char *name; +is_section (name, path) + char *name; + char *path; { register char **vs; + char *temp, *end, *loc; + char **plist; + int x; for (vs = section_list; *vs != NULL; vs++) if ((strcmp (*vs, name) == 0) || (isdigit ((unsigned char)name[0]) && strlen(name) == 1)) - return strdup (name); + return (longsec = strdup(name)); + plist = manpathlist; + if (isdigit ((unsigned char)name[0])) + { + while (*plist != NULL) + { + asprintf (&temp, "%s/man%c/*", *plist, name[0]); + plist++; + + x = 0; + vs = glob_filename (temp); + if ((int)vs == -1) + { + free (temp); + return NULL; + } + for ( ; *vs != NULL; vs++) + { + end = strrchr (*vs, '/'); + if ((loc = strstr (end, name)) != NULL && loc - end > 2 + && *(loc-1) == '.' + && (*(loc+strlen(name)) == '\0' || *(loc+strlen(name)) == '.')) + { + x = 1; + break; + } + } + free (temp); + if (x == 1) + { + asprintf (&temp, "%c", name[0]); + longsec = strdup (name); + return (temp); + } + } + } return NULL; } @@ -647,26 +688,33 @@ convert_name (name, to_cat) * Note that globbing is only done when the section is unspecified. */ char ** -glob_for_file (path, section, name, cat) - register char *path; - register char *section; - register char *name; - register int cat; +glob_for_file (path, section, longsec, name, cat) + char *path; + char *section; + char *longsec; + char *name; + int cat; { char pathname[FILENAME_MAX]; char **gf; + if (longsec == NULL) + longsec = section; + if (cat) - snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%s*", path, section, name, section); + snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%s*", path, section, + name, longsec); else - snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%s*", path, section, name, section); + snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%s*", path, section, + name, longsec); if (debug) fprintf (stderr, "globbing %s\n", pathname); gf = glob_filename (pathname); - if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)) + if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section) + && strlen (longsec) == 1) { if (cat) snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%c*", path, section, name, *section); @@ -675,7 +723,8 @@ glob_for_file (path, section, name, cat) gf = glob_filename (pathname); } - if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)) + if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section) + && strlen (longsec) == 1) { if (cat) snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.0*", path, section, name); @@ -693,20 +742,21 @@ glob_for_file (path, section, name, cat) * globbing. */ char ** -make_name (path, section, name, cat) - register char *path; - register char *section; - register char *name; - register int cat; +make_name (path, section, longsec, name, cat) + char *path; + char *section; + char *longsec; + char *name; + int cat; { register int i = 0; static char *names[3]; char buf[FILENAME_MAX]; if (cat) - snprintf (buf, sizeof(buf), "%s/cat%s/%s.%s", path, section, name, section); + snprintf (buf, sizeof(buf), "%s/cat%s/%s.%s", path, section, name, longsec); else - snprintf (buf, sizeof(buf), "%s/man%s/%s.%s", path, section, name, section); + snprintf (buf, sizeof(buf), "%s/man%s/%s.%s", path, section, name, longsec); if (access (buf, R_OK) == 0) names[i++] = strdup (buf); @@ -1381,11 +1431,12 @@ format_and_display (path, man_file, cat_file) * section. */ int -try_section (path, section, name, glob) - register char *path; - register char *section; - register char *name; - register int glob; +try_section (path, section, longsec, name, glob) + char *path; + char *section; + char *longsec; + char *name; + int glob; { register int found = 0; register int to_cat; @@ -1402,7 +1453,7 @@ try_section (path, section, name, glob) { snprintf(buf, sizeof(buf), "%s/%s", machine, name); arch_search++; - found = try_section (path, section, buf, glob); + found = try_section (path, section, longsec, buf, glob); arch_search--; if (found && !findall) /* only do this architecture... */ return found; @@ -1423,9 +1474,9 @@ try_section (path, section, name, glob) */ cat = 0; if (glob) - names = glob_for_file (path, section, name, cat); + names = glob_for_file (path, section, longsec, name, cat); else - names = make_name (path, section, name, cat); + names = make_name (path, section, longsec, name, cat); if (names == (char **) -1 || *names == NULL) /* @@ -1438,9 +1489,9 @@ try_section (path, section, name, glob) { cat = 1; if (glob) - names = glob_for_file (path, section, name, cat); + names = glob_for_file (path, section, longsec, name, cat); else - names = make_name (path, section, name, cat); + names = make_name (path, section, longsec, name, cat); if (names != (char **) -1 && *names != NULL) { @@ -1516,7 +1567,7 @@ man (name) found = 0; fflush (stdout); - if (section != NULL) + if (shortsec != NULL) { for (mp = manpathlist; *mp != NULL; mp++) { @@ -1533,27 +1584,27 @@ man (name) snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp, locale_lang, locale_terr, locale_codeset); if (is_directory (buf) == 1) - l_found = try_section (buf, section, name, glob); + l_found = try_section (buf, shortsec, longsec, name, glob); } if (!l_found) { if (*locale_lang != '\0') { snprintf(buf, sizeof(buf), "%s/%s.%s", *mp, locale_lang, locale_codeset); if (is_directory (buf) == 1) - l_found = try_section (buf, section, name, glob); + l_found = try_section (buf, shortsec, longsec, name, glob); } if (!l_found && strcmp(locale_lang, "en") != 0) { snprintf(buf, sizeof(buf), "%s/en.%s", *mp, locale_codeset); if (is_directory (buf) == 1) - l_found = try_section (buf, section, name, glob); + l_found = try_section (buf, shortsec, longsec, name, glob); } } locale_opts = NULL; } if (!l_found) { #endif - found += try_section (*mp, section, name, glob); + found += try_section (*mp, shortsec, longsec, name, glob); #ifdef __FreeBSD__ } else found += l_found; @@ -1582,27 +1633,27 @@ man (name) snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp, locale_lang, locale_terr, locale_codeset); if (is_directory (buf) == 1) - l_found = try_section (buf, *sp, name, glob); + l_found = try_section (buf, *sp, longsec, name, glob); } if (!l_found) { if (*locale_lang != '\0') { snprintf(buf, sizeof(buf), "%s/%s.%s", *mp, locale_lang, locale_codeset); if (is_directory (buf) == 1) - l_found = try_section (buf, *sp, name, glob); + l_found = try_section (buf, *sp, longsec, name, glob); } if (!l_found && strcmp(locale_lang, "en") != 0) { snprintf(buf, sizeof(buf), "%s/en.%s", *mp, locale_codeset); if (is_directory (buf) == 1) - l_found = try_section (buf, *sp, name, glob); + l_found = try_section (buf, *sp, longsec, name, glob); } } locale_opts = NULL; } if (!l_found) { #endif - found += try_section (*mp, *sp, name, glob); + found += try_section (*mp, *sp, longsec, name, glob); #ifdef __FreeBSD__ } else found += l_found;