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
00029
00030
00031
00032 #include <stdlib.h>
00033
00034 #include "setup.h"
00035
00036 #if OBJECT_SYSTEM
00037
00038 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
00039 #include "bload.h"
00040 #endif
00041
00042 #include "classcom.h"
00043 #include "classini.h"
00044 #include "constant.h"
00045 #include "constrct.h"
00046 #include "cstrccom.h"
00047 #include "cstrcpsr.h"
00048 #include "envrnmnt.h"
00049 #include "evaluatn.h"
00050 #include "inscom.h"
00051 #include "insfun.h"
00052 #include "insmngr.h"
00053 #include "memalloc.h"
00054 #include "modulutl.h"
00055 #include "msgfun.h"
00056 #include "router.h"
00057 #include "scanner.h"
00058 #include "utility.h"
00059
00060 #define _CLASSFUN_SOURCE_
00061 #include "classfun.h"
00062
00063
00064
00065
00066
00067
00068 #define BIG_PRIME 11329
00069
00070 #define CLASS_ID_MAP_CHUNK 30
00071
00072 #define PUT_PREFIX "put-"
00073 #define PUT_PREFIX_LENGTH 4
00074
00075
00076
00077
00078
00079
00080
00081 static unsigned HashSlotName(SYMBOL_HN *);
00082
00083 #if (! RUN_TIME)
00084 static int NewSlotNameID(void *);
00085 static void DeassignClassID(void *,unsigned);
00086 #endif
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #if WIN_BTC
00103 #pragma argsused
00104 #endif
00105 globle void IncrementDefclassBusyCount(
00106 void *theEnv,
00107 void *theDefclass)
00108 {
00109 #if MAC_MCW || WIN_MCW || MAC_XCD
00110 #pragma unused(theEnv)
00111 #endif
00112
00113 ((DEFCLASS *) theDefclass)->busy++;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 globle void DecrementDefclassBusyCount(
00128 void *theEnv,
00129 void *theDefclass)
00130 {
00131 if (! ConstructData(theEnv)->ClearInProgress)
00132 ((DEFCLASS *) theDefclass)->busy--;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 globle intBool InstancesPurge(
00145 void *theEnv)
00146 {
00147 int svdepth;
00148
00149 DestroyAllInstances(theEnv);
00150 svdepth = EvaluationData(theEnv)->CurrentEvaluationDepth;
00151 if (EvaluationData(theEnv)->CurrentEvaluationDepth == 0)
00152 EvaluationData(theEnv)->CurrentEvaluationDepth = -1;
00153 CleanupInstances(theEnv);
00154 EvaluationData(theEnv)->CurrentEvaluationDepth = svdepth;
00155 return((InstanceData(theEnv)->InstanceList != NULL) ? FALSE : TRUE);
00156 }
00157
00158 #if ! RUN_TIME
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 globle void InitializeClasses(
00172 void *theEnv)
00173 {
00174 register int i;
00175
00176 DefclassData(theEnv)->ClassTable =
00177 (DEFCLASS **) gm2(theEnv,(int) (sizeof(DEFCLASS *) * CLASS_TABLE_HASH_SIZE));
00178 for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)
00179 DefclassData(theEnv)->ClassTable[i] = NULL;
00180 DefclassData(theEnv)->SlotNameTable =
00181 (SLOT_NAME **) gm2(theEnv,(int) (sizeof(SLOT_NAME *) * SLOT_NAME_TABLE_HASH_SIZE));
00182 for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)
00183 DefclassData(theEnv)->SlotNameTable[i] = NULL;
00184 }
00185
00186 #endif
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 globle SLOT_DESC *FindClassSlot(
00199 DEFCLASS *cls,
00200 SYMBOL_HN *sname)
00201 {
00202 long i;
00203
00204 for (i = 0 ; i < cls->slotCount ; i++)
00205 {
00206 if (cls->slots[i].slotName->name == sname)
00207 return(&cls->slots[i]);
00208 }
00209 return(NULL);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 globle void ClassExistError(
00222 void *theEnv,
00223 char *func,
00224 char *cname)
00225 {
00226 PrintErrorID(theEnv,"CLASSFUN",1,FALSE);
00227 EnvPrintRouter(theEnv,WERROR,"Unable to find class ");
00228 EnvPrintRouter(theEnv,WERROR,cname);
00229 EnvPrintRouter(theEnv,WERROR," in function ");
00230 EnvPrintRouter(theEnv,WERROR,func);
00231 EnvPrintRouter(theEnv,WERROR,".\n");
00232 SetEvaluationError(theEnv,TRUE);
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 globle void DeleteClassLinks(
00244 void *theEnv,
00245 CLASS_LINK *clink)
00246 {
00247 CLASS_LINK *ctmp;
00248
00249 for (ctmp = clink ; ctmp != NULL ; ctmp = clink)
00250 {
00251 clink = clink->nxt;
00252 rtn_struct(theEnv,classLink,ctmp);
00253 }
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 globle void PrintClassName(
00269 void *theEnv,
00270 char *logicalName,
00271 DEFCLASS *theDefclass,
00272 intBool linefeedFlag)
00273 {
00274 if ((theDefclass->header.whichModule->theModule != ((struct defmodule *) EnvGetCurrentModule(theEnv))) &&
00275 (theDefclass->system == 0))
00276 {
00277 EnvPrintRouter(theEnv,logicalName,
00278 EnvGetDefmoduleName(theEnv,theDefclass->header.whichModule->theModule));
00279 EnvPrintRouter(theEnv,logicalName,"::");
00280 }
00281 EnvPrintRouter(theEnv,logicalName,ValueToString(theDefclass->header.name));
00282 if (linefeedFlag)
00283 EnvPrintRouter(theEnv,logicalName,"\n");
00284 }
00285
00286 #if DEBUGGING_FUNCTIONS || ((! BLOAD_ONLY) && (! RUN_TIME))
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 globle void PrintPackedClassLinks(
00300 void *theEnv,
00301 char *logicalName,
00302 char *title,
00303 PACKED_CLASS_LINKS *plinks)
00304 {
00305 long i;
00306
00307 EnvPrintRouter(theEnv,logicalName,title);
00308 for (i = 0 ; i < plinks->classCount ; i++)
00309 {
00310 EnvPrintRouter(theEnv,logicalName," ");
00311 PrintClassName(theEnv,logicalName,plinks->classArray[i],FALSE);
00312 }
00313 EnvPrintRouter(theEnv,logicalName,"\n");
00314 }
00315
00316 #endif
00317
00318 #if ! RUN_TIME
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 globle void PutClassInTable(
00329 void *theEnv,
00330 DEFCLASS *cls)
00331 {
00332 cls->hashTableIndex = HashClass(GetDefclassNamePointer((void *) cls));
00333 cls->nxtHash = DefclassData(theEnv)->ClassTable[cls->hashTableIndex];
00334 DefclassData(theEnv)->ClassTable[cls->hashTableIndex] = cls;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 globle void RemoveClassFromTable(
00346 void *theEnv,
00347 DEFCLASS *cls)
00348 {
00349 DEFCLASS *prvhsh,*hshptr;
00350
00351 prvhsh = NULL;
00352 hshptr = DefclassData(theEnv)->ClassTable[cls->hashTableIndex];
00353 while (hshptr != cls)
00354 {
00355 prvhsh = hshptr;
00356 hshptr = hshptr->nxtHash;
00357 }
00358 if (prvhsh == NULL)
00359 DefclassData(theEnv)->ClassTable[cls->hashTableIndex] = cls->nxtHash;
00360 else
00361 prvhsh->nxtHash = cls->nxtHash;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 globle void AddClassLink(
00380 void *theEnv,
00381 PACKED_CLASS_LINKS *src,
00382 DEFCLASS *cls,
00383 int posn)
00384 {
00385 PACKED_CLASS_LINKS dst;
00386
00387 dst.classArray = (DEFCLASS **) gm2(theEnv,(sizeof(DEFCLASS *) * (src->classCount + 1)));
00388
00389 if (posn == -1)
00390 {
00391 GenCopyMemory(DEFCLASS *,src->classCount,dst.classArray,src->classArray);
00392 dst.classArray[src->classCount] = cls;
00393 }
00394 else
00395 {
00396 if (posn != 0)
00397 GenCopyMemory(DEFCLASS *,posn,dst.classArray,src->classArray);
00398 GenCopyMemory(DEFCLASS *,src->classCount - posn,
00399 dst.classArray + posn + 1,src->classArray + posn);
00400 dst.classArray[posn] = cls;
00401 }
00402 dst.classCount = (unsigned short) (src->classCount + 1);
00403 DeletePackedClassLinks(theEnv,src,FALSE);
00404 src->classCount = dst.classCount;
00405 src->classArray = dst.classArray;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 globle void DeleteSubclassLink(
00420 void *theEnv,
00421 DEFCLASS *sclass,
00422 DEFCLASS *cls)
00423 {
00424 long deletedIndex;
00425 PACKED_CLASS_LINKS *src,dst;
00426
00427 src = &sclass->directSubclasses;
00428 for (deletedIndex = 0 ; deletedIndex < src->classCount ; deletedIndex++)
00429 if (src->classArray[deletedIndex] == cls)
00430 break;
00431 if (deletedIndex == src->classCount)
00432 return;
00433 if (src->classCount > 1)
00434 {
00435 dst.classArray = (DEFCLASS **) gm2(theEnv,(sizeof(DEFCLASS *) * (src->classCount - 1)));
00436 if (deletedIndex != 0)
00437 GenCopyMemory(DEFCLASS *,deletedIndex,dst.classArray,src->classArray);
00438 GenCopyMemory(DEFCLASS *,src->classCount - deletedIndex - 1,
00439 dst.classArray + deletedIndex,src->classArray + deletedIndex + 1);
00440 }
00441 else
00442 dst.classArray = NULL;
00443 dst.classCount = (unsigned short) (src->classCount - 1);
00444 DeletePackedClassLinks(theEnv,src,FALSE);
00445 src->classCount = dst.classCount;
00446 src->classArray = dst.classArray;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 globle DEFCLASS *NewClass(
00458 void *theEnv,
00459 SYMBOL_HN *className)
00460 {
00461 register DEFCLASS *cls;
00462
00463 cls = get_struct(theEnv,defclass);
00464 InitializeConstructHeader(theEnv,"defclass",(struct constructHeader *) cls,className);
00465
00466 cls->id = 0;
00467 cls->installed = 0;
00468 cls->busy = 0;
00469 cls->system = 0;
00470 cls->abstract = 0;
00471 cls->reactive = 1;
00472 #if DEBUGGING_FUNCTIONS
00473 cls->traceInstances = DefclassData(theEnv)->WatchInstances;
00474 cls->traceSlots = DefclassData(theEnv)->WatchSlots;
00475 #endif
00476 cls->hashTableIndex = 0;
00477 cls->directSuperclasses.classCount = 0;
00478 cls->directSuperclasses.classArray = NULL;
00479 cls->directSubclasses.classCount = 0;
00480 cls->directSubclasses.classArray = NULL;
00481 cls->allSuperclasses.classCount = 0;
00482 cls->allSuperclasses.classArray = NULL;
00483 cls->slots = NULL;
00484 cls->instanceTemplate = NULL;
00485 cls->slotNameMap = NULL;
00486 cls->instanceSlotCount = 0;
00487 cls->localInstanceSlotCount = 0;
00488 cls->slotCount = 0;
00489 cls->maxSlotNameID = 0;
00490 cls->handlers = NULL;
00491 cls->handlerOrderMap = NULL;
00492 cls->handlerCount = 0;
00493 cls->instanceList = NULL;
00494 cls->instanceListBottom = NULL;
00495 cls->nxtHash = NULL;
00496 cls->scopeMap = NULL;
00497 ClearBitString(cls->traversalRecord,TRAVERSAL_BYTES);
00498 return(cls);
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 globle void DeletePackedClassLinks(
00513 void *theEnv,
00514 PACKED_CLASS_LINKS *plp,
00515 int deleteTop)
00516 {
00517 if (plp->classCount > 0)
00518 {
00519 rm(theEnv,(void *) plp->classArray,(sizeof(DEFCLASS *) * plp->classCount));
00520 plp->classCount = 0;
00521 plp->classArray = NULL;
00522 }
00523 if (deleteTop)
00524 rtn_struct(theEnv,packedClassLinks,plp);
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 globle void AssignClassID(
00538 void *theEnv,
00539 DEFCLASS *cls)
00540 {
00541 register unsigned i;
00542
00543 if ((DefclassData(theEnv)->MaxClassID % CLASS_ID_MAP_CHUNK) == 0)
00544 {
00545 DefclassData(theEnv)->ClassIDMap = (DEFCLASS **) genrealloc(theEnv,(void *) DefclassData(theEnv)->ClassIDMap,
00546 (unsigned) (DefclassData(theEnv)->MaxClassID * sizeof(DEFCLASS *)),
00547 (unsigned) ((DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK) * sizeof(DEFCLASS *)));
00548 DefclassData(theEnv)->AvailClassID += (unsigned short) CLASS_ID_MAP_CHUNK;
00549
00550 for (i = DefclassData(theEnv)->MaxClassID ; i < (unsigned) (DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK) ; i++)
00551 DefclassData(theEnv)->ClassIDMap[i] = NULL;
00552 }
00553 DefclassData(theEnv)->ClassIDMap[DefclassData(theEnv)->MaxClassID] = cls;
00554 cls->id = DefclassData(theEnv)->MaxClassID++;
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 globle SLOT_NAME *AddSlotName(
00571 void *theEnv,
00572 SYMBOL_HN *slotName,
00573 int newid,
00574 int usenewid)
00575 {
00576 SLOT_NAME *snp;
00577 unsigned hashTableIndex;
00578 char *buf;
00579 size_t bufsz;
00580
00581 hashTableIndex = HashSlotName(slotName);
00582 snp = DefclassData(theEnv)->SlotNameTable[hashTableIndex];
00583 while ((snp != NULL) ? (snp->name != slotName) : FALSE)
00584 snp = snp->nxt;
00585 if (snp != NULL)
00586 {
00587 if (usenewid && (newid != snp->id))
00588 {
00589 SystemError(theEnv,"CLASSFUN",1);
00590 EnvExitRouter(theEnv,EXIT_FAILURE);
00591 }
00592 snp->use++;
00593 }
00594 else
00595 {
00596 snp = get_struct(theEnv,slotName);
00597 snp->name = slotName;
00598 snp->hashTableIndex = hashTableIndex;
00599 snp->use = 1;
00600 snp->id = (short) (usenewid ? newid : NewSlotNameID(theEnv));
00601 snp->nxt = DefclassData(theEnv)->SlotNameTable[hashTableIndex];
00602 DefclassData(theEnv)->SlotNameTable[hashTableIndex] = snp;
00603 IncrementSymbolCount(slotName);
00604 bufsz = (sizeof(char) *
00605 (PUT_PREFIX_LENGTH + strlen(ValueToString(slotName)) + 1));
00606 buf = (char *) gm2(theEnv,bufsz);
00607 genstrcpy(buf,PUT_PREFIX);
00608 genstrcat(buf,ValueToString(slotName));
00609 snp->putHandlerName = (SYMBOL_HN *) EnvAddSymbol(theEnv,buf);
00610 IncrementSymbolCount(snp->putHandlerName);
00611 rm(theEnv,(void *) buf,bufsz);
00612 snp->bsaveIndex = 0L;
00613 }
00614 return(snp);
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 globle void DeleteSlotName(
00629 void *theEnv,
00630 SLOT_NAME *slotName)
00631 {
00632 SLOT_NAME *snp,*prv;
00633
00634 if (slotName == NULL)
00635 return;
00636 prv = NULL;
00637 snp = DefclassData(theEnv)->SlotNameTable[slotName->hashTableIndex];
00638 while (snp != slotName)
00639 {
00640 prv = snp;
00641 snp = snp->nxt;
00642 }
00643 snp->use--;
00644 if (snp->use != 0)
00645 return;
00646 if (prv == NULL)
00647 DefclassData(theEnv)->SlotNameTable[snp->hashTableIndex] = snp->nxt;
00648 else
00649 prv->nxt = snp->nxt;
00650 DecrementSymbolCount(theEnv,snp->name);
00651 DecrementSymbolCount(theEnv,snp->putHandlerName);
00652 rtn_struct(theEnv,slotName,snp);
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 LOCALE void RemoveDefclass(
00670 void *theEnv,
00671 void *vcls)
00672 {
00673 DEFCLASS *cls = (DEFCLASS *) vcls;
00674 HANDLER *hnd;
00675 long i;
00676
00677
00678
00679
00680 for (i = 0 ; i < cls->directSuperclasses.classCount ; i++)
00681 DeleteSubclassLink(theEnv,cls->directSuperclasses.classArray[i],cls);
00682
00683 RemoveClassFromTable(theEnv,cls);
00684
00685 InstallClass(theEnv,cls,FALSE);
00686
00687 DeletePackedClassLinks(theEnv,&cls->directSuperclasses,FALSE);
00688 DeletePackedClassLinks(theEnv,&cls->allSuperclasses,FALSE);
00689 DeletePackedClassLinks(theEnv,&cls->directSubclasses,FALSE);
00690
00691 for (i = 0 ; i < cls->slotCount ; i++)
00692 {
00693 if (cls->slots[i].defaultValue != NULL)
00694 {
00695 if (cls->slots[i].dynamicDefault)
00696 ReturnPackedExpression(theEnv,(EXPRESSION *) cls->slots[i].defaultValue);
00697 else
00698 rtn_struct(theEnv,dataObject,cls->slots[i].defaultValue);
00699 }
00700 DeleteSlotName(theEnv,cls->slots[i].slotName);
00701 RemoveConstraint(theEnv,cls->slots[i].constraint);
00702 }
00703
00704 if (cls->instanceSlotCount != 0)
00705 {
00706 rm(theEnv,(void *) cls->instanceTemplate,
00707 (sizeof(SLOT_DESC *) * cls->instanceSlotCount));
00708 rm(theEnv,(void *) cls->slotNameMap,
00709 (sizeof(unsigned) * (cls->maxSlotNameID + 1)));
00710 }
00711 if (cls->slotCount != 0)
00712 rm(theEnv,(void *) cls->slots,(sizeof(SLOT_DESC) * cls->slotCount));
00713
00714 for (i = 0 ; i < cls->handlerCount ; i++)
00715 {
00716 hnd = &cls->handlers[i];
00717 if (hnd->actions != NULL)
00718 ReturnPackedExpression(theEnv,hnd->actions);
00719 if (hnd->ppForm != NULL)
00720 rm(theEnv,(void *) hnd->ppForm,(sizeof(char) * (strlen(hnd->ppForm)+1)));
00721 if (hnd->usrData != NULL)
00722 { ClearUserDataList(theEnv,hnd->usrData); }
00723 }
00724 if (cls->handlerCount != 0)
00725 {
00726 rm(theEnv,(void *) cls->handlers,(sizeof(HANDLER) * cls->handlerCount));
00727 rm(theEnv,(void *) cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount));
00728 }
00729
00730 SetDefclassPPForm((void *) cls,NULL);
00731 DeassignClassID(theEnv,(unsigned) cls->id);
00732 rtn_struct(theEnv,defclass,cls);
00733 }
00734
00735 #endif
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 LOCALE void DestroyDefclass(
00747 void *theEnv,
00748 void *vcls)
00749 {
00750 DEFCLASS *cls = (DEFCLASS *) vcls;
00751 long i;
00752 #if ! RUN_TIME
00753 HANDLER *hnd;
00754 DeletePackedClassLinks(theEnv,&cls->directSuperclasses,FALSE);
00755 DeletePackedClassLinks(theEnv,&cls->allSuperclasses,FALSE);
00756 DeletePackedClassLinks(theEnv,&cls->directSubclasses,FALSE);
00757 #endif
00758 for (i = 0 ; i < cls->slotCount ; i++)
00759 {
00760 if (cls->slots[i].defaultValue != NULL)
00761 {
00762 #if ! RUN_TIME
00763 if (cls->slots[i].dynamicDefault)
00764 ReturnPackedExpression(theEnv,(EXPRESSION *) cls->slots[i].defaultValue);
00765 else
00766 rtn_struct(theEnv,dataObject,cls->slots[i].defaultValue);
00767 #else
00768 if (cls->slots[i].dynamicDefault == 0)
00769 rtn_struct(theEnv,dataObject,cls->slots[i].defaultValue);
00770 #endif
00771 }
00772 }
00773
00774 #if ! RUN_TIME
00775 if (cls->instanceSlotCount != 0)
00776 {
00777 rm(theEnv,(void *) cls->instanceTemplate,
00778 (sizeof(SLOT_DESC *) * cls->instanceSlotCount));
00779 rm(theEnv,(void *) cls->slotNameMap,
00780 (sizeof(unsigned) * (cls->maxSlotNameID + 1)));
00781 }
00782
00783 if (cls->slotCount != 0)
00784 rm(theEnv,(void *) cls->slots,(sizeof(SLOT_DESC) * cls->slotCount));
00785
00786 for (i = 0 ; i < cls->handlerCount ; i++)
00787 {
00788 hnd = &cls->handlers[i];
00789 if (hnd->actions != NULL)
00790 ReturnPackedExpression(theEnv,hnd->actions);
00791
00792 if (hnd->ppForm != NULL)
00793 rm(theEnv,(void *) hnd->ppForm,(sizeof(char) * (strlen(hnd->ppForm)+1)));
00794
00795 if (hnd->usrData != NULL)
00796 { ClearUserDataList(theEnv,hnd->usrData); }
00797 }
00798
00799 if (cls->handlerCount != 0)
00800 {
00801 rm(theEnv,(void *) cls->handlers,(sizeof(HANDLER) * cls->handlerCount));
00802 rm(theEnv,(void *) cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount));
00803 }
00804
00805 DestroyConstructHeader(theEnv,&cls->header);
00806
00807 rtn_struct(theEnv,defclass,cls);
00808 #else
00809 #if MAC_MCW || WIN_MCW || MAC_XCD
00810 #pragma unused(hnd)
00811 #endif
00812 #endif
00813 }
00814
00815 #if ! RUN_TIME
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 globle void InstallClass(
00830 void *theEnv,
00831 DEFCLASS *cls,
00832 int set)
00833 {
00834 SLOT_DESC *slot;
00835 HANDLER *hnd;
00836 long i;
00837
00838 if ((set && cls->installed) ||
00839 ((set == FALSE) && (cls->installed == 0)))
00840 return;
00841
00842
00843
00844
00845
00846
00847
00848
00849 if (set == FALSE)
00850 {
00851 cls->installed = 0;
00852
00853 DecrementSymbolCount(theEnv,cls->header.name);
00854
00855 #if DEFMODULE_CONSTRUCT
00856 DecrementBitMapCount(theEnv,cls->scopeMap);
00857 #endif
00858 ClearUserDataList(theEnv,cls->header.usrData);
00859
00860 for (i = 0 ; i < cls->slotCount ; i++)
00861 {
00862 slot = &cls->slots[i];
00863 DecrementSymbolCount(theEnv,slot->overrideMessage);
00864 if (slot->defaultValue != NULL)
00865 {
00866 if (slot->dynamicDefault)
00867 ExpressionDeinstall(theEnv,(EXPRESSION *) slot->defaultValue);
00868 else
00869 ValueDeinstall(theEnv,(DATA_OBJECT *) slot->defaultValue);
00870 }
00871 }
00872 for (i = 0 ; i < cls->handlerCount ; i++)
00873 {
00874 hnd = &cls->handlers[i];
00875 DecrementSymbolCount(theEnv,hnd->name);
00876 if (hnd->actions != NULL)
00877 ExpressionDeinstall(theEnv,hnd->actions);
00878 }
00879 }
00880 else
00881 {
00882 cls->installed = 1;
00883 IncrementSymbolCount(cls->header.name);
00884 }
00885 }
00886
00887 #endif
00888
00889 #if (! BLOAD_ONLY) && (! RUN_TIME)
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 globle int IsClassBeingUsed(
00903 DEFCLASS *cls)
00904 {
00905 long i;
00906
00907 if (cls->busy > 0)
00908 return(TRUE);
00909 for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
00910 if (IsClassBeingUsed(cls->directSubclasses.classArray[i]))
00911 return(TRUE);
00912 return(FALSE);
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923 globle int RemoveAllUserClasses(
00924 void *theEnv)
00925 {
00926 void *userClasses,*ctmp;
00927 int success = TRUE;
00928
00929 #if BLOAD || BLOAD_AND_BSAVE
00930 if (Bloaded(theEnv))
00931 return(FALSE);
00932 #endif
00933
00934
00935
00936 userClasses = EnvGetNextDefclass(theEnv,NULL);
00937 while (userClasses != NULL)
00938 {
00939 if (((DEFCLASS *) userClasses)->system == 0)
00940 break;
00941 userClasses = EnvGetNextDefclass(theEnv,userClasses);
00942 }
00943 while (userClasses != NULL)
00944 {
00945 ctmp = userClasses;
00946 userClasses = EnvGetNextDefclass(theEnv,userClasses);
00947 if (EnvIsDefclassDeletable(theEnv,ctmp))
00948 {
00949 RemoveConstructFromModule(theEnv,(struct constructHeader *) ctmp);
00950 RemoveDefclass(theEnv,ctmp);
00951 }
00952 else
00953 {
00954 success = FALSE;
00955 CantDeleteItemErrorMessage(theEnv,"defclass",EnvGetDefclassName(theEnv,ctmp));
00956 }
00957 }
00958 return(success);
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 globle int DeleteClassUAG(
00972 void *theEnv,
00973 DEFCLASS *cls)
00974 {
00975 long subCount;
00976
00977 while (cls->directSubclasses.classCount != 0)
00978 {
00979 subCount = cls->directSubclasses.classCount;
00980 DeleteClassUAG(theEnv,cls->directSubclasses.classArray[0]);
00981 if (cls->directSubclasses.classCount == subCount)
00982 return(FALSE);
00983 }
00984 if (EnvIsDefclassDeletable(theEnv,(void *) cls))
00985 {
00986 RemoveConstructFromModule(theEnv,(struct constructHeader *) cls);
00987 RemoveDefclass(theEnv,(void *) cls);
00988 return(TRUE);
00989 }
00990 return(FALSE);
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 globle void MarkBitMapSubclasses(
01008 char *map,
01009 DEFCLASS *cls,
01010 int set)
01011 {
01012 long i;
01013
01014 if (set)
01015 SetBitMap(map,cls->id);
01016 else
01017 ClearBitMap(map,cls->id);
01018 for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
01019 MarkBitMapSubclasses(map,cls->directSubclasses.classArray[i],set);
01020 }
01021
01022 #endif
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 globle short FindSlotNameID(
01042 void *theEnv,
01043 SYMBOL_HN *slotName)
01044 {
01045 SLOT_NAME *snp;
01046
01047 snp = DefclassData(theEnv)->SlotNameTable[HashSlotName(slotName)];
01048 while ((snp != NULL) ? (snp->name != slotName) : FALSE)
01049 snp = snp->nxt;
01050 return((snp != NULL) ? (short) snp->id : (short) -1);
01051 }
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 globle SYMBOL_HN *FindIDSlotName(
01062 void *theEnv,
01063 int id)
01064 {
01065 SLOT_NAME *snp;
01066
01067 snp = FindIDSlotNameHash(theEnv,id);
01068 return((snp != NULL) ? snp->name : NULL);
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 globle SLOT_NAME *FindIDSlotNameHash(
01080 void *theEnv,
01081 int id)
01082 {
01083 register int i;
01084 SLOT_NAME *snp;
01085
01086 for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)
01087 {
01088 snp = DefclassData(theEnv)->SlotNameTable[i];
01089 while (snp != NULL)
01090 {
01091 if (snp->id == id)
01092 return(snp);
01093 snp = snp->nxt;
01094 }
01095 }
01096 return(NULL);
01097 }
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 globle int GetTraversalID(
01112 void *theEnv)
01113 {
01114 register unsigned i;
01115 register DEFCLASS *cls;
01116
01117 if (DefclassData(theEnv)->CTID >= MAX_TRAVERSALS)
01118 {
01119 PrintErrorID(theEnv,"CLASSFUN",2,FALSE);
01120 EnvPrintRouter(theEnv,WERROR,"Maximum number of simultaneous class hierarchy\n traversals exceeded ");
01121 PrintLongInteger(theEnv,WERROR,(long) MAX_TRAVERSALS);
01122 EnvPrintRouter(theEnv,WERROR,".\n");
01123 SetEvaluationError(theEnv,TRUE);
01124 return(-1);
01125 }
01126
01127 for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)
01128 for (cls = DefclassData(theEnv)->ClassTable[i] ; cls != NULL ; cls = cls->nxtHash)
01129 ClearTraversalID(cls->traversalRecord,DefclassData(theEnv)->CTID);
01130 return(DefclassData(theEnv)->CTID++);
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 globle void ReleaseTraversalID(
01144 void *theEnv)
01145 {
01146 DefclassData(theEnv)->CTID--;
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 globle unsigned HashClass(
01162 SYMBOL_HN *cname)
01163 {
01164 unsigned long tally;
01165
01166 tally = ((unsigned long) cname->bucket) * BIG_PRIME;
01167 return((unsigned) (tally % CLASS_TABLE_HASH_SIZE));
01168 }
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 static unsigned HashSlotName(
01189 SYMBOL_HN *sname)
01190 {
01191 unsigned long tally;
01192
01193 tally = ((unsigned long) sname->bucket) * BIG_PRIME;
01194 return((unsigned) (tally % SLOT_NAME_TABLE_HASH_SIZE));
01195 }
01196
01197 #if (! RUN_TIME)
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 static int NewSlotNameID(
01209 void *theEnv)
01210 {
01211 int newid = 0;
01212 register unsigned i;
01213 SLOT_NAME *snp;
01214
01215 while (TRUE)
01216 {
01217 for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)
01218 {
01219 snp = DefclassData(theEnv)->SlotNameTable[i];
01220 while ((snp != NULL) ? (snp->id != newid) : FALSE)
01221 snp = snp->nxt;
01222 if (snp != NULL)
01223 break;
01224 }
01225 if (i < SLOT_NAME_TABLE_HASH_SIZE)
01226 newid++;
01227 else
01228 break;
01229 }
01230 return(newid);
01231 }
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 static void DeassignClassID(
01245 void *theEnv,
01246 unsigned id)
01247 {
01248 int i;
01249 int reallocReqd;
01250 unsigned short oldChunk = 0,newChunk = 0;
01251
01252 DefclassData(theEnv)->ClassIDMap[id] = NULL;
01253 for (i = id + 1 ; i < DefclassData(theEnv)->MaxClassID ; i++)
01254 if (DefclassData(theEnv)->ClassIDMap[i] != NULL)
01255 return;
01256 reallocReqd = FALSE;
01257 while (DefclassData(theEnv)->ClassIDMap[id] == NULL)
01258 {
01259 DefclassData(theEnv)->MaxClassID = (unsigned short) id;
01260 if ((DefclassData(theEnv)->MaxClassID % CLASS_ID_MAP_CHUNK) == 0)
01261 {
01262 newChunk = DefclassData(theEnv)->MaxClassID;
01263 if (reallocReqd == FALSE)
01264 {
01265 oldChunk = (unsigned short) (DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK);
01266 reallocReqd = TRUE;
01267 }
01268 }
01269 if (id == 0)
01270 break;
01271 id--;
01272 }
01273 if (reallocReqd)
01274 {
01275 DefclassData(theEnv)->ClassIDMap = (DEFCLASS **) genrealloc(theEnv,(void *) DefclassData(theEnv)->ClassIDMap,
01276 (unsigned) (oldChunk * sizeof(DEFCLASS *)),
01277 (unsigned) (newChunk * sizeof(DEFCLASS *)));
01278
01279 DefclassData(theEnv)->AvailClassID = newChunk;
01280 }
01281 }
01282
01283 #endif
01284
01285 #endif