コード例 #1
0
ファイル: constrct.c プロジェクト: atrniv/CLIPS
globle int EnvSave(
  void *theEnv,
  EXEC_STATUS,
  char *fileName)
  {
   struct callFunctionItem *saveFunction;
   FILE *filePtr;
   void *defmodulePtr;

   /*=====================*/
   /* Open the save file. */
   /*=====================*/

   if ((filePtr = GenOpen(theEnv,execStatus,fileName,"w")) == NULL)
     { return(FALSE); }

   /*===========================*/
   /* Bypass the router system. */
   /*===========================*/

   SetFastSave(theEnv,execStatus,filePtr);

   /*======================*/
   /* Save the constructs. */
   /*======================*/
   
   for (defmodulePtr = EnvGetNextDefmodule(theEnv,execStatus,NULL);
        defmodulePtr != NULL;
        defmodulePtr = EnvGetNextDefmodule(theEnv,execStatus,defmodulePtr))
     {
      for (saveFunction = ConstructData(theEnv,execStatus)->ListOfSaveFunctions;
           saveFunction != NULL;
           saveFunction = saveFunction->next)
        {
         ((* (void (*)(void *,EXEC_STATUS,void *,char *)) saveFunction->func))(theEnv,execStatus,defmodulePtr,(char *) filePtr);
        }
     }

   /*======================*/
   /* Close the save file. */
   /*======================*/

   GenClose(theEnv,execStatus,filePtr);

   /*===========================*/
   /* Remove the router bypass. */
   /*===========================*/

   SetFastSave(theEnv,execStatus,NULL);

   /*=========================*/
   /* Return TRUE to indicate */
   /* successful completion.  */
   /*=========================*/

   return(TRUE);
  }
コード例 #2
0
ファイル: filecom.c プロジェクト: DrItanium/AdventureEngine
globle intBool EnvDribbleOn(
    void *theEnv,
    char *fileName)
{
    /*==============================*/
    /* If a dribble file is already */
    /* open, then close it.         */
    /*==============================*/

    if (FileCommandData(theEnv)->DribbleFP != NULL)
    {
        EnvDribbleOff(theEnv);
    }

    /*========================*/
    /* Open the dribble file. */
    /*========================*/

    FileCommandData(theEnv)->DribbleFP = GenOpen(theEnv,fileName,(char*)"w");
    if (FileCommandData(theEnv)->DribbleFP == NULL)
    {
        OpenErrorMessage(theEnv,(char*)"dribble-on",fileName);
        return(0);
    }

    /*============================*/
    /* Create the dribble router. */
    /*============================*/

    EnvAddRouter(theEnv,(char*)"dribble", 40,
                 FindDribble, PrintDribble,
                 GetcDribble, UngetcDribble,
                 ExitDribble);

    FileCommandData(theEnv)->DribbleCurrentPosition = 0;

    /*================================================*/
    /* Call the dribble status function. This is used */
    /* by some of the machine specific interfaces to  */
    /* do things such as changing the wording of menu */
    /* items from "Turn Dribble On..." to             */
    /* "Turn Dribble Off..."                          */
    /*================================================*/

    if (FileCommandData(theEnv)->DribbleStatusFunction != NULL)
    {
        (*FileCommandData(theEnv)->DribbleStatusFunction)(theEnv,TRUE);
    }

    /*=====================================*/
    /* Return TRUE to indicate the dribble */
    /* file was successfully opened.       */
    /*=====================================*/

    return(TRUE);
}
コード例 #3
0
ファイル: fileutil.c プロジェクト: DrItanium/maya
bool DribbleOn(
  Environment *theEnv,
  const char *fileName)
  {
   /*==============================*/
   /* If a dribble file is already */
   /* open, then close it.         */
   /*==============================*/

   if (FileCommandData(theEnv)->DribbleFP != NULL)
     { DribbleOff(theEnv); }

   /*========================*/
   /* Open the dribble file. */
   /*========================*/

   FileCommandData(theEnv)->DribbleFP = GenOpen(theEnv,fileName,"w");
   if (FileCommandData(theEnv)->DribbleFP == NULL)
     {
      OpenErrorMessage(theEnv,"dribble-on",fileName);
      return false;
     }

   /*============================*/
   /* Create the dribble router. */
   /*============================*/

   AddRouter(theEnv,"dribble",40,
             QueryDribbleCallback,WriteDribbleCallback,
             ReadDribbleCallback,UnreadDribbleCallback,
             ExitDribbleCallback,NULL);

   FileCommandData(theEnv)->DribbleCurrentPosition = 0;

   /*================================================*/
   /* Call the dribble status function. This is used */
   /* by some of the machine specific interfaces to  */
   /* do things such as changing the wording of menu */
   /* items from "Turn Dribble On..." to             */
   /* "Turn Dribble Off..."                          */
   /*================================================*/

   if (FileCommandData(theEnv)->DribbleStatusFunction != NULL)
     { (*FileCommandData(theEnv)->DribbleStatusFunction)(theEnv,true); }

   /*=====================================*/
   /* Return true to indicate the dribble */
   /* file was successfully opened.       */
   /*=====================================*/

   return true;
  }
