Testing C++ Compilers for ISO Language Conformance 
by Brian A. Malloy, Scott A. Linde, Edward B. Duffy, James F. Power 

Figure 1:

% python binarytest.py 
F.... 
============================================= 
FAIL: testDecimal (__main__.BadInputTest) 
--------------------------------------------- 
Traceback (most recent call last): 
File "binarytest.py", line 27, in testDecimal
self.assertRaises(InvalidBinaryError,Binary,0.5) 
File "/usr/local/Python-2.2 /Lib/unittest.py", 
   line 279, in failUnlessRaises 
   raise self.failureException, excName 
AssertionError: InvalidBinaryError 
----------------------------------------------- 
Ran 5 tests in 0.019s 
FAILED (failure s=1) 


Listing One 
1 class BinaryError( Exception): pass 
2 class InvalidBinar yError(BinaryE rror): pass 
3 class Binary: 
4    def _init_ ( self, n = '0' ): 
5       """number s are stored as integers""" 
6       if int(n) < 0: 
7           raise InvalidBinary Error, n 
8           "Negative numbers are invalid" 
9       self.number = int( n ) 
10   def _add_ ( self, rhs ): 
11      return Binary(self.number+rhs.number) 
12   def _mul_ ( self, rhs ): 
13      return Binary(self.number*rhs.number) 
14   def _eq_ ( self, rhs ): 
15      return (self.num ber==rhs.numbe r) 
16   def _ne_ ( self, rhs ): 
17      return (self.num ber!=rhs.numbe r) 
18   def _str_ ( self ): 
19      """Prints the number in binary format""" 
20      number = self.number 
21      result = [] 
22      while number: 
23          result.inser t(0, str(number%2)) 
24          number = number / 2 
25      return "".join(result) 
26 def test(): 
27   bin1 = Binary( 17 ) 
28   bin2 = Binary( 127 ) 
29   print bin1, " + ", bin2, " is ", bin1+bin2 
30   print bin1, " * ", bin2, " is ", bin1*bin2 
31   if bin1 != bin2: print "Not Equal" 
32   else : print "Equal" 
33   if bin2 != Binary(127): print "Not Equal" 
34   else : print "Equal" 
35 if name == " _main_": 
36   test() 

Listing Two
1 import unittest 
2 from binary import Binary 
3 from binary import InvalidBinaryError 
4 class BinaryTest(unittest.TestCase): 
5    def setUp(s elf): 
6        self.n = Binary(0) 
7    def tearDow n(self): pass 
8    def testZero(self): 
9        self.asse rtEqual(self.n, Binary(0)) 
10    def testAdd ition(self): 
11       rhs = Binary(7) 
12       self.assertEqual((self.n+rhs), Binary(7)) 
13       self.assertEqual((Binary(7)+rhs), Binary(14)) 
14   def testMultiplication(self): 
15       for n in range(100): 
16           self.assertEqual(Binary(n)*Binary(n), \
17           Binary(n*n)) 
18 class BadInputTest(unittest.TestCase): 
19   def setUp(self): 
20       self.n = Binary(0) 
21   def testNegative(self): 
22       """Binary should fail with negative input""" 
23       self.assertRaises(InvalidBinaryError, \
24       Binary, -1) 
25   def testDecimal(self): 
26       self.assertRaises(InvalidBinaryError,\
27       Binary, 0.5) 
28 if name == " _main_ ": 
29   unittest.main () 


Listing Three 
1 #!/usr/bin/env python2.2 
2 import unittest, fnmatch, os, sys, cpptests 
3 def doTests(fu llpath, directory): 
4     dirlist = os.listdir(fullpath) 
5     runner = unittest.TextTestRunner () 
6     suite = unittest.TestSuite() 
7     for fname in dirlist : 
8        if os.path.isfile(fullpath+' /'+fname) \ 
9            and fnmatch.fnma tch(fname, "*.cpp"): 
10           gen = cpptests.CppTestCase("test Execute", \ 
11               fname[:-4 ]) 
12           suite.addTest( gen ) 
13    runner.run(suite) 
14 def cleanUp(fu llpath): 
15     dirlist = os.listdir(fullpath) 
16     for fname in dirlist : 
17        if os.path.isfile(fullpath+' /'+fname) and \ 
18           (fnmatch.fnmatch(fname, "*.o") 
19           or fnmatch.fnmatch(fname, "*.obj") 
20           or fnmatch.fnmatch(fname, "*.exe")): 
21           os.remove(fname) 
22 if __name__ == "__main__": 
23     if len(sys.argv) != 2: 
24         print "usage: ", sys.argv[0], " <clause dir>" 
25     else : 
26         directory = sys.argv[1] 
27         fullpath = os.getcwd() +'/'+directory 
28         if os.path.isdir(fullpath): 
29             os.chdir(fullpath) 
30             doTests(fullpath, directory) 
31             cleanUp(fullpath) 
32         else : 
33             print directory, " is not in this directory" 
34             print "Current directory is: ", os.getcwd() 


