| #!/usr/bin/env python |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) |
| # |
| # SPDX-License-Identifier: BSD-2-Clause |
| # |
| # |
| |
| from __future__ import absolute_import, division, print_function, \ |
| unicode_literals |
| from camkes.internal.tests.utils import CAmkESTest, c_compiler |
| from camkes.ast.ckeywords import C_KEYWORDS |
| |
| import os |
| import subprocess |
| import sys |
| import tempfile |
| import unittest |
| |
| ME = os.path.abspath(__file__) |
| |
| # Make CAmkES importable |
| sys.path.append(os.path.join(os.path.dirname(ME), '../../..')) |
| |
| |
| class TestCKeywords(CAmkESTest): |
| ''' |
| Test generation of the file ckeywords.py. |
| ''' |
| |
| @unittest.skipIf(c_compiler() is None, 'C compiler not available') |
| def test_missing(self): |
| ''' |
| Check if there are C keywords our local Clang is aware of that are not |
| noted in ckeywords.py. |
| ''' |
| |
| cc = c_compiler() |
| assert cc is not None |
| |
| # Check we can #include TokenKinds.def, otherwise there's no point |
| # continuing. |
| with open(os.devnull, 'wt') as f: |
| p = subprocess.Popen([cc, '-x', 'c', '-E', '-'], stdout=f, stderr=f, |
| stdin=subprocess.PIPE, universal_newlines=True) |
| p.communicate('#include <TokenKinds.def>\n') |
| if p.returncode != 0: |
| self.skipTest('TokenKinds.def unavailble for including (try ' |
| 'setting C_INCLUDE_PATH)') |
| |
| tmp = self.mkdtemp() |
| |
| src = os.path.join(os.path.dirname(ME), '../../../tools/ckeywords.c') |
| assert os.path.exists(src) |
| |
| # Compile the C keyword generator. |
| aout = os.path.join(tmp, 'a.out') |
| subprocess.check_call([cc, src, '-std=c11', '-W', '-Wall', '-Wextra', |
| '-Werror', '-o', aout]) |
| |
| generated = subprocess.check_output([aout]) |
| |
| # Unsafe, but we trust the generated code. |
| namespace = {} |
| exec(generated in namespace) |
| |
| self.assertIn('C_KEYWORDS', namespace, 'C keywords apparently not ' |
| 'generated by keyword generator') |
| new_keywords = namespace['C_KEYWORDS'] |
| |
| # Check for keywords picked up locally that are not recognised by the |
| # AST sources. We don't bother checking the other way around because the |
| # AST sources may recognise extended keywords that our current compiler |
| # does not. |
| diff = new_keywords - C_KEYWORDS |
| self.assertEqual(diff, set([]), 'extra C keywords (%s) found that are ' |
| 'not currently recognised' % ', '.join(diff)) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |