[comp.sys.amiga] mg2a patch for sorted buffer menus

jw@obelisk.sics.se (Johan Widen) (06/20/88)

I just can't stand that tha buffer menus in mg are unsorted. The following
patch provides sorted buffer menus. It assumes that you have a qsort
(or rather something like the lattice tqsort) routine in your library.

*** ttymenu.c.old	Wed Jun 15 16:57:36 1988
--- ttymenu.c	Sun Jun 19 13:26:17 1988
***************
*** 480,485 ****
--- 480,504 ----
  		return (readin(fn));		/* Read it in.	*/
  	return TRUE;
  	}
+ 
+ struct name_node {
+ 	char *name;
+ 	struct name_node *next;
+ };
+ 
+ static void free_name_list(name_list)
+ register struct name_node *name_list;
+ {
+ 	register struct name_node *tmp;
+ 
+ 	while(name_list) {
+ 		tmp = name_list;
+ 		name_list = name_list->next;
+ 		free(tmp->name);
+ 		free(tmp);
+ 	}
+ }
+ 
  /*
   * Add_Dir - given a dir and a name, add the menu name with the files in
   *	dir as entries.  Use AllocMem() in order to make
***************
*** 494,499 ****
--- 513,521 ----
  	static char			Name_Buf[LONGEST_NAME] ;
  	char				*AllocMem();
  	struct	FileInfoBlock		*File_Info;
+ 	struct name_node		*name_list, *tmp_name;
+ 	char				*cp, **name_table;
+ 	int				i;
  
  	if ((File_Info = (struct FileInfoBlock *)
  		AllocMem((LONG)sizeof(struct FileInfoBlock), 0L)) == NULL)
***************
*** 511,533 ****
  		goto out;
  
  	if (Menu_Add(name, TRUE, TRUE) == 0) goto out;
  	for (count = 0; ExNext(my_lock, File_Info) 
! 			|| IoErr() != ERROR_NO_MORE_ENTRIES; count++)
! 		if (File_Info -> fib_DirEntryType < 0L) {
! 			if (Menu_Item_Add(File_Info -> fib_FileName,
! 				(USHORT)ITEMENABLED, 0L, (BYTE)0, TRUE)
! 					== MNUM(NOMENU, NOITEM, NOSUB))
! 					break ;
! 			}
! 		else {
! 			(void) strcpy(Name_Buf, File_Info -> fib_FileName) ;
  			(void) strcat(Name_Buf, "/") ;
! 			if (Menu_Item_Add(Name_Buf,
  				(USHORT) ITEMENABLED, 0L, (BYTE)0, TRUE)
  					 == MNUM(NOMENU, NOITEM, NOSUB))
! 				break ;
! 			}
! 	if (count == 0) Menu_Item_Add("EMPTY", (USHORT)0, 0L, (BYTE)0, FALSE) ;
  
  	/* Put everything back */
  	if (*last_char == '\0') *last_char = '/' ;
--- 533,580 ----
  		goto out;
  
  	if (Menu_Add(name, TRUE, TRUE) == 0) goto out;
+         name_list = NULL;
  	for (count = 0; ExNext(my_lock, File_Info) 
! 			|| IoErr() != ERROR_NO_MORE_ENTRIES; count++) {
! 		(void) strcpy(Name_Buf, File_Info -> fib_FileName) ;
! 		if (File_Info -> fib_DirEntryType >= 0L) {
  			(void) strcat(Name_Buf, "/") ;
! 		}
! 		if(!(cp = malloc(strlen(Name_Buf) + 1))) {
! 			free_name_list(name_list);
! 			return(FALSE);
! 		}
! 		strcpy(cp, Name_Buf);
! 		if(!(tmp_name = (struct name_node *)
! 			malloc(sizeof(struct name_node)))) {
! 			free_name_list(name_list);
! 			return(FALSE);
! 		}
! 		tmp_name->name = cp;
! 		tmp_name->next = name_list;
! 		name_list = tmp_name;
! 	}
! 	if (count > 0) {
! 		if (!(name_table = (char **) malloc(count*sizeof(char *)))) {
! 			free_name_list(name_list);
! 			return(FALSE);
! 		}
! 		i = count;
! 		for (tmp_name = name_list; tmp_name;
! 		     tmp_name = tmp_name->next) {
! 			name_table[--i] = tmp_name->name;
! 		}
! 		tqsort(name_table, count);
! 		for (i = 0; i < count; i++) {
! 			if (Menu_Item_Add(name_table[i],
  				(USHORT) ITEMENABLED, 0L, (BYTE)0, TRUE)
  					 == MNUM(NOMENU, NOITEM, NOSUB))
! 					break ;
! 		}
! 		free_name_list(name_list);
! 		free(name_table);
! 	} else
! 		Menu_Item_Add("EMPTY", (USHORT)0, 0L, (BYTE)0, FALSE) ;
  
  	/* Put everything back */
  	if (*last_char == '\0') *last_char = '/' ;
