[comp.sources.x] v02i081: X11 Release 3, Patch5

mikew@wyse.wyse.com (Mike Wexler) (01/10/89)

Submitted-by: jim@expo.lcs.mit.edu (Jim Fulton)
Posting-number: Volume 2, Issue 81
Archive-name: x11.3/patch5



		       Created on Monday, 9 January 1989

				  PART 1 of 3


Fixes 5, 6, and 7 are part of a single update to the xman program.  Together
they affect the following files:

	clients/xman/CHANGES
	clients/xman/README
	clients/xman/ScrollByL.c
	clients/xman/TODO
	clients/xman/buttons.c
	clients/xman/defs.h
	clients/xman/globals.c
	clients/xman/globals.h
	clients/xman/handler.c
	clients/xman/help.c
	clients/xman/main.c
	clients/xman/man.c
	clients/xman/man.h
	clients/xman/menu.c
	clients/xman/misc.c
	clients/xman/pages.c
	clients/xman/search.c
	clients/xman/tkfuncs.c
	clients/xman/version.h
	clients/xman/xman.help
	clients/xman/xman.man

To apply these fixes, concatenate all three files and pipe them to patch -p0
from the top of your X sources:

	%  cat fix5 fix6 fix7 | patch -p0


The following is fix5 (you will also need fix6 and fix7):



*** /tmp/,RCSt1a17149	Fri Jan  6 18:56:33 1989
--- clients/xman/buttons.c	Fri Jan  6 18:41:55 1989
***************
*** 1,8 ****
  /*
   * xman - X window system manual page display program.
   *
!  * $XConsortium: buttons.c,v 1.2 88/09/04 20:27:16 swick Exp $
!  * $oHeader: buttons.c,v 4.0 88/08/31 22:11:26 kit Exp $
   *
   * Copyright 1987, 1988 Massachusetts Institute of Technology
   *
--- 1,8 ----
  /*
   * xman - X window system manual page display program.
   *
!  * $XConsortium: buttons.c,v 1.3 89/01/06 18:41:51 kit Exp $
!  * $Header: buttons.c,v 1.3 89/01/06 18:41:51 kit Exp $
   *
   * Copyright 1987, 1988 Massachusetts Institute of Technology
   *
***************
*** 21,27 ****
   */
  
  #if ( !defined(lint) && !defined(SABER))
!   static char rcs_version[] = "$Athena: buttons.c,v 4.0 88/08/31 22:11:26 kit Exp $";
  #endif
  
  #include "globals.h"
--- 21,27 ----
   */
  
  #if ( !defined(lint) && !defined(SABER))
!   static char rcs_version[] = "$Athena: buttons.c,v 4.5 88/12/19 13:46:34 kit Exp $";
  #endif
  
  #include "globals.h"
***************
*** 45,53 ****
  #define TOPARGS 5
  
  void
! MakeTopMenuWidget(top)
! Widget top;
  {
    Widget menu;			/* Top Box and menu. */
    Menu topbox;			/* The menu structure for this box. */
    Button topbuttons[TOPBUTTONS]; /* The button structure for these buttons. */
--- 45,53 ----
  #define TOPARGS 5
  
  void
! MakeTopMenuWidget()
  {
+   Widget top;			/* top box widget. */
    Widget menu;			/* Top Box and menu. */
    Menu topbox;			/* The menu structure for this box. */
    Button topbuttons[TOPBUTTONS]; /* The button structure for these buttons. */
***************
*** 60,65 ****
--- 60,80 ----
      "Manual Page"
      };
  
+ /* create the top icon. */
+ 
+   num_args = 0;
+   XtSetArg(arglist[num_args], XtNiconPixmap,
+ 	   XCreateBitmapFromData( XtDisplay(initial_widget), 
+ 				 XtScreen(initial_widget)->root,
+ 				 iconclosed_bits, iconclosed_width,
+ 				 iconclosed_height));
+   num_args++;
+   XtSetArg(arglist[num_args], XtNallowShellResize, TRUE); 
+   num_args++;
+ 
+   top = XtCreatePopupShell(TOPBOXNAME, topLevelShellWidgetClass, 
+ 			   initial_widget, arglist, num_args);
+ 
    /* Set up the manual structure. */
  
    topbox.number = TOPBUTTONS;
***************
*** 73,79 ****
    topbox.buttons = topbuttons;
    topbox.callback = TopCallback;
  
! /* Set up the button structures, by assiging each one a name and a 
   * width, this puts either one button on a line or two depending on
   * the length of the string that will go into the buttons. See Menu.c for 
   * details.
--- 88,95 ----
    topbox.buttons = topbuttons;
    topbox.callback = TopCallback;
  
! /*
!  * Set up the button structures, by assiging each one a name and a 
   * width, this puts either one button on a line or two depending on
   * the length of the string that will go into the buttons. See Menu.c for 
   * details.
***************
*** 91,105 ****
    menu = MakeMenu(top,&topbox, NULL); /* Create the menu. */
    XtManageChild(menu);		/* Manage the menu. */
  
! /* create the top icon. */
! 
!   num_args = 0;
!   XtSetArg(arglist[num_args], XtNiconPixmap,
! 	   XCreateBitmapFromData( XtDisplay(top), XtScreen(top)->root,
! 				 iconclosed_bits, iconclosed_width,
! 				 iconclosed_height));
!   num_args++;
!   XtSetValues(top,arglist,num_args);
  }
  
  /*	Function Name: CreateManpage
--- 107,115 ----
    menu = MakeMenu(top,&topbox, NULL); /* Create the menu. */
    XtManageChild(menu);		/* Manage the menu. */
  
!   XtRealizeWidget(top);
!   XtMapWidget(top);
!   AddCursor(top, resources.cursors.top);
  }
  
  /*	Function Name: CreateManpage
***************
*** 136,142 ****
  
  /* Initialize the number of screens that will be shown */
  
!   man_globals->both_shown = both_shown_initial;
  
    for ( i = 0 ; i < sections ; i++) 
      man_globals->manpagewidgets.box[i] = NULL;
--- 146,152 ----
  
  /* Initialize the number of screens that will be shown */
  
!   man_globals->both_shown = resources.both_shown_initial;
  
    for ( i = 0 ; i < sections ; i++) 
      man_globals->manpagewidgets.box[i] = NULL;
***************
*** 174,181 ****
    XtSetArg(arglist[num_args], XtNheight, default_height);
    num_args++; 
  
!   top = XtCreateApplicationShell(name, topLevelShellWidgetClass,
! 				 arglist, num_args);
  
    man_globals->This_Manpage = top; /* pointer to root widget of Manualpage. */
    num_args = 0;
--- 184,191 ----
    XtSetArg(arglist[num_args], XtNheight, default_height);
    num_args++; 
  
!   top = XtCreatePopupShell(name, topLevelShellWidgetClass, initial_widget,
! 			   arglist, num_args);
  
    man_globals->This_Manpage = top; /* pointer to root widget of Manualpage. */
    num_args = 0;
***************
*** 215,230 ****
      mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
  				    pane, arglist, num_args);
      
!     man_globals->current_directory = 1;
      MakeDirectoryBox(man_globals, mpw->directory,
! 		     mpw->box + man_globals->current_directory, 1);
      XtManageChild(mpw->box[man_globals->current_directory]);
    }
  
  /* Create Manpage */
  
