⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msgfun.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  }/*********************************************************************  NAME         : DeleteHandler  DESCRIPTION  : Deletes one or more message-handlers                   from a class definition  INPUTS       : 1) The class address                 2) The message-handler name                    (if this is * and there is no handler                     called *, then the delete operations                     will be applied to all handlers matching the type                 3) The message-handler type                    (if this is -1, then the delete operations will be                     applied to all handlers matching the name                 4) A flag saying whether to print error messages when                     handlers are not found meeting specs  RETURNS      : 1 if successful, 0 otherwise  SIDE EFFECTS : Handlers deleted  NOTES        : If any handlers for the class are                   currently executing, this routine                   will fail **********************************************************************/globle int DeleteHandler(   void *theEnv,   DEFCLASS *cls,   SYMBOL_HN *mname,   int mtype,   int indicate_missing)  {   long i;   HANDLER *hnd;   int found,success = 1;   if (cls->handlerCount == 0)     {      if (indicate_missing)        {         HandlerDeleteError(theEnv,EnvGetDefclassName(theEnv,(void *) cls));         return(0);        }      return(1);     }   if (HandlersExecuting(cls))     {      HandlerDeleteError(theEnv,EnvGetDefclassName(theEnv,(void *) cls));      return(0);     }   if (mtype == -1)     {      found = FALSE;      for (i = MAROUND ; i <= MAFTER ; i++)        {         hnd = FindHandlerByAddress(cls,mname,(unsigned) i);         if (hnd != NULL)           {            found = TRUE;            if (hnd->system == 0)              hnd->mark = 1;            else              {               PrintErrorID(theEnv,"MSGPSR",3,FALSE);               EnvPrintRouter(theEnv,WERROR,"System message-handlers may not be modified.\n");               success = 0;              }           }        }      if ((found == FALSE) ? (strcmp(ValueToString(mname),"*") == 0) : FALSE)        {         for (i = 0 ; i < cls->handlerCount ; i++)           if (cls->handlers[i].system == 0)             cls->handlers[i].mark = 1;        }     }   else     {      hnd = FindHandlerByAddress(cls,mname,(unsigned) mtype);      if (hnd == NULL)        {         if (strcmp(ValueToString(mname),"*") == 0)           {            for (i = 0 ; i < cls->handlerCount ; i++)              if ((cls->handlers[i].type == (unsigned) mtype) &&                  (cls->handlers[i].system == 0))                cls->handlers[i].mark = 1;           }         else           {            if (indicate_missing)              HandlerDeleteError(theEnv,EnvGetDefclassName(theEnv,(void *) cls));            success = 0;           }        }      else if (hnd->system == 0)        hnd->mark = 1;      else        {         if (indicate_missing)           {            PrintErrorID(theEnv,"MSGPSR",3,FALSE);            EnvPrintRouter(theEnv,WERROR,"System message-handlers may not be modified.\n");           }         success = 0;        }     }   DeallocateMarkedHandlers(theEnv,cls);   return(success);  }/***************************************************  NAME         : DeallocateMarkedHandlers  DESCRIPTION  : Removes any handlers from a class                   that have been previously marked                   for deletion.  INPUTS       : The class  RETURNS      : Nothing useful  SIDE EFFECTS : Marked handlers are deleted  NOTES        : Assumes none of the handlers are                   currently executing or have a                   busy count != 0 for any reason ***************************************************/globle void DeallocateMarkedHandlers(  void *theEnv,  DEFCLASS *cls)  {   short count;   HANDLER *hnd,*nhnd;   unsigned *arr,*narr;   long i,j;   for (i = 0 , count = 0 ; i < cls->handlerCount ; i++)     {      hnd = &cls->handlers[i];      if (hnd->mark == 1)        {         count++;         DecrementSymbolCount(theEnv,hnd->name);         ExpressionDeinstall(theEnv,hnd->actions);         ReturnPackedExpression(theEnv,hnd->actions);         ClearUserDataList(theEnv,hnd->usrData);         if (hnd->ppForm != NULL)           rm(theEnv,(void *) hnd->ppForm,              (sizeof(char) * (strlen(hnd->ppForm)+1)));        }      else         /* ============================================            Use the busy field to count how many            message-handlers are removed before this one            ============================================ */        hnd->busy = count;     }   if (count == 0)     return;   if (count == cls->handlerCount)     {      rm(theEnv,(void *) cls->handlers,(sizeof(HANDLER) * cls->handlerCount));      rm(theEnv,(void *) cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount));      cls->handlers = NULL;      cls->handlerOrderMap = NULL;      cls->handlerCount = 0;     }   else     {      count = cls->handlerCount - count;      hnd = cls->handlers;      arr = cls->handlerOrderMap;      nhnd = (HANDLER *) gm2(theEnv,(sizeof(HANDLER) * count));      narr = (unsigned *) gm2(theEnv,(sizeof(unsigned) * count));      for (i = 0 , j = 0 ; j < count ; i++)        {         if (hnd[arr[i]].mark == 0)           {            /* ==============================================================               The offsets in the map need to be decremented by the number of               preceding nodes which were deleted.  Use the value of the busy               field set in the first loop.               ============================================================== */            narr[j] = arr[i] - hnd[arr[i]].busy;            j++;           }        }      for (i = 0 , j = 0 ; j < count ; i++)        {         if (hnd[i].mark == 0)           {            hnd[i].busy = 0;            GenCopyMemory(HANDLER,1,&nhnd[j],&hnd[i]);            j++;           }        }      rm(theEnv,(void *) hnd,(sizeof(HANDLER) * cls->handlerCount));      rm(theEnv,(void *) arr,(sizeof(unsigned) * cls->handlerCount));      cls->handlers = nhnd;      cls->handlerOrderMap = narr;      cls->handlerCount = count;     }  }#endif/*****************************************************  NAME         : HandlerType  DESCRIPTION  : Determines type of message-handler  INPUTS       : 1) Calling function string                 2) String representing type  RETURNS      : MAROUND  (0) for "around"                 MBEFORE  (1) for "before"                 MPRIMARY (2) for "primary"                 MAFTER   (3) for "after"                 MERROR   (4) on errors  SIDE EFFECTS : None  NOTES        : None *****************************************************/globle unsigned HandlerType(  void *theEnv,  char *func,  char *str)  {   register unsigned i;   for (i = MAROUND ; i <= MAFTER ; i++)     if (strcmp(str,MessageHandlerData(theEnv)->hndquals[i]) == 0)       {        return(i);       }   PrintErrorID(theEnv,"MSGFUN",7,FALSE);   EnvPrintRouter(theEnv,"werror","Unrecognized message-handler type in ");   EnvPrintRouter(theEnv,"werror",func);   EnvPrintRouter(theEnv,"werror",".\n");   return(MERROR);  }/*****************************************************************  NAME         : CheckCurrentMessage  DESCRIPTION  : Makes sure that a message is available                   and active for an internal message function  INPUTS       : 1) The name of the function checking the message                 2) A flag indicating whether the object must be                      a class instance or not (it could be a                      primitive type)  RETURNS      : TRUE if all OK, FALSE otherwise  SIDE EFFECTS : EvaluationError set on errors  NOTES        : None *****************************************************************/globle int CheckCurrentMessage(  void *theEnv,  char *func,  int ins_reqd)  {   register DATA_OBJECT *activeMsgArg;   if (!MessageHandlerData(theEnv)->CurrentCore || (MessageHandlerData(theEnv)->CurrentCore->hnd->actions != ProceduralPrimitiveData(theEnv)->CurrentProcActions))     {      PrintErrorID(theEnv,"MSGFUN",4,FALSE);      EnvPrintRouter(theEnv,WERROR,func);      EnvPrintRouter(theEnv,WERROR," may only be called from within message-handlers.\n");      SetEvaluationError(theEnv,TRUE);      return(FALSE);     }   activeMsgArg = GetNthMessageArgument(theEnv,0);   if ((ins_reqd == TRUE) ? (activeMsgArg->type != INSTANCE_ADDRESS) : FALSE)     {      PrintErrorID(theEnv,"MSGFUN",5,FALSE);      EnvPrintRouter(theEnv,WERROR,func);      EnvPrintRouter(theEnv,WERROR," operates only on instances.\n");      SetEvaluationError(theEnv,TRUE);      return(FALSE);     }   if ((activeMsgArg->type == INSTANCE_ADDRESS) ?       (((INSTANCE_TYPE *) activeMsgArg->value)->garbage == 1) : FALSE)     {      StaleInstanceAddress(theEnv,func,0);      SetEvaluationError(theEnv,TRUE);      return(FALSE);     }   return(TRUE);  }/***************************************************  NAME         : PrintHandler  DESCRIPTION  : Displays a handler synopsis  INPUTS       : 1) Logical name of output                 2) The handler                 5) Flag indicating whether to                    printout a terminating newline  RETURNS      : Nothing useful  SIDE EFFECTS : None  NOTES        : None ***************************************************/globle void PrintHandler(  void *theEnv,  char *logName,  HANDLER *theHandler,  int crtn)  {   EnvPrintRouter(theEnv,logName,ValueToString(theHandler->name));   EnvPrintRouter(theEnv,logName," ");   EnvPrintRouter(theEnv,logName,MessageHandlerData(theEnv)->hndquals[theHandler->type]);   EnvPrintRouter(theEnv,logName," in class ");   PrintClassName(theEnv,logName,theHandler->cls,crtn);  }/***********************************************************  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 address of the found handler,                   NULL 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 HANDLER *FindHandlerByAddress(  DEFCLASS *cls,  SYMBOL_HN *name,  unsigned type)  {   register int b;   long i;   HANDLER *hnd;   unsigned *arr;   if ((b = FindHandlerNameGroup(cls,name)) == -1)     return(NULL);   arr = cls->handlerOrderMap;   hnd = cls->handlers;   for (i = (unsigned) b ; i < cls->handlerCount ; i++)     {      if (hnd[arr[i]].name != name)        return(NULL);      if (hnd[arr[i]].type == type)        return(&hnd[arr[i]]);     }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -