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

📄 msgfun.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
                   CLIPS_FALSE otherwise  SIDE EFFECTS : None  NOTES        : None *****************************************************/globle int HandlersExecuting(cls)  DEFCLASS *cls;  {   register unsigned i;      for (i = 0 ; i < cls->handlerCount ; i++)     if (cls->handlers[i].busy > 0)       return(CLIPS_TRUE);   return(CLIPS_FALSE);  }  /*********************************************************************  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(cls,mname,mtype,indicate_missing)   DEFCLASS *cls;   SYMBOL_HN *mname;   int mtype,indicate_missing;  {   register int i;   HANDLER *hnd;   int found,success = 1;   if (cls->handlerCount == 0)     {      if (indicate_missing)        {         HandlerDeleteError(GetDefclassName((VOID *) cls));         return(0);        }      return(1);     }   if (HandlersExecuting(cls))     {      HandlerDeleteError(GetDefclassName((VOID *) cls));      return(0);     }   if (mtype == -1)     {      found = CLIPS_FALSE;      for (i = MAROUND ; i <= MAFTER ; i++)        {         hnd = FindHandlerByAddress(cls,mname,(unsigned) i);         if (hnd != NULL)           {            found = CLIPS_TRUE;            if (hnd->system == 0)              hnd->mark = 1;            else              {               PrintErrorID("MSGPSR",3,CLIPS_FALSE);               PrintCLIPS(WERROR,"System message-handlers may not be modified.\n");               success = 0;              }           }        }      if ((found == CLIPS_FALSE) ? (strcmp(ValueToString(mname),"*") == 0) : CLIPS_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 == mtype) &&                   (cls->handlers[i].system == 0))                cls->handlers[i].mark = 1;           }         else           {            if (indicate_missing)              HandlerDeleteError(GetDefclassName((VOID *) cls));            success = 0;           }        }      else if (hnd->system == 0)        hnd->mark = 1;      else        {         if (indicate_missing)           {            PrintErrorID("MSGPSR",3,CLIPS_FALSE);            PrintCLIPS(WERROR,"System message-handlers may not be modified.\n");           }         success = 0;        }     }        DeallocateMarkedHandlers(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(cls)  DEFCLASS *cls;  {   unsigned count;   HANDLER *hnd,*nhnd;   unsigned *arr,*narr;   register int i,j;   for (i = 0 , count = 0 ; i < cls->handlerCount ; i++)     {      hnd = &cls->handlers[i];      if (hnd->mark == 1)        {         count++;         DecrementSymbolCount(hnd->name);         ExpressionDeinstall(hnd->actions);         ReturnPackedExpression(hnd->actions);         if (hnd->ppForm != NULL)           rm((VOID *) hnd->ppForm,              (int) (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((VOID *) cls->handlers,(int) (sizeof(HANDLER) * cls->handlerCount));      rm((VOID *) cls->handlerOrderMap,(int) (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((int) (sizeof(HANDLER) * count));      narr = (unsigned *) gm2((int) (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;            CopyMemory(HANDLER,1,&nhnd[j],&hnd[i]);            j++;           }        }      rm((VOID *) hnd,(int) (sizeof(HANDLER) * cls->handlerCount));      rm((VOID *) arr,(int) (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 int HandlerType(func,str)  char *func,*str;  {   register int i;      for (i = MAROUND ; i <= MAFTER ; i++)     if (strcmp(str,hndquals[i]) == 0)       {#if ! IMPERATIVE_MESSAGE_HANDLERS        if (i == MAROUND)          break;#endif#if ! AUXILIARY_MESSAGE_HANDLERS        if ((i == MBEFORE) || (i == MAFTER))          break;#endif        return(i);       }          PrintErrorID("MSGFUN",7,CLIPS_FALSE);   PrintCLIPS("werror","Unrecognized message-handler type in ");   PrintCLIPS("werror",func);   PrintCLIPS("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 CLIPS                      primitive type)  RETURNS      : CLIPS_TRUE if all OK, CLIPS_FALSE otherwise  SIDE EFFECTS : EvaluationError set on errors  NOTES        : None *****************************************************************/globle int CheckCurrentMessage(func,ins_reqd)  char *func;  int ins_reqd;  {   register DATA_OBJECT *activeMsgArg;      if (!CurrentCore || (CurrentCore->hnd->actions != CurrentProcActions))     {      PrintErrorID("MSGFUN",4,CLIPS_FALSE);      PrintCLIPS(WERROR,func);      PrintCLIPS(WERROR," may only be called from within message-handlers.\n");      SetEvaluationError(CLIPS_TRUE);      return(CLIPS_FALSE);     }   activeMsgArg = GetNthMessageArgument(0);   if ((ins_reqd == CLIPS_TRUE) ? (activeMsgArg->type != INSTANCE_ADDRESS) : CLIPS_FALSE)     {      PrintErrorID("MSGFUN",5,CLIPS_FALSE);      PrintCLIPS(WERROR,func);      PrintCLIPS(WERROR," operates only on instances.\n");      SetEvaluationError(CLIPS_TRUE);      return(CLIPS_FALSE);     }   if ((activeMsgArg->type == INSTANCE_ADDRESS) ?       (((INSTANCE_TYPE *) activeMsgArg->value)->garbage == 1) : CLIPS_FALSE)     {      StaleInstanceAddress(func);      SetEvaluationError(CLIPS_TRUE);      return(CLIPS_FALSE);     }   return(CLIPS_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(log,theHandler,crtn)  char *log;  HANDLER *theHandler;  int crtn;  {   PrintCLIPS(log,ValueToString(theHandler->name));   PrintCLIPS(log," ");   PrintCLIPS(log,hndquals[theHandler->type]);   PrintCLIPS(log," in class ");   PrintClassName(log,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(cls,name,type)  DEFCLASS *cls;  SYMBOL_HN *name;  unsigned type;  {   register int b,i;   HANDLER *hnd;   unsigned *arr;      if ((b = FindHandlerNameGroup(cls,name)) == -1)     return(NULL);   arr = cls->handlerOrderMap;   hnd = cls->handlers;   for (i = b ; i < cls->handlerCount ; i++)     {      if (hnd[arr[i]].name != name)        return(NULL);

⌨️ 快捷键说明

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