00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define _BSAVE_SOURCE_
00029
00030 #include "setup.h"
00031
00032 #include "argacces.h"
00033 #include "bload.h"
00034 #include "cstrnbin.h"
00035 #include "envrnmnt.h"
00036 #include "exprnpsr.h"
00037 #include "memalloc.h"
00038 #include "moduldef.h"
00039 #include "router.h"
00040 #include "symblbin.h"
00041
00042 #include "bsave.h"
00043
00044
00045
00046
00047
00048 #if BLOAD_AND_BSAVE
00049 static void FindNeededItems(void *);
00050 static void InitializeFunctionNeededFlags(void *);
00051 static void WriteNeededFunctions(void *,FILE *);
00052 static size_t FunctionBinarySize(void *);
00053 static void WriteBinaryHeader(void *,FILE *);
00054 static void WriteBinaryFooter(void *,FILE *);
00055 #endif
00056 static void DeallocateBsaveData(void *);
00057
00058
00059
00060
00061
00062 globle void InitializeBsaveData(
00063 void *theEnv)
00064 {
00065 AllocateEnvironmentData(theEnv,BSAVE_DATA,sizeof(struct bsaveData),DeallocateBsaveData);
00066 }
00067
00068
00069
00070
00071
00072 static void DeallocateBsaveData(
00073 void *theEnv)
00074 {
00075 struct BinaryItem *tmpPtr, *nextPtr;
00076
00077 tmpPtr = BsaveData(theEnv)->ListOfBinaryItems;
00078 while (tmpPtr != NULL)
00079 {
00080 nextPtr = tmpPtr->next;
00081 rtn_struct(theEnv,BinaryItem,tmpPtr);
00082 tmpPtr = nextPtr;
00083 }
00084 }
00085
00086
00087
00088
00089
00090 globle int BsaveCommand(
00091 void *theEnv)
00092 {
00093 #if (! RUN_TIME) && BLOAD_AND_BSAVE
00094 char *fileName;
00095
00096 if (EnvArgCountCheck(theEnv,"bsave",EXACTLY,1) == -1) return(FALSE);
00097 fileName = GetFileName(theEnv,"bsave",1);
00098 if (fileName != NULL)
00099 { if (EnvBsave(theEnv,fileName)) return(TRUE); }
00100 #else
00101 #if MAC_MCW || WIN_MCW || MAC_XCD
00102 #pragma unused(theEnv)
00103 #endif
00104 #endif
00105 return(FALSE);
00106 }
00107
00108 #if BLOAD_AND_BSAVE
00109
00110
00111
00112
00113
00114 globle intBool EnvBsave(
00115 void *theEnv,
00116 char *fileName)
00117 {
00118 FILE *fp;
00119 struct BinaryItem *biPtr;
00120 char constructBuffer[CONSTRUCT_HEADER_SIZE];
00121 long saveExpressionCount;
00122
00123
00124
00125
00126
00127
00128 if (Bloaded(theEnv))
00129 {
00130 PrintErrorID(theEnv,"BSAVE",1,FALSE);
00131 EnvPrintRouter(theEnv,WERROR,
00132 "Cannot perform a binary save while a binary load is in effect.\n");
00133 return(0);
00134 }
00135
00136
00137
00138
00139
00140 if ((fp = GenOpen(theEnv,fileName,"wb")) == NULL)
00141 {
00142 OpenErrorMessage(theEnv,"bsave",fileName);
00143 return(0);
00144 }
00145
00146
00147
00148
00149
00150 SaveCurrentModule(theEnv);
00151
00152
00153
00154
00155
00156 WriteBinaryHeader(theEnv,fp);
00157
00158
00159
00160
00161
00162
00163
00164 ExpressionData(theEnv)->ExpressionCount = 0;
00165 InitializeFunctionNeededFlags(theEnv);
00166 InitAtomicValueNeededFlags(theEnv);
00167 FindHashedExpressions(theEnv);
00168 FindNeededItems(theEnv);
00169 SetAtomicValueIndices(theEnv,FALSE);
00170
00171
00172
00173
00174
00175 WriteNeededFunctions(theEnv,fp);
00176 WriteNeededAtomicValues(theEnv,fp);
00177
00178
00179
00180
00181
00182
00183 GenWrite((void *) &ExpressionData(theEnv)->ExpressionCount,(unsigned long) sizeof(unsigned long),fp);
00184
00185
00186
00187
00188
00189
00190 for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
00191 biPtr != NULL;
00192 biPtr = biPtr->next)
00193 {
00194 if (biPtr->bsaveStorageFunction != NULL)
00195 {
00196 genstrncpy(constructBuffer,biPtr->name,CONSTRUCT_HEADER_SIZE);
00197 GenWrite(constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp);
00198 (*biPtr->bsaveStorageFunction)(theEnv,fp);
00199 }
00200 }
00201
00202
00203
00204
00205
00206 WriteBinaryFooter(theEnv,fp);
00207
00208
00209
00210
00211
00212 ExpressionData(theEnv)->ExpressionCount = 0;
00213 BsaveHashedExpressions(theEnv,fp);
00214 saveExpressionCount = ExpressionData(theEnv)->ExpressionCount;
00215 BsaveConstructExpressions(theEnv,fp);
00216 ExpressionData(theEnv)->ExpressionCount = saveExpressionCount;
00217
00218
00219
00220
00221
00222 WriteNeededConstraints(theEnv,fp);
00223
00224
00225
00226
00227
00228 for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
00229 biPtr != NULL;
00230 biPtr = biPtr->next)
00231 {
00232 if (biPtr->bsaveFunction != NULL)
00233 {
00234 genstrncpy(constructBuffer,biPtr->name,CONSTRUCT_HEADER_SIZE);
00235 GenWrite(constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp);
00236 (*biPtr->bsaveFunction)(theEnv,fp);
00237 }
00238 }
00239
00240
00241
00242
00243
00244 WriteBinaryFooter(theEnv,fp);
00245
00246
00247
00248
00249
00250 RestoreAtomicValueBuckets(theEnv);
00251
00252
00253
00254
00255
00256 GenClose(theEnv,fp);
00257
00258
00259
00260
00261
00262 RestoreCurrentModule(theEnv);
00263
00264
00265
00266
00267
00268 return(TRUE);
00269 }
00270
00271
00272
00273
00274
00275
00276 static void InitializeFunctionNeededFlags(
00277 void *theEnv)
00278 {
00279 struct FunctionDefinition *functionList;
00280
00281 for (functionList = GetFunctionList(theEnv);
00282 functionList != NULL;
00283 functionList = functionList->next)
00284 { functionList->bsaveIndex = 0; }
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 static void FindNeededItems(
00294 void *theEnv)
00295 {
00296 struct BinaryItem *biPtr;
00297
00298 for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
00299 biPtr != NULL;
00300 biPtr = biPtr->next)
00301 { if (biPtr->findFunction != NULL) (*biPtr->findFunction)(theEnv); }
00302 }
00303
00304
00305
00306
00307
00308 static void WriteNeededFunctions(
00309 void *theEnv,
00310 FILE *fp)
00311 {
00312 unsigned long int count = 0;
00313 size_t space, length;
00314 struct FunctionDefinition *functionList;
00315
00316
00317
00318
00319
00320 for (functionList = GetFunctionList(theEnv);
00321 functionList != NULL;
00322 functionList = functionList->next)
00323 {
00324 if (functionList->bsaveIndex)
00325 { functionList->bsaveIndex = (short int) count++; }
00326 else
00327 { functionList->bsaveIndex = -1; }
00328 }
00329
00330
00331
00332
00333
00334 GenWrite(&count,(unsigned long) sizeof(unsigned long int),fp);
00335 if (count == 0)
00336 {
00337 GenWrite(&count,(unsigned long) sizeof(unsigned long int),fp);
00338 return;
00339 }
00340
00341
00342
00343
00344
00345
00346 space = FunctionBinarySize(theEnv);
00347 GenWrite(&space,(unsigned long) sizeof(unsigned long int),fp);
00348
00349
00350
00351
00352
00353 for (functionList = GetFunctionList(theEnv);
00354 functionList != NULL;
00355 functionList = functionList->next)
00356 {
00357 if (functionList->bsaveIndex >= 0)
00358 {
00359 length = strlen(ValueToString(functionList->callFunctionName)) + 1;
00360 GenWrite(ValueToString(functionList->callFunctionName),(unsigned long) length,fp);
00361 }
00362 }
00363 }
00364
00365
00366
00367
00368
00369
00370 static size_t FunctionBinarySize(
00371 void *theEnv)
00372 {
00373 size_t size = 0;
00374 struct FunctionDefinition *functionList;
00375
00376 for (functionList = GetFunctionList(theEnv);
00377 functionList != NULL;
00378 functionList = functionList->next)
00379 {
00380 if (functionList->bsaveIndex >= 0)
00381 { size += strlen(ValueToString(functionList->callFunctionName)) + 1; }
00382 }
00383
00384 return(size);
00385 }
00386
00387
00388
00389
00390
00391
00392 globle void SaveBloadCount(
00393 void *theEnv,
00394 long cnt)
00395 {
00396 BLOADCNTSV *tmp, *prv;
00397
00398 tmp = get_struct(theEnv,bloadcntsv);
00399 tmp->val = cnt;
00400 tmp->nxt = NULL;
00401
00402 if (BsaveData(theEnv)->BloadCountSaveTop == NULL)
00403 { BsaveData(theEnv)->BloadCountSaveTop = tmp; }
00404 else
00405 {
00406 prv = BsaveData(theEnv)->BloadCountSaveTop;
00407 while (prv->nxt != NULL)
00408 { prv = prv->nxt; }
00409 prv->nxt = tmp;
00410 }
00411 }
00412
00413
00414
00415
00416
00417
00418 globle void RestoreBloadCount(
00419 void *theEnv,
00420 long *cnt)
00421 {
00422 BLOADCNTSV *tmp;
00423
00424 *cnt = BsaveData(theEnv)->BloadCountSaveTop->val;
00425 tmp = BsaveData(theEnv)->BloadCountSaveTop;
00426 BsaveData(theEnv)->BloadCountSaveTop = BsaveData(theEnv)->BloadCountSaveTop->nxt;
00427 rtn_struct(theEnv,bloadcntsv,tmp);
00428 }
00429
00430
00431
00432
00433
00434
00435 globle void MarkNeededItems(
00436 void *theEnv,
00437 struct expr *testPtr)
00438 {
00439 while (testPtr != NULL)
00440 {
00441 switch (testPtr->type)
00442 {
00443 case SYMBOL:
00444 case STRING:
00445 case GBL_VARIABLE:
00446 case INSTANCE_NAME:
00447 ((SYMBOL_HN *) testPtr->value)->neededSymbol = TRUE;
00448 break;
00449
00450 case FLOAT:
00451 ((FLOAT_HN *) testPtr->value)->neededFloat = TRUE;
00452 break;
00453
00454 case INTEGER:
00455 ((INTEGER_HN *) testPtr->value)->neededInteger = TRUE;
00456 break;
00457
00458 case FCALL:
00459 ((struct FunctionDefinition *) testPtr->value)->bsaveIndex = TRUE;
00460 break;
00461
00462 case RVOID:
00463 break;
00464
00465 default:
00466 if (EvaluationData(theEnv)->PrimitivesArray[testPtr->type] == NULL) break;
00467 if (EvaluationData(theEnv)->PrimitivesArray[testPtr->type]->bitMap)
00468 { ((BITMAP_HN *) testPtr->value)->neededBitMap = TRUE; }
00469 break;
00470
00471 }
00472
00473 if (testPtr->argList != NULL)
00474 { MarkNeededItems(theEnv,testPtr->argList); }
00475
00476 testPtr = testPtr->nextArg;
00477 }
00478 }
00479
00480
00481
00482
00483
00484 static void WriteBinaryHeader(
00485 void *theEnv,
00486 FILE *fp)
00487 {
00488 GenWrite(BloadData(theEnv)->BinaryPrefixID,(unsigned long) strlen(BloadData(theEnv)->BinaryPrefixID) + 1,fp);
00489 GenWrite(BloadData(theEnv)->BinaryVersionID,(unsigned long) strlen(BloadData(theEnv)->BinaryVersionID) + 1,fp);
00490 }
00491
00492
00493
00494
00495
00496 static void WriteBinaryFooter(
00497 void *theEnv,
00498 FILE *fp)
00499 {
00500 char footerBuffer[CONSTRUCT_HEADER_SIZE];
00501
00502 genstrncpy(footerBuffer,BloadData(theEnv)->BinaryPrefixID,CONSTRUCT_HEADER_SIZE);
00503 GenWrite(footerBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp);
00504 }
00505
00506 #endif
00507
00508 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
00509
00510
00511
00512
00513
00514
00515
00516 globle intBool AddBinaryItem(
00517 void *theEnv,
00518 char *name,
00519 int priority,
00520 void (*findFunction)(void *),
00521 void (*expressionFunction)(void *,FILE *),
00522 void (*bsaveStorageFunction)(void *,FILE *),
00523 void (*bsaveFunction)(void *,FILE *),
00524 void (*bloadStorageFunction)(void *),
00525 void (*bloadFunction)(void *),
00526 void (*clearFunction)(void *))
00527 {
00528 struct BinaryItem *newPtr, *currentPtr, *lastPtr = NULL;
00529
00530
00531
00532
00533
00534 newPtr = get_struct(theEnv,BinaryItem);
00535
00536 newPtr->name = name;
00537 newPtr->findFunction = findFunction;
00538 newPtr->expressionFunction = expressionFunction;
00539 newPtr->bsaveStorageFunction = bsaveStorageFunction;
00540 newPtr->bsaveFunction = bsaveFunction;
00541 newPtr->bloadStorageFunction = bloadStorageFunction;
00542 newPtr->bloadFunction = bloadFunction;
00543 newPtr->clearFunction = clearFunction;
00544 newPtr->priority = priority;
00545
00546
00547
00548
00549
00550
00551 if (BsaveData(theEnv)->ListOfBinaryItems == NULL)
00552 {
00553 newPtr->next = NULL;
00554 BsaveData(theEnv)->ListOfBinaryItems = newPtr;
00555 return(TRUE);
00556 }
00557
00558
00559
00560
00561
00562
00563
00564 currentPtr = BsaveData(theEnv)->ListOfBinaryItems;
00565 while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE)
00566 {
00567 lastPtr = currentPtr;
00568 currentPtr = currentPtr->next;
00569 }
00570
00571 if (lastPtr == NULL)
00572 {
00573 newPtr->next = BsaveData(theEnv)->ListOfBinaryItems;
00574 BsaveData(theEnv)->ListOfBinaryItems = newPtr;
00575 }
00576 else
00577 {
00578 newPtr->next = currentPtr;
00579 lastPtr->next = newPtr;
00580 }
00581
00582
00583
00584
00585
00586
00587 return(TRUE);
00588 }
00589
00590 #endif
00591
00592
00593
00594
00595