eval.c revision 8e7248e505faa19396d4e853604e3fa7cd2cb3b5
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * eval.c -- constraint evaluation module
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * this module evaluates constraints.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic struct node *eval_dup(struct node *np, struct lut *ex,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int check_expr_args(struct evalue *lp, struct evalue *rp,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * begins_with -- return true if rhs path begins with everything in lhs path
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwbegins_with(struct node *lhs, struct node *rhs, struct lut *ex)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (0); /* nope, ran out of rhs first */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (0); /* nope, different component names */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (lhs->u.name.child && lhs->u.name.child->t == T_NUM) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb } else if (lhs->u.name.child && lhs->u.name.child->t == T_NAME) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb iterinfop = lut_lookup(ex, (void *)lhs->u.name.child->u.name.s,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (rhs->u.name.child && rhs->u.name.child->t == T_NUM) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb } else if (rhs->u.name.child && rhs->u.name.child->t == T_NAME) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw iterinfop = lut_lookup(ex, (void *)rhs->u.name.child->u.name.s,
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States out(O_DIE, "begins_with: unexpected rhs child");
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (0); /* nope, instance numbers were different */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as return (begins_with(lhs->u.name.next, rhs->u.name.next, ex));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * eval_getname - used by eval_func to evaluate a name, preferably without using
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * eval_dup (but if it does have to use eval_dup then the *dupedp flag is set).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic struct node *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbeval_getname(struct node *funcnp, struct lut *ex, struct node *events[],
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct config *croot, struct arrow *arrowp, int try, int *dupedp)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * evaluate a variety of functions and place result in valuep. return 1 if
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * function evaluation was successful; 0 if otherwise (e.g., the case of an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * invalid argument to the function)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb/*ARGSUSED*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amweval_func(struct node *funcnp, struct lut *ex, struct node *events[],
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego struct config *croot, struct arrow *arrowp, int try, struct evalue *valuep)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb /* within()'s are not really constraints -- always true */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (1);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb lhs = eval_getname(funcnp, ex, events, np->u.expr.left, globals,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb out(O_ALTFP|O_VERB2|O_NONL, ") returned %d", (int)valuep->v);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (funcname == L_confprop || funcname == L_confprop_defined) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as const char *s;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* for now s will point to a quote [see addconfigprop()] */
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States nodep = eval_getname(funcnp, ex, events, np->u.expr.left,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (s == NULL && strcmp(np->u.expr.right->u.quote.s,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego "class-code") == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "%s: \"%s\" not found for path ",
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (1);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego out(O_ALTFP|O_VERB3|O_NONL, " %s(\"", funcname);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego ptree_name_iter(O_ALTFP|O_VERB3|O_NONL, nodep);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "\", \"%s\") = \"%s\" ",
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb const char *connstrings[] = { "connected", "CONNECTED", NULL };
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb lhs = eval_getname(funcnp, ex, events, np->u.expr.left, globals,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb /* to thine self always be connected */
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States return (1);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Extract "connected" property from each cp. Search this
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * property for the name associated with the other cp[].
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (s != NULL) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego while (w != NULL) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego const char *typestrings[] = { "type", "TYPE", NULL };
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego const char *s;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego nodep = eval_getname(funcnp, ex, events, np, globals,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (s != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh const char *s;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh nodep = eval_getname(funcnp, ex, events, np, globals,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States path = ipath2str(NULL, ipath(nodep));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States FREE((void *)path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States valuep->t = UINT64;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego nvlist_t *asru = NULL, *fru = NULL, *rsrc = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw nodep = eval_getname(funcnp, ex, events, np->u.expr.left,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego platform_units_translate(0, croot, &asru, &fru, &rsrc, path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw outfl(O_ALTFP|O_VERB2|O_NONL, np->file, np->line, "has_fault(");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ptree_name_iter(O_ALTFP|O_VERB2|O_NONL, np->u.expr.left);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERTinfo(np->t == T_EVENT, ptree_nodetype2str(np->t));
valuep->v = 0;
if (duped)
if (try)
switch (valuep->t) {
case UINT64:
case NODEPTR:
case STRING:
int alloced = 0;
if (alloced)
int alloced = 0;
char *str;
serdvalp)) {
if (alloced)
serdvalp->v);
serdvalp->v);
valuep->v = 0;
int nvals;
switch (cmpval.t) {
case UNDEFINED:
case UINT64:
case STRING:
case NODEPTR:
&nvals);
valuep->v = 0;
} else if (nvals == 0) {
for (i = 0; i < nvals; i++) {
T_NAME) {
preval.v);
if (valuep->v)
for (i = 0; i < nvals; i++) {
vals[i].v);
* defines for u.expr.temp - these are used for T_OR and T_AND so that if
#define EXPR_TEMP_BOTH_UNK 0
static struct node *
return (NULL);
switch (np->t) {
case T_GLOBID:
case T_ASSIGN:
case T_CONDIF:
case T_CONDELSE:
case T_NE:
case T_EQ:
case T_LT:
case T_LE:
case T_GT:
case T_GE:
case T_BITAND:
case T_BITOR:
case T_BITXOR:
case T_BITNOT:
case T_LSHIFT:
case T_RSHIFT:
case T_NOT:
case T_ADD:
case T_SUB:
case T_MUL:
case T_DIV:
case T_MOD:
case T_LIST:
case T_AND:
case EXPR_TEMP_LHS_UNK:
case EXPR_TEMP_RHS_UNK:
case T_OR:
case EXPR_TEMP_LHS_UNK:
case EXPR_TEMP_RHS_UNK:
case T_NAME: {
int got_matchf = 0;
int got_matcht = 0;
got_matchf++;
got_matcht++;
return (newnp);
* absolutely (no more expansion/wildcarding).
return (retp);
case T_EVENT:
case T_FUNC:
case T_QUOTE:
return (newnp);
case T_NUM:
return (newnp);
case T_TIMEVAL:
return (newnp);
T_NAME) {
FREE(s);
T_NAME) {
FREE(s);
switch (np->t) {
case T_GLOBID:
if (try)
case T_ASSIGN:
if (try)
case T_EQ:
#define IMPLICIT_ASSIGN_IN_EQ
#ifdef IMPLICIT_ASSIGN_IN_EQ
if (try == 0 &&
case T_LT:
case T_LE:
case T_GT:
case T_GE:
case T_BITAND:
case T_BITOR:
case T_BITXOR:
case T_BITNOT:
case T_LSHIFT:
case T_RSHIFT:
case T_CONDIF: {
int dotrue = 0;
if (dotrue)
if (dotrue)
case T_CONDELSE:
case T_NE:
case T_LIST:
case T_AND:
if (!try) {
if (valuep->v != 0) {
if (valuep->v == 0) {
case T_OR:
if (!try) {
if (valuep->v == 0) {
if (valuep->v != 0) {
case T_NOT:
case T_ADD:
case T_SUB:
case T_MUL:
case T_DIV:
if (rval.v == 0) {
case T_MOD:
if (rval.v == 0) {
case T_NAME:
if (try) {
int i, gotmatch = 0;
gotmatch++;
if (!gotmatch) {
NULL);
valuep->v =
case T_QUOTE:
case T_FUNC:
case T_NUM:
case T_TIMEVAL:
static struct node *
return (np);
static struct node *
return (np);