コード例 #4
0
ファイル: factcom.c プロジェクト: DrItanium/DROID-CLIPS
globle intBool EnvLoadFacts(
  void *theEnv,
  char *fileName)
  {
   FILE *filePtr;
   struct token theToken;
   struct expr *testPtr;
   DATA_OBJECT rv;

   /*======================================================*/
   /* Open the file. Use either "fast save" or I/O Router. */
   /*======================================================*/

   if ((filePtr = GenOpen(theEnv,fileName,(char*)"r")) == NULL)
     {
      OpenErrorMessage(theEnv,(char*)"load-facts",fileName);
      return(FALSE);
     }

   SetFastLoad(theEnv,filePtr);

   /*=================*/
   /* Load the facts. */
   /*=================*/

   theToken.type = LPAREN;
   while (theToken.type != STOP)
     {
      testPtr = StandardLoadFact(theEnv,(char *) filePtr,&theToken);
      if (testPtr == NULL) theToken.type = STOP;
      else EvaluateExpression(theEnv,testPtr,&rv);
      ReturnExpression(theEnv,testPtr);
     }

   /*=================*/
   /* Close the file. */
   /*=================*/

   SetFastLoad(theEnv,NULL);
   GenClose(theEnv,filePtr);

   /*================================================*/
   /* Return TRUE if no error occurred while loading */
   /* the facts, otherwise return FALSE.             */
   /*================================================*/

   if (EvaluationData(theEnv)->EvaluationError) return(FALSE);
   return(TRUE);
  }
コード例 #5
0
ファイル: filecom.c プロジェクト: ricksladkey/CLIPS
globle int OpenBatch(
  void *theEnv,
  char *fileName,
  int placeAtEnd)
  {
   FILE *theFile;

   /*======================*/
   /* Open the batch file. */
   /*======================*/

   theFile = GenOpen(theEnv,fileName,"r");

   if (theFile == NULL)
     {
      OpenErrorMessage(theEnv,"batch",fileName);
      return(FALSE);
     }

   /*============================*/
   /* Create the batch router if */
   /* it doesn't already exist.  */
   /*============================*/

   if (FileCommandData(theEnv)->TopOfBatchList == NULL)
     {
      EnvAddRouter(theEnv,"batch", 20,
                 FindBatch, NULL,
                 GetcBatch, UngetcBatch,
                 ExitBatch);
     }

   /*====================================*/
   /* Add the newly opened batch file to */
   /* the list of batch files opened.    */
   /*====================================*/

   AddBatch(theEnv,placeAtEnd,(void *) theFile,FILE_BATCH,NULL);

   /*===================================*/
   /* Return TRUE to indicate the batch */
   /* file was successfully opened.     */
   /*===================================*/

   return(TRUE);
  }
