?? msgfun.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 05/17/06 */ /* */ /* OBJECT MESSAGE FUNCTIONS */ /*******************************************************//*************************************************************//* Purpose: *//* *//* Principal Programmer(s): *//* Brian L. Donnell *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* 6.23: Changed name of variable log to logName *//* because of Unix compiler warnings of shadowed *//* definitions. *//* *//* 6.24: Removed IMPERATIVE_MESSAGE_HANDLERS and *//* AUXILIARY_MESSAGE_HANDLERS compilation flags. *//* *//* Renamed BOOLEAN macro type to intBool. *//* *//*************************************************************//* ========================================= ***************************************** EXTERNAL DEFINITIONS ========================================= ***************************************** */#include "setup.h"#if OBJECT_SYSTEM#include "classcom.h"#include "classfun.h"#include "memalloc.h"#include "envrnmnt.h"#include "extnfunc.h"#include "insfun.h"#include "msgcom.h"#include "prccode.h"#include "router.h"#define _MSGFUN_SOURCE_#include "msgfun.h"/* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTION HEADERS ========================================= ***************************************** */#if DEBUGGING_FUNCTIONSstatic HANDLER_LINK *DisplayPrimaryCore(void *,char *,HANDLER_LINK *,int);static void PrintPreviewHandler(void *,char *,HANDLER_LINK *,int,char *);#endif/* ========================================= ***************************************** EXTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** *//******************************************************** NAME : UnboundHandlerErr DESCRIPTION : Print out a synopis of the currently executing handler for unbound variable errors INPUTS : None RETURNS : Nothing useful SIDE EFFECTS : Error synopsis printed to WERROR NOTES : None ********************************************************/globle void UnboundHandlerErr( void *theEnv) { EnvPrintRouter(theEnv,WERROR,"message-handler "); PrintHandler(theEnv,WERROR,MessageHandlerData(theEnv)->CurrentCore->hnd,TRUE); }/***************************************************************** NAME : PrintNoHandlerError DESCRIPTION : Print "No primaries found" error message for send INPUTS : The name of the message RETURNS : Nothing useful SIDE EFFECTS : None NOTES : None *****************************************************************/globle void PrintNoHandlerError( void *theEnv, char *msg) { PrintErrorID(theEnv,"MSGFUN",1,FALSE); EnvPrintRouter(theEnv,WERROR,"No applicable primary message-handlers found for "); EnvPrintRouter(theEnv,WERROR,msg); EnvPrintRouter(theEnv,WERROR,".\n"); }/*************************************************************** NAME : CheckHandlerArgCount DESCRIPTION : Verifies that the current argument list satisfies the current handler's parameter count restriction INPUTS : None RETURNS : TRUE if all OK, FALSE otherwise SIDE EFFECTS : EvaluationError set on errors NOTES : Uses ProcParamArraySize and CurrentCore globals ***************************************************************/globle int CheckHandlerArgCount( void *theEnv) { HANDLER *hnd; hnd = MessageHandlerData(theEnv)->CurrentCore->hnd; if ((hnd->maxParams == -1) ? (ProceduralPrimitiveData(theEnv)->ProcParamArraySize < hnd->minParams) : (ProceduralPrimitiveData(theEnv)->ProcParamArraySize != hnd->minParams)) { SetEvaluationError(theEnv,TRUE); PrintErrorID(theEnv,"MSGFUN",2,FALSE); EnvPrintRouter(theEnv,WERROR,"Message-handler "); EnvPrintRouter(theEnv,WERROR,ValueToString(hnd->name)); EnvPrintRouter(theEnv,WERROR," "); EnvPrintRouter(theEnv,WERROR,MessageHandlerData(theEnv)->hndquals[hnd->type]); EnvPrintRouter(theEnv,WERROR," in class "); EnvPrintRouter(theEnv,WERROR,EnvGetDefclassName(theEnv,(void *) hnd->cls)); EnvPrintRouter(theEnv,WERROR," expected "); EnvPrintRouter(theEnv,WERROR,(char *) ((hnd->maxParams == -1) ? "at least " : "exactly ")); PrintLongInteger(theEnv,WERROR,(long long) (hnd->minParams-1)); EnvPrintRouter(theEnv,WERROR," argument(s).\n"); return(FALSE); } return(TRUE); }/*************************************************** NAME : SlotAccessViolationError DESCRIPTION : Prints out an error message when attempt is made to set a read-only or initialize-only slot improperly INPUTS : 1) The slot name 2) A flag indicating if the source is a class or an instance 3) A pointer to the source instance/class RETURNS : Nothing useful SIDE EFFECTS : Error message printed NOTES : None ***************************************************/globle void SlotAccessViolationError( void *theEnv, char *slotName, intBool instanceFlag, void *theInstanceOrClass) { PrintErrorID(theEnv,"MSGFUN",3,FALSE); EnvPrintRouter(theEnv,WERROR,slotName); EnvPrintRouter(theEnv,WERROR," slot in "); if (instanceFlag) PrintInstanceNameAndClass(theEnv,WERROR,(INSTANCE_TYPE *) theInstanceOrClass,FALSE); else { EnvPrintRouter(theEnv,WERROR,"class "); PrintClassName(theEnv,WERROR,(DEFCLASS *) theInstanceOrClass,FALSE); } EnvPrintRouter(theEnv,WERROR,": write access denied.\n"); }/*************************************************** NAME : SlotVisibilityViolationError DESCRIPTION : Prints out an error message when attempt is made to access a private slot improperly INPUTS : 1) The slot descriptor 2) A pointer to the source class RETURNS : Nothing useful SIDE EFFECTS : Error message printed NOTES : None ***************************************************/globle void SlotVisibilityViolationError( void *theEnv, SLOT_DESC *sd, DEFCLASS *theDefclass) { PrintErrorID(theEnv,"MSGFUN",6,FALSE); EnvPrintRouter(theEnv,WERROR,"Private slot "); EnvPrintRouter(theEnv,WERROR,ValueToString(sd->slotName->name)); EnvPrintRouter(theEnv,WERROR," of class "); PrintClassName(theEnv,WERROR,sd->cls,FALSE); EnvPrintRouter(theEnv,WERROR," cannot be accessed directly\n by handlers attached to class "); PrintClassName(theEnv,WERROR,theDefclass,TRUE); }#if ! RUN_TIME/****************************************************************************** NAME : NewSystemHandler DESCRIPTION : Adds a new system handler for a system class The handler is assumed to be primary and of the form: (defmessage-handler <class> <handler> () (<func>)) INPUTS : 1) Name-string of the system class 2) Name-string of the system handler 3) Name-string of the internal H/L function to implement this handler 4) The number of extra arguments (past the instance itself) that the handler willl accept RETURNS : Nothing useful SIDE EFFECTS : Creates the new handler and inserts it in the system class's handler array On errors, generate a system error and exits. NOTES : Does not check to see if handler already exists *******************************************************************************/globle void NewSystemHandler( void *theEnv, char *cname, char *mname, char *fname, int extraargs) { DEFCLASS *cls; HANDLER *hnd; cls = LookupDefclassInScope(theEnv,cname); hnd = InsertHandlerHeader(theEnv,cls,(SYMBOL_HN *) EnvAddSymbol(theEnv,mname),MPRIMARY); IncrementSymbolCount(hnd->name); hnd->system = 1; hnd->minParams = hnd->maxParams = extraargs + 1; hnd->localVarCount = 0; hnd->actions = get_struct(theEnv,expr); hnd->actions->argList = NULL; hnd->actions->type = FCALL; hnd->actions->value = (void *) FindFunction(theEnv,fname); hnd->actions->nextArg = NULL; }/*************************************************** NAME : InsertHandlerHeader DESCRIPTION : Allocates a new handler header and inserts it in the proper (sorted) position in the class hnd array INPUTS : 1) The class 2) The handler name 3) The handler type RETURNS : The address of the new handler header, NULL on errors SIDE EFFECTS : Class handler array reallocated and resorted NOTES : Assumes handler does not exist ***************************************************/globle HANDLER *InsertHandlerHeader( void *theEnv, DEFCLASS *cls, SYMBOL_HN *mname, int mtype) { HANDLER *nhnd,*hnd; unsigned *narr,*arr; long i; long j,ni = -1; hnd = cls->handlers; arr = cls->handlerOrderMap; nhnd = (HANDLER *) gm2(theEnv,(sizeof(HANDLER) * (cls->handlerCount+1))); narr = (unsigned *) gm2(theEnv,(sizeof(unsigned) * (cls->handlerCount+1))); GenCopyMemory(HANDLER,cls->handlerCount,nhnd,hnd); for (i = 0 , j = 0 ; i < cls->handlerCount ; i++ , j++) { if (ni == -1) { if ((hnd[arr[i]].name->bucket > mname->bucket) ? TRUE : (hnd[arr[i]].name == mname)) { ni = i; j++; } } narr[j] = arr[i]; } if (ni == -1) ni = (int) cls->handlerCount; narr[ni] = cls->handlerCount; nhnd[cls->handlerCount].system = 0; nhnd[cls->handlerCount].type = mtype; nhnd[cls->handlerCount].busy = 0; nhnd[cls->handlerCount].mark = 0;#if DEBUGGING_FUNCTIONS nhnd[cls->handlerCount].trace = MessageHandlerData(theEnv)->WatchHandlers;#endif nhnd[cls->handlerCount].name = mname; nhnd[cls->handlerCount].cls = cls; nhnd[cls->handlerCount].minParams = 0; nhnd[cls->handlerCount].maxParams = 0; nhnd[cls->handlerCount].localVarCount = 0; nhnd[cls->handlerCount].actions = NULL; nhnd[cls->handlerCount].ppForm = NULL; nhnd[cls->handlerCount].usrData = NULL; if (cls->handlerCount != 0) { rm(theEnv,(void *) hnd,(sizeof(HANDLER) * cls->handlerCount)); rm(theEnv,(void *) arr,(sizeof(unsigned) * cls->handlerCount)); } cls->handlers = nhnd; cls->handlerOrderMap = narr; cls->handlerCount++; return(&nhnd[cls->handlerCount-1]); }#endif#if (! BLOAD_ONLY) && (! RUN_TIME)/***************************************************** NAME : HandlersExecuting DESCRIPTION : Determines if any message-handlers for a class are currently executing INPUTS : The class address RETURNS : TRUE if any handlers are executing, FALSE otherwise SIDE EFFECTS : None NOTES : None *****************************************************/globle int HandlersExecuting( DEFCLASS *cls) { long i; for (i = 0 ; i < cls->handlerCount ; i++) if (cls->handlers[i].busy > 0) return(TRUE); return(FALSE);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -