<<<<<<< unpack.c node->details->attrs, name);  if(h_val != NULL && value == NULL && invert == FALSE) { accept = TRUE; =======
match_attrs(const char *attr, const char *op, const char *value,	    const char *type, GListPtr node_list){	int lpc = 0;	GListPtr result = NULL;		if(attr == NULL || op == NULL) {		crm_err("Invlaid attribute or operation in expression"			" (\'%s\' \'%s\' \'%s\')", attr, op, value);		return NULL;	}	slist_iter(		node, node_t, node_list, lpc,		gboolean accept = FALSE;				int cmp = 0;		const char *h_val = (const char*)g_hash_table_lookup(<<<<<<< unpack.c			node->details->attrs, name);					if(h_val != NULL && value == NULL && invert == FALSE) {			accept = TRUE;=======			node->details->attrs, attr);		if(value != NULL && h_val != NULL) {			if(type == NULL || (safe_str_eq(type, "string"))) {				cmp = strcmp(h_val, value);			} else if(safe_str_eq(type, "number")) {				float value_f = atof(value);				float h_val_f = atof(h_val);				if(h_val_f < value_f) {					cmp = -1;				} else if(h_val_f > value_f)  {					cmp = 1;				} else {					cmp = 0;				}							} else if(safe_str_eq(type, "version")) {				crm_err("Version comparisions are not yet supported");				continue;			}					} else if(value == NULL && h_val == NULL) {			cmp = 0;		} else if(value == NULL) {			cmp = 1;		} else {			cmp = -1;		}				if(safe_str_eq(op, "exists")) {			if(h_val != NULL) accept = TRUE;	>>>>>>> 1.13		} else if(safe_str_eq(op, "notexists")) {			if(h_val == NULL) accept = TRUE;		} else if(safe_str_eq(op, "eq")) {			if((h_val == value) || cmp == 0)				accept = TRUE;		} else if(safe_str_eq(op, "ne")) {			if((h_val == NULL && value != NULL)			   || (h_val != NULL && value == NULL)			   || cmp != 0)				accept = TRUE;		} else if(value == NULL || h_val == NULL) {			// the comparision is meaningless from this point on			accept = FALSE;					} else if(safe_str_eq(op, "lt")) {			if(cmp < 0) accept = TRUE;					} else if(safe_str_eq(op, "lte")) {			if(cmp <= 0) accept = TRUE;					} else if(safe_str_eq(op, "gt")) {			if(cmp > 0) accept = TRUE;					} else if(safe_str_eq(op, "gte")) {			if(cmp >= 0) accept = TRUE;					}				if(accept) {			crm_trace("node %s matched", node->details->uname);			result = g_list_append(result, node);		} else {			crm_trace("node %s did not match", node->details->uname);		}		   		);		return result;}gbooleanadd_node_attrs(xmlNodePtr attrs, node_t *node){	const char *name  = NULL;	const char *value = NULL;		while(attrs != NULL){		name  = xmlGetProp(attrs, XML_NVPAIR_ATTR_NAME);		value = xmlGetProp(attrs, XML_NVPAIR_ATTR_VALUE);					if(name != NULL		   && value != NULL		   && safe_val(NULL, node, details) != NULL) {			crm_verbose("Adding %s => %s", name, value);			/* this is frustrating... no way to pass in const			 *  keys or values yet docs say:			 *   Note: If keys and/or values are dynamically			 *   allocated, you should free them first.			 */			g_hash_table_insert(node->details->attrs,					    crm_strdup(name),					    crm_strdup(value));		}		attrs = attrs->next;	}	 	g_hash_table_insert(node->details->attrs,			    crm_strdup("uname"),			    crm_strdup(node->details->uname)); 	g_hash_table_insert(node->details->attrs,			    crm_strdup("id"),			    crm_strdup(node->details->id));	return TRUE;}gbooleanunpack_rsc_location(xmlNodePtr xml_obj, GListPtr rsc_list, GListPtr node_list,		    GListPtr *node_constraints){/*  <constraints>     <rsc_location rsc="Filesystem-whatever-1" timestamp="..." lifetime="...">     	<rule score="+50.0" result="can"><!ATTLIST node_expression	  id         CDATA #REQUIRED	  attribute  CDATA #REQUIRED	  operation  (lt|gt|lte|gte|eq|ne|exists|notexists)	  value      CDATA #IMPLIED	  type	     (integer|string|version)    'string'>	</rule>     	<rule score="+500.0">       		<node_expression match="cpu:50GHz" />	</rule>     	<rule result="cannot">       		<node_expression not_match="san"/>	</rule>...   Translation:   Further translation:       */	xmlNodePtr rules    = xml_obj->children;	const char *id_lh   = xmlGetProp(xml_obj, "rsc");	const char *id      = xmlGetProp(xml_obj, XML_ATTR_ID);	resource_t *rsc_lh = pe_find_resource(rsc_list, id_lh);	if(rsc_lh == NULL) {		crm_err("No resource (con=%s, rsc=%s)",		       id, id_lh);		return FALSE;	}				if(rules == NULL) {		crm_err("no rules for constraint %s", id);	}		while(rules != NULL) {		gboolean first_expr = TRUE;		gboolean   can_run  = FALSE;		gboolean   do_and   = TRUE;		xmlNodePtr rule     = rules;		xmlNodePtr expr     = rule->children;		const char *rule_id = xmlGetProp(rule, XML_ATTR_ID);		const char *score   = xmlGetProp(rule, "score");		const char *result  = xmlGetProp(rule, "result");		const char *boolean = xmlGetProp(rule, "boolean_op");		float score_f       = atof(score?score:"0.0");		rsc_to_node_t *new_con = NULL;		if(safe_str_eq(boolean, "or")) {			do_and = FALSE;		}		rules = rules->next;		if(result == NULL || (safe_str_eq(result, "can"))) {			can_run = TRUE;		}		new_con = rsc2node_new(rule_id, rsc_lh, score_f,				       can_run, NULL, node_constraints);		if(new_con == NULL) {			crm_err("couldnt create constraint %s", rule_id);			continue;		}				/* feels like a hack */		if(expr == NULL && can_run) {			new_con->node_list_rh = node_list_dup(node_list,FALSE);		}				while(expr != NULL) {			const char *attr  = xmlGetProp(expr, "attribute");			const char *op    = xmlGetProp(expr, "operation");			const char *value = xmlGetProp(expr, "value");			const char *type  = xmlGetProp(expr, "type");			crm_trace("processing expression: %s", xmlGetProp(expr, "id"));			expr = expr->next;			GListPtr match_L = match_attrs(				attr, op, value, type, node_list);						if(first_expr) {				new_con->node_list_rh =	node_list_dup(					match_L, FALSE);				first_expr = FALSE;				continue;			}			GListPtr old_list = new_con->node_list_rh;			if(do_and) {				crm_trace("do_and");								new_con->node_list_rh = node_list_and(					old_list, match_L, FALSE);			} else {				crm_trace("do_or");								new_con->node_list_rh = node_list_or(					old_list, match_L, FALSE);			}			pe_free_shallow_adv(match_L,  FALSE);			pe_free_shallow_adv(old_list, TRUE);		}				if(new_con->node_list_rh == NULL) {			crm_warn("No matching nodes for constraint/rule %s/%s",				 id, xmlGetProp(rule, "id"));		}		crm_debug_action(print_rsc_to_node("Added", new_con, FALSE));	}	return TRUE;}