コード例 #6
0
ファイル: filertr.c プロジェクト: Anusaaraka/anusaaraka
globle int OpenAFile(
  void *theEnv,
  char *fileName,
  char *accessMode,
  char *logicalName)
  {
   FILE *newstream;
   struct fileRouter *newRouter;

   /*==================================*/
   /* Make sure the file can be opened */
   /* with the specified access mode.  */
   /*==================================*/

   if ((newstream = GenOpen(theEnv,fileName,accessMode)) == NULL)
     { return(FALSE); }

   /*===========================*/
   /* Create a new file router. */
   /*===========================*/

   newRouter = get_struct(theEnv,fileRouter);
   newRouter->logicalName = (char *) gm2(theEnv,strlen(logicalName) + 1);
   genstrcpy(newRouter->logicalName,logicalName);
   newRouter->stream = newstream;

   /*==========================================*/
   /* Add the newly opened file to the list of */
   /* files associated with logical names.     */
   /*==========================================*/

   newRouter->next = FileRouterData(theEnv)->ListOfFileRouters;
   FileRouterData(theEnv)->ListOfFileRouters = newRouter;

   /*==================================*/
   /* Return TRUE to indicate the file */
   /* was opened successfully.         */
   /*==================================*/

   return(TRUE);
  }
コード例 #7
0
ファイル: cstrcpsr.c プロジェクト: Anusaaraka/anusaaraka
globle int EnvLoad(
  void *theEnv,
  char *fileName)
  {
   FILE *theFile;
   int noErrorsDetected;

   /*=======================================*/
   /* Open the file specified by file name. */
   /*=======================================*/

   if ((theFile = GenOpen(theEnv,fileName,"r")) == NULL) return(0);

   /*===================================================*/
   /* Read in the constructs. Enabling fast load allows */
   /* the router system to be bypassed for quicker load */
   /* times.                                            */
   /*===================================================*/

   SetFastLoad(theEnv,theFile);
   noErrorsDetected = LoadConstructsFromLogicalName(theEnv,(char *) theFile);
   SetFastLoad(theEnv,NULL);

   /*=================*/
   /* Close the file. */
   /*=================*/

   GenClose(theEnv,theFile);

   /*========================================*/
   /* If no errors occurred during the load, */
   /* return 1, otherwise return -1.         */
   /*========================================*/

   if (noErrorsDetected) return(1);

   return(-1);
  }
コード例 #8
0
ファイル: constrct.c プロジェクト: Khenji55/Computacion_UCLM
globle int EnvSave(
  void *theEnv,
  const char *fileName)
  {
   struct callFunctionItem *saveFunction;
   FILE *filePtr;
   struct defmodule *defmodulePtr;
   intBool updated = FALSE;
   intBool unvisited = TRUE;

   /*=====================*/
   /* Open the save file. */
   /*=====================*/

   if ((filePtr = GenOpen(theEnv,fileName,"w")) == NULL)
     { return(FALSE); }

   /*===========================*/
   /* Bypass the router system. */
   /*===========================*/

   SetFastSave(theEnv,filePtr);

   /*================================*/
   /* Mark all modules as unvisited. */
   /*================================*/
   
   MarkModulesAsUnvisited(theEnv);
  
   /*===============================================*/
   /* Save the constructs. Repeatedly loop over the */
   /* modules until each module has been save.      */
   /*===============================================*/
   
   while (unvisited)
     {
      unvisited = FALSE;
      updated = FALSE;
      
      for (defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
           defmodulePtr != NULL;
           defmodulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,defmodulePtr))
        {
         /*=================================================================*/
         /* We only want to save a module if all of the modules it imports  */
         /* from have already been saved. Since there can't be circular     */
         /* dependencies in imported modules, this should save the modules  */
         /* that don't import anything first and then work back from those. */
         /*=================================================================*/
         
         if (defmodulePtr->visitedFlag)
           { /* Module has already been saved. */ }
         else if (AllImportedModulesVisited(theEnv,defmodulePtr))
           {
            for (saveFunction = ConstructData(theEnv)->ListOfSaveFunctions;
                 saveFunction != NULL;
                 saveFunction = saveFunction->next)
              {
               ((* (void (*)(void *,void *,char *)) saveFunction->func))(theEnv,defmodulePtr,(char *) filePtr);
              }
              
            updated = TRUE;
            defmodulePtr->visitedFlag = TRUE;
           }
         else
           { unvisited = TRUE; }
        }
        
      /*=====================================================================*/
      /* At least one module should be saved in every pass. If all have been */
      /* visited/saved, then both flags will be FALSE. If all remaining      */
      /* unvisited/unsaved modules were visited/saved, then unvisited will   */
      /* be FALSE and updated will be TRUE. If some, but not all, remaining  */
      /* unvisited/unsaved modules are visited/saved, then  unvisited will   */
      /* be TRUE and updated will be TRUE. This leaves the case where there  */
      /* are remaining unvisited/unsaved modules, but none were              */
      /* visited/saved: unvisited is TRUE and updated is FALSE.              */
      /*=====================================================================*/
      
      if (unvisited && (! updated))
        {
         SystemError(theEnv,"CONSTRCT",2);
         break;
        }
     }

   /*======================*/
   /* Close the save file. */
   /*======================*/

   GenClose(theEnv,filePtr);

   /*===========================*/
   /* Remove the router bypass. */
   /*===========================*/

   SetFastSave(theEnv,NULL);

   /*=========================*/
   /* Return TRUE to indicate */
   /* successful completion.  */
   /*=========================*/

   return(TRUE);
  }