!   font_height = (fonts.normal->max_bounds.ascent + 
! 		   fonts.normal->max_bounds.descent);
  
    num_args = 0;
    XtSetArg(arglist[num_args], XtNallowVert, TRUE);
--- 225,241 ----
      mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
  				    pane, arglist, num_args);
      
!     man_globals->current_directory = INITIAL_DIR;
      MakeDirectoryBox(man_globals, mpw->directory,
! 		     mpw->box + man_globals->current_directory, 
! 		     man_globals->current_directory );
      XtManageChild(mpw->box[man_globals->current_directory]);
    }
  
  /* Create Manpage */
  
!   font_height = (resources.fonts.normal->max_bounds.ascent + 
! 		   resources.fonts.normal->max_bounds.descent);
  
    num_args = 0;
    XtSetArg(arglist[num_args], XtNallowVert, TRUE);
***************
*** 285,291 ****
      if (man_globals->both_shown) {
        XtManageChild(dir);
        man_globals->dir_shown = TRUE;
!       XtPanedSetMinMax(dir, directory_height, directory_height);
        XtSetSensitive(man_globals->put_up_manpage,FALSE);
        XtSetSensitive(man_globals->put_up_directory,FALSE);
        ChangeLabel(man_globals->both_shown_button, SHOW_ONE);
--- 296,303 ----
      if (man_globals->both_shown) {
        XtManageChild(dir);
        man_globals->dir_shown = TRUE;
!       XtPanedSetMinMax(dir, resources.directory_height, 
! 		       resources.directory_height);
        XtSetSensitive(man_globals->put_up_manpage,FALSE);
        XtSetSensitive(man_globals->put_up_directory,FALSE);
        ChangeLabel(man_globals->both_shown_button, SHOW_ONE);
***************
*** 320,326 ****
   */
  
    XtRealizeWidget(  man_globals->This_Manpage );
!   AddCursor( man_globals->This_Manpage, cursors.manpage);
    XtPanedSetMinMax(dir, 1, 10000); 
  }
  
--- 332,340 ----
   */
  
    XtRealizeWidget(  man_globals->This_Manpage );
!   XtMapWidget( man_globals->This_Manpage );
! 
!   AddCursor( man_globals->This_Manpage, resources.cursors.manpage);
    XtPanedSetMinMax(dir, 1, 10000); 
  }
  
***************
*** 467,473 ****
    MakeLong((Widget) pupwidget);
  
    XtRealizeWidget(popup_shell);	/* Realize it and change its cursor. */
!   AddCursor(popup_shell,cursors.top);
  }
  
  /*	Function Name: MakeDirPopUpWidget
--- 481,487 ----
    MakeLong((Widget) pupwidget);
  
    XtRealizeWidget(popup_shell);	/* Realize it and change its cursor. */
!   AddCursor(popup_shell,resources.cursors.top);
  }
  
  /*	Function Name: MakeDirPopUpWidget
***************
*** 494,513 ****
    Arg args[1];			/* The argument list. */
    int i;			/* A counter. */
    Cardinal num_args = 0;	/* The number of arguments. */
-   static char * name[MAXSECT];	/*the names of of the popups */
  
- /* Get the names from the manual structure. */
- 
-   for ( i = 1; i < sections; i++)
-     name[i - 1] = manual[i].blabel;
- 
    popup_shell = XtCreatePopupShell( SPOPUPNAME, overrideShellWidgetClass,
  				   widget, NULL, (Cardinal) 0);
    XtSetArg(args[num_args],XtNjustify,XtJustifyLeft); 
    num_args++;
  
!   popup.number = sections - 1;	/* We ignore section (0) even though it is
! 				   in the manual structure. */
    popup.name = "Manual Sections";
    popup.label_args = NULL;
    popup.label_num = (Cardinal) 0;
--- 508,520 ----
    Arg args[1];			/* The argument list. */
    int i;			/* A counter. */
    Cardinal num_args = 0;	/* The number of arguments. */
  
    popup_shell = XtCreatePopupShell( SPOPUPNAME, overrideShellWidgetClass,
  				   widget, NULL, (Cardinal) 0);
    XtSetArg(args[num_args],XtNjustify,XtJustifyLeft); 
    num_args++;
  
!   popup.number = sections;
    popup.name = "Manual Sections";
    popup.label_args = NULL;
    popup.label_num = (Cardinal) 0;
***************
*** 518,525 ****
    popup.buttons = buttons;
    popup.callback = DirPopUpCallback;
  
!   for ( i = 0 ; i < sections - 1; i ++) {
!     buttons[i].name = name[i];
      buttons[i].number_per_line = 0;
    }
  
--- 525,532 ----
    popup.buttons = buttons;
    popup.callback = DirPopUpCallback;
  
!   for ( i = 0 ; i < sections; i ++) {
!     buttons[i].name = manual[i].blabel;
      buttons[i].number_per_line = 0;
    }
  
***************
*** 529,566 ****
    XtManageChild(pupwidget);
    (void) MakeLong(pupwidget);
    XtRealizeWidget(popup_shell);
!   AddCursor(popup_shell,cursors.top);
  }
  
  /*	Function Name: CreateManpageName
   *	Description: Creates the manual page name for a given item.
!  *	Arguments: filename - the filename to convert.
   *	Returns: the manual page properly allocated.
   */
  
  /*
!  * If the filename is foo.c - Create an entry of the form:  foo
!  * If the filename is foo.cX - Create an entry of the form: foo(X)
   */
  
  char *
! CreateManpageName(filename)
! char * filename;
  {
!   char * cp, temp[BUFSIZ];
  
!   strcpy(temp, filename);
!   cp = rindex(temp, '.');
!   if (cp[2] != '\0') {
!     *cp++ = '(';  
!     *cp++ = *(cp + 1);
      *cp++ = ')';
      *cp = '\0';
    }
    else
      *cp = '\0';  
!   
!   return(StrAlloc(temp));
  }
  
  /*	Function Name: CreateList
--- 536,578 ----
    XtManageChild(pupwidget);
    (void) MakeLong(pupwidget);
    XtRealizeWidget(popup_shell);
!   AddCursor(popup_shell,resources.cursors.top);
  }
  
  /*	Function Name: CreateManpageName
   *	Description: Creates the manual page name for a given item.
!  *	Arguments: entry - the entry to convert.
   *	Returns: the manual page properly allocated.
   */
  
  /*
!  * If the filename is foo.3     - Create an entry of the form:  foo
!  * If the filename is foo.3X11 
!  * or foo.cX11.stuff            - Create an entry of the form:  foo(X11)
   */
  
  char *
! CreateManpageName(entry)
! char * entry;
  {
!   char * cp;
!   char page[BUFSIZ];
  
!   ParseEntry(entry, NULL, NULL, page);
! 
!   cp = index(page, '.');
!   if ( (cp[2] != '\0') && (cp[2] != '.') ) {
!     *cp++ = '(';
!     while( (cp[1] != '\0') && (cp[1] != '.') ) {
!       *cp = cp[1]; cp++;
!     }
      *cp++ = ')';
      *cp = '\0';
    }
    else
      *cp = '\0';  
! 
!   return(StrAlloc(page));
  }
  
  /*	Function Name: CreateList
***************
*** 581,587 ****
  
    for (current = ret_list, count = 0 ; count < manual[section].nentries ;
         count++, current++)
!     *current = CreateManpageName(manual[section].entries[count].label);
   
    *current = NULL;		/* NULL terminate the list. */
    return(ret_list);
