bool BaseCodec::addAttributeToMap (ClassAd& ad, const char* name, AttributeMapType& _map) { ExprTree *expr; // All these extra lookups are horrible. They have to // be there because the ClassAd may have multiple // copies of the same attribute name! This means that // the last attribute with a given name will set the // value, but the last attribute tends to be the // attribute with the oldest (wrong) value. How // annoying is that! if (!(expr = ad.Lookup(name))) { dprintf(D_FULLDEBUG, "Warning: failed to lookup attribute '%s' from ad\n", name); return false; } classad::Value value; ad.EvaluateExpr(expr,value); std::string key = name; switch (value.GetType()) { // seems this covers expressions also case classad::Value::ERROR_VALUE: case classad::Value::UNDEFINED_VALUE: case classad::Value::BOOLEAN_VALUE: _map[key] = new AviaryAttribute(AviaryAttribute::EXPR_TYPE,trimQuotes(ExprTreeToString(expr)).c_str()); break; case classad::Value::INTEGER_VALUE: { int i; value.IsIntegerValue (i); string i_str; sprintf(i_str,"%d",i); _map[key] = new AviaryAttribute(AviaryAttribute::INTEGER_TYPE,i_str.c_str()); break; } case classad::Value::REAL_VALUE: { double d; value.IsRealValue(d); string d_str; sprintf(d_str,"%f",d); _map[key] = new AviaryAttribute(AviaryAttribute::FLOAT_TYPE,d_str.c_str()); break; } case classad::Value::STRING_VALUE: default: _map[key] = new AviaryAttribute(AviaryAttribute::STRING_TYPE,trimQuotes(ExprTreeToString(expr)).c_str()); } return true; }
static bool read_classad_file(const char *filename, ClassAdList &classads, const char * constr) { bool success = false; FILE* file = safe_fopen_wrapper_follow(filename, "r"); if (file == NULL) { fprintf(stderr, "Can't open file of job ads: %s\n", filename); return false; } else { CondorClassAdFileParseHelper parse_helper("\n"); for (;;) { ClassAd* classad = new ClassAd(); int error; bool is_eof; int cAttrs = classad->InsertFromFile(file, is_eof, error, &parse_helper); bool include_classad = cAttrs > 0 && error >= 0; if (include_classad && constr) { classad::Value val; if (classad->EvaluateExpr(constr,val)) { if ( ! val.IsBooleanValueEquiv(include_classad)) { include_classad = false; } } } if (include_classad) { classads.Insert(classad); } else { delete classad; } if (is_eof) { success = true; break; } if (error < 0) { success = false; break; } } fclose(file); } return success; }
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; }
/********************************************************************* * * 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 ¶meters, 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; }