From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-017 Date: Wed, 20 Apr 94 13:09:01 MET DST C.S.M.P. Digest Wed, 20 Apr 94 Volume 3 : Issue 17 Today's Topics: 'aete' and AppleScript Help on recursive read of directory catalog..? How can I display TIFF? Inverting a button in a dialog Looking for styled TE replacement? Mounting AFPServer volume... PPC ThreadManager w-CodeWarrior RJW: Retrieving application name from OSType Creator Range of OSErr's for private use? Simple Q: Assigning char * to char []. How? [Q] Validity of a memory address textedit bounds 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 as comp.sys.mac.programmer.src. ------------------------------------------------------- >From "Jared M. Oberhaus" Subject: 'aete' and AppleScript Date: Tue, 29 Mar 1994 03:54:34 -0500 Organization: Senior, Electrical and Computer Engineering, Carnegie Mellon, Pittsburgh, PA OK, I think I've figured out that the aete resource is the Dictionary for translating raw AppleEvent formats into plain English-like commands. But, where is the Template resource for ResEdit, so I can create and modify this resource? And if it doesn't exist yet, how do all you other guys do it? Not the hard way, I hope... Help!! ps-I saw the demo of Resorcerer and noticed that it supports aete resources, and looked around, and I supposed I could figure out how to do an aete resoure by looking at the hex offsets, etc., but I don't exactly feel like doing that! pps-If you could, when you respond, could you respond to All (that is, put me on the adressee list) instead of just Readers, that way, it'll be easier than looking through five hundred messages every day... Thanks! - --------------------------------------------------------------------------- Jared M. Oberhaus oberhaus+@CMU.EDU Electrical and Computer Engineering Class of 1994 Carnegie Mellon University - --------------------------------------------------------------------------- "We are upping our standards,...so up yours." - Pat Paulsen for President, 1988 +++++++++++++++++++++++++++ >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 30 Mar 94 11:19:56 +1300 Organization: University of Waikato, Hamilton, New Zealand In article , "Jared M. Oberhaus" writes: > OK, I think I've figured out that the aete resource is the Dictionary > for translating raw AppleEvent formats into plain English-like commands. > > But, where is the Template resource for ResEdit, so I can create and > modify this resource? I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit doesn't seem to be entirely reliable in its support for templates, and I've hit problems trying to use it to open some aete resources. Generally, if I want to know details of event IDs etc, I use MPW's DeRez to decompile the aete into source form. If I don't, then the Script Editor's "Open Dictionary" command suffices. 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 My hard disk is a Mightgrosoft-free zone. +++++++++++++++++++++++++++ >From knut.mork@admin.uio.no (Knut Mork) Date: Wed, 30 Mar 1994 10:16:28 +0200 Organization: UniNett In article <1994Mar30.111959.27070@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote: > In article , "Jared M. Oberhaus" writes: > > OK, I think I've figured out that the aete resource is the Dictionary > > for translating raw AppleEvent formats into plain English-like commands. > > > > But, where is the Template resource for ResEdit, so I can create and > > modify this resource? > > I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit > doesn't seem to be entirely reliable in its support for templates, and I've > hit problems trying to use it to open some aete resources. > > Generally, if I want to know details of event IDs etc, I use MPW's DeRez to > decompile the aete into source form. If I don't, then the Script Editor's > "Open Dictionary" command suffices. The AppleScript developer CD also has a HyperCard stack for constructing aete resources, which is extremely useful. It has Rez templates for MPW, but those didn't work.. they compiled 'aete' resources which were invalid, at least for me. Anybody else have this problem? --Knut +++++++++++++++++++++++++++ >From mlanett@netcom.com (Mark Lanett) Date: Wed, 30 Mar 1994 08:14:12 GMT Organization: Etch-a-Sketch Analysis and Design ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit >doesn't seem to be entirely reliable in its support for templates, and I've >hit problems trying to use it to open some aete resources. I don't have the AS toolkit, so when I felt like doing stuff with scripting I had to figure out the format of the aete resource myself, and... It looks like it can't be handled by ResEdit. Apparently all the "direct" types like shorts and longs are word-aligned, but strings are not. There's no way to create a template which handles word-alignment in ResEdit, alas, and since the strings *aren't* aligned you can't make a template that works by specifying ESTR instead of PSTR. >...the Script Editor's >"Open Dictionary" command suffices. Never even thought of that one. Oh well, Sucks to be me. >My hard disk is a Mightgrosoft-free zone. I love MS products. *My* HD is a Symantec-free zone. -- Mark Lanett "...a bajillion brilliant Jobsian lithium licks" +++++++++++++++++++++++++++ >From alldritt@mdd.comm.mot.com (Mark Alldritt) Date: 30 Mar 1994 08:31:00 -0800 Organization: Motorola - Wireless Data Group; Richmond, BC In mlanett@netcom.com (Mark Lanett) writes: >ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >>I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit >>doesn't seem to be entirely reliable in its support for templates, and I've >>hit problems trying to use it to open some aete resources. >I don't have the AS toolkit, so when I felt like doing stuff with scripting >I had to figure out the format of the aete resource myself, and... >It looks like it can't be handled by ResEdit. Apparently all the "direct" >types like shorts and longs are word-aligned, but strings are not. There's no >way to create a template which handles word-alignment in ResEdit, alas, and >since the strings *aren't* aligned you can't make a template that works by >specifying ESTR instead of PSTR. The AppleScript developer CD contains a TMPL resource for editing aete resources which works reasonably well. The problem is that TMPL layouts can only handle a limited number of fields. Application aete resources are generally too large to be edited using the aete TMPL. Another alternative is the aete editing Hypercard stack Apple provides on the AppleScript CD and (I think) on the Develop Bookmark CD. However, if your just interested in know what events and classes a application understands then the Script Editor's dictionary window is your best bet. -Mark +++++++++++++++++++++++++++ >From lai@apple.com (Ed Lai) Date: 5 Apr 1994 17:04:19 GMT Organization: Apple In article , "Jared M. Oberhaus" wrote: > OK, I think I've figured out that the aete resource is the Dictionary > for translating raw AppleEvent formats into plain English-like commands. > > But, where is the Template resource for ResEdit, so I can create and > modify this resource? > It should be on the developer CD. You should also find a copy in from ftp.apple.com in /pub/appleevents, although that may not be the latest copy. The problem is that ResEdit template editing probably uses the dialog manager and there can only be a limited number of item in the dialog, any decent size aete would reach the limit so for practical purpose it is useless for aete unless the aete is are very simple like those in an OSAX. You should be able to find the HyperCard aete editor stack in the same place. > And if it doesn't exist yet, how do all you other guys do it? Not the > hard way, I hope... > > Help!! > > ps-I saw the demo of Resorcerer and noticed that it supports aete > resources, and looked around, and I supposed I could figure out how to > do an aete resoure by looking at the hex offsets, etc., but I don't > exactly feel like doing that! I hear that Resorcerer is very good at editing aete resource, this is certainly a solution for those who owns Resorcerer. There is yet another solution. I have written an osax to translate between resources and list using ResEdit template, and since aete is a resource with ResEdit template. In theory you can use the osax and generate aete resource using AppleScript. I have not tried it for a long time, but I suspect it is very slow so may not be practical except for smaller aete. The osax can be found in ftp.apple.com in /pub/lai/osax/pgmTool.sit.hqx -- /* Disclaimer: All statments and opinions expressed are my own */ /* Edmund K. Lai */ /* Apple Computer, MS303-3A */ /* 20525 Mariani Ave, */ /* Cupertino, CA 95014 */ /* (408)974-6272 */ zW@h9cOi --------------------------- >From dsf5454@ritvax.isc.rit.edu Subject: Help on recursive read of directory catalog..? Date: Sun, 3 Apr 1994 16:59:38 GMT Organization: Rochester Institute of Technology Ok...basically, I have a crucial subroutine where I need to read a directory tree below a specific subdirectory. However, I notice that I seem to be crashing into the debugger with an error of #28 and somewhere around in a VBL queue - stack and application heap collison. Therefore, I'm not sure how I could efficiently code such a recursive call... suggestions or pointers, anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to start from root folder. I have a newer version that was re-written, but the principle is the same... Roughly speaking, here's what it looks like at the moment..: -Dan Internet: dsf5454@ritvax.isc.rit.edu BITNET/CREN: dsf5454@ritvax.BITNET long RecursiveDirList (t, dirIDToSearch) short t; long dirIDToSearch; { short index = 1; OSErr err; long curLine; do { myCPB.fileParam.ioFDirIndex = index; myCPB.fileParam.ioVRefNum = vRefNum; myCPB.fileParam.ioDirID = dirIDToSearch; myCPB.fileParam.ioNamePtr = (unsigned char *)fName; err = PBGetCatInfo ((CInfoPBPtr)&myCPB, 0); if (err == noErr) { if (((myCPB.fileParam.ioFlAttrib >> 4) & 0x01) == 1) { RecursiveDirList(t+1,myCPB.fileParam.ioDirID); err = 0; /* It's a directory; we want to go deeper into the subdirectories */ } else { /* it's a file */ } } index++; } while ((err != fnfErr) && (err == noErr)); } +++++++++++++++++++++++++++ >From allon@intercon.com (Allon Stern) Date: Tue, 5 Apr 1994 03:09:18 -0400 Organization: InterCon Systems Corporation, Herndon VA. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu writes: > > Ok...basically, I have a crucial subroutine where I need to read a > directory tree below a specific subdirectory. However, I notice that I > seem to be crashing into the debugger with an error of #28 and > somewhere around in a VBL queue - stack and application heap collison. > Therefore, I'm not sure how I could efficiently code such a recursive > call... suggestions or pointers, anybody? I'm calling it with > RecursiveDirList(1, 2L); in main to tell it to start from root folder. > > I have a newer version that was re-written, but the principle is the > same... > Roughly speaking, here's what it looks like at the moment..: > > -Dan > Internet: dsf5454@ritvax.isc.rit.edu > BITNET/CREN: dsf5454@ritvax.BITNET It seems to me that you could probably do this non-recusively. Keep in mind that you will end up using stack space for each recursive call, and also that PBGetCatInfo and the file manager may also use some stack space. Rather than using the stack to store where you were, you could build your own stack structure, say, using an array. This would minimize stack usage, and would also store the same information much more efficiently. If it is a transient thing (i.e. you use a bunch of storage for a short time, then would release it), you could use temporary memory for it. You could also use a dynamic array, and if you run out of room in your own heap, you could transfer the contents to a handle in temporary memory space. You could try increasing the memory requested for the program, but I think the best thing in this case is to find a non-recursive way to do it. -- Allon | Allon Stern | 703-709-5557 | Ring around the Internet | | allon@intercon.com | KE4FYL | A packet with a bit not set | +--------------------+--------------+ ENQ ACK ENQ ACK | | All opinions above are my own. | We all go down! | |------------------------------------------------------------------| +++++++++++++++++++++++++++ >From d88-jwa@mumrik.nada.kth.se (Jon Wätte) Date: 5 Apr 1994 08:13:09 GMT Organization: The Royal Institute of Technology In <9404050309.AA18685@hazmat.intercon.com> allon@intercon.com (Allon Stern) writes: >> Ok...basically, I have a crucial subroutine where I need to read a >> directory tree below a specific subdirectory. However, I notice that I >> seem to be crashing into the debugger with an error of #28 and >> somewhere around in a VBL queue - stack and application heap collison. >It seems to me that you could probably do this non-recusively. >Keep in mind that you will end up using stack space for each recursive call, >and also that PBGetCatInfo and the file manager may also use some stack >space. Yeah, but PBGetCatInfo will give the stack space back when it's done. (It should be called as PBGetCatInfoSync() by the way, or maybe PBGetCatInfoAsync ( ) ; while ( rec . ioResult == 1 ) Yield ( ) ;) Anyway, his routine only ate 4+4+4+4+4+4+4 bytes per recursion (2 int arguments, a6 link, return address, three int locals, given 4-byte ints) At 28 bytes per recursion, you need > 1000 folders deep structures to hit any real problems, unless you have MASSIVE parameter blocks and Str255s on the stack higher up. (Putting Str255s on the stack is a BAD idea btw) What he could do is call StackSpace() (or whatever) before each recursive call, and call Debugger() if it goes below a K or so. Most probably, however, he's having some other bug which is causing the problem. -- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe -- What we need is a good GNU [...] licence manager implementation. -- Raphael Manfredi +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 5 Apr 1994 12:44:02 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu writes: > Ok...basically, I have a crucial subroutine where I need to read a directory > tree below a specific subdirectory. However, I notice that I seem to be > crashing into the debugger with an error of #28 and somewhere around in a VBL > queue - stack and application heap collison. Therefore, I'm not sure how I > could efficiently code such a recursive call... suggestions or pointers, > anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to > start from root folder. You're using too much stack in your recursive routine - either that, of you don't have much stack when you start your recursive routine. You can check the stack space before you start with the StackSpace function. If that isn't your problem, then you might want to look at one of the recursive routines I put in DTS's MoreFiles File Manager sample code. In particular, the routines in DirectoryCopy.c show how you can use very little stack space per level in a recursive routine that enumerates a directory structure on a Macintosh disk volume. The code in MoreFiles is based on the ideas presented in the Technical Note " +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 5 Apr 1994 12:45:03 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu writes: Ooops, hit the send button too soon... starting where I left off. on ideas presented in the Technical Note "FL 31 - Searching Volumes-Solutions and Problems". Hope that helps. Jim Luther Apple DTS --------------------------- >From jbell@garnet.berkeley.edu (John E. Bell) Subject: How can I display TIFF? Date: 22 Mar 1994 11:07:24 GMT Organization: University of California, Berkeley How can I display a TIFF file in my program? Are there library routines somewhere? Thanks - John E. Bell +++++++++++++++++++++++++++ >From mssmith@afterlife.ncsc.mil (M. Scott Smith) Date: Tue, 22 Mar 1994 12:18:47 GMT Organization: The Great Beyond In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E. Bell) writes: > >How can I display a TIFF file in my program? Are there library routines >somewhere? > >Thanks - John E. Bell John, There are some samples floating about that show how to read the TIFF format. The TIFF format is kind of an ugly thing to read; it takes a lot of work. It's designed to be a very flexible file format, so each TIFF file starts out with a number of "tags" which can contain everything from the expected width and height of the image, to the resolution, even comments and tags/fields which are specific to certain applications. I guess in order to claim that your program can read TIFF, you need to intelligently read a certain number of these tags, and you can ignore the rest. The tags will give you information like offsets for finding the actual data, etc. Really kind of yechy. But, alas: if I remember correctly, NIH Image, a program which you can find at the usual FTP sites, reads color TIFF images. The only problem is that it's written in Pascal. (That may not be a problem for some people.) You can probably easily translate it to C. I've written black and white TIFF-reading code (not color), and I suppose I might some day spruce that up to serve as an example. (Right now, I think I'd be embarassed to claim credit for it. It does read files quickly though.) What I'd like is a nice C++ library that lets you save/read PixMaps to/from a multitude of file formats, such as PICT, TIFF, PostScript, and the like. I don't think such a thing exists (anyone know??), so it seems whenever you want to write a program with these capabilities, you need to re-invent the wheel. Maybe people could get together and build this library; between us, I'm sure we have all of the capability. Anyway, good luck with the TIFF reading. (Trivia: TIFF stands for Tagged Image File Format.) - Scott - - M. Scott Smith (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu) Mac developer. Student. Not a member of the Michael Bolton fan club. +++++++++++++++++++++++++++ >From perm@csd.uu.se (Per Mildner) Date: 22 Mar 1994 16:04:36 GMT Organization: Computing Science Dept.,Uppsala University, Sweden I recommend looking for LIBTIFF with Archie, it reads and writes various tiff formats. My only problem with that is that I know an application (Optix by Blueridge) that unpacks CCITT Group IV (fax) very much faster than the seemingly optimized LIBTIFF code (on a Quadra 700). Regards, -- Per Mildner Per.Mildner@CSD.UU.SE Computing Science Dept. tel: +46 18 181049 Uppsala University, Sweden fax: +46 18 511925 +++++++++++++++++++++++++++ >From markhanrek@aol.com (MarkHanrek) Date: 22 Mar 1994 20:45:07 -0500 Organization: America Online, Inc. (1-800-827-6364) Yes, there is some TIFF source code available from a variety of places. The place to start, though, is the Aldus Developer Desk, which is on CompuServe, from which you will be able to download the current TIFF Level 6.0 specification, example source code (for level 5), and some TIFF pictures which are good to use for testing. Or you could contact Aldus directly. Perhaps there is Internet access to them Mark Hanrek +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Wed, 23 Mar 1994 02:51:35 GMT Organization: NETCOM On-line Communication Services (408 241-9760 guest) There's some TIFF reader code on AOL. Next time I log on I'll get a description of it for you. Seems like I saw some elsewhere, too. i'll check it out. -Ken- +++++++++++++++++++++++++++ >From xinwei@otter.Stanford.EDU (Sha Xin Wei) Date: 5 Apr 1994 21:39:26 GMT Organization: Stanford University M. Scott Smith writes > In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E. Bell) writes: > > > >How can I display a TIFF file in my program? Are there library routines > >somewhere? > > > >Thanks - John E. Bell > > John, > > There are some samples floating about that show how to read the TIFF > format.> Maybe people could get together and build this library; between us, > I'm sure we have all of the capability. > > Anyway, good luck with the TIFF reading. (Trivia: TIFF stands for > Tagged Image File Format.) > > - Scott > > --- > M. Scott Smith (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu) By the way, in the unix world there's a whole wonderful library named pbmplus by Jef Pozkaner, written in C, which is in the public domain. It provides a slew of tools for conversion between 12-40 different graphics formats (depending on how you count) -- PICT, TIFF, PS, GIF, etc., and much more: color histogram, diffusion, quatization, scaling, rotation, palette remaps, even general convolution given a user-supplied kernel. All in public domain. PixelMagician, a NeXTSTEP application has extended pbmplus to handle pixmaps with alpha channel, and a few more formats. If anyone has compiled this under MPW or ThinkC, could they please publish it? Thanks. Sha Xin Wei Stanford University --------------------------- >From Vik_Rubenfeld@lamg.com (Vik Rubenfeld) Subject: Inverting a button in a dialog Date: 05 Apr 1994 00:21:14 -0000 Organization: (none) I've set up a filter procedure that returns the item number of the cancel button if the user hits the escape key. This lets the user dismiss the dialog from the keyboard, without using the mouse. It works great. However, it does not invert the cancel button before dismissing the dialog. So, could someone upload some sample code that highlights (inverses) a standard dialog button? Thanks. +++++++++++++++++++++++++++ >From t-gaul@i-link.com (Troy Gaul) Date: Tue, 05 Apr 1994 10:48:58 -0500 Organization: I-Link, Ltd. In article <101974014.48568985@lamgnet.lamg.com>, Vik_Rubenfeld@lamg.com (Vik Rubenfeld) wrote: > I've set up a filter procedure that returns the item number of the cancel > button if the user hits the escape key. This lets the user dismiss the dialog > from the keyboard, without using the mouse. It works great. However, it does > not invert the cancel button before dismissing the dialog. > > So, could someone upload some sample code that highlights (inverses) a > standard dialog button? Thanks. ControlHandle GetControlItemHandle(DialogPtr dlog, short item) { short iKind; Handle iHandle; Rect iRect; GetDItem(dlog, item, &iKind, &iHandle, &iRect); switch (iKind & ~itemDisable) { case btnCtrl + ctrlItem: case chkCtrl + ctrlItem: case radCtrl + ctrlItem: case resCtrl + ctrlItem: return (ControlHandle) iHandle; } return nil; } void FlashDItem(DialogPtr dlog, short item) { long ignored; ControlHandle button; button = GetControlItemHandle(dlog, item); if (button != nil && (**button).contrlHilite != 255) { HiliteControl(button, 1); Delay(8, &ignored); // the Apple prescribed period of time HiliteControl(button, 0); } } Of course, to flash the cancel button, you just call: FlashDItem(dlog, cancel); _troy //////// //////___Troy Gaul_________________________t-gaul@i-link.com__ // // // I-Link, Ltd. ; West Des Moines, Iowa // // // // "Iungo ergo sum." (I-Link, therefore I am.) // // //////________________________________________________________ // +++++++++++++++++++++++++++ >From charlesworth@andyne.on.ca (Dave Charlesworth) Date: Tue, 5 Apr 1994 22:15:45 GMT Organization: Andyne Computing I don't have sample code handy but you'll find it really simple to write. Here's the basic outline: 1. Get the Cancel button item from the dialog. 2. Coerce it to a control. 3. Tell the control to highlight. 4. Wait long enough for the user to see it. 5. Go on with dismissing your dialog... .../dave Dave Charlesworth --------------------------- >From RobTerrell@aol.com (Rob Terrell) Subject: Looking for styled TE replacement? Date: 4 Apr 1994 17:55:08 GMT Organization: Jecta Development Corp. A few weeks back someone mentioned a styled text edit replacement called "WASTE". The poster claimed it would do styles as well as >32K of text. I've never heard of it, nor has archie. Any ideas? Thanks, Rob Software Designs Unlimited +++++++++++++++++++++++++++ >From mlanett@netcom.com (Mark Lanett) Date: Tue, 5 Apr 1994 02:30:27 GMT Organization: Etch-a-Sketch Analysis and Design RobTerrell@aol.com (Rob Terrell) writes: >A few weeks back someone mentioned a styled text edit replacement >called "WASTE". The poster claimed it would do styles as well as >32K >of text. Host: ghost.dsi.unimi.it (149.132.1.2) Path: pub2/papers/piovanel/ -- Mark Lanett "...a bajillion brilliant Jobsian lithium licks" --------------------------- >From rdm4@acpub.duke.edu (RYAN MARTELL) Subject: Mounting AFPServer volume... Date: 5 Apr 1994 21:26:42 GMT Organization: Duke University, Durham, N.C. Does anyone have any sample code showing how to mount a volume from an AFPServer remotely? I already have the address of the Server, and figure I need to use AFPCommand, but I don't know how to send the proper name/password verification data- or is there just a standard call to do all of that for you? (Essentially, I am trying to write something that acts as the chooser for you..) Any help would be appreciated, please reply by email. -Ryan Martell +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 5 Apr 1994 23:55:02 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2nsl2i$p38@news.duke.edu>, rdm4@acpub.duke.edu (RYAN MARTELL) writes: > Does anyone have any sample code showing how to mount a volume from an > AFPServer remotely? I already have the address of the Server, and > figure I need to use AFPCommand, but I don't know how to send the > proper name/password verification data- or is there just a standard > call to do all of that for you? (Essentially, I am trying to write > something that acts as the chooser for you..) There's two ways to do this so that the volume is mounted by the File Manager (you probably don't want to mount the volume using AFP commands because the File Manager won't know about the volume if mounted that way). The first method is to use the Alias Manager. Create a new alias record using the NewAliasMinimalFromFullPath function. Then, resolve the alias with the ResolveAlias function. The Alias Manager will take care of the user interface for you. The second way is to use the File Manager's PBVolumeMount function. You'll need to build an AFP VolumeMountInfo record to pass to PBVolumeMount. The BuildAFPVolMountInfo function in the Apple DTS MoreFiles sample code will do that for you. MoreFiles also includes a high level versions of the VolumeMount related calls if you don't like using parameter blocks. - Jim Luther --------------------------- >From Frank Price Subject: PPC ThreadManager w-CodeWarrior Date: 5 Apr 1994 16:38:15 GMT Organization: Pomona College Has anybody managed to get the ThreadManager 2.0d7 release running native on the PowerPC using CodeWarrior? All I get is crashes on NewThread which somewhat limits what one can do. Other simple calls like GetCurrentThread seem to work fine. Haven't tried this with MPW yet, but I don't imagine it would be any different (but if it wasn't different, how could they have released this??) Compiling the same code for 68k runs fine. No, I'm not trying to make preemptive threads, and I believe it would return an error even if I had. Also, did anyone notice that the Threads.h header file doesn't even compile? An excess comma has to be removed from inside an enum. I get the feeling this went out the door a little too quickly. -Frank _______________________________________________________________________ | Frank Price | wprice@jarthur.claremont.edu | |_______________|______________________________________________________| +++++++++++++++++++++++++++ >From REDDEN@applelink.apple.com (Kevin Redden) Date: Tue, 5 Apr 1994 21:07:53 GMT Organization: Apple Computer In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price wrote: > Has anybody managed to get the ThreadManager 2.0d7 release running native > on the PowerPC using CodeWarrior? All I get is crashes on NewThread which > somewhat limits what one can do. Other simple calls like GetCurrentThread > seem to work fine. Haven't tried this with MPW yet, but I don't imagine it > would be any different (but if it wasn't different, how could they have > released this??) Compiling the same code for 68k runs fine. No, I'm not > trying to make preemptive threads, and I believe it would return an error > even if I had. Also, did anyone notice that the Threads.h header file > doesn't even compile? An excess comma has to be removed from inside an > enum. I get the feeling this went out the door a little too quickly. > I had some code that I got working with it quite a while ago (I'm not positive that it was 2.0d7 but I think so because I got the same comma error), but I never tried it with CodeWarrier, just Apples SDK for PowerPC. The comma compiles straight through with CFront and I believe that PPCC only flags it when -strict on is specified. I did bring the comma problem up with one of the engineers that works on the Threads package but it was already too late. Hopefully in the next versionÉ Kevin Tech Lead, Macintosh On RISC SDK 2.0 +++++++++++++++++++++++++++ >From bpost@apple.com (Brad Post) Date: Wed, 6 Apr 1994 01:44:05 GMT Organization: Apple Computer In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price wrote: > > Has anybody managed to get the ThreadManager 2.0d7 release running native > on the PowerPC using CodeWarrior? All I get is crashes on NewThread which > somewhat limits what one can do. Other simple calls like GetCurrentThread > seem to work fine. Haven't tried this with MPW yet, but I don't imagine it > would be any different (but if it wasn't different, how could they have > released this??) Compiling the same code for 68k runs fine. No, I'm not > trying to make preemptive threads, and I believe it would return an error > even if I had. Also, did anyone notice that the Threads.h header file > doesn't even compile? An excess comma has to be removed from inside an > enum. I get the feeling this went out the door a little too quickly. Okay this is a simple problem to fix (crashing that is). The problem is that you are most likely using the Voodoo Monkey Debugger Init. It doesn't know about the native thread manager, so it's trying to do some gross stuff that it shouldn't be doing. Remove it and you should work just fine. As for the comma, it slipped out, and it should be fixed in the latest/next release (or it's an exercise for the programmer !-) Brad 'SMMFD' Post +++++++++++++++++++++++++++ >From jwbaxter@olympus.net (John W. Baxter) Date: Tue, 05 Apr 1994 17:46:04 -0700 Organization: Internet for the Olympic Peninsula In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price wrote: > Has anybody managed to get the ThreadManager 2.0d7 release running native > on the PowerPC using CodeWarrior? All I get is crashes on NewThread which > somewhat limits what one can do. You might have better luck with the ThreadManager 2.0 (no qualification) which appeared on the April Developer CD. I don't believe this one is the last word in Thread Managers, either, though. -- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound] jwbaxter@pt.olympus.net +++++++++++++++++++++++++++ >From Frank Price Date: 6 Apr 1994 17:04:27 GMT Organization: Pomona College In article Brad Post, bpost@apple.com writes: >Okay this is a simple problem to fix (crashing that is). The problem is >that you are most likely using the Voodoo Monkey Debugger Init. It doesn't >know about the native thread manager, so it's trying to do some gross stuff >that it shouldn't be doing. Remove it and you should work just fine. As >for the comma, it slipped out, and it should be fixed in the latest/next >release (or it's an exercise for the programmer !-) I wasn't and haven't ever used Voodoo Monkey. I also took the suggestions of others to get the 2.0 release off the April CD instead of 2.0d7. Same problem. Compiling the simple NativeThreads app linking with the xcoff file, it always crashes with an "access fault exception" at NewThread. Would appreciate it if someone could try this out to confirm what I'm saying. I'm using DR2 of CodeWarrior. And again, everything still works fine for the same code in 68k on the same machine. -Frank _______________________________________________________________________ | Frank Price | wprice@jarthur.claremont.edu | |_______________|______________________________________________________| --------------------------- >From piper@char.vnet.net (John Wash) Subject: RJW: Retrieving application name from OSType Creator Date: 31 Mar 1994 17:04:19 -0500 Organization: Vnet Internet Access, Inc. - Charlotte, NC. (704) 374-0779 Hi. This is done in the Finder, so I'm sure there's a simple way to do it. I have a document reference stored in a database. I know it's four-character Creator. How do I resolve that Creator into a path to the application? I've looked through my old Inside Macs. It seems to me that it should be just a Toolbox call, but I can't seem to find it. E-mail or followup messages appreciated. Thanks! John Wash piper@vnet.net -- - John Wash piper@vnet.net Wee Doggie Musical Instruments 919-851-4620 "Bagpipes are the missing link between music and noise." --Gordon Mooney +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 5 Apr 1994 12:34:09 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2nfhd3$1b3@char.vnet.net>, piper@char.vnet.net (John Wash) writes: > How do I resolve that Creator into a path to the > application? I'd start by using the Process Manager to look through the list of open processes to see if the application is already running. If the process isn't running, then use the Desktop Manager's PBDTGetAPPL function on the mounted volumes to try to locate the application. You'll want to start with the volume the file with the creator is on and if you don't find a match there, go on to the boot volume, local volumes, and then last, remote volumes. So, until you find a match, here's the steps you'll need to take: 1) Make sure the volume supports the Desktop Manager using PBHGetVolParms (check for the bHasDesktopMgr attribute bit). 2) Open the desktop database (i.e., get the dtRefNum needed to make calls to the Desktop Manager) on that volume using PBDTOpenInform. If PBDTOpenInform fails with a paramErr, then try again using PBDTGetPath to open the desktop database. 3) Call PBDTGetAPPL using the creator of the application you want to find. Start with ioIndex = 0 to get the newest match in the desktop database, check to make sure the application match is really there and if not, increment the index, call PBDTGetAPPL again to get the next match. If you get to the end of the match list on the volume (with an afpItemNotFound error), try the next volume. OK, so what if you don't find a match using the Desktop Manager, then you'll probably want to try any volumes that *don't* support the Desktop Manager (and thus, have the old Desktop resource file). There's more than one way to do this. You could simply search the volume (using PBCatSearch) for a file with the creator and a file type of 'APPL'. Or, if you really wanted, you could use the Desktop file on the disk volume. Since the Finder already has the Desktop file open and you won't be able to open it with the Resource Manager, you'll need to make a temporary copy of the Desktop file. You can use the FileCopy function in DTS's MoreFiles File Manager sample code to make the copy of the Desktop file. Then you can open it up with the Resource Manager and use the 'APPL' resourced to attempt to find a matching application. The Technical Note "Resources Contained in the Desktop File" describes the resources you'll find in the Desktop file and in particular, the 'APPL' resources. So, what else can you do if none of these things finds an application match? You could search each mounted volume for for a file with the creator and a file type of 'APPL'. The CreatorTypeFileSearch function in the MoreFiles sample uses CatSearch to quickly search a volume for a file specified by creator and file type. About the only thing you cannot do that the Finder does is look through the Finder's open windows for a match. - Jim Luther --------------------------- >From stk@uropax.contrib.de (Stefan Kurth) Subject: Range of OSErr's for private use? Date: 5 Apr 1994 20:47:50 +0200 Organization: Contributed Software GbR Almost every function that I write returns a value of type OSErr. Sometimes it would be desirable to return a private error code of my own, rather than one of the Apple ones. Is there a range of values that I can safely use for my own #defines, without having to worry whether Apple might use them for their system 9.0 implementation of the espresso manager or something? -Stefan _____________________________________________________________________ Stefan Kurth Berlin, Germany stk@contrib.de +++++++++++++++++++++++++++ >From gurgle@netcom.com (Pete Gontier) Date: Wed, 6 Apr 1994 19:00:25 GMT Organization: cellular stk@uropax.contrib.de (Stefan Kurth) writes: >Almost every function that I write returns a value of type OSErr. >Sometimes it would be desirable to return a private error code of my >own, rather than one of the Apple ones. Is there a range of values >that I can safely use for my own #defines, without having to worry >whether Apple might use them for their system 9.0 implementation of the >espresso manager or something? I was just thinking about this the other night, and my conclusion was both yes and no. It seems that the majority of error codes that Apple adds are negative. They still have thousands left over, but they like to leave gaps in between groups of error codes, so they might use positive codes in the not-too-distant future. In fact, they already do use some of the lower positive codes (for CTB calls). You could risk using relatively high positive codes, but it probably wouldn't work in the long run and it wouldn't even be guranateed to work in the short run. One alternative I thought of is to simply return a 'long'. Since an 'OSErr' is nothing but a signed 16-bit quantity, you could use signed values which don't fit in 16 bits for your error codes and return a 'long'. When you go to report the error, you could determine if the value would have fit into an 'OSErr', and if it would have, that's what it is, but if it wouldn't have, it must be one of your custom error codes. The only problem with this is that if some of your routines return an 'OSErr' and others return a 'CustomErr', C won't help you if you forget and assign a 'CustomErr' to an 'OSErr'. (A certain Swede who shall be nameless is likely to pop in here and complain that not only should I really be advocating exceptions instead of error codes but also that Pascal would be much better for this scheme because it wouldn't allow you to screw up assigning the function result. To which I say: yeah, and your mother wears army boots! :-) Of course, this is not what I personally do. Each of my modules has a unique 8-bit "location code", and each module's functions which can produce errors produce a 16-bit struct (fits nicely in a register) which also contains a non-unique error code. Put the two codes together and you have a description of which module caused the error and a a description of what the error was which does not rely on 'OSErr'. -- Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com --------------------------- >From guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif) Subject: Simple Q: Assigning char * to char []. How? Date: Mon, 4 Apr 1994 21:27:46 GMT Organization: Princeton University This seems ridiculous: You should be able to assign a char * to an array of characters. If you declare char a[10], a is a pointer to the first of a contiguous group of 10 characters. Yet when I try this on THINK C 6.0.1, it tells me I cannot assign to an array. If I try to get around this with an assignment to &a[0], it tells me that an lvalue is required. This is an error I have gotten many times, and I do not know how to get around it. ANY help would be greatly appreciated!! Thanks for the time. Guy guyyalif@phoenix.princeton.edu +++++++++++++++++++++++++++ >From zstern@adobe.com (Zalman Stern) Date: Tue, 5 Apr 1994 06:32:24 GMT Organization: Adobe Systems Incorporated Guy Udassin Yalif writes > This seems ridiculous: You should be able to assign a char * to > an array of characters. If you declare char a[10], a is a pointer > to the first of a contiguous group of 10 characters. No, a represents an absolute address of ten characters of storage. There is no storage allocated for a pointer (e.g. 4 bytes holding an address) which points to the beginning of that ten byte array. Another way to put this is that the declarations "extern char a[]" and "extern char *a" are very different. The best way to see this is to look at the assembly code generated for the following function: extern char an_array[]; extern char *a_pointer; int foo(void) { int return_value; return_value = an_array[42]; return_value += a_pointer[42]; return return_value; } > Yet when I try > this on THINK C 6.0.1, it tells me I cannot assign to an array. If > I try to get around this with an assignment to &a[0], it tells > me that an lvalue is required. This is an error I have gotten > many times, and I do not know how to get around it. ANY help would > be greatly appreciated!! Thanks for the time. Guy The C language specification says that array values are automatically converted to pointer values in most circumstances. It does not say they are the same thing. Think-C is trying to tell you that you do not understand the language. A good reading of the ANSI-C standard or other rigorous C documentation might be in order. -- Zalman Stern zalman@adobe.com (415) 962 3824 Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900 "Do right, and risk consequences." Motto of Sam Houston (via Molly Ivins) +++++++++++++++++++++++++++ >From d88-jwa@mumrik.nada.kth.se (Jon Wätte) Date: 5 Apr 1994 08:00:58 GMT Organization: The Royal Institute of Technology In <1994Apr4.212746.24171@Princeton.EDU> guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif) writes: >This seems ridiculous: You should be able to assign a char * to >an array of characters. If you declare char a[10], a is a pointer No, you should not. It's right there in K&R 2nd ed (and, indeed, 1st ed as well) That's because the array is a CONSTANT pointer to a slab of memory that lives on the stack or in global space. You can't just move that slab of memory; all you can do is copy stuff into or out of the memory the array is "pointing to". >me that an lvalue is required. This is an error I have gotten >many times, and I do not know how to get around it. ANY help would You can't. If you want to shove stuff into the actual array memory, you should use strcpy() or memcpy() or possibly BlockMove(). If you want a variable that can point at different arrays, you should use a pointer variable and initialize it first. -- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe -- What we need is a good GNU [...] licence manager implementation. -- Raphael Manfredi --------------------------- >From potterf@tartarus.uwa.edu.au (Felix Potter) Subject: [Q] Validity of a memory address Date: 28 Mar 1994 06:54:22 GMT Organization: The University of Western Australia How does one check that a pointer is valid? (Without dereferencing it and possibly crashing the machine.) At the moment my definition for a pointer that is at least _possibly_ OK is: not null (ie. not equal to 0), and even (ie. not divisble by 2), and > ApplZone (low memory global), and < ApplLimit (low memory global) So if my pointer fails one of these conditions, then I know straight away that something has gone wrong. Does anyone have any comments on either how reasonable or, on the other hand, how totally stupid the above description is? Any suggestions for better ways of going about it? The reason I want to be able to check _quickly_ whether a pointer is valid or not is that I am writing a few little 'wrapper' macros/functions to go around the standard C malloc/calloc/realloc/free functions. I realise that just about every man and his dog has done this before me, but hey, I'm having fun :) One of the things I would like to be able to do is detect heap corruption, and corruption of my record keeping information in particular, and so I'd like to be able to tell if dereferencing a pointer is going to crash my code or not before I do it, in a few strategic places. Hence my above query. Also, I'm going to be asking in come more general-purpose newsgroups, but does anyone have any ideas about how to check pointers on other systems, DOS and UNIX in particular? Thanks for any help (or even idle flames, if I'm being particularly stupid :) -- ____________________________________________________________________________ Felix Potter potterf@lethe.uwa.edu.au potterf@tartarus.uwa.edu.au University of Western Australia, Perth. potter_f@cs.uwa.edu.au +++++++++++++++++++++++++++ >From potterf@tartarus.uwa.edu.au (Felix Potter) Date: 28 Mar 1994 06:58:21 GMT Organization: The University of Western Australia I (potterf@tartarus.uwa.edu.au), in a fit of stupidity, wrote: > How does one check that a pointer is valid? (Without dereferencing it and > possibly crashing the machine.) At the moment my definition for a pointer > that is at least _possibly_ OK is: > not null (ie. not equal to 0), and > even (ie. not divisble by 2), and ^^^^ ^^^^^^^^^^^^^^^^^ Oops *blush* :) Obviously I mean "divisible by 2." -- ____________________________________________________________________________ Felix Potter potterf@lethe.uwa.edu.au potterf@tartarus.uwa.edu.au University of Western Australia, Perth. potter_f@cs.uwa.edu.au +++++++++++++++++++++++++++ >From Cameron Esfahani Date: Mon, 4 Apr 1994 04:42:50 GMT Organization: Apple Computer, Inc. In article <2n5uuu$ekq@styx.uwa.edu.au> Felix Potter, potterf@tartarus.uwa.edu.au writes: > How does one check that a pointer is valid? (Without dereferencing it and > possibly crashing the machine.) At the moment my definition for a pointer > that is at least _possibly_ OK is: > not null (ie. not equal to 0), and > even (ie. not divisble by 2), and > > ApplZone (low memory global), and > < ApplLimit (low memory global) > So if my pointer fails one of these conditions, then I know straight away > that something has gone wrong. Does anyone have any comments on either how > reasonable or, on the other hand, how totally stupid the above description is? > Any suggestions for better ways of going about it? > > The reason I want to be able to check _quickly_ whether a pointer is valid > or not is that I am writing a few little 'wrapper' macros/functions to > go around the standard C malloc/calloc/realloc/free functions. I realise that > just about every man and his dog has done this before me, but hey, I'm > having fun :) One of the things I would like to be able to do is detect > heap corruption, and corruption of my record keeping information in > particular, and so I'd like to be able to tell if dereferencing a pointer > is going to crash my code or not before I do it, in a few strategic places. > Hence my above query. > > Also, I'm going to be asking in come more general-purpose newsgroups, but > does anyone have any ideas about how to check pointers on other systems, > DOS and UNIX in particular? > > Thanks for any help (or even idle flames, if I'm being particularly stupid :) Well, try installing your own Bus Error Handler and dereference the pointer. If you get called in your Bus Error Handler, then it is not a valid pointer. If you don't, it's valid.... Cameron Esfahani dirty@apple.com +++++++++++++++++++++++++++ >From ari@world.std.com (Ari I Halberstadt) Date: Mon, 4 Apr 1994 06:26:22 GMT Organization: The World Public Access UNIX, Brookline, MA In article <2n5uuu$ekq@styx.uwa.edu.au>, Felix Potter wrote: >How does one check that a pointer is valid? (Without dereferencing it and >possibly crashing the machine.) At the moment my definition for a pointer >that is at least _possibly_ OK is: > not null (ie. not equal to 0), and > even (ie. not divisble by 2), and > > ApplZone (low memory global), and > < ApplLimit (low memory global) >So if my pointer fails one of these conditions, then I know straight away >that something has gone wrong. Does anyone have any comments on either how >reasonable or, on the other hand, how totally stupid the above description is? >Any suggestions for better ways of going about it? Those are most of the tests you'd ever need. If you get a crash from dereferencing a pointer after doing those checks then I'd be pretty surprised. If you didn't mind the speed hit, you could look for the pointer in some private table of valid pointers, using some sort of binary tree, for instance. What these tests don't tell you, however, is whether the contents of the pointer are valid. What I've done in my applications is create a header that is placed at the start of every pointer allocated. The header contains the size of the pointer and a 4-byte signature code. A unique signature code is used for every type of object I allocate. Then I do something like this: ObjectPtr NewObject(...) { ObjectPtr object = NewObjectPtr(sizeof(ObjectType), 'objp'); ... assert(ValidObject(object)); return(object); } Boolean ValidObject(ObjectPtr object) { if (! ValidObjectPtr(object, sizeof(ObjectType), 'objp')) return(false); ... more tests to check relationships among members of the object ... } void DoSomethingToObject(ObjectPtr object) { assert(ValidObject(object)); ... use object ... assert(ValidObject(object)); } The function ValidObjectPtr compares the size and ID code passed to it as parameters with the values stored in the pointer's header. If they differ, then the pointer is deemed invalid and false is returned. The function also checks that the pointer's header and the end of the pointer are within the application's heap zone. As a further enhancement, you could store a trailer at the end of each pointer. The trailer would contain the same 4-byte id code, and would help catch errors that resulted from overwriting the end of the pointer. Also, when you allocate a pointer, fill it with some random (or not so random) garbage. Something like 0xff works pretty well and is easy to spot with a debugger. Using an odd value like 0xff is also good since any members of the object that are pointers will be detected as illegal pointers (since they'll be odd integers). When you dispose of the pointer, again fill it with 0xff, since this will ensure that you won't be able to use its contents without immediate errors. Alternatively, you could zero the pointer when you allocate it, thus removing the need to initialize members to a default value. However, you should still fill the pointer with invalid data when it is disposed of. My personal preference is to zero program objects but to fill data pointers with 0xff bits. I disable the filling of memory with 0xff bits for greater efficiency in the final application If you were really paranoid, you could checksum the contents of the pointer. For instance, instead of just calling ValidObject, you could do something like: CheckInObject(object); ... CheckOutObject(object); CheckInObject would calculate a checksum for the object and compare it with the checksum saved in the pointer's header. If the checksums differ, CheckInObject would fail (e.g., raise an exception). Then, it would call ValidObject, and finally it would increment a counter to indicate that the object had been checksummed and is in use. A value greater than zero for the counter would prevent further calls to CheckInObject from calculating a checksum or calling ValidObject. CheckOutObject would decrement the counter each time it is called. When the matching call to CheckOutObject is made (the counter is zero) then a new checksum would be calculated for the object and the checksum would be stored in the pointer's header. This should be reasonably efficient and quite robust. You could make CheckInObject and CheckOutObject macros that you could undefine when debug code was disabled, or could change the macros so that they didn't do the checksum operation in the final product. I haven't used this method yet in my own applications, but I'm thinking of adding it. > >The reason I want to be able to check _quickly_ whether a pointer is valid >or not is that I am writing a few little 'wrapper' macros/functions to >go around the standard C malloc/calloc/realloc/free functions. I realise that >just about every man and his dog has done this before me, but hey, I'm >having fun :) One of the things I would like to be able to do is detect >heap corruption, and corruption of my record keeping information in >particular, and so I'd like to be able to tell if dereferencing a pointer >is going to crash my code or not before I do it, in a few strategic places. >Hence my above query. To check the heap, you can just use MacsBug or TMON with heap check enabled. It works pretty well for most things. With TMON, one problem is that by the time the heap is corrupted you can't figure out where it failed in your code since all of the function labels are gone (it's kind of a pain to get around this problem). I like to validate memory on several different levels. The most secure, but slowest, level is used during development. Less checks are done in a beta level, and most (or all) checks are disabled in a release version. However, lately, my memory checks have been fairly fast (they used to be really slow), so I'm thinking of leaving at least some of them in the release level. Just checking the validity of pointers before calling memory allocation and disposal routines is better than nothing, but overall is not very secure. A pointer can easily become corrupted long before free is ever called on it. You can also do a lot of extra verification if you provide type information (like a four-byte code) in your code. If you get fancy, you can even check the logical relationships among the members of your objects. Checking logical relationships helps catch additional programmatic errors. >Also, I'm going to be asking in come more general-purpose newsgroups, but >does anyone have any ideas about how to check pointers on other systems, >DOS and UNIX in particular? All of the checks I described above can be used on Unix systems. You might have trouble finding something equivalent to ApplZone/ApplLimit on Unix, but there's probably some equivalent, even if it's not totally portable. The checks should probably also work with DOS systems. The interpretation of multiple byte character constants is not defined by the language, so things like 'objp' may have to be modified (e.g., use defines in some common memory header, don't scatter the constants all over the place). -- Ari Halberstadt ari@world.std.com #include "These beetles were long considered to be very rare because very few entomologists look for beetles in the mountains, in winter, at night, during snow storms." -- Purves W. K., et al, "Life: The Science of +++++++++++++++++++++++++++ >From Alexander M. Rosenberg Date: Mon, 4 Apr 1994 12:39:22 GMT Organization: Hackers Anonymous In article <1994Apr4.044250.27756@gallant.apple.com> Cameron Esfahani, dirty@guest.apple.com writes: > Well, try installing your own Bus Error Handler and dereference > the pointer. If you get called in your Bus Error Handler, then it > is not a valid pointer. If you don't, it's valid.... Trouble-maker. - ------------------------------------------------------------------------- - 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 - :-) - - - nobody cares what I say. - - +++++++++++++++++++++++++++ >From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne) Date: 5 Apr 94 05:34:57 GMT Organization: University of Illinois at Urbana ari@world.std.com (Ari I Halberstadt) writes: >What I've done in my applications... Ari offers some good suggestions. I once saw most of his suggestions implemented in a library that was published in MacTech (MacTutor?) a while back. I can't remember the name of the article, but I remember the library functioned on the principle of wrapping accesses to your data with MMUse and MMUnuse. The idea being that you had to call MMUse to be able to use your data and must call MMUnuse as soon as you were done with it at that point. This allowed for all kinds of nifty things the library could do behind your back, like checksumming, checking for leaks, and even some primitive virtual memory techniques. If I could remember the names of the authors, I'd cite them for you. (Was it 'MemMan'?) -- Jim Browne | jbrowne@ncsa.uiuc.edu | Head NCSA Mac Telnet Hacker, SDG System Administrator | (217) 244-7798 | Click me "Not me, not yet, not that bad." +++++++++++++++++++++++++++ >From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne) Date: 5 Apr 94 07:28:00 GMT Organization: University of Illinois at Urbana jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne) writes: >ari@world.std.com (Ari I Halberstadt) writes: >>What I've done in my applications... >Ari offers some good suggestions. I once saw most of his suggestions >implemented in a library that was published in MacTech (MacTutor?) a while >back. I can't remember the name of the article, but I remember the library >functioned on the principle of wrapping accesses to your data with MMUse and >MMUnuse. The idea being that you had to call MMUse to be able to use your >data and must call MMUnuse as soon as you were done with it at that point. >This allowed for all kinds of nifty things the library could do behind your >back, like checksumming, checking for leaks, and even some primitive virtual >memory techniques. If I could remember the names of the authors, I'd cite >them for you. Well, I've gone and looked up the article. Thanks to those great people at MacTech, I was able to grep the text index of articles for MacTech vols. 1-8. Here's the reference: "A Memory Manager for the Rest of US." by Jordan Zimmerman. Vol. 7 No. 9 Pg. 40 -- Jim Browne | jbrowne@ncsa.uiuc.edu | Head NCSA Mac Telnet Hacker, SDG System Administrator | (217) 244-7798 | Click me --"It's really weird... kind of like how Telnet is programmed." - Q. Koziol -- --------------------------- >From Ben J Fry Subject: textedit bounds Date: Tue, 5 Apr 1994 21:15:13 -0400 Organization: Freshman, Design, Carnegie Mellon, Pittsburgh, PA does anyone know how to figure out the real boundaries for a styled textedit field? that is, the natural boundary rectangle that the text would fit in... any help would be really appreciated.. i've nearly worn out my think reference in trying to look for this... (if that's possible...) ben +++++++++++++++++++++++++++ >From ari@world.std.com (Ari I Halberstadt) Date: Wed, 6 Apr 1994 21:27:41 GMT Organization: The World Public Access UNIX, Brookline, MA In article , Ben J Fry wrote: >does anyone know how to figure out the real boundaries for a styled >textedit field? that is, the natural boundary rectangle that the text >would fit in... > >any help would be really appreciated.. i've nearly worn out my think >reference in trying to look for this... (if that's possible...) > > >ben Assuming you have word wrap turned on, you can find the width of the text from the width of the destination rectangle. You can get the height of the text with TEGetHeight. If you don't have word wrap turned on, then you can either assume some maximum width, say 72 inches (5184 pixels). This is a large enough value to ensure that the user can view most text, without making the horizontal scroll bar as useless as a value of 32767 would. If you really want to be accurate, then you you can calculate the width of the widest line in the text. Here's some code to do this for both styled and unstyled text. It knows way too much about TextEdit internals, but hey, it works :-) A few utility functions: typedef unsigned long TicksType; typedef SignedByte HandleStateType; HandleStateType HandleLock(void *h) { HandleStateType state; state = HGetState(h); HLock(h); return(state); } void HandleStateSet(void *h, HandleStateType state) { HSetState(h, state); } // word wrap macros #define TEWrap(te) ((**(te)).crOnly >= 0) #define TEWrapSet(wrap, te) ((void) ((**(te)).crOnly = ((wrap) ? 1 : -1))) static Boolean TEOldStyle(TEHandle te) { return((**te).txSize != -1); } /* Calculate the width of the widest line in the line range. If the operation takes longer than 'timeout' ticks to compute, then the last line reached is returned in 'finalLine', and the result of the function is the width of the widest line between 'firstLine' and 'finalLine'. Otherwise (i.e., no timeout), the result of the function is the width of the widest line and 'finalLine' is equal to 'lastLine'. The time out is provided since calculating the widths of the lines-- especially for long styled text documents--can take quite a while, and doing so every time the document changes could be prohibitively slow. Instead, if 'finalLine' is less than 'lastLine', then after processing some events, the application can continue to call this function, passing the value of 'finalLine' as the 'firstLine' parameter, until 'finalLine' is equal to 'lastLine', at which point the maximum of the values returned by the successive calls to this function will be the width of the widest line in the original line range. */ static short TEWidthUnstyled(short firstLine, short lastLine, TicksType timeout, long *finalLine, TEHandle te) { HandleStateType svTextHandleState; /* saved state of handle to text */ GrafPtr svPort; /* saved graf port */ Ptr textPtr; /* pointer to text */ short textWidth; /* width of text */ short lineIndex; /* current line number */ short lineLongest; /* length of longest line */ short lineStart; /* first character of line */ short lineEnd; /* last character of line */ long startTicks /* time when we started */ short txFont, txSize, txFace; /* saved text state */ require(TEOldStyle(te)); /* quick out */ if ((**te).nLines == 0) return(0); /* keep track of elapsed time */ startTicks = TickCount(); /* find longest line */ lineStart = lineEnd = lineLongest = 0; for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) { /* remember length of longest line encountered so far */ if (lineLongest < (**te).lineStarts[lineIndex + 1] - (**te).lineStarts[lineIndex]) { lineStart = (**te).lineStarts[lineIndex]; lineEnd = (**te).lineStarts[lineIndex + 1]; lineLongest = lineEnd - lineStart; } /* stop if took too long */ if (TickCount() - startTicks > timeout) break; } /* calculate width of longest line */ GetPort(&svPort); SetPort((**te).inPort); txFont = (**te).inPort->txFont; txSize = (**te).inPort->txSize; txFace = (**te).inPort->txFace; TextFont((**te).txFont); TextSize((**te).txSize); TextFace((**te).txFace); svTextHandleState = HandleLock((**te).hText); textPtr = *(**te).hText; textWidth = TextWidth(textPtr, lineStart, lineEnd - lineStart); HandleStateSet((**te).hText, svTextHandleState); TextFont(txFont); TextSize(txSize); TextFace(txFace); SetPort(svPort); *finalLine = lineIndex; return(textWidth); } /* see description of TEWidthUnstyled */ static short TEWidthStyled(short firstLine, short lastLine, TicksType timeout, long *finalLine, TEHandle te) { HandleStateType svTextHandleState; /* saved state of handle to text */ HandleStateType svStyleHandleState; /* saved state of handle to style record */ HandleStateType svStyleTableState; /* saved state of handle to style table */ GrafPtr svPort; /* saved graf port */ TEStylePtr stylePtr; /* text's style record */ STPtr styleTable; /* text's style table */ StyleRun *runPtr; /* style runs array */ short runStart; /* start of next style run */ Ptr textPtr; /* pointer to text */ short textLength; /* length of text run */ short textWidth; /* width of text */ short lineWidth; /* width of current line */ short lineIndex; /* current line number */ short lineStart; /* first character of line */ short lineEnd; /* last character of line */ long startTicks; /* time when we started */ short txFont, txSize, txFace; /* saved text state */ require(! TEOldStyle(te)); /* quick out */ if ((**te).nLines == 0) return(0); /* keep track of elapsed time */ startTicks = TickCount(); /* setup port */ GetPort(&svPort); SetPort((**te).inPort); txFont = (**te).inPort->txFont; txSize = (**te).inPort->txSize; txFace = (**te).inPort->txFace; /* lock and dereference handles */ svTextHandleState = HandleLock((**te).hText); textPtr = *(**te).hText; svStyleHandleState = HandleLock(GetStylHandle(te)); stylePtr = *GetStylHandle(te); svStyleTableState = HandleLock(stylePtr->styleTab); styleTable = *stylePtr->styleTab; /* initialize loop */ textWidth = 0; runPtr = stylePtr->runs; runStart = runPtr[1].startChar; TextFont(styleTable[runPtr->styleIndex].stFont); TextFace(styleTable[runPtr->styleIndex].stFace); TextSize(styleTable[runPtr->styleIndex].stSize); /* calculate widths of all lines */ for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) { /* calculate width of line */ lineWidth = 0; lineStart = (**te).lineStarts[lineIndex]; lineEnd = (**te).lineStarts[lineIndex + 1]; while (lineStart < lineEnd) { if (lineStart == runStart) { /* use next style run (assumes run array is sorted by startChar) */ runPtr++; runStart = runPtr[1].startChar; check(runPtr->startChar == lineStart); TextFont(styleTable[runPtr->styleIndex].stFont); TextFace(styleTable[runPtr->styleIndex].stFace); TextSize(styleTable[runPtr->styleIndex].stSize); } /* calculate width of style run */ check(lineStart < runStart); textLength = min(lineEnd - lineStart, runStart - lineStart); check(textLength >= 1); lineWidth += TextWidth(textPtr, lineStart, textLength); lineStart += textLength; } textWidth = max(textWidth, lineWidth); /* stop if took too long */ if (TickCount() - startTicks > timeout) break; } /* restore saved state */ HandleStateSet(RecoverHandle((Ptr) styleTable), svStyleTableState); HandleStateSet(RecoverHandle((Ptr) stylePtr), svStyleHandleState); HandleStateSet(RecoverHandle((Ptr) textPtr), svTextHandleState); TextFont(txFont); TextSize(txSize); TextFace(txFace); SetPort(svPort); *finalLine = lineIndex; return(textWidth); } /* see description of TEWidthUnstyled */ short TEWidthTimeout(short start, short end, TicksType timeout, long *final, TEHandle te) { return(TEOldStyle(te) ? TEWidthUnstyled(start, end, timeout, final, te) : TEWidthStyled(start, end, timeout, final, te)); } /* calculate the width of the widest line in the line range */ short TEWidth(short start, short end, TEHandle te) { return(TEWidthTimeout(start, end, LONG_MAX, 0, te)); } -- Ari Halberstadt ari@world.std.com #include "These beetles were long considered to be very rare because very few entomologists look for beetles in the mountains, in winter, at night, during snow storms." -- Purves W. K., et al, "Life: The Science of --------------------------- End of C.S.M.P. Digest **********************