1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 08/16/14 */
5 /* */
6 /* DEFGLOBAL BSAVE/BLOAD MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Implements the binary save/load feature for the */
11 /* 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.30: Changed integer type/precision. */
22 /* */
23 /* Moved WatchGlobals global to defglobalData. */
24 /* */
25 /*************************************************************/
26
27 #define _GLOBLBIN_SOURCE_
28
29 #include "setup.h"
30
31 #if DEFGLOBAL_CONSTRUCT && (BLOAD || BLOAD_AND_BSAVE || BLOAD_ONLY) && (! RUN_TIME)
32
33 #include <stdio.h>
34 #define _STDIO_INCLUDED_
35
36 #include "memalloc.h"
37 #include "multifld.h"
38 #include "globldef.h"
39 #include "bload.h"
40 #include "bsave.h"
41 #include "moduldef.h"
42 #include "globlbsc.h"
43 #include "envrnmnt.h"
44
45 #include "globlbin.h"
46
47 /***************************************/
48 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
49 /***************************************/
50
51 #if BLOAD_AND_BSAVE
52 static void BsaveFind(void *);
53 static void BsaveStorage(void *,FILE *);
54 static void BsaveBinaryItem(void *,FILE *);
55 #endif
56 static void BloadStorageDefglobals(void *);
57 static void BloadBinaryItem(void *);
58 static void UpdateDefglobalModule(void *,void *,long);
59 static void UpdateDefglobal(void *,void *,long);
60 static void ClearBload(void *);
61 static void DeallocateDefglobalBloadData(void *);
62
63 /*********************************************/
64 /* DefglobalBinarySetup: Installs the binary */
65 /* save/load feature for the defglobals. */
66 /*********************************************/
DefglobalBinarySetup(void * theEnv)67 globle void DefglobalBinarySetup(
68 void *theEnv)
69 {
70 AllocateEnvironmentData(theEnv,GLOBLBIN_DATA,sizeof(struct defglobalBinaryData),DeallocateDefglobalBloadData);
71 #if (BLOAD_AND_BSAVE || BLOAD)
72 AddAfterBloadFunction(theEnv,"defglobal",ResetDefglobals,50);
73 #endif
74
75 #if BLOAD_AND_BSAVE
76 AddBinaryItem(theEnv,"defglobal",0,BsaveFind,NULL,
77 BsaveStorage,BsaveBinaryItem,
78 BloadStorageDefglobals,BloadBinaryItem,
79 ClearBload);
80 #endif
81
82 #if (BLOAD || BLOAD_ONLY)
83 AddBinaryItem(theEnv,"defglobal",0,NULL,NULL,NULL,NULL,
84 BloadStorageDefglobals,BloadBinaryItem,
85 ClearBload);
86 #endif
87 }
88
89 /*********************************************************/
90 /* DeallocateDefglobalBloadData: Deallocates environment */
91 /* data for the defglobal bsave functionality. */
92 /*********************************************************/
DeallocateDefglobalBloadData(void * theEnv)93 static void DeallocateDefglobalBloadData(
94 void *theEnv)
95 {
96 #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME)
97 size_t space;
98 long i;
99
100 for (i = 0; i < DefglobalBinaryData(theEnv)->NumberOfDefglobals; i++)
101 {
102 if (DefglobalBinaryData(theEnv)->DefglobalArray[i].current.type == MULTIFIELD)
103 { ReturnMultifield(theEnv,(struct multifield *) DefglobalBinaryData(theEnv)->DefglobalArray[i].current.value); }
104 }
105
106 space = DefglobalBinaryData(theEnv)->NumberOfDefglobals * sizeof(struct defglobal);
107 if (space != 0)
108 { genfree(theEnv,(void *) DefglobalBinaryData(theEnv)->DefglobalArray,space); }
109
110 space = DefglobalBinaryData(theEnv)->NumberOfDefglobalModules * sizeof(struct defglobalModule);
111 if (space != 0)
112 { genfree(theEnv,(void *) DefglobalBinaryData(theEnv)->ModuleArray,space); }
113 #endif
114 }
115
116 #if BLOAD_AND_BSAVE
117
118 /****************************************************/
119 /* BsaveFind: Counts the number of data structures */
120 /* which must be saved in the binary image for */
121 /* the defglobals in the current environment. */
122 /****************************************************/
BsaveFind(void * theEnv)123 static void BsaveFind(
124 void *theEnv)
125 {
126 struct defglobal *defglobalPtr;
127 struct defmodule *theModule;
128
129 /*=======================================================*/
130 /* If a binary image is already loaded, then temporarily */
131 /* save the count values since these will be overwritten */
132 /* in the process of saving the binary image. */
133 /*=======================================================*/
134
135 SaveBloadCount(theEnv,DefglobalBinaryData(theEnv)->NumberOfDefglobalModules);
136 SaveBloadCount(theEnv,DefglobalBinaryData(theEnv)->NumberOfDefglobals);
137
138 /*============================================*/
139 /* Set the count of defglobals and defglobals */
140 /* module data structures to zero. */
141 /*============================================*/
142
143 DefglobalBinaryData(theEnv)->NumberOfDefglobals = 0;
144 DefglobalBinaryData(theEnv)->NumberOfDefglobalModules = 0;
145
146 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
147 theModule != NULL;
148 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
149 {
150 /*================================================*/
151 /* Set the current module to the module being */
152 /* examined and increment the number of defglobal */
153 /* modules encountered. */
154 /*================================================*/
155
156 EnvSetCurrentModule(theEnv,(void *) theModule);
157 DefglobalBinaryData(theEnv)->NumberOfDefglobalModules++;
158
159 /*====================================================*/
160 /* Loop through each defglobal in the current module. */
161 /*====================================================*/
162
163 for (defglobalPtr = (struct defglobal *) EnvGetNextDefglobal(theEnv,NULL);
164 defglobalPtr != NULL;
165 defglobalPtr = (struct defglobal *) EnvGetNextDefglobal(theEnv,defglobalPtr))
166 {
167 /*======================================================*/
168 /* Initialize the construct header for the binary save. */
169 /*======================================================*/
170
171 MarkConstructHeaderNeededItems(&defglobalPtr->header,DefglobalBinaryData(theEnv)->NumberOfDefglobals++);
172 }
173 }
174 }
175
176 /*****************************************************/
177 /* BsaveStorage: Writes out storage requirements for */
178 /* all defglobal structures to the binary file */
179 /*****************************************************/
BsaveStorage(void * theEnv,FILE * fp)180 static void BsaveStorage(
181 void *theEnv,
182 FILE *fp)
183 {
184 size_t space;
185
186 /*===========================================================*/
187 /* Only two data structures are saved as part of a defglobal */
188 /* binary image: the defglobal data structure and the */
189 /* defglobalModule data structure. */
190 /*===========================================================*/
191
192 space = sizeof(long) * 2;
193 GenWrite(&space,sizeof(size_t),fp);
194 GenWrite(&DefglobalBinaryData(theEnv)->NumberOfDefglobals,sizeof(long int),fp);
195 GenWrite(&DefglobalBinaryData(theEnv)->NumberOfDefglobalModules,sizeof(long int),fp);
196 }
197
198 /*********************************************/
199 /* BsaveBinaryItem: Writes out all defglobal */
200 /* structures to the binary file */
201 /*********************************************/
BsaveBinaryItem(void * theEnv,FILE * fp)202 static void BsaveBinaryItem(
203 void *theEnv,
204 FILE *fp)
205 {
206 size_t space;
207 struct defglobal *theDefglobal;
208 struct bsaveDefglobal newDefglobal;
209 struct defmodule *theModule;
210 struct bsaveDefglobalModule tempDefglobalModule;
211 struct defglobalModule *theModuleItem;
212
213 /*==========================================================*/
214 /* Write out the amount of space taken up by the defglobal */
215 /* and defglobalModule data structures in the binary image. */
216 /*==========================================================*/
217
218 space = DefglobalBinaryData(theEnv)->NumberOfDefglobals * sizeof(struct bsaveDefglobal) +
219 (DefglobalBinaryData(theEnv)->NumberOfDefglobalModules * sizeof(struct bsaveDefglobalModule));
220 GenWrite(&space,sizeof(size_t),fp);
221
222 /*=================================================*/
223 /* Write out each defglobal module data structure. */
224 /*=================================================*/
225
226 DefglobalBinaryData(theEnv)->NumberOfDefglobals = 0;
227 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
228 theModule != NULL;
229 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
230 {
231 EnvSetCurrentModule(theEnv,(void *) theModule);
232
233 theModuleItem = (struct defglobalModule *)
234 GetModuleItem(theEnv,NULL,FindModuleItem(theEnv,"defglobal")->moduleIndex);
235 AssignBsaveDefmdlItemHdrVals(&tempDefglobalModule.header,
236 &theModuleItem->header);
237 GenWrite(&tempDefglobalModule,sizeof(struct bsaveDefglobalModule),fp);
238 }
239
240 /*===========================*/
241 /* Write out each defglobal. */
242 /*===========================*/
243
244 DefglobalBinaryData(theEnv)->NumberOfDefglobals = 0;
245 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
246 theModule != NULL;
247 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
248 {
249 EnvSetCurrentModule(theEnv,(void *) theModule);
250
251 for (theDefglobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,NULL);
252 theDefglobal != NULL;
253 theDefglobal = (struct defglobal *) EnvGetNextDefglobal(theEnv,theDefglobal))
254 {
255 AssignBsaveConstructHeaderVals(&newDefglobal.header,
256 &theDefglobal->header);
257 newDefglobal.initial = HashedExpressionIndex(theEnv,theDefglobal->initial);
258
259 GenWrite(&newDefglobal,sizeof(struct bsaveDefglobal),fp);
260 }
261 }
262
263 /*=============================================================*/
264 /* If a binary image was already loaded when the bsave command */
265 /* was issued, then restore the counts indicating the number */
266 /* of defglobals and defglobal modules in the binary image */
267 /* (these were overwritten by the binary save). */
268 /*=============================================================*/
269
270 RestoreBloadCount(theEnv,&DefglobalBinaryData(theEnv)->NumberOfDefglobalModules);
271 RestoreBloadCount(theEnv,&DefglobalBinaryData(theEnv)->NumberOfDefglobals);
272 }
273
274 #endif /* BLOAD_AND_BSAVE */
275
276 /***********************************************/
277 /* BloadStorageDefglobals: Allocates space for */
278 /* the defglobals used by this binary image. */
279 /***********************************************/
BloadStorageDefglobals(void * theEnv)280 static void BloadStorageDefglobals(
281 void *theEnv)
282 {
283 size_t space;
284
285 /*=======================================================*/
286 /* Determine the number of defglobal and defglobalModule */
287 /* data structures to be read. */
288 /*=======================================================*/
289
290 GenReadBinary(theEnv,&space,sizeof(size_t));
291 GenReadBinary(theEnv,&DefglobalBinaryData(theEnv)->NumberOfDefglobals,sizeof(long int));
292 GenReadBinary(theEnv,&DefglobalBinaryData(theEnv)->NumberOfDefglobalModules,sizeof(long int));
293
294 /*===================================*/
295 /* Allocate the space needed for the */
296 /* defglobalModule data structures. */
297 /*===================================*/
298
299 if (DefglobalBinaryData(theEnv)->NumberOfDefglobalModules == 0)
300 {
301 DefglobalBinaryData(theEnv)->DefglobalArray = NULL;
302 DefglobalBinaryData(theEnv)->ModuleArray = NULL;
303 }
304
305 space = DefglobalBinaryData(theEnv)->NumberOfDefglobalModules * sizeof(struct defglobalModule);
306 DefglobalBinaryData(theEnv)->ModuleArray = (struct defglobalModule *) genalloc(theEnv,space);
307
308 /*===================================*/
309 /* Allocate the space needed for the */
310 /* defglobal data structures. */
311 /*===================================*/
312
313 if (DefglobalBinaryData(theEnv)->NumberOfDefglobals == 0)
314 {
315 DefglobalBinaryData(theEnv)->DefglobalArray = NULL;
316 return;
317 }
318
319 space = (DefglobalBinaryData(theEnv)->NumberOfDefglobals * sizeof(struct defglobal));
320 DefglobalBinaryData(theEnv)->DefglobalArray = (struct defglobal *) genalloc(theEnv,space);
321 }
322
323 /******************************************************/
324 /* BloadBinaryItem: Loads and refreshes the defglobal */
325 /* constructs used by this binary image. */
326 /******************************************************/
BloadBinaryItem(void * theEnv)327 static void BloadBinaryItem(
328 void *theEnv)
329 {
330 size_t space;
331
332 /*======================================================*/
333 /* Read in the amount of space used by the binary image */
334 /* (this is used to skip the construct in the event it */
335 /* is not available in the version being run). */
336 /*======================================================*/
337
338 GenReadBinary(theEnv,&space,sizeof(size_t));
339
340 /*=============================================*/
341 /* Read in the defglobalModule data structures */
342 /* and refresh the pointers. */
343 /*=============================================*/
344
345 BloadandRefresh(theEnv,DefglobalBinaryData(theEnv)->NumberOfDefglobalModules,
346 sizeof(struct bsaveDefglobalModule),
347 UpdateDefglobalModule);
348
349 /*=======================================*/
350 /* Read in the defglobal data structures */
351 /* and refresh the pointers. */
352 /*=======================================*/
353
354 BloadandRefresh(theEnv,DefglobalBinaryData(theEnv)->NumberOfDefglobals,
355 sizeof(struct bsaveDefglobal),
356 UpdateDefglobal);
357 }
358
359 /************************************************/
360 /* UpdateDefglobalModule: Bload refresh routine */
361 /* for defglobal module data structures. */
362 /************************************************/
UpdateDefglobalModule(void * theEnv,void * buf,long obji)363 static void UpdateDefglobalModule(
364 void *theEnv,
365 void *buf,
366 long obji)
367 {
368 struct bsaveDefglobalModule *bdmPtr;
369
370 bdmPtr = (struct bsaveDefglobalModule *) buf;
371
372 UpdateDefmoduleItemHeader(theEnv,&bdmPtr->header,&DefglobalBinaryData(theEnv)->ModuleArray[obji].header,
373 (int) sizeof(struct defglobal),
374 (void *) DefglobalBinaryData(theEnv)->DefglobalArray);
375 }
376
377 /******************************************/
378 /* UpdateDefglobal: Bload refresh routine */
379 /* for defglobal data structures. */
380 /******************************************/
UpdateDefglobal(void * theEnv,void * buf,long obji)381 static void UpdateDefglobal(
382 void *theEnv,
383 void *buf,
384 long obji)
385 {
386 struct bsaveDefglobal *bdp;
387
388 bdp = (struct bsaveDefglobal *) buf;
389 UpdateConstructHeader(theEnv,&bdp->header,&DefglobalBinaryData(theEnv)->DefglobalArray[obji].header,
390 (int) sizeof(struct defglobalModule),(void *) DefglobalBinaryData(theEnv)->ModuleArray,
391 (int) sizeof(struct defglobal),(void *) DefglobalBinaryData(theEnv)->DefglobalArray);
392
393 #if DEBUGGING_FUNCTIONS
394 DefglobalBinaryData(theEnv)->DefglobalArray[obji].watch = DefglobalData(theEnv)->WatchGlobals;
395 #endif
396 DefglobalBinaryData(theEnv)->DefglobalArray[obji].initial = HashedExpressionPointer(bdp->initial);
397 DefglobalBinaryData(theEnv)->DefglobalArray[obji].current.type = RVOID;
398
399 }
400
401 /***************************************/
402 /* ClearBload: Defglobal clear routine */
403 /* when a binary load is in effect. */
404 /***************************************/
ClearBload(void * theEnv)405 static void ClearBload(
406 void *theEnv)
407 {
408 long i;
409 size_t space;
410
411 /*=======================================================*/
412 /* Decrement in use counters for atomic values contained */
413 /* in the construct headers. Also decrement data */
414 /* structures used to store the defglobal's value. */
415 /*=======================================================*/
416
417 for (i = 0; i < DefglobalBinaryData(theEnv)->NumberOfDefglobals; i++)
418 {
419 UnmarkConstructHeader(theEnv,&DefglobalBinaryData(theEnv)->DefglobalArray[i].header);
420
421 ValueDeinstall(theEnv,&(DefglobalBinaryData(theEnv)->DefglobalArray[i].current));
422 if (DefglobalBinaryData(theEnv)->DefglobalArray[i].current.type == MULTIFIELD)
423 { ReturnMultifield(theEnv,(struct multifield *) DefglobalBinaryData(theEnv)->DefglobalArray[i].current.value); }
424 }
425
426 /*==============================================================*/
427 /* Deallocate the space used for the defglobal data structures. */
428 /*==============================================================*/
429
430 space = DefglobalBinaryData(theEnv)->NumberOfDefglobals * sizeof(struct defglobal);
431 if (space != 0) genfree(theEnv,(void *) DefglobalBinaryData(theEnv)->DefglobalArray,space);
432 DefglobalBinaryData(theEnv)->NumberOfDefglobals = 0;
433
434 /*=====================================================================*/
435 /* Deallocate the space used for the defglobal module data structures. */
436 /*=====================================================================*/
437
438 space = DefglobalBinaryData(theEnv)->NumberOfDefglobalModules * sizeof(struct defglobalModule);
439 if (space != 0) genfree(theEnv,(void *) DefglobalBinaryData(theEnv)->ModuleArray,space);
440 DefglobalBinaryData(theEnv)->NumberOfDefglobalModules = 0;
441 }
442
443 /********************************************************/
444 /* BloadDefglobalModuleReference: Returns the defglobal */
445 /* module pointer for using with the bload function. */
446 /********************************************************/
BloadDefglobalModuleReference(void * theEnv,int theIndex)447 globle void *BloadDefglobalModuleReference(
448 void *theEnv,
449 int theIndex)
450 {
451 return ((void *) &DefglobalBinaryData(theEnv)->ModuleArray[theIndex]);
452 }
453
454 #endif /* DEFGLOBAL_CONSTRUCT && (BLOAD || BLOAD_AND_BSAVE || BLOAD_ONLY) && (! RUN_TIME) */
455
456
457
458