#include "setup.h"
#if OBJECT_SYSTEM
#include <string.h>
#include "argacces.h"
#if BLOAD || BLOAD_AND_BSAVE
#include "bload.h"
#endif
#include "classcom.h"
#include "classfun.h"
#include "classinf.h"
#if (! BLOAD_ONLY) && (! RUN_TIME)
#include "constrct.h"
#include "msgpsr.h"
#endif
#include "envrnmnt.h"
#if ! RUN_TIME
#include "extnfunc.h"
#endif
#include "insfun.h"
#include "insmoddp.h"
#include "msgfun.h"
#include "msgpass.h"
#include "memalloc.h"
#include "prccode.h"
#include "prntutil.h"
#include "router.h"
#if DEBUGGING_FUNCTIONS
#include "watch.h"
#endif
#include "msgcom.h"
#if ! RUN_TIME
static void CreateSystemHandlers(Environment *,void *);
#endif
#if (! BLOAD_ONLY) && (! RUN_TIME)
static bool WildDeleteHandler(Environment *,Defclass *,CLIPSLexeme *,const char *);
#endif
#if DEBUGGING_FUNCTIONS
static bool DefmessageHandlerWatchAccess(Environment *,int,bool,Expression *);
static bool DefmessageHandlerWatchPrint(Environment *,const char *,int,Expression *);
static bool DefmessageHandlerWatchSupport(Environment *,const char *,const char *,bool,
void (*)(Environment *,const char *,Defclass *,unsigned),
void (*)(Defclass *,unsigned,bool),
Expression *);
static bool WatchClassHandlers(Environment *,Defclass *,const char *,int,const char *,bool,bool,
void (*)(Environment *,const char *,Defclass *,unsigned),
void (*)(Defclass *,unsigned,bool));
static void PrintHandlerWatchFlag(Environment *,const char *,Defclass *,unsigned);
#endif
static void DeallocateMessageHandlerData(Environment *);
void SetupMessageHandlers(
Environment *theEnv)
{
EntityRecord handlerGetInfo = { "HANDLER_GET", HANDLER_GET,0,1,1,
PrintHandlerSlotGetFunction,
PrintHandlerSlotGetFunction,NULL,
HandlerSlotGetFunction,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL },
handlerPutInfo = { "HANDLER_PUT", HANDLER_PUT,0,1,1,
PrintHandlerSlotPutFunction,
PrintHandlerSlotPutFunction,NULL,
HandlerSlotPutFunction,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
AllocateEnvironmentData(theEnv,MESSAGE_HANDLER_DATA,sizeof(struct messageHandlerData),DeallocateMessageHandlerData);
memcpy(&MessageHandlerData(theEnv)->HandlerGetInfo,&handlerGetInfo,sizeof(struct entityRecord));
memcpy(&MessageHandlerData(theEnv)->HandlerPutInfo,&handlerPutInfo,sizeof(struct entityRecord));
MessageHandlerData(theEnv)->hndquals[0] = "around";
MessageHandlerData(theEnv)->hndquals[1] = "before";
MessageHandlerData(theEnv)->hndquals[2] = "primary";
MessageHandlerData(theEnv)->hndquals[3] = "after";
InstallPrimitive(theEnv,&MessageHandlerData(theEnv)->HandlerGetInfo,HANDLER_GET);
InstallPrimitive(theEnv,&MessageHandlerData(theEnv)->HandlerPutInfo,HANDLER_PUT);
#if ! RUN_TIME
MessageHandlerData(theEnv)->INIT_SYMBOL = CreateSymbol(theEnv,INIT_STRING);
IncrementLexemeCount(MessageHandlerData(theEnv)->INIT_SYMBOL);
MessageHandlerData(theEnv)->DELETE_SYMBOL = CreateSymbol(theEnv,DELETE_STRING);
IncrementLexemeCount(MessageHandlerData(theEnv)->DELETE_SYMBOL);
MessageHandlerData(theEnv)->CREATE_SYMBOL = CreateSymbol(theEnv,CREATE_STRING);
IncrementLexemeCount(MessageHandlerData(theEnv)->CREATE_SYMBOL);
AddClearFunction(theEnv,"defclass",CreateSystemHandlers,-100,NULL);
#if ! BLOAD_ONLY
MessageHandlerData(theEnv)->SELF_SYMBOL = CreateSymbol(theEnv,SELF_STRING);
IncrementLexemeCount(MessageHandlerData(theEnv)->SELF_SYMBOL);
AddConstruct(theEnv,"defmessage-handler","defmessage-handlers",
ParseDefmessageHandler,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
AddUDF(theEnv,"undefmessage-handler","v",2,3,"y",UndefmessageHandlerCommand,"UndefmessageHandlerCommand",NULL);
#endif
AddUDF(theEnv,"send","*",2,UNBOUNDED,"*;*;y",SendCommand,"SendCommand",NULL);
#if DEBUGGING_FUNCTIONS
AddUDF(theEnv,"preview-send","v",2,2,"y",PreviewSendCommand,"PreviewSendCommand",NULL);
AddUDF(theEnv,"ppdefmessage-handler","v",2,4,"y",PPDefmessageHandlerCommand,"PPDefmessageHandlerCommand",NULL);
AddUDF(theEnv,"list-defmessage-handlers","v",0,2,"y",ListDefmessageHandlersCommand,"ListDefmessageHandlersCommand",NULL);
#endif
AddUDF(theEnv,"next-handlerp","b",0,0,NULL,NextHandlerAvailableFunction,"NextHandlerAvailableFunction",NULL);
FuncSeqOvlFlags(theEnv,"next-handlerp",true,false);
AddUDF(theEnv,"call-next-handler","*",0,0,NULL,CallNextHandler,"CallNextHandler",NULL);
FuncSeqOvlFlags(theEnv,"call-next-handler",true,false);
AddUDF(theEnv,"override-next-handler","*",0,UNBOUNDED,NULL,CallNextHandler,"CallNextHandler",NULL);
FuncSeqOvlFlags(theEnv,"override-next-handler",true,false);
AddUDF(theEnv,"dynamic-get","*",1,1,"y",DynamicHandlerGetSlot,"DynamicHandlerGetSlot",NULL);
AddUDF(theEnv,"dynamic-put","*",1,UNBOUNDED,"*;y",DynamicHandlerPutSlot,"DynamicHandlerPutSlot",NULL);
AddUDF(theEnv,"get","*",1,1,"y",DynamicHandlerGetSlot,"DynamicHandlerGetSlot",NULL);
AddUDF(theEnv,"put","*",1,UNBOUNDED,"*;y",DynamicHandlerPutSlot,"DynamicHandlerPutSlot",NULL);
#endif
#if DEBUGGING_FUNCTIONS
AddWatchItem(theEnv,"messages",0,&MessageHandlerData(theEnv)->WatchMessages,36,NULL,NULL);
AddWatchItem(theEnv,"message-handlers",0,&MessageHandlerData(theEnv)->WatchHandlers,35,
DefmessageHandlerWatchAccess,DefmessageHandlerWatchPrint);
#endif
}
static void DeallocateMessageHandlerData(
Environment *theEnv)
{
HANDLER_LINK *tmp, *mhead, *chead;
mhead = MessageHandlerData(theEnv)->TopOfCore;
while (mhead != NULL)
{
tmp = mhead;
mhead = mhead->nxt;
rtn_struct(theEnv,messageHandlerLink,tmp);
}
chead = MessageHandlerData(theEnv)->OldCore;
while (chead != NULL)
{
mhead = chead;
chead = chead->nxtInStack;
while (mhead != NULL)
{
tmp = mhead;
mhead = mhead->nxt;
rtn_struct(theEnv,messageHandlerLink,tmp);
}
}
}
const char *DefmessageHandlerName(
Defclass *theDefclass,
unsigned theIndex)
{
return theDefclass->handlers[theIndex-1].header.name->contents;
}
const char *DefmessageHandlerType(
Defclass *theDefclass,
unsigned theIndex)
{
Environment *theEnv = theDefclass->header.env;
return MessageHandlerData(theEnv)->hndquals[theDefclass->handlers[theIndex-1].type];
}
unsigned GetNextDefmessageHandler(
Defclass *theDefclass,
unsigned theIndex)
{
if (theIndex == 0)
{ return (theDefclass->handlers != NULL) ? 1 : 0; }
if (theIndex == theDefclass->handlerCount)
{ return 0; }
return theIndex+1;
}
DefmessageHandler *GetDefmessageHandlerPointer(
Defclass *theDefclass,
unsigned int theIndex)
{
return &theDefclass->handlers[theIndex-1];
}
#if DEBUGGING_FUNCTIONS
bool DefmessageHandlerGetWatch(
Defclass *theDefclass,
unsigned theIndex)
{
return theDefclass->handlers[theIndex-1].trace;
}
void DefmessageHandlerSetWatch(
Defclass *theClass,
unsigned theIndex,
bool newState)
{
theClass->handlers[theIndex-1].trace = newState;
}
#endif
unsigned FindDefmessageHandler(
Defclass *theDefclass,
const char *hname,
const char *htypestr)
{
unsigned htype;
CLIPSLexeme *hsym;
int theIndex;
Environment *theEnv = theDefclass->header.env;
htype = HandlerType(theEnv,"handler-lookup",false,htypestr);
if (htype == MERROR)
{ return 0; }
hsym = FindSymbolHN(theEnv,hname,SYMBOL_BIT);
if (hsym == NULL)
{ return 0; }
theIndex = FindHandlerByIndex(theDefclass,hsym,htype);
return (unsigned) (theIndex+1);
}
bool DefmessageHandlerIsDeletable(
Defclass *theDefclass,
unsigned theIndex)
{
Environment *theEnv = theDefclass->header.env;
if (! ConstructsDeletable(theEnv))
{ return false; }
if (theDefclass->handlers[theIndex-1].system == 1)
{ return false; }
#if (! BLOAD_ONLY) && (! RUN_TIME)
return (HandlersExecuting(theDefclass) == false) ? true : false;
#else
return false;
#endif
}
void UndefmessageHandlerCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
#if RUN_TIME || BLOAD_ONLY
PrintErrorID(theEnv,"MSGCOM",3,false);
WriteString(theEnv,STDERR,"Unable to delete message-handlers.\n");
#else
CLIPSLexeme *mname;
const char *tname;
UDFValue theArg;
Defclass *cls;
#if BLOAD || BLOAD_AND_BSAVE
if (Bloaded(theEnv))
{
PrintErrorID(theEnv,"MSGCOM",3,false);
WriteString(theEnv,STDERR,"Unable to delete message-handlers.\n");
return;
}
#endif
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg)) return;
cls = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
if ((cls == NULL) ? (strcmp(theArg.lexemeValue->contents,"*") != 0) : false)
{
ClassExistError(theEnv,"undefmessage-handler",theArg.lexemeValue->contents);
return;
}
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg)) return;
mname = theArg.lexemeValue;
if (UDFHasNextArgument(context))
{
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg)) return;
tname = theArg.lexemeValue->contents;
if (strcmp(tname,"*") == 0)
tname = NULL;
}
else
tname = MessageHandlerData(theEnv)->hndquals[MPRIMARY];
WildDeleteHandler(theEnv,cls,mname,tname);
#endif
}
bool UndefmessageHandler(
Defclass *theDefclass,
unsigned mhi,
Environment *allEnv)
{
Environment *theEnv;
#if (! RUN_TIME) && (! BLOAD_ONLY)
bool success;
GCBlock gcb;
#endif
if (theDefclass == NULL)
{ theEnv = allEnv; }
else
{ theEnv = theDefclass->header.env; }
#if RUN_TIME || BLOAD_ONLY
PrintErrorID(theEnv,"MSGCOM",3,false);
WriteString(theEnv,STDERR,"Unable to delete message-handlers.\n");
return false;
#else
#if BLOAD || BLOAD_AND_BSAVE
if (Bloaded(theEnv))
{
PrintErrorID(theEnv,"MSGCOM",3,false);
WriteString(theEnv,STDERR,"Unable to delete message-handlers.\n");
return false;
}
#endif
GCBlockStart(theEnv,&gcb);
if (theDefclass == NULL)
{
if (mhi != 0)
{
PrintErrorID(theEnv,"MSGCOM",1,false);
WriteString(theEnv,STDERR,"Incomplete message-handler specification for deletion.\n");
GCBlockEnd(theEnv,&gcb);
return false;
}
success = WildDeleteHandler(theEnv,NULL,NULL,NULL);
GCBlockEnd(theEnv,&gcb);
return success;
}
if (mhi == 0)
{
success = WildDeleteHandler(theEnv,theDefclass,NULL,NULL);
GCBlockEnd(theEnv,&gcb);
return success;
}
if (HandlersExecuting(theDefclass))
{
HandlerDeleteError(theEnv,DefclassName(theDefclass));
GCBlockEnd(theEnv,&gcb);
return false;
}
theDefclass->handlers[mhi-1].mark = 1;
DeallocateMarkedHandlers(theEnv,theDefclass);
GCBlockEnd(theEnv,&gcb);
return true;
#endif
}
#if DEBUGGING_FUNCTIONS
void PPDefmessageHandlerCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
UDFValue theArg;
CLIPSLexeme *csym, *msym;
const char *tname;
const char *logicalName;
Defclass *cls = NULL;
unsigned mtype;
DefmessageHandler *hnd = NULL;
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
{ return; }
csym = FindSymbolHN(theEnv,theArg.lexemeValue->contents,SYMBOL_BIT);
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
{ return; }
msym = FindSymbolHN(theEnv,theArg.lexemeValue->contents,SYMBOL_BIT);
if (UDFHasNextArgument(context))
{
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
{ return; }
tname = theArg.lexemeValue->contents;
}
else
tname = MessageHandlerData(theEnv)->hndquals[MPRIMARY];
mtype = HandlerType(theEnv,"ppdefmessage-handler",true,tname);
if (mtype == MERROR)
{
SetEvaluationError(theEnv,true);
return;
}
if (UDFHasNextArgument(context))
{
logicalName = GetLogicalName(context,STDOUT);
if (logicalName == NULL)
{
IllegalLogicalNameMessage(theEnv,"ppdefmessage-handler");
SetHaltExecution(theEnv,true);
SetEvaluationError(theEnv,true);
return;
}
}
else
{ logicalName = STDOUT; }
if (csym != NULL)
cls = LookupDefclassByMdlOrScope(theEnv,csym->contents);
if (((cls == NULL) || (msym == NULL)) ? true :
((hnd = FindHandlerByAddress(cls,msym,mtype)) == NULL))
{
PrintErrorID(theEnv,"MSGCOM",2,false);
WriteString(theEnv,STDERR,"Unable to find message-handler '");
WriteString(theEnv,STDERR,msym->contents);
WriteString(theEnv,STDERR,"' ");
WriteString(theEnv,STDERR,tname);
WriteString(theEnv,STDERR," for class '");
WriteString(theEnv,STDERR,csym->contents);
WriteString(theEnv,STDERR,"' in function 'ppdefmessage-handler'.\n");
SetEvaluationError(theEnv,true);
return;
}
if (strcmp(logicalName,"nil") == 0)
{
if (hnd->header.ppForm != NULL)
{ returnValue->lexemeValue = CreateString(theEnv,hnd->header.ppForm); }
else
{ returnValue->lexemeValue = CreateString(theEnv,""); }
}
else
{
if (hnd->header.ppForm != NULL)
WriteString(theEnv,logicalName,hnd->header.ppForm);
}
}
void ListDefmessageHandlersCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
bool inhp;
Defclass *clsptr;
if (UDFArgumentCount(context) == 0)
ListDefmessageHandlers(theEnv,NULL,STDOUT,false);
else
{
clsptr = ClassInfoFnxArgs(context,"list-defmessage-handlers",&inhp);
if (clsptr == NULL)
return;
ListDefmessageHandlers(theEnv,clsptr,STDOUT,inhp);
}
}
void PreviewSendCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
Defclass *cls;
UDFValue theArg;
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
{ return; }
cls = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
if (cls == NULL)
{
ClassExistError(theEnv,"preview-send",theArg.lexemeValue->contents);
return;
}
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
{ return; }
PreviewSend(cls,STDOUT,theArg.lexemeValue->contents);
}
const char *DefmessageHandlerPPForm(
Defclass *theDefclass,
unsigned theIndex)
{
return theDefclass->handlers[theIndex-1].header.ppForm;
}
void ListDefmessageHandlers(
Environment *theEnv,
Defclass *theDefclass,
const char *logName,
bool inhp)
{
unsigned long cnt;
PACKED_CLASS_LINKS plinks;
if (theDefclass != NULL)
{
if (inhp)
{ cnt = DisplayHandlersInLinks(theEnv,logName,&theDefclass->allSuperclasses,0); }
else
{
plinks.classCount = 1;
plinks.classArray = &theDefclass;
cnt = DisplayHandlersInLinks(theEnv,logName,&plinks,0);
}
}
else
{
plinks.classCount = 1;
cnt = 0L;
for (theDefclass = GetNextDefclass(theEnv,NULL) ;
theDefclass != NULL ;
theDefclass = GetNextDefclass(theEnv,theDefclass))
{
plinks.classArray = &theDefclass;
cnt += DisplayHandlersInLinks(theEnv,logName,&plinks,0);
}
}
PrintTally(theEnv,logName,cnt,"message-handler","message-handlers");
}
void PreviewSend(
Defclass *theDefclass,
const char *logicalName,
const char *msgname)
{
HANDLER_LINK *core;
CLIPSLexeme *msym;
Environment *theEnv = theDefclass->header.env;
msym = FindSymbolHN(theEnv,msgname,SYMBOL_BIT);
if (msym == NULL)
{ return; }
core = FindPreviewApplicableHandlers(theEnv,theDefclass,msym);
if (core != NULL)
{
DisplayCore(theEnv,logicalName,core,0);
DestroyHandlerLinks(theEnv,core);
}
}
unsigned long DisplayHandlersInLinks(
Environment *theEnv,
const char *logName,
PACKED_CLASS_LINKS *plinks,
unsigned int theIndex)
{
unsigned long i;
unsigned long cnt;
cnt = plinks->classArray[theIndex]->handlerCount;
if ((theIndex + 1) < plinks->classCount)
cnt += DisplayHandlersInLinks(theEnv,logName,plinks,theIndex + 1);
for (i = 0 ; i < plinks->classArray[theIndex]->handlerCount ; i++)
PrintHandler(theEnv,logName,&plinks->classArray[theIndex]->handlers[i],false,true);
return cnt;
}
#endif
#if ! RUN_TIME
static void CreateSystemHandlers(
Environment *theEnv,
void *context)
{
NewSystemHandler(theEnv,USER_TYPE_NAME,INIT_STRING,"init-slots",0);
NewSystemHandler(theEnv,USER_TYPE_NAME,DELETE_STRING,"delete-instance",0);
NewSystemHandler(theEnv,USER_TYPE_NAME,CREATE_STRING,"(create-instance)",0);
#if DEBUGGING_FUNCTIONS
NewSystemHandler(theEnv,USER_TYPE_NAME,PRINT_STRING,"ppinstance",0);
#endif
NewSystemHandler(theEnv,USER_TYPE_NAME,DIRECT_MODIFY_STRING,"(direct-modify)",1);
NewSystemHandler(theEnv,USER_TYPE_NAME,MSG_MODIFY_STRING,"(message-modify)",1);
NewSystemHandler(theEnv,USER_TYPE_NAME,DIRECT_DUPLICATE_STRING,"(direct-duplicate)",2);
NewSystemHandler(theEnv,USER_TYPE_NAME,MSG_DUPLICATE_STRING,"(message-duplicate)",2);
}
#endif
#if (! BLOAD_ONLY) && (! RUN_TIME)
static bool WildDeleteHandler(
Environment *theEnv,
Defclass *cls,
CLIPSLexeme *msym,
const char *tname)
{
int mtype;
if (msym == NULL)
msym = CreateSymbol(theEnv,"*");
if (tname != NULL)
{
mtype = (int) HandlerType(theEnv,"undefmessage-handler",true,tname);
if (mtype == MERROR)
return false;
}
else
mtype = -1;
if (cls == NULL)
{
bool success = true;
for (cls = GetNextDefclass(theEnv,NULL) ;
cls != NULL ;
cls = GetNextDefclass(theEnv,cls))
if (DeleteHandler(theEnv,cls,msym,mtype,false) == false)
success = false;
return(success);
}
return(DeleteHandler(theEnv,cls,msym,mtype,true));
}
#endif
#if DEBUGGING_FUNCTIONS
static bool DefmessageHandlerWatchAccess(
Environment *theEnv,
int code,
bool newState,
Expression *argExprs)
{
#if MAC_XCD
#pragma unused(code)
#endif
if (newState)
return(DefmessageHandlerWatchSupport(theEnv,"watch",NULL,newState,
NULL,DefmessageHandlerSetWatch,argExprs));
else
return(DefmessageHandlerWatchSupport(theEnv,"unwatch",NULL,newState,
NULL,DefmessageHandlerSetWatch,argExprs));
}
static bool DefmessageHandlerWatchPrint(
Environment *theEnv,
const char *logName,
int code,
Expression *argExprs)
{
#if MAC_XCD
#pragma unused(code)
#endif
return DefmessageHandlerWatchSupport(theEnv,"list-watch-items",logName,false,
PrintHandlerWatchFlag,NULL,argExprs);
}
static bool DefmessageHandlerWatchSupport(
Environment *theEnv,
const char *funcName,
const char *logName,
bool newState,
void (*printFunc)(Environment *,const char *,Defclass *,unsigned),
void (*traceFunc)(Defclass *,unsigned,bool),
Expression *argExprs)
{
Defmodule *theModule;
Defclass *theClass;
const char *theHandlerStr;
int theType;
unsigned int argIndex = 2;
UDFValue tmpData;
if (argExprs == NULL)
{
SaveCurrentModule(theEnv);
theModule = GetNextDefmodule(theEnv,NULL);
while (theModule != NULL)
{
SetCurrentModule(theEnv,theModule);
if (traceFunc == NULL)
{
WriteString(theEnv,logName,DefmoduleName(theModule));
WriteString(theEnv,logName,":\n");
}
theClass = GetNextDefclass(theEnv,NULL);
while (theClass != NULL)
{
if (WatchClassHandlers(theEnv,theClass,NULL,-1,logName,newState,
true,printFunc,traceFunc) == false)
return false;
theClass = GetNextDefclass(theEnv,theClass);
}
theModule = GetNextDefmodule(theEnv,theModule);
}
RestoreCurrentModule(theEnv);
return true;
}
while (argExprs != NULL)
{
if (EvaluateExpression(theEnv,argExprs,&tmpData))
return false;
if (tmpData.header->type != SYMBOL_TYPE)
{
ExpectedTypeError1(theEnv,funcName,argIndex,"'class name'");
return false;
}
theClass = LookupDefclassByMdlOrScope(theEnv,tmpData.lexemeValue->contents);
if (theClass == NULL)
{
ExpectedTypeError1(theEnv,funcName,argIndex,"'class name'");
return false;
}
if (GetNextArgument(argExprs) != NULL)
{
argExprs = GetNextArgument(argExprs);
argIndex++;
if (EvaluateExpression(theEnv,argExprs,&tmpData))
return false;
if (tmpData.header->type != SYMBOL_TYPE)
{
ExpectedTypeError1(theEnv,funcName,argIndex,"'handler name'");
return false;
}
theHandlerStr = tmpData.lexemeValue->contents;
if (GetNextArgument(argExprs) != NULL)
{
argExprs = GetNextArgument(argExprs);
argIndex++;
if (EvaluateExpression(theEnv,argExprs,&tmpData))
return false;
if (tmpData.header->type != SYMBOL_TYPE)
{
ExpectedTypeError1(theEnv,funcName,argIndex,"'handler type'");
return false;
}
if ((theType = (int) HandlerType(theEnv,funcName,true,tmpData.lexemeValue->contents)) == MERROR)
return false;
}
else
theType = -1;
}
else
{
theHandlerStr = NULL;
theType = -1;
}
if (WatchClassHandlers(theEnv,theClass,theHandlerStr,theType,logName,
newState,false,printFunc,traceFunc) == false)
{
ExpectedTypeError1(theEnv,funcName,argIndex,"handler");
return false;
}
argIndex++;
argExprs = GetNextArgument(argExprs);
}
return true;
}
static bool WatchClassHandlers(
Environment *theEnv,
Defclass *theClass,
const char *theHandlerStr,
int theType,
const char *logName,
bool newState,
bool indentp,
void (*printFunc)(Environment *,const char *,Defclass *,unsigned),
void (*traceFunc)(Defclass *,unsigned,bool))
{
unsigned theHandler;
bool found = false;
theHandler = GetNextDefmessageHandler(theClass,0);
while (theHandler != 0)
{
if ((theType == -1) ? true :
(theType == (int) theClass->handlers[theHandler-1].type))
{
if ((theHandlerStr == NULL) ? true :
(strcmp(theHandlerStr,DefmessageHandlerName(theClass,theHandler)) == 0))
{
if (traceFunc != NULL)
(*traceFunc)(theClass,theHandler,newState);
else
{
if (indentp)
WriteString(theEnv,logName," ");
(*printFunc)(theEnv,logName,theClass,theHandler);
}
found = true;
}
}
theHandler = GetNextDefmessageHandler(theClass,theHandler);
}
if ((theHandlerStr != NULL) && (theType != -1) && (found == false))
return false;
return true;
}
static void PrintHandlerWatchFlag(
Environment *theEnv,
const char *logName,
Defclass *theClass,
unsigned theHandler)
{
WriteString(theEnv,logName,DefclassName(theClass));
WriteString(theEnv,logName," ");
WriteString(theEnv,logName,DefmessageHandlerName(theClass,theHandler));
WriteString(theEnv,logName," ");
WriteString(theEnv,logName,DefmessageHandlerType(theClass,theHandler));
if (DefmessageHandlerGetWatch(theClass,theHandler))
WriteString(theEnv,logName," = on\n");
else
WriteString(theEnv,logName," = off\n");
}
#endif
#endif