コード例 #9
0
ファイル: fileutil.c プロジェクト: DrItanium/maya
bool BatchStar(
  Environment *theEnv,
  const char *fileName)
  {
   int inchar;
   bool done = false;
   FILE *theFile;
   char *theString = NULL;
   size_t position = 0;
   size_t maxChars = 0;
#if (! RUN_TIME) && (! BLOAD_ONLY)
   char *oldParsingFileName;
   long oldLineCountValue;
#endif
   /*======================*/
   /* Open the batch file. */
   /*======================*/

   theFile = GenOpen(theEnv,fileName,"r");

   if (theFile == NULL)
     {
      OpenErrorMessage(theEnv,"batch",fileName);
      return false;
     }

   /*======================================*/
   /* Setup for capturing errors/warnings. */
   /*======================================*/

#if (! RUN_TIME) && (! BLOAD_ONLY)
   oldParsingFileName = CopyString(theEnv,GetParsingFileName(theEnv));
   SetParsingFileName(theEnv,fileName);

   CreateErrorCaptureRouter(theEnv);

   oldLineCountValue = SetLineCount(theEnv,1);
#endif

   /*=====================================*/
   /* If embedded, clear the error flags. */
   /*=====================================*/
   
   if (EvaluationData(theEnv)->CurrentExpression == NULL)
     { ResetErrorFlags(theEnv); }

   /*=============================================*/
   /* Evaluate commands from the file one by one. */
   /*=============================================*/

   while (! done)
     {
      inchar = getc(theFile);
      if (inchar == EOF)
        {
         inchar = '\n';
         done = true;
        }
        
      theString = ExpandStringWithChar(theEnv,inchar,theString,&position,
                                       &maxChars,maxChars+80);

      if (CompleteCommand(theString) != 0)
        {
         FlushPPBuffer(theEnv);
         SetPPBufferStatus(theEnv,false);
         RouteCommand(theEnv,theString,false);
         FlushPPBuffer(theEnv);
         SetHaltExecution(theEnv,false);
         SetEvaluationError(theEnv,false);
         FlushBindList(theEnv,NULL);
         genfree(theEnv,theString,maxChars);
         theString = NULL;
         maxChars = 0;
         position = 0;
#if (! RUN_TIME) && (! BLOAD_ONLY)
         FlushParsingMessages(theEnv);
#endif
        }

      if ((inchar == '\r') || (inchar == '\n'))
        { IncrementLineCount(theEnv); }
     }

   if (theString != NULL)
     { genfree(theEnv,theString,maxChars); }

   /*=======================*/
   /* Close the batch file. */
   /*=======================*/

   GenClose(theEnv,theFile);

   /*========================================*/
   /* Cleanup for capturing errors/warnings. */
   /*========================================*/

#if (! RUN_TIME) && (! BLOAD_ONLY)
   FlushParsingMessages(theEnv);
   DeleteErrorCaptureRouter(theEnv);

   SetLineCount(theEnv,oldLineCountValue);

   SetParsingFileName(theEnv,oldParsingFileName);
   DeleteString(theEnv,oldParsingFileName);
#endif

   return true;
  }
