tizen 2.4 release
[external/clips.git] / src / filertr.c
1    /*******************************************************/
2    /*      "C" Language Integrated Production System      */
3    /*                                                     */
4    /*             CLIPS Version 6.30  01/26/15            */
5    /*                                                     */
6    /*               FILE I/O ROUTER MODULE                */
7    /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: I/O Router routines which allow files to be used */
11 /*   as input and output sources.                            */
12 /*                                                           */
13 /* Principal Programmer(s):                                  */
14 /*      Gary D. Riley                                        */
15 /*                                                           */
16 /* Contributing Programmer(s):                               */
17 /*      Brian L. Dantes                                      */
18 /*                                                           */
19 /* Revision History:                                         */
20 /*                                                           */
21 /*      6.24: Added environment parameter to GenClose.       */
22 /*            Added environment parameter to GenOpen.        */
23 /*                                                           */
24 /*            Added pragmas to remove compilation warnings.  */
25 /*                                                           */
26 /*      6.30: Removed conditional code for unsupported       */
27 /*            compilers/operating systems (IBM_MCW,          */
28 /*            MAC_MCW, and IBM_TBC).                         */
29 /*                                                           */
30 /*            Used gengetc and genungetchar rather than      */
31 /*            getc and ungetc.                               */
32 /*                                                           */
33 /*            Replaced BASIC_IO and ADVANCED_IO compiler     */
34 /*            flags with the single IO_FUNCTIONS compiler    */
35 /*            flag.                                          */
36 /*                                                           */
37 /*            Added const qualifiers to remove C++           */
38 /*            deprecation warnings.                          */
39 /*                                                           */
40 /*            Added STDOUT and STDIN logical name            */
41 /*            definitions.                                   */
42 /*                                                           */
43 /*************************************************************/
44
45 #define _FILERTR_SOURCE_
46
47 #include <stdio.h>
48 #define _STDIO_INCLUDED_
49 #include <string.h>
50
51 #include "setup.h"
52
53 #include "constant.h"
54 #include "envrnmnt.h"
55 #include "memalloc.h"
56 #include "router.h"
57 #include "sysdep.h"
58
59 #include "filertr.h"
60
61 /***************************************/
62 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
63 /***************************************/
64
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 *);
70
71 /***************************************************************/
72 /* InitializeFileRouter: Initializes file input/output router. */
73 /***************************************************************/
74 globle void InitializeFileRouter(
75   void *theEnv)
76   {
77    AllocateEnvironmentData(theEnv,FILE_ROUTER_DATA,sizeof(struct fileRouterData),DeallocateFileRouterData);
78
79    EnvAddRouter(theEnv,"fileio",0,FindFile,
80              PrintFile,GetcFile,
81              UngetcFile,ExitFile);
82   }
83
84 /*****************************************/
85 /* DeallocateFileRouterData: Deallocates */
86 /*    environment data for file routers. */
87 /*****************************************/
88 static void DeallocateFileRouterData(
89   void *theEnv)
90   {
91    struct fileRouter *tmpPtr, *nextPtr;
92
93    tmpPtr = FileRouterData(theEnv)->ListOfFileRouters;
94    while (tmpPtr != NULL)
95      {
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);
100       tmpPtr = nextPtr;
101      }
102   }
103
104 /*****************************************/
105 /* FindFptr: Returns a pointer to a file */
106 /*   stream for a given logical name.    */
107 /*****************************************/
108 globle FILE *FindFptr(
109   void *theEnv,
110   const char *logicalName)
111   {
112    struct fileRouter *fptr;
113
114    /*========================================================*/
115    /* Check to see if standard input or output is requested. */
116    /*========================================================*/
117
118    if (strcmp(logicalName,STDOUT) == 0)
119      { return(stdout); }
120    else if (strcmp(logicalName,STDIN) == 0)
121      { return(stdin);  }
122    else if (strcmp(logicalName,WTRACE) == 0)
123      { return(stdout); }
124    else if (strcmp(logicalName,WDIALOG) == 0)
125      { return(stdout); }
126    else if (strcmp(logicalName,WPROMPT) == 0)
127      { return(stdout); }
128    else if (strcmp(logicalName,WDISPLAY) == 0)
129      { return(stdout); }
130    else if (strcmp(logicalName,WERROR) == 0)
131      { return(stdout); }
132    else if (strcmp(logicalName,WWARNING) == 0)
133      { return(stdout); }
134
135    /*==============================================================*/
136    /* Otherwise, look up the logical name on the global file list. */
137    /*==============================================================*/
138
139    fptr = FileRouterData(theEnv)->ListOfFileRouters;
140    while ((fptr != NULL) ? (strcmp(logicalName,fptr->logicalName) != 0) : FALSE)
141      { fptr = fptr->next; }
142
143    if (fptr != NULL) return(fptr->stream);
144
145    return(NULL);
146   }
147
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 /*****************************************************/
155 globle int FindFile(
156   void *theEnv,
157   const char *logicalName)
158   {
159    if (FindFptr(theEnv,logicalName) != NULL) return(TRUE);
160
161    return(FALSE);
162   }
163
164 /********************************************/
165 /* ExitFile:  Exit routine for file router. */
166 /********************************************/
167 static int ExitFile(
168   void *theEnv,
169   int num)
170   {
171 #if MAC_XCD
172 #pragma unused(num)
173 #endif
174 #if IO_FUNCTIONS
175    CloseAllFiles(theEnv);
176 #else
177 #if MAC_XCD
178 #pragma unused(theEnv)
179 #endif
180 #endif
181    return(1);
182   }
183
184 /*********************************************/
185 /* PrintFile: Print routine for file router. */
186 /*********************************************/
187 static int PrintFile(
188   void *theEnv,
189   const char *logicalName,
190   const char *str)
191   {
192    FILE *fptr;
193
194    fptr = FindFptr(theEnv,logicalName);
195
196    genprintfile(theEnv,fptr,str);
197
198    return(1);
199   }
200
201 /*******************************************/
202 /* GetcFile: Getc routine for file router. */
203 /*******************************************/
204 static int GetcFile(
205   void *theEnv,
206   const char *logicalName)
207   {
208    FILE *fptr;
209    int theChar;
210
211    fptr = FindFptr(theEnv,logicalName);
212
213    if (fptr == stdin)
214      { theChar = gengetchar(theEnv); }
215    else
216      { theChar = getc(fptr); }
217
218    /*=================================================*/
219    /* The following code prevents Control-D on UNIX   */
220    /* machines from terminating all input from stdin. */
221    /*=================================================*/
222
223    if ((fptr == stdin) && (theChar == EOF)) clearerr(stdin);
224
225    return(theChar);
226   }
227
228 /***********************************************/
229 /* UngetcFile: Ungetc routine for file router. */
230 /***********************************************/
231 static int UngetcFile(
232   void *theEnv,
233   int ch,
234   const char *logicalName)
235   {
236    FILE *fptr;
237
238    fptr = FindFptr(theEnv,logicalName);
239
240    if (fptr == stdin)
241      { return(genungetchar(theEnv,ch)); }
242    else
243      { return(ungetc(ch,fptr)); }
244   }
245
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(
253   void *theEnv,
254   const char *fileName,
255   const char *accessMode,
256   const char *logicalName)
257   {
258    FILE *newstream;
259    struct fileRouter *newRouter;
260    char *theName;
261
262    /*==================================*/
263    /* Make sure the file can be opened */
264    /* with the specified access mode.  */
265    /*==================================*/
266
267    if ((newstream = GenOpen(theEnv,fileName,accessMode)) == NULL)
268      { return(FALSE); }
269
270    /*===========================*/
271    /* Create a new file router. */
272    /*===========================*/
273
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;
279
280    /*==========================================*/
281    /* Add the newly opened file to the list of */
282    /* files associated with logical names.     */
283    /*==========================================*/
284
285    newRouter->next = FileRouterData(theEnv)->ListOfFileRouters;
286    FileRouterData(theEnv)->ListOfFileRouters = newRouter;
287
288    /*==================================*/
289    /* Return TRUE to indicate the file */
290    /* was opened successfully.         */
291    /*==================================*/
292
293    return(TRUE);
294   }
295
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(
302   void *theEnv,
303   const char *fid)
304   {
305    struct fileRouter *fptr, *prev;
306
307    for (fptr = FileRouterData(theEnv)->ListOfFileRouters, prev = NULL;
308         fptr != NULL;
309         fptr = fptr->next)
310      {
311       if (strcmp(fptr->logicalName,fid) == 0)
312         {
313          GenClose(theEnv,fptr->stream);
314          rm(theEnv,(void *) fptr->logicalName,strlen(fptr->logicalName) + 1);
315          if (prev == NULL)
316            { FileRouterData(theEnv)->ListOfFileRouters = fptr->next; }
317          else
318            { prev->next = fptr->next; }
319          rm(theEnv,fptr,(int) sizeof(struct fileRouter));
320
321          return(TRUE);
322         }
323
324       prev = fptr;
325      }
326
327    return(FALSE);
328   }
329
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(
336   void *theEnv)
337   {
338    struct fileRouter *fptr, *prev;
339
340    if (FileRouterData(theEnv)->ListOfFileRouters == NULL) return(FALSE);
341
342    fptr = FileRouterData(theEnv)->ListOfFileRouters;
343
344    while (fptr != NULL)
345      {
346       GenClose(theEnv,fptr->stream);
347       prev = fptr;
348       rm(theEnv,(void *) fptr->logicalName,strlen(fptr->logicalName) + 1);
349       fptr = fptr->next;
350       rm(theEnv,prev,(int) sizeof(struct fileRouter));
351      }
352
353    FileRouterData(theEnv)->ListOfFileRouters = NULL;
354
355    return(TRUE);
356   }
357
358
359