#include "setup.h"
#if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME)
#include <stdio.h>
#include "bload.h"
#include "bsave.h"
#include "constrct.h"
#include "cstrcbin.h"
#include "envrnmnt.h"
#include "memalloc.h"
#include "moduldef.h"
#include "modulbin.h"
#if BLOAD_AND_BSAVE
static void BsaveFind(Environment *);
static void BsaveStorage(Environment *,FILE *);
static void BsaveBinaryItem(Environment *,FILE *);
#endif
static void BloadStorage(Environment *);
static void BloadBinaryItem(Environment *);
static void UpdateDefmodule(Environment *,void *,unsigned long);
static void UpdatePortItem(Environment *,void *,unsigned long);
static void ClearBload(Environment *);
void DefmoduleBinarySetup(
Environment *theEnv)
{
AddBeforeBloadFunction(theEnv,"defmodule",RemoveAllDefmodules,2000,NULL);
#if BLOAD_AND_BSAVE
AddBinaryItem(theEnv,"defmodule",0,BsaveFind,NULL,
BsaveStorage,BsaveBinaryItem,
BloadStorage,BloadBinaryItem,
ClearBload);
#endif
AddAbortBloadFunction(theEnv,"defmodule",CreateMainModule,0,NULL);
#if (BLOAD || BLOAD_ONLY)
AddBinaryItem(theEnv,"defmodule",0,NULL,NULL,NULL,NULL,
BloadStorage,BloadBinaryItem,
ClearBload);
#endif
}
void UpdateDefmoduleItemHeader(
Environment *theEnv,
struct bsaveDefmoduleItemHeader *theBsaveHeader,
struct defmoduleItemHeader *theHeader,
size_t itemSize,
void *itemArray)
{
size_t firstOffset, lastOffset;
theHeader->theModule = ModulePointer(theBsaveHeader->theModule);
if (theBsaveHeader->firstItem == ULONG_MAX)
{
theHeader->firstItem = NULL;
theHeader->lastItem = NULL;
}
else
{
firstOffset = itemSize * theBsaveHeader->firstItem;
lastOffset = itemSize * theBsaveHeader->lastItem;
theHeader->firstItem =
(ConstructHeader *) &((char *) itemArray)[firstOffset];
theHeader->lastItem =
(ConstructHeader *) &((char *) itemArray)[lastOffset];
}
}
#if BLOAD_AND_BSAVE
void AssignBsaveDefmdlItemHdrVals(
struct bsaveDefmoduleItemHeader *theBsaveHeader,
struct defmoduleItemHeader *theHeader)
{
theBsaveHeader->theModule = theHeader->theModule->header.bsaveID;
if (theHeader->firstItem == NULL)
{
theBsaveHeader->firstItem = ULONG_MAX;
theBsaveHeader->lastItem = ULONG_MAX;
}
else
{
theBsaveHeader->firstItem = theHeader->firstItem->bsaveID;
theBsaveHeader->lastItem = theHeader->lastItem->bsaveID;
}
}
static void BsaveFind(
Environment *theEnv)
{
Defmodule *defmodulePtr;
struct portItem *theList;
SaveBloadCount(theEnv,DefmoduleData(theEnv)->BNumberOfDefmodules);
SaveBloadCount(theEnv,DefmoduleData(theEnv)->NumberOfPortItems);
DefmoduleData(theEnv)->BNumberOfDefmodules = 0;
DefmoduleData(theEnv)->NumberOfPortItems = 0;
for (defmodulePtr = GetNextDefmodule(theEnv,NULL);
defmodulePtr != NULL;
defmodulePtr = GetNextDefmodule(theEnv,defmodulePtr))
{
DefmoduleData(theEnv)->BNumberOfDefmodules++;
MarkConstructHeaderNeededItems(&defmodulePtr->header,defmodulePtr->header.bsaveID);
for (theList = defmodulePtr->importList;
theList != NULL;
theList = theList->next)
{
DefmoduleData(theEnv)->NumberOfPortItems++;
if (theList->moduleName != NULL)
{ theList->moduleName->neededSymbol = true; }
if (theList->constructType != NULL)
{ theList->constructType->neededSymbol = true; }
if (theList->constructName != NULL)
{ theList->constructName->neededSymbol = true; }
}
for (theList = defmodulePtr->exportList;
theList != NULL;
theList = theList->next)
{
DefmoduleData(theEnv)->NumberOfPortItems++;
if (theList->moduleName != NULL)
{ theList->moduleName->neededSymbol = true; }
if (theList->constructType != NULL)
{ theList->constructType->neededSymbol = true; }
if (theList->constructName != NULL)
{ theList->constructName->neededSymbol = true; }
}
}
}
static void BsaveStorage(
Environment *theEnv,
FILE *fp)
{
size_t space;
space = sizeof(long) * 2;
GenWrite(&space,sizeof(size_t),fp);
GenWrite(&DefmoduleData(theEnv)->BNumberOfDefmodules,sizeof(long),fp);
GenWrite(&DefmoduleData(theEnv)->NumberOfPortItems,sizeof(long),fp);
}
static void BsaveBinaryItem(
Environment *theEnv,
FILE *fp)
{
size_t space;
Defmodule *defmodulePtr;
struct bsaveDefmodule newDefmodule;
struct bsavePortItem newPortItem;
struct portItem *theList;
space = DefmoduleData(theEnv)->BNumberOfDefmodules * sizeof(struct bsaveDefmodule);
space += DefmoduleData(theEnv)->NumberOfPortItems * sizeof(struct bsavePortItem);
GenWrite(&space,sizeof(size_t),fp);
DefmoduleData(theEnv)->BNumberOfDefmodules = 0;
DefmoduleData(theEnv)->NumberOfPortItems = 0;
for (defmodulePtr = GetNextDefmodule(theEnv,NULL);
defmodulePtr != NULL;
defmodulePtr = GetNextDefmodule(theEnv,defmodulePtr))
{
AssignBsaveConstructHeaderVals(&newDefmodule.header,&defmodulePtr->header);
DefmoduleData(theEnv)->BNumberOfDefmodules++;
if (defmodulePtr->importList == NULL)
{ newDefmodule.importList = ULONG_MAX; }
else
{
newDefmodule.importList = DefmoduleData(theEnv)->NumberOfPortItems;
for (theList = defmodulePtr->importList;
theList != NULL;
theList = theList->next)
{ DefmoduleData(theEnv)->NumberOfPortItems++; }
}
if (defmodulePtr->exportList == NULL)
{ newDefmodule.exportList = ULONG_MAX; }
else
{
newDefmodule.exportList = DefmoduleData(theEnv)->NumberOfPortItems;
for (theList = defmodulePtr->exportList;
theList != NULL;
theList = theList->next)
{ DefmoduleData(theEnv)->NumberOfPortItems++; }
}
newDefmodule.bsaveID = defmodulePtr->header.bsaveID;
GenWrite(&newDefmodule,sizeof(struct bsaveDefmodule),fp);
}
DefmoduleData(theEnv)->NumberOfPortItems = 0;
defmodulePtr = GetNextDefmodule(theEnv,NULL);
while (defmodulePtr != NULL)
{
for (theList = defmodulePtr->importList;
theList != NULL;
theList = theList->next)
{
DefmoduleData(theEnv)->NumberOfPortItems++;
if (theList->moduleName == NULL) newPortItem.moduleName = ULONG_MAX;
else newPortItem.moduleName = theList->moduleName->bucket;
if (theList->constructType == NULL) newPortItem.constructType = ULONG_MAX;
else newPortItem.constructType = theList->constructType->bucket;
if (theList->constructName == NULL) newPortItem.constructName = ULONG_MAX;
else newPortItem.constructName = theList->constructName->bucket;
if (theList->next == NULL) newPortItem.next = ULONG_MAX;
else newPortItem.next = DefmoduleData(theEnv)->NumberOfPortItems;
GenWrite(&newPortItem,sizeof(struct bsavePortItem),fp);
}
for (theList = defmodulePtr->exportList;
theList != NULL;
theList = theList->next)
{
DefmoduleData(theEnv)->NumberOfPortItems++;
if (theList->moduleName == NULL) newPortItem.moduleName = ULONG_MAX;
else newPortItem.moduleName = theList->moduleName->bucket;
if (theList->constructType == NULL) newPortItem.constructType = ULONG_MAX;
else newPortItem.constructType = theList->constructType->bucket;
if (theList->constructName == NULL) newPortItem.constructName = ULONG_MAX;
else newPortItem.constructName = theList->constructName->bucket;
if (theList->next == NULL) newPortItem.next = ULONG_MAX;
else newPortItem.next = DefmoduleData(theEnv)->NumberOfPortItems;
GenWrite(&newPortItem,sizeof(struct bsavePortItem),fp);
}
defmodulePtr = GetNextDefmodule(theEnv,defmodulePtr);
}
RestoreBloadCount(theEnv,&DefmoduleData(theEnv)->BNumberOfDefmodules);
RestoreBloadCount(theEnv,&DefmoduleData(theEnv)->NumberOfPortItems);
}
#endif
static void BloadStorage(
Environment *theEnv)
{
size_t space;
GenReadBinary(theEnv,&space,sizeof(size_t));
GenReadBinary(theEnv,&DefmoduleData(theEnv)->BNumberOfDefmodules,sizeof(unsigned long));
GenReadBinary(theEnv,&DefmoduleData(theEnv)->NumberOfPortItems,sizeof(unsigned long));
if (DefmoduleData(theEnv)->BNumberOfDefmodules == 0)
{
DefmoduleData(theEnv)->DefmoduleArray = NULL;
return;
}
space = (DefmoduleData(theEnv)->BNumberOfDefmodules * sizeof(Defmodule));
DefmoduleData(theEnv)->DefmoduleArray = (Defmodule *) genalloc(theEnv,space);
if (DefmoduleData(theEnv)->NumberOfPortItems == 0)
{
DefmoduleData(theEnv)->PortItemArray = NULL;
return;
}
space = (DefmoduleData(theEnv)->NumberOfPortItems * sizeof(struct portItem));
DefmoduleData(theEnv)->PortItemArray = (struct portItem *) genalloc(theEnv,space);
}
static void BloadBinaryItem(
Environment *theEnv)
{
size_t space;
GenReadBinary(theEnv,&space,sizeof(size_t));
if (DefmoduleData(theEnv)->BNumberOfDefmodules == 0) return;
BloadandRefresh(theEnv,DefmoduleData(theEnv)->BNumberOfDefmodules,sizeof(struct bsaveDefmodule),UpdateDefmodule);
BloadandRefresh(theEnv,DefmoduleData(theEnv)->NumberOfPortItems,sizeof(struct bsavePortItem),UpdatePortItem);
SetListOfDefmodules(theEnv,DefmoduleData(theEnv)->DefmoduleArray);
SetCurrentModule(theEnv,GetNextDefmodule(theEnv,NULL));
}
static void UpdateDefmodule(
Environment *theEnv,
void *buf,
unsigned long obji)
{
struct bsaveDefmodule *bdp;
struct moduleItem *theItem;
unsigned int i;
bdp = (struct bsaveDefmodule *) buf;
UpdateConstructHeader(theEnv,&bdp->header,&DefmoduleData(theEnv)->DefmoduleArray[obji].header,DEFMODULE,
0,NULL,sizeof(Defmodule),DefmoduleData(theEnv)->DefmoduleArray);
if (GetNumberOfModuleItems(theEnv) == 0)
{ DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray = NULL; }
else
{
DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray =
(struct defmoduleItemHeader **) gm2(theEnv,sizeof(void *) * GetNumberOfModuleItems(theEnv));
}
for (i = 0, theItem = GetListOfModuleItems(theEnv);
(i < GetNumberOfModuleItems(theEnv)) && (theItem != NULL) ;
i++, theItem = theItem->next)
{
if (theItem->bloadModuleReference == NULL)
{ DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray[i] = NULL; }
else
{
DefmoduleData(theEnv)->DefmoduleArray[obji].itemsArray[i] =
(struct defmoduleItemHeader *)
(*theItem->bloadModuleReference)(theEnv,obji);
}
}
DefmoduleData(theEnv)->DefmoduleArray[obji].header.ppForm = NULL;
if (bdp->importList != ULONG_MAX)
{ DefmoduleData(theEnv)->DefmoduleArray[obji].importList = (struct portItem *) &DefmoduleData(theEnv)->PortItemArray[bdp->importList]; }
else
{ DefmoduleData(theEnv)->DefmoduleArray[obji].importList = NULL; }
if (bdp->exportList != ULONG_MAX)
{ DefmoduleData(theEnv)->DefmoduleArray[obji].exportList = (struct portItem *) &DefmoduleData(theEnv)->PortItemArray[bdp->exportList]; }
else
{ DefmoduleData(theEnv)->DefmoduleArray[obji].exportList = NULL; }
DefmoduleData(theEnv)->DefmoduleArray[obji].header.bsaveID = bdp->bsaveID;
}
static void UpdatePortItem(
Environment *theEnv,
void *buf,
unsigned long obji)
{
struct bsavePortItem *bdp;
bdp = (struct bsavePortItem *) buf;
if (bdp->moduleName != ULONG_MAX)
{
DefmoduleData(theEnv)->PortItemArray[obji].moduleName = SymbolPointer(bdp->moduleName);
IncrementLexemeCount(DefmoduleData(theEnv)->PortItemArray[obji].moduleName);
}
else
{ DefmoduleData(theEnv)->PortItemArray[obji].moduleName = NULL; }
if (bdp->constructType != ULONG_MAX)
{
DefmoduleData(theEnv)->PortItemArray[obji].constructType = SymbolPointer(bdp->constructType);
IncrementLexemeCount(DefmoduleData(theEnv)->PortItemArray[obji].constructType);
}
else
{ DefmoduleData(theEnv)->PortItemArray[obji].constructType = NULL; }
if (bdp->constructName != ULONG_MAX)
{
DefmoduleData(theEnv)->PortItemArray[obji].constructName = SymbolPointer(bdp->constructName);
IncrementLexemeCount(DefmoduleData(theEnv)->PortItemArray[obji].constructName);
}
else
{ DefmoduleData(theEnv)->PortItemArray[obji].constructName = NULL; }
if (bdp->next != ULONG_MAX)
{ DefmoduleData(theEnv)->PortItemArray[obji].next = (struct portItem *) &DefmoduleData(theEnv)->PortItemArray[bdp->next]; }
else
{ DefmoduleData(theEnv)->PortItemArray[obji].next = NULL; }
}
static void ClearBload(
Environment *theEnv)
{
unsigned long i;
size_t space;
struct portItem *theList;
for (i = 0; i < DefmoduleData(theEnv)->BNumberOfDefmodules; i++)
{
ReleaseLexeme(theEnv,DefmoduleData(theEnv)->DefmoduleArray[i].header.name);
for (theList = DefmoduleData(theEnv)->DefmoduleArray[i].importList;
theList != NULL;
theList = theList->next)
{
if (theList->moduleName != NULL) ReleaseLexeme(theEnv,theList->moduleName);
if (theList->constructType != NULL) ReleaseLexeme(theEnv,theList->constructType);
if (theList->constructName != NULL) ReleaseLexeme(theEnv,theList->constructName);
}
for (theList = DefmoduleData(theEnv)->DefmoduleArray[i].exportList;
theList != NULL;
theList = theList->next)
{
if (theList->moduleName != NULL) ReleaseLexeme(theEnv,theList->moduleName);
if (theList->constructType != NULL) ReleaseLexeme(theEnv,theList->constructType);
if (theList->constructName != NULL) ReleaseLexeme(theEnv,theList->constructName);
}
rm(theEnv,DefmoduleData(theEnv)->DefmoduleArray[i].itemsArray,sizeof(void *) * GetNumberOfModuleItems(theEnv));
}
space = DefmoduleData(theEnv)->BNumberOfDefmodules * sizeof(Defmodule);
if (space != 0) genfree(theEnv,DefmoduleData(theEnv)->DefmoduleArray,space);
DefmoduleData(theEnv)->BNumberOfDefmodules = 0;
space = DefmoduleData(theEnv)->NumberOfPortItems * sizeof(struct portItem);
if (space != 0) genfree(theEnv,DefmoduleData(theEnv)->PortItemArray,space);
DefmoduleData(theEnv)->NumberOfPortItems = 0;
SetListOfDefmodules(theEnv,NULL);
CreateMainModule(theEnv,NULL);
DefmoduleData(theEnv)->MainModuleRedefinable = true;
}
#endif