summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/cargo/cfg.py74
-rw-r--r--unittests/cargotests.py69
2 files changed, 36 insertions, 107 deletions
diff --git a/mesonbuild/cargo/cfg.py b/mesonbuild/cargo/cfg.py
index 3586a2a54..a0ee6e2b7 100644
--- a/mesonbuild/cargo/cfg.py
+++ b/mesonbuild/cargo/cfg.py
@@ -23,12 +23,9 @@ so you could have examples like:
from __future__ import annotations
import dataclasses
import enum
-import functools
import typing as T
-from . import builder
-from .. import mparser
from ..mesonlib import MesonBugException
if T.TYPE_CHECKING:
@@ -144,8 +141,8 @@ class Identifier(IR):
@dataclasses.dataclass
class Equal(IR):
- lhs: IR
- rhs: IR
+ lhs: Identifier
+ rhs: String
@dataclasses.dataclass
@@ -219,57 +216,20 @@ def parse(ast: _LEX_STREAM) -> IR:
return _parse(ast_i)
-@functools.singledispatch
-def ir_to_meson(ir: T.Any, build: builder.Builder) -> mparser.BaseNode:
- raise NotImplementedError
-
-
-@ir_to_meson.register
-def _(ir: String, build: builder.Builder) -> mparser.BaseNode:
- return build.string(ir.value)
-
-
-@ir_to_meson.register
-def _(ir: Identifier, build: builder.Builder) -> mparser.BaseNode:
- host_machine = build.identifier('host_machine')
- if ir.value == "target_arch":
- return build.method('cpu_family', host_machine)
- elif ir.value in {"target_os", "target_family"}:
- return build.method('system', host_machine)
- elif ir.value == "target_endian":
- return build.method('endian', host_machine)
- raise MesonBugException(f"Unhandled Cargo identifier: {ir.value}")
-
-
-@ir_to_meson.register
-def _(ir: Equal, build: builder.Builder) -> mparser.BaseNode:
- return build.equal(ir_to_meson(ir.lhs, build), ir_to_meson(ir.rhs, build))
-
-
-@ir_to_meson.register
-def _(ir: Not, build: builder.Builder) -> mparser.BaseNode:
- return build.not_(ir_to_meson(ir.value, build))
-
-
-@ir_to_meson.register
-def _(ir: Any, build: builder.Builder) -> mparser.BaseNode:
- if not ir.args:
- return build.bool(False)
- args = iter(reversed(ir.args))
- last = next(args)
- cur = build.or_(ir_to_meson(next(args), build), ir_to_meson(last, build))
- for a in args:
- cur = build.or_(ir_to_meson(a, build), cur)
- return cur
+def _eval_cfg(ir: IR, cfgs: T.Dict[str, str]) -> bool:
+ if isinstance(ir, Identifier):
+ return ir.value in cfgs
+ elif isinstance(ir, Equal):
+ return cfgs.get(ir.lhs.value) == ir.rhs.value
+ elif isinstance(ir, Not):
+ return not _eval_cfg(ir.value, cfgs)
+ elif isinstance(ir, Any):
+ return any(_eval_cfg(i, cfgs) for i in ir.args)
+ elif isinstance(ir, All):
+ return all(_eval_cfg(i, cfgs) for i in ir.args)
+ else:
+ raise MesonBugException(f'Unhandled Cargo cfg IR: {ir}')
-@ir_to_meson.register
-def _(ir: All, build: builder.Builder) -> mparser.BaseNode:
- if not ir.args:
- return build.bool(True)
- args = iter(reversed(ir.args))
- last = next(args)
- cur = build.and_(ir_to_meson(next(args), build), ir_to_meson(last, build))
- for a in args:
- cur = build.and_(ir_to_meson(a, build), cur)
- return cur
+def eval_cfg(raw: str, cfgs: T.Dict[str, str]) -> bool:
+ return _eval_cfg(parse(lexer(raw)), cfgs)
diff --git a/unittests/cargotests.py b/unittests/cargotests.py
index 90b7f867f..eeb676bd2 100644
--- a/unittests/cargotests.py
+++ b/unittests/cargotests.py
@@ -151,60 +151,29 @@ class CargoCfgTest(unittest.TestCase):
with self.subTest():
self.assertEqual(cfg.parse(iter(cfg.lexer(data))), expected)
- def test_ir_to_meson(self) -> None:
- build = builder.Builder('')
- HOST_MACHINE = build.identifier('host_machine')
-
+ def test_eval_ir(self) -> None:
+ d = {
+ 'target_os': 'unix',
+ 'unix': '',
+ }
cases = [
- ('target_os = "windows"',
- build.equal(build.method('system', HOST_MACHINE),
- build.string('windows'))),
- ('target_arch = "x86"',
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86'))),
- ('target_family = "unix"',
- build.equal(build.method('system', HOST_MACHINE),
- build.string('unix'))),
- ('not(target_arch = "x86")',
- build.not_(build.equal(
- build.method('cpu_family', HOST_MACHINE),
- build.string('x86')))),
- ('any(target_arch = "x86", target_arch = "x86_64")',
- build.or_(
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86')),
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86_64')))),
- ('any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")',
- build.or_(
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86')),
- build.or_(
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86_64')),
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('aarch64'))))),
- ('all(target_arch = "x86", target_arch = "x86_64")',
- build.and_(
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86')),
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86_64')))),
- ('all(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")',
- build.and_(
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86')),
- build.and_(
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('x86_64')),
- build.equal(build.method('cpu_family', HOST_MACHINE),
- build.string('aarch64'))))),
- ('all()', build.bool(True)),
- ('any()', build.bool(False)),
+ ('target_os = "windows"', False),
+ ('target_os = "unix"', True),
+ ('doesnotexist = "unix"', False),
+ ('not(target_os = "windows")', True),
+ ('any(target_os = "windows", target_arch = "x86_64")', False),
+ ('any(target_os = "windows", target_os = "unix")', True),
+ ('all(target_os = "windows", target_os = "unix")', False),
+ ('all(not(target_os = "windows"), target_os = "unix")', True),
+ ('any(unix, windows)', True),
+ ('all()', True),
+ ('any()', False),
+ ('cfg(unix)', True),
+ ('cfg(windows)', False),
]
for data, expected in cases:
with self.subTest():
- value = cfg.ir_to_meson(cfg.parse(iter(cfg.lexer(data))), build)
+ value = cfg.eval_cfg(data, d)
self.assertEqual(value, expected)
class CargoLockTest(unittest.TestCase):