1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 01/25/15 */
5 /* */
6 /* DEFGLOBAL MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Provides core routines for the creation and */
11 /* maintenance of the defglobal construct. */
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.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
22 /* */
23 /* 6.24: Renamed BOOLEAN macro type to intBool. */
24 /* */
25 /* Corrected code to remove run-time program */
26 /* compiler warning. */
27 /* */
28 /* 6.30: Removed conditional code for unsupported */
29 /* compilers/operating systems (IBM_MCW, */
30 /* MAC_MCW, and IBM_TBC). */
31 /* */
32 /* Changed garbage collection algorithm. */
33 /* */
34 /* Added const qualifiers to remove C++ */
35 /* deprecation warnings. */
36 /* */
37 /* Converted API macros to function calls. */
38 /* */
39 /* Fixed linkage issue when BLOAD_ONLY compiler */
40 /* flag is set to 1. */
41 /* */
42 /* Changed find construct functionality so that */
43 /* imported modules are search when locating a */
44 /* named construct. */
45 /* */
46 /*************************************************************/
47
48 #define _GLOBLDEF_SOURCE_
49
50 #include "setup.h"
51
52 #if DEFGLOBAL_CONSTRUCT
53
54 #include <stdio.h>
55 #define _STDIO_INCLUDED_
56
57 #include "memalloc.h"
58 #include "modulpsr.h"
59 #include "multifld.h"
60 #include "router.h"
61 #include "strngrtr.h"
62 #include "modulutl.h"
63 #include "globlbsc.h"
64 #include "globlpsr.h"
65 #include "globlcom.h"
66 #include "utility.h"
67 #include "commline.h"
68 #include "envrnmnt.h"
69
70 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
71 #include "bload.h"
72 #include "globlbin.h"
73 #endif
74
75 #if CONSTRUCT_COMPILER && (! RUN_TIME)
76 #include "globlcmp.h"
77 #endif
78
79 #include "globldef.h"
80
81 /***************************************/
82 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
83 /***************************************/
84
85 static void *AllocateModule(void *);
86 static void ReturnModule(void *,void *);
87 static void ReturnDefglobal(void *,void *);
88 static void InitializeDefglobalModules(void *);
89 static intBool GetDefglobalValue2(void *,void *,DATA_OBJECT_PTR);
90 static void IncrementDefglobalBusyCount(void *,void *);
91 static void DecrementDefglobalBusyCount(void *,void *);
92 static void DeallocateDefglobalData(void *);
93 static void DestroyDefglobalAction(void *,struct constructHeader *,void *);
94 #if (! BLOAD_ONLY)
95 static void DestroyDefglobal(void *,void *);
96 #endif
97
98 /**************************************************************/
99 /* InitializeDefglobals: Initializes the defglobal construct. */
100 /**************************************************************/
InitializeDefglobals(void * theEnv)101 globle void InitializeDefglobals(
102 void *theEnv)
103 {
104 struct entityRecord globalInfo = { "GBL_VARIABLE", GBL_VARIABLE,0,0,0,
105 NULL,
106 NULL,
107 NULL,
108 GetDefglobalValue2,
109 NULL,NULL,
110 NULL,NULL,NULL,NULL,NULL,NULL };
111
112 struct entityRecord defglobalPtrRecord = { "DEFGLOBAL_PTR", DEFGLOBAL_PTR,0,0,0,
113 NULL,NULL,NULL,
114 QGetDefglobalValue,
115 NULL,
116 DecrementDefglobalBusyCount,
117 IncrementDefglobalBusyCount,
118 NULL,NULL,NULL,NULL,NULL };
119
120 AllocateEnvironmentData(theEnv,DEFGLOBAL_DATA,sizeof(struct defglobalData),DeallocateDefglobalData);
121
122 memcpy(&DefglobalData(theEnv)->GlobalInfo,&globalInfo,sizeof(struct entityRecord));
123 memcpy(&DefglobalData(theEnv)->DefglobalPtrRecord,&defglobalPtrRecord,sizeof(struct entityRecord));
124
125 DefglobalData(theEnv)->ResetGlobals = TRUE;
126 DefglobalData(theEnv)->LastModuleIndex = -1;
127
128 InstallPrimitive(theEnv,&DefglobalData(theEnv)->GlobalInfo,GBL_VARIABLE);
129 InstallPrimitive(theEnv,&DefglobalData(theEnv)->DefglobalPtrRecord,DEFGLOBAL_PTR);
130
131 InitializeDefglobalModules(theEnv);
132
133 DefglobalBasicCommands(theEnv);
134 DefglobalCommandDefinitions(theEnv);
135
136 DefglobalData(theEnv)->DefglobalConstruct =
137 AddConstruct(theEnv,"defglobal","defglobals",ParseDefglobal,EnvFindDefglobal,
138 GetConstructNamePointer,GetConstructPPForm,
139 GetConstructModuleItem,EnvGetNextDefglobal,SetNextConstruct,
140 EnvIsDefglobalDeletable,EnvUndefglobal,ReturnDefglobal);
141 }
142
143 /****************************************************/
144 /* DeallocateDefglobalData: Deallocates environment */
145 /* data for the defglobal construct. */
146 /****************************************************/
DeallocateDefglobalData(void * theEnv)147 static void DeallocateDefglobalData(
148 void *theEnv)
149 {
150 #if ! RUN_TIME
151 struct defglobalModule *theModuleItem;
152 void *theModule;
153
154 #if BLOAD || BLOAD_AND_BSAVE
155 if (Bloaded(theEnv)) return;
156 #endif
157
158 DoForAllConstructs(theEnv,DestroyDefglobalAction,DefglobalData(theEnv)->DefglobalModuleIndex,FALSE,NULL);
159
160 for (theModule = EnvGetNextDefmodule(theEnv,NULL);
161 theModule != NULL;
162 theModule = EnvGetNextDefmodule(theEnv,theModule))
163 {
164 theModuleItem = (struct defglobalModule *)
165 GetModuleItem(theEnv,(struct defmodule *) theModule,
166 DefglobalData(theEnv)->DefglobalModuleIndex);
167 rtn_struct(theEnv,defglobalModule,theModuleItem);
168 }
169 #else
170 DoForAllConstructs(theEnv,DestroyDefglobalAction,DefglobalData(theEnv)->DefglobalModuleIndex,FALSE,NULL);
171 #endif
172 }
173
174 /***************************************************/
175 /* DestroyDefglobalAction: Action used to remove */
176 /* defglobals as a result of DestroyEnvironment. */
177 /***************************************************/
DestroyDefglobalAction(void * theEnv,struct constructHeader * theConstruct,void * buffer)178 static void DestroyDefglobalAction(
179 void *theEnv,
180 struct constructHeader *theConstruct,
181 void *buffer)
182 {
183 #if MAC_XCD
184 #pragma unused(buffer)
185 #endif
186 #if (! BLOAD_ONLY)
187 struct defglobal *theDefglobal = (struct defglobal *) theConstruct;
188
189 if (theDefglobal == NULL) return;
190
191 DestroyDefglobal(theEnv,theDefglobal);
192 #else
193 #if MAC_XCD
194 #pragma unused(theEnv,theConstruct)
195 #endif
196 #endif
197 }
198
199 /*********************************************************/
200 /* InitializeDefglobalModules: Initializes the defglobal */
201 /* construct for use with the defmodule construct. */
202 /*********************************************************/
InitializeDefglobalModules(void * theEnv)203 static void InitializeDefglobalModules(
204 void *theEnv)
205 {
206 DefglobalData(theEnv)->DefglobalModuleIndex = RegisterModuleItem(theEnv,"defglobal",
207 AllocateModule,
208 ReturnModule,
209 #if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
210 BloadDefglobalModuleReference,
211 #else
212 NULL,
213 #endif
214 #if CONSTRUCT_COMPILER && (! RUN_TIME)
215 DefglobalCModuleReference,
216 #else
217 NULL,
218 #endif
219 EnvFindDefglobalInModule);
220
221 #if (! BLOAD_ONLY) && (! RUN_TIME) && DEFMODULE_CONSTRUCT
222 AddPortConstructItem(theEnv,"defglobal",SYMBOL);
223 #endif
224 }
225
226 /*************************************************/
227 /* AllocateModule: Allocates a defglobal module. */
228 /*************************************************/
AllocateModule(void * theEnv)229 static void *AllocateModule(
230 void *theEnv)
231 {
232 return((void *) get_struct(theEnv,defglobalModule));
233 }
234
235 /***********************************************/
236 /* ReturnModule: Deallocates a defglobal module. */
237 /***********************************************/
ReturnModule(void * theEnv,void * theItem)238 static void ReturnModule(
239 void *theEnv,
240 void *theItem)
241 {
242 FreeConstructHeaderModule(theEnv,(struct defmoduleItemHeader *) theItem,DefglobalData(theEnv)->DefglobalConstruct);
243 rtn_struct(theEnv,defglobalModule,theItem);
244 }
245
246 /**************************************************************/
247 /* GetDefglobalModuleItem: Returns a pointer to the defmodule */
248 /* item for the specified defglobal or defmodule. */
249 /**************************************************************/
GetDefglobalModuleItem(void * theEnv,struct defmodule * theModule)250 globle struct defglobalModule *GetDefglobalModuleItem(
251 void *theEnv,
252 struct defmodule *theModule)
253 {
254 return((struct defglobalModule *) GetConstructModuleItemByIndex(theEnv,theModule,DefglobalData(theEnv)->DefglobalModuleIndex));
255 }
256
257 /*****************************************************/
258 /* EnvFindDefglobal: Searches for a defglobal in the */
259 /* list of defglobals. Returns a pointer to the */
260 /* defglobal if found, otherwise NULL. */
261 /*****************************************************/
EnvFindDefglobal(void * theEnv,const char * defglobalName)262 globle void *EnvFindDefglobal(
263 void *theEnv,
264 const char *defglobalName)
265 {
266 return(FindNamedConstructInModuleOrImports(theEnv,defglobalName,DefglobalData(theEnv)->DefglobalConstruct));
267 }
268
269 /*****************************************************/
270 /* EnvFindDefglobalInModule: Searches for a defglobal in the */
271 /* list of defglobals. Returns a pointer to the */
272 /* defglobal if found, otherwise NULL. */
273 /*****************************************************/
EnvFindDefglobalInModule(void * theEnv,const char * defglobalName)274 globle void *EnvFindDefglobalInModule(
275 void *theEnv,
276 const char *defglobalName)
277 {
278 return(FindNamedConstructInModule(theEnv,defglobalName,DefglobalData(theEnv)->DefglobalConstruct));
279 }
280
281 /********************************************************************/
282 /* EnvGetNextDefglobal: If passed a NULL pointer, returns the first */
283 /* defglobal in the defglobal list. Otherwise returns the next */
284 /* defglobal following the defglobal passed as an argument. */
285 /********************************************************************/
EnvGetNextDefglobal(void * theEnv,void * defglobalPtr)286 globle void *EnvGetNextDefglobal(
287 void *theEnv,
288 void *defglobalPtr)
289 {
290 return((void *) GetNextConstructItem(theEnv,(struct constructHeader *) defglobalPtr,DefglobalData(theEnv)->DefglobalModuleIndex));
291 }
292
293 /*********************************************************/
294 /* EnvIsDefglobalDeletable: Returns TRUE if a particular */
295 /* defglobal can be deleted, otherwise returns FALSE. */
296 /*********************************************************/
EnvIsDefglobalDeletable(void * theEnv,void * ptr)297 globle intBool EnvIsDefglobalDeletable(
298 void *theEnv,
299 void *ptr)
300 {
301 if (! ConstructsDeletable(theEnv))
302 { return FALSE; }
303
304 if (((struct defglobal *) ptr)->busyCount) return(FALSE);
305
306 return(TRUE);
307 }
308
309 /************************************************************/
310 /* ReturnDefglobal: Returns the data structures associated */
311 /* with a defglobal construct to the pool of free memory. */
312 /************************************************************/
ReturnDefglobal(void * theEnv,void * vTheDefglobal)313 static void ReturnDefglobal(
314 void *theEnv,
315 void *vTheDefglobal)
316 {
317 #if (! BLOAD_ONLY) && (! RUN_TIME)
318 struct defglobal *theDefglobal = (struct defglobal *) vTheDefglobal;
319
320 if (theDefglobal == NULL) return;
321
322 /*====================================*/
323 /* Return the global's current value. */
324 /*====================================*/
325
326 ValueDeinstall(theEnv,&theDefglobal->current);
327 if (theDefglobal->current.type == MULTIFIELD)
328 { ReturnMultifield(theEnv,(struct multifield *) theDefglobal->current.value); }
329
330 /*================================================*/
331 /* Return the expression representing the initial */
332 /* value of the defglobal when it was defined. */
333 /*================================================*/
334
335 RemoveHashedExpression(theEnv,theDefglobal->initial);
336
337 /*===============================*/
338 /* Release items stored in the */
339 /* defglobal's construct header. */
340 /*===============================*/
341
342 DeinstallConstructHeader(theEnv,&theDefglobal->header);
343
344 /*======================================*/
345 /* Return the defglobal data structure. */
346 /*======================================*/
347
348 rtn_struct(theEnv,defglobal,theDefglobal);
349
350 /*===========================================*/
351 /* Set the variable indicating that a change */
352 /* has been made to a global variable. */
353 /*===========================================*/
354
355 DefglobalData(theEnv)->ChangeToGlobals = TRUE;
356 #endif
357 }
358
359 /************************************************************/
360 /* DestroyDefglobal: Returns the data structures associated */
361 /* with a defglobal construct to the pool of free memory. */
362 /************************************************************/
363 #if (! BLOAD_ONLY)
DestroyDefglobal(void * theEnv,void * vTheDefglobal)364 static void DestroyDefglobal(
365 void *theEnv,
366 void *vTheDefglobal)
367 {
368 struct defglobal *theDefglobal = (struct defglobal *) vTheDefglobal;
369
370 if (theDefglobal == NULL) return;
371
372 /*====================================*/
373 /* Return the global's current value. */
374 /*====================================*/
375
376 if (theDefglobal->current.type == MULTIFIELD)
377 { ReturnMultifield(theEnv,(struct multifield *) theDefglobal->current.value); }
378
379 #if (! RUN_TIME)
380
381 /*===============================*/
382 /* Release items stored in the */
383 /* defglobal's construct header. */
384 /*===============================*/
385
386 DeinstallConstructHeader(theEnv,&theDefglobal->header);
387
388 /*======================================*/
389 /* Return the defglobal data structure. */
390 /*======================================*/
391
392 rtn_struct(theEnv,defglobal,theDefglobal);
393 #endif
394 }
395 #endif
396
397 /************************************************/
398 /* QSetDefglobalValue: Lowest level routine for */
399 /* setting a defglobal's value. */
400 /************************************************/
QSetDefglobalValue(void * theEnv,struct defglobal * theGlobal,DATA_OBJECT_PTR vPtr,int resetVar)401 globle void QSetDefglobalValue(
402 void *theEnv,
403 struct defglobal *theGlobal,
404 DATA_OBJECT_PTR vPtr,
405 int resetVar)
406 {
407 /*====================================================*/
408 /* If the new value passed for the defglobal is NULL, */
409 /* then reset the defglobal to the initial value it */
410 /* had when it was defined. */
411 /*====================================================*/
412
413 if (resetVar)
414 {
415 EvaluateExpression(theEnv,theGlobal->initial,vPtr);
416 if (EvaluationData(theEnv)->EvaluationError)
417 {
418 vPtr->type = SYMBOL;
419 vPtr->value = EnvFalseSymbol(theEnv);
420 }
421 }
422
423 /*==========================================*/
424 /* If globals are being watch, then display */
425 /* the change to the global variable. */
426 /*==========================================*/
427
428 #if DEBUGGING_FUNCTIONS
429 if (theGlobal->watch)
430 {
431 EnvPrintRouter(theEnv,WTRACE,":== ?*");
432 EnvPrintRouter(theEnv,WTRACE,ValueToString(theGlobal->header.name));
433 EnvPrintRouter(theEnv,WTRACE,"* ==> ");
434 PrintDataObject(theEnv,WTRACE,vPtr);
435 EnvPrintRouter(theEnv,WTRACE," <== ");
436 PrintDataObject(theEnv,WTRACE,&theGlobal->current);
437 EnvPrintRouter(theEnv,WTRACE,"\n");
438 }
439 #endif
440
441 /*==============================================*/
442 /* Remove the old value of the global variable. */
443 /*==============================================*/
444
445 ValueDeinstall(theEnv,&theGlobal->current);
446 if (theGlobal->current.type == MULTIFIELD)
447 { ReturnMultifield(theEnv,(struct multifield *) theGlobal->current.value); }
448
449 /*===========================================*/
450 /* Set the new value of the global variable. */
451 /*===========================================*/
452
453 theGlobal->current.type = vPtr->type;
454 if (vPtr->type != MULTIFIELD) theGlobal->current.value = vPtr->value;
455 else DuplicateMultifield(theEnv,&theGlobal->current,vPtr);
456 ValueInstall(theEnv,&theGlobal->current);
457
458 /*===========================================*/
459 /* Set the variable indicating that a change */
460 /* has been made to a global variable. */
461 /*===========================================*/
462
463 DefglobalData(theEnv)->ChangeToGlobals = TRUE;
464
465 if ((UtilityData(theEnv)->CurrentGarbageFrame->topLevel) && (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&
466 (EvaluationData(theEnv)->CurrentExpression == NULL) && (UtilityData(theEnv)->GarbageCollectionLocks == 0))
467 {
468 CleanCurrentGarbageFrame(theEnv,NULL);
469 CallPeriodicTasks(theEnv);
470 }
471 }
472
473 /**************************************************************/
474 /* QFindDefglobal: Searches for a defglobal in the list of */
475 /* defglobals. Returns a pointer to the defglobal if found, */
476 /* otherwise NULL. */
477 /**************************************************************/
QFindDefglobal(void * theEnv,SYMBOL_HN * defglobalName)478 globle struct defglobal *QFindDefglobal(
479 void *theEnv,
480 SYMBOL_HN *defglobalName)
481 {
482 struct defglobal *theDefglobal;
483
484 for (theDefglobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,NULL);
485 theDefglobal != NULL;
486 theDefglobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,theDefglobal))
487 { if (defglobalName == theDefglobal->header.name) return (theDefglobal); }
488
489 return(NULL);
490 }
491
492 /*********************************************************************/
493 /* EnvGetDefglobalValueForm: Returns the pretty print representation */
494 /* of the current value of the specified defglobal. For example, */
495 /* if the current value of ?*x* is 5, the string "?*x* = 5" would */
496 /* be returned. */
497 /*********************************************************************/
EnvGetDefglobalValueForm(void * theEnv,char * buffer,size_t bufferLength,void * vTheGlobal)498 globle void EnvGetDefglobalValueForm(
499 void *theEnv,
500 char *buffer,
501 size_t bufferLength,
502 void *vTheGlobal)
503 {
504 struct defglobal *theGlobal = (struct defglobal *) vTheGlobal;
505
506 OpenStringDestination(theEnv,"GlobalValueForm",buffer,bufferLength);
507 EnvPrintRouter(theEnv,"GlobalValueForm","?*");
508 EnvPrintRouter(theEnv,"GlobalValueForm",ValueToString(theGlobal->header.name));
509 EnvPrintRouter(theEnv,"GlobalValueForm","* = ");
510 PrintDataObject(theEnv,"GlobalValueForm",&theGlobal->current);
511 CloseStringDestination(theEnv,"GlobalValueForm");
512 }
513
514 /************************************************************/
515 /* EnvGetGlobalsChanged: Returns the defglobal change flag. */
516 /************************************************************/
EnvGetGlobalsChanged(void * theEnv)517 globle int EnvGetGlobalsChanged(
518 void *theEnv)
519 {
520 return(DefglobalData(theEnv)->ChangeToGlobals);
521 }
522
523 /*********************************************************/
524 /* EnvSetGlobalsChanged: Sets the defglobal change flag. */
525 /*********************************************************/
EnvSetGlobalsChanged(void * theEnv,int value)526 globle void EnvSetGlobalsChanged(
527 void *theEnv,
528 int value)
529 {
530 DefglobalData(theEnv)->ChangeToGlobals = value;
531 }
532
533 /**********************************************************/
534 /* GetDefglobalValue2: Returns the value of the specified */
535 /* global variable in the supplied DATA_OBJECT. */
536 /**********************************************************/
GetDefglobalValue2(void * theEnv,void * theValue,DATA_OBJECT_PTR vPtr)537 static intBool GetDefglobalValue2(
538 void *theEnv,
539 void *theValue,
540 DATA_OBJECT_PTR vPtr)
541 {
542 struct defglobal *theGlobal;
543 int count;
544
545 /*===========================================*/
546 /* Search for the specified defglobal in the */
547 /* modules visible to the current module. */
548 /*===========================================*/
549
550 theGlobal = (struct defglobal *)
551 FindImportedConstruct(theEnv,"defglobal",NULL,ValueToString(theValue),
552 &count,TRUE,NULL);
553
554 /*=============================================*/
555 /* If it wasn't found, print an error message. */
556 /*=============================================*/
557
558 if (theGlobal == NULL)
559 {
560 PrintErrorID(theEnv,"GLOBLDEF",1,FALSE);
561 EnvPrintRouter(theEnv,WERROR,"Global variable ?*");
562 EnvPrintRouter(theEnv,WERROR,ValueToString(theValue));
563 EnvPrintRouter(theEnv,WERROR,"* is unbound.\n");
564 vPtr->type = SYMBOL;
565 vPtr->value = EnvFalseSymbol(theEnv);
566 SetEvaluationError(theEnv,TRUE);
567 return(FALSE);
568 }
569
570 /*========================================================*/
571 /* The current implementation of the defmodules shouldn't */
572 /* allow a construct to be defined which would cause an */
573 /* ambiguous reference, but we'll check for it anyway. */
574 /*========================================================*/
575
576 if (count > 1)
577 {
578 AmbiguousReferenceErrorMessage(theEnv,"defglobal",ValueToString(theValue));
579 vPtr->type = SYMBOL;
580 vPtr->value = EnvFalseSymbol(theEnv);
581 SetEvaluationError(theEnv,TRUE);
582 return(FALSE);
583 }
584
585 /*=================================*/
586 /* Get the value of the defglobal. */
587 /*=================================*/
588
589 QGetDefglobalValue(theEnv,theGlobal,vPtr);
590
591 return(TRUE);
592 }
593
594 /***************************************************************/
595 /* QGetDefglobalValue: Returns the value of a global variable. */
596 /***************************************************************/
QGetDefglobalValue(void * theEnv,void * vTheGlobal,DATA_OBJECT_PTR vPtr)597 globle int QGetDefglobalValue(
598 void *theEnv,
599 void *vTheGlobal,
600 DATA_OBJECT_PTR vPtr)
601 {
602 struct defglobal *theGlobal = (struct defglobal *) vTheGlobal;
603
604 /*===============================================*/
605 /* Transfer values which can be copied directly. */
606 /*===============================================*/
607
608 vPtr->type = theGlobal->current.type;
609 vPtr->value = theGlobal->current.value;
610 vPtr->begin = theGlobal->current.begin;
611 vPtr->end = theGlobal->current.end;
612
613 /*===========================================================*/
614 /* If the global contains a multifield value, return a copy */
615 /* of the value so that routines which use this value are */
616 /* not affected if the value of the global is later changed. */
617 /*===========================================================*/
618
619 if (vPtr->type == MULTIFIELD)
620 {
621 vPtr->value = EnvCreateMultifield(theEnv,(unsigned long) (vPtr->end + 1));
622 GenCopyMemory(struct field,vPtr->end + 1,
623 &((struct multifield *) vPtr->value)->theFields[0],
624 &((struct multifield *) theGlobal->current.value)->theFields[theGlobal->current.begin]);
625 }
626
627 return(TRUE);
628 }
629
630 /************************************************************/
631 /* EnvGetDefglobalValue: Returns the value of the specified */
632 /* global variable in the supplied DATA_OBJECT. */
633 /************************************************************/
EnvGetDefglobalValue(void * theEnv,const char * variableName,DATA_OBJECT_PTR vPtr)634 globle intBool EnvGetDefglobalValue(
635 void *theEnv,
636 const char *variableName,
637 DATA_OBJECT_PTR vPtr)
638 {
639 struct defglobal *theDefglobal;
640
641 if ((theDefglobal = (struct defglobal *) EnvFindDefglobal(theEnv,variableName)) == NULL)
642 { return(FALSE); }
643
644 QGetDefglobalValue(theEnv,theDefglobal,vPtr);
645
646 return(TRUE);
647 }
648
649 /****************************************************************/
650 /* EnvSetDefglobalValue: Sets the value of the specified global */
651 /* variable to the value stored in the supplied DATA_OBJECT. */
652 /****************************************************************/
EnvSetDefglobalValue(void * theEnv,const char * variableName,DATA_OBJECT_PTR vPtr)653 globle intBool EnvSetDefglobalValue(
654 void *theEnv,
655 const char *variableName,
656 DATA_OBJECT_PTR vPtr)
657 {
658 struct defglobal *theGlobal;
659
660 if ((theGlobal = QFindDefglobal(theEnv,(SYMBOL_HN *) EnvAddSymbol(theEnv,variableName))) == NULL)
661 { return(FALSE); }
662
663 QSetDefglobalValue(theEnv,theGlobal,vPtr,FALSE);
664
665 return(TRUE);
666 }
667
668 /**********************************************************/
669 /* DecrementDefglobalBusyCount: Decrements the busy count */
670 /* of a defglobal data structure. */
671 /**********************************************************/
DecrementDefglobalBusyCount(void * theEnv,void * vTheGlobal)672 static void DecrementDefglobalBusyCount(
673 void *theEnv,
674 void *vTheGlobal)
675 {
676 struct defglobal *theGlobal = (struct defglobal *) vTheGlobal;
677
678 if (! ConstructData(theEnv)->ClearInProgress) theGlobal->busyCount--;
679 }
680
681 /**********************************************************/
682 /* IncrementDefglobalBusyCount: Increments the busy count */
683 /* of a defglobal data structure. */
684 /**********************************************************/
IncrementDefglobalBusyCount(void * theEnv,void * vTheGlobal)685 static void IncrementDefglobalBusyCount(
686 void *theEnv,
687 void *vTheGlobal)
688 {
689 struct defglobal *theGlobal = (struct defglobal *) vTheGlobal;
690 #if MAC_XCD
691 #pragma unused(theEnv)
692 #endif
693
694 theGlobal->busyCount++;
695 }
696
697 /***********************************************************************/
698 /* UpdateDefglobalScope: Updates the scope flag of all the defglobals. */
699 /***********************************************************************/
UpdateDefglobalScope(void * theEnv)700 globle void UpdateDefglobalScope(
701 void *theEnv)
702 {
703 struct defglobal *theDefglobal;
704 int moduleCount;
705 struct defmodule *theModule;
706 struct defmoduleItemHeader *theItem;
707
708 /*============================*/
709 /* Loop through every module. */
710 /*============================*/
711
712 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
713 theModule != NULL;
714 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
715 {
716 /*============================================================*/
717 /* Loop through every defglobal in the module being examined. */
718 /*============================================================*/
719
720 theItem = (struct defmoduleItemHeader *)
721 GetModuleItem(theEnv,theModule,DefglobalData(theEnv)->DefglobalModuleIndex);
722
723 for (theDefglobal = (struct defglobal *) theItem->firstItem;
724 theDefglobal != NULL ;
725 theDefglobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,theDefglobal))
726 {
727 /*====================================================*/
728 /* If the defglobal is visible to the current module, */
729 /* then mark it as being in scope, otherwise mark it */
730 /* as being out of scope. */
731 /*====================================================*/
732
733 if (FindImportedConstruct(theEnv,"defglobal",theModule,
734 ValueToString(theDefglobal->header.name),
735 &moduleCount,TRUE,NULL) != NULL)
736 { theDefglobal->inScope = TRUE; }
737 else
738 { theDefglobal->inScope = FALSE; }
739 }
740 }
741 }
742
743 /*******************************************************/
744 /* GetNextDefglobalInScope: Returns the next defglobal */
745 /* that is scope of the current module. Works in a */
746 /* similar fashion to GetNextDefglobal, but skips */
747 /* defglobals that are out of scope. */
748 /*******************************************************/
GetNextDefglobalInScope(void * theEnv,void * vTheGlobal)749 globle void *GetNextDefglobalInScope(
750 void *theEnv,
751 void *vTheGlobal)
752 {
753 struct defglobal *theGlobal = (struct defglobal *) vTheGlobal;
754 struct defmoduleItemHeader *theItem;
755
756 /*=======================================*/
757 /* If we're beginning the search for the */
758 /* first defglobal in scope, then ... */
759 /*=======================================*/
760
761 if (theGlobal == NULL)
762 {
763 /*==============================================*/
764 /* If the current module has been changed since */
765 /* the last time the scopes were computed, then */
766 /* recompute the scopes. */
767 /*==============================================*/
768
769 if (DefglobalData(theEnv)->LastModuleIndex != DefmoduleData(theEnv)->ModuleChangeIndex)
770 {
771 UpdateDefglobalScope(theEnv);
772 DefglobalData(theEnv)->LastModuleIndex = DefmoduleData(theEnv)->ModuleChangeIndex;
773 }
774
775 /*==========================================*/
776 /* Get the first module and first defglobal */
777 /* to start the search with. */
778 /*==========================================*/
779
780 DefglobalData(theEnv)->TheDefmodule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
781 theItem = (struct defmoduleItemHeader *)
782 GetModuleItem(theEnv,DefglobalData(theEnv)->TheDefmodule,DefglobalData(theEnv)->DefglobalModuleIndex);
783 theGlobal = (struct defglobal *) theItem->firstItem;
784 }
785
786 /*==================================================*/
787 /* Otherwise, see if the last defglobal returned by */
788 /* this function has a defglobal following it. */
789 /*==================================================*/
790
791 else
792 { theGlobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,theGlobal); }
793
794 /*======================================*/
795 /* Continue looping through the modules */
796 /* until a defglobal in scope is found. */
797 /*======================================*/
798
799 while (DefglobalData(theEnv)->TheDefmodule != NULL)
800 {
801 /*=====================================================*/
802 /* Loop through the defglobals in the module currently */
803 /* being examined to see if one is in scope. */
804 /*=====================================================*/
805
806 for (;
807 theGlobal != NULL;
808 theGlobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,theGlobal))
809 { if (theGlobal->inScope) return((void *) theGlobal); }
810
811 /*================================================*/
812 /* If a global in scope couldn't be found in this */
813 /* module, then move on to the next module. */
814 /*================================================*/
815
816 DefglobalData(theEnv)->TheDefmodule = (struct defmodule *) EnvGetNextDefmodule(theEnv,DefglobalData(theEnv)->TheDefmodule);
817 theItem = (struct defmoduleItemHeader *)
818 GetModuleItem(theEnv,DefglobalData(theEnv)->TheDefmodule,DefglobalData(theEnv)->DefglobalModuleIndex);
819 theGlobal = (struct defglobal *) theItem->firstItem;
820 }
821
822 /*====================================*/
823 /* All the globals in scope have been */
824 /* traversed and there are none left. */
825 /*====================================*/
826
827 return(NULL);
828 }
829
830 /*##################################*/
831 /* Additional Environment Functions */
832 /*##################################*/
833
EnvDefglobalModule(void * theEnv,void * theDefglobal)834 globle const char *EnvDefglobalModule(
835 void *theEnv,
836 void *theDefglobal)
837 {
838 return GetConstructModuleName((struct constructHeader *) theDefglobal);
839 }
840
EnvGetDefglobalName(void * theEnv,void * theDefglobal)841 globle const char *EnvGetDefglobalName(
842 void *theEnv,
843 void *theDefglobal)
844 {
845 return GetConstructNameString((struct constructHeader *) theDefglobal);
846 }
847
EnvGetDefglobalPPForm(void * theEnv,void * theDefglobal)848 globle const char *EnvGetDefglobalPPForm(
849 void *theEnv,
850 void *theDefglobal)
851 {
852 return GetConstructPPForm(theEnv,(struct constructHeader *) theDefglobal);
853 }
854
855 /*#####################################*/
856 /* ALLOW_ENVIRONMENT_GLOBALS Functions */
857 /*#####################################*/
858
859 #if ALLOW_ENVIRONMENT_GLOBALS
860
DefglobalModule(void * theDefglobal)861 globle const char *DefglobalModule(
862 void *theDefglobal)
863 {
864 return EnvDefglobalModule(GetCurrentEnvironment(),theDefglobal);
865 }
866
FindDefglobal(const char * defglobalName)867 globle void *FindDefglobal(
868 const char *defglobalName)
869 {
870 return EnvFindDefglobal(GetCurrentEnvironment(),defglobalName);
871 }
872
GetDefglobalName(void * theDefglobal)873 globle const char *GetDefglobalName(
874 void *theDefglobal)
875 {
876 return EnvGetDefglobalName(GetCurrentEnvironment(),theDefglobal);
877 }
878
GetDefglobalPPForm(void * theDefglobal)879 globle const char *GetDefglobalPPForm(
880 void *theDefglobal)
881 {
882 return EnvGetDefglobalPPForm(GetCurrentEnvironment(),theDefglobal);
883 }
884
GetDefglobalValue(const char * variableName,DATA_OBJECT_PTR vPtr)885 globle intBool GetDefglobalValue(
886 const char *variableName,
887 DATA_OBJECT_PTR vPtr)
888 {
889 return EnvGetDefglobalValue(GetCurrentEnvironment(),variableName,vPtr);
890 }
891
GetDefglobalValueForm(char * buffer,unsigned bufferLength,void * vTheGlobal)892 globle void GetDefglobalValueForm(
893 char *buffer,
894 unsigned bufferLength,
895 void *vTheGlobal)
896 {
897 EnvGetDefglobalValueForm(GetCurrentEnvironment(),buffer,bufferLength,vTheGlobal);
898 }
899
GetGlobalsChanged()900 globle int GetGlobalsChanged()
901 {
902 return EnvGetGlobalsChanged(GetCurrentEnvironment());
903 }
904
GetNextDefglobal(void * defglobalPtr)905 globle void *GetNextDefglobal(
906 void *defglobalPtr)
907 {
908 return EnvGetNextDefglobal(GetCurrentEnvironment(),defglobalPtr);
909 }
910
IsDefglobalDeletable(void * ptr)911 globle intBool IsDefglobalDeletable(
912 void *ptr)
913 {
914 return EnvIsDefglobalDeletable(GetCurrentEnvironment(),ptr);
915 }
916
SetDefglobalValue(const char * variableName,DATA_OBJECT_PTR vPtr)917 globle intBool SetDefglobalValue(
918 const char *variableName,
919 DATA_OBJECT_PTR vPtr)
920 {
921 return EnvSetDefglobalValue(GetCurrentEnvironment(),variableName,vPtr);
922 }
923
SetGlobalsChanged(int value)924 globle void SetGlobalsChanged(
925 int value)
926 {
927 EnvSetGlobalsChanged(GetCurrentEnvironment(),value);
928 }
929
930 #endif /* ALLOW_ENVIRONMENT_GLOBALS */
931
932 #endif /* DEFGLOBAL_CONSTRUCT */
933
934
935