📄 msgfun.c
字号:
return(NULL);
}
/***********************************************************
NAME : FindHandlerByAddress
DESCRIPTION : Uses a binary search on a class's
handler header array
INPUTS : 1) The class address
2) The handler symbolic name
3) The handler type (MPRIMARY,etc.)
RETURNS : The index of the found handler,
-1 if not found
SIDE EFFECTS : None
NOTES : Assumes array is in ascending order
1st key: symbolic name of handler
2nd key: type of handler
***********************************************************/
globle int FindHandlerByIndex(
DEFCLASS *cls,
SYMBOL_HN *name,
unsigned type)
{
register int b;
unsigned i;
HANDLER *hnd;
unsigned *arr;
if ((b = FindHandlerNameGroup(cls,name)) == -1)
return(-1);
arr = cls->handlerOrderMap;
hnd = cls->handlers;
for (i = (unsigned) b ; i < cls->handlerCount ; i++)
{
if (hnd[arr[i]].name != name)
return(-1);
if (hnd[arr[i]].type == type)
return((int) arr[i]);
}
return(-1);
}
/*****************************************************
NAME : FindHandlerNameGroup
DESCRIPTION : Uses a binary search on a class's
handler header array
INPUTS : 1) The class address
2) The handler symbolic name
RETURNS : The index of the found handler group
-1 if not found
SIDE EFFECTS : None
NOTES : Assumes array is in ascending order
1st key: handler name symbol bucket
*****************************************************/
globle int FindHandlerNameGroup(
DEFCLASS *cls,
SYMBOL_HN *name)
{
register int b,e,i,j;
HANDLER *hnd;
unsigned *arr;
int start;
if (cls->handlerCount == 0)
return(-1);
hnd = cls->handlers;
arr = cls->handlerOrderMap;
b = 0;
e = (int) (cls->handlerCount-1);
start = -1;
do
{
i = (b+e)/2;
if (name->bucket == hnd[arr[i]].name->bucket)
{
for (j = i ; j >= b ; j--)
{
if (hnd[arr[j]].name == name)
start = j;
if (hnd[arr[j]].name->bucket != name->bucket)
break;
}
if (start != -1)
return(start);
for (j = i+1 ; j <= e ; j++)
{
if (hnd[arr[j]].name == name)
return(j);
if (hnd[arr[j]].name->bucket != name->bucket)
return(-1);
}
return(-1);
}
else if (name->bucket < hnd[arr[i]].name->bucket)
e = i-1;
else
b = i+1;
}
while (b <= e);
return(-1);
}
/***************************************************
NAME : HandlerDeleteError
DESCRIPTION : Prints out an error message when
handlers cannot be deleted
INPUTS : Name-string of the class
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : None
***************************************************/
globle void HandlerDeleteError(
void *theEnv,
char *cname)
{
PrintErrorID(theEnv,"MSGFUN",8,FALSE);
EnvPrintRouter(theEnv,WERROR,"Unable to delete message-handler(s) from class ");
EnvPrintRouter(theEnv,WERROR,cname);
EnvPrintRouter(theEnv,WERROR,".\n");
}
#if DEBUGGING_FUNCTIONS
/********************************************************************
NAME : DisplayCore
DESCRIPTION : Gives a schematic "printout" of the
core framework for a message showing
arounds, primaries, shadows etc.
This routine uses recursion to print indentation
to indicate shadowing and where handlers begin
and end execution wrt one another.
INPUTS : 1) Logical name of output
2) The remaining core
3) The number of handlers this (partial) core
shadows
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : Expects that the core was created in PREVIEW mode,
i.e. implicit handlers are SLOT_DESC addresses
(in PERFORM mode they are INSTANCE_SLOT addresses)
Assumes (partial) core is not empty
********************************************************************/
globle void DisplayCore(
void *theEnv,
char *logicalName,
HANDLER_LINK *core,
int sdepth)
{
if (core->hnd->type == MAROUND)
{
PrintPreviewHandler(theEnv,logicalName,core,sdepth,BEGIN_TRACE);
if (core->nxt != NULL)
DisplayCore(theEnv,logicalName,core->nxt,sdepth+1);
PrintPreviewHandler(theEnv,logicalName,core,sdepth,END_TRACE);
}
else
{
while ((core != NULL) ? (core->hnd->type == MBEFORE) : FALSE)
{
PrintPreviewHandler(theEnv,logicalName,core,sdepth,BEGIN_TRACE);
PrintPreviewHandler(theEnv,logicalName,core,sdepth,END_TRACE);
core = core->nxt;
}
if ((core != NULL) ? (core->hnd->type == MPRIMARY) : FALSE)
core = DisplayPrimaryCore(theEnv,logicalName,core,sdepth);
while ((core != NULL) ? (core->hnd->type == MAFTER) : FALSE)
{
PrintPreviewHandler(theEnv,logicalName,core,sdepth,BEGIN_TRACE);
PrintPreviewHandler(theEnv,logicalName,core,sdepth,END_TRACE);
core = core->nxt;
}
}
}
/*******************************************************************
NAME : FindPreviewApplicableHandlers
DESCRIPTION : See FindApplicableHandlers
However, this function only examines classes rather
than instances for implicit slot-accessors
INPUTS : 1) The class address
2) The message name symbol
RETURNS : The links of applicable handlers, NULL on errors
SIDE EFFECTS : Links are allocated for the list
NOTES : None
******************************************************************/
globle HANDLER_LINK *FindPreviewApplicableHandlers(
void *theEnv,
DEFCLASS *cls,
SYMBOL_HN *mname)
{
register int i;
HANDLER_LINK *tops[4],*bots[4];
for (i = MAROUND ; i <= MAFTER ; i++)
tops[i] = bots[i] = NULL;
for (i = 0 ; i < cls->allSuperclasses.classCount ; i++)
FindApplicableOfName(theEnv,cls->allSuperclasses.classArray[i],tops,bots,mname);
return(JoinHandlerLinks(theEnv,tops,bots,mname));
}
/***********************************************************
NAME : WatchMessage
DESCRIPTION : Prints a condensed description of a
message and its arguments
INPUTS : 1) The output logical name
2) BEGIN_TRACE or END_TRACE string
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : Uses the global variables ProcParamArray
and CurrentMessageName
***********************************************************/
globle void WatchMessage(
void *theEnv,
char *logName,
char *tstring)
{
EnvPrintRouter(theEnv,logName,"MSG ");
EnvPrintRouter(theEnv,logName,tstring);
EnvPrintRouter(theEnv,logName," ");
EnvPrintRouter(theEnv,logName,ValueToString(MessageHandlerData(theEnv)->CurrentMessageName));
EnvPrintRouter(theEnv,logName," ED:");
PrintLongInteger(theEnv,logName,(long) EvaluationData(theEnv)->CurrentEvaluationDepth);
PrintProcParamArray(theEnv,logName);
}
/***********************************************************
NAME : WatchHandler
DESCRIPTION : Prints a condensed description of a
message-handler and its arguments
INPUTS : 1) The output logical name
2) The handler address
3) BEGIN_TRACE or END_TRACE string
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : Uses the global variables ProcParamArray
and CurrentMessageName
***********************************************************/
globle void WatchHandler(
void *theEnv,
char *logName,
HANDLER_LINK *hndl,
char *tstring)
{
HANDLER *hnd;
EnvPrintRouter(theEnv,logName,"HND ");
EnvPrintRouter(theEnv,logName,tstring);
EnvPrintRouter(theEnv,logName," ");
hnd = hndl->hnd;
PrintHandler(theEnv,WTRACE,hnd,TRUE);
EnvPrintRouter(theEnv,logName," ED:");
PrintLongInteger(theEnv,logName,(long) EvaluationData(theEnv)->CurrentEvaluationDepth);
PrintProcParamArray(theEnv,logName);
}
#endif /* DEBUGGING_FUNCTIONS */
/* =========================================
*****************************************
INTERNALLY VISIBLE FUNCTIONS
=========================================
***************************************** */
#if DEBUGGING_FUNCTIONS
/********************************************************************
NAME : DisplayPrimaryCore
DESCRIPTION : Gives a schematic "printout" of the primary
message showing other shadowed primaries
This routine uses recursion to print indentation
to indicate shadowing and where handlers begin
and end execution wrt one another.
INPUTS : 1) The logical name of the output
2) The remaining core
3) The number of handlers this (partial) core
shadows
RETURNS : The address of the handler following the primary
group of handlers in the core
SIDE EFFECTS : None
NOTES : Expects that the core was created in PREVIEW mode,
i.e. implicit handlers are SLOT_DESC addresses
(in PERFORM mode they are INSTANCE_SLOT addresses)
Assumes (partial) core is not empty
********************************************************************/
static HANDLER_LINK *DisplayPrimaryCore(
void *theEnv,
char *logicalName,
HANDLER_LINK *core,
int pdepth)
{
register HANDLER_LINK *rtn;
PrintPreviewHandler(theEnv,logicalName,core,pdepth,BEGIN_TRACE);
if ((core->nxt != NULL) ? (core->nxt->hnd->type == MPRIMARY) : FALSE)
rtn = DisplayPrimaryCore(theEnv,logicalName,core->nxt,pdepth+1);
else
rtn = core->nxt;
PrintPreviewHandler(theEnv,logicalName,core,pdepth,END_TRACE);
return(rtn);
}
/***************************************************
NAME : PrintPreviewHandler
DESCRIPTION : Displays a message preview
INPUTS : 1) The logical name of the output
2) Handler-link
3) Number of handlers shadowed
4) The trace-string
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : None
***************************************************/
static void PrintPreviewHandler(
void *theEnv,
char *logicalName,
HANDLER_LINK *cptr,
int sdepth,
char *tstr)
{
register int i;
for (i = 0 ; i < sdepth ; i++)
EnvPrintRouter(theEnv,logicalName,"| ");
EnvPrintRouter(theEnv,logicalName,tstr);
EnvPrintRouter(theEnv,logicalName," ");
PrintHandler(theEnv,logicalName,cptr->hnd,TRUE);
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -