Source code for catkin_pkg.condition
# Copyright 2017 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import operator
import pyparsing
[docs]def evaluate_condition(condition, context):
if condition is None:
return True
expr = _get_condition_expression()
try:
parse_results = expr.parseString(condition, parseAll=True)
except pyparsing.ParseException as e:
raise ValueError(
"condition '%s' failed to parse: %s" % (condition, e))
return _evaluate(parse_results.asList()[0], context)
_condition_expression = None
def _get_condition_expression():
global _condition_expression
if not _condition_expression:
pp = pyparsing
operator = pp.Regex('==|!=|>=|>|<=|<').setName('operator')
identifier = pp.Word('$', pp.alphanums + '_', min=2)
value = pp.Word(pp.alphanums + '_-')
comparison_term = identifier | value
condition = pp.Group(comparison_term + operator + comparison_term)
_condition_expression = pp.operatorPrecedence(
condition, [
('and', 2, pp.opAssoc.LEFT, ),
('or', 2, pp.opAssoc.LEFT, ),
])
return _condition_expression
def _evaluate(parse_results, context):
if not isinstance(parse_results, list):
if parse_results.startswith('$'):
# get variable from context
return str(context.get(parse_results[1:], ''))
# return literal value
return parse_results
# recursion
assert len(parse_results) == 3
# handle logical operators
if parse_results[1] == 'and':
return _evaluate(parse_results[0], context) and \
_evaluate(parse_results[2], context)
if parse_results[1] == 'or':
return _evaluate(parse_results[0], context) or \
_evaluate(parse_results[2], context)
# handle comparison operators
operators = {
'==': operator.eq,
'!=': operator.ne,
'<=': operator.le,
'<': operator.lt,
'>=': operator.ge,
'>': operator.gt,
}
assert parse_results[1] in operators.keys()
return operators[parse_results[1]](
_evaluate(parse_results[0], context),
_evaluate(parse_results[2], context))