summaryrefslogtreecommitdiffstats
path: root/src/usr/targeting/common/predicates/predicatepostfixexpr.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/targeting/common/predicates/predicatepostfixexpr.C')
-rw-r--r--src/usr/targeting/common/predicates/predicatepostfixexpr.C220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/usr/targeting/common/predicates/predicatepostfixexpr.C b/src/usr/targeting/common/predicates/predicatepostfixexpr.C
new file mode 100644
index 000000000..babebfb1f
--- /dev/null
+++ b/src/usr/targeting/common/predicates/predicatepostfixexpr.C
@@ -0,0 +1,220 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/targeting/predicates/predicatepostfixexpr.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+
+/**
+ * @file targeting/common/predicates/predicatepostfixexpr.C
+ *
+ * @brief Implementation for predicate which allows callers to chain multiple
+ * other predicates together in complex logical expressions, and then
+ * evaluate them against a target
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+#include <targeting/adapters/assertadapter.H>
+
+// Targeting Component
+#include <targeting/common/predicates/predicates.H>
+#include <targeting/common/trace.H>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FN
+
+//******************************************************************************
+// Interface
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+#define TARG_CLASS "PredicatePostfixExpr::"
+
+//******************************************************************************
+// PredicatePostfixExpr::PredicatePostfixExpr
+//******************************************************************************
+
+PredicatePostfixExpr::PredicatePostfixExpr()
+{
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::~PredicatePostfixExpr
+//******************************************************************************
+
+PredicatePostfixExpr::~PredicatePostfixExpr()
+{
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::push
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::push(
+ const PredicateBase* const i_pPredicate)
+{
+ #define TARG_FN "push(...)"
+
+ TARG_ASSERT(i_pPredicate != NULL,
+ TARG_LOC "Caller supplied a NULL predicate");
+ Operation l_op = {EVAL,i_pPredicate};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::And
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::And()
+{
+ #define TARG_FN "And()"
+
+ Operation l_op = {AND,NULL};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::Not
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::Not()
+{
+ #define TARG_FN "Not()"
+
+ Operation l_op = {NOT,NULL};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::Or
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::Or()
+{
+ #define TARG_FN "Or()"
+
+ Operation l_op = {OR,NULL};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::operator()
+//******************************************************************************
+
+bool PredicatePostfixExpr::operator()(
+ const Target* const i_pTarget) const
+{
+ #define TARG_FN "operator()(...)"
+
+ TARG_ASSERT(i_pTarget != NULL,
+ TARG_LOC "Caller supplied a NULL target");
+
+ std::vector<bool> l_stack;
+ bool l_result = false;
+
+ for(uint32_t i=0; i<iv_ops.size(); ++i)
+ {
+ switch(iv_ops[i].logicalOp)
+ {
+ case EVAL:
+ l_stack.push_back((*iv_ops[i].pPredicate)(i_pTarget));
+ break;
+ case AND:
+ TARG_ASSERT(l_stack.size() >= 2,
+ TARG_LOC "Stack for AND must be >=2 but is %d",
+ l_stack.size());
+ l_result = l_stack.back();
+ l_stack.pop_back();
+ l_stack.back() = (l_stack.back() & l_result);
+ break;
+ case OR:
+ TARG_ASSERT(l_stack.size() >= 2,
+ TARG_LOC "Stack for OR must be >= 2 but is %d",
+ l_stack.size());
+ l_result = l_stack.back();
+ l_stack.pop_back();
+ l_stack.back() = (l_stack.back() | l_result);
+ break;
+ case NOT:
+ TARG_ASSERT(l_stack.size() >= 1,
+ TARG_LOC "Stack for NOT must be >= 1 but is %d",
+ l_stack.size());
+ l_stack.back() = !l_stack.back();
+ break;
+ default:
+ TARG_ASSERT(0,
+ TARG_LOC "Attempted to evaluate unsupported "
+ "logical operation %d",
+ iv_ops[i].logicalOp);
+ break;
+ }
+ }
+
+ // If no predicates and we haven't asserted (no misformatting), element
+ // should be returned
+ if(l_stack.size() == 0)
+ {
+ l_result = true;
+ }
+ else
+ {
+ TARG_ASSERT(l_stack.size() == 1,
+ TARG_LOC "Postfix expression created incorrectly. Stack "
+ "size should be 1 but is %d",
+ l_stack.size());
+
+ l_result = l_stack.front();
+ }
+
+ return l_result;
+
+ #undef TARG_FN
+}
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
OpenPOWER on IntegriCloud