1from unittest import TestCase, main 2 3from multiprocessing import Process, Queue 4from six.moves.queue import Empty 5 6import sys 7 8if ".." not in sys.path: 9 sys.path.insert(0, "..") 10 11from ply.lex import lex 12from ply.cpp import * 13 14 15def preprocessing(in_, out_queue): 16 out = None 17 18 try: 19 p = Preprocessor(lex()) 20 p.parse(in_) 21 tokens = [t.value for t in p.parser] 22 out = "".join(tokens) 23 finally: 24 out_queue.put(out) 25 26class CPPTests(TestCase): 27 "Tests related to ANSI-C style lexical preprocessor." 28 29 def __test_preprocessing(self, in_, expected, time_limit = 1.0): 30 out_queue = Queue() 31 32 preprocessor = Process( 33 name = "PLY`s C preprocessor", 34 target = preprocessing, 35 args = (in_, out_queue) 36 ) 37 38 preprocessor.start() 39 40 try: 41 out = out_queue.get(timeout = time_limit) 42 except Empty: 43 preprocessor.terminate() 44 raise RuntimeError("Time limit exceeded!") 45 else: 46 self.assertMultiLineEqual(out, expected) 47 48 def test_concatenation(self): 49 self.__test_preprocessing("""\ 50#define a(x) x##_ 51#define b(x) _##x 52#define c(x) _##x##_ 53#define d(x,y) _##x##y##_ 54 55a(i) 56b(j) 57c(k) 58d(q,s)""" 59 , """\ 60 61 62 63 64 65i_ 66_j 67_k_ 68_qs_""" 69 ) 70 71 def test_deadloop_macro(self): 72 # If there is a word which equals to name of a parametrized macro, then 73 # attempt to expand such word as a macro manages the parser to fall 74 # into an infinite loop. 75 76 self.__test_preprocessing("""\ 77#define a(x) x 78 79a;""" 80 , """\ 81 82 83a;""" 84 ) 85 86 def test_index_error(self): 87 # If there are no tokens after a word ("a") which equals to name of 88 # a parameterized macro, then attempt to expand this word leads to 89 # IndexError. 90 91 self.__test_preprocessing("""\ 92#define a(x) x 93 94a""" 95 , """\ 96 97 98a""" 99 ) 100 101main() 102