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
00033 #include "setup.h"
00034
00035 #if INSTANCE_SET_QUERIES
00036
00037 #include "argacces.h"
00038 #include "classcom.h"
00039 #include "classfun.h"
00040 #include "envrnmnt.h"
00041 #include "memalloc.h"
00042 #include "exprnpsr.h"
00043 #include "insfun.h"
00044 #include "insmngr.h"
00045 #include "insqypsr.h"
00046 #include "prcdrfun.h"
00047 #include "router.h"
00048 #include "utility.h"
00049
00050 #define _INSQUERY_SOURCE_
00051 #include "insquery.h"
00052
00053
00054
00055
00056
00057
00058
00059 static void PushQueryCore(void *);
00060 static void PopQueryCore(void *);
00061 static QUERY_CORE *FindQueryCore(void *,int);
00062 static QUERY_CLASS *DetermineQueryClasses(void *,EXPRESSION *,char *,unsigned *);
00063 static QUERY_CLASS *FormChain(void *,char *,DATA_OBJECT *);
00064 static void DeleteQueryClasses(void *,QUERY_CLASS *);
00065 static int TestForFirstInChain(void *,QUERY_CLASS *,int);
00066 static int TestForFirstInstanceInClass(void *,struct defmodule *,int,DEFCLASS *,QUERY_CLASS *,int);
00067 static void TestEntireChain(void *,QUERY_CLASS *,int);
00068 static void TestEntireClass(void *,struct defmodule *,int,DEFCLASS *,QUERY_CLASS *,int);
00069 static void AddSolution(void *);
00070 static void PopQuerySoln(void *);
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 globle void SetupQuery(
00082 void *theEnv)
00083 {
00084 AllocateEnvironmentData(theEnv,INSTANCE_QUERY_DATA,sizeof(struct instanceQueryData),NULL);
00085
00086 #if ! RUN_TIME
00087 InstanceQueryData(theEnv)->QUERY_DELIMETER_SYMBOL = (SYMBOL_HN *) EnvAddSymbol(theEnv,QUERY_DELIMETER_STRING);
00088 IncrementSymbolCount(InstanceQueryData(theEnv)->QUERY_DELIMETER_SYMBOL);
00089
00090 EnvDefineFunction2(theEnv,"(query-instance)",'o',
00091 PTIEF GetQueryInstance,"GetQueryInstance",NULL);
00092
00093 EnvDefineFunction2(theEnv,"(query-instance-slot)",'u',
00094 PTIEF GetQueryInstanceSlot,"GetQueryInstanceSlot",NULL);
00095
00096 EnvDefineFunction2(theEnv,"any-instancep",'b',PTIEF AnyInstances,"AnyInstances",NULL);
00097 AddFunctionParser(theEnv,"any-instancep",ParseQueryNoAction);
00098
00099 EnvDefineFunction2(theEnv,"find-instance",'m',
00100 PTIEF QueryFindInstance,"QueryFindInstance",NULL);
00101 AddFunctionParser(theEnv,"find-instance",ParseQueryNoAction);
00102
00103 EnvDefineFunction2(theEnv,"find-all-instances",'m',
00104 PTIEF QueryFindAllInstances,"QueryFindAllInstances",NULL);
00105 AddFunctionParser(theEnv,"find-all-instances",ParseQueryNoAction);
00106
00107 EnvDefineFunction2(theEnv,"do-for-instance",'u',
00108 PTIEF QueryDoForInstance,"QueryDoForInstance",NULL);
00109 AddFunctionParser(theEnv,"do-for-instance",ParseQueryAction);
00110
00111 EnvDefineFunction2(theEnv,"do-for-all-instances",'u',
00112 PTIEF QueryDoForAllInstances,"QueryDoForAllInstances",NULL);
00113 AddFunctionParser(theEnv,"do-for-all-instances",ParseQueryAction);
00114
00115 EnvDefineFunction2(theEnv,"delayed-do-for-all-instances",'u',
00116 PTIEF DelayedQueryDoForAllInstances,
00117 "DelayedQueryDoForAllInstances",NULL);
00118 AddFunctionParser(theEnv,"delayed-do-for-all-instances",ParseQueryAction);
00119 #endif
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 globle void *GetQueryInstance(
00132 void *theEnv)
00133 {
00134 register QUERY_CORE *core;
00135
00136 core = FindQueryCore(theEnv,ValueToInteger(GetpValue(GetFirstArgument())));
00137 return(GetFullInstanceName(theEnv,core->solns[ValueToInteger(GetpValue(GetFirstArgument()->nextArg))]));
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 globle void GetQueryInstanceSlot(
00150 void *theEnv,
00151 DATA_OBJECT *result)
00152 {
00153 INSTANCE_TYPE *ins;
00154 INSTANCE_SLOT *sp;
00155 DATA_OBJECT temp;
00156 QUERY_CORE *core;
00157
00158 result->type = SYMBOL;
00159 result->value = EnvFalseSymbol(theEnv);
00160
00161 core = FindQueryCore(theEnv,ValueToInteger(GetpValue(GetFirstArgument())));
00162 ins = core->solns[ValueToInteger(GetpValue(GetFirstArgument()->nextArg))];
00163 EvaluateExpression(theEnv,GetFirstArgument()->nextArg->nextArg,&temp);
00164 if (temp.type != SYMBOL)
00165 {
00166 ExpectedTypeError1(theEnv,"get",1,"symbol");
00167 SetEvaluationError(theEnv,TRUE);
00168 return;
00169 }
00170 sp = FindInstanceSlot(theEnv,ins,(SYMBOL_HN *) temp.value);
00171 if (sp == NULL)
00172 {
00173 SlotExistError(theEnv,ValueToString(temp.value),"instance-set query");
00174 return;
00175 }
00176 result->type = (unsigned short) sp->type;
00177 result->value = sp->value;
00178 if (sp->type == MULTIFIELD)
00179 {
00180 result->begin = 0;
00181 SetpDOEnd(result,GetInstanceSlotLength(sp));
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 globle intBool AnyInstances(
00250 void *theEnv)
00251 {
00252 QUERY_CLASS *qclasses;
00253 unsigned rcnt;
00254 int TestResult;
00255
00256 qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg,
00257 "any-instancep",&rcnt);
00258 if (qclasses == NULL)
00259 return(FALSE);
00260 PushQueryCore(theEnv);
00261 InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00262 InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt));
00263 InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00264 TestResult = TestForFirstInChain(theEnv,qclasses,0);
00265 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00266 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt));
00267 rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore);
00268 PopQueryCore(theEnv);
00269 DeleteQueryClasses(theEnv,qclasses);
00270 return(TestResult);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 globle void QueryFindInstance(
00286 void *theEnv,
00287 DATA_OBJECT *result)
00288 {
00289 QUERY_CLASS *qclasses;
00290 unsigned rcnt,i;
00291
00292 result->type = MULTIFIELD;
00293 result->begin = 0;
00294 result->end = -1;
00295 qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg,
00296 "find-instance",&rcnt);
00297 if (qclasses == NULL)
00298 {
00299 result->value = (void *) EnvCreateMultifield(theEnv,0L);
00300 return;
00301 }
00302 PushQueryCore(theEnv);
00303 InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00304 InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **)
00305 gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt));
00306 InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00307 if (TestForFirstInChain(theEnv,qclasses,0) == TRUE)
00308 {
00309 result->value = (void *) EnvCreateMultifield(theEnv,rcnt);
00310 SetpDOEnd(result,rcnt);
00311 for (i = 1 ; i <= rcnt ; i++)
00312 {
00313 SetMFType(result->value,i,INSTANCE_NAME);
00314 SetMFValue(result->value,i,GetFullInstanceName(theEnv,InstanceQueryData(theEnv)->QueryCore->solns[i - 1]));
00315 }
00316 }
00317 else
00318 result->value = (void *) EnvCreateMultifield(theEnv,0L);
00319 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00320 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt));
00321 rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore);
00322 PopQueryCore(theEnv);
00323 DeleteQueryClasses(theEnv,qclasses);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 globle void QueryFindAllInstances(
00345 void *theEnv,
00346 DATA_OBJECT *result)
00347 {
00348 QUERY_CLASS *qclasses;
00349 unsigned rcnt;
00350 register unsigned i,j;
00351
00352 result->type = MULTIFIELD;
00353 result->begin = 0;
00354 result->end = -1;
00355 qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg,
00356 "find-all-instances",&rcnt);
00357 if (qclasses == NULL)
00358 {
00359 result->value = (void *) EnvCreateMultifield(theEnv,0L);
00360 return;
00361 }
00362 PushQueryCore(theEnv);
00363 InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00364 InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt));
00365 InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00366 InstanceQueryData(theEnv)->QueryCore->action = NULL;
00367 InstanceQueryData(theEnv)->QueryCore->soln_set = NULL;
00368 InstanceQueryData(theEnv)->QueryCore->soln_size = rcnt;
00369 InstanceQueryData(theEnv)->QueryCore->soln_cnt = 0;
00370 TestEntireChain(theEnv,qclasses,0);
00371 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00372 result->value = (void *) EnvCreateMultifield(theEnv,InstanceQueryData(theEnv)->QueryCore->soln_cnt * rcnt);
00373 while (InstanceQueryData(theEnv)->QueryCore->soln_set != NULL)
00374 {
00375 for (i = 0 , j = (unsigned) (result->end + 2) ; i < rcnt ; i++ , j++)
00376 {
00377 SetMFType(result->value,j,INSTANCE_NAME);
00378 SetMFValue(result->value,j,GetFullInstanceName(theEnv,InstanceQueryData(theEnv)->QueryCore->soln_set->soln[i]));
00379 }
00380 result->end = (long) j-2;
00381 PopQuerySoln(theEnv);
00382 }
00383 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt));
00384 rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore);
00385 PopQueryCore(theEnv);
00386 DeleteQueryClasses(theEnv,qclasses);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 globle void QueryDoForInstance(
00404 void *theEnv,
00405 DATA_OBJECT *result)
00406 {
00407 QUERY_CLASS *qclasses;
00408 unsigned rcnt;
00409
00410 result->type = SYMBOL;
00411 result->value = EnvFalseSymbol(theEnv);
00412 qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg->nextArg,
00413 "do-for-instance",&rcnt);
00414 if (qclasses == NULL)
00415 return;
00416 PushQueryCore(theEnv);
00417 InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00418 InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt));
00419 InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00420 InstanceQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
00421 if (TestForFirstInChain(theEnv,qclasses,0) == TRUE)
00422 EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->action,result);
00423 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00424 ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
00425 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt));
00426 rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore);
00427 PopQueryCore(theEnv);
00428 DeleteQueryClasses(theEnv,qclasses);
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 globle void QueryDoForAllInstances(
00445 void *theEnv,
00446 DATA_OBJECT *result)
00447 {
00448 QUERY_CLASS *qclasses;
00449 unsigned rcnt;
00450
00451 result->type = SYMBOL;
00452 result->value = EnvFalseSymbol(theEnv);
00453 qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg->nextArg,
00454 "do-for-all-instances",&rcnt);
00455 if (qclasses == NULL)
00456 return;
00457 PushQueryCore(theEnv);
00458 InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00459 InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt));
00460 InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00461 InstanceQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
00462 InstanceQueryData(theEnv)->QueryCore->result = result;
00463 ValueInstall(theEnv,InstanceQueryData(theEnv)->QueryCore->result);
00464 TestEntireChain(theEnv,qclasses,0);
00465 ValueDeinstall(theEnv,InstanceQueryData(theEnv)->QueryCore->result);
00466 PropagateReturnValue(theEnv,InstanceQueryData(theEnv)->QueryCore->result);
00467 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00468 ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
00469 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt));
00470 rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore);
00471 PopQueryCore(theEnv);
00472 DeleteQueryClasses(theEnv,qclasses);
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 globle void DelayedQueryDoForAllInstances(
00493 void *theEnv,
00494 DATA_OBJECT *result)
00495 {
00496 QUERY_CLASS *qclasses;
00497 unsigned rcnt;
00498 register unsigned i;
00499
00500 result->type = SYMBOL;
00501 result->value = EnvFalseSymbol(theEnv);
00502 qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg->nextArg,
00503 "delayed-do-for-all-instances",&rcnt);
00504 if (qclasses == NULL)
00505 return;
00506 PushQueryCore(theEnv);
00507 InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00508 InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt));
00509 InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00510 InstanceQueryData(theEnv)->QueryCore->action = NULL;
00511 InstanceQueryData(theEnv)->QueryCore->soln_set = NULL;
00512 InstanceQueryData(theEnv)->QueryCore->soln_size = rcnt;
00513 InstanceQueryData(theEnv)->QueryCore->soln_cnt = 0;
00514 TestEntireChain(theEnv,qclasses,0);
00515 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00516 InstanceQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
00517 while (InstanceQueryData(theEnv)->QueryCore->soln_set != NULL)
00518 {
00519 for (i = 0 ; i < rcnt ; i++)
00520 InstanceQueryData(theEnv)->QueryCore->solns[i] = InstanceQueryData(theEnv)->QueryCore->soln_set->soln[i];
00521 PopQuerySoln(theEnv);
00522 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00523 EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->action,result);
00524 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00525 if (ProcedureFunctionData(theEnv)->ReturnFlag == TRUE)
00526 { PropagateReturnValue(theEnv,result); }
00527 PeriodicCleanup(theEnv,FALSE,TRUE);
00528 if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
00529 {
00530 while (InstanceQueryData(theEnv)->QueryCore->soln_set != NULL)
00531 PopQuerySoln(theEnv);
00532 break;
00533 }
00534 }
00535 ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
00536 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt));
00537 rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore);
00538 PopQueryCore(theEnv);
00539 DeleteQueryClasses(theEnv,qclasses);
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 static void PushQueryCore(
00558 void *theEnv)
00559 {
00560 QUERY_STACK *qptr;
00561
00562 qptr = get_struct(theEnv,query_stack);
00563 qptr->core = InstanceQueryData(theEnv)->QueryCore;
00564 qptr->nxt = InstanceQueryData(theEnv)->QueryCoreStack;
00565 InstanceQueryData(theEnv)->QueryCoreStack = qptr;
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 static void PopQueryCore(
00579 void *theEnv)
00580 {
00581 QUERY_STACK *qptr;
00582
00583 InstanceQueryData(theEnv)->QueryCore = InstanceQueryData(theEnv)->QueryCoreStack->core;
00584 qptr = InstanceQueryData(theEnv)->QueryCoreStack;
00585 InstanceQueryData(theEnv)->QueryCoreStack = InstanceQueryData(theEnv)->QueryCoreStack->nxt;
00586 rtn_struct(theEnv,query_stack,qptr);
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 static QUERY_CORE *FindQueryCore(
00600 void *theEnv,
00601 int depth)
00602 {
00603 QUERY_STACK *qptr;
00604
00605 if (depth == 0)
00606 return(InstanceQueryData(theEnv)->QueryCore);
00607 qptr = InstanceQueryData(theEnv)->QueryCoreStack;
00608 while (depth > 1)
00609 {
00610 qptr = qptr->nxt;
00611 depth--;
00612 }
00613 return(qptr->core);
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 static QUERY_CLASS *DetermineQueryClasses(
00637 void *theEnv,
00638 EXPRESSION *classExp,
00639 char *func,
00640 unsigned *rcnt)
00641 {
00642 QUERY_CLASS *clist = NULL,*cnxt = NULL,*cchain = NULL,*tmp;
00643 int new_list = FALSE;
00644 DATA_OBJECT temp;
00645
00646 *rcnt = 0;
00647 while (classExp != NULL)
00648 {
00649 if (EvaluateExpression(theEnv,classExp,&temp))
00650 {
00651 DeleteQueryClasses(theEnv,clist);
00652 return(NULL);
00653 }
00654 if ((temp.type == SYMBOL) && (temp.value == (void *) InstanceQueryData(theEnv)->QUERY_DELIMETER_SYMBOL))
00655 {
00656 new_list = TRUE;
00657 (*rcnt)++;
00658 }
00659 else if ((tmp = FormChain(theEnv,func,&temp)) != NULL)
00660 {
00661 if (clist == NULL)
00662 clist = cnxt = cchain = tmp;
00663 else if (new_list == TRUE)
00664 {
00665 new_list = FALSE;
00666 cnxt->nxt = tmp;
00667 cnxt = cchain = tmp;
00668 }
00669 else
00670 cchain->chain = tmp;
00671 while (cchain->chain != NULL)
00672 cchain = cchain->chain;
00673 }
00674 else
00675 {
00676 SyntaxErrorMessage(theEnv,"instance-set query class restrictions");
00677 DeleteQueryClasses(theEnv,clist);
00678 SetEvaluationError(theEnv,TRUE);
00679 return(NULL);
00680 }
00681 classExp = classExp->nextArg;
00682 }
00683 return(clist);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 static QUERY_CLASS *FormChain(
00700 void *theEnv,
00701 char *func,
00702 DATA_OBJECT *val)
00703 {
00704 DEFCLASS *cls;
00705 QUERY_CLASS *head,*bot,*tmp;
00706 register long i,end;
00707 char *className;
00708 struct defmodule *currentModule;
00709
00710 currentModule = ((struct defmodule *) EnvGetCurrentModule(theEnv));
00711 if (val->type == DEFCLASS_PTR)
00712 {
00713 IncrementDefclassBusyCount(theEnv,(void *) val->value);
00714 head = get_struct(theEnv,query_class);
00715 head->cls = (DEFCLASS *) val->value;
00716 if (DefclassInScope(theEnv,head->cls,currentModule))
00717 head->theModule = currentModule;
00718 else
00719 head->theModule = head->cls->header.whichModule->theModule;
00720 head->chain = NULL;
00721 head->nxt = NULL;
00722 return(head);
00723 }
00724 if (val->type == SYMBOL)
00725 {
00726
00727
00728
00729
00730
00731
00732 cls = LookupDefclassByMdlOrScope(theEnv,DOPToString(val));
00733 if (cls == NULL)
00734 {
00735 ClassExistError(theEnv,func,DOPToString(val));
00736 return(NULL);
00737 }
00738 IncrementDefclassBusyCount(theEnv,(void *) cls);
00739 head = get_struct(theEnv,query_class);
00740 head->cls = cls;
00741 if (DefclassInScope(theEnv,head->cls,currentModule))
00742 head->theModule = currentModule;
00743 else
00744 head->theModule = head->cls->header.whichModule->theModule;
00745 head->chain = NULL;
00746 head->nxt = NULL;
00747 return(head);
00748 }
00749 if (val->type == MULTIFIELD)
00750 {
00751 head = bot = NULL;
00752 end = GetpDOEnd(val);
00753 for (i = GetpDOBegin(val) ; i <= end ; i++)
00754 {
00755 if (GetMFType(val->value,i) == SYMBOL)
00756 {
00757 className = ValueToString(GetMFValue(val->value,i));
00758 cls = LookupDefclassByMdlOrScope(theEnv,className);
00759 if (cls == NULL)
00760 {
00761 ClassExistError(theEnv,func,className);
00762 DeleteQueryClasses(theEnv,head);
00763 return(NULL);
00764 }
00765 }
00766 else
00767 {
00768 DeleteQueryClasses(theEnv,head);
00769 return(NULL);
00770 }
00771 IncrementDefclassBusyCount(theEnv,(void *) cls);
00772 tmp = get_struct(theEnv,query_class);
00773 tmp->cls = cls;
00774 if (DefclassInScope(theEnv,tmp->cls,currentModule))
00775 tmp->theModule = currentModule;
00776 else
00777 tmp->theModule = tmp->cls->header.whichModule->theModule;
00778 tmp->chain = NULL;
00779 tmp->nxt = NULL;
00780 if (head == NULL)
00781 head = tmp;
00782 else
00783 bot->chain = tmp;
00784 bot = tmp;
00785 }
00786 return(head);
00787 }
00788 return(NULL);
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 static void DeleteQueryClasses(
00801 void *theEnv,
00802 QUERY_CLASS *qlist)
00803 {
00804 QUERY_CLASS *tmp;
00805
00806 while (qlist != NULL)
00807 {
00808 while (qlist->chain != NULL)
00809 {
00810 tmp = qlist->chain;
00811 qlist->chain = qlist->chain->chain;
00812 DecrementDefclassBusyCount(theEnv,(void *) tmp->cls);
00813 rtn_struct(theEnv,query_class,tmp);
00814 }
00815 tmp = qlist;
00816 qlist = qlist->nxt;
00817 DecrementDefclassBusyCount(theEnv,(void *) tmp->cls);
00818 rtn_struct(theEnv,query_class,tmp);
00819 }
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 static int TestForFirstInChain(
00835 void *theEnv,
00836 QUERY_CLASS *qchain,
00837 int indx)
00838 {
00839 QUERY_CLASS *qptr;
00840 int id;
00841
00842 InstanceQueryData(theEnv)->AbortQuery = TRUE;
00843 for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain)
00844 {
00845 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00846 if ((id = GetTraversalID(theEnv)) == -1)
00847 return(FALSE);
00848 if (TestForFirstInstanceInClass(theEnv,qptr->theModule,id,qptr->cls,qchain,indx))
00849 {
00850 ReleaseTraversalID(theEnv);
00851 return(TRUE);
00852 }
00853 ReleaseTraversalID(theEnv);
00854 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
00855 return(FALSE);
00856 }
00857 return(FALSE);
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 static int TestForFirstInstanceInClass(
00875 void *theEnv,
00876 struct defmodule *theModule,
00877 int id,
00878 DEFCLASS *cls,
00879 QUERY_CLASS *qchain,
00880 int indx)
00881 {
00882 long i;
00883 INSTANCE_TYPE *ins;
00884 DATA_OBJECT temp;
00885
00886 if (TestTraversalID(cls->traversalRecord,id))
00887 return(FALSE);
00888 SetTraversalID(cls->traversalRecord,id);
00889 if (DefclassInScope(theEnv,cls,theModule) == FALSE)
00890 return(FALSE);
00891 ins = cls->instanceList;
00892 while (ins != NULL)
00893 {
00894 InstanceQueryData(theEnv)->QueryCore->solns[indx] = ins;
00895 if (qchain->nxt != NULL)
00896 {
00897 ins->busy++;
00898 if (TestForFirstInChain(theEnv,qchain->nxt,indx+1) == TRUE)
00899 {
00900 ins->busy--;
00901 break;
00902 }
00903 ins->busy--;
00904 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
00905 break;
00906 }
00907 else
00908 {
00909 ins->busy++;
00910 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00911 EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->query,&temp);
00912 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00913 PeriodicCleanup(theEnv,FALSE,TRUE);
00914 ins->busy--;
00915 if (EvaluationData(theEnv)->HaltExecution == TRUE)
00916 break;
00917 if ((temp.type != SYMBOL) ? TRUE :
00918 (temp.value != EnvFalseSymbol(theEnv)))
00919 break;
00920 }
00921 ins = ins->nxtClass;
00922 while ((ins != NULL) ? (ins->garbage == 1) : FALSE)
00923 ins = ins->nxtClass;
00924 }
00925 if (ins != NULL)
00926 return(((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
00927 ? FALSE : TRUE);
00928 for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
00929 {
00930 if (TestForFirstInstanceInClass(theEnv,theModule,id,cls->directSubclasses.classArray[i],
00931 qchain,indx))
00932 return(TRUE);
00933 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
00934 return(FALSE);
00935 }
00936 return(FALSE);
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 static void TestEntireChain(
00953 void *theEnv,
00954 QUERY_CLASS *qchain,
00955 int indx)
00956 {
00957 QUERY_CLASS *qptr;
00958 int id;
00959
00960 InstanceQueryData(theEnv)->AbortQuery = TRUE;
00961 for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain)
00962 {
00963 InstanceQueryData(theEnv)->AbortQuery = FALSE;
00964 if ((id = GetTraversalID(theEnv)) == -1)
00965 return;
00966 TestEntireClass(theEnv,qptr->theModule,id,qptr->cls,qchain,indx);
00967 ReleaseTraversalID(theEnv);
00968 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
00969 return;
00970 }
00971 }
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 static void TestEntireClass(
00989 void *theEnv,
00990 struct defmodule *theModule,
00991 int id,
00992 DEFCLASS *cls,
00993 QUERY_CLASS *qchain,
00994 int indx)
00995 {
00996 long i;
00997 INSTANCE_TYPE *ins;
00998 DATA_OBJECT temp;
00999
01000 if (TestTraversalID(cls->traversalRecord,id))
01001 return;
01002 SetTraversalID(cls->traversalRecord,id);
01003 if (DefclassInScope(theEnv,cls,theModule) == FALSE)
01004 return;
01005 ins = cls->instanceList;
01006 while (ins != NULL)
01007 {
01008 InstanceQueryData(theEnv)->QueryCore->solns[indx] = ins;
01009 if (qchain->nxt != NULL)
01010 {
01011 ins->busy++;
01012 TestEntireChain(theEnv,qchain->nxt,indx+1);
01013 ins->busy--;
01014 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
01015 break;
01016 }
01017 else
01018 {
01019 ins->busy++;
01020 EvaluationData(theEnv)->CurrentEvaluationDepth++;
01021 EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->query,&temp);
01022 EvaluationData(theEnv)->CurrentEvaluationDepth--;
01023 PeriodicCleanup(theEnv,FALSE,TRUE);
01024 ins->busy--;
01025 if (EvaluationData(theEnv)->HaltExecution == TRUE)
01026 break;
01027 if ((temp.type != SYMBOL) ? TRUE :
01028 (temp.value != EnvFalseSymbol(theEnv)))
01029 {
01030 if (InstanceQueryData(theEnv)->QueryCore->action != NULL)
01031 {
01032 ins->busy++;
01033 EvaluationData(theEnv)->CurrentEvaluationDepth++;
01034 ValueDeinstall(theEnv,InstanceQueryData(theEnv)->QueryCore->result);
01035 EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->action,InstanceQueryData(theEnv)->QueryCore->result);
01036 ValueInstall(theEnv,InstanceQueryData(theEnv)->QueryCore->result);
01037 EvaluationData(theEnv)->CurrentEvaluationDepth--;
01038 PeriodicCleanup(theEnv,FALSE,TRUE);
01039 ins->busy--;
01040 if (ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
01041 {
01042 InstanceQueryData(theEnv)->AbortQuery = TRUE;
01043 break;
01044 }
01045 if (EvaluationData(theEnv)->HaltExecution == TRUE)
01046 break;
01047 }
01048 else
01049 AddSolution(theEnv);
01050 }
01051 }
01052
01053 ins = ins->nxtClass;
01054 while ((ins != NULL) ? (ins->garbage == 1) : FALSE)
01055 ins = ins->nxtClass;
01056 }
01057 if (ins != NULL)
01058 return;
01059 for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
01060 {
01061 TestEntireClass(theEnv,theModule,id,cls->directSubclasses.classArray[i],qchain,indx);
01062 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (InstanceQueryData(theEnv)->AbortQuery == TRUE))
01063 return;
01064 }
01065 }
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 static void AddSolution(
01077 void *theEnv)
01078 {
01079 QUERY_SOLN *new_soln;
01080 register unsigned i;
01081
01082 new_soln = (QUERY_SOLN *) gm2(theEnv,(int) sizeof(QUERY_SOLN));
01083 new_soln->soln = (INSTANCE_TYPE **)
01084 gm2(theEnv,(sizeof(INSTANCE_TYPE *) * (InstanceQueryData(theEnv)->QueryCore->soln_size)));
01085 for (i = 0 ; i < InstanceQueryData(theEnv)->QueryCore->soln_size ; i++)
01086 new_soln->soln[i] = InstanceQueryData(theEnv)->QueryCore->solns[i];
01087 new_soln->nxt = NULL;
01088 if (InstanceQueryData(theEnv)->QueryCore->soln_set == NULL)
01089 InstanceQueryData(theEnv)->QueryCore->soln_set = new_soln;
01090 else
01091 InstanceQueryData(theEnv)->QueryCore->soln_bottom->nxt = new_soln;
01092 InstanceQueryData(theEnv)->QueryCore->soln_bottom = new_soln;
01093 InstanceQueryData(theEnv)->QueryCore->soln_cnt++;
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 static void PopQuerySoln(
01106 void *theEnv)
01107 {
01108 InstanceQueryData(theEnv)->QueryCore->soln_bottom = InstanceQueryData(theEnv)->QueryCore->soln_set;
01109 InstanceQueryData(theEnv)->QueryCore->soln_set = InstanceQueryData(theEnv)->QueryCore->soln_set->nxt;
01110 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->soln_bottom->soln,
01111 (sizeof(INSTANCE_TYPE *) * InstanceQueryData(theEnv)->QueryCore->soln_size));
01112 rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->soln_bottom,sizeof(QUERY_SOLN));
01113 }
01114
01115 #endif
01116
01117