--- 593,599 ----
  
    for (current = ret_list, count = 0 ; count < manual[section].nentries ;
         count++, current++)
!     *current = CreateManpageName(manual[section].entries[count]);
   
    *current = NULL;		/* NULL terminate the list. */
    return(ret_list);
***************
*** 618,624 ****
    num_args++;
    XtSetArg(arglist[num_args], XtNborderWidth, 0);
    num_args++;
!   XtSetArg(arglist[num_args], XtNfont, fonts.directory);
    num_args++;
    
    *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
--- 630,636 ----
    num_args++;
    XtSetArg(arglist[num_args], XtNborderWidth, 0);
    num_args++;
!   XtSetArg(arglist[num_args], XtNfont, resources.fonts.directory);
    num_args++;
    
    *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
***************
*** 669,675 ****
  						arglist,num_args);
    XtManageChild(box);
    XtRealizeWidget(shell);
!   AddCursor(shell,cursors.top);
  
    num_args = 0;
    shell = XtCreatePopupShell("likeToSave",transientShellWidgetClass,
--- 681,687 ----
  						arglist,num_args);
    XtManageChild(box);
    XtRealizeWidget(shell);
!   AddCursor(shell,resources.cursors.top);
  
    num_args = 0;
    shell = XtCreatePopupShell("likeToSave",transientShellWidgetClass,
***************
*** 727,731 ****
  
    XtManageChild(box);
    XtRealizeWidget(shell);
!   AddCursor(shell,cursors.top);
  }
--- 739,743 ----
  
    XtManageChild(box);
    XtRealizeWidget(shell);
!   AddCursor(shell,resources.cursors.top);
  }
*** /tmp/,RCSt1a17205	Fri Jan  6 18:56:49 1989
--- clients/xman/man.c	Fri Jan  6 18:42:17 1989
***************
*** 1,7 ****
  /*
   * xman - X window system manual page display program.
   *
!  * $XConsortium: man.c,v 1.2 88/09/06 17:48:10 jim Exp $
   *
   * Copyright 1987, 1988 Massachusetts Institute of Technology
   *
--- 1,7 ----
  /*
   * xman - X window system manual page display program.
   *
!  * $XConsortium: man.c,v 1.3 89/01/06 18:42:14 kit Exp $
   *
   * Copyright 1987, 1988 Massachusetts Institute of Technology
   *
***************
*** 20,49 ****
   */
  
  #if ( !defined(lint) && !defined(SABER))
!   static char rcs_version[] = "$Athena: man.c,v 4.0 88/08/31 22:12:33 kit Exp $";
  #endif
  
  #include "globals.h"
  
- static void SetSectionNames();
- static int GetSectNumber();
- static void CheckMandesc();
- 
  static char error_buf[BUFSIZ];		/* The buffer for error messages. */
  
! /*	Function Name: CmpEntryLabel - used in qsort().
!  *	Description: compares to elements by using their labels.
!  *	Arguments: e1, e2 - two elements to compare by label.
!  *	Returns: an integer >, < or = 0.
!  */
  
! static int 
! CmpEntryLabel(e1, e2) 
! struct entry *e1, *e2;
! {
!   return(strcmp(e1->label, e2->label));
! }
  
  /*	Function Name: Man
   *	Description: Builds a list of all manual directories and files.
   *	Arguments: none. 
--- 20,46 ----
   */
  
  #if ( !defined(lint) && !defined(SABER))
!   static char rcs_version[] = "$Athena: man.c,v 4.5 88/12/19 13:47:35 kit Exp $";
  #endif
  
  #include "globals.h"
  
  static char error_buf[BUFSIZ];		/* The buffer for error messages. */
  
! static void SortList(), ReadMandescFile(), SortAndRemove(), InitManual();
! static void AddToCurrentSection(), AddNewSection(), AddStandardSections();
! static int CmpEntryLabel();
  
! #define SECT_ERROR -1
! #define streq(a, b)        ( strcmp((a), (b)) == 0 )
  
+ typedef struct _SectionList {
+   struct _SectionList * next;	/* link to next elem in list. */
+   char * label, *directory;	/* The label and directory that this 
+ 				   section represents. */
+   Boolean standard;		/* Is this one of the standard sections? */
+ } SectionList;
+ 
  /*	Function Name: Man
   *	Description: Builds a list of all manual directories and files.
   *	Arguments: none. 
***************
*** 53,351 ****
  int
  Man()
  {
!   char *man_nomatch[MAXSECT + 1]; /* allow NULL termination. */
!   char *manptr, manualdir[BUFSIZ], *local_ptr;
!   int i,current[MAXSECT],nsect;
  
!   nsect = FIXEDSECT;
  
!   for (i = 0 ; i < MAXSECT ; i ++) {
!     current[i] = 0;		/* set current entries = 0. */
!     if ( (manual[i].entries = 
! 	  (struct entry *) malloc(MAXENTRY * sizeof(struct entry))) == NULL )
!       PrintError("Could not allocate memory, while building manpage list.");
!     
!     manual[i].blabel = "Dummy Section Label";
!     manual[i].longest = 1;
!   }
  
!   SetManNames(manual);
!   manptr = getenv("MANPATH");
!   if (manptr == NULL || strcmp(manptr,"") == 0) {
! #ifdef DEBUG  /* Since man does not complain we had better not either. */
!     sprintf(error_buf,"Could not find MANPATH searching only, %s.",MANDIR);
!     PrintWarning(error_buf);
! #endif
!     strcpy(manualdir,MANDIR);
    }
!   else
!     strcpy(manualdir,manptr);
  
!   local_ptr = manualdir;
!   do {
!     char *man[MAXSECT];
!     char *curmandir;
!     if ( (manptr = index(local_ptr,':')) != NULL) {    
!       *manptr = '\0';
!       curmandir = local_ptr;
!       local_ptr = manptr + 1;
!     }
!     else
!       curmandir = local_ptr;
  
! /*    if (!Preformatted(curmandir, manual, current, nsect)) { */
!       if (GetEntry(curmandir,man_nomatch)) {
! 	MatchEntries(curmandir,manual,man_nomatch,man,&nsect);
! 	AddStruct(manual,curmandir,man,current,nsect);
        }
! /*    } */
  
!   } while (manptr != NULL);
! 
!   SetSectionNames(manual);
!   SortAndRemove(manual, nsect);
! #ifdef notdef
!   DumpManual(nsect);
  #endif
!   return(nsect);		/* return the number of man sections. */
  }    
  
! /*	Function Name: GetEntry
!  *	Description: This function gets the names of the manual page
!  *                   directories, then closes the directory.
!  *	Arguments: path - the path to this directory.
!  *                 man - The directries of unformatted manual pages.
!  *	Returns: FALSE if directory could not be opened.
   */
  
