1 /*******************************************************/
2 /* "C" Language Integrated Production System */
4 /* CLIPS Version 6.30 01/26/15 */
6 /* FILE I/O ROUTER MODULE */
7 /*******************************************************/
9 /*************************************************************/
10 /* Purpose: I/O Router routines which allow files to be used */
11 /* as input and output sources. */
13 /* Principal Programmer(s): */
16 /* Contributing Programmer(s): */
19 /* Revision History: */
21 /* 6.24: Added environment parameter to GenClose. */
22 /* Added environment parameter to GenOpen. */
24 /* Added pragmas to remove compilation warnings. */
26 /* 6.30: Removed conditional code for unsupported */
27 /* compilers/operating systems (IBM_MCW, */
28 /* MAC_MCW, and IBM_TBC). */
30 /* Used gengetc and genungetchar rather than */
31 /* getc and ungetc. */
33 /* Replaced BASIC_IO and ADVANCED_IO compiler */
34 /* flags with the single IO_FUNCTIONS compiler */
37 /* Added const qualifiers to remove C++ */
38 /* deprecation warnings. */
40 /* Added STDOUT and STDIN logical name */
43 /*************************************************************/
45 #define _FILERTR_SOURCE_
48 #define _STDIO_INCLUDED_
61 /***************************************/
62 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
63 /***************************************/
65 static int ExitFile(void *,int);
66 static int PrintFile(void *,const char *,const char *);
67 static int GetcFile(void *,const char *);
68 static int UngetcFile(void *,int,const char *);
69 static void DeallocateFileRouterData(void *);
71 /***************************************************************/
72 /* InitializeFileRouter: Initializes file input/output router. */
73 /***************************************************************/
74 globle void InitializeFileRouter(
77 AllocateEnvironmentData(theEnv,FILE_ROUTER_DATA,sizeof(struct fileRouterData),DeallocateFileRouterData);
79 EnvAddRouter(theEnv,"fileio",0,FindFile,
84 /*****************************************/
85 /* DeallocateFileRouterData: Deallocates */
86 /* environment data for file routers. */
87 /*****************************************/
88 static void DeallocateFileRouterData(
91 struct fileRouter *tmpPtr, *nextPtr;
93 tmpPtr = FileRouterData(theEnv)->ListOfFileRouters;
94 while (tmpPtr != NULL)
96 nextPtr = tmpPtr->next;
97 GenClose(theEnv,tmpPtr->stream);
98 rm(theEnv,(void *) tmpPtr->logicalName,strlen(tmpPtr->logicalName) + 1);
99 rtn_struct(theEnv,fileRouter,tmpPtr);
104 /*****************************************/
105 /* FindFptr: Returns a pointer to a file */
106 /* stream for a given logical name. */
107 /*****************************************/
108 globle FILE *FindFptr(
110 const char *logicalName)
112 struct fileRouter *fptr;
114 /*========================================================*/
115 /* Check to see if standard input or output is requested. */
116 /*========================================================*/
118 if (strcmp(logicalName,STDOUT) == 0)
120 else if (strcmp(logicalName,STDIN) == 0)
122 else if (strcmp(logicalName,WTRACE) == 0)
124 else if (strcmp(logicalName,WDIALOG) == 0)
126 else if (strcmp(logicalName,WPROMPT) == 0)
128 else if (strcmp(logicalName,WDISPLAY) == 0)
130 else if (strcmp(logicalName,WERROR) == 0)
132 else if (strcmp(logicalName,WWARNING) == 0)
135 /*==============================================================*/
136 /* Otherwise, look up the logical name on the global file list. */
137 /*==============================================================*/
139 fptr = FileRouterData(theEnv)->ListOfFileRouters;
140 while ((fptr != NULL) ? (strcmp(logicalName,fptr->logicalName) != 0) : FALSE)
141 { fptr = fptr->next; }
143 if (fptr != NULL) return(fptr->stream);
148 /*****************************************************/
149 /* FindFile: Find routine for file router logical */
150 /* names. Returns TRUE if the specified logical */
151 /* name has an associated file stream (which means */
152 /* that the logical name can be handled by the */
153 /* file router). Otherwise, FALSE is returned. */
154 /*****************************************************/
157 const char *logicalName)
159 if (FindFptr(theEnv,logicalName) != NULL) return(TRUE);
164 /********************************************/
165 /* ExitFile: Exit routine for file router. */
166 /********************************************/
175 CloseAllFiles(theEnv);
178 #pragma unused(theEnv)
184 /*********************************************/
185 /* PrintFile: Print routine for file router. */
186 /*********************************************/
187 static int PrintFile(
189 const char *logicalName,
194 fptr = FindFptr(theEnv,logicalName);
196 genprintfile(theEnv,fptr,str);
201 /*******************************************/
202 /* GetcFile: Getc routine for file router. */
203 /*******************************************/
206 const char *logicalName)
211 fptr = FindFptr(theEnv,logicalName);
214 { theChar = gengetchar(theEnv); }
216 { theChar = getc(fptr); }
218 /*=================================================*/
219 /* The following code prevents Control-D on UNIX */
220 /* machines from terminating all input from stdin. */
221 /*=================================================*/
223 if ((fptr == stdin) && (theChar == EOF)) clearerr(stdin);
228 /***********************************************/
229 /* UngetcFile: Ungetc routine for file router. */
230 /***********************************************/
231 static int UngetcFile(
234 const char *logicalName)
238 fptr = FindFptr(theEnv,logicalName);
241 { return(genungetchar(theEnv,ch)); }
243 { return(ungetc(ch,fptr)); }
246 /*********************************************************/
247 /* OpenFile: Opens a file with the specified access mode */
248 /* and stores the opened stream on the list of files */
249 /* associated with logical names Returns TRUE if the */
250 /* file was succesfully opened, otherwise FALSE. */
251 /*********************************************************/
252 globle int OpenAFile(
254 const char *fileName,
255 const char *accessMode,
256 const char *logicalName)
259 struct fileRouter *newRouter;
262 /*==================================*/
263 /* Make sure the file can be opened */
264 /* with the specified access mode. */
265 /*==================================*/
267 if ((newstream = GenOpen(theEnv,fileName,accessMode)) == NULL)
270 /*===========================*/
271 /* Create a new file router. */
272 /*===========================*/
274 newRouter = get_struct(theEnv,fileRouter);
275 theName = (char *) gm2(theEnv,strlen(logicalName) + 1);
276 genstrcpy(theName,logicalName);
277 newRouter->logicalName = theName;
278 newRouter->stream = newstream;
280 /*==========================================*/
281 /* Add the newly opened file to the list of */
282 /* files associated with logical names. */
283 /*==========================================*/
285 newRouter->next = FileRouterData(theEnv)->ListOfFileRouters;
286 FileRouterData(theEnv)->ListOfFileRouters = newRouter;
288 /*==================================*/
289 /* Return TRUE to indicate the file */
290 /* was opened successfully. */
291 /*==================================*/
296 /*************************************************************/
297 /* CloseFile: Closes the file associated with the specified */
298 /* logical name. Returns TRUE if the file was successfully */
299 /* closed, otherwise FALSE. */
300 /*************************************************************/
301 globle int CloseFile(
305 struct fileRouter *fptr, *prev;
307 for (fptr = FileRouterData(theEnv)->ListOfFileRouters, prev = NULL;
311 if (strcmp(fptr->logicalName,fid) == 0)
313 GenClose(theEnv,fptr->stream);
314 rm(theEnv,(void *) fptr->logicalName,strlen(fptr->logicalName) + 1);
316 { FileRouterData(theEnv)->ListOfFileRouters = fptr->next; }
318 { prev->next = fptr->next; }
319 rm(theEnv,fptr,(int) sizeof(struct fileRouter));
330 /**********************************************/
331 /* CloseAllFiles: Closes all files associated */
332 /* with a file I/O router. Returns TRUE if */
333 /* any file was closed, otherwise FALSE. */
334 /**********************************************/
335 globle int CloseAllFiles(
338 struct fileRouter *fptr, *prev;
340 if (FileRouterData(theEnv)->ListOfFileRouters == NULL) return(FALSE);
342 fptr = FileRouterData(theEnv)->ListOfFileRouters;
346 GenClose(theEnv,fptr->stream);
348 rm(theEnv,(void *) fptr->logicalName,strlen(fptr->logicalName) + 1);
350 rm(theEnv,prev,(int) sizeof(struct fileRouter));
353 FileRouterData(theEnv)->ListOfFileRouters = NULL;