From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-059 Date: Mon, 19 Sep 1994 11:51:20 +0200 (MET DST) C.S.M.P. Digest Mon, 19 Sep 94 Volume 3 : Issue 59 Today's Topics: AppleGuide script examples anyone? Crazy error alert messages? Goto Pro's and Con's Need help with saving-writing structs to a file. PBCatSearch-catChangedErr PixToPic Slashed Progress Bar The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier (pottier@clipper.ens.fr). The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you may still be able to post messages to the group by using a mail server like anon.penet.fi (mail help@anon.penet.fi for more information). Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at nef.ens.fr). Article threads are not added to the digest until the last article added to the thread is at least two weeks old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The digest is officially distributed by two means, by email and ftp. If you want to receive the digest by mail, send email to listserv@ens.fr with no subject and one of the following commands as body: help Sends you a summary of commands subscribe csmp-digest Your Name Adds you to the mailing list signoff csmp-digest Removes you from the list Once you have subscribed, you will automatically receive each new issue as it is created. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest. Questions related to the ftp site should be directed to scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP digest are available there. Also, the digests are available to WAIS users. To search back issues with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html. ------------------------------------------------------- >From d.a.davies@bham.ac.uk (David Davies) Subject: AppleGuide script examples anyone? Date: Thu, 01 Sep 1994 14:27:20 +0000 Organization: Birmingham University, UK. Has anyone had a go at writing scripts for AppleGuide? Would anyone mind showing me just the simplest example if they have one. I've seen lots of compiled guides working but not seen the source for any as yet. I have a version of GuideMaker from one of the 7.5 beta CDs and I wanted to have a go at making a Guide myself... Thanks, -- David Davies Department of Physiology, University of Birmingham, UK. Tel: 021 414 3255 Fax: 021 414 6924 http://medweb.bham.ac.uk/http/signatures/davies.html +++++++++++++++++++++++++++ >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!") Date: Fri, 02 Sep 1994 11:58:43 +0800 Organization: Department of Computer Science, The University of Western Australia In article , d.a.davies@bham.ac.uk (David Davies) wrote: >Has anyone had a go at writing scripts for AppleGuide? Yes (: >Would anyone mind showing me just the simplest example if they have one. [Well it's not simple but it is comprehensive.] I just posted the source code to the Anarchie Guide to MacGifts, so it should show up on UMich and Info-Mac mirrors soon. Here are the blurb I attached to the MacGifts mailing... >Attached is the Anarchie Guide source code distribution. Anarchie Guide >is one of the first publically available guides and I decided to make its >source code available for two reasons. Firstly it¹s very hard to localise >a guide without source code. Secondly there is no publically available >guide source code and I thought it would be a good chance to rectify that. > >You need GuideMaker to be able to build this source however the source >code files are text files and you can browse them with any text editor. For those of you too excited to wait, you can FTP it from... ftp://redback.cs.uwa.edu.au/Others/Quinn/ Share and Enjoy. -- Quinn "The Eskimo!" "Scout in a can. Simple, cheap, easy to use and it's expendable!" Now if only Redback would stay up for more than 5 minutes, huh Pete? --------------------------- >From rtmd30@email.sps.mot.com (Greg Ferguson) Subject: Crazy error alert messages? Date: Tue, 23 Aug 1994 20:45:12 GMT Organization: Motorola, Inc. Hi, We're looking for some ideas for out-of-the-ordinary Alert messages. My manager suggested the following one day: I suggest that we use this as the standard unanticipated error message in all applications that we develop. That is, after analyzing all know error conditions (which hopefully would present a relevant error message), display the following message as a last resort: AN ERROR HAS JUST OCCURRED WHICH WAS PREVIOUSLY THOUGHT TO BE IMPOSSIBLE. (taken from an old mainframe manual) This is for those "we're going to crash if you do that again" type situations. BTW, we can afford to be a bit frivolous as this is for in-house and test code. :-) Thanks, Greg -- Greg Ferguson rtmd30@email.sps.mot.com +++++++++++++++++++++++++++ >From Jeff Abrahamson Date: Wed, 24 Aug 94 08:18:36 -0500 Organization: Purple In article , Greg Ferguson writes: > We're looking for some ideas for out-of-the-ordinary Alert messages. > > My manager suggested the following one day: > > I suggest that we use this as the standard unanticipated error message in > all applications that we develop. That is, after analyzing all know error > conditions (which hopefully would present a relevant error message), > display the following message as a last resort: > > AN ERROR HAS JUST OCCURRED WHICH WAS PREVIOUSLY THOUGHT TO BE IMPOSSIBLE. > > (taken from an old mainframe manual) > > This is for those "we're going to crash if you do that again" type situations. > > BTW, we can afford to be a bit frivolous as this is for in-house and test > code. :-) Well, then, how about: A subspace error (-129937) has occurred. Please check this universe for consistency. or An ATSM error has occurred. Please quit as soon as possible to avoid previous crashes. [ATSM is the Advanced Time Services Manager. It was discussed either here in a previous thread or on the CW mailing list. Jens Alfke has most thoroughly documented its use. :-) ] -Jeff Abrahamson clio!jeff@vu-vlsi.ee.vill.edu +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Wed, 24 Aug 1994 15:18:50 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) How about: "Yours is the only Macintosh this error ever occurred on." "Please report what you did to cause it to Apple." or: "It broke!" or: "Why should I tell YOU what there error number was?" "You'll never be able to correct it!" "Try that again and you'll be ordered to use IBM's for 6 months" All seriousness aside... -Ken- +++++++++++++++++++++++++++ >From ogawa@teleport.com (Arthur Ogawa) Date: Wed, 24 Aug 94 21:25:02 GMT Organization: TeX Consultants In Article <94082408183600240@purple.com>, Jeff Abrahamson wrote: > >In article , Greg Ferguson writes: > >> We're looking for some ideas for out-of-the-ordinary Alert messages. [deleted] Here's one from TeX, by Donald Knuth: "This can't happen" Arthur Ogawa, TeX Consultants, Kaweah CA 93237-0051 Ph: 209/561-4585, FAX: -4584 PGP Key: finger -l ogawa@teleport.com +++++++++++++++++++++++++++ >From spencerl@crl.com (Spencer Low) Date: Wed, 24 Aug 1994 16:45:44 -0800 Organization: LowTek Creations In article <94082408183600240@purple.com>, clio!jeff@vu-vlsi.ee.vill.edu wrote: > A subspace error (-129937) has occurred. Please check > this universe for consistency. Of course, you could also include the following one (for you develop readers): A subspace error (-16.7 * 10^6) has occured. pi does *not* equal 3.141592654. Please make sure your universe is in existance. Spencer ________________________________________________________________________ Spencer "MaxRAM" Low ------ LowTek Creations ----- spencerl@crl.com +++++++++++++++++++++++++++ >From Manuel Veloso Date: Fri, 26 Aug 1994 06:11:38 GMT Organization: Ibex Productions In article Greg Ferguson, rtmd30@email.sps.mot.com writes: >We're looking for some ideas for out-of-the-ordinary Alert messages. Why not just use the simple, yet poignant, "Whoops!" or the more minimal message from mpw gcc "Ack!" or the ultimate testing message from Radiation, "Warning! The radiation shield on your Macintosh has failed. Please step back 5 feet." +++++++++++++++++++++++++++ >From goo@cwis.unomaha.edu (Kent Radek) Date: 27 Aug 94 03:19:27 GMT Organization: University of Nebraska Omaha I once got a message like this in the CodeWarrior debugger: "An error #-930 has occurred, because an error occurred." goo +++++++++++++++++++++++++++ >From reinder@neuretp.biol.ruu.nl (Reinder Verlinde) Date: Wed, 31 Aug 1994 14:41:13 GMT Organization: Rijksuniversiteit Utrecht How about: "The item could not be deleted because it doesn't exist" (Macintosh Finder) or: "numeric constant too long (> 255 characters)" (MPW C++) "too many errors on one line. Use fewer" "This union already has a perfectly good definition" "This struct already has a perfectly good definition" "This array has no size, and that's bad" "Only one parameter per register please" "a typedef name was a complete surprise to me at this point in your program" "type in (cast) must be scalar; ANSI 3.3.4; page 39, lines 10-11 (I know you don't care, I'm just trying to annoy you)" "Call me paranoid but finding '/*' inside this comment makes me suspicious" "Trailing comma not permitted in enum definition. (This time I'm letting you off with a warning)" "This function has an explicit return type and deserves a return value" "...And the lord said, 'lo, there shall only be case or default labels inside a switch statement'" "Symbol table full - fatal heap error; please go buy a RAM upgrade from your local Apple dealer" "String literal too long (I let you have 512 characters, that's 3 more than ANSI said I should)" "This label is the target of a goto from outside of the block containing this label AND this block has an automatic variable with an initializer AND your window wasn't wide enough to read this whole error message" (all from MPW C) reinder@neuretp.biol.ruu.nl (Reinder Verlinde) +++++++++++++++++++++++++++ >From deanp@zikzak.apana.org.au (Dean Perry) Date: 4 Sep 1994 04:29:15 GMT Organization: Zikzak public access UNIX, Melbourne Australia Greg Ferguson (rtmd30@email.sps.mot.com) wrote: : We're looking for some ideas for out-of-the-ordinary Alert messages. This one, hijacked from an old (85?) BMUG newsletter (ish) "Really spin the hard disk at 90000 rpm?" dean -- Zikzak public access UNIX, Melbourne, Australia. +++++++++++++++++++++++++++ >From deanp@zikzak.apana.org.au (Dean Perry) Date: 5 Sep 1994 14:22:48 GMT Organization: Zikzak public access UNIX, Melbourne Australia Or this cutie, from MacApp this evening: Could not complete the command "x" because "class", an internal component is missing. Call Apple for a secret decoder ring. dean (again) -- Zikzak public access UNIX, Melbourne, Australia. --------------------------- >From steven.webber@digitec.co.za (Steven Webber) Subject: Goto Pro's and Con's Date: 23 Aug 94 23:21:00 GMT Organization: Digitec Online Hi there. I've got a question for all you programmers out there. Do you use goto's in your code? Do you think using Goto's is a bad or good idea? Why do you like/dislike using them? Everybodies ideas would be most welcome. Thanks Steven. Steven.Webber@Digitec.co.za ___ Blue Wave/QWK v2.12 OS/2 - -- - - Digitec Online --- Johannesburg, South Africa --- tel +27 11 476-2008 --- - - You can TELNET Africa's biggest and most popular BBS on 196.11.62.106 --- +++++++++++++++++++++++++++ >From s3026557@titanic.mpce.mq.edu.au (Duncan Anker) Date: 24 Aug 1994 10:04:44 GMT Organization: Macquarie University, School of Mathematics, Physics, Computing and Electronics Steven Webber (steven.webber@digitec.co.za) wrote: : Hi there. : I've got a question for all you programmers out there. : Do you use goto's in your code? : Do you think using Goto's is a bad or good idea? : Why do you like/dislike using them? : Everybodies ideas would be most welcome. Thou shalt not use gotos. Neither shalt thou abolish them entirely. Personally, I don't use them, although they can be useful when escaping from error situations in deeply nested code (or so I've heard). If you find yourself using gotos, consider rewriting your functions. :-) cheers. -- s3026557@titanic.mpce.mq.edu.au * Duncan Anker * e3026557@hardy.ocs.mq.edu.au If you're a horse, and someone gets on you, and falls off, and then gets right back on you, I think you should buck him off right away. +++++++++++++++++++++++++++ >From eascharf@u.washington.edu (Elizabeth Scharf) Date: 24 Aug 1994 13:59:22 GMT Organization: University of Washington, Seattle I am fairly partial to break/continue statements for making loop execution easier to read. I also use goto for error handling in some routines, but with several restrictions, like only one label per routine called "CleanUp:" and only one return point which is after CleanUp. I try to write code that can determine its error state and what needs cleaning up at the end so as to make the goto basically like the end of a bunch of if statements, but without the code waterfall. Other than that, I try to avoid them because they make things harder to read and maintain. Donald Knuth presents several examples where using gotos are beneficial, usually for algorithm optomization (see Knuth, "Literate Programming") A good read in any case. rmgw This is not my account: Please address replies to hawkfish@aol.com Disclaimer: All views expressed are entirely my own and do not reflect the opinions of Elizabeth Scharf or the University of Washington. - --------------------------------------------------------------------------- Richard Wesley | "No, No No, 'Eureka' is Greek; it means 'This hawkfish@aol.com | bath is too hot'" 71062.1711@compuserve.com | - Dr. Who - --------------------------------------------------------------------------- +++++++++++++++++++++++++++ >From dennis@mr2.ece.cmu.edu (Dennis J. Ciplickas) Date: 24 Aug 1994 14:25:39 GMT Organization: Electrical and Computer Engineering, Carnegie Mellon In article <300.310.uupcb@digitec.co.za> steven.webber@digitec.co.za (Steven Webber) writes: >Hi there. >I've got a question for all you programmers out there. >Do you use goto's in your code? >Do you think using Goto's is a bad or good idea? >Why do you like/dislike using them? (You didn't specify which language you were thinking about, but I'll assume C.) I regularly use an "error exit" goto construct in my C code because it's just too damn difficult to unravel yourself at each point where you might need to exit. A common example is in a routine that must allocate a few different items, and if any one of them fails you complain to the user and quit. For example: OSErr Allocater(void) { OSErr err; Handle h1,h2; Ptr p1,p2; // null out our block pointers so that if we have to leave // prematurely, only those that actually got allocated get // deallocated. h1 = h2 = NULL; p1 = p2 = NULL; // now allocate all the blocks if (!(h1 = NewHandle(10))) { err = MemError(); showerror(1,"Memory Error %d allocating h1."); goto errexit; } if (!(h2 = NewHandle(20))) { err = MemError(); showerror(1,"Memory Error %d allocating h2."); goto errexit; } if (!(p1 = NewPtr(10))) { err = MemError(); showerror(1,"Memory Error %d allocating p1."); goto errexit; } if (!(p2 = NewPtr(10))) { err = MemError(); showerror(1,"Memory Error %d allocating p2."); goto errexit; } // then do some work. ... if (err = DoSomethingElse(h1,h2)) goto errexit; ... err = noErr; // deallocate and leave errexit: if (h1) DisposHandle(h1); if (h2) DisposHandle(h2); if (p1) DisposPtr(p1); if (p2) DisposPtr(p2); return err; } -Dennis +++++++++++++++++++++++++++ >From pcastine@prz.tu-berlin.de (Peter Castine) Date: Wed, 24 Aug 1994 15:24:35 GMT Organization: Process Control Center In article <300.310.uupcb@digitec.co.za>, steven.webber@digitec.co.za (Steven Webber) wrote: > Hi there. > > I've got a question for all you programmers out there. > > Do you use goto's in your code? > > Do you think using Goto's is a bad or good idea? > > Why do you like/dislike using them? > > Everybodies ideas would be most welcome. Haven't used a goto since I stopped programming in BASIC (which was when I bought my own Mac in '86). Actually, the last BASIC I used (BBC BASIC on an Acorn Beeb) let me avoid GOTOs _almost_ entirely, so add a few years. The problems with GOTO are discussed thoroughly in Anthony Hoare's seminal paper ``GOTO cosidered dangerous'' (Sorry, I don't have the complete reference) and in every book on structured programming techniques written since. Essentially, there is nothing you can do with GOTO you can't do with procedure calls, stuctured loops, and if-then-else constructs. Structured code is generally easier to read and understand (and, hence, easier to modify without causing it to stop working). There are some exceptional situations where GOTOs may make sense (C's break, continue, and exit statements are semi-structured GOTOs in disguise; in other languages you might use a GOTO where you'd see a break in C). -- Peter Castine | C (n.): A programming language that is sort of pcastine@prz.tu-berlin.de | like Pascal except more like assembly except Process Control Center | that it isn't very much like either one, or Technical University Berlin | anything else. -- Ray Simard +++++++++++++++++++++++++++ >From Darrin Cardani Date: Wed, 24 Aug 1994 13:31:38 GMT Organization: AT&T Global Information Solutions, Atlanta >In article <300.310.uupcb@digitec.co.za> Steven Webber writes: >Hi there. > >I've got a question for all you programmers out there. > >Do you use goto's in your code? Occasionally. The only time I really use them (well, in non-BASIC programming ;) is for error handling. I often have a set of Sound Manager calls that look something like this: { SndError = SndManagerCall1 (blah); if (SndError != noError) goto Cleanup; SndError = SndManagerCall2 (blah); if (SndError != noError) goto Cleanup; ..etc... return (noError); Cleanup: } >Do you think using Goto's is a bad or good idea? In general I use the control structures provided by the language since that's what they were made for. They're a bad idea if they obscure your code and don't add anything to it. I think in the above, it saves space and is pretty clear. Darrin +++++++++++++++++++++++++++ >From jwbaxter@olympus.net (John W. Baxter) Date: Wed, 24 Aug 1994 08:17:32 -0700 Organization: Internet for the Olympic Peninsula In article <300.310.uupcb@digitec.co.za>, steven.webber@digitec.co.za (Steven Webber) wrote: > Hi there. > > I've got a question for all you programmers out there. > > Do you use goto's in your code? I use them when I feel they are the cleanest solution to a dirty problem. As Sean mentioned, error handling can be one such, in a language such as see which doesn't provide something better. C++ with exceptions offers something better...too bad it doesn't exist yet in many compilers. > Do you think using Goto's is a bad or good idea? > Why do you like/dislike using them? The cost of software is more in the maintenance than in the original coding. Uncontrolled use of gotos usually makes the maintenance more expensive (and sometimes essentially impossible: it's cheaper to start fresh), because it tends to make the code hard to read (for a human...the compiler does fine). On the other hand, dirty tricks to avoid gotos has a similar effect...the code is hard to maintain. But what do I know???...I've only been doing this since the late 1950s (and not continuously during that time). --John -- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound] "Occasionally...astronomers add a second to either June 31 or December 31..." IM: OS Utilities, p 4-12 jwbaxter@pt.olympus.net +++++++++++++++++++++++++++ >From h+@nada.kth.se (Jon W{tte) Date: Wed, 24 Aug 1994 23:10:27 +0200 Organization: Royal Institute of Something or other In article <300.310.uupcb@digitec.co.za>, steven.webber@digitec.co.za (Steven Webber) wrote: >Do you use goto's in your code? Yes. >Do you think using Goto's is a bad or good idea? >Why do you like/dislike using them? Sometimes they help structure code immensely, like when you test for pre-conditions and want to take an early exit, but still clean up stuff. Also for "retry" kinds of things it's much simpler and easier on the eyes with a strategically-placed goto. C++ stack-based objects help reduce gotos, but not eliminate them totally. The controversy these days is on non-local gotos, like longjmp() and C++ try/catch exceptions. I tend to like these as well, but they _do_ add a need for careful structuring in order to be used cleanly and effectively. -- Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden "Don't use the Layer Manager" +++++++++++++++++++++++++++ >From bootstrap1@aol.com (Bootstrap1) Date: 24 Aug 1994 17:40:16 -0400 Organization: America Online, Inc. (1-800-827-6364) In article , dennis@mr2.ece.cmu.edu (Dennis J. Ciplickas) writes: > I regularly use an "error exit" goto construct in my C > code because it's just too damn difficult to unravel yourself at each > point where you might need to exit. A common example is in a routine > that must allocate a few different items, and if any one of them fails > you complain to the user and quit. For example: While I think it is fine to use a goto construct in a well structured way such as you illustrate in your example, I still never use them myself. As with using continue and break in loops and return in the middle of functions, I find it makes the flow of a function more difficult to follow. Knowing that a function starts executing at the top and falls straight through all the way to the bottom makes debugging and reading code much easier, at least for me. And you can still avoid having to unravel on reaching an error conditions, as well as the dreaded "code waterfall" someone else mentioned, without using gotos, as the following edit of your sample shows OSErr Allocater(void) { OSErr err; Handle h1,h2; Ptr p1,p2; // null out our block pointers so that if we have to leave // prematurely, only those that actually got allocated get // deallocated. h1 = h2 = NULL; p1 = p2 = NULL; h1 = NewHandle(10); if ((err = MemError()) != noErr) showerror(1,"Memory Error %d allocating h1."); if (err == noErr) { h2 = NewHandle(20); if ((err = MemError()) != noErr) showerror(1,"Memory Error %d allocating h2."); } if (err == noErr) { p1 = NewPtr(10); if ((err = MemError()) != noErr) showerror(1,"Memory Error %d allocating p1."); } if (err == noErr) { p2 = NewPtr(10); if ((err = MemError()) != noErr) showerror(1,"Memory Error %d allocating p2."); } // then do some work. ... if (err == noErr) err = DoSomethingElse(h1,h2); if (err != noErr) { // deallocate if (h1) DisposHandle(h1); if (h2) DisposHandle(h2); if (p1) DisposPtr(p1); if (p2) DisposPtr(p2); } return err; } +++++++++++++++++++++++++++ >From howard@netcom.com (Howard Berkey) Date: Wed, 24 Aug 1994 22:42:04 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) In article <300.310.uupcb@digitec.co.za>, Steven Webber wrote: >Hi there. > >I've got a question for all you programmers out there. > >Do you use goto's in your code? > Oh, about as often as longjmp() :-) >Do you think using Goto's is a bad or good idea? > I can think of very few situations that require them, if any. One might be removal of recursion in a routine that would be uglier to do in any other way. *might* be. 99% of the time continue or break work as well or better in the remaining situations. >Why do you like/dislike using them? > It decreases readability of your code, complicates flow, is ugly, and makes your co-workers laugh at you. It makes bugs potentially harder to find. It is usually done as a quick hack or kludge (IOW it probably introduces a new bug). -H- -- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Howard Berkey howard@netcom.com Segmentation Fault (core dumped) +++++++++++++++++++++++++++ >From hulburt@leland.stanford.edu (Greg Payne) Date: 25 Aug 1994 02:29:26 GMT Organization: Stanford University In article <300.310.uupcb@digitec.co.za> steven.webber@digitec.co.za (Steven Webber) writes: > Hi there. > > I've got a question for all you programmers out there. > > Do you use goto's in your code? > > Do you think using Goto's is a bad or good idea? > > Why do you like/dislike using them? > > Everybodies ideas would be most welcome. > > Thanks > Steven. > Well, here is my 2 cents: I personally dont use gotos (too many people said they were bad in all my cs classes). I supposed they have their place, but they can really make code hard to understand. I translated an airfoil code from fortran to c, and it really wasn't documented too well. I did know most of the general method, through, but it was a real pain going through goto-loops that wandered all over the place to do the same thing a switch or if then else in c. Unless it is to get out of a deeply nest loop or for error-handling, I'd say they are probably bad programming. Greg Payne greg@aerometrics.com +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Thu, 25 Aug 1994 19:18:17 +1200 (NZST) Organization: (none) steven.webber@digitec.co.za (Steven Webber) writes: > I've got a question for all you programmers out there. > > Do you use goto's in your code? In assembler: all the time. In C or Pascal: I don't remember the last time. 10 years ago? You don't need them. -- Bruce +++++++++++++++++++++++++++ >From radixinc@aol.com (RadixInc) Date: 25 Aug 1994 15:53:01 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2860687096@hoult.actrix.gen.nz>, Bruce@hoult.actrix.gen.nz (Bruce Hoult) writes: <> In C, I use goto once in a while for one purpose only: to get out of a loop or deep if... structure when something awful happens. I used to write the gotos myself, but I've been using the exception-handling macros that were in a "d e v e l o p" article a few issues back, and they look like function calls, even though they turn into gotos. If I had real exception handling I wouldn't need to use goto at all, though there is something nice about having the error handling and recovery/cleanup code in the same function that generates the error. I used gotos once before to write a state-machine parser, but again I had macros to hide the goto/label stuff. This technique was discussed in "Computer Language" magazine, May 1991, and it worked out very well. There are times when goto is the best and cleanest way to do something, but you have to discipline yourself to use goto only when you are convinced that there is no cleaner way to go. I've yet to see a decent C programmer use goto in the offhand way a lot of BASIC programmers use it. A lot of the anti-goto sentiment comes out of Wirth's article "GOTO considered harmful," and he was referring to languages current at the time: PL/I, Fortran, and most of all BASIC. The typical Pascal book (including Wirth's) rail against goto, but he also acknowledges the (rare) necessity of it, because Pascal does after all implement goto. For example, removing tail recursion from algorithms like Quicksort is arguably best done with a goto, even in Pascal. (Of course there are other ways to do this; please don't assail me with goto-less Quicksorts). Wirth is right about the careless and unnecessary use of goto common in Fortran, BASIC, and PL/I, but those languages don't (or didn't at the time) have the control structures needed to obviate the use of goto. In modern languages, and modern implementations of Fortran and BASIC, the goto is mostly unnecessary, as it is in C and Pascal. Gregory Jorgensen Radix Consulting Inc. +++++++++++++++++++++++++++ >From alexr@apple.com (Alexander M. Rosenberg) Date: Thu, 25 Aug 1994 21:26:02 GMT Organization: Hackers Anonymous In article <300.310.uupcb@digitec.co.za>, steven.webber@digitec.co.za (Steven Webber) wrote: > I've got a question for all you programmers out there. > > Do you use goto's in your code? > > Do you think using Goto's is a bad or good idea? > > Why do you like/dislike using them? Read Literate Programming by Donald Knuth. It includes an updated version of an old paper of his on this topic. I think that it should answer your questions quite nicely. (And it explained all those stupid looping constructs that Pascal has.) - ------------------------------------------------------------------------- - Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne - - 330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr - Propulsion - - Palo Alto, CA 94301 - - Systems - - (415) 329-8463 - Nobody is my employer so - :-) - - (408) 974-3110 - nobody cares what I say. - - +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Fri, 26 Aug 1994 11:25:15 +1200 (NZST) Organization: (none) bootstrap1@aol.com (Bootstrap1) writes: > While I think it is fine to use a goto construct in a well structured way > such as you illustrate in your example, I still never use them myself. As > with using continue and break in loops and return in the middle of > functions, I find it makes the flow of a function more difficult to > follow. Knowing that a function starts executing at the top and falls > straight through all the way to the bottom makes debugging and reading > code much easier, at least for me. And you can still avoid having to > unravel on reaching an error conditions, as well as the dreaded "code > waterfall" someone else mentioned, without using gotos, as the following > edit of your sample shows A agree with your points, but dislike all the extra testing of err (both in error and normal situations) in your solution, and you're *still* obscuring the main flow of control in the normal situation. I much prefer a "block" that uses break to exit when there is an error. Yes, I read your comment about break, and disagree. Unfortunately, C and Pascal don't have a construct with this purpose, but one can easily be faked using "repeat until true" or "do { } while (0)"... To further mangle this eample code: OSErr Allocater(void) { OSErr err; Handle h1,h2; Ptr p1,p2; // null out our block pointers so that if we have to leave // prematurely, only those that actually got allocated get // deallocated. h1 = h2 = NULL; p1 = p2 = NULL; do { // once only for error checking h1 = NewHandle(10); if ((err = MemError()) != noErr){ showerror(1,"Memory Error %d allocating h1."); break; } h2 = NewHandle(20); if ((err = MemError()) != noErr){ showerror(1,"Memory Error %d allocating h2."); break; } p1 = NewPtr(10); if ((err = MemError()) != noErr){ showerror(1,"Memory Error %d allocating p1."); break; } p2 = NewPtr(10); if ((err = MemError()) != noErr){ showerror(1,"Memory Error %d allocating p2."); break; } // then do some work. ... err = DoSomethingElse(h1,h2); } while (0); if (err != noErr) { // deallocate if (h1) DisposHandle(h1); if (h2) DisposHandle(h2); if (p1) DisposPtr(p1); if (p2) DisposPtr(p2); } return err; } +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 26 Aug 1994 03:40:36 GMT Organization: The University of Texas at Austin, Austin, Texas In article , dennis@mr2.ece.cmu.edu (Dennis J. Ciplickas) wrote: > In article <300.310.uupcb@digitec.co.za> steven.webber@digitec.co.za (Steven Webber) writes: > >Hi there. > >I've got a question for all you programmers out there. > >Do you use goto's in your code? > >Do you think using Goto's is a bad or good idea? > >Why do you like/dislike using them? > > (You didn't specify which language you were thinking about, but I'll > assume C.) I regularly use an "error exit" goto construct in my C > code because it's just too damn difficult to unravel yourself at each > point where you might need to exit. A common example is in a routine > that must allocate a few different items, and if any one of them fails > you complain to the user and quit. For example: > [code chopped] > -Dennis The fact is that memerrors aren't fatal. there's nothing wrong with something like the following: OSErr Allocater(void) { OSErr err; Handle h1,h2; Ptr p1,p2; h1 = NewHandle( 10 ); h2 = NewHandle( 20 ); p1 = NewPtr( 10 ); p2 = NewPtr( 10 ); if ( noErr != ( err = MemError() ) ) { // then do some work. } else { //report your errors } if ( h1 ) DisposHandle( h1 ); if ( h2 ) DisposHandle( h2 ); if ( p1 ) DisposPtr( p1 ); if ( p2 ) DisposPtr( p2 ); return err; } While I won't categorically say that gotos are evil, I haven't used one since I gave up Fortran. -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From radixinc@aol.com (RadixInc) Date: 26 Aug 1994 00:35:04 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <33isqt$sie@search01.news.aol.com>, radixinc@aol.com (RadixInc) writes: <> As one polite person pointed out to me by email, the paper "GOTO Considered Harmful" was written be Edsger Dijkstra, not Niklaus Wirth. I always get them confused--they both have unpronouncable last names. I believe Dijkstra's paper appeared in the CACM, but I don't have it. My point remains the same, only that perhaps Dijkstra is a bit more adamant about not using GOTO than Wirth. Gregory Jorgensen Radix Consulting Inc. +++++++++++++++++++++++++++ >From radixinc@aol.com (RadixInc) Date: 26 Aug 1994 02:59:05 -0400 Organization: America Online, Inc. (1-800-827-6364) In article , dennis@mr2.ece.cmu.edu (Dennis J. Ciplickas) wrote: << I regularly use an "error exit" goto construct in my C code because it's just too damn difficult to unravel yourself at each point where you might need to exit.>> There's a good article in "d e v e l o p," August 1992, called "Living In An Exceptional World" by Sean Parent. He proposes an elegant mechanism for handling exceptions with macros, including clean-up and recovery. His technique uses macros that resolve to gotos, but it keeps the source code clean. I've been using these macros for a year or so, and I haven't had to use an actual goto since. Check it out. Gregory Jorgensen Radix Consulting Inc. +++++++++++++++++++++++++++ >From dennis@mr2.ece.cmu.edu (Dennis J. Ciplickas) Date: 26 Aug 1994 16:07:46 GMT Organization: Electrical and Computer Engineering, Carnegie Mellon In article <33geo0$5h3@search01.news.aol.com> bootstrap1@aol.com (Bootstrap1) writes: >In article , dennis@mr2.ece.cmu.edu >(Dennis J. Ciplickas) writes: >> I regularly use an "error exit" goto construct in my C >> code because it's just too damn difficult to unravel yourself at each >> point where you might need to exit. A common example is in a routine >> that must allocate a few different items, and if any one of them fails >> you complain to the user and quit. For example: >>[code deleted] > >While I think it is fine to use a goto construct in a well structured way >such as you illustrate in your example, I still never use them myself. As >with using continue and break in loops and return in the middle of >functions, I find it makes the flow of a function more difficult to >follow. Knowing that a function starts executing at the top and falls >straight through all the way to the bottom makes debugging and reading >code much easier, at least for me. And you can still avoid having to >unravel on reaching an error conditions, as well as the dreaded "code >waterfall" someone else mentioned, without using gotos, as the following >edit of your sample shows >[code removed] I understand your desire to keep the code readable, but in all honesty, the sample code you provided was difficult to read. Not to mention it relies on the compiler to optimize away all of the redundant checks on the err vaiarble. To the original poster: in my mind, it comes down to this. If using a goto will make the code MORE readable and MORE maintainable, then go for it. If it will obscure the flow of the code then don't. FORTRAN did not give programmers good methods for dealing with code structure (e.g. break, continue, etc.), only giving them the infamous GOTO to implement such a flow. Misuse of GOTO ended up obscuring the program flow. If I were to go out on a limb, I'd say that improper indentation makes code unreadable (and hence more difficult to maintain) more than the goto construct I presented. (Of course, FORTRAN had stringent column requirements, too, so it was also bogus in this respect.) Just my $0.02. -Dennis +++++++++++++++++++++++++++ >From Kevin.R.Boyce@gsfc.nasa.gov (Kevin R. Boyce) Date: Fri, 26 Aug 1994 12:47:08 -0400 Organization: NASA Goddard Space Flight Center -- Greenbelt, Maryland USA In article <33jrdo$95h@search01.news.aol.com>, radixinc@aol.com (RadixInc) wrote: >In article <33isqt$sie@search01.news.aol.com>, radixinc@aol.com (RadixInc) >writes: > ><considered harmful,...>> > >As one polite person pointed out to me by email, the paper "GOTO >Considered Harmful" was written be Edsger Dijkstra, not Niklaus Wirth. I >always get them confused--they both have unpronouncable last names. I >believe Dijkstra's paper appeared in the CACM, but I don't have it. >From Jargon File 3.0.0: :considered harmful: adj. Edsger W. Dijkstra's note in the March 1968 "Communications of the ACM", "Goto Statement Considered Harmful", fired the first salvo in the structured programming wars. Amusingly, the ACM considered the resulting acrimony sufficiently harmful that it will (by policy) no longer print an article taking so assertive a position against a coding practice. In the ensuing decades, a large number of both serious papers and parodies have borne titles of the form "X considered Y". The structured-programming wars eventually blew over with the realization that both sides were wrong, but use of such titles has remained as a persistent minor in-joke (the `considered silly' found at various places in this lexicon is related). -- Kevin Kevin.R.Boyce@gsfc.nasa.gov What may appear to the faint-hearted as a limitless expanse of God-forsaken wilderness is in reality a golden opportunity for ourselves, and our children, and our children's children, and the generations a-comin' to carve a new life out of the American Indian. --Firesign Theatre +++++++++++++++++++++++++++ >From walkerj@math.scarolina.edu (James W. Walker) Date: 26 Aug 1994 17:25:30 GMT Organization: Dept. of Mathematics, Univ. of South Carolina In article <33k3rp$b4v@search01.news.aol.com>, radixinc@aol.com (RadixInc) wrote: > There's a good article in "d e v e l o p," August 1992, called "Living In > An Exceptional World" by Sean Parent. He proposes an elegant mechanism for > handling exceptions with macros, including clean-up and recovery. His > technique uses macros that resolve to gotos, but it keeps the source code > clean. I've been using these macros for a year or so, and I haven't had to > use an actual goto since. Check it out. I use those macros too. However, I renamed his "nrequire" as "forbid". I find it easier to read actual English words. -- Jim Walker +++++++++++++++++++++++++++ >From hanrek@cts.com (Mark Hanrek) Date: 26 Aug 1994 18:31:38 GMT Organization: The Information Workshop If one is using a modern language, the "rule" to not use goto's is meaningless. It was a rule meant to deter "spaghetti code", because it was so easy to create a tangled web. With today's languages, we create messes of a different kind. The right thing to do, regardless, is to imitate the constructs and structuring we find in good example source code. Whether we code a "break", a "try/catch", or "goto", we are doing it because it is the appropriate thing to do. Hope this helps. Mark Hanrek +++++++++++++++++++++++++++ >From urge@mcl.ucsb.edu (Scott Bronson) Date: 27 Aug 1994 23:27:35 GMT Organization: University of California, Santa Barbara In Jaeger@fquest.com (Brian Stern) writes: >The fact is that memerrors aren't fatal. there's nothing wrong with >something like the following: > h1 = NewHandle( 10 ); > h2 = NewHandle( 20 ); > p1 = NewPtr( 10 ); > p2 = NewPtr( 10 ); > if ( noErr != ( err = MemError() ) ) { /* do something */ } Well, there's nothing wrong with *your* code, but there's a serious flaw in this technique. What about this: h1 = NewHandle( 30 ), h2 = NewHandle( 10 ); If there are 26 bytes of memory free, h2 will be a vaild handle and MemError() is going to report noErr because the last memory allocation succeeded. However, h1 will be nil! If you do your memory allocations from smallest to largest, you will probably be OK. However, heap fragmentation can still cause some unexpected surprises when mixing the allocation of pointers and handles. So, even though this works, I hope that no programmers rely on it unless they're sure they know EXACTLY what they're doing. Personally, I shun it--too much analysis on noncritical parts of my code gives me a bad case of programmer burnout. - Scott (urge@mcl.mcl.ucsb.edu) +++++++++++++++++++++++++++ >From bb@lightside.com (Bob Bradley) Date: Sat, 27 Aug 1994 02:24:40 -0800 Organization: SS Software Inc. In Jaeger@fquest.com (Brian Stern) writes: >The fact is that memerrors aren't fatal. there's nothing wrong with >something like the following: > h1 = NewHandle( 10 ); > h2 = NewHandle( 20 ); > p1 = NewPtr( 10 ); > p2 = NewPtr( 10 ); > if ( noErr != ( err = MemError() ) ) { /* do something */ } If you don't have enough memory for the first one, you're still going to try all the others. I would check for both the handle not being NULL and that MemError() did not return anything but, noErr after each call to NewHandle(...). +++++++++++++++++++++++++++ >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 29 Aug 94 16:58:57 +1200 Organization: University of Waikato, Hamilton, New Zealand In article <300.310.uupcb@digitec.co.za>, steven.webber@digitec.co.za (Steven Webber) writes: > > Do you use goto's in your code? Nope. I use Modula-2, which doesn't have goto's. > Do you think using Goto's is a bad or good idea? I think overall they're a poor idea, because it's so hard to spot any mistakes that you make with them. But then, I also think exceptions are a poor idea--I like being able to see the control flow in my program at a glance. Modula-2 has this LOOP construct, which is basically an endless loop, within which you have to put EXIT statements to exit, eg: LOOP (* do some cool stuff *) IF ExitCondition1 THEN EXIT END (*IF*); (* do more cool stuff *) IF ExitCondition2 THEN EXIT END (*IF*) (* and so on *) END (*LOOP*) Modula-2 also has the usual WHILE, REPEAT and FOR loops, just like Pascal, but I find that 90% of my loops are LOOP loops. This is because I frequently need to check for error returns from system calls, and abort the loop if I get one. Furthermore, I frequently encounter the need to check for error returns during a linear sequence of operations, not necessarily in a loop, and abort the sequence at the point I hit the error. This gave me the idea for a loop- statement-that-doesn't-loop. I fake this in Modula-2 something like this: InitStorage; LOOP (*once*) DoOSCall1; IF Err <> noErr THEN EXIT END (*IF*); DoOSCall2; IF Err <> noErr THEN EXIT END (*IF*); (* all done *) EXIT END (*LOOP*); DisposeStorage "InitStorage" initializes all pointers to NIL, marks files as unopened etc, and "DisposeStorage" goes through and disposes of all allocated pointers, closes all open files and so on. By strictly adhering to this layout, it's always easy to see where control will go in all situations. Thought for the week: Testing is of limited help if you can't write correct code to begin with. Lawrence D'Oliveiro fone: +64-7-856-2889 Info & Tech Services Division fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00 +++++++++++++++++++++++++++ >From dbenn@leven.appcomp.utas.edu.au (David Benn) Date: Tue, 30 Aug 94 02:32:39 GMT Organization: University of Tasmania I don't know if anyone has mentioned this during the course of this thread, but "The C Users Journal", June 1994 has an article called "Control Structures" which discusses many of the issues that have cropped up in this discussion. The article is in on page 81 and is by Chuck Allison. Rgds, David Benn -- D.Benn@appcomp.utas.edu.au - David Benn. University of Tasmania at Launceston. The effort to understand the universe is one of the few things that lifts human life above the level of farce, and gives it some of the grace of tragedy. (Steven Weinberg) +++++++++++++++++++++++++++ >From dowdy@apple.com (Tom Dowdy) Date: Wed, 31 Aug 1994 00:25:26 GMT Organization: Apple Computer, Inc. In article <33k3rp$b4v@search01.news.aol.com>, radixinc@aol.com (RadixInc) wrote: > In article , dennis@mr2.ece.cmu.edu > (Dennis J. Ciplickas) wrote: > > << I regularly use an "error exit" goto construct in my C code because > it's just too damn difficult to unravel yourself at each point where you > might need to exit.>> > > There's a good article in "d e v e l o p," August 1992, called "Living In > An Exceptional World" by Sean Parent. He proposes an elegant mechanism for > handling exceptions with macros, including clean-up and recovery. His > technique uses macros that resolve to gotos, but it keeps the source code > clean. I've been using these macros for a year or so, and I haven't had to > use an actual goto since. Check it out. I'd like to put another vote down for this style of handling... Sean wrote these macros for us a *loooong* time ago, and they are used in various parts of system software, including just about all of the GX printing code. In fact, a version of Exceptions.h ships with the GX includes because we couldn't imagine the work involved in un-"nrequire"ing the sample driver code. These macros take a small amount to get used to, but once you've got it, you'll find that you just about never fail to include some level of error handling in your code (even if it's just simple cleanup-exit type). -- Tom Dowdy Internet: dowdy@apple.COM Apple Computer MS:302-3KS UUCP: {sun,voder,amdahl,decwrl}!apple!dowdy 1 Infinite Loop AppleLink: DOWDY1 Cupertino, CA 95014 "The 'Ooh-Ah' Bird is so called because it lays square eggs." +++++++++++++++++++++++++++ >From h+@nada.kth.se (Jon W{tte) Date: Fri, 02 Sep 1994 09:18:45 +0200 Organization: Royal Institute of Something or other In article , dowdy@apple.com (Tom Dowdy) wrote: >all of the GX printing code. In fact, a version of Exceptions.h >ships with the GX includes because we couldn't imagine the work >involved in un-"nrequire"ing the sample driver code. Yes, and during the beta cycle, I pointed out that the name "Exceptions.h" collides with the same file name in the Think Class Library, and suggested changing the name to GXExceptions.h, since the Think Class Library is probably the most used Mac application framework. THIS WAS PROMISED! Of course it didn't happen. Cheers, / h+ -- Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden Reality exists only in your imagination. --------------------------- >From jcd7106@tamsun.tamu.edu (John C. Daub) Subject: Need help with saving-writing structs to a file. Date: 3 Sep 1994 16:08:55 -0500 Organization: Texas A&M University, College Station Hi :) I'm having some trouble with trying to write stuff to a file. My program is, essentially, a database. The information the user enters is saved in a struct (and linked list). To illustrate, here's the struct: struct SongInfo { Str255 title; Str255 artist; unsigned short songTime; short tempo; Boolean isOriginal; Str255 songComments; Boolean fitsGenCrit; short listGen; short menuItem; struct SongInfo *next, *prev; }; typedef struct SongInfo SongInfo *SongInfoPtr; >From what i can tell with my entering/editing functions, there seems to be no problems with entering information nor with editing that information (and even removing an entry). But, when i try to save this information/structs/linked-list to a file, I get all sorts of weird things (I open up the data fork, raw, in something like BBEdit Lite). Here's my basic routine for trying to save: (skip all the stuff about FSOpen(), Create(), SetEOF(), SetFPos(), etc). curPtr = gFirstSongInfoPtr; err = FSWrite( fRefNum, &(sizeof(SongInfo)), &curPtr ); if ( err != noErr ) return( err ); curPtr = curPtr->next; I also have a global to hold the offset...start at the beginning of the file, add the one song, increase the offset global by sizeof(SongInfo), then go back and repeat this until you get to the end of it all. Now, i wonder if i'm doing something wrong with checking for curPtr->next = NIL and then letting this while loop for the FSWrite() go too long, or what. I've seen sample source that does this same sort of thing, and it works fine there, but why not here? One time, i ended up with parts of the database info, then i got half of a source file in there (don't ask me how). Could it be something to do with using Pascal strings? Would it help to perhaps save each part of the struct on it's own...like convert the pascal strings to C strings (read them into an array or something), enter that, then move to the next struct member, write that, then the next, write that...each time increasing the offest by sizeof(variable)? Any help in writing structs to a file would be greatly appreaciated :) pleae email to: hsoi@tamu.edu thanx, John +++++++++++++++++++++++++++ >From decartwr@newstand.syr.edu (Dana Cartwright 3rd) Date: 3 Sep 1994 22:10:46 GMT Organization: Syracuse University, Syracuse NY, USA John C. Daub (jcd7106@tamsun.tamu.edu) wrote: : But, when i try to save this information/structs/linked-list to a file, : I get all sorts of weird things (I open up the data fork, raw, in : something like BBEdit Lite). I try to avoid writing structs directly to files. For at least two reasons. First, structs are compiled differently by different compilers...that is, the compiler is free to add padding here and there in structs to maintain data alignment. So if you write a struct to a file, there's a goodly chance you're writing more bytes than you might imagine just from a visual inspection of the struct, and if you re-compile your code with a different compiler (even from the same company), you might no longer be able to read back your older files. Second, if you want any kind of cross-platform compatibility, you have "little-endian" versus "big-endian" (basically, the order of bytes within multi-byte numbers) issues, which are most easily dealt with by exercising VERY tight control over the way data is read/written. Hard to do that when you let the compiler dictate how your data is laid out. I'm guessing here, but I would not be at all surprised if structs were sometimes different on 68K versus PPC compilers. So one way to "solve" your problem would be to more precisely control your file format, which would also probably resolve some of the problems you mention in your post. +++++++++++++++++++++++++++ >From afcjlloyd@aol.com (AFC JLloyd) Date: 3 Sep 1994 18:50:03 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <34aol7$p4u@tamsun.tamu.edu>, jcd7106@tamsun.tamu.edu (John C. Daub) writes: >Hi :) I'm having some trouble with trying to write stuff to a file. > >[ some stuff omitted ] > >Here's my basic routine for trying to save: > >(skip all the stuff about FSOpen(), Create(), SetEOF(), SetFPos(), etc). > > curPtr = gFirstSongInfoPtr; > > err = FSWrite( fRefNum, &(sizeof(SongInfo)), &curPtr ); This FSWrite statement has two problems. You should rewrite it like this: long bytesWritten = sizeof(SongInfo); err = FSWrite( fRefNum, &bytesWritten, curPtr ); It's not a good idea to pass an address of a compiler generated constant to a function that will write into the address. And if you want to write out a set of bytes starting at an address, pass the value of that address, not the address of a pointer that points to the desired address. Jim Lloyd afcjlloyd@aol.com +++++++++++++++++++++++++++ >From bb@lightside.com (Bob Bradley) Date: Fri, 02 Sep 1994 17:42:28 -0800 Organization: SS Software Inc. In article <34as96$hh3@newstand.syr.edu>, decartwr@mailbox.syr.edu wrote: > I try to avoid writing structs directly to files. For at least two > reasons. First, structs are compiled differently by different > compilers...that is, the compiler is free to add padding here and > there in structs to maintain data alignment. So if you write a > struct to a file, there's a goodly chance you're writing more bytes > than you might imagine just from a visual inspection of the > struct, and if you re-compile your code with a different compiler > (even from the same company), you might no longer be able to read > back your older files. I wasn't aware of the problems that can arise when reading/writing structs to a file, how can I change my code to fix the problems? I typically have something like: typedef struct { short shortNumber; FSSpec spec; } MyRecord; And I write that whole structure to disk. In order to do things correctly (to elminate the problems mentioned above) do I have to write each field of the structure individually? I frequently have structures inside of structures and I also save some Apple defined structures to disk, is there any way to fix the problem when you don't actually know the format of the structure (ie. I wouldn't be able to save each individual field)? +++++++++++++++++++++++++++ >From vanderHarg@DIMES.TUDelft.NL (Arthur van der Harg) Date: Sun, 4 Sep 1994 12:16:54 GMT Organization: Hardly In article <34as96$hh3@newstand.syr.edu>, decartwr@mailbox.syr.edu wrote: > I'm guessing here, but I would not be at all surprised if structs > were sometimes different on 68K versus PPC compilers. Or between differently compiled versions on 68k. SC++ 7.x lets you choose field alignment to 1, 2 or 4-byte boundaries. So if you have a field with an odd or non-mod4 number of bytes, the structure will be aligned differently for different compiler *settings*, let alone different compilers or different architectures. Arthur -- This message (c) Arthur van der Harg +++++++++++++++++++++++++++ >From parkb@bigbang.Stanford.EDU (Brian Park) Date: 5 Sep 1994 07:31:25 GMT Organization: Stanford University Dana Cartwright 3rd wrote: >I try to avoid writing structs directly to files. For at least two >reasons. First, structs are compiled differently by different >compilers... [...] >Second, if you want any kind of cross-platform compatibility, you >have "little-endian" versus "big-endian" [...] Resource Manager writes structures to files... doesn't it? -- Brian Park parkb@bigbang.stanford.edu +++++++++++++++++++++++++++ >From hanrek@cts.com (Mark Hanrek) Date: Mon, 5 Sep 1994 08:08:27 GMT Organization: The Information Worskhop In article <34aol7$p4u@tamsun.tamu.edu>, jcd7106@tamsun.tamu.edu (John C. Daub) wrote: > Hi :) I'm having some trouble with trying to write stuff to a file. > > My program is, essentially, a database. The information the user enters > is saved in a struct (and linked list). > > [ stuff deleted ] > > From what i can tell with my entering/editing functions, there seems > to be no problems with entering information nor with editing that > information (and even removing an entry). > > But, when i try to save this information/structs/linked-list to a file, > I get all sorts of weird things (I open up the data fork, raw, in > something like BBEdit Lite). John, You didn't mention exactly how you are determining that something is wrong. Do things appear "wierd" only when you look at it with BBEdit? It should look wierd because you are writing binary stuff, no to mention that the unused portions of p-strings and any fields that have not had anything stored in them will have random values in them. You'll want to use a hex editor like HexEdit. If you mean "wierd things when you read it back in"... of course, you cannot expect the links ( next/previous ) to be correct. You will want to read in a record's worth from disk, but copy to good stuff into a brand new record you've just created, just as you do when entering a new record. I figure you know this, but just in case. :) Also, perhaps you should use FlushVol() as well, to ensure that all of your file writes actually get written to disk. The gist of my message here is that so often, there isn't a problem with what we are examining, but with the methods we are using to examine things. That's not a new comet you've discovered, it is just a dead gnat stuck to the lens of the telescope. :) I've been bit by this one many times ( but not lately :). Just maybe one of the above will help to "jiggle something free" for ya. Mark Hanrek +++++++++++++++++++++++++++ >From howard@netcom.com (Howard Berkey) Date: Mon, 5 Sep 1994 17:59:13 GMT Organization: Psychonaut Foundation Short answer: look in a computer science textbook. Non-snide answer: Essentially the best way to write a data structure to a file is to first flatten it into an array, changing the pointers to array indices. For example, to write a binary tree, make the root node element 0 of the array, and change its left and right node pointers to 1 and 2, respectively. Then put the nodes they pointed to into those array elements. Go to array element 1 and repeat. And so on. Reading back in is easy. I'll append some code at the end of the message. A list is even easier. Now, one thing to make sure of is that you are using the same structure alignment between builds. I stupidly bit myself the other day by not checking the project prefs in CodeWarrior the other day... the app I had generating the file was set to 68K struct alignment, and the one reading it in was set to 68K 4-byte. This caused all sorts of problems. Luckily on the mac you don't need to worry about the endian-ness of the machine. Anyway, here's a quick example in C++. I cut and pasted this from something in progress so it may contain bugs but it will get the general idea across (Assume that CPolygon is defined somewhere else and knows how to write itself): class CBSPTree { private: CPolygon *rootPoly; CBSPTree *backChild; CBSPTree *frontChild; int nodes; struct treeFileFormat { CPolygon *thePoly; int frontChild; int backChild; int nodes; }; public: void flattenSubtree(int current, int nextFree, struct treeFileFormat *theArray); void writeTree(short treeFile); void readTree(short treeFile); }; void CBSPTree :: writeTree(short treeFile) { long inOutCount=(long) sizeof(int); int i; treeFileFormat *theArray; theArray = new treeFileFormat[this->nodes]; flattenSubtree(0, 1, theArray); i=this->nodes + 1; FSWrite(treeFile,&inOutCount,&i); for(i=0;i<=this->nodes;i++) { theArray[i].thePoly->writePoly(treeFile); FSWrite(treeFile,&inOutCount, &theArray[i].nodes); FSWrite(treeFile,&inOutCount,&theArray[i].frontChild); FSWrite(treeFile,&inOutCount,&theArray[i].backChild); } } void CBSPTree :: flattenSubtree(int current, int nextFree, treeFileFormat *theArray) { int myIndex; myIndex=current; if(this->rootPoly != NULL) { theArray[myIndex].thePoly=this->rootPoly; theArray[myIndex].nodes=this->nodes; if(this->frontChild != NULL) { theArray[myIndex].frontChild=nextFree++; current=theArray[myIndex].frontChild; this->frontChild->flattenSubtree(current, nextFree, theArray); } else { theArray[myIndex].frontChild=-1; } if(this->backChild != NULL) { theArray[myIndex].backChild=nextFree++; current=theArray[myIndex].backChild; this->backChild->flattenSubtree(current, nextFree, theArray); } else { theArray[myIndex].backChild=-1; } } } void CBSPTree :: readTree(short treeFile) { struct treeFileFormat *treeArray; CBSPTree *BSPArray, *tmpTree; long inOutCount=(long) sizeof(int); int i, count; SetFPos(treeFile, fsFromStart, 0); FSRead(treeFile, &inOutCount, &count); treeArray=new treeFileFormat[count]; BSPArray=new CBSPTree[count]; for(i=0;ireadPoly(treeFile); FSRead(treeFile, &inOutCount, &treeArray[i].nodes); FSRead(treeFile, &inOutCount, &treeArray[i].frontChild); FSRead(treeFile, &inOutCount, &treeArray[i].backChild); } for(i=0;iFrom wdh@fresh.com (Bill Hofmann) Subject: PBCatSearch-catChangedErr Date: Sat, 3 Sep 1994 21:41:58 GMT Organization: Fresh Software OK, I've got PBCatSearch working, it's a little arcane, but what isn't nowadays. I use the results to scan certain files for certain resources (ie, I do an FSpOpenResFile on the files returned). But here's the problem: AutoDoubler (and I suppose other utils of that ilk) modify the catalog when I open the files, causing PBCatSearch to return catChangedErr (-1304) on the next call to it. So far, the only real solution seems to be a real humongous search (ie, so that I only have to call PBCatSearch once). Am I right? -Bill -- Bill Hofmann wdh@fresh.com Fresh Software and Instructional Design voice: +1 510 524 0852 1640 San Pablo Ave #C Berkeley CA 94702 USA fax: +1 510 524 0853 +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 4 Sep 1994 12:01:05 -0400 Organization: America Online, Inc. (1-800-827-6364) In article , wdh@fresh.com (Bill Hofmann) writes: >OK, I've got PBCatSearch working, it's a little arcane, but what isn't >nowadays. I use the results to scan certain files for certain resources >(ie, I do an FSpOpenResFile on the files returned). But here's the >problem: AutoDoubler (and I suppose other utils of that ilk) modify the >catalog when I open the files, causing PBCatSearch to return catChangedErr >(-1304) on the next call to it. > >So far, the only real solution seems to be a real humongous search (ie, so >that I only have to call PBCatSearch once). Am I right? You're right, you're best off finding all of your matches and then processing them after the matches are found. However, this makes it impossible to let the user cancel a long search -- you need to weigh that against the need to get all matches. BTW: Any call that writes to an HFS volume will result in a catSearchErr. The HFS file system is a little brain dead in this respect because it really only needs to return catSearchErr if the *catalog* changes, not *any* write to the volume. Since the AppleShare and File Sharing file servers use HFS's CatSearch to search on the server Macintosh, this makes searches on AppleShare volumes fail with afpCatalogChanged even more often (in which case, the error cannot be ignored and the search cannot be resumed) because there will likely be multiple writers on an AppleShare volume. I guess I should try to get HFS's CatSearch problems all fixed in the next System Update... - Jim Luther --------------------------- >From JFN@cmq.qc.ca (Jean-Francois Nadeau) Subject: PixToPic Date: 05 Sep 1994 14:48:08 GMT Organization: Club Macintosh de Quebec Hello! How i can transform a PICT resource in a PixMapHandle? Thanks! JFN@cmq.upc.qc.ca - ----------------------------------------------------------- Synapse -- Le serveur telematique du Club Macintosh de Quebec vox: 418.527.0250 fax: 418.527.9304 net: info@cmq.qc.ca - ----------------------------------------------------------- +++++++++++++++++++++++++++ >From Dmitry Boldyrev Date: 5 Sep 1994 21:49:03 GMT Organization: University of Utah In article <65502.4681425@cmq.cmq.qc.ca> Jean-Francois Nadeau, JFN@cmq.qc.ca writes: >Hello! > >How i can transform a PICT resource in a PixMapHandle? > >Thanks! Hmm.. It shouldn't be very hard.. void CiconToPixmap(short res_id, PixMapPtr thebitmap) { CIconHandle theicon; short right, bottom; unsigned long offRowBytes, sizeOfmap; sysinfo system; Ptr offBaseAddr = nil; Rect wbounds; GWorldPtr currPort; GDHandle currDev; short err; static Rect dOffBounds; // Bounds of OffScreen Graphics // World static GWorldPtr gMyOffG; // Pointer to OffScreen Graphics World Boolean gblockAlloc; // Variable to check the successful memoryblock allocation InitSysinfo( &system ); theicon = GetCIcon( res_id ); right = ( (**theicon).iconBMap ).bounds.right; bottom = ( (**theicon).iconBMap ).bounds.bottom; SetRect( &wbounds, 0, 0, GameResHr, GameResVr ); SetRect( &dOffBounds, 0, 0, right, bottom ); GetGWorld( &currPort, &currDev ); // Build Offscreen Graphics world err = NewGWorld( &gMyOffG, 0, &dOffBounds, nil, nil, 0 ); // Create Offscreen Graphics worl if ( err != noErr ) { /* ... */ } // Lock down Pixels that we are drawing to so that memory will not // move gblockAlloc = LockPixels (gMyOffG->portPixMap); if ( !gblockAlloc ) { /* ... */ } // Setup drawing area to be our offscreen graphics world SetGWorld (gMyOffG, nil); //The drawing area PlotCIcon( &dOffBounds, theicon ); // Done drawing, now reset Port etc. SetGWorld (currPort, currDev); // Initialize the PixMap for copying offRowBytes = ( ( ( system.PixelDepth * right ) + 31 ) / 32 ) * 4; sizeOfmap = bottom * offRowBytes; offBaseAddr = NewPtr( sizeOfmap ); if ( offBaseAddr = nil ) { /* ... */ } printf( "%d\n", offRowBytes ); while( !Button() ){} thebitmap->baseAddr = offBaseAddr; thebitmap->rowBytes = offRowBytes; thebitmap->bounds = (**theicon).iconPMap.bounds; BlitPixie( *gMyOffG->portPixMap, thebitmap, &(**theicon).iconPMap.bounds, &thebitmap->bounds, &wbounds ); UnlockPixels( gMyOffG->portPixMap ); } Oh, btw, use CopyBits instead of BlitPixie.. easy to modify.. Dmitry (A friend of mine wrote it.. His name is John Whited) +++++++++++++++++++++++++++ >From gurgle@dnai.com (Pete Gontier) Date: Mon, 05 Sep 1994 16:27:52 -0800 Organization: Integer Poet Software In article <65502.4681425@cmq.cmq.qc.ca>, JFN@cmq.qc.ca wrote: > How i can transform a PICT resource in a PixMapHandle? This question, puzzlingly, comes up pretty often, even though it has a fairly obvious one-word answer: DrawPicture There must be something about the topic that's inherently confusing, or it wouldn't come up so often. Of course, you have to have a pixel map lying around, but sample code for that is easy enough to find; here is the canonical reference: ftp://ftp.apple.com/dts/mac/tn/quickdraw.qd/qd-13-principia-off-screen.hqx I have also posted some sample code for TCL 1.1.3, called 'CPixMap'. ftp://ftp.dnai.com/users/gurgle/CPixMap.sit.bin Now, you could be talking about grabbing a pixel map and putting it into a picture. That has a three-word answer: OpenPicture CopyBits ClosePicture In either case, you'll be needing a pixel map. :-) -- Pete Gontier // Integer Poet Software // gurgle@dnai.com "The need to be (or appear to be) sophisticated pervades the very atmosphere in which we, the Magazine Reading Class, move." -- Eliis Weiner, Spy Magazine, 9/94 --------------------------- >From bb@lightside.com (Bob Bradley) Subject: Slashed Progress Bar Date: Sat, 27 Aug 1994 02:25:15 -0800 Organization: SS Software Inc. I'm trying to implement the Slashed Progress Bar just like Anarchie's when it's trying to connect and similar to the Finder's when it's doing something that it doesn't know how long it will take. I've looked at Anarchie and it doesn't seem to use a PICT resource like the Finder does. I'd like to do something similar to Anarchie but, am not sure how. Anyone have any sample source or suggestions? I'm writing a simple progress bar CDEF that will do progress bars ike normal and support that moving slashed "Not sure how long it will take but, I'm trying" look which I why I want to stay away from PICT's. +++++++++++++++++++++++++++ >From trygve@netcom.com (Trygve Isaacson) Date: Mon, 29 Aug 1994 00:51:29 GMT Organization: Wall Data Incorporated In article , bb@lightside.com (Bob Bradley) wrote: [ deletia ] > I've looked at Anarchie and it doesn't seem to use a PICT resource like > the Finder does. I'd like to do something similar to Anarchie but, am not > sure how. Anyone have any sample source or suggestions? > > I'm writing a simple progress bar CDEF that will do progress bars ike > normal and support that moving slashed "Not sure how long it will take > but, I'm trying" look which I why I want to stay away from PICT's. I prefer the term "meat grinder" for the unknown-duration effect :) First, I'd suggest looking in the various source code archives on the net. There's got to be a CDEF out there that already does this. If not... You say you want to stay away from PICTs, but I don't see why. When you know how long it's going to take, draw the two gauge parts yourself (FillRect or PaintRect each rectangle). When you don't know how long it's going to take, just cycle through the four meat grinder PICTs (roll your own or just use the Finder's). As for the gauge bar color values, here's what I'm using (I think I got these by taking screen shots of the Finder's progress dialog and testing the color values in Photoshop or something). I imagine there's some RGB value that would work in all depths without require a depth test, but these look right. "Completed" gauge colors: 8-bit, dark gray: r=g=b=17476 2-bit, dark gray: r=g=b=21845 1-bit, black : r=g=b=0 "Uncompleted" gauge colors: 8-bit, light purple: r=g=54248, b=65535 2-bit, light gray : r=g=b=43690 1-bit, white : r=g=b=65535 I rolled everything into a TGauge MacApp control class, but since you're doing a CDEF, you might want to define special meaning to the control's min/max/value to achieve the meat grinder effect. E.g.: if maxFrom heathcot@bnr.ca (Graham Heathcote) Date: Mon, 29 Aug 1994 00:29:35 GMT Organization: BNR Australia In article , bb@lightside.com (Bob Bradley) wrote: > I'm trying to implement the Slashed Progress Bar just like Anarchie's when > it's trying to connect and similar to the Finder's when it's doing > something that it doesn't know how long it will take. > > I've looked at Anarchie and it doesn't seem to use a PICT resource like > the Finder does. I'd like to do something similar to Anarchie but, am not > sure how. Anyone have any sample source or suggestions? > > I'm writing a simple progress bar CDEF that will do progress bars ike > normal and support that moving slashed "Not sure how long it will take > but, I'm trying" look which I why I want to stay away from PICT's. I have just implemented a C++ class to perform the standard progress bar and the slashed bar as you call it. I have a few things to finish off and then will be placing the sources into c.s.m. I thought about implementing the picture method of Finder, but this didn't work for my implementation as I wanted the progress bar to be any size as defined in the DITL, and the picture needs to be the same size as the user item or it will be scalled, YUK. So I went with a pixel pattern (or infact 16) and just filled the user item with each successive pattern. This gives exactly the same effect as the finder, except since I am using 16 images it is much smother than Finder. e-mail me if you need any more details, or a preliminary copy of the source and example app I have put together. Regards, Graham Heathcote. -- Graham Heathcote BNR Australia email: heathcot@bnr.ca +++++++++++++++++++++++++++ >From Matt Slot Date: 29 Aug 1994 01:50:48 GMT Organization: University of Michigan Bob Bradley, bb@lightside.com writes: >I'm trying to implement the Slashed Progress Bar just like Anarchie's when >it's trying to connect and similar to the Finder's when it's doing >something that it doesn't know how long it will take. ... >I'm writing a simple progress bar CDEF that will do progress bars ike >normal and support that moving slashed "Not sure how long it will take >but, I'm trying" look which I why I want to stay away from PICT's. I downloaded a progress bar CDEF from the archives, one done by Eddy J. Gurney from HP, and added the "barber-shop pole" idling effect. I sent him a copy and his response was favorable. I will post this to alt.sources.mac, with a tester for you to try out. The basic idea is that the progress goes from 0 to n (begin -> end), and to make it idle you cycle from -4 to -1 (well anything negative MOD 4). I can't say its the fastest or best implementation, but it is satisfactory for what I have used it in so far. Matt +++++++++++++++++++++++++++ >From giles@med.cornell.edu (Aaron Giles) Date: 29 Aug 1994 02:14:59 GMT Organization: Cornell University Medical College In article , bb@lightside.com (Bob Bradley) wrote: > I've looked at Anarchie and it doesn't seem to use a PICT resource like > the Finder does. I'd like to do something similar to Anarchie but, am not > sure how. Anyone have any sample source or suggestions? Well, here is some example code which I used in JPEGView. Basically, it involves setting the PenWidth to a wide pen and drawing some diagonal lines. It is implemented as a dialog user item; each time this user item gets called, it increments the position of the bar. I just do an InvalRect() on the user item to get it move one notch. // defined elsewhere in the application static const RGBColor kBlack = { 0x0000, 0x0000, 0x0000 }; // draw an indefinite progress bar using the standard Finder colors static pascal void UpdateBarIndef(DialogPtr theDialog, short theItem) { static RGBColor gBarBackground = { 0xcccc, 0xcccc, 0xffff }; static RGBColor gBarForeground = { 0x4000, 0x4000, 0x4000 }; static short gBarOffset = 0; Boolean useBW = !(((CGrafPtr)theDialog)->portVersion & 0xc000) || (*((CGrafPtr)theDialog)->portPixMap)->pixelSize == 1; short itemType, left; Handle itemHandle; RgnHandle oldClip; GrafPtr oldPort; Rect itemRect; GetPort(oldPort); SetPort(theDialog); GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect); if (oldClip = NewRgn()) { GetClip(oldClip); PenSize(1, 1); RGBForeColor(&kBlack); FrameRect(&itemRect); InsetRect(&itemRect, 1, 1); ClipRect(&itemRect); left = itemRect.left - (3 * Height(&itemRect)) + (gBarOffset * Height(&itemRect) / 2); PenSize(Height(&itemRect), 1); while (left < itemRect.right) { RGBForeColor(&gBarForeground); MoveTo(left, itemRect.top); LineTo(left += Height(&itemRect), itemRect.bottom); if (useBW) RGBForeColor(&kWhite); else RGBForeColor(&gBarBackground); MoveTo(left, itemRect.top); LineTo(left += Height(&itemRect), itemRect.bottom); } PenSize(1, 1); SetClip(oldClip); DisposeRgn(oldClip); gBarOffset = (gBarOffset + 1) & 3; } RGBForeColor(&kBlack); SetPort(oldPort); } -- Aaron Giles (giles@med.cornell.edu) Power Macintosh Developer, Cornell University Medical College JPEGView home page: http://www.med.cornell.edu/jpegview.html JPEGView FTP site: ftp://ftp.med.cornell.edu/pub/aarong/jpegview/ +++++++++++++++++++++++++++ >From alexr@apple.com (Alex Rosenberg) Date: Mon, 29 Aug 1994 07:59:37 GMT Organization: Hackers Anonymous In article , heathcot@bnr.ca (Graham Heathcote) wrote: > In article , bb@lightside.com > (Bob Bradley) wrote: > > > I'm trying to implement the Slashed Progress Bar just like Anarchie's when > > it's trying to connect and similar to the Finder's when it's doing > > something that it doesn't know how long it will take. > > > > I've looked at Anarchie and it doesn't seem to use a PICT resource like > > the Finder does. I'd like to do something similar to Anarchie but, am not > > sure how. Anyone have any sample source or suggestions? > > > > I'm writing a simple progress bar CDEF that will do progress bars ike > > normal and support that moving slashed "Not sure how long it will take > > but, I'm trying" look which I why I want to stay away from PICT's. > > I have just implemented a C++ class to perform the standard progress bar > and the slashed bar as you call it. I have a few things to finish off and > then will be placing the sources into c.s.m. > > I thought about implementing the picture method of Finder, but this didn't > work for my implementation as I wanted the progress bar to be any size as > defined in the DITL, and the picture needs to be the same size as the user > item or it will be scalled, YUK. So I went with a pixel pattern (or infact > 16) and just filled the user item with each successive pattern. This gives > exactly the same effect as the finder, except since I am using 16 images > it is much smother than Finder. Instead of using multiple patterns, you can get the same effect by moving the origin with a SetOrigin call. (As I do in XMODEM Tool 1.1.) - ------------------------------------------------------------------------- - Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne - - 330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr - Propulsion - - Palo Alto, CA 94301 - - Systems - - (415) 329-8463 - Nobody is my employer so - :-) - - (408) 974-3110 - nobody cares what I say. - - +++++++++++++++++++++++++++ >From msguzzo@srqa01.jsc.nasa.gov (Michael Guzzo) Date: Mon, 29 Aug 1994 15:20:45 Organization: Calspan/Space Shuttle Safety & Mission Assurance In article bb@lightside.com (Bob Bradley) writes: >From: bb@lightside.com (Bob Bradley) >Subject: Slashed Progress Bar >Date: Sat, 27 Aug 1994 02:25:15 -0800 >I'm trying to implement the Slashed Progress Bar just like Anarchie's when >it's trying to connect and similar to the Finder's when it's doing >something that it doesn't know how long it will take. >I've looked at Anarchie and it doesn't seem to use a PICT resource like >the Finder does. I'd like to do something similar to Anarchie but, am not >sure how. Anyone have any sample source or suggestions? >I'm writing a simple progress bar CDEF that will do progress bars ike >normal and support that moving slashed "Not sure how long it will take >but, I'm trying" look which I why I want to stay away from PICT's. How about using two ppats? Set the pen height and width to the height of your progress bar using the ppat, draw a filled rect, and then switch to the other ppat.. continue until you're done. Draw the ppat to look like the barberpole is moving. Just off the top of my head, I don't have any sample code... ________________________________________________________________________ Michael S. Guzzo msguzzo@srqa01.jsc.nasa.gov You're gonna have to face it, you're addicted to Doom! +++++++++++++++++++++++++++ >From Chris Ferris Date: Sun, 4 Sep 1994 15:16:44 GMT Organization: Tycho Consultants In article , Michael Guzzo writes: > > In article bb@lightside.com (Bob Bradley) writes: > >From: bb@lightside.com (Bob Bradley) > >Subject: Slashed Progress Bar > >Date: Sat, 27 Aug 1994 02:25:15 -0800 > > >I'm trying to implement the Slashed Progress Bar... [ Stuff cut ] > How about using two ppats? Set the pen height and width to the height of > your progress bar using the ppat, draw a filled rect, and then switch to the > other ppat.. continue until you're done. Draw the ppat to look like the > barberpole is moving. There is a simpler solution using only one ppat. Define a single ppat for the 'barbers pole' which is black and white separated diagonaly 11111111 = 0xFF 01111111 = 0x7F 00111111 = 0x3F 00011111 = 0x1F 00001111 = 0x0F 00000111 = 0x07 00000011 = 0x03 00000001 = 0x01 Inside your progress bar function use SetOrigin to move the co-ordinate system used by QD patterns by one pixel horizontally for each update to the bar, resetting to 0 when you reach 8. The pattern will appear to move along the progress bar, just remember to compensate for the change in co-ordinates before calling FillRect. ___ | chris@tycho.demon.co.uk / ___ | Chris Ferris, Tycho Consultants /__/_ | / | 'The best way to predict the future is to invent it!' / | Apple Computer Inc --------------------------- End of C.S.M.P. Digest **********************