From 1a6261ace44da5b9e6c6807a5b097c58f161d172 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Aug 13 2018 14:44:19 +0000 Subject: Add some basic linux cfg parsing --- diff --git a/rustcfg/__init__.py b/rustcfg/__init__.py index e7e2109..aa3e77e 100644 --- a/rustcfg/__init__.py +++ b/rustcfg/__init__.py @@ -30,6 +30,17 @@ def cfg_grammar(): grammar = (cfg_exp() | multiarch_tuple()) + pp.stringEnd() return grammar +def dump_tree(t, level=0, evalf=None): + print('{}structure {}{}{}{}'.format(' '*level, t.getName(), + ' [' if evalf else '', + evalf(t) if evalf else '', + ']' if evalf else '')) + for item in t: + if isinstance(item, str): + print('{}{!r}'.format(' '*(level+1), item)) + else: + dump_tree(item, level+1, evalf=evalf) + class Evaluator: """Evalutate cfg expressions @@ -43,6 +54,7 @@ class Evaluator: """ def __init__(self, options=()): self.options = options + self.tree = None def eval_tree(self, tree): kind = tree.getName() @@ -72,13 +84,20 @@ class Evaluator: else: assert False, f'Unknown element {kind}' -def dump_tree(t, level=0, evalf=None): - print('{}structure {}{}{}{}'.format(' '*level, t.getName(), - ' [' if evalf else '', - evalf(t) if evalf else '', - ']' if evalf else '')) - for item in t: - if isinstance(item, str): - print('{}{!r}'.format(' '*(level+1), item)) - else: - dump_tree(item, level+1, evalf=evalf) + def eval_parsed(self): + return self.eval_tree(self.tree) + + @classmethod + def platform(cls): + """An Evaluator populated with some platform options + + I don't see a list that'd specify what the allowed options + are, so this is culled from deps used in crates packaged in + Fedora 28. + """ + return cls(options=('unix', + ('target_os', 'linux'))) + + def parse(self, string): + g = cfg_grammar() + self.tree = g.parseString(string) diff --git a/rustcfg/test/test_expressions.py b/rustcfg/test/test_expressions.py index e7d6f67..4058edd 100644 --- a/rustcfg/test/test_expressions.py +++ b/rustcfg/test/test_expressions.py @@ -1,7 +1,7 @@ import pytest import rustcfg -testdata = [ +asdf_data = [ # None means expression is unparsable ('cfg(ok)', True), ('cfg(not_ok)', False), @@ -23,8 +23,7 @@ testdata = [ ('cfg(foo = "not bar")', False), ('cfg(foo=bar)', None), ('cfg(foo foo = = " bar ")', None), - ('cfg(foo = foo = " bar ")', None), -] + ('cfg(foo = foo = " bar ")', None)] @pytest.fixture def asdf_evaluator(): @@ -36,7 +35,7 @@ def asdf_evaluator(): ('foo', ' bar ')) return rustcfg.Evaluator(options=options) -@pytest.mark.parametrize("expression,result", testdata) +@pytest.mark.parametrize("expression,result", asdf_data) def test_parsing(expression, result, asdf_evaluator): g = rustcfg.cfg_grammar() try: @@ -50,3 +49,27 @@ def test_parsing(expression, result, asdf_evaluator): if result is not None: res = asdf_evaluator.eval_tree(t) assert res == result + +linux_data = [ + ('cfg(unix)', True), + ('cfg(windows)', False), + + ('cfg(all(unix, not(target_os = "fuchsia"), not(target_os = "emscripten"), not(target_os = "macos"), not(target_os = "ios")))', True), + ("cfg(all(unix, not(target_os = \"fuchsia\"), not(target_os = \"emscripten\"), not(target_os = \"macos\"), not(target_os = \"ios\")))", True), + + ("cfg(all(unix, not(target_os = \"macos\")))", True), + ('cfg(not(any(target_os = "windows", target_os = "macos")))', True), + ('cfg(not(target_os = "redox"))', True), + ('cfg(not(target_os = "windows"))', True), + ("cfg(not(target_os = \"windows\"))", True), + ('cfg(target_env = "msvc")', False)] + +@pytest.fixture +def linux_evaluator(): + return rustcfg.Evaluator.platform() + +@pytest.mark.parametrize("expression,result", linux_data) +def test_linux(expression, result, linux_evaluator): + linux_evaluator.parse(expression) + res = linux_evaluator.eval_parsed() + res == result