/********************************************************** NAME : DetermineQueryClasses DESCRIPTION : Builds a list of classes to be used in instance queries - uses parse form. INPUTS : 1) The parse class expression chain 2) The name of the function being executed 3) Caller's buffer for restriction count (# of separate lists) RETURNS : The query list, or NULL on errors SIDE EFFECTS : Memory allocated for list Busy count incremented for all classes NOTES : Each restriction is linked by nxt pointer, multiple classes in a restriction are linked by the chain pointer. Rcnt caller's buffer is set to reflect the total number of chains Assumes classExp is not NULL and that each restriction chain is terminated with the QUERY_DELIMITER_SYMBOL "(QDS)" **********************************************************/ static QUERY_CLASS *DetermineQueryClasses( void *theEnv, EXEC_STATUS, EXPRESSION *classExp, char *func, unsigned *rcnt) { QUERY_CLASS *clist = NULL,*cnxt = NULL,*cchain = NULL,*tmp; int new_list = FALSE; DATA_OBJECT temp; *rcnt = 0; while (classExp != NULL) { if (EvaluateExpression(theEnv,execStatus,classExp,&temp)) { DeleteQueryClasses(theEnv,execStatus,clist); return(NULL); } if ((temp.type == SYMBOL) && (temp.value == (void *) InstanceQueryData(theEnv,execStatus)->QUERY_DELIMETER_SYMBOL)) { new_list = TRUE; (*rcnt)++; } else if ((tmp = FormChain(theEnv,execStatus,func,&temp)) != NULL) { if (clist == NULL) clist = cnxt = cchain = tmp; else if (new_list == TRUE) { new_list = FALSE; cnxt->nxt = tmp; cnxt = cchain = tmp; } else cchain->chain = tmp; while (cchain->chain != NULL) cchain = cchain->chain; } else { SyntaxErrorMessage(theEnv,execStatus,"instance-set query class restrictions"); DeleteQueryClasses(theEnv,execStatus,clist); SetEvaluationError(theEnv,execStatus,TRUE); return(NULL); } classExp = classExp->nextArg; } return(clist); }
/****************************************************************************** NAME : QueryDoForAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and executes a user-function for each set as it is found INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. Also, the action is executed for every instance set. Caller's result buffer holds result of last action executed. NOTES : H/L Syntax : See ParseQueryAction() ******************************************************************************/ globle void QueryDoForAllInstances( void *theEnv, EXEC_STATUS, DATA_OBJECT *result) { QUERY_CLASS *qclasses; unsigned rcnt; result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv,execStatus); qclasses = DetermineQueryClasses(theEnv,execStatus,GetFirstArgument()->nextArg->nextArg, "do-for-all-instances",&rcnt); if (qclasses == NULL) return; PushQueryCore(theEnv,execStatus); InstanceQueryData(theEnv,execStatus)->QueryCore = get_struct(theEnv,execStatus,query_core); InstanceQueryData(theEnv,execStatus)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,execStatus,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv,execStatus)->QueryCore->query = GetFirstArgument(); InstanceQueryData(theEnv,execStatus)->QueryCore->action = GetFirstArgument()->nextArg; InstanceQueryData(theEnv,execStatus)->QueryCore->result = result; ValueInstall(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->result); TestEntireChain(theEnv,execStatus,qclasses,0); ValueDeinstall(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->result); PropagateReturnValue(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->result); InstanceQueryData(theEnv,execStatus)->AbortQuery = FALSE; ProcedureFunctionData(theEnv,execStatus)->BreakFlag = FALSE; rm(theEnv,execStatus,(void *) InstanceQueryData(theEnv,execStatus)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,execStatus,query_core,InstanceQueryData(theEnv,execStatus)->QueryCore); PopQueryCore(theEnv,execStatus); DeleteQueryClasses(theEnv,execStatus,qclasses); }
/****************************************************************************** NAME : QueryDoForAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and executes a user-function for each set as it is found INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. Also, the action is executed for every instance set. Caller's result buffer holds result of last action executed. NOTES : H/L Syntax : See ParseQueryAction() ******************************************************************************/ globle void QueryDoForAllInstances( DATA_OBJECT *result) { QUERY_CLASS *qclasses; int rcnt; result->type = SYMBOL; result->value = FalseSymbol; qclasses = DetermineQueryClasses(GetFirstArgument()->nextArg->nextArg, "do-for-all-instances",&rcnt); if (qclasses == NULL) return; PushQueryCore(); QueryCore = get_struct(query_core); QueryCore->solns = (INSTANCE_TYPE **) gm2((int) (sizeof(INSTANCE_TYPE *) * rcnt)); QueryCore->query = GetFirstArgument(); QueryCore->action = GetFirstArgument()->nextArg; QueryCore->result = result; ValueInstall(QueryCore->result); TestEntireChain(qclasses,0); ValueDeinstall(QueryCore->result); PropagateReturnValue(QueryCore->result); AbortQuery = FALSE; BreakFlag = FALSE; rm((void *) QueryCore->solns,(int) (sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(query_core,QueryCore); PopQueryCore(); DeleteQueryClasses(qclasses); }
/****************************************************************************** NAME : QueryDoForInstance DESCRIPTION : Finds the first set of instances which satisfy the query and executes a user-action with that set INPUTS : None RETURNS : Caller's result buffer SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated zero or more times (depending on instance restrictions and how early the expression evaulates to TRUE - if at all). Also the action expression is executed zero or once. Caller's result buffer holds result of user-action NOTES : H/L Syntax : See ParseQueryAction() ******************************************************************************/ globle void QueryDoForInstance( void *theEnv, DATA_OBJECT *result) { QUERY_CLASS *qclasses; unsigned rcnt; result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv); qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg->nextArg, "do-for-instance",&rcnt); if (qclasses == NULL) return; PushQueryCore(theEnv); InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core); InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument(); InstanceQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg; if (TestForFirstInChain(theEnv,qclasses,0) == TRUE) EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->action,result); InstanceQueryData(theEnv)->AbortQuery = FALSE; ProcedureFunctionData(theEnv)->BreakFlag = FALSE; rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore); PopQueryCore(theEnv); DeleteQueryClasses(theEnv,qclasses); }
/****************************************************************************** NAME : QueryDoForInstance DESCRIPTION : Finds the first set of instances which satisfy the query and executes a user-action with that set INPUTS : None RETURNS : Caller's result buffer SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated zero or more times (depending on instance restrictions and how early the expression evaulates to TRUE - if at all). Also the action expression is executed zero or once. Caller's result buffer holds result of user-action NOTES : H/L Syntax : See ParseQueryAction() ******************************************************************************/ globle void QueryDoForInstance( DATA_OBJECT *result) { QUERY_CLASS *qclasses; int rcnt; result->type = SYMBOL; result->value = FalseSymbol; qclasses = DetermineQueryClasses(GetFirstArgument()->nextArg->nextArg, "do-for-instance",&rcnt); if (qclasses == NULL) return; PushQueryCore(); QueryCore = get_struct(query_core); QueryCore->solns = (INSTANCE_TYPE **) gm2((int) (sizeof(INSTANCE_TYPE *) * rcnt)); QueryCore->query = GetFirstArgument(); QueryCore->action = GetFirstArgument()->nextArg; if (TestForFirstInChain(qclasses,0) == TRUE) EvaluateExpression(QueryCore->action,result); AbortQuery = FALSE; BreakFlag = FALSE; rm((void *) QueryCore->solns,(int) (sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(query_core,QueryCore); PopQueryCore(); DeleteQueryClasses(qclasses); }
/****************************************************************************** NAME : DelayedQueryDoForAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and and exceutes a user-action for each set This function differs from QueryDoForAllInstances() in that it forms the complete list of query satisfactions BEFORE executing any actions. INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. The action is executed for evry query satisfaction. Caller's result buffer holds result of last action executed. NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void DelayedQueryDoForAllInstances( void *theEnv, EXEC_STATUS, DATA_OBJECT *result) { QUERY_CLASS *qclasses; unsigned rcnt; register unsigned i; result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv,execStatus); qclasses = DetermineQueryClasses(theEnv,execStatus,GetFirstArgument()->nextArg->nextArg, "delayed-do-for-all-instances",&rcnt); if (qclasses == NULL) return; PushQueryCore(theEnv,execStatus); InstanceQueryData(theEnv,execStatus)->QueryCore = get_struct(theEnv,execStatus,query_core); InstanceQueryData(theEnv,execStatus)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,execStatus,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv,execStatus)->QueryCore->query = GetFirstArgument(); InstanceQueryData(theEnv,execStatus)->QueryCore->action = NULL; InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set = NULL; InstanceQueryData(theEnv,execStatus)->QueryCore->soln_size = rcnt; InstanceQueryData(theEnv,execStatus)->QueryCore->soln_cnt = 0; TestEntireChain(theEnv,execStatus,qclasses,0); InstanceQueryData(theEnv,execStatus)->AbortQuery = FALSE; InstanceQueryData(theEnv,execStatus)->QueryCore->action = GetFirstArgument()->nextArg; while (InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set != NULL) { for (i = 0 ; i < rcnt ; i++) InstanceQueryData(theEnv,execStatus)->QueryCore->solns[i] = InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set->soln[i]; PopQuerySoln(theEnv,execStatus); execStatus->CurrentEvaluationDepth++; EvaluateExpression(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->action,result); execStatus->CurrentEvaluationDepth--; if (ProcedureFunctionData(theEnv,execStatus)->ReturnFlag == TRUE) { PropagateReturnValue(theEnv,execStatus,result); } PeriodicCleanup(theEnv,execStatus,FALSE,TRUE); if (execStatus->HaltExecution || ProcedureFunctionData(theEnv,execStatus)->BreakFlag || ProcedureFunctionData(theEnv,execStatus)->ReturnFlag) { while (InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set != NULL) PopQuerySoln(theEnv,execStatus); break; } } ProcedureFunctionData(theEnv,execStatus)->BreakFlag = FALSE; rm(theEnv,execStatus,(void *) InstanceQueryData(theEnv,execStatus)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,execStatus,query_core,InstanceQueryData(theEnv,execStatus)->QueryCore); PopQueryCore(theEnv,execStatus); DeleteQueryClasses(theEnv,execStatus,qclasses); }
/****************************************************************************** NAME : DelayedQueryDoForAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and and exceutes a user-action for each set This function differs from QueryDoForAllInstances() in that it forms the complete list of query satisfactions BEFORE executing any actions. INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. The action is executed for evry query satisfaction. Caller's result buffer holds result of last action executed. NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void DelayedQueryDoForAllInstances( DATA_OBJECT *result) { QUERY_CLASS *qclasses; int rcnt; register int i; result->type = SYMBOL; result->value = FalseSymbol; qclasses = DetermineQueryClasses(GetFirstArgument()->nextArg->nextArg, "delayed-do-for-all-instances",&rcnt); if (qclasses == NULL) return; PushQueryCore(); QueryCore = get_struct(query_core); QueryCore->solns = (INSTANCE_TYPE **) gm2((int) (sizeof(INSTANCE_TYPE *) * rcnt)); QueryCore->query = GetFirstArgument(); QueryCore->action = NULL; QueryCore->soln_set = NULL; QueryCore->soln_size = rcnt; QueryCore->soln_cnt = 0; TestEntireChain(qclasses,0); AbortQuery = FALSE; QueryCore->action = GetFirstArgument()->nextArg; while (QueryCore->soln_set != NULL) { for (i = 0 ; i < rcnt ; i++) QueryCore->solns[i] = QueryCore->soln_set->soln[i]; PopQuerySoln(); CurrentEvaluationDepth++; EvaluateExpression(QueryCore->action,result); CurrentEvaluationDepth--; if (ReturnFlag == TRUE) { PropagateReturnValue(result); } PeriodicCleanup(FALSE,TRUE); if (HaltExecution || BreakFlag || ReturnFlag) { while (QueryCore->soln_set != NULL) PopQuerySoln(); break; } } BreakFlag = FALSE; rm((void *) QueryCore->solns,(int) (sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(query_core,QueryCore); PopQueryCore(); DeleteQueryClasses(qclasses); }
/****************************************************************************** NAME : QueryFindAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and stores their names in the user's multi-field variable The sets are stored sequentially : Number of sets = (Multi-field length) / (Set length) The first set is if the first (set length) atoms of the multi-field variable, and so on. INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void QueryFindAllInstances( void *theEnv, EXEC_STATUS, DATA_OBJECT *result) { QUERY_CLASS *qclasses; unsigned rcnt; register unsigned i,j; result->type = MULTIFIELD; result->begin = 0; result->end = -1; qclasses = DetermineQueryClasses(theEnv,execStatus,GetFirstArgument()->nextArg, "find-all-instances",&rcnt); if (qclasses == NULL) { result->value = (void *) EnvCreateMultifield(theEnv,execStatus,0L); return; } PushQueryCore(theEnv,execStatus); InstanceQueryData(theEnv,execStatus)->QueryCore = get_struct(theEnv,execStatus,query_core); InstanceQueryData(theEnv,execStatus)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,execStatus,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv,execStatus)->QueryCore->query = GetFirstArgument(); InstanceQueryData(theEnv,execStatus)->QueryCore->action = NULL; InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set = NULL; InstanceQueryData(theEnv,execStatus)->QueryCore->soln_size = rcnt; InstanceQueryData(theEnv,execStatus)->QueryCore->soln_cnt = 0; TestEntireChain(theEnv,execStatus,qclasses,0); InstanceQueryData(theEnv,execStatus)->AbortQuery = FALSE; result->value = (void *) EnvCreateMultifield(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->soln_cnt * rcnt); while (InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set != NULL) { for (i = 0 , j = (unsigned) (result->end + 2) ; i < rcnt ; i++ , j++) { SetMFType(result->value,j,INSTANCE_NAME); SetMFValue(result->value,j,GetFullInstanceName(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->soln_set->soln[i])); } result->end = (long) j-2; PopQuerySoln(theEnv,execStatus); } rm(theEnv,execStatus,(void *) InstanceQueryData(theEnv,execStatus)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,execStatus,query_core,InstanceQueryData(theEnv,execStatus)->QueryCore); PopQueryCore(theEnv,execStatus); DeleteQueryClasses(theEnv,execStatus,qclasses); }
/****************************************************************************** NAME : QueryFindAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and stores their names in the user's multi-field variable The sets are stored sequentially : Number of sets = (Multi-field length) / (Set length) The first set is if the first (set length) atoms of the multi-field variable, and so on. INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void QueryFindAllInstances( DATA_OBJECT *result) { QUERY_CLASS *qclasses; int rcnt; register int i,j; result->type = MULTIFIELD; result->begin = 0; result->end = -1; qclasses = DetermineQueryClasses(GetFirstArgument()->nextArg, "find-all-instances",&rcnt); if (qclasses == NULL) { result->value = (void *) CreateMultifield(0L); return; } PushQueryCore(); QueryCore = get_struct(query_core); QueryCore->solns = (INSTANCE_TYPE **) gm2((int) (sizeof(INSTANCE_TYPE *) * rcnt)); QueryCore->query = GetFirstArgument(); QueryCore->action = NULL; QueryCore->soln_set = NULL; QueryCore->soln_size = rcnt; QueryCore->soln_cnt = 0; TestEntireChain(qclasses,0); AbortQuery = FALSE; result->value = (void *) CreateMultifield(QueryCore->soln_cnt * rcnt); while (QueryCore->soln_set != NULL) { for (i = 0 , j = result->end + 2 ; i < rcnt ; i++ , j++) { SetMFType(result->value,j,INSTANCE_NAME); SetMFValue(result->value,j,GetFullInstanceName(QueryCore->soln_set->soln[i])); } result->end = j-2; PopQuerySoln(); } rm((void *) QueryCore->solns,(int) (sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(query_core,QueryCore); PopQueryCore(); DeleteQueryClasses(qclasses); }
/****************************************************************************** NAME : QueryFindInstance DESCRIPTION : Finds the first set of instances which satisfy the query and stores their names in the user's multi-field variable INPUTS : Caller's result buffer RETURNS : TRUE if the query is satisfied, FALSE otherwise SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated zero or more times (depending on instance restrictions and how early the expression evaulates to TRUE - if at all). NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void QueryFindInstance( void *theEnv, EXEC_STATUS, DATA_OBJECT *result) { QUERY_CLASS *qclasses; unsigned rcnt,i; result->type = MULTIFIELD; result->begin = 0; result->end = -1; qclasses = DetermineQueryClasses(theEnv,execStatus,GetFirstArgument()->nextArg, "find-instance",&rcnt); if (qclasses == NULL) { result->value = (void *) EnvCreateMultifield(theEnv,execStatus,0L); return; } PushQueryCore(theEnv,execStatus); InstanceQueryData(theEnv,execStatus)->QueryCore = get_struct(theEnv,execStatus,query_core); InstanceQueryData(theEnv,execStatus)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,execStatus,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv,execStatus)->QueryCore->query = GetFirstArgument(); if (TestForFirstInChain(theEnv,execStatus,qclasses,0) == TRUE) { result->value = (void *) EnvCreateMultifield(theEnv,execStatus,rcnt); SetpDOEnd(result,rcnt); for (i = 1 ; i <= rcnt ; i++) { SetMFType(result->value,i,INSTANCE_NAME); SetMFValue(result->value,i,GetFullInstanceName(theEnv,execStatus,InstanceQueryData(theEnv,execStatus)->QueryCore->solns[i - 1])); } } else result->value = (void *) EnvCreateMultifield(theEnv,execStatus,0L); InstanceQueryData(theEnv,execStatus)->AbortQuery = FALSE; rm(theEnv,execStatus,(void *) InstanceQueryData(theEnv,execStatus)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,execStatus,query_core,InstanceQueryData(theEnv,execStatus)->QueryCore); PopQueryCore(theEnv,execStatus); DeleteQueryClasses(theEnv,execStatus,qclasses); }
/****************************************************************************** NAME : QueryFindInstance DESCRIPTION : Finds the first set of instances which satisfy the query and stores their names in the user's multi-field variable INPUTS : Caller's result buffer RETURNS : TRUE if the query is satisfied, FALSE otherwise SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated zero or more times (depending on instance restrictions and how early the expression evaulates to TRUE - if at all). NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void QueryFindInstance( DATA_OBJECT *result) { QUERY_CLASS *qclasses; int rcnt,i; result->type = MULTIFIELD; result->begin = 0; result->end = -1; qclasses = DetermineQueryClasses(GetFirstArgument()->nextArg, "find-instance",&rcnt); if (qclasses == NULL) { result->value = (void *) CreateMultifield(0L); return; } PushQueryCore(); QueryCore = get_struct(query_core); QueryCore->solns = (INSTANCE_TYPE **) gm2((int) (sizeof(INSTANCE_TYPE *) * rcnt)); QueryCore->query = GetFirstArgument(); if (TestForFirstInChain(qclasses,0) == TRUE) { result->value = (void *) CreateMultifield(rcnt); result->end = rcnt-1; for (i = 1 ; i <= rcnt ; i++) { SetMFType(result->value,i,INSTANCE_NAME); SetMFValue(result->value,i,GetFullInstanceName(QueryCore->solns[i - 1])); } } else result->value = (void *) CreateMultifield(0L); AbortQuery = FALSE; rm((void *) QueryCore->solns,(int) (sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(query_core,QueryCore); PopQueryCore(); DeleteQueryClasses(qclasses); }
/****************************************************************************** NAME : AnyInstances DESCRIPTION : Determines if there any existing instances which satisfy the query INPUTS : None RETURNS : TRUE if the query is satisfied, FALSE otherwise SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated zero or more times (depending on instance restrictions and how early the expression evaulates to TRUE - if at all). NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle BOOLEAN AnyInstances() { QUERY_CLASS *qclasses; int rcnt; int TestResult; qclasses = DetermineQueryClasses(GetFirstArgument()->nextArg, "any-instancep",&rcnt); if (qclasses == NULL) return(FALSE); PushQueryCore(); QueryCore = get_struct(query_core); QueryCore->solns = (INSTANCE_TYPE **) gm2((int) (sizeof(INSTANCE_TYPE *) * rcnt)); QueryCore->query = GetFirstArgument(); TestResult = TestForFirstInChain(qclasses,0); AbortQuery = FALSE; rm((void *) QueryCore->solns,(int) (sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(query_core,QueryCore); PopQueryCore(); DeleteQueryClasses(qclasses); return(TestResult); }
/****************************************************************************** NAME : AnyInstances DESCRIPTION : Determines if there any existing instances which satisfy the query INPUTS : None RETURNS : TRUE if the query is satisfied, FALSE otherwise SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated zero or more times (depending on instance restrictions and how early the expression evaulates to TRUE - if at all). NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle intBool AnyInstances( void *theEnv) { QUERY_CLASS *qclasses; unsigned rcnt; int TestResult; qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg, "any-instancep",&rcnt); if (qclasses == NULL) return(FALSE); PushQueryCore(theEnv); InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core); InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument(); TestResult = TestForFirstInChain(theEnv,qclasses,0); InstanceQueryData(theEnv)->AbortQuery = FALSE; rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore); PopQueryCore(theEnv); DeleteQueryClasses(theEnv,qclasses); return(TestResult); }
/************************************************************* NAME : FormChain DESCRIPTION : Builds a list of classes to be used in instance queries - uses parse form. INPUTS : 1) Name of calling function for error msgs 2) Data object - must be a symbol or a multifield value containing all symbols The symbols must be names of existing classes RETURNS : The query chain, or NULL on errors SIDE EFFECTS : Memory allocated for chain Busy count incremented for all classes NOTES : None *************************************************************/ static QUERY_CLASS *FormChain( void *theEnv, EXEC_STATUS, char *func, DATA_OBJECT *val) { DEFCLASS *cls; QUERY_CLASS *head,*bot,*tmp; register long i,end; /* 6.04 Bug Fix */ char *className; struct defmodule *currentModule; currentModule = ((struct defmodule *) EnvGetCurrentModule(theEnv,execStatus)); if (val->type == DEFCLASS_PTR) { IncrementDefclassBusyCount(theEnv,execStatus,(void *) val->value); head = get_struct(theEnv,execStatus,query_class); head->cls = (DEFCLASS *) val->value; if (DefclassInScope(theEnv,execStatus,head->cls,currentModule)) head->theModule = currentModule; else head->theModule = head->cls->header.whichModule->theModule; head->chain = NULL; head->nxt = NULL; return(head); } if (val->type == SYMBOL) { /* =============================================== Allow instance-set query restrictions to have a module specifier as part of the class name, but search imported defclasses too if a module specifier is not given =============================================== */ cls = LookupDefclassByMdlOrScope(theEnv,execStatus,DOPToString(val)); if (cls == NULL) { ClassExistError(theEnv,execStatus,func,DOPToString(val)); return(NULL); } IncrementDefclassBusyCount(theEnv,execStatus,(void *) cls); head = get_struct(theEnv,execStatus,query_class); head->cls = cls; if (DefclassInScope(theEnv,execStatus,head->cls,currentModule)) head->theModule = currentModule; else head->theModule = head->cls->header.whichModule->theModule; head->chain = NULL; head->nxt = NULL; return(head); } if (val->type == MULTIFIELD) { head = bot = NULL; end = GetpDOEnd(val); for (i = GetpDOBegin(val) ; i <= end ; i++) { if (GetMFType(val->value,i) == SYMBOL) { className = ValueToString(GetMFValue(val->value,i)); cls = LookupDefclassByMdlOrScope(theEnv,execStatus,className); if (cls == NULL) { ClassExistError(theEnv,execStatus,func,className); DeleteQueryClasses(theEnv,execStatus,head); return(NULL); } } else { DeleteQueryClasses(theEnv,execStatus,head); return(NULL); } IncrementDefclassBusyCount(theEnv,execStatus,(void *) cls); tmp = get_struct(theEnv,execStatus,query_class); tmp->cls = cls; if (DefclassInScope(theEnv,execStatus,tmp->cls,currentModule)) tmp->theModule = currentModule; else tmp->theModule = tmp->cls->header.whichModule->theModule; tmp->chain = NULL; tmp->nxt = NULL; if (head == NULL) head = tmp; else bot->chain = tmp; bot = tmp; } return(head); } return(NULL); }
/****************************************************************************** NAME : DelayedQueryDoForAllInstances DESCRIPTION : Finds all sets of instances which satisfy the query and and exceutes a user-action for each set This function differs from QueryDoForAllInstances() in that it forms the complete list of query satisfactions BEFORE executing any actions. INPUTS : Caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : The query class-expressions are evaluated once, and the query boolean-expression is evaluated once for every instance set. The action is executed for evry query satisfaction. Caller's result buffer holds result of last action executed. NOTES : H/L Syntax : See ParseQueryNoAction() ******************************************************************************/ globle void DelayedQueryDoForAllInstances( void *theEnv, DATA_OBJECT *result) { QUERY_CLASS *qclasses; unsigned rcnt; register unsigned i; struct garbageFrame newGarbageFrame; struct garbageFrame *oldGarbageFrame; result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv); qclasses = DetermineQueryClasses(theEnv,GetFirstArgument()->nextArg->nextArg, "delayed-do-for-all-instances",&rcnt); if (qclasses == NULL) return; PushQueryCore(theEnv); InstanceQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core); InstanceQueryData(theEnv)->QueryCore->solns = (INSTANCE_TYPE **) gm2(theEnv,(sizeof(INSTANCE_TYPE *) * rcnt)); InstanceQueryData(theEnv)->QueryCore->query = GetFirstArgument(); InstanceQueryData(theEnv)->QueryCore->action = NULL; InstanceQueryData(theEnv)->QueryCore->soln_set = NULL; InstanceQueryData(theEnv)->QueryCore->soln_size = rcnt; InstanceQueryData(theEnv)->QueryCore->soln_cnt = 0; TestEntireChain(theEnv,qclasses,0); InstanceQueryData(theEnv)->AbortQuery = FALSE; InstanceQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg; oldGarbageFrame = UtilityData(theEnv)->CurrentGarbageFrame; memset(&newGarbageFrame,0,sizeof(struct garbageFrame)); newGarbageFrame.priorFrame = oldGarbageFrame; UtilityData(theEnv)->CurrentGarbageFrame = &newGarbageFrame; while (InstanceQueryData(theEnv)->QueryCore->soln_set != NULL) { for (i = 0 ; i < rcnt ; i++) InstanceQueryData(theEnv)->QueryCore->solns[i] = InstanceQueryData(theEnv)->QueryCore->soln_set->soln[i]; PopQuerySoln(theEnv); EvaluateExpression(theEnv,InstanceQueryData(theEnv)->QueryCore->action,result); if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag) { while (InstanceQueryData(theEnv)->QueryCore->soln_set != NULL) PopQuerySoln(theEnv); break; } CleanCurrentGarbageFrame(theEnv,NULL); CallPeriodicTasks(theEnv); } RestorePriorGarbageFrame(theEnv,&newGarbageFrame,oldGarbageFrame,result); CallPeriodicTasks(theEnv); ProcedureFunctionData(theEnv)->BreakFlag = FALSE; rm(theEnv,(void *) InstanceQueryData(theEnv)->QueryCore->solns,(sizeof(INSTANCE_TYPE *) * rcnt)); rtn_struct(theEnv,query_core,InstanceQueryData(theEnv)->QueryCore); PopQueryCore(theEnv); DeleteQueryClasses(theEnv,qclasses); }