text: from unittest import TestCase, main
  
  from multiprocessing import Process, Queue
  from six.moves.queue import Empty
  
  import sys
  
  if ".." not in sys.path:
      sys.path.insert(0, "..")
  
  from ply.lex import lex
  from ply.cpp import *
  
  
  def preprocessing(in_, out_queue):
      out = None
  
      try:
          p = Preprocessor(lex())
          p.parse(in_)
          tokens = [t.value for t in p.parser]
          out = "".join(tokens)
      finally:
          out_queue.put(out)
  
  class CPPTests(TestCase):
      "Tests related to ANSI-C style lexical preprocessor."
  
      def __test_preprocessing(self, in_, expected, time_limit = 1.0):
          out_queue = Queue()
  
          preprocessor = Process(
              name = "PLY`s C preprocessor",
              target = preprocessing,
              args = (in_, out_queue)
          )
  
          preprocessor.start()
  
          try:
              out = out_queue.get(timeout = time_limit)
          except Empty:
              preprocessor.terminate()
              raise RuntimeError("Time limit exceeded!")
          else:
              self.assertMultiLineEqual(out, expected)
  
      def test_concatenation(self):
          self.__test_preprocessing("""\
  #define a(x) x##_
  #define b(x) _##x
  #define c(x) _##x##_
  #define d(x,y) _##x##y##_
  
  a(i)
  b(j)
  c(k)
  d(q,s)"""
              , """\
  
  
  
  
  
  i_
  _j
  _k_
  _qs_"""
          )
  
      def test_deadloop_macro(self):
          # If there is a word which equals to name of a parametrized macro, then
          # attempt to expand such word as a macro manages the parser to fall
          # into an infinite loop.
  
          self.__test_preprocessing("""\
  #define a(x) x
  
  a;"""
              , """\
  
  
  a;"""
          )
  
      def test_index_error(self):
          # If there are no tokens after a word ("a") which equals to name of
          # a parameterized macro, then attempt to expand this word leads to
          # IndexError.
  
          self.__test_preprocessing("""\
  #define a(x) x
  
  a"""
              , """\
  
  
  a"""
          )
  
  main()
  