1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 08/16/14 */
5 /* */
6 /* I/O ROUTER MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Provides a centralized mechanism for handling */
11 /* input and output requests. */
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: Removed conversion of '\r' to '\n' from the */
22 /* EnvGetcRouter function. */
23 /* */
24 /* Renamed BOOLEAN macro type to intBool. */
25 /* */
26 /* Added support for passing context information */
27 /* to the router functions. */
28 /* */
29 /* 6.30: Fixed issues with passing context to routers. */
30 /* */
31 /* Added AwaitingInput flag. */
32 /* */
33 /* Added const qualifiers to remove C++ */
34 /* deprecation warnings. */
35 /* */
36 /* Converted API macros to function calls. */
37 /* */
38 /*************************************************************/
39
40 #define _ROUTER_SOURCE_
41
42 #include <stdio.h>
43 #define _STDIO_INCLUDED_
44 #include <stdlib.h>
45 #include <string.h>
46
47 #include "setup.h"
48
49 #include "argacces.h"
50 #include "constant.h"
51 #include "envrnmnt.h"
52 #include "extnfunc.h"
53 #include "filertr.h"
54 #include "memalloc.h"
55 #include "strngrtr.h"
56 #include "sysdep.h"
57
58 #include "router.h"
59
60 /***************************************/
61 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
62 /***************************************/
63
64 static int QueryRouter(void *,const char *,struct router *);
65 static void DeallocateRouterData(void *);
66
67 /*********************************************************/
68 /* InitializeDefaultRouters: Initializes output streams. */
69 /*********************************************************/
InitializeDefaultRouters(void * theEnv)70 globle void InitializeDefaultRouters(
71 void *theEnv)
72 {
73 AllocateEnvironmentData(theEnv,ROUTER_DATA,sizeof(struct routerData),DeallocateRouterData);
74
75 RouterData(theEnv)->CommandBufferInputCount = 0;
76 RouterData(theEnv)->AwaitingInput = TRUE;
77
78 #if (! RUN_TIME)
79 EnvDefineFunction2(theEnv,"exit", 'v', PTIEF ExitCommand, "ExitCommand", "*1i");
80 #endif
81 InitializeFileRouter(theEnv);
82 InitializeStringRouter(theEnv);
83 }
84
85 /*************************************************/
86 /* DeallocateRouterData: Deallocates environment */
87 /* data for I/O routers. */
88 /*************************************************/
DeallocateRouterData(void * theEnv)89 static void DeallocateRouterData(
90 void *theEnv)
91 {
92 struct router *tmpPtr, *nextPtr;
93
94 tmpPtr = RouterData(theEnv)->ListOfRouters;
95 while (tmpPtr != NULL)
96 {
97 nextPtr = tmpPtr->next;
98 genfree(theEnv,(void *) tmpPtr->name,strlen(tmpPtr->name) + 1);
99 rtn_struct(theEnv,router,tmpPtr);
100 tmpPtr = nextPtr;
101 }
102 }
103
104 /*******************************************/
105 /* EnvPrintRouter: Generic print function. */
106 /*******************************************/
EnvPrintRouter(void * theEnv,const char * logicalName,const char * str)107 globle int EnvPrintRouter(
108 void *theEnv,
109 const char *logicalName,
110 const char *str)
111 {
112 struct router *currentPtr;
113
114 /*===================================================*/
115 /* If the "fast save" option is being used, then the */
116 /* logical name is actually a pointer to a file and */
117 /* fprintf can be called directly to bypass querying */
118 /* all of the routers. */
119 /*===================================================*/
120
121 if (((char *) RouterData(theEnv)->FastSaveFilePtr) == logicalName)
122 {
123 fprintf(RouterData(theEnv)->FastSaveFilePtr,"%s",str);
124 return(2);
125 }
126
127 /*==============================================*/
128 /* Search through the list of routers until one */
129 /* is found that will handle the print request. */
130 /*==============================================*/
131
132 currentPtr = RouterData(theEnv)->ListOfRouters;
133 while (currentPtr != NULL)
134 {
135 if ((currentPtr->printer != NULL) ? QueryRouter(theEnv,logicalName,currentPtr) : FALSE)
136 {
137 SetEnvironmentRouterContext(theEnv,currentPtr->context);
138 if (currentPtr->environmentAware)
139 { (*currentPtr->printer)(theEnv,logicalName,str); }
140 else
141 { ((int (*)(const char *,const char *)) (*currentPtr->printer))(logicalName,str); }
142
143 return(1);
144 }
145 currentPtr = currentPtr->next;
146 }
147
148 /*=====================================================*/
149 /* The logical name was not recognized by any routers. */
150 /*=====================================================*/
151
152 if (strcmp(WERROR,logicalName) != 0) UnrecognizedRouterMessage(theEnv,logicalName);
153 return(0);
154 }
155
156 /**************************************************/
157 /* EnvGetcRouter: Generic get character function. */
158 /**************************************************/
EnvGetcRouter(void * theEnv,const char * logicalName)159 globle int EnvGetcRouter(
160 void *theEnv,
161 const char *logicalName)
162 {
163 struct router *currentPtr;
164 int inchar;
165
166 /*===================================================*/
167 /* If the "fast load" option is being used, then the */
168 /* logical name is actually a pointer to a file and */
169 /* getc can be called directly to bypass querying */
170 /* all of the routers. */
171 /*===================================================*/
172
173 if (((char *) RouterData(theEnv)->FastLoadFilePtr) == logicalName)
174 {
175 inchar = getc(RouterData(theEnv)->FastLoadFilePtr);
176
177 if ((inchar == '\r') || (inchar == '\n'))
178 {
179 if (((char *) RouterData(theEnv)->FastLoadFilePtr) == RouterData(theEnv)->LineCountRouter)
180 { IncrementLineCount(theEnv); }
181 }
182
183 /* if (inchar == '\r') return('\n'); */
184
185 return(inchar);
186 }
187
188 /*===============================================*/
189 /* If the "fast string get" option is being used */
190 /* for the specified logical name, then bypass */
191 /* the router system and extract the character */
192 /* directly from the fast get string. */
193 /*===============================================*/
194
195 if (RouterData(theEnv)->FastCharGetRouter == logicalName)
196 {
197 inchar = (unsigned char) RouterData(theEnv)->FastCharGetString[RouterData(theEnv)->FastCharGetIndex];
198
199 RouterData(theEnv)->FastCharGetIndex++;
200
201 if (inchar == '\0') return(EOF);
202
203 if ((inchar == '\r') || (inchar == '\n'))
204 {
205 if (RouterData(theEnv)->FastCharGetRouter == RouterData(theEnv)->LineCountRouter)
206 { IncrementLineCount(theEnv); }
207 }
208
209 return(inchar);
210 }
211
212 /*==============================================*/
213 /* Search through the list of routers until one */
214 /* is found that will handle the getc request. */
215 /*==============================================*/
216
217 currentPtr = RouterData(theEnv)->ListOfRouters;
218 while (currentPtr != NULL)
219 {
220 if ((currentPtr->charget != NULL) ? QueryRouter(theEnv,logicalName,currentPtr) : FALSE)
221 {
222 SetEnvironmentRouterContext(theEnv,currentPtr->context);
223 if (currentPtr->environmentAware)
224 { inchar = (*currentPtr->charget)(theEnv,logicalName); }
225 else
226 { inchar = ((int (*)(const char *)) (*currentPtr->charget))(logicalName); }
227
228 if ((inchar == '\r') || (inchar == '\n'))
229 {
230 if ((RouterData(theEnv)->LineCountRouter != NULL) &&
231 (strcmp(logicalName,RouterData(theEnv)->LineCountRouter) == 0))
232 { IncrementLineCount(theEnv); }
233 }
234
235 return(inchar);
236 }
237 currentPtr = currentPtr->next;
238 }
239
240 /*=====================================================*/
241 /* The logical name was not recognized by any routers. */
242 /*=====================================================*/
243
244 UnrecognizedRouterMessage(theEnv,logicalName);
245 return(-1);
246 }
247
248 /******************************************************/
249 /* EnvUngetcRouter: Generic unget character function. */
250 /******************************************************/
EnvUngetcRouter(void * theEnv,int ch,const char * logicalName)251 globle int EnvUngetcRouter(
252 void *theEnv,
253 int ch,
254 const char *logicalName)
255 {
256 struct router *currentPtr;
257
258 /*===================================================*/
259 /* If the "fast load" option is being used, then the */
260 /* logical name is actually a pointer to a file and */
261 /* ungetc can be called directly to bypass querying */
262 /* all of the routers. */
263 /*===================================================*/
264
265 if (((char *) RouterData(theEnv)->FastLoadFilePtr) == logicalName)
266 {
267 if ((ch == '\r') || (ch == '\n'))
268 {
269 if (((char *) RouterData(theEnv)->FastLoadFilePtr) == RouterData(theEnv)->LineCountRouter)
270 { DecrementLineCount(theEnv); }
271 }
272
273 return(ungetc(ch,RouterData(theEnv)->FastLoadFilePtr));
274 }
275
276 /*===============================================*/
277 /* If the "fast string get" option is being used */
278 /* for the specified logical name, then bypass */
279 /* the router system and unget the character */
280 /* directly from the fast get string. */
281 /*===============================================*/
282
283 if (RouterData(theEnv)->FastCharGetRouter == logicalName)
284 {
285 if ((ch == '\r') || (ch == '\n'))
286 {
287 if (RouterData(theEnv)->FastCharGetRouter == RouterData(theEnv)->LineCountRouter)
288 { DecrementLineCount(theEnv); }
289 }
290
291 if (RouterData(theEnv)->FastCharGetIndex > 0) RouterData(theEnv)->FastCharGetIndex--;
292 return(ch);
293 }
294
295 /*===============================================*/
296 /* Search through the list of routers until one */
297 /* is found that will handle the ungetc request. */
298 /*===============================================*/
299
300 currentPtr = RouterData(theEnv)->ListOfRouters;
301 while (currentPtr != NULL)
302 {
303 if ((currentPtr->charunget != NULL) ? QueryRouter(theEnv,logicalName,currentPtr) : FALSE)
304 {
305 if ((ch == '\r') || (ch == '\n'))
306 {
307 if ((RouterData(theEnv)->LineCountRouter != NULL) &&
308 (strcmp(logicalName,RouterData(theEnv)->LineCountRouter) == 0))
309 { DecrementLineCount(theEnv); }
310 }
311
312 SetEnvironmentRouterContext(theEnv,currentPtr->context);
313 if (currentPtr->environmentAware)
314 { return((*currentPtr->charunget)(theEnv,ch,logicalName)); }
315 else
316 { return(((int (*)(int,const char *)) (*currentPtr->charunget))(ch,logicalName)); }
317 }
318
319 currentPtr = currentPtr->next;
320 }
321
322 /*=====================================================*/
323 /* The logical name was not recognized by any routers. */
324 /*=====================================================*/
325
326 UnrecognizedRouterMessage(theEnv,logicalName);
327 return(-1);
328 }
329
330 /*****************************************************/
331 /* ExitCommand: H/L command for exiting the program. */
332 /*****************************************************/
ExitCommand(void * theEnv)333 globle void ExitCommand(
334 void *theEnv)
335 {
336 int argCnt;
337 int status;
338
339 if ((argCnt = EnvArgCountCheck(theEnv,"exit",NO_MORE_THAN,1)) == -1) return;
340 if (argCnt == 0)
341 { EnvExitRouter(theEnv,EXIT_SUCCESS); }
342 else
343 {
344 status = (int) EnvRtnLong(theEnv,1);
345 if (GetEvaluationError(theEnv)) return;
346 EnvExitRouter(theEnv,status);
347 }
348
349 return;
350 }
351
352 /***********************************************/
353 /* EnvExitRouter: Generic exit function. Calls */
354 /* all of the router exit functions. */
355 /***********************************************/
EnvExitRouter(void * theEnv,int num)356 globle void EnvExitRouter(
357 void *theEnv,
358 int num)
359 {
360 struct router *currentPtr, *nextPtr;
361
362 RouterData(theEnv)->Abort = FALSE;
363 currentPtr = RouterData(theEnv)->ListOfRouters;
364 while (currentPtr != NULL)
365 {
366 nextPtr = currentPtr->next;
367 if (currentPtr->active == TRUE)
368 {
369 if (currentPtr->exiter != NULL)
370 {
371 SetEnvironmentRouterContext(theEnv,currentPtr->context);
372 if (currentPtr->environmentAware)
373 { (*currentPtr->exiter)(theEnv,num); }
374 else
375 { ((int (*)(int))(*currentPtr->exiter))(num); }
376 }
377 }
378 currentPtr = nextPtr;
379 }
380
381 if (RouterData(theEnv)->Abort) return;
382 genexit(theEnv,num);
383 }
384
385 /********************************************/
386 /* AbortExit: Forces ExitRouter to terminate */
387 /* after calling all closing routers. */
388 /********************************************/
AbortExit(void * theEnv)389 globle void AbortExit(
390 void *theEnv)
391 {
392 RouterData(theEnv)->Abort = TRUE;
393 }
394
395 /************************************************************/
396 /* EnvAddRouter: Adds an I/O router to the list of routers. */
397 /************************************************************/
EnvAddRouter(void * theEnv,const char * routerName,int priority,int (* queryFunction)(void *,const char *),int (* printFunction)(void *,const char *,const char *),int (* getcFunction)(void *,const char *),int (* ungetcFunction)(void *,int,const char *),int (* exitFunction)(void *,int))398 globle intBool EnvAddRouter(
399 void *theEnv,
400 const char *routerName,
401 int priority,
402 int (*queryFunction)(void *,const char *),
403 int (*printFunction)(void *,const char *,const char *),
404 int (*getcFunction)(void *,const char *),
405 int (*ungetcFunction)(void *,int,const char *),
406 int (*exitFunction)(void *,int))
407 {
408 return EnvAddRouterWithContext(theEnv,routerName,priority,
409 queryFunction,printFunction,getcFunction,
410 ungetcFunction,exitFunction,NULL);
411 }
412
413 /***********************************************************************/
414 /* EnvAddRouterWithContext: Adds an I/O router to the list of routers. */
415 /***********************************************************************/
EnvAddRouterWithContext(void * theEnv,const char * routerName,int priority,int (* queryFunction)(void *,const char *),int (* printFunction)(void *,const char *,const char *),int (* getcFunction)(void *,const char *),int (* ungetcFunction)(void *,int,const char *),int (* exitFunction)(void *,int),void * context)416 globle intBool EnvAddRouterWithContext(
417 void *theEnv,
418 const char *routerName,
419 int priority,
420 int (*queryFunction)(void *,const char *),
421 int (*printFunction)(void *,const char *,const char *),
422 int (*getcFunction)(void *,const char *),
423 int (*ungetcFunction)(void *,int,const char *),
424 int (*exitFunction)(void *,int),
425 void *context)
426 {
427 struct router *newPtr, *lastPtr, *currentPtr;
428 char *nameCopy;
429
430 newPtr = get_struct(theEnv,router);
431
432 nameCopy = (char *) genalloc(theEnv,strlen(routerName) + 1);
433 genstrcpy(nameCopy,routerName);
434 newPtr->name = nameCopy;
435
436 newPtr->active = TRUE;
437 newPtr->environmentAware = TRUE;
438 newPtr->context = context;
439 newPtr->priority = priority;
440 newPtr->query = queryFunction;
441 newPtr->printer = printFunction;
442 newPtr->exiter = exitFunction;
443 newPtr->charget = getcFunction;
444 newPtr->charunget = ungetcFunction;
445 newPtr->next = NULL;
446
447 if (RouterData(theEnv)->ListOfRouters == NULL)
448 {
449 RouterData(theEnv)->ListOfRouters = newPtr;
450 return(1);
451 }
452
453 lastPtr = NULL;
454 currentPtr = RouterData(theEnv)->ListOfRouters;
455 while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE)
456 {
457 lastPtr = currentPtr;
458 currentPtr = currentPtr->next;
459 }
460
461 if (lastPtr == NULL)
462 {
463 newPtr->next = RouterData(theEnv)->ListOfRouters;
464 RouterData(theEnv)->ListOfRouters = newPtr;
465 }
466 else
467 {
468 newPtr->next = currentPtr;
469 lastPtr->next = newPtr;
470 }
471
472 return(1);
473 }
474
475 /********************************************************************/
476 /* EnvDeleteRouter: Removes an I/O router from the list of routers. */
477 /********************************************************************/
EnvDeleteRouter(void * theEnv,const char * routerName)478 globle int EnvDeleteRouter(
479 void *theEnv,
480 const char *routerName)
481 {
482 struct router *currentPtr, *lastPtr;
483
484 currentPtr = RouterData(theEnv)->ListOfRouters;
485 lastPtr = NULL;
486
487 while (currentPtr != NULL)
488 {
489 if (strcmp(currentPtr->name,routerName) == 0)
490 {
491 genfree(theEnv,(void *) currentPtr->name,strlen(currentPtr->name) + 1);
492 if (lastPtr == NULL)
493 {
494 RouterData(theEnv)->ListOfRouters = currentPtr->next;
495 rm(theEnv,currentPtr,(int) sizeof(struct router));
496 return(1);
497 }
498 lastPtr->next = currentPtr->next;
499 rm(theEnv,currentPtr,(int) sizeof(struct router));
500 return(1);
501 }
502 lastPtr = currentPtr;
503 currentPtr = currentPtr->next;
504 }
505
506 return(0);
507 }
508
509 /*********************************************************************/
510 /* QueryRouters: Determines if any router recognizes a logical name. */
511 /*********************************************************************/
QueryRouters(void * theEnv,const char * logicalName)512 globle int QueryRouters(
513 void *theEnv,
514 const char *logicalName)
515 {
516 struct router *currentPtr;
517
518 currentPtr = RouterData(theEnv)->ListOfRouters;
519 while (currentPtr != NULL)
520 {
521 if (QueryRouter(theEnv,logicalName,currentPtr) == TRUE) return(TRUE);
522 currentPtr = currentPtr->next;
523 }
524
525 return(FALSE);
526 }
527
528 /************************************************/
529 /* QueryRouter: Determines if a specific router */
530 /* recognizes a logical name. */
531 /************************************************/
QueryRouter(void * theEnv,const char * logicalName,struct router * currentPtr)532 static int QueryRouter(
533 void *theEnv,
534 const char *logicalName,
535 struct router *currentPtr)
536 {
537 /*===================================================*/
538 /* If the router is inactive, then it can't respond. */
539 /*===================================================*/
540
541 if (currentPtr->active == FALSE)
542 { return(FALSE); }
543
544 /*=============================================================*/
545 /* If the router has no query function, then it can't respond. */
546 /*=============================================================*/
547
548 if (currentPtr->query == NULL) return(FALSE);
549
550 /*=========================================*/
551 /* Call the router's query function to see */
552 /* if it recognizes the logical name. */
553 /*=========================================*/
554
555 SetEnvironmentRouterContext(theEnv,currentPtr->context);
556 if (currentPtr->environmentAware)
557 {
558 if ((*currentPtr->query)(theEnv,logicalName) == TRUE)
559 { return(TRUE); }
560 }
561 else
562 {
563 if (((int (*)(const char *)) (*currentPtr->query))(logicalName) == TRUE)
564 { return(TRUE); }
565 }
566
567 return(FALSE);
568 }
569
570 /*******************************************************/
571 /* EnvDeactivateRouter: Deactivates a specific router. */
572 /*******************************************************/
EnvDeactivateRouter(void * theEnv,const char * routerName)573 globle int EnvDeactivateRouter(
574 void *theEnv,
575 const char *routerName)
576 {
577 struct router *currentPtr;
578
579 currentPtr = RouterData(theEnv)->ListOfRouters;
580
581 while (currentPtr != NULL)
582 {
583 if (strcmp(currentPtr->name,routerName) == 0)
584 {
585 currentPtr->active = FALSE;
586 return(TRUE);
587 }
588 currentPtr = currentPtr->next;
589 }
590
591 return(FALSE);
592 }
593
594 /***************************************************/
595 /* EnvActivateRouter: Activates a specific router. */
596 /***************************************************/
EnvActivateRouter(void * theEnv,const char * routerName)597 globle int EnvActivateRouter(
598 void *theEnv,
599 const char *routerName)
600 {
601 struct router *currentPtr;
602
603 currentPtr = RouterData(theEnv)->ListOfRouters;
604
605 while (currentPtr != NULL)
606 {
607 if (strcmp(currentPtr->name,routerName) == 0)
608 {
609 currentPtr->active = TRUE;
610 return(TRUE);
611 }
612 currentPtr = currentPtr->next;
613 }
614
615 return(FALSE);
616 }
617
618 /********************************************************/
619 /* SetFastLoad: Used to bypass router system for loads. */
620 /********************************************************/
SetFastLoad(void * theEnv,FILE * filePtr)621 globle void SetFastLoad(
622 void *theEnv,
623 FILE *filePtr)
624 {
625 RouterData(theEnv)->FastLoadFilePtr = filePtr;
626 }
627
628 /********************************************************/
629 /* SetFastSave: Used to bypass router system for saves. */
630 /********************************************************/
SetFastSave(void * theEnv,FILE * filePtr)631 globle void SetFastSave(
632 void *theEnv,
633 FILE *filePtr)
634 {
635 RouterData(theEnv)->FastSaveFilePtr = filePtr;
636 }
637
638 /******************************************************/
639 /* GetFastLoad: Returns the "fast load" file pointer. */
640 /******************************************************/
GetFastLoad(void * theEnv)641 globle FILE *GetFastLoad(
642 void *theEnv)
643 {
644 return(RouterData(theEnv)->FastLoadFilePtr);
645 }
646
647 /******************************************************/
648 /* GetFastSave: Returns the "fast save" file pointer. */
649 /******************************************************/
GetFastSave(void * theEnv)650 globle FILE *GetFastSave(
651 void *theEnv)
652 {
653 return(RouterData(theEnv)->FastSaveFilePtr);
654 }
655
656 /*****************************************************/
657 /* UnrecognizedRouterMessage: Standard error message */
658 /* for an unrecognized router name. */
659 /*****************************************************/
UnrecognizedRouterMessage(void * theEnv,const char * logicalName)660 globle void UnrecognizedRouterMessage(
661 void *theEnv,
662 const char *logicalName)
663 {
664 PrintErrorID(theEnv,"ROUTER",1,FALSE);
665 EnvPrintRouter(theEnv,WERROR,"Logical name ");
666 EnvPrintRouter(theEnv,WERROR,logicalName);
667 EnvPrintRouter(theEnv,WERROR," was not recognized by any routers\n");
668 }
669
670 /*****************************************/
671 /* PrintNRouter: Generic print function. */
672 /*****************************************/
PrintNRouter(void * theEnv,const char * logicalName,const char * str,unsigned long length)673 globle int PrintNRouter(
674 void *theEnv,
675 const char *logicalName,
676 const char *str,
677 unsigned long length)
678 {
679 char *tempStr;
680 int rv;
681
682 tempStr = (char *) genalloc(theEnv,length+1);
683 genstrncpy(tempStr,str,length);
684 tempStr[length] = 0;
685 rv = EnvPrintRouter(theEnv,logicalName,tempStr);
686 genfree(theEnv,tempStr,length+1);
687 return(rv);
688 }
689
690 /*#####################################*/
691 /* ALLOW_ENVIRONMENT_GLOBALS Functions */
692 /*#####################################*/
693
694 #if ALLOW_ENVIRONMENT_GLOBALS
695
ActivateRouter(const char * routerName)696 globle int ActivateRouter(
697 const char *routerName)
698 {
699 return EnvActivateRouter(GetCurrentEnvironment(),routerName);
700 }
701
AddRouter(const char * routerName,int priority,int (* queryFunction)(const char *),int (* printFunction)(const char *,const char *),int (* getcFunction)(const char *),int (* ungetcFunction)(int,const char *),int (* exitFunction)(int))702 globle intBool AddRouter(
703 const char *routerName,
704 int priority,
705 int (*queryFunction)(const char *),
706 int (*printFunction)(const char *,const char *),
707 int (*getcFunction)(const char *),
708 int (*ungetcFunction)(int,const char *),
709 int (*exitFunction)(int))
710 {
711 struct router *newPtr, *lastPtr, *currentPtr;
712 void *theEnv;
713 char *nameCopy;
714
715 theEnv = GetCurrentEnvironment();
716
717 newPtr = get_struct(theEnv,router);
718
719 nameCopy = (char *) genalloc(theEnv,strlen(routerName) + 1);
720 genstrcpy(nameCopy,routerName);
721 newPtr->name = nameCopy;
722
723 newPtr->active = TRUE;
724 newPtr->environmentAware = FALSE;
725 newPtr->priority = priority;
726 newPtr->context = NULL;
727 newPtr->query = (int (*)(void *,const char *)) queryFunction;
728 newPtr->printer = (int (*)(void *,const char *,const char *)) printFunction;
729 newPtr->exiter = (int (*)(void *,int)) exitFunction;
730 newPtr->charget = (int (*)(void *,const char *)) getcFunction;
731 newPtr->charunget = (int (*)(void *,int,const char *)) ungetcFunction;
732 newPtr->next = NULL;
733
734 if (RouterData(theEnv)->ListOfRouters == NULL)
735 {
736 RouterData(theEnv)->ListOfRouters = newPtr;
737 return(1);
738 }
739
740 lastPtr = NULL;
741 currentPtr = RouterData(theEnv)->ListOfRouters;
742 while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE)
743 {
744 lastPtr = currentPtr;
745 currentPtr = currentPtr->next;
746 }
747
748 if (lastPtr == NULL)
749 {
750 newPtr->next = RouterData(theEnv)->ListOfRouters;
751 RouterData(theEnv)->ListOfRouters = newPtr;
752 }
753 else
754 {
755 newPtr->next = currentPtr;
756 lastPtr->next = newPtr;
757 }
758
759 return(1);
760 }
761
DeactivateRouter(const char * routerName)762 globle int DeactivateRouter(
763 const char *routerName)
764 {
765 return EnvDeactivateRouter(GetCurrentEnvironment(),routerName);
766 }
767
DeleteRouter(const char * routerName)768 globle int DeleteRouter(
769 const char *routerName)
770 {
771 return EnvDeleteRouter(GetCurrentEnvironment(),routerName);
772 }
773
ExitRouter(int num)774 globle void ExitRouter(
775 int num)
776 {
777 EnvExitRouter(GetCurrentEnvironment(),num);
778 }
779
GetcRouter(const char * logicalName)780 globle int GetcRouter(
781 const char *logicalName)
782 {
783 return EnvGetcRouter(GetCurrentEnvironment(),logicalName);
784 }
785
PrintRouter(const char * logicalName,const char * str)786 globle int PrintRouter(
787 const char *logicalName,
788 const char *str)
789 {
790 return EnvPrintRouter(GetCurrentEnvironment(),logicalName,str);
791 }
792
UngetcRouter(int ch,const char * logicalName)793 globle int UngetcRouter(
794 int ch,
795 const char *logicalName)
796 {
797 return EnvUngetcRouter(GetCurrentEnvironment(),ch,logicalName);
798 }
799
800 #endif /* ALLOW_ENVIRONMENT_GLOBALS */
801
802