1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# 5# Copyright 2017, Data61 6# Commonwealth Scientific and Industrial Research Organisation (CSIRO) 7# ABN 41 687 119 230. 8# 9# This software may be distributed and modified according to the terms of 10# the BSD 2-Clause license. Note that NO WARRANTY is provided. 11# See "LICENSE_BSD2.txt" for details. 12# 13# @TAG(DATA61_BSD) 14# 15 16from __future__ import absolute_import, division, print_function, \ 17 unicode_literals 18 19import os, subprocess, sys, tempfile, unittest 20 21ME = os.path.abspath(__file__) 22 23# Make CAmkES importable 24sys.path.append(os.path.join(os.path.dirname(ME), '../../..')) 25 26from camkes.ast.ckeywords import C_KEYWORDS 27from camkes.internal.tests.utils import CAmkESTest, c_compiler 28 29class TestCKeywords(CAmkESTest): 30 ''' 31 Test generation of the file ckeywords.py. 32 ''' 33 34 @unittest.skipIf(c_compiler() is None, 'C compiler not available') 35 def test_missing(self): 36 ''' 37 Check if there are C keywords our local Clang is aware of that are not 38 noted in ckeywords.py. 39 ''' 40 41 cc = c_compiler() 42 assert cc is not None 43 44 # Check we can #include TokenKinds.def, otherwise there's no point 45 # continuing. 46 with open(os.devnull, 'wt') as f: 47 p = subprocess.Popen([cc, '-x', 'c', '-E', '-'], stdout=f, stderr=f, 48 stdin=subprocess.PIPE, universal_newlines=True) 49 p.communicate('#include <TokenKinds.def>\n') 50 if p.returncode != 0: 51 self.skipTest('TokenKinds.def unavailble for including (try ' 52 'setting C_INCLUDE_PATH)') 53 54 tmp = self.mkdtemp() 55 56 src = os.path.join(os.path.dirname(ME), '../../../tools/ckeywords.c') 57 assert os.path.exists(src) 58 59 # Compile the C keyword generator. 60 aout = os.path.join(tmp, 'a.out') 61 subprocess.check_call([cc, src, '-std=c11', '-W', '-Wall', '-Wextra', 62 '-Werror', '-o', aout]) 63 64 generated = subprocess.check_output([aout]) 65 66 # Unsafe, but we trust the generated code. 67 namespace = {} 68 exec generated in namespace 69 70 self.assertIn('C_KEYWORDS', namespace, 'C keywords apparently not ' 71 'generated by keyword generator') 72 new_keywords = namespace['C_KEYWORDS'] 73 74 # Check for keywords picked up locally that are not recognised by the 75 # AST sources. We don't bother checking the other way around because the 76 # AST sources may recognise extended keywords that our current compiler 77 # does not. 78 diff = new_keywords - C_KEYWORDS 79 self.assertEqual(diff, set([]), 'extra C keywords (%s) found that are ' 80 'not currently recognised' % ', '.join(diff)) 81 82if __name__ == '__main__': 83 unittest.main() 84