コード例 #10
0
ファイル: fileutil.c プロジェクト: DrItanium/maya
bool OpenBatch(
  Environment *theEnv,
  const char *fileName,
  bool placeAtEnd)
  {
   FILE *theFile;

   /*======================*/
   /* Open the batch file. */
   /*======================*/

   theFile = GenOpen(theEnv,fileName,"r");

   if (theFile == NULL)
     {
      OpenErrorMessage(theEnv,"batch",fileName);
      return false;
     }

   /*============================*/
   /* Create the batch router if */
   /* it doesn't already exist.  */
   /*============================*/

   if (FileCommandData(theEnv)->TopOfBatchList == NULL)
     {
      AddRouter(theEnv,"batch",20,QueryBatchCallback,NULL,
                ReadBatchCallback,UnreadBatchCallback,
                ExitBatchCallback,NULL);
     }

   /*===============================================================*/
   /* If a batch file is already open, save its current line count. */
   /*===============================================================*/

   if (FileCommandData(theEnv)->TopOfBatchList != NULL)
     { FileCommandData(theEnv)->TopOfBatchList->lineNumber = GetLineCount(theEnv); }

#if (! RUN_TIME) && (! BLOAD_ONLY)

   /*========================================================================*/
   /* If this is the first batch file, remember the prior parsing file name. */
   /*========================================================================*/

   if (FileCommandData(theEnv)->TopOfBatchList == NULL)
     { FileCommandData(theEnv)->batchPriorParsingFile = CopyString(theEnv,GetParsingFileName(theEnv)); }

   /*=======================================================*/
   /* Create the error capture router if it does not exist. */
   /*=======================================================*/

   SetParsingFileName(theEnv,fileName);
   SetLineCount(theEnv,0);

   CreateErrorCaptureRouter(theEnv);
#endif

   /*====================================*/
   /* Add the newly opened batch file to */
   /* the list of batch files opened.    */
   /*====================================*/

   AddBatch(theEnv,placeAtEnd,theFile,NULL,FILE_BATCH,NULL,fileName);

   /*===================================*/
   /* Return true to indicate the batch */
   /* file was successfully opened.     */
   /*===================================*/

   return true;
  }
