Ejemplo n.º 1
0
void walkReplaceBuiltin(ACCExpr *expr)
{
    while(1) {
    if (expr->value == "__bitconcat") {
        ACCExpr *list = expr->operands.front();
        if (list->value == PARAMETER_MARKER)
            list->value = "{";
        expr->value = list->value;
        expr->operands = list->operands;
    }
    else if (expr->value == "__bitsubstr") {
        ACCExpr *list = expr->operands.front();
        ACCExpr *bitem = list->operands.front();
        if (!isIdChar(bitem->value[0])) {  // can only do bit select on net or reg (not expressions)
            printf("[%s:%d] can only do __bitsubstr on elementary items\n", __FUNCTION__, __LINE__);
            dumpExpr("BITSUB", expr);
            exit(-1);
        }
        bitem->operands.push_back(allocExpr("[", allocExpr(":", getRHS(list), getRHS(list, 2))));
        expr->value = bitem->value;
        expr->operands = bitem->operands;
    }
    else if (expr->value == "__phi") {
        ACCExpr *list = expr->operands.front(); // get "(" list of [":", cond, value] items
        int size = list->operands.size();
        ACCExpr *firstInList = getRHS(list, 0), *secondInList = getRHS(list);
        ACCExpr *newe = nullptr;
        if (size == 2 && matchExpr(getRHS(firstInList, 0), invertExpr(getRHS(secondInList, 0))))
            newe = allocExpr("?", getRHS(firstInList, 0), getRHS(firstInList), getRHS(secondInList));
        else if (size == 2 && getRHS(firstInList, 0)->value == "__default" && exprWidth(getRHS(secondInList)) == 1)
            newe = allocExpr("&", getRHS(secondInList, 0), getRHS(secondInList));
        else if (size == 1)
            newe = getRHS(firstInList);
        else {
            //dumpExpr("PHI", list);
            newe = allocExpr("|");
            for (auto item: list->operands) {
                dumpExpr("PHIELEMENTBEF", item);
                if (checkInteger(getRHS(item), "0"))
                    continue;    // default value is already '0'
                item->value = "?"; // Change from ':' -> '?'
                item->operands.push_back(allocExpr("0"));
                updateWidth(item, exprWidth(getRHS(item)));
                newe->operands.push_back(item);
                if (trace_expr)
                    dumpExpr("PHIELEMENT", item);
            }
        }
        expr->value = newe->value;
        expr->operands = newe->operands;
    }
    else
        break;
    }
    for (auto item: expr->operands)
        walkReplaceBuiltin(item);
}
Ejemplo n.º 2
0
Archivo: lexicon.c Proyecto: Aconex/pcp
/*
 * dereference macro  ... return one of the DEREF_* values
 * for DEREF_ERROR, error is reported here
 */
