static void WriteBinaryHeader( void *theEnv, FILE *fp) { GenWrite(BloadData(theEnv)->BinaryPrefixID,(unsigned long) strlen(BloadData(theEnv)->BinaryPrefixID) + 1,fp); GenWrite(BloadData(theEnv)->BinaryVersionID,(unsigned long) strlen(BloadData(theEnv)->BinaryVersionID) + 1,fp); }
static void DeallocateBloadData( void *theEnv) { DeallocateCallList(theEnv,BloadData(theEnv)->BeforeBloadFunctions); DeallocateCallList(theEnv,BloadData(theEnv)->AfterBloadFunctions); DeallocateCallList(theEnv,BloadData(theEnv)->ClearBloadReadyFunctions); DeallocateCallList(theEnv,BloadData(theEnv)->AbortBloadFunctions); }
globle void AddAfterBloadFunction( void *theEnv, char *name, void (*func)(void *), int priority) { BloadData(theEnv)->AfterBloadFunctions = AddFunctionToCallList(theEnv,name,priority,func,BloadData(theEnv)->AfterBloadFunctions,TRUE); }
globle void InitializeBloadData( void *theEnv) { AllocateEnvironmentData(theEnv,BLOAD_DATA,sizeof(struct bloadData),NULL); AddEnvironmentCleanupFunction(theEnv,"bload",DeallocateBloadData,-1500); BloadData(theEnv)->BinaryPrefixID = "\1\2\3\4CLIPS"; BloadData(theEnv)->BinaryVersionID = "V6.20"; }
globle void AddClearBloadReadyFunction( void *theEnv, char *name, int (*func)(void *), int priority) { BloadData(theEnv)->ClearBloadReadyFunctions = AddFunctionToCallList(theEnv,name,priority, (void (*)(void *)) func, BloadData(theEnv)->ClearBloadReadyFunctions,TRUE); }
static void WriteBinaryFooter( void *theEnv, FILE *fp) { char footerBuffer[CONSTRUCT_HEADER_SIZE]; genstrncpy(footerBuffer,BloadData(theEnv)->BinaryPrefixID,CONSTRUCT_HEADER_SIZE); GenWrite(footerBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp); }
static void AbortBload( void *theEnv) { struct callFunctionItem *bfPtr; for (bfPtr = BloadData(theEnv)->AbortBloadFunctions; bfPtr != NULL; bfPtr = bfPtr->next) { if (bfPtr->environmentAware) { (*bfPtr->func)(theEnv); } else { (* (void (*)(void)) bfPtr->func)(); } } }
/********************************************************* NAME : UpdateExpression DESCRIPTION : Given a bloaded expression buffer, this routine refreshes the pointers in the expression array INPUTS : 1) a bloaded expression buffer 2) the index of the expression to refresh RETURNS : Nothing useful SIDE EFFECTS : Expression updated NOTES : None *********************************************************/ static void UpdateExpression( Environment *theEnv, void *buf, unsigned long obji) { BSAVE_EXPRESSION *bexp; unsigned long theIndex; bexp = (BSAVE_EXPRESSION *) buf; ExpressionData(theEnv)->ExpressionArray[obji].type = bexp->type; switch(bexp->type) { case FCALL: ExpressionData(theEnv)->ExpressionArray[obji].value = BloadData(theEnv)->FunctionArray[bexp->value]; break; case GCALL: #if DEFGENERIC_CONSTRUCT ExpressionData(theEnv)->ExpressionArray[obji].value = GenericPointer(bexp->value); #else ExpressionData(theEnv)->ExpressionArray[obji].value = NULL; #endif break; case PCALL: #if DEFFUNCTION_CONSTRUCT ExpressionData(theEnv)->ExpressionArray[obji].value = DeffunctionPointer(bexp->value); #else ExpressionData(theEnv)->ExpressionArray[obji].value = NULL; #endif break; case DEFTEMPLATE_PTR: #if DEFTEMPLATE_CONSTRUCT ExpressionData(theEnv)->ExpressionArray[obji].value = DeftemplatePointer(bexp->value); #else ExpressionData(theEnv)->ExpressionArray[obji].value = NULL; #endif break; case DEFCLASS_PTR: #if OBJECT_SYSTEM ExpressionData(theEnv)->ExpressionArray[obji].value = DefclassPointer(bexp->value); #else ExpressionData(theEnv)->ExpressionArray[obji].value = NULL; #endif break; case DEFGLOBAL_PTR: #if DEFGLOBAL_CONSTRUCT ExpressionData(theEnv)->ExpressionArray[obji].value = DefglobalPointer(bexp->value); #else ExpressionData(theEnv)->ExpressionArray[obji].value = NULL; #endif break; case INTEGER_TYPE: ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->IntegerArray[bexp->value]; IncrementIntegerCount(ExpressionData(theEnv)->ExpressionArray[obji].integerValue); break; case FLOAT_TYPE: ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->FloatArray[bexp->value]; IncrementFloatCount(ExpressionData(theEnv)->ExpressionArray[obji].floatValue); break; case INSTANCE_NAME_TYPE: #if ! OBJECT_SYSTEM ExpressionData(theEnv)->ExpressionArray[obji].type = SYMBOL_TYPE; #endif case GBL_VARIABLE: case SYMBOL_TYPE: case STRING_TYPE: ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->SymbolArray[bexp->value]; IncrementLexemeCount(ExpressionData(theEnv)->ExpressionArray[obji].lexemeValue); break; #if DEFTEMPLATE_CONSTRUCT case FACT_ADDRESS_TYPE: ExpressionData(theEnv)->ExpressionArray[obji].value = &FactData(theEnv)->DummyFact; RetainFact((Fact *) ExpressionData(theEnv)->ExpressionArray[obji].value); break; #endif #if OBJECT_SYSTEM case INSTANCE_ADDRESS_TYPE: ExpressionData(theEnv)->ExpressionArray[obji].value = &InstanceData(theEnv)->DummyInstance; RetainInstance((Instance *) ExpressionData(theEnv)->ExpressionArray[obji].value); break; #endif case EXTERNAL_ADDRESS_TYPE: ExpressionData(theEnv)->ExpressionArray[obji].value = NULL; break; case VOID_TYPE: break; default: if (EvaluationData(theEnv)->PrimitivesArray[bexp->type] == NULL) break; if (EvaluationData(theEnv)->PrimitivesArray[bexp->type]->bitMap) { ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->BitMapArray[bexp->value]; IncrementBitMapCount((CLIPSBitMap *) ExpressionData(theEnv)->ExpressionArray[obji].value); } break; } theIndex = bexp->nextArg; if (theIndex == ULONG_MAX) { ExpressionData(theEnv)->ExpressionArray[obji].nextArg = NULL; } else { ExpressionData(theEnv)->ExpressionArray[obji].nextArg = (struct expr *) &ExpressionData(theEnv)->ExpressionArray[theIndex]; } theIndex = bexp->argList; if (theIndex == ULONG_MAX) { ExpressionData(theEnv)->ExpressionArray[obji].argList = NULL; } else { ExpressionData(theEnv)->ExpressionArray[obji].argList = (struct expr *) &ExpressionData(theEnv)->ExpressionArray[theIndex]; } }
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 Bloaded( void *theEnv) { return(BloadData(theEnv)->BloadActive); }