! static Boolean
! GetEntry(path, man)
! char * path;
! char * man[MAXSECT];
  {
!   DIR * dir;
!   struct stat sb;
!   register struct direct *dp;
!   int numberman;
!   char full_path[BUFSIZ];
  
!   numberman = 0;
  
!   /*
!    * Read through this directory and save up any directory name
!    * which begins with "man".
!    */
!   
!   if((dir = opendir(path)) == NULL) {	
!     sprintf(error_buf,"Can't open directory %s", path);
!     PrintWarning(error_buf);
!     return(FALSE);
!   }
  
!   while((dp = readdir(dir)) != NULL) {
!     if((dp->d_namlen >= LSEARCHDIR) && 
!        (strncmp(dp->d_name, SEARCHDIR, LSEARCHDIR) == 0)) {
!       if(numberman == MAXSECT) 
! 	PrintError(
! 	  "Too many manual sections, recompile with larger allocations");
!       sprintf(full_path, "%s/%s", path, dp->d_name);
!       if((stat(full_path, &sb) >= 0) && (sb.st_mode & S_IFDIR))
! 	man[numberman++] = StrAlloc(dp->d_name);
      }
    }
-   
-   man[numberman] = NULL;	/* NULL terminate this list. */
-   closedir(dir);
-   return(TRUE);
- }
  
! /*	Function Name: MatchEntries
!  *	Description: This fucntion gives the correct number to the 
!  *                   directory, so that all manl entries will be 
!  *                   in the same place.
!  *	Arguments: path - path name if the current searched directory.
!  *                 manual - a pointer to the manual structure.
!  *                 manin - the unmatched states of the directories.
!  *                 manout - the new wonderfully matched directories.
!  *                 number - a pointer to the current number of sections.
!  *	Returns: manout.
   */
  
! void
! MatchEntries(path,manual,manin,manout,number)
! char * path;
! Manual * manual;
! char **manin;
! char **manout;
! int *number;
! {
!   int sect;
! 
!   bzero((char *) manout, MAXSECT * sizeof(char *));
! 
!   for ( ; *manin != NULL ; manin++) {
!     if ( (sect = GetSectNumber( (*manin)[LMAN] )) >= 0) 
!       manout[sect] = *manin;
    }
  
!   CheckMandesc(path, manout, manual, number);
! }
! 
! /*	Function Name: CheckMandesc
   *	Description: Reads the mandesc file, and adds more sections as 
   *                   nescessary.
!  *	Arguments: path - path name if the current searched directory.
!  *                 manual - a pointer to the manual structure.
!  *                 man - directories, now sorted by order.
!  *                 number - a pointer to the current number of sections.
!  *	Returns: none
   */
    
  static void
! CheckMandesc(path, manout, manual, number)
! int *number;
  char * path;
- char ** manout;
- Manual * manual;
  {
    char mandesc_file[BUFSIZ];	/* full path to the mandesc file. */
    FILE * descfile;
!   char character;
!   char string[BUFSIZ];
!   int sectnum;
!   register int j;
  
    sprintf(mandesc_file, "%s/%s", path, MANDESC);
!   if ( (descfile = fopen(mandesc_file, "r")) == NULL) 
!     return;			/* if no description file we are done. */
!   while ( (character = getc(descfile)) != EOF) {
!     Boolean flag = TRUE;
  
!     fgets(string, 100, descfile);
!     string[strlen(string)-1] = '\0';        /* Strip off the CR. */
!     if ( (sectnum = GetSectNumber(character)) >= 0) {
!       if (manout[sectnum] == NULL) {
! 	sprintf(error_buf, "Error in file: %s.", mandesc_file);
! 	PrintWarning(error_buf);
! 	sprintf(error_buf, "Could not find the directory %s/man%c.", 
! 		path, character);
! 	PrintWarning(error_buf);
  	continue;
        }
!       for (j = FIXEDSECT ; j < *number ; j++) {
! /*
!  * If this section exists then do not create a new one for it.
!  */
! 	if ( (!strcmp(manual[j].blabel , string)) ) {
! 	  manout[j] = manout[sectnum];
! 	  flag = FALSE;
! 	}
!       }
!       if (flag) {
! 	manual[*number].blabel = StrAlloc(string);
! 	manual[*number].sect = StrAlloc(manout[sectnum]);
! 	manout[*number] = StrAlloc(manout[sectnum]);
! 	if ( ++(*number) >= MAXSECT) {
! 	  sprintf(error_buf,"Number of sections exceeded %d recompile %s",
! 		  MAXSECT,"with larger MAXSECT.");
! 	    PrintError(error_buf);
! 	}
!       } 
!       manout[sectnum][0] = '\0'; /* remove it's name for the prev place */
      }
!     else { /* (sectnum = GetSectNumber(character)) >= 0) */
!       sprintf(error_buf, "Unknown man directory 'man%s'.", character);
!       PrintWarning(error_buf);
!     }
    }
!   fclose(descfile);
  }
  
! /*	Function Name: AddStruct
!  *	Description: add the new entries to the manual structure.
!  *	Arguments: manual - the manual structure to add them to.
!  *                 path   - the man path for these entires.
!  *                 man  - a pointer to the man directory names. 
!  *                 current - a pointer to the number of the current entry.
!  *	Returns: current - new current pointer numbers and changes manual
   */
  
! void
! AddStruct(manual,path,man,current,number)
! Manual * manual;
  char * path;
- char * man[MAXSECT];
- int current[MAXSECT];
- int number;
  {
!   int i;
!   DIR * dir;
!   register struct direct *dp;
!   char section[BUFSIZ];
  
!   /*
!    * Go through each manual directory saving up the individual
!    * page entries.
!    * Demand that a page entry not start with a '.' but have
!    * a dot somewhere.
!    */
  
!   for(i=0; i < number; i++,man++) {
!     register int j, k;
!     int longest, lpixels;
  
!     longest = lpixels = 1;	/* prevents division by zero. */
!     k = current[i];
  
!     path = StrAlloc(path);	/* allocate a space to save the path. */
  
!     /* 
!      * Use the man directories to get the file names 'cause they should be 
!      * more complete. 
!      */ 
  
!     if (*man == NULL)
!       continue;
!     sprintf(section,"%s/%s",path, *man);
!     if ( (dir = opendir(section)) == NULL) {
!       sprintf(error_buf, "Could not open directory %s.", section);
!       PrintWarning(error_buf);
!       continue;
!     }
  
!     while((dp = readdir(dir)) != NULL) {
!       if( k >= MAXENTRY) {
! 	sprintf(error_buf,"Too many manual pages in %s %s", section,
! 		"Try recompiling with larger allocations");
! 	PrintError(error_buf);
!       }
!       /* starts with a dot? no dot in name? */
!       if( (dp->d_name[0] == '.') || (rindex(dp->d_name,'.') == NULL) )
! 	continue;
!       manual[i].entries[k].label = StrAlloc(dp->d_name);
!       manual[i].entries[k].path = path;
!       k++;
! /* 
!  * This sets the value of the longest string in characters and pixels, I have
!  * to play a few games since the longest string in characters is not 
!  * nescessarily the longest string in pixels, and XTextWidth is not very fast.
   */
!       if ((j = strlen(dp->d_name)) >= longest - 2) {
! 	longest = j;
! 	if  ( (j = XTextWidth(fonts.directory,dp->d_name,strlen(dp->d_name))) >
! 	     lpixels)
! 	lpixels = j;
!       }
      }
!     closedir(dir);
! /*
!  * Yes, this check is needed, because we may add to the structure more 
!  * than once, depending on the MANPATH.
!  */
!     if ( (lpixels + 5) > manual[i].longest)
!       manual[i].longest = lpixels+5;
!     current[i] = manual[i].nentries = k;
    }
  }
  
  /*	Function Name: SortAndRemove
--- 50,348 ----
  int
  Man()
  {
!   SectionList *list = NULL;
!   char *ptr, manpath[BUFSIZ], *path, *current_label;
!   int sect;
  
! /* 
!  * Get the environment variable MANPATH, and if it doesn't exist then back
!  * up to MANDIR.
!  */
  
