/* boolean merge expression */ Expr * boolMergeExpr(int op, Expr *arg) { /* error guard */ if (arg == NULL) return NULL; /* check argument semantics */ if (arg->sem != SEM_BOOLEAN) { synerr(); fprintf(stderr, "operator \"%s\" requires boolean valued argument\n", opStrings(op)); return NULL; } return mergeExpr(op, arg); }
/* fill in appropriate evaluator function for given Expr */ void findEval(Expr *x) { int arity = 0; Metric *m; /* * arity values constructed from bit masks * 1 arg1 has tspan 1, and must always have one metric value * 2 arg2 has tspan 1, and must always have one metric value */ if (x->arg1 && x->arg1->tspan == 1) { for (m = x->arg1->metrics; m; m = m->next) { if (m->desc.indom == PM_INDOM_NULL) continue; if (m->specinst == 0) break; } if (m == NULL) arity |= 1; } if (x->arg2 && x->arg2->tspan == 1) { for (m = x->arg2->metrics; m; m = m->next) { if (m->desc.indom == PM_INDOM_NULL) continue; if (m->specinst == 0) break; } if (m == NULL) arity |= 2; } /* * never come here with x->op == NULL or OP_VAR */ switch (x->op) { case RULE: x->eval = rule; break; case CND_RULESET: x->eval = ruleset; break; case CND_FETCH: if (x->metrics->desc.indom == PM_INDOM_NULL || x->metrics->conv == 0) x->eval = cndFetch_1; else if (x->metrics->specinst == 0) x->eval = cndFetch_all; else x->eval = cndFetch_n; break; case CND_SUM_HOST: x->eval = cndSum_host; break; case CND_SUM_INST: x->eval = cndSum_inst; break; case CND_SUM_TIME: x->eval = cndSum_time; break; case CND_AVG_HOST: x->eval = cndAvg_host; break; case CND_AVG_INST: x->eval = cndAvg_inst; break; case CND_AVG_TIME: x->eval = cndAvg_time; break; case CND_MAX_HOST: x->eval = cndMax_host; break; case CND_MAX_INST: x->eval = cndMax_inst; break; case CND_MAX_TIME: x->eval = cndMax_time; break; case CND_MIN_HOST: x->eval = cndMin_host; break; case CND_MIN_INST: x->eval = cndMin_inst; break; case CND_MIN_TIME: x->eval = cndMin_time; break; case CND_ALL_HOST: x->eval = cndAll_host; break; case CND_ALL_INST: x->eval = cndAll_inst; break; case CND_ALL_TIME: x->eval = cndAll_time; break; case CND_SOME_HOST: x->eval = cndSome_host; break; case CND_SOME_INST: x->eval = cndSome_inst; break; case CND_SOME_TIME: x->eval = cndSome_time; break; case CND_PCNT_HOST: x->eval = cndPcnt_host; break; case CND_PCNT_INST: x->eval = cndPcnt_inst; break; case CND_PCNT_TIME: x->eval = cndPcnt_time; break; case CND_COUNT_HOST: x->eval = cndCount_host; break; case CND_COUNT_INST: x->eval = cndCount_inst; break; case CND_COUNT_TIME: x->eval = cndCount_time; break; case ACT_SEQ: x->eval = actAnd; break; case ACT_ALT: x->eval = actOr; break; case ACT_SHELL: x->eval = actShell; break; case ACT_ALARM: x->eval = actAlarm; break; case ACT_STOMP: x->eval = actStomp; break; case ACT_SYSLOG: x->eval = actSyslog; break; case ACT_PRINT: x->eval = actPrint; break; case ACT_ARG: x->eval = actArg; break; case CND_DELAY: if (arity & 1) x->eval = cndDelay_1; else x->eval = cndDelay_n; break; case CND_RATE: if (arity & 1) x->eval = cndRate_1; else x->eval = cndRate_n; break; case CND_INSTANT: if (arity & 1) x->eval = cndInstant_1; else x->eval = cndInstant_n; break; case CND_NEG: if (arity & 1) x->eval = cndNeg_1; else x->eval = cndNeg_n; break; case CND_NOT: if (arity & 1) x->eval = cndNot_1; else x->eval = cndNot_n; break; case CND_RISE: if (arity & 1) x->eval = cndRise_1; else x->eval = cndRise_n; break; case CND_FALL: if (arity & 1) x->eval = cndFall_1; else x->eval = cndFall_n; break; case CND_ADD: if (arity & 1) { if (arity & 2) x->eval = cndAdd_1_1; else x->eval = cndAdd_1_n; } else { if (arity & 2) x->eval = cndAdd_n_1; else x->eval = cndAdd_n_n; } break; case CND_SUB: if (arity & 1) { if (arity & 2) x->eval = cndSub_1_1; else x->eval = cndSub_1_n; } else { if (arity & 2) x->eval = cndSub_n_1; else x->eval = cndSub_n_n; } break; case CND_MUL: if (arity & 1) { if (arity & 2) x->eval = cndMul_1_1; else x->eval = cndMul_1_n; } else { if (arity & 2) x->eval = cndMul_n_1; else x->eval = cndMul_n_n; } break; case CND_DIV: if (arity & 1) { if (arity & 2) x->eval = cndDiv_1_1; else x->eval = cndDiv_1_n; } else { if (arity & 2) x->eval = cndDiv_n_1; else x->eval = cndDiv_n_n; } break; case CND_EQ: if (arity & 1) { if (arity & 2) x->eval = cndEq_1_1; else x->eval = cndEq_1_n; } else { if (arity & 2) x->eval = cndEq_n_1; else x->eval = cndEq_n_n; } break; case CND_NEQ: if (arity & 1) { if (arity & 2) x->eval = cndNeq_1_1; else x->eval = cndNeq_1_n; } else { if (arity & 2) x->eval = cndNeq_n_1; else x->eval = cndNeq_n_n; } break; case CND_LT: if (arity & 1) { if (arity & 2) x->eval = cndLt_1_1; else x->eval = cndLt_1_n; } else { if (arity & 2) x->eval = cndLt_n_1; else x->eval = cndLt_n_n; } break; case CND_LTE: if (arity & 1) { if (arity & 2) x->eval = cndLte_1_1; else x->eval = cndLte_1_n; } else { if (arity & 2) x->eval = cndLte_n_1; else x->eval = cndLte_n_n; } break; case CND_GT: if (arity & 1) { if (arity & 2) x->eval = cndGt_1_1; else x->eval = cndGt_1_n; } else { if (arity & 2) x->eval = cndGt_n_1; else x->eval = cndGt_n_n; } break; case CND_GTE: if (arity & 1) { if (arity & 2) x->eval = cndGte_1_1; else x->eval = cndGte_1_n; } else { if (arity & 2) x->eval = cndGte_n_1; else x->eval = cndGte_n_n; } break; case CND_AND: if (arity & 1) { if (arity & 2) x->eval = cndAnd_1_1; else x->eval = cndAnd_1_n; } else { if (arity & 2) x->eval = cndAnd_n_1; else x->eval = cndAnd_n_n; } break; case CND_OR: if (arity & 1) { if (arity & 2) x->eval = cndOr_1_1; else x->eval = cndOr_1_n; } else { if (arity & 2) x->eval = cndOr_n_1; else x->eval = cndOr_n_n; } break; case CND_MATCH: case CND_NOMATCH: x->eval = cndMatch_inst; break; case CND_OTHER: /* OTHER is not really evaluated in this sense, see ruleset() */ x->eval = NULL; break; default: __pmNotifyErr(LOG_ERR, "findEval: internal error: bad op (%d) %s\n", x->op, opStrings(x->op)); dumpExpr(x); exit(1); } /* patch in fake actions for archive mode */ if (archives && (x->op == ACT_SHELL || x->op == ACT_ALARM || x->op == ACT_SYSLOG || x->op == ACT_PRINT || x->op == ACT_STOMP)) { x->eval = actFake; } }
void __dumpExpr(int level, Expr *x) { int i; int j; int k; for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, "Expr dump @ " PRINTF_P_PFX "%p\n", x); if (x == NULL) return; for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, " op=%d (%s) arg1=" PRINTF_P_PFX "%p arg2=" PRINTF_P_PFX "%p parent=" PRINTF_P_PFX "%p\n", x->op, opStrings(x->op), x->arg1, x->arg2, x->parent); for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, " eval="); for (j = 0; fn_map[j].addr; j++) { if (x->eval == fn_map[j].addr) { fprintf(stderr, "%s", fn_map[j].name); break; } } if (fn_map[j].addr == NULL) fprintf(stderr, "" PRINTF_P_PFX "%p()", x->eval); fprintf(stderr, " metrics=" PRINTF_P_PFX "%p ring=" PRINTF_P_PFX "%p\n", x->metrics, x->ring); for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, " valid=%d cardinality[H,I,T]=[%d,%d,%d] tspan=%d\n", x->valid, x->hdom, x->e_idom, x->tdom, x->tspan); for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, " nsmpls=%d nvals=%d sem=", x->nsmpls, x->nvals); for (j = 0; sem_map[j].name; j++) { if (x->sem == sem_map[j].val) { fprintf(stderr, "%s", sem_map[j].name); break; } } if (sem_map[j].name == NULL) fprintf(stderr, "%d", x->sem); if (UNITS_UNKNOWN(x->units)) fprintf(stderr, " units=UNKNOWN\n"); else fprintf(stderr, " units=%s\n", pmUnitsStr(&x->units)); if (x->valid > 0) { if (x->sem == SEM_BOOLEAN || x->sem == SEM_CHAR || x->sem == SEM_NUMVAR || x->sem == SEM_NUMCONST || x->sem == PM_SEM_COUNTER || x->sem == PM_SEM_INSTANT || x->sem == PM_SEM_DISCRETE) { for (j = 0; j < x->nsmpls; j++) { for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, " smpls[%d].ptr " PRINTF_P_PFX "%p ", j, x->smpls[j].ptr); for (k = 0; k < x->tspan; k++) { if (x->tspan > 1 && x->sem != SEM_CHAR) { if (k > 0) fprintf(stderr, ", "); fprintf(stderr, "{%d} ", k); } if (x->sem == SEM_BOOLEAN) { char c = *((char *)x->smpls[j].ptr+k); if ((int)c == B_TRUE) fprintf(stderr, "true"); else if ((int)c == B_FALSE) fprintf(stderr, "false"); else if ((int)c == B_UNKNOWN) fprintf(stderr, "unknown"); else fprintf(stderr, "bogus (0x%x)", c & 0xff); } else if (x->sem == SEM_CHAR) { if (k == 0) fprintf(stderr, "\"%s\"", (char *)x->smpls[j].ptr); } else { double v = *((double *)x->smpls[j].ptr+k); int fp_bad = 0; #ifdef HAVE_FPCLASSIFY fp_bad = fpclassify(v) == FP_NAN; #else #ifdef HAVE_ISNAN fp_bad = isnan(v); #endif #endif if (fp_bad) fputc('?', stderr); else fprintf(stderr, "%g", v); } } fputc('\n', stderr); } } else if (x->sem == SEM_REGEX) { for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, " handle=" PRINTF_P_PFX "%p\n", x->ring); } } }