c_char * q_propertyName( q_expr e) { q_expr p; c_char *name; c_long len,i; if (q_isFnc(e,Q_EXPR_PROPERTY)) { i=0; len = 0; while ((p = q_getPar(e,i)) != NULL) { len = len + 1 + strlen(q_getId(p)); i++; } name = (c_char *)os_malloc(len); i=0; name[0]=0; while ((p = q_getPar(e,i)) != NULL) { if (i!=0) os_strcat(name,"."); os_strcat(name,q_getId(p)); i++; } } else { assert(FALSE); name = NULL; } return name; }
c_bool u_topicContentFilterValidate ( u_topic _this, q_expr expr, c_value params[]) { v_topic topic; c_type type; c_bool result; q_expr subexpr, term; int i; v_filter filter; u_result uResult; result = FALSE; filter = NULL; uResult = u_entityReadClaim(u_entity(_this), (v_entity*)(&topic)); if (uResult == U_RESULT_OK) { assert(topic); type = v_topicMessageType(topic); i = 0; subexpr = q_getPar(expr, i); /* get rid of Q_EXPR_PROGRAM */ while ((term = q_getPar(subexpr, i++)) != NULL) { if (q_getTag(term) == Q_EXPR_WHERE) { filter = v_filterNew(topic, term, params); } } u_entityRelease(u_entity(_this)); } if (filter != NULL) { result = TRUE; c_free(filter); } return result; }
static void q_countVarWalk( q_expr e, c_iter list) { q_list l; q_expr found; if (e != NULL) { switch(e->kind) { case T_VAR: found = c_iterResolve(list,compareVar,e); if (found == NULL) { list = c_iterInsert(list,e); } break; case T_FNC: if (e->info.function->tag == Q_EXPR_CALLBACK) { q_countVarWalk(q_getPar(e,2),list); } else { l = e->info.function->params; while (l != NULL) { q_countVarWalk(l->expr,list); l = l->next; } } break; default: break; } } }
q_expr q_removeNots( q_expr e) { q_expr r,p; c_long len,i; if (e == NULL) { return NULL; } if (e->kind == T_FNC) { switch (e->info.function->tag) { case Q_EXPR_NOT: r = q_removeNots(q_deNot(q_takePar(e,0))); break; default: len = q_getLen(e); for (i=0;i<len;i++) { p = q_removeNots(q_getPar(e,i)); q_swapPar(e,i,p); } r = e; } } else { r = e; } return r; }
u_bool u_topicContentFilterValidate ( const u_topic _this, const q_expr expr, const c_value params[], os_uint32 nrOfParams) { v_topic topic; u_bool result; q_expr subexpr, term; int i; v_filter filter; u_result uResult; assert(_this); assert(expr); result = FALSE; filter = NULL; uResult = u_topicReadClaim(_this, &topic, C_MM_RESERVATION_LOW); if (uResult == U_RESULT_OK) { assert(topic); i = 0; subexpr = q_getPar(expr, i); /* get rid of Q_EXPR_PROGRAM */ while ((term = q_getPar(subexpr, i++)) != NULL) { if (q_getTag(term) == Q_EXPR_WHERE) { filter = v_filterNew(v_topicMessageType(topic), v_topicMessageKeyList(topic), term, params, nrOfParams); } } u_topicRelease(_this, C_MM_RESERVATION_LOW); } if (filter != NULL) { result = TRUE; c_free(filter); } return result; }
void q_print( q_expr e, c_long i) { char llstr[36]; q_list l; c_long n,p; c_string name; c_string metaName; if (e == NULL) return; switch(e->kind) { case T_VAR: case T_INT: llstr[35] = '\0'; printf("%s",os_lltostr(e->info.integer, &llstr[35])); break; case T_DBL: printf("%f",e->info.real); break; case T_CHR: printf("\'%c\'",e->info.character); break; case T_STR: printf("%s",e->info.string); break; case T_ID: printf("%s",e->info.string); break; case T_FNC: if (e->info.function->tag == Q_EXPR_CALLBACK) { name = (c_char *)q_tagImage(e->info.function->tag); metaName = c_metaName(c_metaObject(q_getTyp(q_getPar(e,0)))); if (metaName != NULL) { printf("%s(<%s>,0x" PA_ADDRFMT,name,metaName,(c_address)q_getPar(e,1)); c_free(metaName); } else { printf("%s(<anonomous type>,0x" PA_ADDRFMT,name,(c_address)q_getPar(e,1)); } p = i+strlen(name)+1; printf(",\n"); for (n=0;n<p;n++) printf(" "); q_print(q_getPar(e,2),p); printf(")"); } else { name = (c_char *)q_tagImage(e->info.function->tag); printf("%s(",name); p = i+strlen(name)+1; l = e->info.function->params; if (l != NULL) { q_print(l->expr,p); l = l->next; } while (l != NULL) { printf(",\n"); for (n=0;n<p;n++) printf(" "); q_print(l->expr,p); l = l->next; } printf(")"); } break; case T_TYP: name = c_metaName(c_metaObject(e->info.type)); if (name == NULL) { printf("<unnamed type>"); } else { printf("%s",name); } c_free(name); break; case T_ERR: break; } }
q_expr q_takeKey( q_expr *e, c_array keyList) { q_expr *l,*r,p,q,x; c_long i,len; c_char qn[1024]; q_tag tag; if (e == NULL) return NULL; if (*e == NULL) return NULL; len = c_arraySize(keyList); if (len == 0) { return NULL; } switch (q_getKind(*e)) { case T_FNC: tag = q_getTag(*e); switch (tag) { case Q_EXPR_AND: l = &(*e)->info.function->params->expr; r = &(*e)->info.function->params->next->expr; p = q_takeKey(l,keyList); q = q_takeKey(r,keyList); if ((*l == NULL) && (*r == NULL)) { q_dispose(*e); *e = NULL; } else if ((*l == NULL) && (*r != NULL)) { x = *r; *r = NULL; q_dispose(*e); *e = x; } else if ((*l != NULL) && (*r == NULL)) { x = *l; *l = NULL; q_dispose(*e); *e = x; } if (p == NULL) { if (q == NULL) return NULL; return q; } else { if (q == NULL) { return p; } return q_newFnc(tag,q_insert(q_insert(NULL,p),q)); } case Q_EXPR_EQ: case Q_EXPR_NE: case Q_EXPR_LT: case Q_EXPR_LE: case Q_EXPR_GT: case Q_EXPR_GE: case Q_EXPR_LIKE: l = &(*e)->info.function->params->expr; r = &(*e)->info.function->params->next->expr; if (q_takeKey(l,keyList) != NULL) { if (q_takeKey(r,keyList) != NULL) { p = *e; *e = NULL; return p; } } return NULL; case Q_EXPR_PROPERTY: i=0; qn[0]=0; while ((p = q_getPar(*e,i)) != NULL) { if (i!=0) os_strcat(qn,"."); os_strcat(qn,q_getId(p)); i++; } for (i=0; i<len; i++) { if (strcmp(qn,c_fieldName(keyList[i])) == 0) { return *e; } } return NULL; case Q_EXPR_CALLBACK: return NULL; default: assert(FALSE); break; } break; case T_VAR: case T_INT: case T_DBL: case T_CHR: case T_STR: return *e; case T_TYP: case T_ERR: break; case T_ID: for (i=0; i<len; i++) { if (strcmp(qn,c_fieldName(keyList[i])) == 0) { return *e; } } return NULL; default: assert(FALSE); break; } return NULL; }
q_expr q_takeField( q_expr *e, c_string name) { q_expr *l,*r,p,q,x; c_long i; c_char qn[1024]; q_tag tag; if (e == NULL) return NULL; if (*e == NULL) return NULL; switch (q_getKind(*e)) { case T_FNC: tag = q_getTag(*e); switch (tag) { case Q_EXPR_PROGRAM: return q_takeField(&(*e)->info.function->params->expr,name); case Q_EXPR_OR: /* This function should never be used upon an OR expression. However if that functionality is required then this function should be redesigned. */ assert(FALSE); break; case Q_EXPR_AND: l = &(*e)->info.function->params->expr; r = &(*e)->info.function->params->next->expr; p = q_takeField(l,name); q = q_takeField(r,name); if ((*l == NULL) && (*r == NULL)) { q_dispose(*e); *e = NULL; } else if ((*l == NULL) && (*r != NULL)) { x = *r; *r = NULL; q_dispose(*e); *e = x; } else if ((*l != NULL) && (*r == NULL)) { x = *l; *l = NULL; q_dispose(*e); *e = x; } if (p == NULL) { if (q == NULL) return NULL; return q; } else { if (q == NULL) { return p; } return q_newFnc(tag,q_insert(q_insert(NULL,p),q)); } case Q_EXPR_EQ: case Q_EXPR_NE: case Q_EXPR_LT: case Q_EXPR_LE: case Q_EXPR_GT: case Q_EXPR_GE: case Q_EXPR_LIKE: l = &(*e)->info.function->params->expr; r = &(*e)->info.function->params->next->expr; p = *e; if (q_takeField(l,name) != NULL) { *e = NULL; return p; } if (q_takeField(r,name) != NULL) { *e = NULL; return p; } return NULL; case Q_EXPR_NOT: p = *e; if (q_takeField(&(*e)->info.function->params->expr,name) != NULL) { *e = NULL; return p; } break; case Q_EXPR_PROPERTY: i=0; qn[0]=0; while ((p = q_getPar(*e,i)) != NULL) { if (i!=0) os_strcat(qn,"."); os_strcat(qn,q_getId(p)); i++; } if (strcmp(qn,name) == 0) return *e; return NULL; case Q_EXPR_CALLBACK: return q_exprCopy(*e); default: assert(FALSE); break; } break; case T_TYP: case T_VAR: case T_INT: case T_DBL: case T_CHR: case T_STR: case T_ERR: break; case T_ID: if (strcmp(q_getId(*e),name) == 0) return *e; return NULL; default: assert(FALSE); break; } return NULL; }
q_expr q_exprCopy( q_expr e) { q_list n = NULL; q_expr copy; if (e == NULL) { return NULL; } switch (q_getKind(e)) { case T_FNC: if (e->info.function->tag == Q_EXPR_CALLBACK) { /* The first parameter specifies the result type of the callback function. */ /* The second parameter is not of type q_expr but is a function pointer. */ /* The function pointer is the address of the callback function. */ /* increment ref count of internal c_type because it is being copied */ c_keep (q_getTyp(q_getPar(e,0))); n = q_append(n,q_getPar(e,0)); n = q_append(n,q_getPar(e,1)); n = q_append(n,q_exprCopy(q_getPar(e,2))); copy = q_newFnc(q_getTag(e),n); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; } else { copy = q_newFnc(q_getTag(e),q_listCopy(q_getLst(e,0))); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; } case T_TYP: copy = q_newTyp(q_getTyp(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; case T_VAR: copy = q_newVar(q_getVar(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; case T_INT: copy = q_newInt(q_getInt(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; case T_DBL: copy = q_newDbl(q_getDbl(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; case T_CHR: copy = q_newChr(q_getChr(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; case T_STR: copy = q_newStr(q_getStr(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; case T_ID: copy = q_newId(q_getId(e)); q_exprSetText(copy, e->text); q_exprSetInstanceState(copy, e->instanceState); q_exprSetSampleState(copy, e->sampleState); q_exprSetViewState(copy, e->viewState); return copy; default: assert(FALSE); break; } return NULL; }
void q_disjunctify( q_expr e) { q_expr leftTerm, rightTerm; c_long len,i; q_expr newTerm, notTerm; if (e == NULL) return; if (e->kind == T_FNC) { switch (e->info.function->tag) { case Q_EXPR_AND: #if 1 q_promote(e); #else leftTerm = q_leftPar(e); rightTerm = q_rightPar(e); q_disjunctify(leftTerm); q_disjunctify(rightTerm); if (q_isFnc(leftTerm,Q_EXPR_OR)) { newTerm = F2(Q_EXPR_AND,q_rightPar(leftTerm),q_exprCopy(rightTerm)); q_swapRight(leftTerm,q_swapRight(e,newTerm)); q_setTag(leftTerm,Q_EXPR_AND); q_setTag(e,Q_EXPR_OR); q_disjunctify(e); } if (q_isFnc(rightTerm,Q_EXPR_OR)) { newTerm = F2(Q_EXPR_AND,q_rightPar(rightTerm),q_exprCopy(leftTerm)); q_swapRight(rightTerm,q_swapLeft(e,newTerm)); q_setTag(rightTerm,Q_EXPR_AND); q_setTag(e,Q_EXPR_OR); q_disjunctify(e); } #endif break; case Q_EXPR_OR: leftTerm = q_leftPar(e); rightTerm = q_rightPar(e); q_disjunctify(leftTerm); q_disjunctify(rightTerm); break; case Q_EXPR_NOT: notTerm = q_getPar(e,0); if (notTerm->kind == T_FNC) { switch (notTerm->info.function->tag) { case Q_EXPR_NOT: q_swapExpr(e,q_takePar(notTerm,0)); q_dispose(notTerm); q_disjunctify(e); break; case Q_EXPR_OR: case Q_EXPR_AND: /* e = not (A and/or B) */ notTerm = q_takePar(e,0); /* e = not; notTerm = (A and/or B); */ newTerm = F1(Q_EXPR_NOT,q_exprCopy(q_getPar(notTerm,0))); /* newTerm = not A */ #if 1 q_disjunctify(newTerm); #endif q_swapPar(notTerm,0,newTerm); /* notTerm = (not A) and/or B */ newTerm = F1(Q_EXPR_NOT,q_exprCopy(q_getPar(notTerm,1))); /* newTerm = not B */ #if 1 q_disjunctify(newTerm); #endif q_swapPar(notTerm,1,newTerm); /* notTerm = (not A) and/or (not B) */ if (notTerm->info.function->tag == Q_EXPR_OR) { notTerm->info.function->tag = Q_EXPR_AND; } else { notTerm->info.function->tag = Q_EXPR_OR; } /* notTerm = (not A) or/and (not B) */ q_swapExpr(e,notTerm); /* e = (not A) or/and (not B) */ q_dispose(notTerm); #if 0 q_disjunctify(e); #endif break; #define _CASE_(l,n) case l: notTerm = q_takePar(e,0); \ q_swapExpr(e,notTerm); \ e->info.function->tag = n; \ q_dispose(notTerm); \ q_disjunctify(e); \ break _CASE_(Q_EXPR_EQ,Q_EXPR_NE); _CASE_(Q_EXPR_NE,Q_EXPR_EQ); _CASE_(Q_EXPR_LT,Q_EXPR_GE); _CASE_(Q_EXPR_LE,Q_EXPR_GT); _CASE_(Q_EXPR_GT,Q_EXPR_LE); _CASE_(Q_EXPR_GE,Q_EXPR_LT); #undef _CASE_ default: /* let it be */ break; } } break; case Q_EXPR_CALLBACK: q_disjunctify(q_getPar(e,2)); break; default: /* let it be */ len = q_getLen(e); for (i=0;i<len;i++) { q_disjunctify(q_getPar(e,i)); } break; } } }