Path: utzoo!mnetor!uunet!husc6!hao!gatech!purdue!i.cc.purdue.edu!j.cc.purdue.edu!ahh From: ahh@j.cc.purdue.edu (Brent L. Woods) Newsgroups: comp.sources.amiga Subject: Files - a disk contents database program (2 of 2) Message-ID: <6089@j.cc.purdue.edu> Date: 5 Jan 88 01:03:37 GMT Organization: Co-Moderators Unlimited. Lines: 1062 Keywords: Not compile tested. Approved: ahh@j.cc.purdue.edu (Brent Woods) Program Name: Files Submitted By: dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon) Summary: A floppy disk file name archiving/database program. Poster Boy: Brent Woods (ahh@j.cc.purdue.edu) Tested. NOTES: Number two of two. I was unable to compile this program due to difficulties in duplicating the compiler environment that was needed (detailed in one of the files of the posting). Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga USENET: ...!j.cc.purdue.edu!ahh ARPANET: ahh@j.cc.purdue.edu BITNET: PODUM@PURCCVM PHONE: +1 (317) 743-8421 USNAIL: 320 Brown St., #406 / West Lafayette, IN 47906 ================================================================ # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # files.doc # files.h # gadget.c # head # main.c # memory.c # menu.c # newwildcmp.c # This archive created: Mon Jan 4 19:57:24 1988 # By: Brent L. Woods (Co-Moderators Unlimited.) cat << \SHAR_EOF > files.doc FILE CATALOG UTILITY By Matthew Dillon. dillon@ucbvax.berkeley.edu (ARPANET) ..!ihnp4!ucbvax!dillon (USENET) Matthew Dillon 891 Regal Rd. Berkeley, California 94708 USA WINDOW TITLE: Holds operational status. Normally holds two numbers SELECTED/ENTRIES Where SELECTED is the number of files currently selected for viewing. The ALL gadget selects all entries for viewing. PATTERN: Entering a wildcard pattern here selects for viewing those entries (file name or comment) which matches the pattern. "+pattern" adds entries to the currently selected list, and "-pattern" removes entries from the currently selected list. "pattern" alone is equivalent to "-*" "+pattern". Note that if looking for a specific program you need to specify it like: "*viacom.arc" with the "*" in front to handle any prefix to the file. '*' and '?' are acceptable wildcards. Any combination is allowed. The search is case independant. VOLUME: Entering a disk volume name (e.g. "df1:") or directory path (e.g. "df1:src/files") causes that volume/directory to be searched and all files to be added to the database. The FULL path name is determined, including the volume name, independant of the original specification. This means you can say "df1:" instead of "mydisk:" and entries in the database will begin "mydisk:blah..". When I say 'volume' in the following description I mean either a directory or volume. This also serves to UPDATE entries in the database. Specifically, if the volume already exists in the database new files are added and files which no longer exist (in the volume) are removed. Any comments which you have added to the database are KEPT. Note, however, that if a file contains a comment field and the database entry also has a comment field the database entry's comment field is used. Example: To add a whole lot of floppies simply specify DF0:, hit return, then place new floppies in DF0: and hit return without having to retype DF0: or even reselect the string gadget. NOTE!! Each disk should have a unique volume name or it will exclude other disks! Now that isn't too much to ask for, is it? COMMENT: After selecting a file with the left mouse button you may enter a comment for it. The comment field is automatically activated after selection and any previous comment loaded into the field. SLIDE BAR: The slide bar is used to move around in the database. Normally the database is too large for much resolution on the slide bar (mine is 3821 entries at the moment), in which case one normally selects a subsection of the database with the PATTERN field before moving around. The display area places the comment after the longest file path in the currently selected subset, so you might have to make the window wider to see the comments. INFO: Program info. My name in lights! DEL: Delete the highlighted item or the currently selected subsection of the database if there is no highlighted item. YOU CAN DELETE THE ENTIRE DATABASE THIS WAY!! BUT... UNDO: Undo the last delete operation. For best results hit immediately after a DEL. ALL: Selects the entire database for viewing. ---------------------------------------------------------------------------- MENUS SAVE save database under previously loaded name SAVEAS save database under a new name LOADDEF load the default database (s:catalog.db or previously loaded file). Information is appended to the memory image. LOAD specify a filename to load as the database. Information is appended as in LOADDEF QUIT Quit the program (for those who do not know how to use the close gadget) ADDKILLPAT Create a kill entry in the database (@@KILLPAT). The comment field of this entry is a pattern. If the pattern matches an about-to-be-loaded path the path is not loaded. Any number of kill entries may exist in the database. Example: set the comment to *.o, and no object files will be added from new volumes. The filerequester code was provided by Peter Da Silva and hacked moderately. All other code is my own. ---------------------------------------------------------------------------- LIMITATIONS -Volume Names may not begin with @@ -Volume Names beginning with '+' and '-' are o.k., but difficult to specify in the PATTERN field due to the special meaning of '+' & '-'. -Full File Paths and comments must be smaller than 128 characters each -There is no limitation to the database size except for the amount of memory you have. ---------------------------------------------------------------------------- FILE FORMAT The database is an ascii file. The first line is a number (3) specifying the number of lines per entry. The next line starts the first entry, with 3 lines per entry (and no extra lines at the end of the database). No tabs are allowed. The initial number is used for upward compatibility when/if I add more information to the database. The three lines are: 1 -file name 2 -file comment 3 -file size (bytes) Future additions will also include: 4 -date SHAR_EOF cat << \SHAR_EOF > files.h /* * FILES.H * */ #include #include #define GAD_INFO 1 #define GAD_DEL 2 #define GAD_UNDO 3 #define GAD_ALL 4 #define GAD_VOLUME 8 #define GAD_PATTERN 9 #define GAD_COMMENT 10 #define GAD_SLIDER 11 #define GAD_BIGBOX 12 #define MEN_SAVE 1 #define MEN_SAVEAS 2 #define MEN_LOAD 3 #define MEN_LOADEF 4 #define MEN_QUIT 5 #define MEN_KILLPAT 6 #define title(str) SetWindowTitles(Win,(str),NULL) #define KILLNAME "@@KILLPAT" #define RECORD struct _RECORD typedef unsigned long ulong; typedef unsigned short uword; typedef unsigned char ubyte; /* * Each record is stored in the following structure. */ #define R_SELECTED 0x01 /* A selected item */ #define R_KILLPAT 0x02 /* deleted item (undoable) */ #define R_UPDATE 0x04 /* flag delete (used for updating a volume) */ #define R_SOFTERR 0x08 /* software error if ever encountered! */ RECORD { RECORD *next; /* record list, doubly linked */ RECORD *prev; char *comment; /* comment */ char *name; /* entire file name */ long bytes; /* file size */ short flags; }; extern WIN *OpenWindow(); extern void *malloc(); extern void *GetMsg(); extern void *AllocMem(); extern RECORD *allocrecord(); extern char *allocstr(); extern RECORD *Rbase; extern RECORD *Highlighted; extern WIN *Win; extern RP *Rp; extern long NumEntries; extern short Modified; SHAR_EOF cat << \SHAR_EOF > gadget.c /* * GADGET.C * * (c)Copyright 1987 Matthew Dillon, All Rights Reserved. * */ #include "files.h" #define NI 0 static BORDER Bdr[10]; static ITEXT BText[] = { { 3,0,JAM2,1,0,NULL,(ubyte *)"info"}, { 3,0,JAM2,1,0,NULL,(ubyte *)"del" }, { 3,0,JAM2,1,0,NULL,(ubyte *)"undo"}, { 3,0,JAM2,1,0,NULL,(ubyte *)"all" } }; static ITEXT SText[] = { { 3,0,JAM2,NI,-2,NULL,(ubyte *)"Volume: " }, { 3,0,JAM2,NI,-2,NULL,(ubyte *)"Pattern: " }, { 3,0,JAM2,NI,-2,NULL,(ubyte *)"Comment: " } }; ubyte Buf1_vol[128]; ubyte Buf2_vol[128]; ubyte Buf1_pat[128]; ubyte Buf2_pat[128]; ubyte Buf1_com[128]; ubyte Buf2_com[128]; STRINGINFO Si_vol = { Buf1_vol,Buf2_vol,0,sizeof(Buf1_vol),0,0,0,0,0,0 }; STRINGINFO Si_pat = { Buf1_pat,Buf2_pat,0,sizeof(Buf2_pat),0,0,0,0,0,0 }; STRINGINFO Si_com = { Buf1_com,Buf2_com,0,sizeof(Buf2_com),0,0,0,0,0,0 }; GADGET Gad_vol = { NULL , NI, 0, NI, NI, GADGHCOMP|GRELWIDTH,GADGIMMEDIATE|RELVERIFY,STRGADGET,NI,NULL,&SText[0],NULL,(APTR)&Si_vol }; GADGET Gad_pat = { &Gad_vol , NI, 1, NI, NI, GADGHCOMP|GRELWIDTH,GADGIMMEDIATE|RELVERIFY,STRGADGET,NI,NULL,&SText[1],NULL,(APTR)&Si_pat }; GADGET Gad_com = { &Gad_pat , NI, 2, NI, NI, GADGHCOMP|GRELWIDTH,GADGIMMEDIATE|RELVERIFY,STRGADGET,NI,NULL,&SText[2],NULL,(APTR)&Si_com }; GADGET Gad_info= { &Gad_com , 5 ,-15, NI, NI, GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[0] }; GADGET Gad_del = { &Gad_info , 50,-15, NI, NI, GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[1] }; GADGET Gad_undo= { &Gad_del ,-110,-15, NI, NI,GADGHCOMP|GRELRIGHT|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[2] }; GADGET Gad_all = { &Gad_undo , -50,-15, NI, NI, GADGHCOMP|GRELRIGHT|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[3] }; GADGET *FirstGadget = &Gad_all; GADGET Gad_box = { NULL , NI, NI, NI, NI, GADGHNONE|GRELWIDTH|GRELHEIGHT,GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE,BOOLGADGET,NULL,NULL,NULL }; PROPINFO Prop_slid = { AUTOKNOB|FREEVERT, 0, 0, 0x30, 0x30 }; IMAGE Imag_slid = { 0,0,2,1,1,NULL,1,0,NULL }; GADGET Gad_slid = { NULL, -20, 12, 20, -30, GADGHCOMP|GRELHEIGHT|GRELRIGHT,GADGIMMEDIATE|RELVERIFY|RIGHTBORDER|FOLLOWMOUSE,PROPGADGET,(APTR)&Imag_slid,NULL,NULL,0,(APTR)&Prop_slid }; initslider(nw) NW *nw; { nw->FirstGadget = &Gad_slid; } initstructs() { register short i; register GADGET *gad; for (i = 0; i < sizeof(Bdr)/sizeof(Bdr[0]); ++i) { register BORDER *b = &Bdr[i]; register short *xy= malloc(5 * 2 * sizeof(short)); /*b->LeftEdge = b->TopEdge = -2;*/ b->FrontPen = 1; b->DrawMode = JAM2; b->Count = 5; b->XY = xy; bzero(xy, 5 * 2 * sizeof(short)); xy[2] = i * Win->RPort->TxWidth + 4; xy[4] = xy[2]; xy[5] = Win->RPort->TxHeight + 2; xy[7] = Win->RPort->TxHeight + 2; } for (i = 0; i < sizeof(SText)/sizeof(SText[0]); ++i) { register ITEXT *it = &SText[i]; it->LeftEdge = -strlen(it->IText) * Win->RPort->TxWidth + 2; it->TopEdge += 2; } for (i = 0; i < sizeof(BText)/sizeof(BText[0]); ++i) { register ITEXT *it = &BText[i]; it->LeftEdge+= 2; it->TopEdge += 2; } for (gad = FirstGadget; gad; gad = gad->NextGadget) { register ubyte *str = gad->GadgetText->IText; gad->Height = Win->RPort->TxHeight + 3; gad->Width = strlen(str) * Win->RPort->TxWidth + 5; if (gad->GadgetType == STRGADGET) { gad->LeftEdge = Win->BorderLeft + strlen(str) * Win->RPort->TxWidth + 2; gad->Width = -gad->LeftEdge - Win->BorderRight; gad->TopEdge = gad->TopEdge * (Win->RPort->TxHeight + 2) + Win->BorderTop; gad->GadgetText->LeftEdge = -strlen(str) * Win->RPort->TxWidth; } else { gad->GadgetRender = (APTR)&Bdr[strlen(str)]; } } Gad_box.LeftEdge= Win->BorderLeft; Gad_box.TopEdge = Gad_com.TopEdge + Win->RPort->TxHeight + 2; Gad_box.Width = -Gad_box.LeftEdge - Win->BorderRight; Gad_box.Height = -Gad_box.TopEdge + Gad_undo.TopEdge - 2; } addgadgets() { register GADGET *gad, *ngad; int i = 0; initstructs(Win); for (gad = FirstGadget; gad; gad = ngad) { ngad = gad->NextGadget; AddGadget(Win, gad, i); ++i; } AddGadget(Win, &Gad_box, i); RefreshGList(FirstGadget, Win, NULL, -1); } remgadgets() { } fixgadgets() { } getgadget(im, sel, str) IMESS *im; short *sel; ubyte **str; { GADGET *gad = (GADGET *)im->IAddress; *sel = gad->Flags & SELECTED; if (gad == &Gad_info) return(GAD_INFO); if (gad == &Gad_del) return(GAD_DEL); if (gad == &Gad_undo) return(GAD_UNDO); if (gad == &Gad_all) return(GAD_ALL); if (gad == &Gad_slid) return(GAD_SLIDER); if (gad == &Gad_box) return(GAD_BIGBOX); if (gad == &Gad_vol || gad == &Gad_pat || gad == &Gad_com) { *str = ((STRINGINFO *)gad->SpecialInfo)->Buffer; if (gad == &Gad_vol) return(GAD_VOLUME); if (gad == &Gad_pat) return(GAD_PATTERN); if (gad == &Gad_com) return(GAD_COMMENT); } return(0); } bigboxbounds(xs,xe,ys,ye) short *xs,*xe,*ys,*ye; { *xs = Gad_box.LeftEdge; *xe = *xs + Gad_box.Width + Win->Width; *ys = Gad_box.TopEdge; *ye = *ys + Gad_box.Height+ Win->Height; if (*xe <= *xs) *xe = *xs + 1; if (*ye <= *ys) *ye = *ys + 1; } getsliderpos(pot, full) short *pot, *full; { *pot = Prop_slid.VertPot; *full= Prop_slid.VertBody; } getboxpos(im) IMESS *im; { return(im->MouseY - Gad_box.TopEdge); } setslider(pos, fatness) { NewModifyProp(&Gad_slid, Win, NULL, AUTOKNOB|FREEVERT,0,pos,0,fatness,1); } setcomment(str) char *str; { strcpy(Buf1_com, str); RefreshGList(&Gad_com, Win, NULL, 1); } activate_vol() { ActivateGadget(&Gad_vol, Win, NULL); } activate_pat() { ActivateGadget(&Gad_pat, Win, NULL); } activate_com() { ActivateGadget(&Gad_com, Win, NULL); } SHAR_EOF cat << \SHAR_EOF > head Approved: ahh@j.cc.purdue.edu (Brent Woods) Program Name: Files Submitted By: dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon) Summary: A floppy disk file name archiving/database program. Poster Boy: Brent Woods (ahh@j.cc.purdue.edu) Tested. NOTES: Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga USENET: ...!j.cc.purdue.edu!ahh ARPANET: ahh@j.cc.purdue.edu BITNET: PODUM@PURCCVM PHONE: +1 (317) 743-8421 USNAIL: 320 Brown St., #406 / West Lafayette, IN 47906 ================================================================ SHAR_EOF cat << \SHAR_EOF > main.c /* * MAIN.C * * FILES * * A file catalog program by Matthew Dillon. * * (c)Copyright 1987 Matthew Dillon, All Rights Reserved. * */ #include "files.h" #include NW Nw = { 30, 30, 500, 150, -1, -1, NEWSIZE|MOUSEBUTTONS|MOUSEMOVE|GADGETDOWN|GADGETUP|MENUPICK|CLOSEWINDOW, WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|ACTIVATE, NULL, NULL, (ubyte *)"V1.1 by Matthew Dillon, Catalog Utility.", NULL, NULL, 182, 66, -1, -1, WBENCHSCREEN }; WIN *Win; RP *Rp; char FileName[128] = { "s:catalog.db" }; main() { char resized = 0; char notdone = 1; char movebox = 0; char moveslider = 0; char addactive = 0; char noload = 1; char dontquit = 0; char mmove = 0; short mmy; IMESS *im; openlibs(INTUITION_LIB|GRAPHICS_LIB); initslider(&Nw); Win = OpenWindow(&Nw); failfalse(Win, "Unable to open window"); Rp = Win->RPort; addmenus(); addgadgets(); again: for (; notdone || dontquit;) { if (dontquit) notdone = 1; dontquit = 0; WaitPort(Win->UserPort); while (im = GetMsg(Win->UserPort)) { switch(im->Class) { case NEWSIZE: resized = 1; break; case MOUSEBUTTONS: break; case MOUSEMOVE: mmove = 1; mmy = im->MouseY; break; case GADGETDOWN: { char *str = NULL; short sel; switch(getgadget(im, &sel, &str)) { case GAD_SLIDER: moveslider = 1; movebox = 0; sliderhit(); break; case GAD_BIGBOX: moveslider = 0; movebox = 1; bigboxhit(im->MouseY, 0); break; } } break; case GADGETUP: { char *str = NULL; short sel; switch(getgadget(im, &sel, &str)) { case GAD_INFO: { long fh = Open("raw:10/24/600/150/INFO", 1006); if (fh) { char buf[8]; fhprintf(fh, "\n\r\n\rVersion 1.1 Written by Matthew Dillon\n\r"); fhprintf(fh, "(c)Copyright 1987 Matthew Dillon, All Rights Reserved.\n\n\r"); fhprintf(fh, " dillon@ucbvax.berkeley.edu (ARPANET)\n\r"); fhprintf(fh, " ...!ihnp4!ucbvax!dillon (USENET)\n\r"); fhprintf(fh, "Matthew Dillon, 891 Regal Rd. Berkeley, Ca. 94708\n\n\r"); fhprintf(fh, "This software is freely redistributable only. This\n\r"); fhprintf(fh, "software is NOT shareware\n\n\r"); fhprintf(fh, "Thanks to Peter Da Silva for providing the filerequestor\n\r"); fhprintf(fh, "\n\n Any key to continue\n\r"); Read(fh, buf, 1); Close(fh); } } break; case GAD_DEL: rem_selected(Highlighted, 0); break; case GAD_UNDO: undo(); break; case GAD_ALL: selectall(); redisplay(0); break; case GAD_VOLUME: if (str[0]) add_volume(str); activate_vol(); break; case GAD_PATTERN: if (str[0]) { title("Wait"); select_pattern(str, 0); } activate_pat(); break; case GAD_COMMENT: mod_comment(str); break; case GAD_SLIDER: moveslider = 0; sliderhit(); break; case GAD_BIGBOX: movebox = 0; bigboxhit(im->MouseY, 1); break; } } break; case MENUPICK: switch(getmenu(im)) { case MEN_SAVE: { FILE *fi; if (noload && NumEntries == 0) { title("Did I just save you from making a mistake?"); break; } fi = fopen(FileName, "w"); if (fi) { save_database(fi); if (ferror(fi)) { title("File Error"); dontquit = 1; } else { title("Saved ok"); Modified = 0; } fclose(fi); } else { title("Unable to open file for write"); } } break; case MEN_SAVEAS: { FILE *fi; if (stdfile("SAVE DATABASE", FileName, "", FileName)) { noload = 0; if (fi = fopen(FileName, "w")) { save_database(fi); if (ferror(fi)) { title("File Error"); dontquit = 1; } else { title("Saved ok"); Modified = 0; } fclose(fi); } else { title("Unable to open file for write"); } } } break; case MEN_LOADEF: { FILE *fi = fopen(FileName, "r"); long entries = NumEntries; if (fi) { noload = 0; load_database(fi); if (!entries) Modified = 0; fclose(fi); } else { title("Unable to open file for read"); } } break; case MEN_LOAD: { FILE *fi; long entries = NumEntries; if (stdfile("LOAD DATABASE", FileName, "", FileName)) { noload = 0; if (fi = fopen(FileName, "r")) { load_database(fi); if (!entries) Modified = 0; fclose(fi); } else { title("Unable to open file for read"); } } } break; case MEN_QUIT: notdone = 0; break; case MEN_KILLPAT: resetsort(); addentry(KILLNAME, "", 0); select_pattern(KILLNAME, 0); break; } break; case CLOSEWINDOW: notdone = 0; break; } ReplyMsg(im); if (resized) { fixgadgets(); redisplay(0); } resized = 0; } if (mmove) { if (moveslider) sliderhit(); if (movebox) bigboxhit(mmy, 0); mmove = 0; } } if (Modified) { title("MODIFICATIONS MADE! HIT CLOSE-BOX AGAIN TO VERIFY"); Modified = 0; notdone = 1; goto again; } failfalse(NULL, NULL); } failfalse(val, str) long val; char *str; { if (val == NULL) { if (str) puts(str); if (Win) { remmenus(); remgadgets(); CloseWindow(Win); Win = NULL; } closelibs(-1); exit((str)? 1 : 0); } } failtrue(val, str) long val; char *str; { if (val) failfalse(NULL, str); } SHAR_EOF cat << \SHAR_EOF > memory.c /* * MEMORY.C * * (c)Copyright 1987 Matthew Dillon, All Rights Reserved. * */ #include "files.h" #define BLKSIZE 256 /* # of records to allocate at once */ #define STRBLKSIZE 4096 #define MAXSTRLEN 64 /* maximum string len for cached strings */ static RECORD *Freelist; static RECORD *Blk; static short Bi; static char *Strs[MAXSTRLEN]; static char *Sbuf; static short Si; RECORD * allocrecord() { register RECORD *rec; if (rec = Freelist) { Freelist = Freelist->next; return(rec); } if (!Bi) { Blk = (RECORD *)malloc(sizeof(RECORD) * BLKSIZE); if (!Blk) return(NULL); Bi = 256; } --Bi; return(Blk++); } void freerecord(rec) RECORD *rec; { rec->next = Freelist; Freelist = rec; } char * allocstr(str) char *str; { register short bytes = strlen(str) + 1; register char *ptr; if (bytes >= 4 && bytes < MAXSTRLEN) { if (Strs[bytes]) { ptr = Strs[bytes]; Strs[bytes] = *(char **)ptr; } else { bytes = (bytes + 1) & ~1; if (Si < bytes) { Sbuf = malloc(STRBLKSIZE); if (!Sbuf) return(NULL); Si = STRBLKSIZE; } ptr = Sbuf; Sbuf += bytes; Si -= bytes; } } else { ptr = malloc(bytes); if (!ptr) return(NULL); } strcpy(ptr, str); return(ptr); } void freestr(ptr) char *ptr; { register short len; if (ptr) { len = strlen(ptr) + 1; if (len >= 4 && len < MAXSTRLEN) { *(char **)ptr = Strs[len]; Strs[len] = ptr; } else { free(ptr); } } } SHAR_EOF cat << \SHAR_EOF > menu.c /* * MENU.C * * (c)Copyright 1987 Matthew Dillon, All Rights Reserved. * */ #include "files.h" #define NI 0 /* means 'not initialized' */ static ITEXT IText[] = { { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Save" }, { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"SaveAs" }, { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Load" }, { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"LoadDefault" }, { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Quit" }, { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"AddKillPat" }, }; static ITEM Item[] = { { &Item[1], 0, NI, NI, NI, 0, 0, (APTR)&IText[0], NULL }, { &Item[2], 0, NI, NI, NI, 0, 0, (APTR)&IText[1], NULL }, { &Item[3], 0, NI, NI, NI, 0, 0, (APTR)&IText[2], NULL }, { &Item[4], 0, NI, NI, NI, 0, 0, (APTR)&IText[3], NULL }, { NULL , 0, NI, NI, NI, 0, 0, (APTR)&IText[4], NULL }, { NULL , 0, NI, NI, NI, 0, 0, (APTR)&IText[5], NULL }, }; static MENU Menu[] = { { &Menu[1], NI, 0, NI, NI, NI, "Project" , NI }, { NULL , NI, 0, NI, NI, NI, "Control", NI } }; addmenus() { MENU *menu; ITEM *item, *nit; short left = 5; short height; short width; for (menu = Menu, item = Item; menu; menu = menu->NextMenu) { height = 0; width = strlen(menu->MenuName); menu->FirstItem = item; for (item = menu->FirstItem; item; item = item->NextItem) { if (width < strlen(((ITEXT *)item->ItemFill)->IText)) width = strlen(((ITEXT *)item->ItemFill)->IText); } width *= Win->RPort->TxWidth; for (item = menu->FirstItem; item; nit = item, item = item->NextItem) { item->Width = width; item->Height = Win->RPort->TxHeight + 2; item->TopEdge = height; item->Flags |= ITEMTEXT|ITEMENABLED|HIGHCOMP; height += item->Height; } menu->LeftEdge = left; menu->Width = width; menu->Height = height; menu->Flags = MENUENABLED; item = nit + 1; left += width + 4; } SetMenuStrip(Win, Menu); } remmenus() { ClearMenuStrip(Win); } getmenu(im) IMESS *im; { register short mn = MENUNUM(im->Code); register short in = ITEMNUM(im->Code); switch(mn) { case 0: switch(in) { case 0: return(MEN_SAVE); case 1: return(MEN_SAVEAS); case 2: return(MEN_LOAD); case 3: return(MEN_LOADEF); case 4: return(MEN_QUIT); } break; case 1: switch(in) { case 0: return(MEN_KILLPAT); } break; } return(0); } SHAR_EOF cat << \SHAR_EOF > newwildcmp.c /* * NEWWILDCMP.C * * (c)Copyright 1987 Matthew Dillon, All Rights Reserved. * * Compare a wild card name with a normal name * * This function replaces wildcmp() in SUP32.LIB (as not everybody will * have the latest SUP32.LIB). The only difference is that this call * is case insensitive. Later releases of SUP32.LIB will fix the * case-sensitive bug. */ #define MAXB 8 newwildcmp(wild, name) char *wild, *name; { register char *w = wild; register char *n = name; char *back[MAXB][2]; register short bi = 0; register char c1, c2; while (*n || *w) { switch (*w) { case '*': if (bi == MAXB) { puts ("Too many levels of '*'"); return (0); } back[bi][0] = w; back[bi][1] = n; ++bi; ++w; continue; goback: --bi; while (bi >= 0 && *back[bi][1] == '\0') --bi; if (bi < 0) return (0); w = back[bi][0] + 1; n = ++back[bi][1]; ++bi; continue; case '?': if (!*n) { if (bi) goto goback; return (0); } break; default: c1 = *n; c2 = *w; if (c1 >= 'A' && c1 <= 'Z') /* to lower case */ c1 |= 0x20; if (c2 >= 'A' && c2 <= 'Z') c2 |= 0x20; if (c1 != c2) { if (bi) goto goback; return (0); } break; } if (*n) ++n; if (*w) ++w; } return (1); } SHAR_EOF # End of shell archive exit 0