***************
*** 557,562 ****
--- 604,612 ----
  	struct DosInfo			*dosinfo;
  	UBYTE				buffer[80];
  	int				ramflag = 0;
+ 	struct name_node		*name_list, *tmp_name;
+ 	char				*cp, **name_table;
+ 	int				count, i;
  
  	/* if you've gotten this far, none of these will be null. */
  	DosBase = (struct DosLibrary *) OpenLibrary(DOSNAME,0L);
***************
*** 566,571 ****
--- 616,623 ----
  	dosinfo = (struct DosInfo *) BADDR(rootnode->rn_Info);
  	devlist = (struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  
+         name_list = NULL;
+ 	count = 0;
  	while (devlist) {
  		/* select by specified device type */
  		if (devlist->dl_Type != devtype) {
***************
*** 581,601 ****
  		 * disks should be the only devices added to the list. Magic
  		 * disk test courtesy of Phillip Lindsay, Commodore-Amiga Inc.
  		 */
! 		if (devtype != DLT_DEVICE)
! 			Menu_Item_Add(buffer, (USHORT)ITEMENABLED,
! 					0L, (BYTE)0, TRUE);
! 		else if (devlist->dl_Task) {	/* why does this work? */
! 			Menu_Item_Add(buffer, (USHORT)ITEMENABLED,
! 					0L, (BYTE)0, TRUE);
! 			if (!strcmp(buffer,"RAM:")) ramflag = 1;
  		}
  		devlist = (struct DeviceList *) BADDR(devlist->dl_Next);
  	}
- 	/* if ramdisk isn't loaded yet, add it anyway */
- 	if ((devtype == DLT_DEVICE) && !ramflag)
- 		Menu_Item_Add("RAM:",(USHORT)ITEMENABLED, 0L, (BYTE) 0, FALSE);
  	Permit();
  	CloseLibrary(DosBase);
  }
  
  btocstr(bp,buf,bufsiz)
--- 633,689 ----
  		 * disks should be the only devices added to the list. Magic
  		 * disk test courtesy of Phillip Lindsay, Commodore-Amiga Inc.
  		 */
! 		if (devtype != DLT_DEVICE || devlist->dl_Task) {
! 			count++;
! 			if(!(cp = malloc(strlen(buffer) + 1))) {
! 				free_name_list(name_list);
! 				Permit();
! 				CloseLibrary(DosBase);
! 				return;
! 			}
! 			strcpy(cp, buffer);
! 			if(!(tmp_name = (struct name_node *)
! 				malloc(sizeof(struct name_node)))) {
! 				free_name_list(name_list);
! 				Permit();
! 				CloseLibrary(DosBase);
! 				return;
! 			}
! 			tmp_name->name = cp;
! 			tmp_name->next = name_list;
! 			name_list = tmp_name;
! 			if (devtype == DLT_DEVICE &&
! 			    !strcmp(buffer,"RAM:"))
! 				ramflag = 1;
  		}
  		devlist = (struct DeviceList *) BADDR(devlist->dl_Next);
  	}
  	Permit();
  	CloseLibrary(DosBase);
+ 	if (count > 0 || (devtype == DLT_DEVICE && !ramflag)) {
+ 		if (!(name_table = (char **)
+ 			malloc((count + 1)*sizeof(char *)))) {
+ 			free_name_list(name_list);
+ 			return;
+ 		}
+ 		name_table[count] = "RAM:";
+ 		i = count;
+ 		for (tmp_name = name_list; tmp_name;
+ 		     tmp_name = tmp_name->next) {
+ 			name_table[--i] = tmp_name->name;
+ 		}
+ 		if(devtype == DLT_DEVICE && !ramflag)
+ 			count++;
+ 		tqsort(name_table, count);
+ 		for (i = 0; i < count; i++) {
+ 			if (Menu_Item_Add(name_table[i],
+ 				(USHORT)ITEMENABLED, 0L, (BYTE)0, TRUE)
+ 					== MNUM(NOMENU, NOITEM, NOSUB))
+ 					break ;
+ 		}
+ 		free_name_list(name_list);
+ 		free(name_table);
+ 	}
  }
  
  btocstr(bp,buf,bufsiz)
--
Johan Widen
SICS, PO Box 1263, S-164 28 KISTA, SWEDEN
Tel: +46 8 752 15 32	Ttx: 812 61 54 SICS S	Fax: +46 8 751 72 30
Internet: jw@sics.se or {mcvax,munnari,ukc,unido}!enea!sics.se!jw