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; }
q_expr q_takeTerm( q_expr *e) { q_expr or,left; or = *e; if (or == NULL) { return NULL; } if ((q_getKind(or) != T_FNC) || (q_getTag(or) != Q_EXPR_OR)) { *e = NULL; return or; } left = q_takePar(or,0); *e = q_takePar(or,0); q_listDispose(or->info.function->params); os_free(or->info.function); os_free(or); return left; }
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; }
/** * The following method like many other implement a generic expr walk with specific functionality. */ void q_prefixFieldNames ( q_expr *e, c_char *prefix) { q_tag tag; q_expr p; q_list list; if (e == NULL) return; if (*e == NULL) return; if (prefix == NULL) return; if (strlen(prefix) == 0) return; switch (q_getKind(*e)) { case T_FNC: tag = q_getTag(*e); switch (tag) { case Q_EXPR_AND: case Q_EXPR_OR: 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: q_prefixFieldNames(&(*e)->info.function->params->expr,prefix); q_prefixFieldNames(&(*e)->info.function->params->next->expr,prefix); return; case Q_EXPR_NOT: q_prefixFieldNames(&(*e)->info.function->params->expr,prefix); break; case Q_EXPR_PROPERTY: list = q_listCopy(q_getLst(*e,0)); list = q_insert(list,q_newId(prefix)); p = q_newFnc(Q_EXPR_PROPERTY,list); q_swapExpr(*e,p); q_dispose(p); return; case Q_EXPR_CALLBACK: return; case Q_EXPR_PROGRAM: q_prefixFieldNames(&(*e)->info.function->params->expr,prefix); break; default: assert(FALSE); break; } break; case T_VAR: case T_INT: case T_DBL: case T_CHR: case T_STR: case T_TYP: case T_ERR: break; case T_ID: list = q_insert(NULL,q_newId(q_getId(*e))); list = q_insert(list,q_newId(prefix)); p = q_newFnc(Q_EXPR_PROPERTY,list); q_swapExpr(*e,p); q_dispose(p); return; default: assert(FALSE); 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; }