?? router.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 07/01/05 */ /* */ /* I/O ROUTER MODULE */ /*******************************************************//*************************************************************//* Purpose: Provides a centralized mechanism for handling *//* input and output requests. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* Brian L. Donnell *//* *//* Revision History: *//* 6.24: Removed conversion of '\r' to '\n' from the *//* EnvGetcRouter function. *//* *//* Renamed BOOLEAN macro type to intBool. *//* *//* Added support for passing context information */ /* to the router functions. *//* *//* 6.30: Fixed issues with passing context to routers. *//* *//*************************************************************/#define _ROUTER_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include <stdlib.h>#include <string.h>#include "setup.h"#include "argacces.h"#include "constant.h"#include "envrnmnt.h"#include "extnfunc.h"#include "filertr.h"#include "memalloc.h"#include "strngrtr.h"#include "sysdep.h"#include "router.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static int QueryRouter(void *,char *,struct router *); static void DeallocateRouterData(void *);/*********************************************************//* InitializeDefaultRouters: Initializes output streams. *//*********************************************************/globle void InitializeDefaultRouters( void *theEnv) { AllocateEnvironmentData(theEnv,ROUTER_DATA,sizeof(struct routerData),DeallocateRouterData); RouterData(theEnv)->CommandBufferInputCount = -1; #if (! RUN_TIME) EnvDefineFunction2(theEnv,"exit", 'v', PTIEF ExitCommand, "ExitCommand", "*1i");#endif InitializeFileRouter(theEnv); InitializeStringRouter(theEnv); } /*************************************************//* DeallocateRouterData: Deallocates environment *//* data for I/O routers. *//*************************************************/static void DeallocateRouterData( void *theEnv) { struct router *tmpPtr, *nextPtr; tmpPtr = RouterData(theEnv)->ListOfRouters; while (tmpPtr != NULL) { nextPtr = tmpPtr->next; genfree(theEnv,tmpPtr->name,strlen(tmpPtr->name) + 1); rtn_struct(theEnv,router,tmpPtr); tmpPtr = nextPtr; } }/*******************************************//* EnvPrintRouter: Generic print function. *//*******************************************/globle int EnvPrintRouter( void *theEnv, char *logicalName, char *str) { struct router *currentPtr; /*===================================================*/ /* If the "fast save" option is being used, then the */ /* logical name is actually a pointer to a file and */ /* fprintf can be called directly to bypass querying */ /* all of the routers. */ /*===================================================*/ if (((char *) RouterData(theEnv)->FastSaveFilePtr) == logicalName) { fprintf(RouterData(theEnv)->FastSaveFilePtr,"%s",str); return(2); } /*==============================================*/ /* Search through the list of routers until one */ /* is found that will handle the print request. */ /*==============================================*/ currentPtr = RouterData(theEnv)->ListOfRouters; while (currentPtr != NULL) { if ((currentPtr->printer != NULL) ? QueryRouter(theEnv,logicalName,currentPtr) : FALSE) { SetEnvironmentRouterContext(theEnv,currentPtr->context); if (currentPtr->environmentAware) { (*currentPtr->printer)(theEnv,logicalName,str); } else { ((int (*)(char *,char *)) (*currentPtr->printer))(logicalName,str); } return(1); } currentPtr = currentPtr->next; } /*=====================================================*/ /* The logical name was not recognized by any routers. */ /*=====================================================*/ if (strcmp(WERROR,logicalName) != 0) UnrecognizedRouterMessage(theEnv,logicalName); return(0); }/**************************************************//* EnvGetcRouter: Generic get character function. *//**************************************************/globle int EnvGetcRouter( void *theEnv, char *logicalName) { struct router *currentPtr; int inchar; /*===================================================*/ /* If the "fast load" option is being used, then the */ /* logical name is actually a pointer to a file and */ /* getc can be called directly to bypass querying */ /* all of the routers. */ /*===================================================*/ if (((char *) RouterData(theEnv)->FastLoadFilePtr) == logicalName) { inchar = getc(RouterData(theEnv)->FastLoadFilePtr); if ((inchar == '\r') || (inchar == '\n')) { if (((char *) RouterData(theEnv)->FastLoadFilePtr) == RouterData(theEnv)->LineCountRouter) { IncrementLineCount(theEnv); } } /* if (inchar == '\r') return('\n'); */ return(inchar); } /*===============================================*/ /* If the "fast string get" option is being used */ /* for the specified logical name, then bypass */ /* the router system and extract the character */ /* directly from the fast get string. */ /*===============================================*/ if (RouterData(theEnv)->FastCharGetRouter == logicalName) { inchar = (unsigned char) RouterData(theEnv)->FastCharGetString[RouterData(theEnv)->FastCharGetIndex]; RouterData(theEnv)->FastCharGetIndex++; if (inchar == '\0') return(EOF); if ((inchar == '\r') || (inchar == '\n')) { if (RouterData(theEnv)->FastCharGetRouter == RouterData(theEnv)->LineCountRouter) { IncrementLineCount(theEnv); } } /* if (inchar == '\r') return('\n'); */ return(inchar); } /*==============================================*/ /* Search through the list of routers until one */ /* is found that will handle the getc request. */ /*==============================================*/ currentPtr = RouterData(theEnv)->ListOfRouters; while (currentPtr != NULL) { if ((currentPtr->charget != NULL) ? QueryRouter(theEnv,logicalName,currentPtr) : FALSE) { SetEnvironmentRouterContext(theEnv,currentPtr->context); if (currentPtr->environmentAware) { inchar = (*currentPtr->charget)(theEnv,logicalName); } else { inchar = ((int (*)(char *)) (*currentPtr->charget))(logicalName); } if ((inchar == '\r') || (inchar == '\n')) { if ((RouterData(theEnv)->LineCountRouter != NULL) && (strcmp(logicalName,RouterData(theEnv)->LineCountRouter) == 0)) { IncrementLineCount(theEnv); } } /* if (inchar == '\r') return('\n'); */ /* if (inchar != '\b') { return(inchar); } */ return(inchar); } currentPtr = currentPtr->next; } /*=====================================================*/ /* The logical name was not recognized by any routers. */ /*=====================================================*/ UnrecognizedRouterMessage(theEnv,logicalName); return(-1); }/******************************************************//* EnvUngetcRouter: Generic unget character function. *//******************************************************/globle int EnvUngetcRouter( void *theEnv, int ch, char *logicalName) { struct router *currentPtr; /*===================================================*/ /* If the "fast load" option is being used, then the */ /* logical name is actually a pointer to a file and */ /* ungetc can be called directly to bypass querying */ /* all of the routers. */ /*===================================================*/ if (((char *) RouterData(theEnv)->FastLoadFilePtr) == logicalName) { if ((ch == '\r') || (ch == '\n')) { if (((char *) RouterData(theEnv)->FastLoadFilePtr) == RouterData(theEnv)->LineCountRouter) { DecrementLineCount(theEnv); } } return(ungetc(ch,RouterData(theEnv)->FastLoadFilePtr)); } /*===============================================*/ /* If the "fast string get" option is being used */ /* for the specified logical name, then bypass */ /* the router system and unget the character */ /* directly from the fast get string. */ /*===============================================*/ if (RouterData(theEnv)->FastCharGetRouter == logicalName) { if ((ch == '\r') || (ch == '\n')) { if (RouterData(theEnv)->FastCharGetRouter == RouterData(theEnv)->LineCountRouter) { DecrementLineCount(theEnv); } } if (RouterData(theEnv)->FastCharGetIndex > 0) RouterData(theEnv)->FastCharGetIndex--; return(ch); } /*===============================================*/ /* Search through the list of routers until one */ /* is found that will handle the ungetc request. */ /*===============================================*/ currentPtr = RouterData(theEnv)->ListOfRouters; while (currentPtr != NULL) { if ((currentPtr->charunget != NULL) ? QueryRouter(theEnv,logicalName,currentPtr) : FALSE) { if ((ch == '\r') || (ch == '\n')) { if ((RouterData(theEnv)->LineCountRouter != NULL) && (strcmp(logicalName,RouterData(theEnv)->LineCountRouter) == 0)) { DecrementLineCount(theEnv); } } SetEnvironmentRouterContext(theEnv,currentPtr->context); if (currentPtr->environmentAware) { return((*currentPtr->charunget)(theEnv,ch,logicalName)); } else { return(((int (*)(int,char *)) (*currentPtr->charunget))(ch,logicalName)); } } currentPtr = currentPtr->next; } /*=====================================================*/ /* The logical name was not recognized by any routers. */ /*=====================================================*/ UnrecognizedRouterMessage(theEnv,logicalName); return(-1); }/*****************************************************//* ExitCommand: H/L command for exiting the program. *//*****************************************************/globle void ExitCommand( void *theEnv) { int argCnt; int status; if ((argCnt = EnvArgCountCheck(theEnv,"exit",NO_MORE_THAN,1)) == -1) return; if (argCnt == 0) { EnvExitRouter(theEnv,EXIT_SUCCESS); } else { status = (int) EnvRtnLong(theEnv,1); if (GetEvaluationError(theEnv)) return; EnvExitRouter(theEnv,status); } return; }/***********************************************//* EnvExitRouter: Generic exit function. Calls *//* all of the router exit functions. *//***********************************************/globle void EnvExitRouter( void *theEnv, int num) { struct router *currentPtr, *nextPtr; RouterData(theEnv)->Abort = FALSE; currentPtr = RouterData(theEnv)->ListOfRouters; while (currentPtr != NULL) { nextPtr = currentPtr->next; if (currentPtr->active == TRUE) { if (currentPtr->exiter != NULL) { SetEnvironmentRouterContext(theEnv,currentPtr->context); if (currentPtr->environmentAware) { (*currentPtr->exiter)(theEnv,num); } else { ((int (*)(int))(*currentPtr->exiter))(num); } } } currentPtr = nextPtr;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -