1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 01/25/15 */
5 /* */
6 /* CONSTRUCT MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Provides basic functionality for creating new */
11 /* types of constructs, saving constructs to a file, and */
12 /* adding new functionality to the clear and reset */
13 /* commands. */
14 /* */
15 /* Principal Programmer(s): */
16 /* Gary D. Riley */
17 /* */
18 /* Contributing Programmer(s): */
19 /* */
20 /* Revision History: */
21 /* */
22 /* 6.24: Added environment parameter to GenClose. */
23 /* Added environment parameter to GenOpen. */
24 /* */
25 /* Renamed BOOLEAN macro type to intBool. */
26 /* */
27 /* 6.30: Changed garbage collection algorithm. */
28 /* */
29 /* Removed conditional code for unsupported */
30 /* compilers/operating systems (IBM_MCW and */
31 /* MAC_MCW). */
32 /* */
33 /* Added code for capturing errors/warnings */
34 /* (EnvSetParserErrorCallback). */
35 /* */
36 /* Fixed issue with save function when multiple */
37 /* defmodules exist. */
38 /* */
39 /* Added const qualifiers to remove C++ */
40 /* deprecation warnings. */
41 /* */
42 /* Converted API macros to function calls. */
43 /* */
44 /* Fixed linkage issue when BLOAD_ONLY compiler */
45 /* flag is set to 1. */
46 /* */
47 /* Added code to prevent a clear command from */
48 /* being executed during fact assertions via */
49 /* Increment/DecrementClearReadyLocks API. */
50 /* */
51 /* Added code to keep track of pointers to */
52 /* constructs that are contained externally to */
53 /* to constructs, DanglingConstructs. */
54 /* */
55 /*************************************************************/
56
57 #define _CONSTRCT_SOURCE_
58
59 #include <stdio.h>
60 #define _STDIO_INCLUDED_
61 #include <string.h>
62
63 #include "setup.h"
64
65 #include "constant.h"
66 #include "envrnmnt.h"
67 #include "memalloc.h"
68 #include "router.h"
69 #include "scanner.h"
70 #include "watch.h"
71 #include "prcdrfun.h"
72 #include "prcdrpsr.h"
73 #include "argacces.h"
74 #include "exprnpsr.h"
75 #include "multifld.h"
76 #include "moduldef.h"
77 #include "modulutl.h"
78 #include "sysdep.h"
79 #include "utility.h"
80 #include "commline.h"
81 #include "cstrcpsr.h"
82
83 #include "ruledef.h" /* TBD Remove */
84 #include "constrct.h"
85
86 /***************************************/
87 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
88 /***************************************/
89
90 static void DeallocateConstructData(void *);
91
92 /**************************************************/
93 /* InitializeConstructData: Allocates environment */
94 /* data for constructs. */
95 /**************************************************/
InitializeConstructData(void * theEnv)96 globle void InitializeConstructData(
97 void *theEnv)
98 {
99 AllocateEnvironmentData(theEnv,CONSTRUCT_DATA,sizeof(struct constructData),DeallocateConstructData);
100
101 #if (! RUN_TIME) && (! BLOAD_ONLY)
102 ConstructData(theEnv)->WatchCompilations = ON;
103 #endif
104 }
105
106 /****************************************************/
107 /* DeallocateConstructData: Deallocates environment */
108 /* data for constructs. */
109 /****************************************************/
DeallocateConstructData(void * theEnv)110 static void DeallocateConstructData(
111 void *theEnv)
112 {
113 struct construct *tmpPtr, *nextPtr;
114
115 #if (! RUN_TIME) && (! BLOAD_ONLY)
116 DeallocateCallList(theEnv,ConstructData(theEnv)->ListOfSaveFunctions);
117 #endif
118 DeallocateCallList(theEnv,ConstructData(theEnv)->ListOfResetFunctions);
119 DeallocateCallList(theEnv,ConstructData(theEnv)->ListOfClearFunctions);
120 DeallocateCallList(theEnv,ConstructData(theEnv)->ListOfClearReadyFunctions);
121
122 #if (! RUN_TIME) && (! BLOAD_ONLY)
123 if (ConstructData(theEnv)->ErrorString != NULL)
124 { genfree(theEnv,ConstructData(theEnv)->ErrorString,sizeof(ConstructData(theEnv)->ErrorString) + 1); }
125
126 if (ConstructData(theEnv)->WarningString != NULL)
127 { genfree(theEnv,ConstructData(theEnv)->WarningString,sizeof(ConstructData(theEnv)->WarningString) + 1); }
128
129 ConstructData(theEnv)->ErrorString = NULL;
130 ConstructData(theEnv)->WarningString = NULL;
131
132 EnvSetParsingFileName(theEnv,NULL);
133 EnvSetWarningFileName(theEnv,NULL);
134 EnvSetErrorFileName(theEnv,NULL);
135 #endif
136
137 tmpPtr = ConstructData(theEnv)->ListOfConstructs;
138 while (tmpPtr != NULL)
139 {
140 nextPtr = tmpPtr->next;
141 rtn_struct(theEnv,construct,tmpPtr);
142 tmpPtr = nextPtr;
143 }
144 }
145
146 #if (! RUN_TIME) && (! BLOAD_ONLY)
147
148 /**************************************************/
149 /* EnvSetParserErrorCallback: Allows the function */
150 /* which is called when a construct parsing */
151 /* error occurs to be changed. */
152 /**************************************************/
EnvSetParserErrorCallback(void * theEnv,void (* functionPtr)(void *,const char *,const char *,const char *,long))153 globle void (*EnvSetParserErrorCallback(void *theEnv,
154 void (*functionPtr)(void *,const char *,const char *,const char *,long)))
155 (void *,const char *,const char *,const char*,long)
156 {
157 void (*tmpPtr)(void *,const char *,const char *,const char *,long);
158
159 tmpPtr = ConstructData(theEnv)->ParserErrorCallback;
160 ConstructData(theEnv)->ParserErrorCallback = functionPtr;
161 return(tmpPtr);
162 }
163
164 /*************************************************/
165 /* FindConstruct: Determines whether a construct */
166 /* type is in the ListOfConstructs. */
167 /*************************************************/
FindConstruct(void * theEnv,const char * name)168 globle struct construct *FindConstruct(
169 void *theEnv,
170 const char *name)
171 {
172 struct construct *currentPtr;
173
174 for (currentPtr = ConstructData(theEnv)->ListOfConstructs;
175 currentPtr != NULL;
176 currentPtr = currentPtr->next)
177 {
178 if (strcmp(name,currentPtr->constructName) == 0)
179 { return(currentPtr); }
180 }
181
182 return(NULL);
183 }
184
185 /***********************************************************/
186 /* RemoveConstruct: Removes a construct and its associated */
187 /* parsing function from the ListOfConstructs. Returns */
188 /* TRUE if the construct type was removed, otherwise */
189 /* FALSE. */
190 /***********************************************************/
RemoveConstruct(void * theEnv,const char * name)191 globle int RemoveConstruct(
192 void *theEnv,
193 const char *name)
194 {
195 struct construct *currentPtr, *lastPtr = NULL;
196
197 for (currentPtr = ConstructData(theEnv)->ListOfConstructs;
198 currentPtr != NULL;
199 currentPtr = currentPtr->next)
200 {
201 if (strcmp(name,currentPtr->constructName) == 0)
202 {
203 if (lastPtr == NULL)
204 { ConstructData(theEnv)->ListOfConstructs = currentPtr->next; }
205 else
206 { lastPtr->next = currentPtr->next; }
207 rtn_struct(theEnv,construct,currentPtr);
208 return(TRUE);
209 }
210
211 lastPtr = currentPtr;
212 }
213
214 return(FALSE);
215 }
216
217 /************************************************/
218 /* Save: C access routine for the save command. */
219 /************************************************/
EnvSave(void * theEnv,const char * fileName)220 globle int EnvSave(
221 void *theEnv,
222 const char *fileName)
223 {
224 struct callFunctionItem *saveFunction;
225 FILE *filePtr;
226 struct defmodule *defmodulePtr;
227 intBool updated = FALSE;
228 intBool unvisited = TRUE;
229
230 /*=====================*/
231 /* Open the save file. */
232 /*=====================*/
233
234 if ((filePtr = GenOpen(theEnv,fileName,"w")) == NULL)
235 { return(FALSE); }
236
237 /*===========================*/
238 /* Bypass the router system. */
239 /*===========================*/
240
241 SetFastSave(theEnv,filePtr);
242
243 /*================================*/
244 /* Mark all modules as unvisited. */
245 /*================================*/
246
247 MarkModulesAsUnvisited(theEnv);
248
249 /*===============================================*/
250 /* Save the constructs. Repeatedly loop over the */
251 /* modules until each module has been save. */
252 /*===============================================*/
253
254 while (unvisited)
255 {
256 unvisited = FALSE;
257 updated = FALSE;
258
259 for (defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
260 defmodulePtr != NULL;
261 defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,defmodulePtr))
262 {
263 /*=================================================================*/
264 /* We only want to save a module if all of the modules it imports */
265 /* from have already been saved. Since there can't be circular */
266 /* dependencies in imported modules, this should save the modules */
267 /* that don't import anything first and then work back from those. */
268 /*=================================================================*/
269
270 if (defmodulePtr->visitedFlag)
271 { /* Module has already been saved. */ }
272 else if (AllImportedModulesVisited(theEnv,defmodulePtr))
273 {
274 for (saveFunction = ConstructData(theEnv)->ListOfSaveFunctions;
275 saveFunction != NULL;
276 saveFunction = saveFunction->next)
277 {
278 ((* (void (*)(void *,void *,char *)) saveFunction->func))(theEnv,defmodulePtr,(char *) filePtr);
279 }
280
281 updated = TRUE;
282 defmodulePtr->visitedFlag = TRUE;
283 }
284 else
285 { unvisited = TRUE; }
286 }
287
288 /*=====================================================================*/
289 /* At least one module should be saved in every pass. If all have been */
290 /* visited/saved, then both flags will be FALSE. If all remaining */
291 /* unvisited/unsaved modules were visited/saved, then unvisited will */
292 /* be FALSE and updated will be TRUE. If some, but not all, remaining */
293 /* unvisited/unsaved modules are visited/saved, then unvisited will */
294 /* be TRUE and updated will be TRUE. This leaves the case where there */
295 /* are remaining unvisited/unsaved modules, but none were */
296 /* visited/saved: unvisited is TRUE and updated is FALSE. */
297 /*=====================================================================*/
298
299 if (unvisited && (! updated))
300 {
301 SystemError(theEnv,"CONSTRCT",2);
302 break;
303 }
304 }
305
306 /*======================*/
307 /* Close the save file. */
308 /*======================*/
309
310 GenClose(theEnv,filePtr);
311
312 /*===========================*/
313 /* Remove the router bypass. */
314 /*===========================*/
315
316 SetFastSave(theEnv,NULL);
317
318 /*=========================*/
319 /* Return TRUE to indicate */
320 /* successful completion. */
321 /*=========================*/
322
323 return(TRUE);
324 }
325
326 /*******************************************************/
327 /* RemoveSaveFunction: Removes a function from the */
328 /* ListOfSaveFunctions. Returns TRUE if the function */
329 /* was successfully removed, otherwise FALSE. */
330 /*******************************************************/
RemoveSaveFunction(void * theEnv,const char * name)331 globle intBool RemoveSaveFunction(
332 void *theEnv,
333 const char *name)
334 {
335 int found;
336
337 ConstructData(theEnv)->ListOfSaveFunctions =
338 RemoveFunctionFromCallList(theEnv,name,ConstructData(theEnv)->ListOfSaveFunctions,&found);
339
340 if (found) return(TRUE);
341
342 return(FALSE);
343 }
344
345 /**********************************/
346 /* SetCompilationsWatch: Sets the */
347 /* value of WatchCompilations. */
348 /**********************************/
SetCompilationsWatch(void * theEnv,unsigned value)349 globle void SetCompilationsWatch(
350 void *theEnv,
351 unsigned value)
352 {
353 ConstructData(theEnv)->WatchCompilations = value;
354 }
355
356 /*************************************/
357 /* GetCompilationsWatch: Returns the */
358 /* value of WatchCompilations. */
359 /*************************************/
GetCompilationsWatch(void * theEnv)360 globle unsigned GetCompilationsWatch(
361 void *theEnv)
362 {
363 return(ConstructData(theEnv)->WatchCompilations);
364 }
365
366 /**********************************/
367 /* SetPrintWhileLoading: Sets the */
368 /* value of PrintWhileLoading. */
369 /**********************************/
SetPrintWhileLoading(void * theEnv,intBool value)370 globle void SetPrintWhileLoading(
371 void *theEnv,
372 intBool value)
373 {
374 ConstructData(theEnv)->PrintWhileLoading = value;
375 }
376
377 /*************************************/
378 /* GetPrintWhileLoading: Returns the */
379 /* value of PrintWhileLoading. */
380 /*************************************/
GetPrintWhileLoading(void * theEnv)381 globle intBool GetPrintWhileLoading(
382 void *theEnv)
383 {
384 return(ConstructData(theEnv)->PrintWhileLoading);
385 }
386 #endif
387
388 /*************************************/
389 /* InitializeConstructs: Initializes */
390 /* the Construct Manager. */
391 /*************************************/
InitializeConstructs(void * theEnv)392 globle void InitializeConstructs(
393 void *theEnv)
394 {
395 #if (! RUN_TIME)
396 EnvDefineFunction2(theEnv,"clear", 'v', PTIEF ClearCommand, "ClearCommand", "00");
397 EnvDefineFunction2(theEnv,"reset", 'v', PTIEF ResetCommand, "ResetCommand", "00");
398
399 #if DEBUGGING_FUNCTIONS && (! BLOAD_ONLY)
400 AddWatchItem(theEnv,"compilations",0,&ConstructData(theEnv)->WatchCompilations,30,NULL,NULL);
401 #endif
402 #else
403 #if MAC_XCD
404 #pragma unused(theEnv)
405 #endif
406 #endif
407 }
408
409 /**************************************/
410 /* ClearCommand: H/L access routine */
411 /* for the clear command. */
412 /**************************************/
ClearCommand(void * theEnv)413 globle void ClearCommand(
414 void *theEnv)
415 {
416 if (EnvArgCountCheck(theEnv,"clear",EXACTLY,0) == -1) return;
417 EnvClear(theEnv);
418 return;
419 }
420
421 /**************************************/
422 /* ResetCommand: H/L access routine */
423 /* for the reset command. */
424 /**************************************/
ResetCommand(void * theEnv)425 globle void ResetCommand(
426 void *theEnv)
427 {
428 if (EnvArgCountCheck(theEnv,"reset",EXACTLY,0) == -1) return;
429 EnvReset(theEnv);
430 return;
431 }
432
433 /******************************/
434 /* EnvReset: C access routine */
435 /* for the reset command. */
436 /******************************/
EnvReset(void * theEnv)437 globle void EnvReset(
438 void *theEnv)
439 {
440 struct callFunctionItem *resetPtr;
441
442 /*=====================================*/
443 /* The reset command can't be executed */
444 /* while a reset is in progress. */
445 /*=====================================*/
446
447 if (ConstructData(theEnv)->ResetInProgress) return;
448
449 ConstructData(theEnv)->ResetInProgress = TRUE;
450 ConstructData(theEnv)->ResetReadyInProgress = TRUE;
451
452 /*================================================*/
453 /* If the reset is performed from the top level */
454 /* command prompt, reset the halt execution flag. */
455 /*================================================*/
456
457 if (UtilityData(theEnv)->CurrentGarbageFrame->topLevel) SetHaltExecution(theEnv,FALSE);
458
459 /*=======================================================*/
460 /* Call the before reset function to determine if the */
461 /* reset should continue. [Used by the some of the */
462 /* windowed interfaces to query the user whether a */
463 /* reset should proceed with activations on the agenda.] */
464 /*=======================================================*/
465
466 if ((ConstructData(theEnv)->BeforeResetFunction != NULL) ?
467 ((*ConstructData(theEnv)->BeforeResetFunction)(theEnv) == FALSE) :
468 FALSE)
469 {
470 ConstructData(theEnv)->ResetReadyInProgress = FALSE;
471 ConstructData(theEnv)->ResetInProgress = FALSE;
472 return;
473 }
474 ConstructData(theEnv)->ResetReadyInProgress = FALSE;
475
476 /*===========================*/
477 /* Call each reset function. */
478 /*===========================*/
479
480 for (resetPtr = ConstructData(theEnv)->ListOfResetFunctions;
481 (resetPtr != NULL) && (GetHaltExecution(theEnv) == FALSE);
482 resetPtr = resetPtr->next)
483 {
484 if (resetPtr->environmentAware)
485 { (*resetPtr->func)(theEnv); }
486 else
487 { (* (void (*)(void)) resetPtr->func)(); }
488 }
489
490 /*============================================*/
491 /* Set the current module to the MAIN module. */
492 /*============================================*/
493
494 EnvSetCurrentModule(theEnv,(void *) EnvFindDefmodule(theEnv,"MAIN"));
495
496 /*===========================================*/
497 /* Perform periodic cleanup if the reset was */
498 /* issued from an embedded controller. */
499 /*===========================================*/
500
501 if ((UtilityData(theEnv)->CurrentGarbageFrame->topLevel) && (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&
502 (EvaluationData(theEnv)->CurrentExpression == NULL) && (UtilityData(theEnv)->GarbageCollectionLocks == 0))
503 {
504 CleanCurrentGarbageFrame(theEnv,NULL);
505 CallPeriodicTasks(theEnv);
506 }
507
508 /*===================================*/
509 /* A reset is no longer in progress. */
510 /*===================================*/
511
512 ConstructData(theEnv)->ResetInProgress = FALSE;
513 }
514
515 /************************************/
516 /* SetBeforeResetFunction: Sets the */
517 /* value of BeforeResetFunction. */
518 /************************************/
SetBeforeResetFunction(void * theEnv,int (* theFunction)(void *))519 globle int (*SetBeforeResetFunction(void *theEnv,
520 int (*theFunction)(void *)))(void *)
521 {
522 int (*tempFunction)(void *);
523
524 tempFunction = ConstructData(theEnv)->BeforeResetFunction;
525 ConstructData(theEnv)->BeforeResetFunction = theFunction;
526 return(tempFunction);
527 }
528
529 /****************************************/
530 /* EnvAddResetFunction: Adds a function */
531 /* to ListOfResetFunctions. */
532 /****************************************/
EnvAddResetFunction(void * theEnv,const char * name,void (* functionPtr)(void *),int priority)533 globle intBool EnvAddResetFunction(
534 void *theEnv,
535 const char *name,
536 void (*functionPtr)(void *),
537 int priority)
538 {
539 ConstructData(theEnv)->ListOfResetFunctions = AddFunctionToCallList(theEnv,name,priority,
540 functionPtr,
541 ConstructData(theEnv)->ListOfResetFunctions,TRUE);
542 return(TRUE);
543 }
544
545 /**********************************************/
546 /* EnvRemoveResetFunction: Removes a function */
547 /* from the ListOfResetFunctions. */
548 /**********************************************/
EnvRemoveResetFunction(void * theEnv,const char * name)549 globle intBool EnvRemoveResetFunction(
550 void *theEnv,
551 const char *name)
552 {
553 int found;
554
555 ConstructData(theEnv)->ListOfResetFunctions =
556 RemoveFunctionFromCallList(theEnv,name,ConstructData(theEnv)->ListOfResetFunctions,&found);
557
558 if (found) return(TRUE);
559
560 return(FALSE);
561 }
562
563 /*******************************************/
564 /* EnvIncrementClearReadyLocks: Increments */
565 /* the number of clear ready locks. */
566 /*******************************************/
EnvIncrementClearReadyLocks(void * theEnv)567 globle void EnvIncrementClearReadyLocks(
568 void *theEnv)
569 {
570 ConstructData(theEnv)->ClearReadyLocks++;
571 }
572
573 /*******************************************/
574 /* EnvDecrementClearReadyLocks: Decrements */
575 /* the number of clear locks. */
576 /*******************************************/
EnvDecrementClearReadyLocks(void * theEnv)577 globle void EnvDecrementClearReadyLocks(
578 void *theEnv)
579 {
580 if (ConstructData(theEnv)->ClearReadyLocks > 0)
581 { ConstructData(theEnv)->ClearReadyLocks--; }
582 }
583
584 /*****************************************************/
585 /* EnvClear: C access routine for the clear command. */
586 /*****************************************************/
EnvClear(void * theEnv)587 globle void EnvClear(
588 void *theEnv)
589 {
590 struct callFunctionItem *theFunction;
591
592 /*==========================================*/
593 /* Activate the watch router which captures */
594 /* trace output so that it is not displayed */
595 /* during a clear. */
596 /*==========================================*/
597
598 #if DEBUGGING_FUNCTIONS
599 EnvActivateRouter(theEnv,WTRACE);
600 #endif
601
602 /*===================================*/
603 /* Determine if a clear is possible. */
604 /*===================================*/
605
606 ConstructData(theEnv)->ClearReadyInProgress = TRUE;
607 if ((ConstructData(theEnv)->ClearReadyLocks > 0) ||
608 (ConstructData(theEnv)->DanglingConstructs > 0) ||
609 (ClearReady(theEnv) == FALSE))
610 {
611 PrintErrorID(theEnv,"CONSTRCT",1,FALSE);
612 EnvPrintRouter(theEnv,WERROR,"Some constructs are still in use. Clear cannot continue.\n");
613 #if DEBUGGING_FUNCTIONS
614 EnvDeactivateRouter(theEnv,WTRACE);
615 #endif
616 ConstructData(theEnv)->ClearReadyInProgress = FALSE;
617 return;
618 }
619 ConstructData(theEnv)->ClearReadyInProgress = FALSE;
620
621 /*===========================*/
622 /* Call all clear functions. */
623 /*===========================*/
624
625 ConstructData(theEnv)->ClearInProgress = TRUE;
626
627 for (theFunction = ConstructData(theEnv)->ListOfClearFunctions;
628 theFunction != NULL;
629 theFunction = theFunction->next)
630 {
631 if (theFunction->environmentAware)
632 { (*theFunction->func)(theEnv); }
633 else
634 { (* (void (*)(void)) theFunction->func)(); }
635 }
636
637 /*=============================*/
638 /* Deactivate the watch router */
639 /* for capturing output. */
640 /*=============================*/
641
642 #if DEBUGGING_FUNCTIONS
643 EnvDeactivateRouter(theEnv,WTRACE);
644 #endif
645
646 /*===========================================*/
647 /* Perform periodic cleanup if the clear was */
648 /* issued from an embedded controller. */
649 /*===========================================*/
650
651 if ((UtilityData(theEnv)->CurrentGarbageFrame->topLevel) && (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&
652 (EvaluationData(theEnv)->CurrentExpression == NULL) && (UtilityData(theEnv)->GarbageCollectionLocks == 0))
653 {
654 CleanCurrentGarbageFrame(theEnv,NULL);
655 CallPeriodicTasks(theEnv);
656 }
657
658 /*===========================*/
659 /* Clear has been completed. */
660 /*===========================*/
661
662 ConstructData(theEnv)->ClearInProgress = FALSE;
663
664 #if DEFRULE_CONSTRUCT
665 if ((DefruleData(theEnv)->RightPrimeJoins != NULL) ||
666 (DefruleData(theEnv)->LeftPrimeJoins != NULL))
667 { SystemError(theEnv,"CONSTRCT",1); }
668 #endif
669
670 /*============================*/
671 /* Perform reset after clear. */
672 /*============================*/
673
674 EnvReset(theEnv);
675 }
676
677 /*********************************************************/
678 /* ClearReady: Returns TRUE if a clear can be performed, */
679 /* otherwise FALSE. Note that this is destructively */
680 /* determined (e.g. facts will be deleted as part of */
681 /* the determination). */
682 /*********************************************************/
ClearReady(void * theEnv)683 globle intBool ClearReady(
684 void *theEnv)
685 {
686 struct callFunctionItem *theFunction;
687 int (*tempFunction)(void *);
688
689 for (theFunction = ConstructData(theEnv)->ListOfClearReadyFunctions;
690 theFunction != NULL;
691 theFunction = theFunction->next)
692 {
693 tempFunction = (int (*)(void *)) theFunction->func;
694 if ((*tempFunction)(theEnv) == FALSE)
695 { return(FALSE); }
696 }
697
698 return(TRUE);
699 }
700
701 /******************************************/
702 /* AddClearReadyFunction: Adds a function */
703 /* to ListOfClearReadyFunctions. */
704 /******************************************/
AddClearReadyFunction(void * theEnv,const char * name,int (* functionPtr)(void *),int priority)705 globle intBool AddClearReadyFunction(
706 void *theEnv,
707 const char *name,
708 int (*functionPtr)(void *),
709 int priority)
710 {
711 ConstructData(theEnv)->ListOfClearReadyFunctions =
712 AddFunctionToCallList(theEnv,name,priority,
713 (void (*)(void *)) functionPtr,
714 ConstructData(theEnv)->ListOfClearReadyFunctions,TRUE);
715 return(1);
716 }
717
718 /************************************************/
719 /* RemoveClearReadyFunction: Removes a function */
720 /* from the ListOfClearReadyFunctions. */
721 /************************************************/
RemoveClearReadyFunction(void * theEnv,const char * name)722 globle intBool RemoveClearReadyFunction(
723 void *theEnv,
724 const char *name)
725 {
726 int found;
727
728 ConstructData(theEnv)->ListOfClearReadyFunctions =
729 RemoveFunctionFromCallList(theEnv,name,ConstructData(theEnv)->ListOfClearReadyFunctions,&found);
730
731 if (found) return(TRUE);
732
733 return(FALSE);
734 }
735
736 /****************************************/
737 /* EnvAddClearFunction: Adds a function */
738 /* to ListOfClearFunctions. */
739 /****************************************/
EnvAddClearFunction(void * theEnv,const char * name,void (* functionPtr)(void *),int priority)740 globle intBool EnvAddClearFunction(
741 void *theEnv,
742 const char *name,
743 void (*functionPtr)(void *),
744 int priority)
745 {
746 ConstructData(theEnv)->ListOfClearFunctions =
747 AddFunctionToCallList(theEnv,name,priority,
748 (void (*)(void *)) functionPtr,
749 ConstructData(theEnv)->ListOfClearFunctions,TRUE);
750 return(1);
751 }
752
753 /**********************************************/
754 /* EnvRemoveClearFunction: Removes a function */
755 /* from the ListOfClearFunctions. */
756 /**********************************************/
EnvRemoveClearFunction(void * theEnv,const char * name)757 globle intBool EnvRemoveClearFunction(
758 void *theEnv,
759 const char *name)
760 {
761 int found;
762
763 ConstructData(theEnv)->ListOfClearFunctions =
764 RemoveFunctionFromCallList(theEnv,name,ConstructData(theEnv)->ListOfClearFunctions,&found);
765
766 if (found) return(TRUE);
767
768 return(FALSE);
769 }
770
771 /***********************************************/
772 /* ExecutingConstruct: Returns TRUE if a */
773 /* construct is currently being executed, */
774 /* otherwise FALSE. */
775 /***********************************************/
ExecutingConstruct(void * theEnv)776 globle int ExecutingConstruct(
777 void *theEnv)
778 {
779 return(ConstructData(theEnv)->Executing);
780 }
781
782 /********************************************/
783 /* SetExecutingConstruct: Sets the value of */
784 /* the executing variable indicating that */
785 /* actions such as reset, clear, etc */
786 /* should not be performed. */
787 /********************************************/
SetExecutingConstruct(void * theEnv,int value)788 globle void SetExecutingConstruct(
789 void *theEnv,
790 int value)
791 {
792 ConstructData(theEnv)->Executing = value;
793 }
794
795 /*******************************************************/
796 /* DeinstallConstructHeader: Decrements the busy count */
797 /* of a construct name and frees its pretty print */
798 /* representation string (both of which are stored */
799 /* in the generic construct header). */
800 /*******************************************************/
DeinstallConstructHeader(void * theEnv,struct constructHeader * theHeader)801 globle void DeinstallConstructHeader(
802 void *theEnv,
803 struct constructHeader *theHeader)
804 {
805 DecrementSymbolCount(theEnv,theHeader->name);
806 if (theHeader->ppForm != NULL)
807 {
808 rm(theEnv,(void *) theHeader->ppForm,
809 sizeof(char) * (strlen(theHeader->ppForm) + 1));
810 theHeader->ppForm = NULL;
811 }
812
813 if (theHeader->usrData != NULL)
814 {
815 ClearUserDataList(theEnv,theHeader->usrData);
816 theHeader->usrData = NULL;
817 }
818 }
819
820 /**************************************************/
821 /* DestroyConstructHeader: Frees the pretty print */
822 /* representation string and user data (both of */
823 /* which are stored in the generic construct */
824 /* header). */
825 /**************************************************/
DestroyConstructHeader(void * theEnv,struct constructHeader * theHeader)826 globle void DestroyConstructHeader(
827 void *theEnv,
828 struct constructHeader *theHeader)
829 {
830 if (theHeader->ppForm != NULL)
831 {
832 rm(theEnv,(void *) theHeader->ppForm,
833 sizeof(char) * (strlen(theHeader->ppForm) + 1));
834 theHeader->ppForm = NULL;
835 }
836
837 if (theHeader->usrData != NULL)
838 {
839 ClearUserDataList(theEnv,theHeader->usrData);
840 theHeader->usrData = NULL;
841 }
842 }
843
844 /*****************************************************/
845 /* AddConstruct: Adds a construct and its associated */
846 /* parsing function to the ListOfConstructs. */
847 /*****************************************************/
AddConstruct(void * theEnv,const char * name,const char * pluralName,int (* parseFunction)(void *,const char *),void * (* findFunction)(void *,const char *),SYMBOL_HN * (* getConstructNameFunction)(struct constructHeader *),const char * (* getPPFormFunction)(void *,struct constructHeader *),struct defmoduleItemHeader * (* getModuleItemFunction)(struct constructHeader *),void * (* getNextItemFunction)(void *,void *),void (* setNextItemFunction)(struct constructHeader *,struct constructHeader *),intBool (* isConstructDeletableFunction)(void *,void *),int (* deleteFunction)(void *,void *),void (* freeFunction)(void *,void *))848 globle struct construct *AddConstruct(
849 void *theEnv,
850 const char *name,
851 const char *pluralName,
852 int (*parseFunction)(void *,const char *),
853 void *(*findFunction)(void *,const char *),
854 SYMBOL_HN *(*getConstructNameFunction)(struct constructHeader *),
855 const char *(*getPPFormFunction)(void *,struct constructHeader *),
856 struct defmoduleItemHeader *(*getModuleItemFunction)(struct constructHeader *),
857 void *(*getNextItemFunction)(void *,void *),
858 void (*setNextItemFunction)(struct constructHeader *,struct constructHeader *),
859 intBool (*isConstructDeletableFunction)(void *,void *),
860 int (*deleteFunction)(void *,void *),
861 void (*freeFunction)(void *,void *))
862 {
863 struct construct *newPtr;
864
865 /*=============================*/
866 /* Allocate and initialize the */
867 /* construct data structure. */
868 /*=============================*/
869
870 newPtr = get_struct(theEnv,construct);
871
872 newPtr->constructName = name;
873 newPtr->pluralName = pluralName;
874 newPtr->parseFunction = parseFunction;
875 newPtr->findFunction = findFunction;
876 newPtr->getConstructNameFunction = getConstructNameFunction;
877 newPtr->getPPFormFunction = getPPFormFunction;
878 newPtr->getModuleItemFunction = getModuleItemFunction;
879 newPtr->getNextItemFunction = getNextItemFunction;
880 newPtr->setNextItemFunction = setNextItemFunction;
881 newPtr->isConstructDeletableFunction = isConstructDeletableFunction;
882 newPtr->deleteFunction = deleteFunction;
883 newPtr->freeFunction = freeFunction;
884
885 /*===============================*/
886 /* Add the construct to the list */
887 /* of constructs and return it. */
888 /*===============================*/
889
890 newPtr->next = ConstructData(theEnv)->ListOfConstructs;
891 ConstructData(theEnv)->ListOfConstructs = newPtr;
892 return(newPtr);
893 }
894
895 /************************************/
896 /* AddSaveFunction: Adds a function */
897 /* to the ListOfSaveFunctions. */
898 /************************************/
AddSaveFunction(void * theEnv,const char * name,void (* functionPtr)(void *,void *,const char *),int priority)899 globle intBool AddSaveFunction(
900 void *theEnv,
901 const char *name,
902 void (*functionPtr)(void *,void *,const char *),
903 int priority)
904 {
905 #if (! RUN_TIME) && (! BLOAD_ONLY)
906 ConstructData(theEnv)->ListOfSaveFunctions =
907 AddFunctionToCallList(theEnv,name,priority,
908 (void (*)(void *)) functionPtr,
909 ConstructData(theEnv)->ListOfSaveFunctions,TRUE);
910 #else
911 #if MAC_XCD
912 #pragma unused(theEnv)
913 #endif
914 #endif
915
916 return(1);
917 }
918
919 /*#####################################*/
920 /* ALLOW_ENVIRONMENT_GLOBALS Functions */
921 /*#####################################*/
922
923 #if ALLOW_ENVIRONMENT_GLOBALS
924
AddClearFunction(const char * name,void (* functionPtr)(void),int priority)925 globle intBool AddClearFunction(
926 const char *name,
927 void (*functionPtr)(void),
928 int priority)
929 {
930 void *theEnv;
931
932 theEnv = GetCurrentEnvironment();
933
934 ConstructData(theEnv)->ListOfClearFunctions =
935 AddFunctionToCallList(theEnv,name,priority,
936 (void (*)(void *)) functionPtr,
937 ConstructData(theEnv)->ListOfClearFunctions,FALSE);
938 return(1);
939 }
940
AddResetFunction(const char * name,void (* functionPtr)(void),int priority)941 globle intBool AddResetFunction(
942 const char *name,
943 void (*functionPtr)(void),
944 int priority)
945 {
946 void *theEnv;
947
948 theEnv = GetCurrentEnvironment();
949
950 ConstructData(theEnv)->ListOfResetFunctions =
951 AddFunctionToCallList(theEnv,name,priority,(void (*)(void *)) functionPtr,
952 ConstructData(theEnv)->ListOfResetFunctions,FALSE);
953 return(TRUE);
954 }
955
Clear()956 globle void Clear()
957 {
958 EnvClear(GetCurrentEnvironment());
959 }
960
RemoveClearFunction(const char * name)961 globle intBool RemoveClearFunction(
962 const char *name)
963 {
964 return EnvRemoveClearFunction(GetCurrentEnvironment(),name);
965 }
966
RemoveResetFunction(const char * name)967 globle intBool RemoveResetFunction(
968 const char *name)
969 {
970 return EnvRemoveResetFunction(GetCurrentEnvironment(),name);
971 }
972
Reset()973 globle void Reset()
974 {
975 EnvReset(GetCurrentEnvironment());
976 }
977
978 #if (! RUN_TIME) && (! BLOAD_ONLY)
979
Save(const char * fileName)980 globle int Save(
981 const char *fileName)
982 {
983 return EnvSave(GetCurrentEnvironment(),fileName);
984 }
985 #endif
986
987 #endif
988
989
990