!   ptr = getenv("MANPATH");
!   if (ptr == NULL || streq(ptr , "") )
!     ptr = MANDIR;
!   strcpy(manpath, ptr);
  
! /*
!  * Get the list of manual directories in the users MANPATH that we should
!  * open to look for manual pages.  The ``mandesc'' file is read here.
!  */
! 
!   for ( path = manpath ; (ptr = index(path , ':')) != NULL ; path = ++ptr) { 
!     *ptr = '\0';
!     ReadMandescFile(&list, path);
    }
!   ReadMandescFile(&list, path);
  
!   SortList(&list);
  
!   sect = 0;
!   InitManual( &(manual[sect]), list->label );
!   current_label = NULL;
!   while ( list != NULL ) {
!     SectionList * old_list;
! 
!     if ( current_label == NULL || streq(list->label, current_label) )
!       AddToCurrentSection( &(manual[sect]), list->directory);
!     else {
!       if (manual[sect].nentries == 0) {	/* empty section, re-use it. */
! 	free(manual[sect].blabel);
! 	manual[sect].blabel = list->label;
        }
!       else {
! 	if ( ++sect >= MAXSECT ) {
! 	  sprintf(error_buf, "%s %s", "Too many manual sections, recompile",
! 		  "with a larger value for MAXSECT.");
! 	  PrintError(error_buf);
! 	}
! 	InitManual( &(manual[sect]), list->label );
!       }
!       AddToCurrentSection( &(manual[sect]), list->directory);
!     }
!     /* Save label to see if it matches next entry. */
!     current_label = list->label; 
!     old_list = list;
!     list = list->next;
!     free(old_list);		/* free what you allocate. */
!   }
!   if (manual[sect].nentries != 0)
!     sect++;			/* don't forget that last section. */
!   
!   SortAndRemove(manual, sect);
  
! #ifdef notdef			/* dump info. */
!   DumpManual(sect);
  #endif
!   return(sect);		/* return the number of man sections. */
  }    
  
! /*	Function Name: SortList
!  *	Description: Sorts the list of sections to search.
!  *	Arguments: list - a pointer to the list to sort.
!  *	Returns: a sorted list.
!  *
!  * This is the most complicated part of the entire operation.
!  * all sections with the same label must by right next to each other,
!  * but the sections that are in the standard list have to come first.
   */
  
! static void
! SortList(list)
! SectionList ** list;
  {
!   SectionList * local;
!   SectionList *head, *last, *inner, *old;
!   
!   if (*list == NULL)
!     PrintError("No manual sections to read, exiting.");
  
! /* 
!  * First step 
!  * 
!  * Look for standard list items, and more them to the top of the list.
!  */
  
!   last = NULL;			/* keep Saber happy. */
!   for ( local = *list ; local->next != NULL ; local = local->next) {
!     if ( local->standard ) {
!       if ( local == *list )	/* top element is already standard. */
! 	break;
!       head = local;
  
!       /* Find end of standard block */
!       for ( ; (local->next != NULL) && (local->standard) 
! 	   ; old = local, local = local->next); 
! 
!       last->next = old->next; /* Move the block. */
!       old->next = *list;
!       *list = head;
! 
!       break;			/* First step accomplished. */
      }
+     last = local;
    }
  
! /*
!  *  Second step
!  *
!  *  Move items with duplicate labels right next to each other.
   */
  
!   local = *list;
!   for ( local = *list ; local->next != NULL ; local = local->next) {
!     inner = local->next;
!     while ( inner != NULL) {
!       if ( streq(inner->label, local->label) && (inner != local->next)) {
! 	last->next = inner->next; /* Move it to directly follow local. */
! 	inner->next = local->next;
! 	local->next = inner;
! 	inner = last;		/* just so that we keep marching down the
! 				   tree (this keeps us from looping). */
!       }
!       last = inner;
!       inner = inner->next;
!     }
    }
+ }	
  
! /*	Function Name: ReadMandescFile
   *	Description: Reads the mandesc file, and adds more sections as 
   *                   nescessary.
!  *	Arguments: path - path name if the current search directory.
!  *                 section_list - pointer to the list of sections.
!  *	Returns: TRUE in we should use default sections
   */
    
  static void
! ReadMandescFile( section_list, path )
! SectionList ** section_list;
  char * path;
  {
    char mandesc_file[BUFSIZ];	/* full path to the mandesc file. */
    FILE * descfile;
!   char string[BUFSIZ], local_file[BUFSIZ];
!   Boolean use_defaults = TRUE;
  
    sprintf(mandesc_file, "%s/%s", path, MANDESC);
!   if ( (descfile = fopen(mandesc_file, "r")) != NULL) {
!     while ( fgets(string, BUFSIZ, descfile) != NULL) {
!       string[strlen(string)-1] = '\0';        /* Strip off the CR. */
  
!       if ( streq(string, NO_SECTION_DEFAULTS) ) {
! 	use_defaults = FALSE;
  	continue;
        }
! 
!       sprintf(local_file, "%s%c", MAN, string[0]);
!       AddNewSection(section_list, path, local_file, (string + 1), FALSE );
      }
!     fclose(descfile);
    }
!   if (use_defaults)
!     AddStandardSections(section_list, path);
  }
  
! /*	Function Name: AddStandardSections
!  *	Description: Adds all the standard sections to the list for this path.
!  *	Arguments: list - a pointer to the section list.
!  *                 path - the path to these standard sections.
!  *	Returns: none.
   */
  
! static void
! AddStandardSections(list, path)
! SectionList **list;
  char * path;
  {
!   static char * names[] = {
!     "User Commands       (1)",
!     "System Calls        (2)",
!     "Subroutines         (3)",
!     "Devices             (4)",
!     "File Formats        (5)",
!     "Games               (6)",
!     "Miscellaneous       (7)",
!     "Sys. Administration (8)",
!     "Local               (l)",
!     "New                 (n)",
!     "Old                 (o)",
!     };
!   register int i;
!   char file[BUFSIZ];
  
!   for (i = 1 ; i <= 8 ; i++) {
!     sprintf(file, "%s%d", MAN, i);
!     AddNewSection(list, path, file, names[i-1], TRUE);
!   }
!   i--;
!   sprintf(file, "%sl", MAN);
!   AddNewSection(list, path, file, names[i++], TRUE);
!   sprintf(file, "%sn", MAN);
!   AddNewSection(list, path, file, names[i++], TRUE);
!   sprintf(file, "%so", MAN);
!   AddNewSection(list, path, file, names[i], TRUE);
! }
  
