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-0109941427200001@med262.bham.ac.uk>,
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 <Jeff@purple.com>
Date: Wed, 24 Aug 94 08:18:36 -0500
Organization: Purple


In article <rtmd30-2308941345120001@pangaea.sps.mot.com>, 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 <Jeff@purple.com>
wrote:
>
>In article <rtmd30-2308941345120001@pangaea.sps.mot.com>, 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 <veloso@netcom.com>
Date: Fri, 26 Aug 1994 06:11:38 GMT
Organization: Ibex Productions

In article <rtmd30-2308941345120001@pangaea.sps.mot.com> 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 <name> 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?"

<YES>   <MAYBE>


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 <Darrin.Cardani@AtlantaGA.NCR.COM>
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:
      <Several lines of cleanup code, and return an error>
}

>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.94Aug24102539@mr2.ece.cmu.edu>, 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 <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?  
>

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:

<<I've got a question for all you programmers out there. 
 
Do you use goto's in your code? >>

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.94Aug24102539@mr2.ece.cmu.edu>, 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:

<<A lot of the anti-goto sentiment comes out of Wirth's article "GOTO
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. 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.94Aug24102539@mr2.ece.cmu.edu>, 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.94Aug24102539@mr2.ece.cmu.edu>, 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:
>
><<A lot of the anti-goto sentiment comes out of Wirth's article "GOTO
>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-2508942242470001@slip-1-21.ots.utexas.edu> 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-2508942242470001@slip-1-21.ots.utexas.edu> 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.94Aug24102539@mr2.ece.cmu.edu>, 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-3008941725260001@17.202.68.12>,
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 <vanderHarg@DIMES.TUDelft.nl>

+++++++++++++++++++++++++++

>From parkb@bigbang.Stanford.EDU (Brian Park)
Date: 5 Sep 1994 07:31:25 GMT
Organization: Stanford University

Dana Cartwright 3rd <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...
[...]
>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;i<count;i++) 
   {
      treeArray[i].thePoly = new CPolygon;
      treeArray[i].thePoly->readPoly(treeFile);
      FSRead(treeFile, &inOutCount, &treeArray[i].nodes);
      FSRead(treeFile, &inOutCount, &treeArray[i].frontChild);
      FSRead(treeFile, &inOutCount, &treeArray[i].backChild);
   }

   for(i=0;i<count;i++)
    {
      
      BSPArray[i].rootPoly=treeArray[i].thePoly;
      BSPArray[i].nodes=treeArray[i].nodes;
      if(treeArray[i].frontChild != -1) BSPArray[i].frontChild 
                                       = &BSPArray[treeArray[i].frontChild];
      if(treeArray[i].backChild != -1) BSPArray[i].backChild 
                                       =
&BSPArray[treeArray[i].backChild];                                    
      
    }
    
   *this=BSPArray[0];   

}

-- 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Howard Berkey                                     howard@netcom.com
Segmentation Fault (core dumped)

---------------------------

>From 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-0309941441580001@wdh.slip.netcom.com>, 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 <dmitry@atlas.chem.utah.edu>
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-2708940225150001@user57.lightside.com>, 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 max<min, then
SetCtlValue cranks the meat grinder. Something like that.

..........................................................................
Trygve Isaacson           trygve@netcom.com         Wall Data Incorporated
..........................................................................
  "Books are burning in the main square
                        And I saw there the fire eating the text
     Books are burning in the still air
                     And you know where they burn books people are next"
                                                  -- Andy Partridge, XTC

+++++++++++++++++++++++++++

>From heathcot@bnr.ca (Graham Heathcote)
Date: Mon, 29 Aug 1994 00:29:35 GMT
Organization: BNR Australia

In article <bb-2708940225150001@user57.lightside.com>, 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 <fprefect@engin.umich.edu>
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-2708940225150001@user57.lightside.com>, 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-2908941028320001@47.181.192.70>, heathcot@bnr.ca
(Graham Heathcote) wrote:

> In article <bb-2708940225150001@user57.lightside.com>, 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-2708940225150001@user57.lightside.com> 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 <chris@tycho.demon.co.uk>
Date: Sun, 4 Sep 1994 15:16:44 GMT
Organization: Tycho Consultants


In article <msguzzo.72.000F590A@srqa01.jsc.nasa.gov>, Michael Guzzo 
writes:

>
> In article <bb-2708940225150001@user57.lightside.com> 
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
**********************