Move sympy condition simplification code into separate file
Change-Id: I3f062bf939b452bb41b7a27508a83cbf93abff8c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Qt CMake Build Bot
This commit is contained in:
parent
447c868a5d
commit
590213e531
236
util/cmake/condition_simplifier.py
Normal file
236
util/cmake/condition_simplifier.py
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#############################################################################
|
||||||
|
##
|
||||||
|
## Copyright (C) 2019 The Qt Company Ltd.
|
||||||
|
## Contact: https://www.qt.io/licensing/
|
||||||
|
##
|
||||||
|
## This file is part of the plugins of the Qt Toolkit.
|
||||||
|
##
|
||||||
|
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||||
|
## Commercial License Usage
|
||||||
|
## Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
## accordance with the commercial license agreement provided with the
|
||||||
|
## Software or, alternatively, in accordance with the terms contained in
|
||||||
|
## a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
## and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
## information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
##
|
||||||
|
## GNU General Public License Usage
|
||||||
|
## Alternatively, this file may be used under the terms of the GNU
|
||||||
|
## General Public License version 3 as published by the Free Software
|
||||||
|
## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
## included in the packaging of this file. Please review the following
|
||||||
|
## information to ensure the GNU General Public License requirements will
|
||||||
|
## be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
##
|
||||||
|
## $QT_END_LICENSE$
|
||||||
|
##
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from sympy import simplify_logic, And, Or, Not, SympifyError
|
||||||
|
|
||||||
|
|
||||||
|
def _iterate_expr_tree(expr, op, matches):
|
||||||
|
assert expr.func == op
|
||||||
|
keepers = ()
|
||||||
|
for arg in expr.args:
|
||||||
|
if arg in matches:
|
||||||
|
matches = tuple(x for x in matches if x != arg)
|
||||||
|
elif arg == op:
|
||||||
|
(matches, extra_keepers) = _iterate_expr_tree(arg, op, matches)
|
||||||
|
keepers = (*keepers, *extra_keepers)
|
||||||
|
else:
|
||||||
|
keepers = (*keepers, arg)
|
||||||
|
return matches, keepers
|
||||||
|
|
||||||
|
|
||||||
|
def _simplify_expressions(expr, op, matches, replacement):
|
||||||
|
for arg in expr.args:
|
||||||
|
expr = expr.subs(arg, _simplify_expressions(arg, op, matches, replacement))
|
||||||
|
|
||||||
|
if expr.func == op:
|
||||||
|
(to_match, keepers) = tuple(_iterate_expr_tree(expr, op, matches))
|
||||||
|
if len(to_match) == 0:
|
||||||
|
# build expression with keepers and replacement:
|
||||||
|
if keepers:
|
||||||
|
start = replacement
|
||||||
|
current_expr = None
|
||||||
|
last_expr = keepers[-1]
|
||||||
|
for repl_arg in keepers[:-1]:
|
||||||
|
current_expr = op(start, repl_arg)
|
||||||
|
start = current_expr
|
||||||
|
top_expr = op(start, last_expr)
|
||||||
|
else:
|
||||||
|
top_expr = replacement
|
||||||
|
|
||||||
|
expr = expr.subs(expr, top_expr)
|
||||||
|
|
||||||
|
return expr
|
||||||
|
|
||||||
|
|
||||||
|
def _simplify_flavors_in_condition(base: str, flavors, expr):
|
||||||
|
""" Simplify conditions based on the knowledge of which flavors
|
||||||
|
belong to which OS. """
|
||||||
|
base_expr = simplify_logic(base)
|
||||||
|
false_expr = simplify_logic("false")
|
||||||
|
for flavor in flavors:
|
||||||
|
flavor_expr = simplify_logic(flavor)
|
||||||
|
expr = _simplify_expressions(expr, And, (base_expr, flavor_expr), flavor_expr)
|
||||||
|
expr = _simplify_expressions(expr, Or, (base_expr, flavor_expr), base_expr)
|
||||||
|
expr = _simplify_expressions(expr, And, (Not(base_expr), flavor_expr), false_expr)
|
||||||
|
return expr
|
||||||
|
|
||||||
|
|
||||||
|
def _simplify_os_families(expr, family_members, other_family_members):
|
||||||
|
for family in family_members:
|
||||||
|
for other in other_family_members:
|
||||||
|
if other in family_members:
|
||||||
|
continue # skip those in the sub-family
|
||||||
|
|
||||||
|
f_expr = simplify_logic(family)
|
||||||
|
o_expr = simplify_logic(other)
|
||||||
|
|
||||||
|
expr = _simplify_expressions(expr, And, (f_expr, Not(o_expr)), f_expr)
|
||||||
|
expr = _simplify_expressions(expr, And, (Not(f_expr), o_expr), o_expr)
|
||||||
|
expr = _simplify_expressions(expr, And, (f_expr, o_expr), simplify_logic("false"))
|
||||||
|
return expr
|
||||||
|
|
||||||
|
|
||||||
|
def _recursive_simplify(expr):
|
||||||
|
""" Simplify the expression as much as possible based on
|
||||||
|
domain knowledge. """
|
||||||
|
input_expr = expr
|
||||||
|
|
||||||
|
# Simplify even further, based on domain knowledge:
|
||||||
|
# windowses = ('WIN32', 'WINRT')
|
||||||
|
apples = ("APPLE_OSX", "APPLE_UIKIT", "APPLE_IOS", "APPLE_TVOS", "APPLE_WATCHOS")
|
||||||
|
bsds = ("FREEBSD", "OPENBSD", "NETBSD")
|
||||||
|
androids = ("ANDROID", "ANDROID_EMBEDDED")
|
||||||
|
unixes = (
|
||||||
|
"APPLE",
|
||||||
|
*apples,
|
||||||
|
"BSD",
|
||||||
|
*bsds,
|
||||||
|
"LINUX",
|
||||||
|
*androids,
|
||||||
|
"HAIKU",
|
||||||
|
"INTEGRITY",
|
||||||
|
"VXWORKS",
|
||||||
|
"QNX",
|
||||||
|
"WASM",
|
||||||
|
)
|
||||||
|
|
||||||
|
unix_expr = simplify_logic("UNIX")
|
||||||
|
win_expr = simplify_logic("WIN32")
|
||||||
|
false_expr = simplify_logic("false")
|
||||||
|
true_expr = simplify_logic("true")
|
||||||
|
|
||||||
|
expr = expr.subs(Not(unix_expr), win_expr) # NOT UNIX -> WIN32
|
||||||
|
expr = expr.subs(Not(win_expr), unix_expr) # NOT WIN32 -> UNIX
|
||||||
|
|
||||||
|
# UNIX [OR foo ]OR WIN32 -> ON [OR foo]
|
||||||
|
expr = _simplify_expressions(expr, Or, (unix_expr, win_expr), true_expr)
|
||||||
|
# UNIX [AND foo ]AND WIN32 -> OFF [AND foo]
|
||||||
|
expr = _simplify_expressions(expr, And, (unix_expr, win_expr), false_expr)
|
||||||
|
|
||||||
|
expr = _simplify_flavors_in_condition("WIN32", ("WINRT",), expr)
|
||||||
|
expr = _simplify_flavors_in_condition("APPLE", apples, expr)
|
||||||
|
expr = _simplify_flavors_in_condition("BSD", bsds, expr)
|
||||||
|
expr = _simplify_flavors_in_condition("UNIX", unixes, expr)
|
||||||
|
expr = _simplify_flavors_in_condition("ANDROID", ("ANDROID_EMBEDDED",), expr)
|
||||||
|
|
||||||
|
# Simplify families of OSes against other families:
|
||||||
|
expr = _simplify_os_families(expr, ("WIN32", "WINRT"), unixes)
|
||||||
|
expr = _simplify_os_families(expr, androids, unixes)
|
||||||
|
expr = _simplify_os_families(expr, ("BSD", *bsds), unixes)
|
||||||
|
|
||||||
|
for family in ("HAIKU", "QNX", "INTEGRITY", "LINUX", "VXWORKS"):
|
||||||
|
expr = _simplify_os_families(expr, (family,), unixes)
|
||||||
|
|
||||||
|
# Now simplify further:
|
||||||
|
expr = simplify_logic(expr)
|
||||||
|
|
||||||
|
while expr != input_expr:
|
||||||
|
input_expr = expr
|
||||||
|
expr = _recursive_simplify(expr)
|
||||||
|
|
||||||
|
return expr
|
||||||
|
|
||||||
|
|
||||||
|
def simplify_condition(condition: str) -> str:
|
||||||
|
input_condition = condition.strip()
|
||||||
|
|
||||||
|
# Map to sympy syntax:
|
||||||
|
condition = " " + input_condition + " "
|
||||||
|
condition = condition.replace("(", " ( ")
|
||||||
|
condition = condition.replace(")", " ) ")
|
||||||
|
|
||||||
|
tmp = ""
|
||||||
|
while tmp != condition:
|
||||||
|
tmp = condition
|
||||||
|
|
||||||
|
condition = condition.replace(" NOT ", " ~ ")
|
||||||
|
condition = condition.replace(" AND ", " & ")
|
||||||
|
condition = condition.replace(" OR ", " | ")
|
||||||
|
condition = condition.replace(" ON ", " true ")
|
||||||
|
condition = condition.replace(" OFF ", " false ")
|
||||||
|
# Replace dashes with a token
|
||||||
|
condition = condition.replace("-", "_dash_")
|
||||||
|
|
||||||
|
# SymPy chokes on expressions that contain two tokens one next to
|
||||||
|
# the other delimited by a space, which are not an operation.
|
||||||
|
# So a CMake condition like "TARGET Foo::Bar" fails the whole
|
||||||
|
# expression simplifying process.
|
||||||
|
# Turn these conditions into a single token so that SymPy can parse
|
||||||
|
# the expression, and thus simplify it.
|
||||||
|
# Do this by replacing and keeping a map of conditions to single
|
||||||
|
# token symbols.
|
||||||
|
# Support both target names without double colons, and with double
|
||||||
|
# colons.
|
||||||
|
pattern = re.compile(r"(TARGET [a-zA-Z]+(?:::[a-zA-Z]+)?)")
|
||||||
|
target_symbol_mapping = {}
|
||||||
|
all_target_conditions = re.findall(pattern, condition)
|
||||||
|
for target_condition in all_target_conditions:
|
||||||
|
# Replace spaces and colons with underscores.
|
||||||
|
target_condition_symbol_name = re.sub("[ :]", "_", target_condition)
|
||||||
|
target_symbol_mapping[target_condition_symbol_name] = target_condition
|
||||||
|
condition = re.sub(target_condition, target_condition_symbol_name, condition)
|
||||||
|
|
||||||
|
# Do similar token mapping for comparison operators.
|
||||||
|
pattern = re.compile(r"([a-zA-Z_0-9]+ (?:STRLESS|STREQUAL|STRGREATER) [a-zA-Z_0-9]+)")
|
||||||
|
comparison_symbol_mapping = {}
|
||||||
|
all_comparisons = re.findall(pattern, condition)
|
||||||
|
for comparison in all_comparisons:
|
||||||
|
# Replace spaces and colons with underscores.
|
||||||
|
comparison_symbol_name = re.sub("[ ]", "_", comparison)
|
||||||
|
comparison_symbol_mapping[comparison_symbol_name] = comparison
|
||||||
|
condition = re.sub(comparison, comparison_symbol_name, condition)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Generate and simplify condition using sympy:
|
||||||
|
condition_expr = simplify_logic(condition)
|
||||||
|
condition = str(_recursive_simplify(condition_expr))
|
||||||
|
|
||||||
|
# Restore the target conditions.
|
||||||
|
for symbol_name in target_symbol_mapping:
|
||||||
|
condition = re.sub(symbol_name, target_symbol_mapping[symbol_name], condition)
|
||||||
|
|
||||||
|
# Restore comparisons.
|
||||||
|
for comparison in comparison_symbol_mapping:
|
||||||
|
condition = re.sub(comparison, comparison_symbol_mapping[comparison], condition)
|
||||||
|
|
||||||
|
# Map back to CMake syntax:
|
||||||
|
condition = condition.replace("~", "NOT ")
|
||||||
|
condition = condition.replace("&", "AND")
|
||||||
|
condition = condition.replace("|", "OR")
|
||||||
|
condition = condition.replace("True", "ON")
|
||||||
|
condition = condition.replace("False", "OFF")
|
||||||
|
condition = condition.replace("_dash_", "-")
|
||||||
|
except (SympifyError, TypeError, AttributeError):
|
||||||
|
# sympy did not like our input, so leave this condition alone:
|
||||||
|
condition = input_condition
|
||||||
|
|
||||||
|
return condition or "ON"
|
@ -39,6 +39,8 @@ import io
|
|||||||
import glob
|
import glob
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
from condition_simplifier import simplify_condition
|
||||||
|
|
||||||
try:
|
try:
|
||||||
collectionsAbc = collections.abc
|
collectionsAbc = collections.abc
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -53,8 +55,6 @@ from textwrap import indent as textwrap_indent
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
from sympy.logic import simplify_logic, And, Or, Not
|
|
||||||
from sympy.core.sympify import SympifyError
|
|
||||||
from typing import (
|
from typing import (
|
||||||
List,
|
List,
|
||||||
Optional,
|
Optional,
|
||||||
@ -2054,209 +2054,6 @@ def write_ignored_keys(scope: Scope, indent: str) -> str:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _iterate_expr_tree(expr, op, matches):
|
|
||||||
assert expr.func == op
|
|
||||||
keepers = ()
|
|
||||||
for arg in expr.args:
|
|
||||||
if arg in matches:
|
|
||||||
matches = tuple(x for x in matches if x != arg)
|
|
||||||
elif arg == op:
|
|
||||||
(matches, extra_keepers) = _iterate_expr_tree(arg, op, matches)
|
|
||||||
keepers = (*keepers, *extra_keepers)
|
|
||||||
else:
|
|
||||||
keepers = (*keepers, arg)
|
|
||||||
return matches, keepers
|
|
||||||
|
|
||||||
|
|
||||||
def _simplify_expressions(expr, op, matches, replacement):
|
|
||||||
for arg in expr.args:
|
|
||||||
expr = expr.subs(arg, _simplify_expressions(arg, op, matches, replacement))
|
|
||||||
|
|
||||||
if expr.func == op:
|
|
||||||
(to_match, keepers) = tuple(_iterate_expr_tree(expr, op, matches))
|
|
||||||
if len(to_match) == 0:
|
|
||||||
# build expression with keepers and replacement:
|
|
||||||
if keepers:
|
|
||||||
start = replacement
|
|
||||||
current_expr = None
|
|
||||||
last_expr = keepers[-1]
|
|
||||||
for repl_arg in keepers[:-1]:
|
|
||||||
current_expr = op(start, repl_arg)
|
|
||||||
start = current_expr
|
|
||||||
top_expr = op(start, last_expr)
|
|
||||||
else:
|
|
||||||
top_expr = replacement
|
|
||||||
|
|
||||||
expr = expr.subs(expr, top_expr)
|
|
||||||
|
|
||||||
return expr
|
|
||||||
|
|
||||||
|
|
||||||
def _simplify_flavors_in_condition(base: str, flavors, expr):
|
|
||||||
""" Simplify conditions based on the knownledge of which flavors
|
|
||||||
belong to which OS. """
|
|
||||||
base_expr = simplify_logic(base)
|
|
||||||
false_expr = simplify_logic("false")
|
|
||||||
for flavor in flavors:
|
|
||||||
flavor_expr = simplify_logic(flavor)
|
|
||||||
expr = _simplify_expressions(expr, And, (base_expr, flavor_expr), flavor_expr)
|
|
||||||
expr = _simplify_expressions(expr, Or, (base_expr, flavor_expr), base_expr)
|
|
||||||
expr = _simplify_expressions(expr, And, (Not(base_expr), flavor_expr), false_expr)
|
|
||||||
return expr
|
|
||||||
|
|
||||||
|
|
||||||
def _simplify_os_families(expr, family_members, other_family_members):
|
|
||||||
for family in family_members:
|
|
||||||
for other in other_family_members:
|
|
||||||
if other in family_members:
|
|
||||||
continue # skip those in the sub-family
|
|
||||||
|
|
||||||
f_expr = simplify_logic(family)
|
|
||||||
o_expr = simplify_logic(other)
|
|
||||||
|
|
||||||
expr = _simplify_expressions(expr, And, (f_expr, Not(o_expr)), f_expr)
|
|
||||||
expr = _simplify_expressions(expr, And, (Not(f_expr), o_expr), o_expr)
|
|
||||||
expr = _simplify_expressions(expr, And, (f_expr, o_expr), simplify_logic("false"))
|
|
||||||
return expr
|
|
||||||
|
|
||||||
|
|
||||||
def _recursive_simplify(expr):
|
|
||||||
""" Simplify the expression as much as possible based on
|
|
||||||
domain knowledge. """
|
|
||||||
input_expr = expr
|
|
||||||
|
|
||||||
# Simplify even further, based on domain knowledge:
|
|
||||||
# windowses = ('WIN32', 'WINRT')
|
|
||||||
apples = ("APPLE_OSX", "APPLE_UIKIT", "APPLE_IOS", "APPLE_TVOS", "APPLE_WATCHOS")
|
|
||||||
bsds = ("FREEBSD", "OPENBSD", "NETBSD")
|
|
||||||
androids = ("ANDROID", "ANDROID_EMBEDDED")
|
|
||||||
unixes = (
|
|
||||||
"APPLE",
|
|
||||||
*apples,
|
|
||||||
"BSD",
|
|
||||||
*bsds,
|
|
||||||
"LINUX",
|
|
||||||
*androids,
|
|
||||||
"HAIKU",
|
|
||||||
"INTEGRITY",
|
|
||||||
"VXWORKS",
|
|
||||||
"QNX",
|
|
||||||
"WASM",
|
|
||||||
)
|
|
||||||
|
|
||||||
unix_expr = simplify_logic("UNIX")
|
|
||||||
win_expr = simplify_logic("WIN32")
|
|
||||||
false_expr = simplify_logic("false")
|
|
||||||
true_expr = simplify_logic("true")
|
|
||||||
|
|
||||||
expr = expr.subs(Not(unix_expr), win_expr) # NOT UNIX -> WIN32
|
|
||||||
expr = expr.subs(Not(win_expr), unix_expr) # NOT WIN32 -> UNIX
|
|
||||||
|
|
||||||
# UNIX [OR foo ]OR WIN32 -> ON [OR foo]
|
|
||||||
expr = _simplify_expressions(expr, Or, (unix_expr, win_expr), true_expr)
|
|
||||||
# UNIX [AND foo ]AND WIN32 -> OFF [AND foo]
|
|
||||||
expr = _simplify_expressions(expr, And, (unix_expr, win_expr), false_expr)
|
|
||||||
|
|
||||||
expr = _simplify_flavors_in_condition("WIN32", ("WINRT",), expr)
|
|
||||||
expr = _simplify_flavors_in_condition("APPLE", apples, expr)
|
|
||||||
expr = _simplify_flavors_in_condition("BSD", bsds, expr)
|
|
||||||
expr = _simplify_flavors_in_condition("UNIX", unixes, expr)
|
|
||||||
expr = _simplify_flavors_in_condition("ANDROID", ("ANDROID_EMBEDDED",), expr)
|
|
||||||
|
|
||||||
# Simplify families of OSes against other families:
|
|
||||||
expr = _simplify_os_families(expr, ("WIN32", "WINRT"), unixes)
|
|
||||||
expr = _simplify_os_families(expr, androids, unixes)
|
|
||||||
expr = _simplify_os_families(expr, ("BSD", *bsds), unixes)
|
|
||||||
|
|
||||||
for family in ("HAIKU", "QNX", "INTEGRITY", "LINUX", "VXWORKS"):
|
|
||||||
expr = _simplify_os_families(expr, (family,), unixes)
|
|
||||||
|
|
||||||
# Now simplify further:
|
|
||||||
expr = simplify_logic(expr)
|
|
||||||
|
|
||||||
while expr != input_expr:
|
|
||||||
input_expr = expr
|
|
||||||
expr = _recursive_simplify(expr)
|
|
||||||
|
|
||||||
return expr
|
|
||||||
|
|
||||||
|
|
||||||
def simplify_condition(condition: str) -> str:
|
|
||||||
input_condition = condition.strip()
|
|
||||||
|
|
||||||
# Map to sympy syntax:
|
|
||||||
condition = " " + input_condition + " "
|
|
||||||
condition = condition.replace("(", " ( ")
|
|
||||||
condition = condition.replace(")", " ) ")
|
|
||||||
|
|
||||||
tmp = ""
|
|
||||||
while tmp != condition:
|
|
||||||
tmp = condition
|
|
||||||
|
|
||||||
condition = condition.replace(" NOT ", " ~ ")
|
|
||||||
condition = condition.replace(" AND ", " & ")
|
|
||||||
condition = condition.replace(" OR ", " | ")
|
|
||||||
condition = condition.replace(" ON ", " true ")
|
|
||||||
condition = condition.replace(" OFF ", " false ")
|
|
||||||
# Replace dashes with a token
|
|
||||||
condition = condition.replace("-", "_dash_")
|
|
||||||
|
|
||||||
# SymPy chokes on expressions that contain two tokens one next to
|
|
||||||
# the other delimited by a space, which are not an operation.
|
|
||||||
# So a CMake condition like "TARGET Foo::Bar" fails the whole
|
|
||||||
# expression simplifying process.
|
|
||||||
# Turn these conditions into a single token so that SymPy can parse
|
|
||||||
# the expression, and thus simplify it.
|
|
||||||
# Do this by replacing and keeping a map of conditions to single
|
|
||||||
# token symbols.
|
|
||||||
# Support both target names without double colons, and with double
|
|
||||||
# colons.
|
|
||||||
pattern = re.compile(r"(TARGET [a-zA-Z]+(?:::[a-zA-Z]+)?)")
|
|
||||||
target_symbol_mapping = {}
|
|
||||||
all_target_conditions = re.findall(pattern, condition)
|
|
||||||
for target_condition in all_target_conditions:
|
|
||||||
# Replace spaces and colons with underscores.
|
|
||||||
target_condition_symbol_name = re.sub("[ :]", "_", target_condition)
|
|
||||||
target_symbol_mapping[target_condition_symbol_name] = target_condition
|
|
||||||
condition = re.sub(target_condition, target_condition_symbol_name, condition)
|
|
||||||
|
|
||||||
# Do similar token mapping for comparison operators.
|
|
||||||
pattern = re.compile(r"([a-zA-Z_0-9]+ (?:STRLESS|STREQUAL|STRGREATER) [a-zA-Z_0-9]+)")
|
|
||||||
comparison_symbol_mapping = {}
|
|
||||||
all_comparisons = re.findall(pattern, condition)
|
|
||||||
for comparison in all_comparisons:
|
|
||||||
# Replace spaces and colons with underscores.
|
|
||||||
comparison_symbol_name = re.sub("[ ]", "_", comparison)
|
|
||||||
comparison_symbol_mapping[comparison_symbol_name] = comparison
|
|
||||||
condition = re.sub(comparison, comparison_symbol_name, condition)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Generate and simplify condition using sympy:
|
|
||||||
condition_expr = simplify_logic(condition)
|
|
||||||
condition = str(_recursive_simplify(condition_expr))
|
|
||||||
|
|
||||||
# Restore the target conditions.
|
|
||||||
for symbol_name in target_symbol_mapping:
|
|
||||||
condition = re.sub(symbol_name, target_symbol_mapping[symbol_name], condition)
|
|
||||||
|
|
||||||
# Restore comparisons.
|
|
||||||
for comparison in comparison_symbol_mapping:
|
|
||||||
condition = re.sub(comparison, comparison_symbol_mapping[comparison], condition)
|
|
||||||
|
|
||||||
# Map back to CMake syntax:
|
|
||||||
condition = condition.replace("~", "NOT ")
|
|
||||||
condition = condition.replace("&", "AND")
|
|
||||||
condition = condition.replace("|", "OR")
|
|
||||||
condition = condition.replace("True", "ON")
|
|
||||||
condition = condition.replace("False", "OFF")
|
|
||||||
condition = condition.replace("_dash_", "-")
|
|
||||||
except (SympifyError, TypeError, AttributeError):
|
|
||||||
# sympy did not like our input, so leave this condition alone:
|
|
||||||
condition = input_condition
|
|
||||||
|
|
||||||
return condition or "ON"
|
|
||||||
|
|
||||||
|
|
||||||
def recursive_evaluate_scope(
|
def recursive_evaluate_scope(
|
||||||
scope: Scope, parent_condition: str = "", previous_condition: str = ""
|
scope: Scope, parent_condition: str = "", previous_condition: str = ""
|
||||||
) -> str:
|
) -> str:
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
##
|
##
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
from pro2cmake import simplify_condition
|
from condition_simplifier import simplify_condition
|
||||||
|
|
||||||
|
|
||||||
def validate_simplify(input: str, expected: str) -> None:
|
def validate_simplify(input: str, expected: str) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user