! /*	Function Name: AddNewSection
!  *	Description: Adds the new section onto the current section list.
!  *	Arguments: list - pointer to the section list.
!  *                 path - the path to the current manual section.
!  *                 file - the file to save.
!  *                 label - the current section label.
!  *                 standard - one of the standard labels?
!  *	Returns: none.
!  */
  
! static void
! AddNewSection(list, path, file, label, standard)
! SectionList **list;
! char * path, * label, * file;
! Boolean standard;
! {
!   SectionList * local_list, * end;
!   char full_path[BUFSIZ];
  
! /* Allocate a new list element */
  
!   if ( (local_list = (SectionList *) malloc(sizeof(SectionList)) ) == NULL)
!     PrintError("Could not allocate Memory in AddNewSection.");
  
!   if (*list != NULL) {
!     for ( end = *list ; end->next != NULL ; end = end->next );
!     end->next = local_list;
!   }
!   else 
!     *list = local_list;
  
!   local_list->next = NULL;
!   local_list->label = StrAlloc(label);
!   sprintf(full_path, "%s/%s", path, file);
!   local_list->directory = StrAlloc(full_path);
!   local_list->standard = standard;
! }  
! 
! /*	Function Name: AddToCurrentSection
!  *	Description: This function gets the names of the manual page
!  *                   directories, then closes the directory.
!  *	Arguments:  local_manual - a pointer to a manual pages structure.
!  *                  path - the path to this directory.
!  *	Returns: FALSE if directory could not be opened.
   */
! 
! static void
! AddToCurrentSection(local_manual, path)
! Manual * local_manual;
! char * path;
! {
!   DIR * dir;
!   register struct direct *dp;
!   register int nentries;
!   char full_name[BUFSIZ];
! 
!   if((dir = opendir(path)) == NULL) {	
! #ifdef DEBUG
!     sprintf(error_buf,"Can't open directory %s", path);
!     PrintWarning(NULL, error_buf);
! #endif DEBUG
!     return;
!   }
!   
!   nentries = local_manual->nentries;
! 
!   while( (dp = readdir(dir)) != NULL ) {
!     char * name = dp->d_name;
!     if( (name[0] == '.') || (index(name, '.') == NULL) ) 
!       continue;
!     if ( nentries >= MAXENTRY ) {
!       sprintf(error_buf, "%s %s %s", "Too many manual pages in directory",
! 	      path, "recompile with A larger value for MAXENTRY.");
!       PrintError(error_buf);
      }
!     sprintf(full_name, "%s/%s", path, name);
!     local_manual->entries[nentries++] = StrAlloc(full_name);
    }
+   local_manual->nentries = nentries;
  }
  
  /*	Function Name: SortAndRemove
***************
*** 356,386 ****
   *	Returns: an improved manual stucure
   */
  
! void
  SortAndRemove(manual, number)
  Manual *manual;
  int number;
  {
    int i;
  
    for ( i = 0; i < number; i++) { /* sort each section */
      register int j = 0;
      Manual * man = &(manual[i]);
  
!     qsort(man->entries, man->nentries, sizeof(struct entry), CmpEntryLabel);
  
      while (j < (man->nentries - 1) ) {
!       if (!strcmp(man->entries[j].label, man->entries[j+1].label)) {
! 	register int k = 0;
! 	for( k = j; k < (man->nentries -1); k++)
! 	  man->entries[j] = man->entries[j+1];
  	(man->nentries)--;
        }
!       j++;
      }
    }
  }
  
  /*	Function Name: StrAlloc
   *	Description: this function allocates memory for a character string
   *      pointed to by sp and returns its new pointer.
--- 353,424 ----
   *	Returns: an improved manual stucure
   */
  
! static void
  SortAndRemove(manual, number)
  Manual *manual;
  int number;
  {
    int i;
+   char *l1, *l2;
  
    for ( i = 0; i < number; i++) { /* sort each section */
      register int j = 0;
      Manual * man = &(manual[i]);
  
! #ifdef DEBUG
!   printf("sorting section %d - %s\n", i, man->blabel);
! #endif DEBUG
  
+     qsort(man->entries, man->nentries, sizeof( char * ), CmpEntryLabel);
+ 
+ #ifdef DEBUG
+     printf("removing from section %d.\n", i);
+ #endif DEBUG
+ 
+     if ( (l1 = rindex(man->entries[j], '/')) == NULL)
+       PrintError("Internal error while removing duplicate manual pages.");
+     j++;
+ 
      while (j < (man->nentries - 1) ) {
!       l2 = l1;
!       if ( (l1 = rindex(man->entries[j], '/')) == NULL)
! 	PrintError("Internal error while removing duplicate manual pages.");
!       if ( streq(l1, l2) ) {
! 	register int k;
! 	for( k = j; k < (man->nentries); k++)
! 	  man->entries[k - 1] = man->entries[k];
  	(man->nentries)--;
        }
!       else
! 	j++;
      }
    }
  }
  
+ /*	Function Name: CmpEntryLabel - used in qsort().
+  *	Description: compares to elements by using their labels.
+  *	Arguments: e1, e2 - two items to compare.
+  *	Returns: an integer >, < or = 0.
+  */
+ 
+ static int 
+ CmpEntryLabel(e1, e2) 
+ char **e1, **e2;
+ {
+   char *l1, *l2;
+ 
+ /*
+  * What we really want to compare is the actual names of the manual pages,
+  * and not the full path names.
+  */
+ 
+   if ( (l1 = rindex(*e1, '/')) == NULL)
+     PrintError("Internal error while sorting manual pages.");
+   if ( (l2 = rindex(*e2, '/')) == NULL)
+     PrintError("Internal error while sorting manual pages.");
+   return( strcmp(l1, l2) );
+ }
+ 
  /*	Function Name: StrAlloc
   *	Description: this function allocates memory for a character string
   *      pointed to by sp and returns its new pointer.
***************
*** 401,493 ****
    return(ret);
  }
  
! /*	Function Name:  SetManNames
!  *	Description: This function give a name to manual.sect
!  *	Arguments: manual - pointer to the manual structure.
!  *	Returns: NONE.
!  */
! 
! void
! SetManNames(manual)
! Manual *manual;
! {
!   int i;
!   char string[40];
! 
!   for (i = 0; i < 9; i++) {
!     sprintf(string,"%s%d",MAN,i);
!     manual[i].sect = StrAlloc(string);
!   }
!   sprintf(string,"%s%c",MAN,'l');
!   manual[9].sect = StrAlloc(string);
!   sprintf(string,"%s%c",MAN,'n');
!   manual[10].sect = StrAlloc(string);
! }
! 
! /*	Function Name: GetSectNumber
!  *	Description: this gets a section number of a fixed section.
!  *	Arguments: character - the character representing the section.
!  *	Returns: the number of that section.
!  */
! 
! static int
! GetSectNumber(c)
! char c;
! {
! 
!   switch (c) {
!   case '0':
!   case '1':
!   case '2':
!   case '3':
!   case '4':
!   case '5':
!   case '6':
!   case '7':
!   case '8':
!     return(c - '0');
!   case 'l':
!     return(9);
!   case 'n':
!     return(10);
!   default:
!     break;			/* ignore others, and return -1. */
!   }
!   return(-1);
! }
! 
! /*	Function Name: SetSectNames
!  *	Description: Sets the section names.
!  *	Arguments: manual - the manual structure.
   *	Returns: none.
   */
  
  static void
