mac-rom/ProcessMgr/Utilities.c
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

333 lines
7.6 KiB
C

/*
File: Utilities.c
Contains: Utility routines that could be recoded in assembler for performance
Written by: Phil Goldman
Copyright: © 1986-1992 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<5> 3/23/92 JSM OSEvents.h is obsolete, use Events.h instead.
<4> 1/10/91 DFH Updated copyright years.
<3> 11/1/90 DFH Correct prototyping for DebuggerMsg().
<2> 10/31/90 DFH Got rid of warnings.
<1> 10/22/90 DFH First checked in.
<0> 12/15/86 PYG New Today.
*/
#include <types.h>
#include <quickdraw.h>
#include <memory.h>
#include <resources.h>
#include <toolutils.h>
#include <events.h>
#include "Glue.h"
#include "Lomem.h"
#include "Data.h"
#pragma segment kernel_segment
Handle GetRsrcHdlMatchingFirstLongword(long, long);
#ifdef MSWORKS_FIX
/* Set up app patch addr.
* NOTE: Assumes a5 == PROCESSMGRGLOBALS.
*/
ProcPtr
SetOverlayRecoverHandle(ProcPtr apptrap)
{
void OverlayRecoverHandle(void);
(*pCurrentProcess->p_pcb)->appRecoverHandlePatch = apptrap;
return ((ProcPtr) OverlayRecoverHandle);
}
ProcPtr
GetOverlayRecoverHandleOldTrap(void)
{
unsigned long olda5;
ProcPtr appRecoverHandlePatch;
olda5 = ProcessMgrA5SimpleSetup();
appRecoverHandlePatch = (*pCurrentProcess->p_pcb)->appRecoverHandlePatch;
A5SimpleRestore(olda5);
return appRecoverHandlePatch;
}
#endif MSWORKS_FIX
/* MemClear. Two-bit routine to clear 'bytes' bytes starting at *'ptr' */
void
MemClear(register Ptr ptr, register unsigned long bytes)
{
do
{
*ptr++ = (char) 0x00;
}
while (--bytes != 0);
}
/* StripLeadingNulls. Can you guess what it does?
* NOTE: It sets the last leading NULL to the length of the rest of the string,
* thereby altering the original string. Be careful! But you CAN restore
* the string by storing a NULL byte through the function result.
*/
StringPtr
StripLeadingNulls(StringPtr pString)
{
register Ptr pChar;
register unsigned char strSize;
strSize = Length(pString);
pChar = &StringByte(pString, 0);
while ((strSize != 0) && (*pChar == NULL))
{
--strSize;
pChar++;
}
if (strSize != Length(pString))
{
pString = (StringPtr) (--pChar);
Length(pString) = strSize;
}
return(pString);
}
/* NewMungedString. Copy pProtoStr into a NewString, and replace the 0th
* parameter substring with pSubStr.
*/
Handle
NewMungedString(StringPtr pSubStr, StringPtr pProtoStr)
{
unsigned long ParamZeroStr = TWO_CHAR_STRING('^','0');
StringPtr ptr1, ptr2;
unsigned long len1,len2;
StringHandle retVal;
if ((retVal = NewString(pProtoStr)) != nil)
{
ptr1 = (StringPtr) &ParamZeroStr;
len1 = (unsigned long) Length(ptr1);
ptr1 = &StringByte(ptr1, 0);
len2 = (long) Length(pSubStr);
ptr2 = &StringByte(pSubStr, 0);
(void)Munger(retVal,0,ptr1,len1,ptr2,len2);
if (MEMERROR == noErr)
Length((*retVal)) += len2 - len1;
else
{
DisposHandle(retVal);
retVal = nil;
}
}
return (retVal);
}
/* StrInStrList. Use specified function to check whether the specified string is
* "in" the specified list of strings.
*/
StringPtr
StrInStrList(Ptr strPtr, Ptr strListPtr, short cStrings, RelStringGluePtr relStringGluePtr)
{
while (--cStrings >= 0)
{
if ((*relStringGluePtr)(strListPtr, strPtr) == 0)
return(strListPtr);
strListPtr += Length(strListPtr) + 1;
}
return(nil);
}
/* GetRsrcHdlMatchingFirstLongword. Find the first resource of specified type that
* has the given value in its first long word. Scope is the entire resource chain.
*/
Handle
GetRsrcHdlMatchingFirstLongword(long resType, long firstLong)
{
Handle hdl;
short resIndex, resLast;
resLast = CountResources(resType);
for (resIndex = 1; resIndex <= resLast; resIndex++)
{
hdl = GetIndResource(resType, resIndex);
if (hdl != nil)
{
if (**((long **) hdl) == firstLong)
return (hdl);
ReleaseResource(hdl);
}
}
return (nil);
}
/* GetIconIDFromBundle. Figure out the icon family resource ID for the given type and
* creator. Starts at the current resource map. Uses the same search path that Finder
* does (FREF -> BNDL -> icon resource).
*/
short
GetIconIDFromBundle(OSType theType, unsigned long theCreator)
{
Ptr pRsrc;
short typeIndex, icnIndex;
Handle rsrcHdl;
short localID, globalID;
/* Find the FREF of the type */
rsrcHdl = GetRsrcHdlMatchingFirstLongword('FREF', theType);
if (rsrcHdl == nil)
return(0);
pRsrc = *rsrcHdl + 4;
localID = *((short *) pRsrc);
ReleaseResource(rsrcHdl);
/* Get the BNDL */
rsrcHdl = GetRsrcHdlMatchingFirstLongword('BNDL', theCreator);
if (rsrcHdl == nil)
return(0);
pRsrc = *rsrcHdl + 6;
/* Major loop -- find global id of icon in bundle */
globalID = 0;
for (typeIndex = *((short *) pRsrc)++; typeIndex >= 0; typeIndex--)
{
/* Is this type ICN# ? */
if (*((long *) pRsrc)++ == 'ICN#')
{
/* Minor loop - find a match for our given local ID and get it */
for (icnIndex = *((short *) pRsrc)++; icnIndex >= 0; icnIndex--)
{
if (*((short *) pRsrc)++ == localID)
{
/* Found it! */
globalID = *((short *) pRsrc);
break;
}
pRsrc += 2;
}
/* Either we found it or we looked at all icons */
break;
}
else
{
/* Skip over all of this type's resources, carefully because count
* is zero-based.
*/
((long *) pRsrc) += *((short *) pRsrc)++;
((long *) pRsrc)++;
}
}
/* Clean up and go */
ReleaseResource(rsrcHdl);
return(globalID);
}
/* OptionKeyIsDown. Figure out if the option-key is depressed. */
Boolean
OptionKeyIsDown(void)
{
EventRecord evtRecord;
(void) GetOSEvent(0, &evtRecord);
return((evtRecord.modifiers & optionKey) != 0);
}
#ifdef DEBUG
/* DebuggerMsg. Append message to file name and line number to and pass to debugger */
void
DebuggerMsg(char *cFileString, int debugLine, char *cMsgString)
{
register char *pch, *pch2;
Str255 totalMsgString;
static char assertFailureString[] = "Assertion Failure";
int len;
unsigned long olda5;
if (*((short *)0xF0) == 0x4E4F) /* 'NO' debugging */
return;
if (PROCESSMGRGLOBALS != (Ptr)(-1))
olda5 = ProcessMgrA5SimpleSetup();
/* Normalize C file string */
if (PROCESSMGRGLOBALS != (Ptr)(-1))
cFileString += ((long)PROCESSMGRGLOBALS - (long)olda5); /* Normalize this puppy (HAAAAAAACCK) */
/* Find length of file name (C string) */
len = 0;
pch = cFileString;
while (*pch++)
len++;
/* Stick it in buffer (P string) */
pch = &totalMsgString;
*pch++ = (char) (len + 5);
BlockMove(cFileString, pch, len);
pch += len;
*pch++ = '+';
/* Stick in the line number */
if (*pch = debugLine/1000)
{
debugLine -= (*pch)*1000;
*pch++ += '0';
Length(&totalMsgString)++;
}
if (*pch = debugLine/100)
{
debugLine -= (*pch)*100;
*pch++ += '0';
Length(&totalMsgString)++;
}
*pch = debugLine/10;
debugLine -= (*pch)*10;
*pch++ += '0';
*pch++ = debugLine + '0';
*pch++ = ':';
*pch++ = ' ';
/* Move in the old message */
if (cMsgString != NO_MESSAGE_ID)
{
if (cMsgString == ASSERTION_FAILURE_ID)
cMsgString = assertFailureString;
else
if (PROCESSMGRGLOBALS != (Ptr)(-1))
cMsgString += ((long)PROCESSMGRGLOBALS - (long)olda5); /* Normalize this puppy (HAAAAAAACCK) */
/* Find length of msg (C string) */
len = 0;
pch2 = cMsgString;
while (*pch2++)
len++;
/* Move it on in */
BlockMove(cMsgString, pch, len);
Length(&totalMsgString) += len;
}
/* Restore A5 */
if (PROCESSMGRGLOBALS != (Ptr)(-1))
A5SimpleRestore(olda5);
/* Call the trap (keep at end of routine so we can jump right back in flow of things) */
debugger(&totalMsgString);
}
#endif DEBUG