From: ksand@apple.com (Kent Sandvik )
Subject: Re: TAppl.InstallCohandler mo
Date: Sat, 12 Dec 1992 23:25:18 GMT
Organization: (Evil Eye Creature from Mars, Inc.)
Followup-To: comp.sys.mac.oop.macapp3

In article <724097388.6934764@AppleLink.Apple.COM>,
DEWAELE.W@AppleLink.Apple.COM (De Waele Willy - Gent,BE,IHD) wrote:
> 
> 
>  
> Indeed, Mark, debug versions (of frameworks and our own applications - MacApp
> and others) should be defensive programmed (which save a lot of time), i use
> the following technique taking your example:
>  
> TFoo::Something()
> {...
> #if qDebug
>    if (!IsObject(aCohandler)) {
>      SysBreakStr("TFoo::Something - aCohandler is invalid!");
>     return; }
> #endif
> ...
> }
> SADE must be started up, but i think this is no problem because when working
> with MacApp 3.x, we need a lot of meg's (i don't like limited resources! - *The
> sky's the limit!*).

SysBreakStr are kind of evil, unless SADE is running you usually get a 
System crash. Here's an ASSERT package I worked a little bit on two
weeks ago, it's not yet complete but it could provide material for 
someone else writing similar stuff. Yes, I know of the Assertion MacApp
version, but I wanted more flexibility in my ASSERT package. Note that
this is not a full example, you need to add an Alert resource and a couple
of other small things -- but the main thing was to stimulate the idea
of writing similar flexible ASSERT packages. And this one should be ready
within a month or so (and will then be available on the developer CD).

Kent
---- snippet stuff starts here ----

// TESTING, used for flagging that we use test code inside the classes and
frameworks
// TESTLEVEL0		- user friendly alerts as part of the application
// TESTLEVEL1 	- minor test level (detailed error message in alert box)
// TESTLEVEL2 	- semi-major test level (high level debuggers)
// TESTLEVEL3 	- major test level (low level debuggers)
// TESTLOG1		- trigger a file log of information
// TESTLOG2		- trigger a file log of information from a low level debugger

#define TESTLEVEL3

//
_________________________________________________________________________________________________________
//
//	2. STRING FUNCTIONS
 
// return the len of a C string
inline short clen(char *cptr)
{
	short	i;

	for (i = 0; cptr[i]; ++i)
		;
	return(i);
}


// Convert a c-string to a pascal-string

inline void	c2p(char *cptr)
{
	char	len;

	BlockMove(cptr, cptr + 1, len = clen(cptr));
	*cptr = len;
}


// Convert a pascal-string to a c-string
inline void	p2c(StringPtr cptr)
{
	char	len;

	BlockMove(cptr + 1, cptr, len = *cptr);
	cptr[len] = 0;
}


// Copy two Pascal strings
inline void	Pstrcpy(StringPtr d, StringPtr s)
{
	short	i;

	i = *s;
	do {
		d[i] = s[i];
	} while (i--);
}


// Concatenate two Pascal strings
inline void ConcatPStrings(Str255 first,
						   Str255 second)
{
	short charsToCopy;

	// Truncate if concatenated string would be longer than 255 chars
	charsToCopy = Min(second[0], 255 - first[0]);
	BlockMove(second + 1, first + first[0] + 1, (long)charsToCopy);
	first[0] += charsToCopy;
}


//
_________________________________________________________________________________________________________
//
// MACROS AND DEBUGGING
// ASSERT Function, used for testing conditions and flagging error states.
// Example: vdebugstr("The error message from Foo is %i", fError);

// We need to load in certain include files if we want to use the alert
boxes for
// high level ASSERT functions (we also need to include the
GUIApplication.r file
// into the project).

#if (defined TESTLEVEL0 || defined TESTLEVEL1)
#include "ApplicationResources.h"
#endif


//  Define this flag if you want file and line information as part of the
message.
#define FILELINEINFO


// 	fileinfo will keep track of the current file and line in a global.
static char fileNameArray[32];
static char lineNumberArray[32];


#if (defined TESTLEVEL0 || defined TESTLEVEL1)
inline void AlertUser(Str255 theMessage)
{
	short itemHit;
	
	if(!(AEInteractWithUser(kNoTimeOut, nil, nil)))				// could we interact
with the user?
	{
		ParamText(theMessage, 0, 0,0);
		itemHit = Alert(kUserAlert, nil);
	}
}
#endif

inline void fileinfo(char *file, int line)
{
	sprintf(fileNameArray, "File %s ", file);
	sprintf(lineNumberArray, " Line %d  #", line);
}


//	vxdebugstr that also prints out by default __FILE__ and __LINE__
information
inline void vxdebugstr(char* format,...) 
{
	char buff[255];
	char final[255];

	va_list arglist;
	va_start(arglist,format);
	vsprintf(buff,format,arglist);
	va_end(arglist);

#ifdef FILELINEINFO	
	strcat(final,fileNameArray);
#ifdef TESTLEVEL2
	strcat(final, " ;");							// MacsBug does not like embedded ;s
#endif
	strcat(final, lineNumberArray);
#endif

	strcat(final, buff);
	c2p(final);
	
	// Print out the message, based on the testing level
#ifdef TESTLEVEL1
	AlertUser((Str255)final);
#endif
#ifdef TESTLEVEL2
	SysBreakStr((Str255)final);						// for high level debuggers
#endif
#ifdef TESTLEVEL3
	DebugStr((Str255)final);
#endif
}


//	ASSERT MACROS

//	ASSERT, small (and quick assert),  if assertion is false it will print
out 
// 	a message
//	Use: ASSERT(false, "Problems with TSoundRecorder");

#if (defined TESTLEVEL0 || defined TESTLEVEL1)
#define ASSERT(condition,debugMsg) do {						\
	if(condition == 0)									\
	{												\
		AlertUser(debugMsg);							\
	}												\
   } while (0)											\
 
#elif (defined TESTLEVEL2 || defined TESTLEVEL3)
#define ASSERT(condition,debugMsg) do {						\
	if(condition == 0)									\
	{												\
		DebugStr(debugMsg);							\
	}												\
   } while (0)
#else
#define ASSERT(condition,debugMsg) ((void) 0)
#endif


//	VASSERT, if assertion is false it will print out file, line, message and
possible variable
//	Use: VASSERT(false,("Problems with %d", anErr));

#if (defined TESTLEVEL0)
##define VASSERT(condition,debugMsg) do {					\
	if(condition == 0)									\
	{												\
		vxdebugstr  debugMsg;							\
	}												\
   } while (0)

#elif (defined TESTLEVEL1 || defined TESTLEVEL2 ||  defined TESTLEVEL3)
#define VASSERT(condition,debugMsg) do {					\
	if(condition == 0)									\
	{												\
		fileinfo(__FILE__, __LINE__);						\
		vxdebugstr  debugMsg;							\
	}												\
   } while (0)
   
#else
#define (condition,debugMsg) ((void) 0)
#endif




-------------------
Kent Sandvik (UUCP: ....!apple!ksand; INTERNET: ksand@apple.com)
DISCLAIMER: Private activities on the Net.