! SetSectionNames(manual)
! Manual * manual;
  {
! 
!   /* These are the names for the first 10 sections. */
! 
!   static char * names[] = {
!     "foo bar (0)",
!     "User Commands (1)",
!     "System Calls (2)",
!     "Subroutines(3)",
!     "Devices (4)",
!     "File Formats (5)",
!     "Games (6)",
!     "Miscellaneous (7)",
!     "Sys. Administration (8)",
!     "Local (l)",
!     "New (n)"
!     };
!   register int i;
! 
!   for (i = 1; i < FIXEDSECT; i++)
!     manual[i].blabel = names[i];
  }
! 
  #if defined(DEBUG)
  
  /*	Function Name: DumpManual
--- 439,463 ----
    return(ret);
  }
  
! /*	Function Name: InitManual
!  *	Description: Initializes this manual section.
!  *	Arguments: l_manual - local copy of the manual structure.
!  *                 label - the button label for this section.
   *	Returns: none.
   */
  
  static void
! InitManual(l_manual, label)
! Manual * l_manual;
! char * label;
  {
!   bzero( l_manual, sizeof(Manual) );	        /* clear it. */
!   l_manual->blabel = label;	                /* set label. */
!   l_manual->entries = (char **) malloc( sizeof(char *) * MAXENTRY);
!   if (l_manual->entries == NULL)
! 	PrintError("Could not allocate memory in InitManual().");
  }
!   
  #if defined(DEBUG)
  
  /*	Function Name: DumpManual
***************
*** 502,510 ****
    register int i,j;
    
    for ( i = 0; i < number; i++) {
      for (j = 0; j < manual[i].nentries; j++) 
!       printf("path %-10s label %-20s\n", manual[i].entries[j].path,
! 	     manual[i].entries[j].label);
    }
  }
  
--- 472,480 ----
    register int i,j;
    
    for ( i = 0; i < number; i++) {
+     printf("label: %s\n", manual[i].blabel);
      for (j = 0; j < manual[i].nentries; j++) 
!       printf("%s\n", manual[i].entries[j]);
    }
  }
  
*** /tmp/,RCSt1a17235	Fri Jan  6 18:56:59 1989
--- clients/xman/misc.c	Fri Jan  6 18:42:26 1989
***************
*** 1,7 ****
  /*
   * xman - X window system manual page display program.
   *
!  * $XConsortium: misc.c,v 1.3 88/10/07 17:19:53 jim Exp $
   *
   * Copyright 1987, 1988 Massachusetts Institute of Technology
   *
--- 1,7 ----
  /*
   * xman - X window system manual page display program.
   *
!  * $XConsortium: misc.c,v 1.4 89/01/06 18:42:24 kit Exp $
   *
   * Copyright 1987, 1988 Massachusetts Institute of Technology
   *
***************
*** 20,26 ****
   */
  
  #if ( !defined(lint) && !defined(SABER))
!   static char rcs_version[] = "$Athena: misc.c,v 4.0 88/08/31 22:13:01 kit Exp $";
  #endif
  
  #include "globals.h"
--- 20,26 ----
   */
  
  #if ( !defined(lint) && !defined(SABER))
!   static char rcs_version[] = "$Athena: misc.c,v 4.6 88/12/19 13:48:01 kit Exp $";
  #endif
  
  #include "globals.h"
***************
*** 37,46 ****
   */
  
  void
! PrintWarning(string)
  char * string;
  {
!   fprintf(stderr,"Xman Warning: %s\n",string);
  }
  
  /*	Function Name: PrintError
--- 37,54 ----
   */
  
  void
! PrintWarning(man_globals, string)
! ManpageGlobals * man_globals;
  char * string;
  {
!   char buffer[BUFSIZ];
! 
!   sprintf( buffer, "Xman Warning: %s", string);
! 
!   if (man_globals != NULL) 
!     ChangeLabel(man_globals->label, buffer);
! 
!   fprintf(stderr, "%s\n", buffer);
  }
  
  /*	Function Name: PrintError
***************
*** 63,88 ****
  /*	Function Name: FindFilename
   *	Description: Opens the entry file given the entry struct.
   *	Arguments: man_globals - the globals info for this manpage.
-  *                 name - name of the current manpage.
   *                 entry - the structure containg the info on the file to open.
   *	Returns: fp - the file pointer
   */
  
  FILE *
! FindFilename(man_globals, name, section, entry)
  ManpageGlobals * man_globals;
