[5574] in Athena Bugs
re: changes.71 #725: xman manpage subsections... patch
daemon@ATHENA.MIT.EDU (cfields@ATHENA.MIT.EDU)
Wed Jul 18 19:13:18 1990
From: cfields@ATHENA.MIT.EDU
Date: Wed, 18 Jul 90 19:12:55 -0400
To: bugs@MIT.EDU
> To: bugs@ATHENA.MIT.EDU
> Subject: vax 7.0F: xman
> Date: Wed, 06 Jun 90 17:12:06 EDT
> From: Beth Kevles (Full Time Consultant) <kevles@ATHENA.MIT.EDU>
> System name: CALIBAN
> Type and version: CVAXSTAR 7.0F
> Display type: SM
> What were you trying to do?
> See the manual page for random(3) via sman.
> What's wrong:
> It kept giving me the page for random(3F). Both when I did a
> straight search, and when I went to the "subroutines" section and did a
> search. (I did eventually find the correct manual page by looking at the
> directory of subroutines.)
> What should have happened:
> It should either offer you your choice of 3 or 3f routines with
> the same name, or else give the C routine as the default.
> Please describe any relevant documentation references:
> man xman
The following patch gives the same functionality to xman that man
has for choosing a man page when there are choices available from
multiple subsections. In the above case, a manpage without a subsection
specified has precedence over section F.
*** search.c.src Tue Oct 3 15:58:04 1989
--- search.c Wed Jul 18 18:41:53 1990
***************
*** 24,33 ****
--- 24,51 ----
static char rcs_version[] = "$Athena: search.c,v 4.7 89/01/06 15:59:02 kit Exp $";
#endif
+ #include <strings.h>
#include "globals.h"
/* Map <CR> and control-M to goto begining of file. */
+ /* following SUBSEC* defines stolen from man.c */
+ #define SUBSEC1 "cgv" /* subsections to try in section 1 */
+ #define SUBSEC2 "v"
+ #define SUBSEC3 "sxmncfX*" /* * must be last in search */
+ #define SUBSEC4 "pfn"
+ #define SUBSEC5 "v"
+
+ #ifdef ibm032
+ #define SUBSEC8 "crv" /* Official order for IBM man pages */
+ #else
+ #define SUBSEC8 "cv" /* Standard Berkeley order */
+ #endif
+
+ static char *subsections[] =
+ { "", SUBSEC1, SUBSEC2, SUBSEC3, SUBSEC4, SUBSEC5,
+ "", "", SUBSEC8 };
+
#define SEARCHARGS 10
FILE * DoManualSearch();
***************
*** 318,323 ****
--- 336,381 ----
return(FindManualFile(man_globals, i, e_num));
}
+ /*
+ * Function Name: manCompare
+ * Description: compare a string the user has typed with
+ * a manpage filename
+ * Arguments: userString - user's string
+ * manString - manpage filename string
+ * Returns: a signed value indicating the result of the comparison
+ */
+
+ static int
+ manCompare(userString, manString)
+ char *userString, *manString;
+ {
+ int cmp, len_cmp;
+ char *head, *tail;
+
+ head = rindex(manString, '/');
+ if (head == NULL)
+ PrintError("index failure in BEntrySearch");
+ head++;
+
+ tail = rindex(head, '.');
+ if (tail == NULL)
+ PrintError("index failure in BEntrySearch");
+
+ cmp = strncmp(userString, head, (tail - head));
+ len_cmp = strlen(userString) - (int) (tail - head);
+
+ if ( cmp == 0 && len_cmp == 0)
+ return 0;
+ else
+ {
+ if ( cmp < 0 || ((cmp == 0) && (len_cmp < 0)) )
+ return -1;
+ else /* cmp > 0 || ((cmp == 0) && (len_cmp > 0)) */
+ return 1;
+ }
+ }
+
+
/* Function Name: BEntrySearch
* Description: binary search through entries.
* Arguments: string - the string to match.
***************
*** 332,341 ****
char ** first;
int number;
{
! int check, cmp, len_cmp, global_number;
char *head, *tail;
global_number = 0;
while (TRUE) {
if (number == 0) {
--- 390,403 ----
char ** first;
int number;
{
! int check, cmp, global_number;
! int lastindex, bestchoice, choicerating = 100, tmprating;
! Boolean sofarsogood = FALSE;
char *head, *tail;
global_number = 0;
+ lastindex = number; /* we want to remember this for later */
+
while (TRUE) {
if (number == 0) {
***************
*** 344,367 ****
check = number/2;
! head = rindex(first[ global_number + check ], '/');
! if (head == NULL)
! PrintError("index failure in BEntrySearch");
! head++;
! tail = rindex(head, '.');
! if (tail == NULL)
! PrintError("index failure in BEntrySearch");
! cmp = strncmp(string, head, (tail - head));
! len_cmp = strlen(string) - (int) (tail - head);
! if ( cmp == 0 && len_cmp == 0) {
! return(global_number + check);
}
! else if ( cmp < 0 || ((cmp == 0) && (len_cmp < 0)) )
number = check;
! else /* cmp > 0 || ((cmp == 0) && (len_cmp > 0)) */ {
global_number += (check + 1);
number -= ( check + 1 );
}
--- 406,481 ----
check = number/2;
! cmp = manCompare(string, first[global_number + check]);
! if ( cmp == 0 ) {
! /* get out of binsearch and use more straightforward variables */
! check += global_number;
! if (check > 0)
! {
! sofarsogood = TRUE;
! check--;
! }
! /* no we back up to the first possible match */
! while (sofarsogood)
! if (0 != manCompare(string, first[check]))
! {
! check++;
! sofarsogood = FALSE;
}
! else
! {
! if (check > 0)
! check--;
! else
! sofarsogood = FALSE;
! }
!
! /* go through all the matches and pick the best one */
! while (!manCompare(string, first[check]))
! {
! /* the following rindex's are guaranteed to succeeed because
! we just did them in manCompare */
! head = rindex(first[check], '/') + 1;
! tail = rindex(head, '.') + 1;
!
! if (*tail >= '1' && *tail <= '8') /* the only ones we know */
! {
! if (tail[1] == '\0')
! tmprating = 0; /* get things not in subsections first */
! else
! {
! tmprating = (int) index(subsections[*tail - '0'], tail[1]);
! if (tmprating == 0)
! tmprating = 99; /* not in the list? last choice then. */
! else
! /* zero rating is for no subsection; so the minimum
! we can generate here should be 1 */
! tmprating = 1 + tmprating -
! (int) subsections[*tail - '0'];
! }
!
! if (tmprating < choicerating)
! {
! if ((choicerating = tmprating) == 0)
! return check;
! bestchoice = check;
! }
!
! check++;
! if (check == lastindex)
! return bestchoice;
! }
! else
! return(check);
! }
! return bestchoice;
! }
! else if ( cmp < 0 )
number = check;
! else /* cmp > 0 */ {
global_number += (check + 1);
number -= ( check + 1 );
}