diff options
-rw-r--r-- | docs/markdown/Dependencies.md | 11 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 12 | ||||
-rw-r--r-- | mesonbuild/mparser.py | 60 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 51 | ||||
-rw-r--r-- | test cases/common/230 arithmetic operators/meson.build | 8 |
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) |