Listing Four
1 import unittest, os, re 
2 class CppTestCase(unittest.TestCase): 
3     def __init__ (self, testfun, fname): 
4        unittest.TestCase.init (self, testfun) 
5        self.compile = [ "g++ -c -DGCC29x %s.cpp", \
6           "g++ -Wno- -c -DGCC30x %s.cpp", \
7           "cl /w /nologo /c -DMSVC6x %s.cpp", \ 
8           "bcc32 -w- -q -c -DBORLAND 55 %s.cpp", \
9           "CC -c -DMIPS %s.cpp ] 
10       self.link = [ "g++ -o %s.exe %s.o", \
11          "g++ -o %s.exe %s.o", \ 
12          "cl /nologo /w /Fe%s.exe %s.obj", \
13          "bcc32 -q -e%s.exe %s.obj" , \
14          "CC -o %s.exe %s.o" \
15          ]
16       self.fileName = fname 
17       self.toPass = not (fname[:4] == "fail") 
18       self.hasMain = 0 
19       self.directory = os.getcwd() 
20    def setUp(self): 
21       print "Executing: %s.cpp" % self.fileName 
22       oldFile = open(self.file Name+".cpp", "r") 
23       currentline = oldFile.readline() 
24       while currentline : 
25          if re.search("main", currentline): 
26             self.hasMain = 1 
27             break; 
28           current line = oldFile.readline() 
29       oldFile.close() 
30    def tearDown(self): pass 
31    def testExecute(self): 
32    #Code for this method in Listing Five


Listing Five
1 def testExecute(self): 
2    def testExecute(self): 
3       executed = 0 
4       compiled = (os.system(self.compile[0] % \
5          self.fileName) == 0) 
6       if compiled and self.hasMain: 
7          linked = (os.system(self.link[0] % \
8            (self.fileName, self.fileName)) == 0) 
9          if linked: 
10           executed = (os.system ("%s.exe" % \
11               self.fileName) == 0) 
12      if self.toPass and self.hasMain \
13         and compiled and executed: 
14         print "PASS: Semantics properly supported" 
15      elif self.toPass and self.hasMain \
16         and compiled and not executed: 
17         print "FAIL: Semantics not supported" 
18         failures.add(self.fileName) 
19      elif self.toPass and self.hasMain and \
20         not compiled and not executed: 
21         print "FAIL: Should have compiled" 
22         failures.add(self.fileName) 
23      elif self.toPass and not self.hasMain and \
24         compiled and not executed: 
25         print "PASS: Compiled as expected" 
26      elif self.toPass and not self.hasMain and \
27         not compiled and not executed: 
28         print "FAIL: Should have compiled" 
29         failures.add(self.fileName) 
30      elif not self.toPass and self.hasMain \
31         and compiled and executed: 
32         print "FAIL: Executed but shouldn't have" 
33         failures.add(self.fileName) 
34      elif not self.toPass and self.hasMain \
35         and compiled and not executed: 
36         print "PASS: Semantics properly supported" 
37      elif not self.toPass and self.hasMain \ 
38         and not compiled and not executed: 
39         print "PASS: Did not compile, as expected" 
40      elif not self.toPass and not self.hasMain \
41         and compiled and not executed: 
42         print "FAIL: Should not have compiled " 
43         failures.add(self.fileName) 
44      elif not self.toPass and not self.hasMain \
45         and not compiled and not executed: 
46         print "PASS: Did not compile, as expected" 
47      else: 
48         print "logic errors" 


Listing Six
1 namespace N { 
2   int i; 
3   int g( int a) {return a;}
4   int j(); 
5   void q(); 
6 } 
7 namespace { int l = 1; } 
8 namespace N { 
9   int g( char a) { // overloads N::g( int ) 
10     return l+a;   // l is from unnames namespace 
11  } 
12  int i;           // error: duplicate definition 
13  int j()          // OK: duplicate function declaration 
14  int j()  {       // OK: definition of N::j() 
15     return g(i);  // calls N::g( int ) 
16  } 
17  int q();          // error: different return type 
18 } 


Listing Seven
1 #if defined( BORLAND55) 
2 #include <mem.h> 
3 #else 
4 #include < memory.h > 
5 #endif 
6 struct T { int a; }; 
7 #define N sizeof(T) 
8 int main () {
9    char buf[N]; 
10   T obj; 
11   obj.a = 1138; 
12   memcpy(buf, &obj, N); 
13   memcpy(&obj, buf, N); 
14   if (1138 != obj.a) return 1; 
15   return 0; 
16 } 


Listing Eight
1 typedef int f; 
2 struct A { 
3   friend void f(A &); 
4   operator int (); 
5   void g(A a) { 
6     f(a); 
7   } 
8 } ; 




2

