[5574] in Athena Bugs

home help back first fref pref prev next nref lref last post

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 );
      }

home help back first fref pref prev next nref lref last post