void ParametricAd::addUserTag ( const std::string& attr_name, const std::string& attr_value){ ExprTree* tree = Lookup ( JDL::USERTAGS ) ; if ( tree ==NULL){ // UserTags attribute has still to be created ClassAd ad ; ad.InsertAttr ( attr_name , attr_value ) ; ExprTree* tmp_expr = ad.Copy(); Insert ( JDL::USERTAGS , tmp_expr ) ; }else{ // Already Existing UserTags attribute if ( tree->GetKind () == classad::ExprTree::CLASSAD_NODE ) ((ClassAd*)tree)->InsertAttr ( attr_name , attr_value ) ; } }
bool MakeSignature( const ClassAd *ad, const References &refs, string &sig ) { References::iterator itr; ExprTree *expr; Value val; ClassAdUnParser unp; sig = ""; for( itr=refs.begin( ); itr!= refs.end( ); itr++ ) { if((expr=ad->Lookup(*itr))&&expr->GetKind()==ExprTree::LITERAL_NODE) { unp.Unparse( sig, expr ); } else { return( false ); } sig += ":"; } return( true ); }
void find_attribute_if(std::vector<std::string>* v, ExprTree* e, Predicate predicate, bool deep_find = false) { expression_trace_type exprTrace, exprStack; if (!e) return; else exprStack.push_back(e); while (!exprStack.empty()) { exprTrace.push_front( (e = exprStack.front()) ); exprStack.pop_front(); switch( e->GetKind() ) { case ExprTree::LITERAL_NODE: break; case ExprTree::OP_NODE: { ExprTree* e1 = 0, *e2 = 0, *e3 = 0; Operation::OpKind ok; dynamic_cast<Operation*>(e)->GetComponents(ok, e1, e2, e3); if ( e3 ) exprStack.push_front(e3); if ( e2 ) exprStack.push_front(e2); if ( e1 ) exprStack.push_front(e1); } break; case ExprTree::FN_CALL_NODE: { std::vector<ExprTree*> args; std::string fn; dynamic_cast<FunctionCall*>(e)->GetComponents(fn, args); for( int i = args.size(); i; i--) exprStack.push_front( args[i-1] ); } break; case ExprTree::EXPR_LIST_NODE: { std::vector<ExprTree*> args; dynamic_cast<ExprList*>(e)->GetComponents(args); for( int i = args.size(); i; i--) exprStack.push_front( args[i-1] ); } break; case ExprTree::ATTRREF_NODE: { AttributeReference* a = dynamic_cast<AttributeReference*>(e); ExprTree* reference_expr = 0; std::string name; bool absolute; bool continue_find = false; a->GetComponents(reference_expr, name, absolute); const ClassAd* parent_scope = 0; parent_scope=a->GetParentScope(); if (!reference_expr) { // simple reference "attr" and ".attr"... // ...look-up the parent scope to solve the reference... reference_expr = parent_scope->Lookup(name); if(reference_expr) continue_find = true; else if(predicate(std::make_pair(&exprTrace,a)) && find(v->begin(), v->end(), name) == v->end()) { v->push_back(name); } } else if (parent_scope && deep_find) { // ...reference_expr is not a simple reference "expr.attr" // and the deep resolution is requested. std::string reference_name; Value reference_value; const ClassAd* reference_ad; ExprTree* expr; dynamic_cast<AttributeReference*>(reference_expr)-> GetComponents(expr, reference_name, absolute); if (parent_scope->EvaluateAttr(reference_name, reference_value) && reference_value.IsClassAdValue(reference_ad)) { reference_expr=reference_ad->Lookup(name); continue_find = expr && !(expr->GetKind()==ExprTree::LITERAL_NODE); if(!continue_find && predicate(std::make_pair(&exprTrace,a)) && find(v->begin(), v->end(), name) == v->end()) { v->push_back(name); } } } // ...if the referenced expression has not been evaluated yet... if (reference_expr && find(exprTrace.begin(), exprTrace.end(), reference_expr) == exprTrace.end()) { if (continue_find) exprStack.push_front(reference_expr); // ...further search needed. else if (predicate(std::make_pair(&exprTrace,a)) && find(v->begin(), v->end(), name) == v->end()) { v->push_back(name); } } } break; default: assert( false ); } } }
int unwind_attributes(classad_context cad, char *attribute_name, char ***results) { if (cad == NULL) return C_CLASSAD_INVALID_CONTEXT; if ((results == NULL) || (attribute_name == NULL)) return C_CLASSAD_INVALID_ARG; ClassAd *ad = (ClassAd *)cad; ExprTree *et; bool need_to_delete_et = false; et = ad->Lookup(attribute_name); if (et == NULL) { return C_CLASSAD_VALUE_NOT_FOUND; } if (et->GetKind() == ExprTree::LITERAL_NODE) { // The attribute was probably stringified. Try to parse it. Value v; EvalState state; state.SetScopes( ad ); et->Evaluate(state,v); std::string strres; if (v.IsStringValue( strres )) { ClassAdParser parser; et=NULL; parser.ParseExpression(strres,et); need_to_delete_et = true; } } BinaryOpUnwind res_unp; std::string result; res_unp.Unparse(result, et); int n_results; if (*results == NULL) { n_results = 0; (*results) = (char **)malloc(sizeof(char **)); if ((*results) == NULL) return C_CLASSAD_OUT_OF_MEMORY; (*results)[0] = NULL; } else { for (n_results = 0; (*results)[n_results] != NULL; n_results++) /*NOP*/ ; } std::vector<std::string>::const_iterator it; for (it = res_unp.m_unwind_output.begin(); it != res_unp.m_unwind_output.end(); ++it) { n_results++; char **new_results; new_results = (char **)realloc(*results, (n_results+1)*sizeof(char *)); if (new_results == NULL) { if (need_to_delete_et) delete et; return C_CLASSAD_OUT_OF_MEMORY; } (*results) = new_results; (*results)[n_results] = NULL; (*results)[n_results-1] = strdup(it->c_str()); if (((*results)[n_results-1]) == NULL) { if (need_to_delete_et) delete et; return C_CLASSAD_OUT_OF_MEMORY; } } if (need_to_delete_et) delete et; return C_CLASSAD_NO_ERROR; }
bool AttributeReference:: _Flatten( EvalState &state, Value &val, ExprTree*&ntree, int*) const { ExprTree *tree; ExprTree *dummy; const ClassAd *curAd; bool rval; ntree = NULL; // Just to be safe... wenger 2003-12-11. // find the expression and the evalstate curAd = state.curAd; switch( FindExpr( state, tree, dummy, false ) ) { case EVAL_FAIL: return false; case EVAL_ERROR: val.SetErrorValue(); state.curAd = curAd; return true; case EVAL_UNDEF: if( expr && state.flattenAndInline ) { ExprTree *expr_ntree = NULL; Value expr_val; if( state.depth_remaining <= 0 ) { val.SetErrorValue(); state.curAd = curAd; return false; } state.depth_remaining--; rval = expr->Flatten(state,expr_val,expr_ntree); state.depth_remaining++; if( rval && expr_ntree ) { ntree = MakeAttributeReference(expr_ntree,attributeStr); if( ntree ) { state.curAd = curAd; return true; } } delete expr_ntree; } if( !(ntree = Copy( ) ) ) { CondorErrno = ERR_MEM_ALLOC_FAILED; CondorErrMsg = ""; state.curAd = curAd; return( false ); } state.curAd = curAd; return true; case EVAL_OK: { // Don't flatten or inline a classad that's referred to // by an attribute. if ( tree->GetKind() == CLASSAD_NODE ) { ntree = Copy( ); val.SetUndefinedValue( ); return true; } if( state.depth_remaining <= 0 ) { val.SetErrorValue(); state.curAd = curAd; return false; } state.depth_remaining--; rval = tree->Flatten( state, val, ntree ); state.depth_remaining++; // don't inline if it didn't flatten to a value, and clear cache // do inline if FlattenAndInline was called if( ntree ) { if( state.flattenAndInline ) { // NAC return true; // NAC } // NAC delete ntree; ntree = Copy( ); val.SetUndefinedValue( ); } state.curAd = curAd; return rval; } default: CLASSAD_EXCEPT( "ClassAd: Should not reach here" ); } return false; }