1    /*******************************************************/
2    /*      "C" Language Integrated Production System      */
3    /*                                                     */
4    /*             CLIPS Version 6.30  08/16/14            */
5    /*                                                     */
6    /*             DEFMODULE BSAVE/BLOAD MODULE            */
7    /*******************************************************/
8 
9 /*************************************************************/
10 /* Purpose: Implements the binary save/load feature for the  */
11 /*    defmodule 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 /*************************************************************/
24 
25 #define _MODULBIN_SOURCE_
26 
27 #include "setup.h"
28 
29 #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME)
30 
31 #include <stdio.h>
32 #define _STDIO_INCLUDED_
33 
34 #include "memalloc.h"
35 #include "constrct.h"
36 #include "moduldef.h"
37 #include "bload.h"
38 #include "bsave.h"
39 #include "envrnmnt.h"
40 
41 #include "modulbin.h"
42 
43 /***************************************/
44 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
45 /***************************************/
46 
47 #if BLOAD_AND_BSAVE
48    static void                    BsaveFind(void *);
49    static void                    BsaveStorage(void *,FILE *);
50    static void                    BsaveBinaryItem(void *,FILE *);
51 #endif
52    static void                    BloadStorage(void *);
53    static void                    BloadBinaryItem(void *);
54    static void                    UpdateDefmodule(void *,void *,long);
55    static void                    UpdatePortItem(void *,void *,long);
56    static void                    ClearBload(void *);
57 
58 /*********************************************/
59 /* DefmoduleBinarySetup: Installs the binary */
60 /*   save/load feature for defmodules.       */
61 /*********************************************/
DefmoduleBinarySetup(void * theEnv)62 globle void DefmoduleBinarySetup(
63   void *theEnv)
64   {
65    AddBeforeBloadFunction(theEnv,"defmodule",RemoveAllDefmodules,2000);
66 
67 #if BLOAD_AND_BSAVE
68    AddBinaryItem(theEnv,"defmodule",0,BsaveFind,NULL,
69                              BsaveStorage,BsaveBinaryItem,
70                              BloadStorage,BloadBinaryItem,
71                              ClearBload);
72 #endif
73 
74    AddAbortBloadFunction(theEnv,"defmodule",CreateMainModule,0);
75 
76 #if (BLOAD || BLOAD_ONLY)
77    AddBinaryItem(theEnv,"defmodule",0,NULL,NULL,NULL,NULL,
78                              BloadStorage,BloadBinaryItem,
79                              ClearBload);
80 #endif
81   }
82 
83 /**************************************************************/
84 /* UpdateDefmoduleItemHeader: Updates the values in defmodule */
85 /*   item headers for the loaded binary image.                */
86 /**************************************************************/
UpdateDefmoduleItemHeader(void * theEnv,struct bsaveDefmoduleItemHeader * theBsaveHeader,struct defmoduleItemHeader * theHeader,int itemSize,void * itemArray)87 globle void UpdateDefmoduleItemHeader(
88   void *theEnv,
89   struct bsaveDefmoduleItemHeader *theBsaveHeader,
90   struct defmoduleItemHeader *theHeader,
91   int itemSize,
92   void *itemArray)
93   {
94    long firstOffset,lastOffset;
95 
96    theHeader->theModule = ModulePointer(theBsaveHeader->theModule);
97    if (theBsaveHeader->firstItem == -1L)
98      {
99       theHeader->firstItem = NULL;
100       theHeader->lastItem = NULL;
101      }
102    else
103      {
104       firstOffset = itemSize * theBsaveHeader->firstItem;
105       lastOffset = itemSize * theBsaveHeader->lastItem;
106       theHeader->firstItem =
107         (struct constructHeader *) &((char *) itemArray)[firstOffset];
108       theHeader->lastItem =
109         (struct constructHeader *) &((char *) itemArray)[lastOffset];
110      }
111   }
112 
113 #if BLOAD_AND_BSAVE
114 
115 /*********************************************************/
116 /* AssignBsaveDefmdlItemHdrVals: Assigns the appropriate */
117 /*   values to a bsave defmodule item header record.     */
118 /*********************************************************/
AssignBsaveDefmdlItemHdrVals(struct bsaveDefmoduleItemHeader * theBsaveHeader,struct defmoduleItemHeader * theHeader)119 globle void AssignBsaveDefmdlItemHdrVals(
120   struct bsaveDefmoduleItemHeader *theBsaveHeader,
121   struct defmoduleItemHeader *theHeader)
122   {
123    theBsaveHeader->theModule = theHeader->theModule->bsaveID;
124    if (theHeader->firstItem == NULL)
125      {
126       theBsaveHeader->firstItem = -1L;
127       theBsaveHeader->lastItem = -1L;
128      }
129    else
130      {
131       theBsaveHeader->firstItem = theHeader->firstItem->bsaveID;
132       theBsaveHeader->lastItem = theHeader->lastItem->bsaveID;
133      }
134   }
135 
136 /**********************************************************/
137 /* BsaveFind: Counts the number of data structures which  */
138 /*   must be saved in the binary image for the defmodules */
139 /*   in the current environment.                          */
140 /**********************************************************/
BsaveFind(void * theEnv)141 static void BsaveFind(
142   void *theEnv)
143   {
144    struct defmodule *defmodulePtr;
145    struct portItem *theList;
146 
147    /*=======================================================*/
148    /* If a binary image is already loaded, then temporarily */
149    /* save the count values since these will be overwritten */
150    /* in the process of saving the binary image.            */
151    /*=======================================================*/
152 
153    SaveBloadCount(theEnv,DefmoduleData(theEnv)->BNumberOfDefmodules);
154    SaveBloadCount(theEnv,DefmoduleData(theEnv)->NumberOfPortItems);
155 
156    /*==========================================*/
157    /* Set the count of defmodule and defmodule */
158    /* port items data structures to zero.      */
159    /*==========================================*/
160 
161    DefmoduleData(theEnv)->BNumberOfDefmodules = 0;
162    DefmoduleData(theEnv)->NumberOfPortItems = 0;
163 
164    /*===========================*/
165    /* Loop through each module. */
166    /*===========================*/
167 
168    for (defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
169         defmodulePtr != NULL;
170         defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,defmodulePtr))
171      {
172       /*==============================================*/
173       /* Increment the number of modules encountered. */
174       /*==============================================*/
175 
176       DefmoduleData(theEnv)->BNumberOfDefmodules++;
177 
178       /*===========================*/
179       /* Mark the defmodule's name */
180       /* as being a needed symbol. */
181       /*===========================*/
182 
183       defmodulePtr->name->neededSymbol = TRUE;
184 
185       /*==============================================*/
186       /* Loop through each of the port items in the   */
187       /* defmodule's import list incrementing the     */
188       /* number of port items encountered and marking */
189       /* needed symbols.                              */
190       /*==============================================*/
191 
192       for (theList = defmodulePtr->importList;
193            theList != NULL;
194            theList = theList->next)
195         {
196          DefmoduleData(theEnv)->NumberOfPortItems++;
197          if (theList->moduleName != NULL)
198            { theList->moduleName->neededSymbol = TRUE; }
199          if (theList->constructType != NULL)
200            { theList->constructType->neededSymbol = TRUE; }
201          if (theList->constructName != NULL)
202            { theList->constructName->neededSymbol = TRUE; }
203         }
204 
205       /*==============================================*/
206       /* Loop through each of the port items in the   */
207       /* defmodule's export list incrementing the     */
208       /* number of port items encountered and marking */
209       /* needed symbols.                              */
210       /*==============================================*/
211 
212       for (theList = defmodulePtr->exportList;
213            theList != NULL;
214            theList = theList->next)
215         {
216          DefmoduleData(theEnv)->NumberOfPortItems++;
217          if (theList->moduleName != NULL)
218            { theList->moduleName->neededSymbol = TRUE; }
219          if (theList->constructType != NULL)
220            { theList->constructType->neededSymbol = TRUE; }
221          if (theList->constructName != NULL)
222            { theList->constructName->neededSymbol = TRUE; }
223         }
224      }
225   }
226 
227 /*********************************************************/
228 /* BsaveStorage: Writes out the storage requirements for */
229 /*    all defmodule structures to the binary file.       */
230 /*********************************************************/
BsaveStorage(void * theEnv,FILE * fp)231 static void BsaveStorage(
232   void *theEnv,
233   FILE *fp)
234   {
235    size_t space;
236 
237    space = sizeof(long) * 2;
238    GenWrite(&space,sizeof(size_t),fp);
239    GenWrite(&DefmoduleData(theEnv)->BNumberOfDefmodules,sizeof(long int),fp);
240    GenWrite(&DefmoduleData(theEnv)->NumberOfPortItems,sizeof(long int),fp);
241   }
242 
243 /*********************************************/
244 /* BsaveBinaryItem: Writes out all defmodule */
245 /*   structures to the binary file.          */
246 /*********************************************/
BsaveBinaryItem(void * theEnv,FILE * fp)247 static void BsaveBinaryItem(
248   void *theEnv,
249   FILE *fp)
250   {
251    size_t space;
252    struct defmodule *defmodulePtr;
253    struct bsaveDefmodule newDefmodule;
254    struct bsavePortItem newPortItem;
255    struct portItem *theList;
256 
257    /*=========================================================*/
258    /* Write out the amount of space taken up by the defmodule */
259    /* and port item data structures in the binary image.      */
260    /*=========================================================*/
261 
262    space = DefmoduleData(theEnv)->BNumberOfDefmodules * sizeof(struct bsaveDefmodule);
263    space += DefmoduleData(theEnv)->NumberOfPortItems * sizeof(struct bsavePortItem);
264    GenWrite(&space,sizeof(size_t),fp);
265 
266    /*==========================================*/
267    /* Write out each defmodule data structure. */
268    /*==========================================*/
269 
270    DefmoduleData(theEnv)->BNumberOfDefmodules = 0;
271    DefmoduleData(theEnv)->NumberOfPortItems = 0;
272    for (defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
273         defmodulePtr != NULL;
274         defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,defmodulePtr))
275      {
276       newDefmodule.name = defmodulePtr->name->bucket;
277 
278       DefmoduleData(theEnv)->BNumberOfDefmodules++;
279       if (defmodulePtr->next != NULL)
280         { newDefmodule.next = DefmoduleData(theEnv)->BNumberOfDefmodules; }
281       else
282         { newDefmodule.next = -1L; }
283 
284       if (defmodulePtr->importList == NULL)
285         { newDefmodule.importList = -1L; }
286       else
287         {
288          newDefmodule.importList = DefmoduleData(theEnv)->NumberOfPortItems;
289          for (theList = defmodulePtr->importList;
290               theList != NULL;
291               theList = theList->next)
292            { DefmoduleData(theEnv)->NumberOfPortItems++; }
293         }
294 
295       if (defmodulePtr->exportList == NULL)
296         { newDefmodule.exportList = -1L; }
297       else
298         {
299          newDefmodule.exportList = DefmoduleData(theEnv)->NumberOfPortItems;
300          for (theList = defmodulePtr->exportList;
301               theList != NULL;
302               theList = theList->next)
303            { DefmoduleData(theEnv)->NumberOfPortItems++; }
304         }
305 
306       newDefmodule.bsaveID = defmodulePtr->bsaveID;
307       GenWrite(&newDefmodule,sizeof(struct bsaveDefmodule),fp);
308      }
309 
310    /*==========================================*/
311    /* Write out each port item data structure. */
312    /*==========================================*/
313 
314    DefmoduleData(theEnv)->NumberOfPortItems = 0;
315    defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
316    while (defmodulePtr != NULL)
317      {
318       for (theList = defmodulePtr->importList;
319            theList != NULL;
320            theList = theList->next)
321         {
322          DefmoduleData(theEnv)->NumberOfPortItems++;
323          if (theList->moduleName == NULL) newPortItem.moduleName = -1L;
324          else newPortItem.moduleName = (long) theList->moduleName->bucket;
325 
326          if (theList->constructType == NULL) newPortItem.constructType = -1L;
327          else newPortItem.constructType = (long) theList->constructType->bucket;
328 
329          if (theList->constructName == NULL) newPortItem.constructName = -1L;
330          else newPortItem.constructName = (long) theList->constructName->bucket;
331 
332          if (theList->next == NULL) newPortItem.next = -1L;
333          else newPortItem.next = DefmoduleData(theEnv)->NumberOfPortItems;
334 
335          GenWrite(&newPortItem,sizeof(struct bsavePortItem),fp);
336         }
337 
338       for (theList = defmodulePtr->exportList;
339            theList != NULL;
340            theList = theList->next)
341         {
342          DefmoduleData(theEnv)->NumberOfPortItems++;
343          if (theList->moduleName == NULL) newPortItem.moduleName = -1L;
344          else newPortItem.moduleName = (long) theList->moduleName->bucket;
345 
346          if (theList->constructType == NULL) newPortItem.constructType = -1L;
347          else newPortItem.constructType = (long) theList->constructType->bucket;
348 
349          if (theList->constructName == NULL) newPortItem.constructName = -1L;
350          else newPortItem.constructName = (long) theList->constructName->bucket;
351 
352          if (theList->next == NULL) newPortItem.next = -1L;
353          else newPortItem.next = DefmoduleData(theEnv)->NumberOfPortItems;
354 
355          GenWrite(&newPortItem,sizeof(struct bsavePortItem),fp);
356         }
357 
358       defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,defmodulePtr);
359      }
360 
361    /*=============================================================*/
362    /* If a binary image was already loaded when the bsave command */
363    /* was issued, then restore the counts indicating the number   */
364    /* of defmodule and port items in the binary image (these were */
365    /* overwritten by the binary save).                            */
366    /*=============================================================*/
367 
368    RestoreBloadCount(theEnv,&DefmoduleData(theEnv)->BNumberOfDefmodules);
369    RestoreBloadCount(theEnv,&DefmoduleData(theEnv)->NumberOfPortItems);
370   }
371 
372 #endif /* BLOAD_AND_BSAVE */
373 
374 /**********************************************************/
375 /* BloadStorage: Allocates storage requirements for the   */
376 /*   defmodules and port items used by this binary image. */
377 /**********************************************************/
BloadStorage(void * theEnv)378 static void BloadStorage(
379   void *theEnv)
380   {
381    size_t space;
382 
383    /*=======================================*/
384    /* Determine the number of defmodule and */
385    /* port item data structures to be read. */
386    /*=======================================*/
387 
388    GenReadBinary(theEnv,&space,sizeof(size_t));
389    GenReadBinary(theEnv,&DefmoduleData(theEnv)->BNumberOfDefmodules,sizeof(long int));
390    GenReadBinary(theEnv,&DefmoduleData(theEnv)->NumberOfPortItems,sizeof(long int));
391 
392    /*================================*/
393    /* Allocate the space needed for  */
394    /* the defmodule data structures. */
395    /*================================*/
396 
397    if (DefmoduleData(theEnv)->BNumberOfDefmodules == 0)
398      {
399       DefmoduleData(theEnv)->DefmoduleArray = NULL;
400       return;
401      }
402 
403    space = (DefmoduleData(theEnv)->BNumberOfDefmodules * sizeof(struct defmodule));
404    DefmoduleData(theEnv)->DefmoduleArray = (struct defmodule *) genalloc(theEnv,space);
405 
406    /*================================*/
407    /* Allocate the space needed for  */
408    /* the port item data structures. */
409    /*================================*/
410 
411    if (DefmoduleData(theEnv)->NumberOfPortItems == 0)
412      {
413       DefmoduleData(theEnv)->PortItemArray = NULL;
414       return;
415      }
416 
417    space = (DefmoduleData(theEnv)->NumberOfPortItems * sizeof(struct portItem));
418    DefmoduleData(theEnv)->PortItemArray = (struct portItem *) genalloc(theEnv,space);
419   }
420 
421 /********************************************/
422 /* BloadBinaryItem: Loads and refreshes the */
423 /*   defmodules used by this binary image.  */
424 /********************************************/
BloadBinaryItem(void * theEnv)425 static void BloadBinaryItem(
426   void *theEnv)
427   {
428    size_t space;
429 
430    GenReadBinary(theEnv,&space,sizeof(size_t));
431    if (DefmoduleData(theEnv)->BNumberOfDefmodules == 0) return;
432 
433    BloadandRefresh(theEnv,DefmoduleData(theEnv)->BNumberOfDefmodules,sizeof(struct bsaveDefmodule),UpdateDefmodule);
434    BloadandRefresh(theEnv,DefmoduleData(theEnv)->NumberOfPortItems,sizeof(struct bsavePortItem),UpdatePortItem);
435 
436    SetListOfDefmodules(theEnv,(void *) DefmoduleData(theEnv)->DefmoduleArray);
437    EnvSetCurrentModule(theEnv,(void *) EnvGetNextDefmodule(theEnv,NULL));
438   }
439 
440 /******************************************/
441 /* UpdateDefmodule: Bload refresh routine */
442 /*   for defmodule data structure.        */
443 /******************************************/
UpdateDefmodule(void * theEnv,void * buf,long obji)444 static void UpdateDefmodule(
445   void *theEnv,
446   void *buf,
447   long obji)
448   {
449    struct bsaveDefmodule *bdp;
450    struct moduleItem *theItem;
451    int i;
452 
453    bdp = (struct bsaveDefmodule *) buf;
454    DefmoduleData(theEnv)->DefmoduleArray[obji].name = SymbolPointer(bdp->name);
455    IncrementSymbolCount(DefmoduleData(theEnv)->DefmoduleArray[obji].name);
456    if (bdp->next != -1L)
457      { DefmoduleData(theEnv)->DefmoduleArray[obji].next = (struct defmodule *) &DefmoduleData(theEnv)->DefmoduleArray[bdp->next]; }
458    else
459      { DefmoduleData(theEnv)->DefmoduleArray[obji].next = NULL; }
460 
461    if (GetNumberOfModuleItems(theEnv) == 0)
462      { DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray = NULL; }
463    else
464      {
465       DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray =
466          (struct defmoduleItemHeader **) gm2(theEnv,sizeof(void *) * GetNumberOfModuleItems(theEnv));
467      }
468 
469    for (i = 0, theItem = GetListOfModuleItems(theEnv);
470         (i < GetNumberOfModuleItems(theEnv)) && (theItem != NULL) ;
471         i++, theItem = theItem->next)
472      {
473       if (theItem->bloadModuleReference == NULL)
474         { DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray[i] = NULL; }
475       else
476         {
477          DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray[i] =
478              (struct defmoduleItemHeader *)
479              (*theItem->bloadModuleReference)(theEnv,obji);
480         }
481      }
482 
483    DefmoduleData(theEnv)->DefmoduleArray[obji].ppForm = NULL;
484 
485    if (bdp->importList != -1L)
486      { DefmoduleData(theEnv)->DefmoduleArray[obji].importList = (struct portItem *) &DefmoduleData(theEnv)->PortItemArray[bdp->importList]; }
487    else
488      { DefmoduleData(theEnv)->DefmoduleArray[obji].importList = NULL; }
489 
490    if (bdp->exportList != -1L)
491      { DefmoduleData(theEnv)->DefmoduleArray[obji].exportList = (struct portItem *) &DefmoduleData(theEnv)->PortItemArray[bdp->exportList]; }
492    else
493      { DefmoduleData(theEnv)->DefmoduleArray[obji].exportList = NULL; }
494    DefmoduleData(theEnv)->DefmoduleArray[obji].bsaveID = bdp->bsaveID;
495   }
496 
497 /*****************************************/
498 /* UpdatePortItem: Bload refresh routine */
499 /*   for port item data structure.       */
500 /*****************************************/
UpdatePortItem(void * theEnv,void * buf,long obji)501 static void UpdatePortItem(
502   void *theEnv,
503   void *buf,
504   long obji)
505   {
506    struct bsavePortItem *bdp;
507 
508    bdp = (struct bsavePortItem *) buf;
509 
510    if (bdp->moduleName != -1L)
511      {
512       DefmoduleData(theEnv)->PortItemArray[obji].moduleName = SymbolPointer(bdp->moduleName);
513       IncrementSymbolCount(DefmoduleData(theEnv)->PortItemArray[obji].moduleName);
514      }
515    else
516      { DefmoduleData(theEnv)->PortItemArray[obji].moduleName = NULL; }
517 
518    if (bdp->constructType != -1L)
519      {
520       DefmoduleData(theEnv)->PortItemArray[obji].constructType = SymbolPointer(bdp->constructType);
521       IncrementSymbolCount(DefmoduleData(theEnv)->PortItemArray[obji].constructType);
522      }
523    else
524      { DefmoduleData(theEnv)->PortItemArray[obji].constructType = NULL; }
525 
526    if (bdp->constructName != -1L)
527      {
528       DefmoduleData(theEnv)->PortItemArray[obji].constructName = SymbolPointer(bdp->constructName);
529       IncrementSymbolCount(DefmoduleData(theEnv)->PortItemArray[obji].constructName);
530      }
531    else
532      { DefmoduleData(theEnv)->PortItemArray[obji].constructName = NULL; }
533 
534    if (bdp->next != -1L)
535      { DefmoduleData(theEnv)->PortItemArray[obji].next = (struct portItem *) &DefmoduleData(theEnv)->PortItemArray[bdp->next]; }
536    else
537      { DefmoduleData(theEnv)->PortItemArray[obji].next = NULL; }
538   }
539 
540 /***************************************/
541 /* ClearBload: Defmodule clear routine */
542 /*   when a binary load is in effect.  */
543 /***************************************/
ClearBload(void * theEnv)544 static void ClearBload(
545   void *theEnv)
546   {
547    long i;
548    size_t space;
549    struct portItem *theList;
550 
551    /*===========================*/
552    /* Decrement in use counters */
553    /* used by the binary image. */
554    /*===========================*/
555 
556    for (i = 0; i < DefmoduleData(theEnv)->BNumberOfDefmodules; i++)
557      {
558       DecrementSymbolCount(theEnv,DefmoduleData(theEnv)->DefmoduleArray[i].name);
559       for (theList = DefmoduleData(theEnv)->DefmoduleArray[i].importList;
560            theList != NULL;
561            theList = theList->next)
562         {
563          if (theList->moduleName != NULL) DecrementSymbolCount(theEnv,theList->moduleName);
564          if (theList->constructType != NULL) DecrementSymbolCount(theEnv,theList->constructType);
565          if (theList->constructName != NULL) DecrementSymbolCount(theEnv,theList->constructName);
566         }
567 
568       for (theList = DefmoduleData(theEnv)->DefmoduleArray[i].exportList;
569            theList != NULL;
570            theList = theList->next)
571         {
572          if (theList->moduleName != NULL) DecrementSymbolCount(theEnv,theList->moduleName);
573          if (theList->constructType != NULL) DecrementSymbolCount(theEnv,theList->constructType);
574          if (theList->constructName != NULL) DecrementSymbolCount(theEnv,theList->constructName);
575         }
576 
577       rm(theEnv,DefmoduleData(theEnv)->DefmoduleArray[i].itemsArray,sizeof(void *) * GetNumberOfModuleItems(theEnv));
578      }
579 
580    /*================================*/
581    /* Deallocate the space used for  */
582    /* the defmodule data structures. */
583    /*================================*/
584 
585    space = DefmoduleData(theEnv)->BNumberOfDefmodules * sizeof(struct defmodule);
586    if (space != 0) genfree(theEnv,(void *) DefmoduleData(theEnv)->DefmoduleArray,space);
587    DefmoduleData(theEnv)->BNumberOfDefmodules = 0;
588 
589    /*================================*/
590    /* Deallocate the space used for  */
591    /* the port item data structures. */
592    /*================================*/
593 
594    space = DefmoduleData(theEnv)->NumberOfPortItems * sizeof(struct portItem);
595    if (space != 0) genfree(theEnv,(void *) DefmoduleData(theEnv)->PortItemArray,space);
596    DefmoduleData(theEnv)->NumberOfPortItems = 0;
597 
598    /*===========================*/
599    /* Reset module information. */
600    /*===========================*/
601 
602    SetListOfDefmodules(theEnv,NULL);
603    CreateMainModule(theEnv);
604    DefmoduleData(theEnv)->MainModuleRedefinable = TRUE;
605   }
606 
607 #endif /*  (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME) */
608 
609 
610