Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!mintaka!olivea!apple!vsi1!zorch!mykes From: mykes@zorch.SF-Bay.ORG (Mike Schwartz) Newsgroups: comp.sys.amiga.programmer Subject: Re: Good Programming stops guru |||| and BNF of C++ Message-ID: <1991Jan11.073543.16293@zorch.SF-Bay.ORG> Date: 11 Jan 91 07:35:43 GMT References: <1806@winnie.fit.edu> <658@tnc.UUCP> Organization: SF-Bay Public-Access Unix Lines: 135 I use Manx 'C' 3.6, so my advise may be limited to this environment. Manx supplies a routine called _abort() in the library which can be used to make programs that EASILY clean up after themselves. The routine is automatically called by the Manx debuggers anytime you want to abort the program in the middle of a debug session. The routine is also called when you hit ^C while the program is running. By supplying your own _abort() routine, you can override the one in the library and use it to your advantage. Consider the following code (I have something like it in every one of my 'C' programs): struct IntuitionBase *IntuitionBase = 0; struct GfxBase *GfxBase = 0; /* other libraries can be opened as well... */ struct Screen *screen = 0; struct Window *window = 0; int _abort_code = 0; _abort() { struct IntuiMessage *m; if (window) { while (m = (struct IntuiMessage *)GetMsg(window->UserPort)) ReplyMsg(m); CloseWindow(window); window = 0; } if (screen) { CloseScreen(screen); screen = 0; } if (GfxBase) { CloseLibrary(GfxBase); GfxBase = 0; } if (IntuitionBase) { CloseLibrary(IntuitionBase); IntuitionBase = 0; } exit(_abort_code); } panic(s, a1,a2,a3,a4,a5,a6,a7,a8) ULONG s,a1,a2,a3,a4,a5,a6,a7,a8; /* who cares what type they were... */ { printf(s, a1,a2,a3,a4,a5,a6,a7,a8); _abort_code = 999; _abort(); } panic0(v, s, a1,a2,a3,a4,a5,a6,a7,a8) ULONG s,a1,a2,a3,a4,a5,a6,a7,a8; /* ULONG can be int,short,byte, etc. */ { if (v) return; /* only panic if v is zero */ printf(s, a1,a2,a3,a4,a5,a6,a7,a8); _abort_code = 999; _abort(); } main() { IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 0); panic0(IntuitionBase, "Can't open intuition\n"); GfxBase = ... /* application goes here */ _abort(); /* _abort instead of exit */ } The code for panic shows how (using 32-bit INT model of Manx) you can make a printf() like routine without a lot of ugly looking code. The drawback is that you are pushing a lot of parameters in a lot of places. The code for panic0 shows a way to eliminate a lot of "if" statements from your source code, making a much more brief and readable program. The reason I set the things that _abort() cleans up back to zero is so that if I am using a debugger, or I make a bug that calls _abort() twice somehow, I can use the debugger to execute _abort() again without cleaning up things twice (it may not be too clear from my explanaition, so): You are in your debugger. You can just say "modify register PC = " _abort() and then GO and your program cleans up and exits. Some more tips... You should look at the fields in the Task structure. There are ways to eliminate most GURUs from happening if you install your own exception handler. The vast majority of GURUs are recoverable (merely an odd address or illegal instruction). If you make an exception handler, you can force the program to use your _abort() routine instead of the default "GURU" handlers which force you to reboot. I hate typing Intuition because I constantly misspell it (Intutition, etc.). I hate typing (struct anything *) to cast. I hate typing struct anything period. So what I did was to make an include file called "host.h" that looks something like this: typedef struct IntuitionBase IBASE; typedef struct GfxBase GBASE; typedef struct RastPort RPORT; typedef struct MessagePort MPORT; typedef struct Message MSG; typedef struct IntuiMessage IMSG; etc. I put all kinds of things in this file that I used to retype in many many times/programs. Now I can do: IBASE *IntuitionBase; msg = (MSG *)malloc(sizeof(MSG)); etc. Which is much easier to read and type. Another candidate for the host.h file is function declarations like: UBYTE *malloc(); and another is parameters to open() which I hate to type as well: #define O_READ O_RDONLY #define O_WRITE (O_WRONLY|O_CREAT|O_TRUNC) If you don't have powerwindows, get it. It is the fastest and most interactive way I've found to generate all those nasty intuition structures a program needs. I hope this is some help. Mykes