static int
varDeref(char *name)
{
    Symbol  s;
    Expr    *x;
    LexIn   *t;

    /* lookup macro name */
    if ((s = symLookup(&vars, name)) == NULL) {
	fprintf(stderr, "undefined macro name $%s\n", name);
	return DEREF_ERROR;
    }
    x = symValue(s);

    /* string macro */
    if (x->sem == SEM_CHAR) {
	t = (LexIn *) zalloc(sizeof(LexIn));
	t->prev = lin;
	lin = t;
	lin->name = (char *) alloc(strlen(name) + 1);
	strcpy(lin->name, name);
	lin->macro = (char *) x->ring;
	lin->lno = 1;
	lin->cno = 0;
	return DEREF_STRING;
    }

    /* boolean valued macro */
    if (x->sem == SEM_BOOLEAN) {
	yylval.x = x;
	return DEREF_BOOL;
    }

    /* constant numeric valued macro */
    if (x->sem == SEM_NUMCONST) {
	/*
	 * need to copy the Expr as the one returned here may be freed
	 * later after constant folding, and we need the real macro's
	 * value to be available for use in later rules
	 */
	yylval.x = newExpr(NOP, NULL, NULL, -1, -1, -1, 1, SEM_NUMCONST);
	yylval.x->smpls[0].ptr = x->smpls[0].ptr;
	yylval.x->valid = 1;
	return DEREF_NUMBER;
    }

    /* variable numeric valued macro */
    if (x->sem == SEM_NUMVAR) {
	yylval.x = x;
	return DEREF_NUMBER;
    }

    fprintf(stderr, "varDeref(%s): internal botch sem=%d?\n", name, x->sem);
    dumpExpr(x);
    exit(1);
}
Ejemplo n.º 3
0
void dumpExpr(std::string tag, ACCExpr *next)
{
    printf("DE: %s %p %s\n", tag.c_str(), (void *)next, next ? next->value.c_str() : "");
    int i = 0;
    if (next)
    for (auto item: next->operands) {
        dumpExpr(tag + "_" + autostr(i), item);
        i++;
    }
}
Ejemplo n.º 4
0
Archivo: eval.c Proyecto: linwukang/pcp
/* 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;
    }
}
Ejemplo n.º 5
0
/* reinitialize Metric - only for live host */
int      /* 1: ok, 0: try again later, -1: fail */
reinitMetric(Metric *m)
{
    char	*hname = symName(m->hname);
    char	*mname = symName(m->mname);
    char	**inames;
    int		*iids;
    int		handle;
    int		ret = 1;
    int		sts;
    int		i, j;

    /* set up temporary context */
    if ((handle = newContext(hname)) < 0)
	return 0;

    host_state_changed(hname, STATE_RECONN);

    if ((sts = pmLookupName(1, &mname, &m->desc.pmid)) < 0) {
	ret = 0;
	goto end;
    }

    /* fill in performance metric descriptor */
    if ((sts = pmLookupDesc(m->desc.pmid, &m->desc)) < 0) {
	ret = 0;
        goto end;
    }

    if (m->desc.type == PM_TYPE_STRING ||
	m->desc.type == PM_TYPE_AGGREGATE ||
	m->desc.type == PM_TYPE_AGGREGATE_STATIC ||
	m->desc.type == PM_TYPE_EVENT ||
	m->desc.type == PM_TYPE_HIGHRES_EVENT ||
	m->desc.type == PM_TYPE_UNKNOWN) {
	fprintf(stderr, "%s: metric %s has non-numeric type\n", pmProgname, mname);
	ret = -1;
    }
    else if (m->desc.indom == PM_INDOM_NULL) {
	if (m->specinst != 0) {
	    fprintf(stderr, "%s: metric %s has no instances\n", pmProgname, mname);
	    ret = -1;
	}
	else
	    m->m_idom = 1;
    }
    else {
	if ((sts = pmGetInDom(m->desc.indom, &iids, &inames)) < 0) { /* full profile */
	    ret = 0;
	}
	else {
	    if (m->specinst == 0) {
		/* all instances */
		m->iids = iids;
		m->m_idom = sts;
		m->inames = alloc(m->m_idom*sizeof(char *));
		for (i = 0; i < m->m_idom; i++) {
		    m->inames[i] = sdup(inames[i]);
		}
	    }
	    else {
		/* explicit instance profile */
		m->m_idom = 0;
		for (i = 0; i < m->specinst; i++) {
		    /* look for first matching instance name */
		    for (j = 0; j < sts; j++) {
			if (eqinst(m->inames[i], inames[j])) {
			    m->iids[i] = iids[j];
			    m->m_idom++;
			    break;
			}
		    }
		    if (j == sts) {
			m->iids[i] = PM_IN_NULL;
			ret = 0;
		    }
		}
		if (sts > 0) {
		    /*
		     * pmGetInDom or pmGetInDomArchive returned some
		     * instances above
		     */
		    free(iids);
		}

		/* 
		 * if specinst != m_idom, then some not found ... move these
		 * to the end of the list
		 */
		for (j = m->specinst-1; j >= 0; j--) {
		    if (m->iids[j] != PM_IN_NULL)
			break;
		}
		for (i = 0; i < j; i++) {
		    if (m->iids[i] == PM_IN_NULL) {
			/* need to swap */
			char	*tp;
			tp = m->inames[i];
			m->inames[i] = m->inames[j];
			m->iids[i] = m->iids[j];
			m->inames[j] = tp;
			m->iids[j] = PM_IN_NULL;
			j--;
		    }
		}
	    }

#if PCP_DEBUG
	    if (pmDebug & DBG_TRACE_APPL1) {
		int	numinst;
		fprintf(stderr, "reinitMetric: %s from %s: instance domain specinst=%d\n",
			mname, hname, m->specinst);
		if (m->m_idom < 1) fprintf(stderr, "  %d instances!\n", m->m_idom);
		if (m->specinst == 0) numinst = m->m_idom;
		else numinst = m->specinst;
		for (i = 0; i < numinst; i++) {
		    fprintf(stderr, "  indom[%d]", i);
		    if (m->iids[i] == PM_IN_NULL) 
			fprintf(stderr, " ?missing");
		    else
			fprintf(stderr, " %d", m->iids[i]);
		    fprintf(stderr, " \"%s\"\n", m->inames[i]);
		}
	    }
#endif
	    if (sts > 0) {
		/*
		 * pmGetInDom or pmGetInDomArchive returned some instances
		 * above
		 */
		free(inames);
	    }
	}
    }

    if (ret == 1) {
	/* compute conversion factor into canonical units
	   - non-zero conversion factor flags initialized metric */
	m->conv = scale(m->desc.units);

	/* automatic rate computation */
	if (m->desc.sem == PM_SEM_COUNTER) {
	    m->vals = (double *) ralloc(m->vals, m->m_idom * sizeof(double));
	    for (j = 0; j < m->m_idom; j++)
		m->vals[j] = 0;
	}
    }

    if (ret >= 0) {
	/*
	 * re-shape, starting here are working up the expression until
	 * we reach the top of the tree or the designated metrics
	 * associated with the node are not the same
	 */
	Expr	*x = m->expr;
	while (x) {
	    /*
	     * only re-shape expressions that may have set values
	     */
	    if (x->op == CND_FETCH ||
		x->op == CND_NEG || x->op == CND_ADD || x->op == CND_SUB ||
		x->op == CND_MUL || x->op == CND_DIV ||
		x->op == CND_SUM_HOST || x->op == CND_SUM_INST ||
		x->op == CND_SUM_TIME ||
		x->op == CND_AVG_HOST || x->op == CND_AVG_INST ||
		x->op == CND_AVG_TIME ||
		x->op == CND_MAX_HOST || x->op == CND_MAX_INST ||
		x->op == CND_MAX_TIME ||
		x->op == CND_MIN_HOST || x->op == CND_MIN_INST ||
		x->op == CND_MIN_TIME ||
		x->op == CND_EQ || x->op == CND_NEQ ||
		x->op == CND_LT || x->op == CND_LTE ||
		x->op == CND_GT || x->op == CND_GTE ||
		x->op == CND_NOT || x->op == CND_AND || x->op == CND_OR ||
		x->op == CND_RISE || x->op == CND_FALL || x->op == CND_INSTANT ||
		x->op == CND_MATCH || x->op == CND_NOMATCH) {
		instFetchExpr(x);
		findEval(x);
#if PCP_DEBUG
		if (pmDebug & DBG_TRACE_APPL1) {
		    fprintf(stderr, "reinitMetric: re-shaped ...\n");
		    dumpExpr(x);
		}
#endif
	    }
	    if (x->parent) {
		x = x->parent;
		if (x->metrics == m)
		    continue;
	    }
	    break;
	}
    }

end:
    /* destroy temporary context */
    pmDestroyContext(handle);

    return ret;
}
Ejemplo n.º 6
0
static ACCExpr *get1Token(void)
{
    std::string lexToken;
    auto getNext = [&] (void) -> void {
        lexToken += lexChar;
        lexChar = lexString[lexIndex++];
    };

    ACCExpr *ret = repeatGet1Token;
    repeatGet1Token = nullptr;
    if (ret)
        return ret;
    while (lexChar == ' ' || lexChar == '\t')
        lexChar = lexString[lexIndex++];
    if(lexIndex > lexString.length() || lexChar == 0)
        return nullptr;
    if (isIdChar(lexChar)) {
        do {
            getNext();
        } while (isIdChar(lexChar) || isdigit(lexChar));
        if (lexAllowRange && lexChar == '[') {
            do {
                getNext();
            } while (lexChar != ']');
            getNext();
        }
        if (lexToken == "__defaultClock")
            lexToken = "CLK";
        else if (lexToken == "__defaultnReset")
            lexToken = "nRST";
    }
    else if (isdigit(lexChar))
        do {
            getNext();
        } while (isdigit(lexChar) || lexChar == '.' || lexChar == '\'' || lexChar == 'b'
            || lexChar == 'h' || lexChar == 'd' || lexChar == 'o');
    else if (lexChar == '+' || lexChar == '-' || lexChar == '*' || lexChar == '&' || lexChar == '|')
        do {
            getNext();
        } while (lexChar == lexToken[0]);
    else if (lexChar == '=' || lexChar == '<' || lexChar == '>' || lexChar == '!')
        do {
            getNext();
        } while (lexChar == '=' || lexChar == '<' || lexChar == '>');
    else if (isParen(lexChar) || lexChar == '/' || lexChar == '%' || lexChar == '.'
        || lexChar == ']' || lexChar == '}' || lexChar == ')' || lexChar == '^'
        || lexChar == ',' || lexChar == '?' || lexChar == ':' || lexChar == ';')
        getNext();
    else if (lexChar == '@') { // special 'escape' character for internal SUBSCRIPT_MARKER/PARAMETER_MARKER sequences
        getNext();
        getNext();
    }
    else if (lexChar == '"') {
        do {
            if (lexChar == '\\')
                getNext();
            getNext();
        } while (lexChar != '"');
        getNext();
    }
    else {
        printf("[%s:%d] lexString '%s' unknown lexChar %c %x\n", __FUNCTION__, __LINE__, lexString.c_str(), lexChar, lexChar);
        exit(-1);
    }
    ret = allocExpr(lexToken);
    if (isParen(ret->value)) {
        std::string val = ret->value;
        if (trace_expr)
            printf("[%s:%d] before subparse of '%s'\n", __FUNCTION__, __LINE__, ret->value.c_str());
        ret = getExprList(ret, treePost(ret).substr(1), false, true);
        if (ret->value != val)
            ret = allocExpr(val, ret); // over optimization of '(<singleItem>)'
        if (trace_expr) {
            printf("[%s:%d] after subparse of '%s'\n", __FUNCTION__, __LINE__, ret->value.c_str());
            dumpExpr("SUBPAREN", ret);
        }
    }
    return ret;
}