Code Search for Developers
 
 
  

requireToDebuggerOrNote.c from redshed at Krugle


Show requireToDebuggerOrNote.c syntax highlighted

/****************************************************************************************
	requireToDebuggerOrNote.c $Revision: 3 $
		<http://rentzsch.com/require>
	
	Copyright © 1997-2002 Red Shed Software. All rights reserved.
	by Jonathan 'Wolf' Rentzsch (jon at redshed dot net)
	
	Reports requirement failures via DebugStr() if a debugger is installed. Otherwise the
	failure is reported via the Notification Manager.
	
	When compiling for Carbon, requires C++ (see below).
	When reporting via the Notification Manager, a failure will not halt the caller.
	When reporting via the Notification Manager, if the program hits another requirement
	failure and there is an outstanding failure notification, the second WILL NOT BE
	REPORTED.
	
	************************************************************************************/

#include	"requireImplementation.c"

#ifndef		__NOTIFICATION__
#include	"Notification.h"
#endif	//	__NOTIFICATION__

typedef	struct	{
	NMRec	nm;
	Str255	str;
}	NMStr;

	pascal
	void
NMDisplayProc(
	NMRecPtr	nmReqPtr );

NMStr	gNote;
Boolean	gNoteShowing = false;

//	When compiling for Carbon, C++ needs to be turned on. We need to allocate a
//	routine descriptor for the notification manager's callback.
//
//	Under Classic 68K, routine descriptors aren't used and no allocation is
//	necessary.
//
//	Under CFM (either CFM-68K or CFM-PPC), we can use the BUILD_ROUTINE_DESCRIPTOR
//	macro, which builds the routine descriptor at compile time and it loaded with
//	the rest of the code, automatically.
//
//	The Carbon engineers, in their infinite wisdom, REQUIRES we call a function that
//	in turn (under Mac OS 9) WILL CALL NEWROUTINEDESCRIPTOR, WHICH WILL CALL NEWPTR!
//	This can't be done at interrupt time, and the requirements package WILL be
//	called at interrupt time. The work-around is to give gProc an initial value of a
//	function, which can only be done using C++. The C++ support runtime will execute
//	the function before entering main(), at system task time.

#if	TARGET_API_MAC_CARBON
	NMUPP	gProc = NewNMUPP( NMDisplayProc );
#else
	#if	TARGET_RT_MAC_CFM
		RoutineDescriptor	gRD = BUILD_ROUTINE_DESCRIPTOR( uppNMProcInfo, NMDisplayProc );
		NMUPP				gProc = &gRD;
	#else
		NMUPP	gProc = &NMDisplayProc;
	#endif
#endif

	Boolean
IsDebuggerCallable();

/****************************************************************************************
	Commenter	Date				Comment
	---------	-----------------	-----------------------------------------------------
	wolf		Mon, Jul 21, 1997	Created.
	
	************************************************************************************/

	void
RequireNotice(
	const	char			*msg,
	const	char			*code,
	const	char			*note,
			long			nmbr,
	const	char			*file,
			long			line,
			long			errn )
{
	Str255	outStr = "\p";
	
	#define	out		outStr, sizeof( Str255 ) - 1
	
	//	Message line.
	if( msg )
		RAppendCStringToPString( msg, out );
	else
		RAppendPStringToPString( "\pGeneric Require Failure", out );
	
	//	Note line.
	if( note ) {
		RAppendPStringToPString( "\p\r note: ", out );
		RAppendCStringToPString( note, out );
	}
	//	File line.
	if( file ) {
		RAppendPStringToPString( "\p\r file: ", out );
		RAppendCStringToPString( file, out );
	}
	//	Line line.
	if( line ) {
		RAppendPStringToPString( "\p\r line: ", out );
		RAppendLongToPString( line, out );
	}
	//	Errn line.
	if( errn ) {
		RAppendPStringToPString( "\p\r errn: ", out );
		RAppendLongToPString( errn, out );
	}
	//	Nmbr line.
	if( nmbr ) {
		RAppendPStringToPString( "\p\r nmbr: ", out );
		RAppendLongToPString( nmbr, out );
	}
	//	Code line.
	if( code ) {
		RAppendPStringToPString( "\p\r code: ", out );
		RAppendCStringToPString( code, out );
	}
	#undef	out
	
	if( IsDebuggerCallable() ) {
		DebugStr( outStr );
	} else if( !gNoteShowing ) {
		gNoteShowing = true;
		
		BlockMoveData( outStr, gNote.str, outStr[ 0 ] + 1 );
		gNote.nm.qType = nmType;
		gNote.nm.nmMark = 0;
		gNote.nm.nmIcon = nil;
		gNote.nm.nmSound = nil;
		gNote.nm.nmStr = gNote.str;
		gNote.nm.nmResp = gProc;
		gNote.nm.nmRefCon = SetCurrentA5();
		NMInstall( &gNote.nm );
	}
}

/****************************************************************************************
	Commenter	Date				Comment
	---------	-----------------	-----------------------------------------------------
	wolf		Sun, Jan 30, 2000	Created.
	
	Stolen from Debugging.h:
	
		"Tech Q&A PLAT-30 says to check bit 5 of the byte at 0xbff to
		determine whether Macsbug ( or any other low level debugger )
		is installed; I also check that MacJmp ( which points to the
		entry point for the debugger ) is not nil and not -1.

		MacJmpFlag:
			Bit 5 should be set to indicate the debugger is installed.
			Bit 6 should be set to indicate the debugger is initialized.
			Bit 7 should be clear to indicate that the debugger is NOT busy

		Dr. Macsbug says to also check that the byte at 0xBFF isn't 0xFF."
	
	This probably isn't kosher under Mac OS X...
	
	************************************************************************************/

	Boolean
IsDebuggerCallable()
{
	UInt32	macJmp = *(UInt32*)0x0120;
	UInt8	macJmpFlag = *(UInt8*)0x0BFF;
	
	return( macJmpFlag != 0xFF
			&& (macJmpFlag & 0xE0) == 0x60
			&& macJmp != 0
			&& macJmp != 0xFFFFFFFF );
}

/****************************************************************************************
	Commenter	Date				Comment
	---------	-----------------	-----------------------------------------------------
	wolf		Sat, Jan 29, 2000	Created.
	
	************************************************************************************/

	pascal
	void
NMDisplayProc(
	NMRecPtr	nmReqPtr )
{
	long	oldA5;
	OSErr	err = NMRemove( nmReqPtr );
	
	oldA5 = SetA5( nmReqPtr->nmRefCon );
	gNoteShowing = false;
	SetA5( oldA5 );
}



See more files for this project here

redshed

Code for Mac+WebObjects.

Project homepage: http://sourceforge.net/projects/redshed
Programming language(s): C,Java,Objective C
License: other

  requireToDebugger.c
  requireToDebuggerOrNote.c
  requireToNotification.c
  requireToOptionalDebugger.c