コード例 #11
0
ファイル: factcom.c プロジェクト: DrItanium/DROID-CLIPS
globle intBool EnvSaveFacts(
  void *theEnv,
  char *fileName,
  int saveCode,
  struct expr *theList)
  {
   int tempValue1, tempValue2, tempValue3;
   struct fact *theFact;
   FILE *filePtr;
   struct defmodule *theModule;
   DATA_OBJECT_PTR theDOArray;
   int count, i, printFact, error;

   /*======================================================*/
   /* Open the file. Use either "fast save" or I/O Router. */
   /*======================================================*/

   if ((filePtr = GenOpen(theEnv,fileName,(char*)"w")) == NULL)
     {
      OpenErrorMessage(theEnv,(char*)"save-facts",fileName);
      return(FALSE);
     }

   SetFastSave(theEnv,filePtr);

   /*===========================================*/
   /* Set the print flags so that addresses and */
   /* strings are printed properly to the file. */
   /*===========================================*/

   tempValue1 = PrintUtilityData(theEnv)->PreserveEscapedCharacters;
   PrintUtilityData(theEnv)->PreserveEscapedCharacters = TRUE;
   tempValue2 = PrintUtilityData(theEnv)->AddressesToStrings;
   PrintUtilityData(theEnv)->AddressesToStrings = TRUE;
   tempValue3 = PrintUtilityData(theEnv)->InstanceAddressesToNames;
   PrintUtilityData(theEnv)->InstanceAddressesToNames = TRUE;

   /*===================================================*/
   /* Determine the list of specific facts to be saved. */
   /*===================================================*/

   theDOArray = GetSaveFactsDeftemplateNames(theEnv,theList,saveCode,&count,&error);

   if (error)
     {
      PrintUtilityData(theEnv)->PreserveEscapedCharacters = tempValue1;
      PrintUtilityData(theEnv)->AddressesToStrings = tempValue2;
      PrintUtilityData(theEnv)->InstanceAddressesToNames = tempValue3;
      GenClose(theEnv,filePtr);
      SetFastSave(theEnv,NULL);
      return(FALSE);
     }

   /*=================*/
   /* Save the facts. */
   /*=================*/

   theModule = ((struct defmodule *) EnvGetCurrentModule(theEnv));

   for (theFact = (struct fact *) GetNextFactInScope(theEnv,NULL);
        theFact != NULL;
        theFact = (struct fact *) GetNextFactInScope(theEnv,theFact))
     {
      /*===========================================================*/
      /* If we're doing a local save and the facts's corresponding */
      /* deftemplate isn't in the current module, then don't save  */
      /* the fact.                                                 */
      /*===========================================================*/

      if ((saveCode == LOCAL_SAVE) &&
          (theFact->whichDeftemplate->header.whichModule->theModule != theModule))
        { printFact = FALSE; }

      /*=====================================================*/
      /* Otherwise, if the list of facts to be printed isn't */
      /* restricted, then set the print flag to TRUE.        */
      /*=====================================================*/

      else if (theList == NULL)
        { printFact = TRUE; }

      /*=======================================================*/
      /* Otherwise see if the fact's corresponding deftemplate */
      /* is in the list of deftemplates whose facts are to be  */
      /* saved. If it's in the list, then set the print flag   */
      /* to TRUE, otherwise set it to FALSE.                   */
      /*=======================================================*/

      else
        {
         printFact = FALSE;
         for (i = 0; i < count; i++)
           {
            if (theDOArray[i].value == (void *) theFact->whichDeftemplate)
              {
               printFact = TRUE;
               break;
              }
           }
        }

      /*===================================*/
      /* If the print flag is set to TRUE, */
      /* then save the fact to the file.   */
      /*===================================*/

      if (printFact)
        {
         PrintFact(theEnv,(char *) filePtr,theFact,FALSE,FALSE);
         EnvPrintRouter(theEnv,(char *) filePtr,(char*)"\n");
        }
     }

   /*==========================*/
   /* Restore the print flags. */
   /*==========================*/

   PrintUtilityData(theEnv)->PreserveEscapedCharacters = tempValue1;
   PrintUtilityData(theEnv)->AddressesToStrings = tempValue2;
   PrintUtilityData(theEnv)->InstanceAddressesToNames = tempValue3;

   /*=================*/
   /* Close the file. */
   /*=================*/

   GenClose(theEnv,filePtr);
   SetFastSave(theEnv,NULL);

   /*==================================*/
   /* Free the deftemplate name array. */
   /*==================================*/

   if (theList != NULL) rm3(theEnv,theDOArray,(long) sizeof(DATA_OBJECT) * count);

   /*===================================*/
   /* Return TRUE to indicate no errors */
   /* occurred while saving the facts.  */
   /*===================================*/

   return(TRUE);
  }
コード例 #12
0
ファイル: filecom.c プロジェクト: ricksladkey/CLIPS
globle int EnvBatchStar(
  void *theEnv,
  char *fileName)
  {
   int inchar;
   FILE *theFile;
   char *theString = NULL;
   size_t position = 0;
   size_t maxChars = 0;

   /*======================*/
   /* Open the batch file. */
   /*======================*/

   theFile = GenOpen(theEnv,fileName,"r");

   if (theFile == NULL)
     {
      OpenErrorMessage(theEnv,"batch",fileName);
      return(FALSE);
     }

   /*========================*/
   /* Reset the error state. */
   /*========================*/

   SetHaltExecution(theEnv,FALSE);
   SetEvaluationError(theEnv,FALSE);

   /*=============================================*/
   /* Evaluate commands from the file one by one. */
   /*=============================================*/

   while ((inchar = getc(theFile)) != EOF)
     {
      theString = ExpandStringWithChar(theEnv,inchar,theString,&position,
                                       &maxChars,maxChars+80);

      if (CompleteCommand(theString) != 0)
        {
         FlushPPBuffer(theEnv);
         SetPPBufferStatus(theEnv,OFF);
         RouteCommand(theEnv,theString,FALSE);
         FlushPPBuffer(theEnv);
         SetHaltExecution(theEnv,FALSE);
         SetEvaluationError(theEnv,FALSE);
         FlushBindList(theEnv);      
         genfree(theEnv,theString,(unsigned) maxChars);
         theString = NULL;
         maxChars = 0;
         position = 0;
        }      
     }

   if (theString != NULL)
     { genfree(theEnv,theString,(unsigned) maxChars); }
     
   /*=======================*/
   /* Close the batch file. */
   /*=======================*/

   GenClose(theEnv,theFile);
   return(TRUE);
  }
