globle void SaveBloadCount( void *theEnv, EXEC_STATUS, long cnt) { BLOADCNTSV *tmp, *prv; tmp = get_struct(theEnv,execStatus,bloadcntsv); tmp->val = cnt; tmp->nxt = NULL; if (BsaveData(theEnv,execStatus)->BloadCountSaveTop == NULL) { BsaveData(theEnv,execStatus)->BloadCountSaveTop = tmp; } else { prv = BsaveData(theEnv,execStatus)->BloadCountSaveTop; while (prv->nxt != NULL) { prv = prv->nxt; } prv->nxt = tmp; } }
globle void RestoreBloadCount( void *theEnv, long *cnt) { BLOADCNTSV *tmp; *cnt = BsaveData(theEnv)->BloadCountSaveTop->val; tmp = BsaveData(theEnv)->BloadCountSaveTop; BsaveData(theEnv)->BloadCountSaveTop = BsaveData(theEnv)->BloadCountSaveTop->nxt; rtn_struct(theEnv,bloadcntsv,tmp); }
static void FindNeededItems( void *theEnv) { struct BinaryItem *biPtr; for (biPtr = BsaveData(theEnv)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (biPtr->findFunction != NULL) (*biPtr->findFunction)(theEnv); } }
static void DeallocateBsaveData( void *theEnv) { struct BinaryItem *tmpPtr, *nextPtr; tmpPtr = BsaveData(theEnv)->ListOfBinaryItems; while (tmpPtr != NULL) { nextPtr = tmpPtr->next; rtn_struct(theEnv,BinaryItem,tmpPtr); tmpPtr = nextPtr; } }
void BsaveConstructExpressions( Environment *theEnv, FILE *fp) { struct BinaryItem *biPtr; for (biPtr = BsaveData(theEnv)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (biPtr->expressionFunction != NULL) { (*biPtr->expressionFunction)(theEnv,fp); } } }
globle int EnvBload( void *theEnv, char *fileName) { long numberOfFunctions; unsigned long space; int error; char IDbuffer[20]; char constructBuffer[CONSTRUCT_HEADER_SIZE]; struct BinaryItem *biPtr; struct callFunctionItem *bfPtr; /*================*/ /* Open the file. */ /*================*/ if (GenOpenReadBinary(theEnv,"bload",fileName) == 0) return(FALSE); /*=====================================*/ /* Determine if this is a binary file. */ /*=====================================*/ GenReadBinary(theEnv,IDbuffer,(unsigned long) strlen(BloadData(theEnv)->BinaryPrefixID) + 1); if (strcmp(IDbuffer,BloadData(theEnv)->BinaryPrefixID) != 0) { PrintErrorID(theEnv,"BLOAD",2,FALSE); EnvPrintRouter(theEnv,WERROR,"File "); EnvPrintRouter(theEnv,WERROR,fileName); EnvPrintRouter(theEnv,WERROR," is not a binary construct file.\n"); GenCloseBinary(theEnv); return(FALSE); } /*=======================================*/ /* Determine if it's a binary file using */ /* a format from a different version. */ /*=======================================*/ GenReadBinary(theEnv,IDbuffer,(unsigned long) strlen(BloadData(theEnv)->BinaryVersionID) + 1); if (strcmp(IDbuffer,BloadData(theEnv)->BinaryVersionID) != 0) { PrintErrorID(theEnv,"BLOAD",3,FALSE); EnvPrintRouter(theEnv,WERROR,"File "); EnvPrintRouter(theEnv,WERROR,fileName); EnvPrintRouter(theEnv,WERROR," is an incompatible binary construct file.\n"); GenCloseBinary(theEnv); return(FALSE); } /*====================*/ /* Clear environment. */ /*====================*/ if (BloadData(theEnv)->BloadActive) { if (ClearBload(theEnv) == FALSE) { GenCloseBinary(theEnv); return(FALSE); } } /*=================================*/ /* Determine if the KB environment */ /* was successfully cleared. */ /*=================================*/ if (ClearReady(theEnv) == FALSE) { GenCloseBinary(theEnv); EnvPrintRouter(theEnv,WERROR,"The "); EnvPrintRouter(theEnv,WERROR,APPLICATION_NAME); EnvPrintRouter(theEnv,WERROR," environment could not be cleared.\n"); EnvPrintRouter(theEnv,WERROR,"Binary load cannot continue.\n"); return(FALSE); } /*==================================*/ /* Call the list of functions to be */ /* executed before a bload occurs. */ /*==================================*/ for (bfPtr = BloadData(theEnv)->BeforeBloadFunctions; bfPtr != NULL; bfPtr = bfPtr->next) { if (bfPtr->environmentAware) { (*bfPtr->func)(theEnv); } else { (* (void (*)(void)) bfPtr->func)(); } } /*====================================================*/ /* Read in the functions needed by this binary image. */ /*====================================================*/ BloadData(theEnv)->FunctionArray = ReadNeededFunctions(theEnv,&numberOfFunctions,&error); if (error) { GenCloseBinary(theEnv); AbortBload(theEnv); return(FALSE); } /*================================================*/ /* Read in the atoms needed by this binary image. */ /*================================================*/ ReadNeededAtomicValues(theEnv); /*===========================================*/ /* Determine the number of expressions to be */ /* read and allocate the appropriate space */ /*===========================================*/ AllocateExpressions(theEnv); /*==========================================================*/ /* Read in the memory requirements of the constructs stored */ /* in this binary image and allocate the necessary space */ /*==========================================================*/ for (GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE); strncmp(constructBuffer,BloadData(theEnv)->BinaryPrefixID,CONSTRUCT_HEADER_SIZE) != 0; GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE)) { intBool found; /*================================================*/ /* Search for the construct type in the list of */ /* binary items. If found, allocate the storage */ /* needed by the construct for this binary image. */ /*================================================*/ found = FALSE; for (biPtr = BsaveData(theEnv)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (strncmp(biPtr->name,constructBuffer,CONSTRUCT_HEADER_SIZE) == 0) { if (biPtr->bloadStorageFunction != NULL) { (*biPtr->bloadStorageFunction)(theEnv); found = TRUE; } break; } } /*==========================================*/ /* If the construct type wasn't found, skip */ /* the storage binary load information for */ /* this construct. */ /*==========================================*/ if (! found) { GenReadBinary(theEnv,&space,(unsigned long) sizeof(unsigned long)); GetSeekCurBinary(theEnv,(long) space); if (space != 0) { EnvPrintRouter(theEnv,WDIALOG,"\nSkipping "); EnvPrintRouter(theEnv,WDIALOG,constructBuffer); EnvPrintRouter(theEnv,WDIALOG," constructs because of unavailibility\n"); } } } /*======================================*/ /* Refresh the pointers in expressions. */ /*======================================*/ RefreshExpressions(theEnv); /*==========================*/ /* Read in the constraints. */ /*==========================*/ ReadNeededConstraints(theEnv); /*======================================================*/ /* Read in the constructs stored in this binary image. */ /*======================================================*/ for (GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE); strncmp(constructBuffer,BloadData(theEnv)->BinaryPrefixID,CONSTRUCT_HEADER_SIZE) != 0; GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE)) { intBool found; /*==================================================*/ /* Search for the function to load the construct */ /* into the previously allocated storage. If found, */ /* call the function to load the construct. */ /*==================================================*/ found = FALSE; for (biPtr = BsaveData(theEnv)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (strncmp(biPtr->name,constructBuffer,CONSTRUCT_HEADER_SIZE) == 0) { if (biPtr->bloadFunction != NULL) { (*biPtr->bloadFunction)(theEnv); found = TRUE; } break; } } /*==========================================*/ /* If the construct type wasn't found, skip */ /* the binary data for this construct. */ /*==========================================*/ if (! found) { GenReadBinary(theEnv,&space,(unsigned long) sizeof(unsigned long)); GetSeekCurBinary(theEnv,(long) space); } } /*=================*/ /* Close the file. */ /*=================*/ GenCloseBinary(theEnv); /*========================================*/ /* Free up temporary storage used for the */ /* function and atomic value information. */ /*========================================*/ if (BloadData(theEnv)->FunctionArray != NULL) { genlongfree(theEnv,(void *) BloadData(theEnv)->FunctionArray, (unsigned long) sizeof(struct FunctionDefinition *) * numberOfFunctions); } FreeAtomicValueStorage(theEnv); /*==================================*/ /* Call the list of functions to be */ /* executed after a bload occurs. */ /*==================================*/ for (bfPtr = BloadData(theEnv)->AfterBloadFunctions; bfPtr != NULL; bfPtr = bfPtr->next) { if (bfPtr->environmentAware) { (*bfPtr->func)(theEnv); } else { (* (void (*)(void)) bfPtr->func)(); } } /*=======================================*/ /* Add a clear function to remove binary */ /* load when a clear command is issued. */ /*=======================================*/ BloadData(theEnv)->BloadActive = TRUE; EnvAddClearFunction(theEnv,"bload",(void (*)(void *)) ClearBload,10000); /*=============================*/ /* Return TRUE to indicate the */ /* binary load was successful. */ /*=============================*/ return(TRUE); }
static int ClearBload( void *theEnv) { struct BinaryItem *biPtr; struct callFunctionItem *bfPtr; int ready,error; /*=================================================*/ /* Make sure it's safe to clear the bloaded image. */ /*=================================================*/ error = FALSE; for (bfPtr = BloadData(theEnv)->ClearBloadReadyFunctions; bfPtr != NULL; bfPtr = bfPtr->next) { if (bfPtr->environmentAware) { ready = (* ((int (*)(void *)) bfPtr->func))(theEnv); } else { ready = (* ((int (*)(void)) bfPtr->func))(); } if (ready == FALSE) { if (! error) { PrintErrorID(theEnv,"BLOAD",5,FALSE); EnvPrintRouter(theEnv,WERROR, "Some constructs are still in use by the current binary image:\n"); } EnvPrintRouter(theEnv,WERROR," "); EnvPrintRouter(theEnv,WERROR,bfPtr->name); EnvPrintRouter(theEnv,WERROR,"\n"); error = TRUE; } } /*==================================================*/ /* If some constructs are still in use and can't be */ /* cleared, indicate the binary load can't continue */ /* and return FALSE to indicate this condition. */ /*==================================================*/ if (error == TRUE) { EnvPrintRouter(theEnv,WERROR,"Binary clear cannot continue.\n"); return(FALSE); } /*=============================*/ /* Call bload clear functions. */ /*=============================*/ for (biPtr = BsaveData(theEnv)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (biPtr->clearFunction != NULL) (*biPtr->clearFunction)(theEnv); } /*===========================*/ /* Free bloaded expressions. */ /*===========================*/ ClearBloadedExpressions(theEnv); /*===========================*/ /* Free bloaded constraints. */ /*===========================*/ ClearBloadedConstraints(theEnv); /*==================================*/ /* Remove the bload clear function. */ /*==================================*/ BloadData(theEnv)->BloadActive = FALSE; EnvRemoveClearFunction(theEnv,"bload"); /*====================================*/ /* Return TRUE to indicate the binary */ /* image was successfully cleared. */ /*====================================*/ return(TRUE); }
globle intBool AddBinaryItem( void *theEnv, EXEC_STATUS, char *name, int priority, void (*findFunction)(void *,EXEC_STATUS), void (*expressionFunction)(void *,EXEC_STATUS,FILE *), void (*bsaveStorageFunction)(void *,EXEC_STATUS,FILE *), void (*bsaveFunction)(void *,EXEC_STATUS,FILE *), void (*bloadStorageFunction)(void *,EXEC_STATUS), void (*bloadFunction)(void *,EXEC_STATUS), void (*clearFunction)(void *,EXEC_STATUS)) { struct BinaryItem *newPtr, *currentPtr, *lastPtr = NULL; /*========================================*/ /* Create the binary item data structure. */ /*========================================*/ newPtr = get_struct(theEnv,execStatus,BinaryItem); newPtr->name = name; newPtr->findFunction = findFunction; newPtr->expressionFunction = expressionFunction; newPtr->bsaveStorageFunction = bsaveStorageFunction; newPtr->bsaveFunction = bsaveFunction; newPtr->bloadStorageFunction = bloadStorageFunction; newPtr->bloadFunction = bloadFunction; newPtr->clearFunction = clearFunction; newPtr->priority = priority; /*=================================*/ /* If no binary items are defined, */ /* just put the item on the list. */ /*=================================*/ if (BsaveData(theEnv,execStatus)->ListOfBinaryItems == NULL) { newPtr->next = NULL; BsaveData(theEnv,execStatus)->ListOfBinaryItems = newPtr; return(TRUE); } /*=========================================*/ /* Otherwise, place the binary item at the */ /* appropriate place in the list of binary */ /* items based on its priority. */ /*=========================================*/ currentPtr = BsaveData(theEnv,execStatus)->ListOfBinaryItems; while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE) { lastPtr = currentPtr; currentPtr = currentPtr->next; } if (lastPtr == NULL) { newPtr->next = BsaveData(theEnv,execStatus)->ListOfBinaryItems; BsaveData(theEnv,execStatus)->ListOfBinaryItems = newPtr; } else { newPtr->next = currentPtr; lastPtr->next = newPtr; } /*==================================*/ /* Return TRUE to indicate the item */ /* was successfully added. */ /*==================================*/ return(TRUE); }
globle intBool EnvBsave( void *theEnv, EXEC_STATUS, char *fileName) { FILE *fp; struct BinaryItem *biPtr; char constructBuffer[CONSTRUCT_HEADER_SIZE]; long saveExpressionCount; /*===================================*/ /* A bsave can't occur when a binary */ /* image is already loaded. */ /*===================================*/ if (Bloaded(theEnv,execStatus)) { PrintErrorID(theEnv,execStatus,"BSAVE",1,FALSE); EnvPrintRouter(theEnv,execStatus,WERROR, "Cannot perform a binary save while a binary load is in effect.\n"); return(0); } /*================*/ /* Open the file. */ /*================*/ if ((fp = GenOpen(theEnv,execStatus,fileName,"wb")) == NULL) { OpenErrorMessage(theEnv,execStatus,"bsave",fileName); return(0); } /*==============================*/ /* Remember the current module. */ /*==============================*/ SaveCurrentModule(theEnv,execStatus); /*==================================*/ /* Write binary header to the file. */ /*==================================*/ WriteBinaryHeader(theEnv,execStatus,fp); /*===========================================*/ /* Initialize count variables, index values, */ /* and determine some of the data structures */ /* which need to be saved. */ /*===========================================*/ ExpressionData(theEnv,execStatus)->ExpressionCount = 0; InitializeFunctionNeededFlags(theEnv,execStatus); InitAtomicValueNeededFlags(theEnv,execStatus); FindHashedExpressions(theEnv,execStatus); FindNeededItems(theEnv,execStatus); SetAtomicValueIndices(theEnv,execStatus,FALSE); /*===============================*/ /* Save the functions and atoms. */ /*===============================*/ WriteNeededFunctions(theEnv,execStatus,fp); WriteNeededAtomicValues(theEnv,execStatus,fp); /*=========================================*/ /* Write out the number of expression data */ /* structures in the binary image. */ /*=========================================*/ GenWrite((void *) &ExpressionData(theEnv,execStatus)->ExpressionCount,(unsigned long) sizeof(unsigned long),fp); /*===========================================*/ /* Save the numbers indicating the amount of */ /* memory needed to bload the constructs. */ /*===========================================*/ for (biPtr = BsaveData(theEnv,execStatus)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (biPtr->bsaveStorageFunction != NULL) { genstrncpy(constructBuffer,biPtr->name,CONSTRUCT_HEADER_SIZE); GenWrite(constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp); (*biPtr->bsaveStorageFunction)(theEnv,execStatus,fp); } } /*====================================*/ /* Write a binary footer to the file. */ /*====================================*/ WriteBinaryFooter(theEnv,execStatus,fp); /*===================*/ /* Save expressions. */ /*===================*/ ExpressionData(theEnv,execStatus)->ExpressionCount = 0; BsaveHashedExpressions(theEnv,execStatus,fp); saveExpressionCount = ExpressionData(theEnv,execStatus)->ExpressionCount; BsaveConstructExpressions(theEnv,execStatus,fp); ExpressionData(theEnv,execStatus)->ExpressionCount = saveExpressionCount; /*===================*/ /* Save constraints. */ /*===================*/ WriteNeededConstraints(theEnv,execStatus,fp); /*==================*/ /* Save constructs. */ /*==================*/ for (biPtr = BsaveData(theEnv,execStatus)->ListOfBinaryItems; biPtr != NULL; biPtr = biPtr->next) { if (biPtr->bsaveFunction != NULL) { genstrncpy(constructBuffer,biPtr->name,CONSTRUCT_HEADER_SIZE); GenWrite(constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp); (*biPtr->bsaveFunction)(theEnv,execStatus,fp); } } /*===================================*/ /* Save a binary footer to the file. */ /*===================================*/ WriteBinaryFooter(theEnv,execStatus,fp); /*===========*/ /* Clean up. */ /*===========*/ RestoreAtomicValueBuckets(theEnv,execStatus); /*=================*/ /* Close the file. */ /*=================*/ GenClose(theEnv,execStatus,fp); /*=============================*/ /* Restore the current module. */ /*=============================*/ RestoreCurrentModule(theEnv,execStatus); /*========================================*/ /* Return TRUE to indicate success. */ /*========================================*/ return(TRUE); }