aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Dependencies.md11
-rw-r--r--mesonbuild/backend/vs2010backend.py12
-rw-r--r--mesonbuild/mparser.py60
-rw-r--r--mesonbuild/mtest.py51
-rw-r--r--test cases/common/230 arithmetic operators/meson.build8
5 files changed, 87 insertions, 55 deletions
diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md
index 05c97e5..17c9991 100644
--- a/docs/markdown/Dependencies.md
+++ b/docs/markdown/Dependencies.md
@@ -395,6 +395,17 @@ llvm_dep = dependency(
)
```
+### Using LLVM tools
+When using LLVM as library but also needing its tools, it is often beneficial to use the same version.
+This can partially be achieved with the `version` argument of `find_program()`.
+However, distributions tend to package different LLVM versions in rather different ways.
+Therefore, it is often better to use the llvm dependency directly to retrieve the tools:
+
+```meson
+llvm_dep = dependency('llvm', version : ['>= 8', '< 9'])
+llvm_link = find_program(llvm_dep.get_variable(configtool: 'bindir') / 'llvm-link')
+```
+
## MPI
*(added 0.42.0)*
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 177e715..8ae90b7 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -844,18 +844,18 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDLL'
# Debug format
if '/ZI' in buildtype_args:
- ET.SubElement(type_config, 'DebugInformationFormat').text = 'EditAndContinue'
+ ET.SubElement(clconf, 'DebugInformationFormat').text = 'EditAndContinue'
elif '/Zi' in buildtype_args:
- ET.SubElement(type_config, 'DebugInformationFormat').text = 'ProgramDatabase'
+ ET.SubElement(clconf, 'DebugInformationFormat').text = 'ProgramDatabase'
elif '/Z7' in buildtype_args:
- ET.SubElement(type_config, 'DebugInformationFormat').text = 'OldStyle'
+ ET.SubElement(clconf, 'DebugInformationFormat').text = 'OldStyle'
# Runtime checks
if '/RTC1' in buildtype_args:
- ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'EnableFastChecks'
+ ET.SubElement(clconf, 'BasicRuntimeChecks').text = 'EnableFastChecks'
elif '/RTCu' in buildtype_args:
- ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'UninitializedLocalUsageCheck'
+ ET.SubElement(clconf, 'BasicRuntimeChecks').text = 'UninitializedLocalUsageCheck'
elif '/RTCs' in buildtype_args:
- ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'StackFrameRuntimeCheck'
+ ET.SubElement(clconf, 'BasicRuntimeChecks').text = 'StackFrameRuntimeCheck'
# End configuration
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.props')
generated_files, custom_target_output_files, generated_files_include_dirs = self.generate_custom_generator_commands(target, root)
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index 8753b40..2cffc47 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -489,6 +489,13 @@ class Parser:
return True
return False
+ def accept_any(self, tids: T.Sequence[str]) -> str:
+ tid = self.current.tid
+ if tid in tids:
+ self.getsym()
+ return tid
+ return ''
+
def expect(self, s: str) -> bool:
if self.accept(s):
return True
@@ -562,36 +569,35 @@ class Parser:
return left
def e5(self) -> BaseNode:
- return self.e5add()
-
- def e5add(self) -> BaseNode:
- left = self.e5sub()
- if self.accept('plus'):
- return ArithmeticNode('add', left, self.e5add())
- return left
-
- def e5sub(self) -> BaseNode:
- left = self.e5mod()
- if self.accept('dash'):
- return ArithmeticNode('sub', left, self.e5sub())
- return left
-
- def e5mod(self) -> BaseNode:
- left = self.e5mul()
- if self.accept('percent'):
- return ArithmeticNode('mod', left, self.e5mod())
- return left
-
- def e5mul(self) -> BaseNode:
- left = self.e5div()
- if self.accept('star'):
- return ArithmeticNode('mul', left, self.e5mul())
+ return self.e5addsub()
+
+ def e5addsub(self) -> BaseNode:
+ op_map = {
+ 'plus': 'add',
+ 'dash': 'sub',
+ }
+ left = self.e5muldiv()
+ while True:
+ op = self.accept_any(tuple(op_map.keys()))
+ if op:
+ left = ArithmeticNode(op_map[op], left, self.e5muldiv())
+ else:
+ break
return left
- def e5div(self) -> BaseNode:
+ def e5muldiv(self) -> BaseNode:
+ op_map = {
+ 'percent': 'mod',
+ 'star': 'mul',
+ 'fslash': 'div',
+ }
left = self.e6()
- if self.accept('fslash'):
- return ArithmeticNode('div', left, self.e5div())
+ while True:
+ op = self.accept_any(tuple(op_map.keys()))
+ if op:
+ left = ArithmeticNode(op_map[op], left, self.e6())
+ else:
+ break
return left
def e6(self) -> BaseNode:
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index c35ab5a..23643c5 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -139,7 +139,7 @@ def returncode_to_status(retcode: int) -> str:
return '(killed by signal {} {})'.format(signum, signame)
if retcode <= 128:
- return '(exit status {})'.format((retcode,))
+ return '(exit status {})'.format(retcode)
signum = retcode - 128
try:
@@ -167,6 +167,10 @@ class TestResult(enum.Enum):
UNEXPECTEDPASS = 'UNEXPECTEDPASS'
ERROR = 'ERROR'
+ @staticmethod
+ def maxlen() -> int:
+ return 14 # len(UNEXPECTEDPASS)
+
class TAPParser:
Plan = namedtuple('Plan', ['count', 'late', 'skipped', 'explanation'])
@@ -733,21 +737,23 @@ class TestHarness:
else:
sys.exit('Unknown test result encountered: {}'.format(result.res))
- def print_stats(self, numlen: int, tests: T.List['TestSerialisation'],
+ def print_stats(self, test_count: int, name_max_len: int,
+ tests: T.List['TestSerialisation'],
name: str, result: TestRun, i: int) -> None:
- startpad = ' ' * (numlen - len('{}'.format(i + 1)))
- num = '{}{}/{}'.format(startpad, i + 1, len(tests))
- padding1 = ' ' * (38 - len(name))
- padding2 = ' ' * (8 - len(result.res.value))
- status = ''
-
- if result.res is TestResult.FAIL:
- status = returncode_to_status(result.returncode)
- result_str = '{} {} {}{}{}{:5} s {}'.format(num, name, padding1, result.res.value,
- padding2, result.duration, status)
ok_statuses = (TestResult.OK, TestResult.EXPECTEDFAIL)
- bad_statuses = (TestResult.FAIL, TestResult.TIMEOUT, TestResult.UNEXPECTEDPASS,
- TestResult.ERROR)
+ bad_statuses = (TestResult.FAIL, TestResult.TIMEOUT,
+ TestResult.UNEXPECTEDPASS, TestResult.ERROR)
+ result_str = '{num:{numlen}}/{testcount} {name:{name_max_len}} {res:{reslen}} {dur:.2f}s'.format(
+ numlen=len(str(test_count)),
+ num=i,
+ testcount=test_count,
+ name_max_len=name_max_len,
+ name=name,
+ reslen=TestResult.maxlen(),
+ res=result.res.value,
+ dur=result.duration)
+ if result.res is TestResult.FAIL:
+ result_str += ' ' + returncode_to_status(result.returncode)
if not self.options.quiet or result.res not in ok_statuses:
if result.res not in ok_statuses and mlog.colorize_console:
if result.res in bad_statuses:
@@ -932,8 +938,9 @@ Timeout: {:<4}
def run_tests(self, tests: T.List['TestSerialisation']) -> None:
executor = None
- futures = [] # type: T.List[T.Tuple[conc.Future[TestRun], int, T.List[TestSerialisation], str, int]]
- numlen = len('{}'.format(len(tests)))
+ futures = [] # type: T.List[T.Tuple[conc.Future[TestRun], int, int, T.List[TestSerialisation], str, int]]
+ test_count = len(tests)
+ name_max_len = max([len(self.get_pretty_suite(test)) for test in tests])
self.open_log_files()
startdir = os.getcwd()
if self.options.wd:
@@ -942,7 +949,7 @@ Timeout: {:<4}
try:
for _ in range(self.options.repeat):
- for i, test in enumerate(tests):
+ for i, test in enumerate(tests, 1):
visible_name = self.get_pretty_suite(test)
single_test = self.get_test_runner(test)
@@ -951,12 +958,12 @@ Timeout: {:<4}
futures = []
res = single_test.run()
self.process_test_result(res)
- self.print_stats(numlen, tests, visible_name, res, i)
+ self.print_stats(test_count, name_max_len, tests, visible_name, res, i)
else:
if not executor:
executor = conc.ThreadPoolExecutor(max_workers=self.options.num_processes)
f = executor.submit(single_test.run)
- futures.append((f, numlen, tests, visible_name, i))
+ futures.append((f, test_count, name_max_len, tests, visible_name, i))
if self.options.repeat > 1 and self.fail_count:
break
if self.options.repeat > 1 and self.fail_count:
@@ -971,15 +978,15 @@ Timeout: {:<4}
finally:
os.chdir(startdir)
- def drain_futures(self, futures: T.List[T.Tuple['conc.Future[TestRun]', int, T.List['TestSerialisation'], str, int]]) -> None:
+ def drain_futures(self, futures: T.List[T.Tuple['conc.Future[TestRun]', int, int, T.List['TestSerialisation'], str, int]]) -> None:
for x in futures:
- (result, numlen, tests, name, i) = x
+ (result, test_count, name_max_len, tests, name, i) = x
if self.options.repeat > 1 and self.fail_count:
result.cancel()
if self.options.verbose:
result.result()
self.process_test_result(result.result())
- self.print_stats(numlen, tests, name, result.result(), i)
+ self.print_stats(test_count, name_max_len, tests, name, result.result(), i)
def run_special(self) -> int:
'''Tests run by the user, usually something like "under gdb 1000 times".'''
diff --git a/test cases/common/230 arithmetic operators/meson.build b/test cases/common/230 arithmetic operators/meson.build
new file mode 100644
index 0000000..a904bd0
--- /dev/null
+++ b/test cases/common/230 arithmetic operators/meson.build
@@ -0,0 +1,8 @@
+project('arithmetic operators')
+assert(5 - 3 - 1 == 1)
+assert(5 - (3 - 1) == 3)
+assert(5 - 1 * 3 - 3 == -1)
+assert(420 - 300 - 51 == 69)
+assert(1000 / 2 / 2 / 2 == 125)
+assert(4 * 9 / 3 % 8 - 3 - 10 / 2 == -4)
+assert(94 - 30 + (2 - (40 - 6 + 7) - 9) - 10 == 6)