コード例 #13
0
ファイル: constrct.c プロジェクト: DrItanium/maya
bool Save(
  Environment *theEnv,
  const char *fileName)
  {
   struct saveCallFunctionItem *saveFunction;
   FILE *filePtr;
   Defmodule *defmodulePtr;
   bool updated = false;
   bool unvisited = true;

   /*=====================================*/
   /* If embedded, clear the error flags. */
   /*=====================================*/
   
   if (EvaluationData(theEnv)->CurrentExpression == NULL)
     { ResetErrorFlags(theEnv); }

   /*=====================*/
   /* Open the save file. */
   /*=====================*/

   if ((filePtr = GenOpen(theEnv,fileName,"w")) == NULL)
     { return false; }

   /*===========================*/
   /* Bypass the router system. */
   /*===========================*/

   SetFastSave(theEnv,filePtr);

   /*================================*/
   /* Mark all modules as unvisited. */
   /*================================*/

   MarkModulesAsUnvisited(theEnv);

   /*===============================================*/
   /* Save the constructs. Repeatedly loop over the */
   /* modules until each module has been save.      */
   /*===============================================*/

   while (unvisited)
     {
      unvisited = false;
      updated = false;

      for (defmodulePtr = GetNextDefmodule(theEnv,NULL);
           defmodulePtr != NULL;
           defmodulePtr = GetNextDefmodule(theEnv,defmodulePtr))
        {
         /*=================================================================*/
         /* We only want to save a module if all of the modules it imports  */
         /* from have already been saved. Since there can't be circular     */
         /* dependencies in imported modules, this should save the modules  */
         /* that don't import anything first and then work back from those. */
         /*=================================================================*/

         if (defmodulePtr->visitedFlag)
           { /* Module has already been saved. */ }
         else if (AllImportedModulesVisited(theEnv,defmodulePtr))
           {
            for (saveFunction = ConstructData(theEnv)->ListOfSaveFunctions;
                 saveFunction != NULL;
                 saveFunction = saveFunction->next)
              { (*saveFunction->func)(theEnv,defmodulePtr,(char *) filePtr,saveFunction->context); }

            updated = true;
            defmodulePtr->visitedFlag = true;
           }
         else
           { unvisited = true; }
        }

      /*=====================================================================*/
      /* At least one module should be saved in every pass. If all have been */
      /* visited/saved, then both flags will be false. If all remaining      */
      /* unvisited/unsaved modules were visited/saved, then unvisited will   */
      /* be false and updated will be true. If some, but not all, remaining  */
      /* unvisited/unsaved modules are visited/saved, then  unvisited will   */
      /* be true and updated will be true. This leaves the case where there  */
      /* are remaining unvisited/unsaved modules, but none were              */
      /* visited/saved: unvisited is true and updated is false.              */
      /*=====================================================================*/

      if (unvisited && (! updated))
        {
         SystemError(theEnv,"CONSTRCT",2);
         break;
        }
     }

   /*======================*/
   /* Close the save file. */
   /*======================*/

   GenClose(theEnv,filePtr);

   /*===========================*/
   /* Remove the router bypass. */
   /*===========================*/

   SetFastSave(theEnv,NULL);

   /*=========================*/
   /* Return true to indicate */
   /* successful completion.  */
   /*=========================*/

   return true;
  }
コード例 #14
0
ファイル: bsave.c プロジェクト: zlongshen/CLIPS
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);
}