blob: 8eb2c2f76153061879816818da1f30968cca9605 [file] [log] [blame] [edit]
#!/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()