! char * name;
! int section;
! struct entry * entry;
  {
    FILE * file;
!   char local_filename[BUFSIZ];	/* local filename. */
  
!   sprintf(man_globals->manpage_title,
! 	  "The current manual page is: %s.", name);   
    
!   sprintf(man_globals->filename, "%s/%s%c/%s",
! 	  entry->path, CAT,  manual[section].sect[LCAT], entry->label);
  
  /* if we find the formatted manpage then return it */
  
--- 71,94 ----
  /*	Function Name: FindFilename
   *	Description: Opens the entry file given the entry struct.
   *	Arguments: man_globals - the globals info for this manpage.
   *                 entry - the structure containg the info on the file to open.
   *	Returns: fp - the file pointer
   */
  
  FILE *
! FindFilename(man_globals, entry)
  ManpageGlobals * man_globals;
! char * entry;
  {
    FILE * file;
!   char path[BUFSIZ], page[BUFSIZ], section[BUFSIZ], *temp;
  
!   temp = CreateManpageName(entry);
!   sprintf(man_globals->manpage_title, "The current manual page is: %s.", temp);
!   free(temp);
    
!   ParseEntry(entry, path, section, page);
!   sprintf(man_globals->filename, "%s/%s%c/%s", path, CAT, section[LCAT], page);
  
  /* if we find the formatted manpage then return it */
  
***************
*** 89,109 ****
    if ( (file = fopen(man_globals->filename,"r")) != NULL)
      return(file);
  
! /* If not then look for the unformatted man page, format it and 
!  * write access is allowed to the cat directory, then ask if we
!  * want to save it.
!  */
! 
!   sprintf(local_filename,"%s/%s/%s",
! 	  entry->path, manual[section].sect, entry->label);
!   if ( (file = fopen(local_filename,"r")) == NULL) {
!     char error_buf[BUFSIZ];
!     /* We Really could not find it, this should never happen, yea right. */
!     sprintf(error_buf, "Could open manual page file, %s", local_filename);
!     PrintError(error_buf);
!   }
!   else 
!     return(Format(man_globals,file,local_filename, entry, section));
  }
  
  /*	Function Name: Format
--- 95,101 ----
    if ( (file = fopen(man_globals->filename,"r")) != NULL)
      return(file);
  
!   return(Format(man_globals, entry));
  }
  
  /*	Function Name: Format
***************
*** 111,118 ****
   *                   with the user.
   *	Arguments: man_globals - the psuedo globals
   *                 file - the file pointer to use and return
-  *                 local_filename - the name of the file that is 
-  *                                  being formatted.
   *                 entry - the current entry struct.
   *                 current_box - The current directory being displayed. 
   *	Returns: none.
--- 103,108 ----
***************
*** 121,138 ****
  /* ARGSUSED */
  
  FILE *
! Format(man_globals, file, local_filename, entry, current_box)
  ManpageGlobals * man_globals; 
! FILE * file;
! char * local_filename;
! struct entry * entry;
! int current_box;		/* The current directory being displayed.  */
  {
    Widget w = man_globals->manpagewidgets.directory;
!   char cmdbuf[256];
!   char tmp[25];
!   char catdir[100];
!   int x,y;			/* location to pop up whould you 
  				   like to save widget. */
  
    strcpy(tmp,MANTEMP);		/* get a temp file. */
--- 111,126 ----
  /* ARGSUSED */
  
  FILE *
! Format(man_globals, entry)
  ManpageGlobals * man_globals; 
! char * entry;
  {
+   FILE * file;
    Widget w = man_globals->manpagewidgets.directory;
!   char cmdbuf[BUFSIZ], tmp[BUFSIZ], catdir[BUFSIZ];
!   char path[BUFSIZ], section[BUFSIZ], error_buf[BUFSIZ];
! 
!   Position x,y;			/* location to pop up whould you 
  				   like to save widget. */
  
    strcpy(tmp,MANTEMP);		/* get a temp file. */
***************
*** 157,187 ****
    XFlush(XtDisplay(w));
  */
  /* End replacement. */
! /*
!   ChangeLabel(man_globals->label, "Formatting Manpage, Please Stand by...");
! */
  #ifdef macII
!   sprintf(cmdbuf,"cd %s;/usr/bin/pcat %s | /usr/bin/col | /usr/bin/ul -t dumb > %s",
! 	  entry->path, local_filename, man_globals->tmpfile);
  #else
!   sprintf(cmdbuf,"cd %s;%s %s > %s",
! 	  entry->path,
! 	  FORMAT, local_filename, man_globals->tmpfile);
  #endif
  
!   if(system(cmdbuf) != 0) 	/* execute search. */
!     PrintError("Something went wrong trying to run the command");
  
    if ((file = fopen(man_globals->tmpfile,"r")) == NULL) {  
!     PrintWarning("Something went wrong in retrieving the temp file");
!     PrintError("Try cleaning up /tmp");
    }
  
  /* if the catdir is writeable the ask the user if he/she wants to
     write the man page to it. */
  
!   sprintf(catdir,"%s/%s%c",
! 	  entry->path,CAT, manual[current_box].sect[LCAT], entry->label);
    
    if( (access(catdir,W_OK)) == 0)  {
      x = Width(man_globals->manpagewidgets.manpage)/2;
--- 145,187 ----
    XFlush(XtDisplay(w));
  */
  /* End replacement. */
! 
!   if ( (file = fopen( entry , "r")) == NULL) {
!     /* We Really could not find it, this should never happen, yea right. */
!     sprintf(error_buf, "Could open manual page file, %s", entry);
!     PrintWarning(man_globals, error_buf);
!     return(NULL);
!   }
! 
!   ParseEntry(entry, path, section, NULL);
! 
  #ifdef macII
!   sprintf(cmdbuf,
!         "cd %s;/usr/bin/pcat %s | /usr/bin/col | /usr/bin/ul -t dumb > %s %s",
! 	path, entry, man_globals->tmpfile, "2> /dev/null");
  #else
!   sprintf(cmdbuf,"cd %s ; %s %s > %s %s", path,
! 	  FORMAT, entry, man_globals->tmpfile, "2> /dev/null");
  #endif
  
!   if(system(cmdbuf) != 0) {	/* execute search. */
!     sprintf(error_buf,
! 	    "Something went wrong trying to run the command: %s", cmdbuf);
!     PrintWarning(man_globals, error_buf);
!     return(NULL);
!   }
  
    if ((file = fopen(man_globals->tmpfile,"r")) == NULL) {  
!     sprintf(error_buf, "Something went wrong in retrieving the temp file, %s",
! 	    "Try cleaning up /tmp");
!     PrintWarning(man_globals, error_buf);
!     return(NULL);
    }
  
  /* if the catdir is writeable the ask the user if he/she wants to
     write the man page to it. */
  
!   sprintf(catdir,"%s/%s%c", path, CAT, section[LCAT]);
    
    if( (access(catdir,W_OK)) == 0)  {
      x = Width(man_globals->manpagewidgets.manpage)/2;
***************
*** 188,194 ****
      y = Height(man_globals->manpagewidgets.manpage)/2;
      XtTranslateCoords(man_globals->manpagewidgets.manpage, x, y, &x, &y);
      PositionCenter( PopupChild(man_globals->manpagewidgets.manpage, 0),
! 		   x,y,0,0,0,0);
      XtPopup( PopupChild(man_globals->manpagewidgets.manpage, 0),
  	    XtGrabExclusive);
    }
--- 188,194 ----
      y = Height(man_globals->manpagewidgets.manpage)/2;
      XtTranslateCoords(man_globals->manpagewidgets.manpage, x, y, &x, &y);
      PositionCenter( PopupChild(man_globals->manpagewidgets.manpage, 0),
! 		   (int) x, (int) y,0,0,0,0);
      XtPopup( PopupChild(man_globals->manpagewidgets.manpage, 0),
  	    XtGrabExclusive);
    }
***************
*** 232,238 ****
  {
  
    if (!XtIsRealized(w)) {
!     PrintWarning("Widget is not realized, no cursor added.\n");
      return;
    }
    XDefineCursor(XtDisplay(w),XtWindow(w),cursor);
--- 232,238 ----
  {
  
    if (!XtIsRealized(w)) {
!     PrintWarning(NULL, "Widget is not realized, no cursor added.\n");
      return;
    }
    XDefineCursor(XtDisplay(w),XtWindow(w),cursor);
***************
*** 316,318 ****
--- 316,352 ----
    XtMoveWidget(widget,x_temp,y_temp);
  }  
  
+ /*	Function Name: ParseEntry(entry, path, sect, page)
+  *	Description: Parses the manual pages entry filenames.
+  *	Arguments: str - the full path name.
+  *                 path - the path name.      RETURNED
+  *                 sect - the section name.   RETURNED
+  *                 page - the page name.      RETURNED
+  *	Returns: none.
+  */
+ 
+ void
+ ParseEntry(entry, path, sect, page)
+ char *entry, *path, *page, *sect;
+ {
+   char *c, temp[BUFSIZ];
+ 
+   strcpy(temp, entry);
+ 
+   c = rindex(temp, '/');
+   if (c == NULL) 
+     PrintError("index failure in ParseEntry.");
+   *c++ = '\0';
+   if (page != NULL)
+     strcpy(page, c);
+ 
+   c = rindex(temp, '/');
+   if (c == NULL) 
+     PrintError("index failure in ParseEntry.");
+   *c++ = '\0';
+   if (sect != NULL)
+     strcpy(sect, c);
+ 
+   if (path != NULL)
+     strcpy(path, temp);
+ }
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x