jw@sics.se (Johan Widen) (09/12/87)
Enclosed is a diff for mg1b (MicroGNUEmacs) distributed on Fish disk 68. mg has a directory browser that displays a directory in a menu. The directory is unsorted. This makes it unnecessary hard to locate a file. The enclosed diff adds code that sorts the names displayed in the browser menu. I have only tried this under the Lattice compiler. There should only be one problem with getting this to work under MANX: I used the Lattice library routine tqsort to sort the names. This routine may not be available under MANX. The declaration for tqsort is int tqsort(ta, n); where ta is an array of string pointers (char *) and n is the number of elements in the array. tqsort will sort ta using the procedure strcmp to determine the order of the strings. Sorry about this but I don't know what routines are available under MANX. Now on to something different: string search and query replace in mg. I usually prefer these to be case sensitive (and for query replace not to do any strange things with Capital letters). I realize that some people prefer string search to be case insensitive and that requirements differ depending on what kind of text you are editing. It would be nice if one could control the case sensitivity through a variable as you can in GNU emacs. NOTE: I have not enclosed any diffs for this, it's just wishful thinking. : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. echo 'Extracting mg1b.diff' sed 's/^X//' > mg1b.diff << '+ END-OF-FILE mg1b.diff' X*** ../ttymenu.c Sat Sep 12 01:27:08 1987 X--- ttymenu.c Sat Sep 12 01:21:43 1987 X*************** X*** 24,29 **** X--- 24,31 ---- X extern struct Menu *AutoMenu ; X extern struct Window *EmW ; X X+ extern char *malloc(); X+ X #ifdef LATTICE X static VOID Add_Devices(ULONG) ; X #else X*************** X*** 375,384 **** X--- 377,406 ---- X return (readin(File_Name)); /* Read it in. */ X return TRUE; X } X+ X+ struct name_node { X+ char *name; X+ struct name_node *next; X+ }; X+ X+ static void free_name_list(name_list) X+ register struct name_node *name_list; X+ { X+ register struct name_node *tmp; X+ X+ while(name_list) { X+ tmp = name_list; X+ name_list = name_list->next; X+ free(tmp->name); X+ free(tmp); X+ } X+ } X+ X /* X * Add_Dir - given a dir and a name, add the menu name with the files in X * dir as entries. Use AllocMem() in order to make X * sure the file info block is on a longword boundary. X+ * The entries are sorted before they are added to the menu. X */ X static X Add_Dir(dir, name) char *dir, *name; { X*************** X*** 389,394 **** X--- 411,419 ---- X static char Name_Buf[LONGEST_NAME] ; X char *AllocMem(); X struct FileInfoBlock *File_Info; X+ struct name_node *name_list, *tmp_name; X+ char *cp, **name_table; X+ int i; X X if ((File_Info = (struct FileInfoBlock *) X AllocMem((LONG)sizeof(struct FileInfoBlock), 0L)) == NULL) X*************** X*** 406,428 **** X goto out; X X if (Menu_Add(name, TRUE) == 0) goto out; X for (count = 0; ExNext(my_lock, File_Info) X! || IoErr() != ERROR_NO_MORE_ENTRIES; count++) X! if (File_Info -> fib_DirEntryType < 0L) { X! if (Menu_Item_Add(File_Info -> fib_FileName, X (USHORT)ITEMENABLED, 0L, (BYTE)0) X == MNUM(NOMENU, NOITEM, NOSUB)) X break ; X! } X! else { X! (void) strcpy(Name_Buf, File_Info -> fib_FileName) ; X! (void) strcat(Name_Buf, "/") ; X! if (Menu_Item_Add(Name_Buf, X! (USHORT) ITEMENABLED, 0L, (BYTE)0) X! == MNUM(NOMENU, NOITEM, NOSUB)) X! break ; X! } X! if (count == 0) Menu_Item_Add("EMPTY", (USHORT)0, 0L, (BYTE)0) ; X X /* Put everything back */ X if (*last_char == '\0') *last_char = '/' ; X--- 431,477 ---- X goto out; X X if (Menu_Add(name, TRUE) == 0) goto out; X+ name_list = NULL; X for (count = 0; ExNext(my_lock, File_Info) X! || IoErr() != ERROR_NO_MORE_ENTRIES; count++) { X! (void) strcpy(Name_Buf, File_Info -> fib_FileName) ; X! if (File_Info -> fib_DirEntryType >= 0L) X! (void) strcat(Name_Buf, "/") ; X! if(!(cp = malloc(strlen(Name_Buf) + 1))) { X! free_name_list(name_list); X! return(FALSE); X! } X! strcpy(cp, Name_Buf); X! if(!(tmp_name = (struct name_node *) X! malloc(sizeof(struct name_node)))) { X! free_name_list(name_list); X! return(FALSE); X! } X! tmp_name->name = cp; X! tmp_name->next = name_list; X! name_list = tmp_name; X! } X! if (count > 0) { X! if (!(name_table = (char **) malloc(count*sizeof(char *)))) { X! free_name_list(name_list); X! return(FALSE); X! } X! i = count; X! for (tmp_name = name_list; tmp_name; X! tmp_name = tmp_name->next) { X! name_table[--i] = tmp_name->name; X! } X! tqsort(name_table, count); X! for (i = 0; i < count; i++) { X! if (Menu_Item_Add(name_table[i], X (USHORT)ITEMENABLED, 0L, (BYTE)0) X == MNUM(NOMENU, NOITEM, NOSUB)) X break ; X! } X! free_name_list(name_list); X! free(name_table); X! } else X! Menu_Item_Add("EMPTY", (USHORT)0, 0L, (BYTE)0) ; X X /* Put everything back */ X if (*last_char == '\0') *last_char = '/' ; X*************** X*** 452,457 **** X--- 501,509 ---- X struct DosInfo *dosinfo; X UBYTE buffer[80]; X int ramflag = 0; X+ struct name_node *name_list, *tmp_name; X+ char *cp, **name_table; X+ int count, i; X X /* if you've gotten this far, none of these will be null. */ X DosBase = (struct DosLibrary *) OpenLibrary(DOSNAME,0L); X*************** X*** 461,466 **** X--- 513,520 ---- X dosinfo = (struct DosInfo *) BADDR(rootnode->rn_Info); X devlist = (struct DeviceList *) BADDR(dosinfo->di_DevInfo); X X+ name_list = NULL; X+ count = 0; X while (devlist) { X /* select by specified device type */ X if (devlist->dl_Type != devtype) { X*************** X*** 476,495 **** X * disks should be the only devices added to the list. Magic X * disk test courtesy of Phillip Lindsay, Commodore-Amiga Inc. X */ X! if (devtype != DLT_DEVICE) X! Menu_Item_Add(buffer,(USHORT)ITEMENABLED, 0L, (BYTE)0); X! else if (devlist->dl_Task) { /* why does this work? */ X! Menu_Item_Add(buffer, X! (USHORT)ITEMENABLED, 0L, (BYTE)0); X! if (!strcmp(buffer,"RAM:")) ramflag = 1; X } X devlist = (struct DeviceList *) BADDR(devlist->dl_Next); X } X- /* if ramdisk isn't loaded yet, add it anyway */ X- if ((devtype == DLT_DEVICE) && !ramflag) X- Menu_Item_Add("RAM:",(USHORT)ITEMENABLED, 0L, (BYTE) 0); X Permit(); X CloseLibrary(DosBase); X } X X btocstr(bp,buf,bufsiz) X--- 530,586 ---- X * disks should be the only devices added to the list. Magic X * disk test courtesy of Phillip Lindsay, Commodore-Amiga Inc. X */ X! if (devtype != DLT_DEVICE || devlist->dl_Task) { X! count++; X! if(!(cp = malloc(strlen(buffer) + 1))) { X! free_name_list(name_list); X! Permit(); X! CloseLibrary(DosBase); X! return; X! } X! strcpy(cp, buffer); X! if(!(tmp_name = (struct name_node *) X! malloc(sizeof(struct name_node)))) { X! free_name_list(name_list); X! Permit(); X! CloseLibrary(DosBase); X! return; X! } X! tmp_name->name = cp; X! tmp_name->next = name_list; X! name_list = tmp_name; X! if (devtype == DLT_DEVICE && X! !strcmp(buffer,"RAM:")) X! ramflag = 1; X } X devlist = (struct DeviceList *) BADDR(devlist->dl_Next); X } X Permit(); X CloseLibrary(DosBase); X+ if (count > 0 || (devtype == DLT_DEVICE && !ramflag)) { X+ if (!(name_table = (char **) X+ malloc((count + 1)*sizeof(char *)))) { X+ free_name_list(name_list); X+ return; X+ } X+ name_table[count] = "RAM:"; X+ i = count; X+ for (tmp_name = name_list; tmp_name; X+ tmp_name = tmp_name->next) { X+ name_table[--i] = tmp_name->name; X+ } X+ if(devtype == DLT_DEVICE && !ramflag) X+ count++; X+ tqsort(name_table, count); X+ for (i = 0; i < count; i++) { X+ if (Menu_Item_Add(name_table[i], X+ (USHORT)ITEMENABLED, 0L, (BYTE)0) X+ == MNUM(NOMENU, NOITEM, NOSUB)) X+ break ; X+ } X+ free_name_list(name_list); X+ free(name_table); X+ } X } X X btocstr(bp,buf,bufsiz) + END-OF-FILE mg1b.diff chmod 'u=rw,g=rw,o=r' 'mg1b.diff' echo ' -rw-rw-r-- 1 jw 6523 Sep 12 18:28 mg1b.diff (as sent)' echo -n ' ' /bin/ls -l mg1b.diff exit 0 -- Johan Widen SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw Internet: jw@sics.se