Пример #1
0
  int
  classad_evaluate_boolean_expr(const char *s_in, const classad_expr_tree t_ex,
                                int *result)
   {
    ClassAd *ad;
    ClassAdParser parser;
    
    if (s_in == NULL || t_ex == NULL || result == NULL) 
      return C_CLASSAD_INVALID_ARG;

    ExprTree *et = (ExprTree *)t_ex;

    ad = parser.ParseClassAd(s_in);
    if (ad == NULL) return C_CLASSAD_PARSE_ERROR;

    int retcod = C_CLASSAD_NO_ERROR;

    Value v;
    et->SetParentScope(ad);
    ad->EvaluateExpr(et, v);
    et->SetParentScope(NULL);

    bool tmp_res;

    if (v.IsBooleanValue( tmp_res ))
     {
      if (tmp_res) *result = 1;
      else         *result = 0;
      retcod = C_CLASSAD_NO_ERROR;
     }
    else retcod = C_CLASSAD_INVALID_VALUE;

    delete ad;  

    return retcod;
   }
Пример #2
0
bool
Metric::evaluate(char const *attr_name,classad::Value &result,classad::ClassAd &metric_ad,classad::ClassAd const &daemon_ad,MetricTypeEnum type,ExtArray<MyString> *regex_groups,char const *regex_attr)
{
	bool retval = true;
	ExprTree *expr = NULL;
	if( !(expr=metric_ad.Lookup(attr_name)) ) {
		return true;
	}
	classad::ClassAd const *ad = &daemon_ad;
	ClassAd daemon_ad_copy;
	if( regex_attr ) {
		// make a modifiable copy of daemon_ad and insert regex_attr = regex_attr, so the user-defined expression can refer to it
		daemon_ad_copy = daemon_ad;
		ad = &daemon_ad_copy;
		daemon_ad_copy.AssignExpr(ATTR_REGEX,regex_attr);
	}
	expr->SetParentScope(ad);
	if( !ad->EvaluateExpr(expr,result) ||
		(type == STRING && !result.IsStringValue()) ||
		(type == DOUBLE && !result.IsNumber()) ||
        (type == FLOAT && !result.IsNumber()) ||
        (type == INT8 && !result.IsIntegerValue()) ||
        (type == UINT8 && !result.IsIntegerValue()) ||
        (type == INT16 && !result.IsIntegerValue()) ||
        (type == UINT16 && !result.IsIntegerValue()) ||
        (type == INT32 && !result.IsIntegerValue()) ||
        (type == UINT32 && !result.IsIntegerValue()) ||
		(type == BOOLEAN && !result.IsBooleanValue()) )
	{
		retval = false;
		classad::ClassAdUnParser unparser;
		std::string expr_str;
		unparser.Unparse(expr_str,expr);
		dprintf(D_FULLDEBUG,"Failed to evaluate the following%s%s: %s=%s\n",
				name.empty() ? "" : " attribute of metric ",
				name.c_str(),
				attr_name,
				expr_str.c_str());
	}
	expr->SetParentScope(&metric_ad);

	// do regex macro substitutions
	if( regex_groups && regex_groups->length() > 0 ) {
		std::string str_value;
		if( result.IsStringValue(str_value) && str_value.find("\\")!=std::string::npos ) {
			std::string new_str_value;
			const char *ch = str_value.c_str();
			while( *ch ) {
				if( *ch == '\\' ) {
					ch++;
					if( !isdigit(*ch) ) {
						new_str_value += *(ch++);
					}
					else {
						char *endptr = NULL;
						long index = strtol(ch,&endptr,10);
						ch = endptr;
						if( index < regex_groups->length() ) {
							new_str_value += (*regex_groups)[index];
						}
					}
				}
				else {
					new_str_value += *(ch++);
				}
			}
			result.SetStringValue(new_str_value);
		}
	}

	return retval;
}
Пример #3
0
/*********************************************************************
 *
 * Function: process_evaluate
 * Purpose:  Given a line that begins with "evaluate", parse the rest
 *           of the line and perform the evaluation.
 *
 *********************************************************************/
static void process_evaluate(const string &line,
							 int token_start, int line_number, 
							 const Parameters &parameters,
							 ErrorCount *errors)
{
	string classad_name, expression_string;
	ExprTree       *expr;
	ClassAdParser  parser;

	classad_name = extract_token(&token_start, line);
	expr = NULL;
	if ((unsigned) token_start < line.size()) {
		expression_string = line.substr(token_start, line.size() - token_start);
	} else {
		expression_string = "";
	}
	if (!classad_name.compare("") 
		|| !expression_string.compare("")) {
		cout << "Error: Missing evaluate information on line " << line_number 
			 << "." << endl;
		cout << "       Format: evaluate <classad> <expression>"
			 << endl;
		errors->IncrementErrors();
	}
	else {
		if (!parser.ParseExpression(expression_string, expr)) {
			cout << "Error: Can't parse expression (" << expression_string 
				 << ") on line " << line_number << "." << endl;
			errors->IncrementErrors();
		}
		else {
			ClassAd *classad = classads[classad_name];
			
			if (classad == NULL) {
				cout << "Error: Unknown ClassAd: \"" << classad_name 
					 << "\" on line " << line_number << "." << endl;
				errors->IncrementErrors();
			}
			else {
				Value  value;
				expr->SetParentScope(classad);
				if (!classad->EvaluateExpr(expr, value)) {
					cout << "Error: Can't evaluate expression (" << expression_string 
						 << ") on line " <<line_number << "." << endl;
					errors->IncrementErrors();
				}
				else {
					PrettyPrint unparser;
					string value_string;

					unparser.Unparse(value_string, value);
					cout << "OK: Evaluating \"" << expression_string
						 << "\" in " << classad_name 
						 << " evaluates to " << value_string
						 << " on line " << line_number << endl;
				}
			}
		}
	}
	if (expr != NULL) {
		delete expr;
	}
	return;
}