]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - contrib/dg-extract-results.py
PR c++/87554 - ICE with extern template and reference member.
[thirdparty/gcc.git] / contrib / dg-extract-results.py
index 196b6b2eebb9419e58b56bf9dcbced4024333f85..4e113a8dd6bbbc7e2d48c2d7d2c475bebad37e9c 100644 (file)
@@ -10,7 +10,9 @@
 import sys
 import getopt
 import re
+import io
 from datetime import datetime
+from operator import attrgetter
 
 # True if unrecognised lines should cause a fatal error.  Might want to turn
 # this on by default later.
@@ -20,13 +22,22 @@ strict = False
 # they should keep the original order.
 sort_logs = True
 
+# A version of open() that is safe against whatever binary output
+# might be added to the log.
+def safe_open (filename):
+    if sys.version_info >= (3, 0):
+        return open (filename, 'r', errors = 'surrogateescape')
+    return open (filename, 'r')
+
+# Force stdout to handle escape sequences from a safe_open file.
+if sys.version_info >= (3, 0):
+    sys.stdout = io.TextIOWrapper (sys.stdout.buffer,
+                                   errors = 'surrogateescape')
+
 class Named:
     def __init__ (self, name):
         self.name = name
 
-    def __cmp__ (self, other):
-        return cmp (self.name, other.name)
-
 class ToolRun (Named):
     def __init__ (self, name):
         Named.__init__ (self, name)
@@ -106,7 +117,7 @@ class Prog:
         self.tool_re = re.compile (r'^\t\t=== (.*) tests ===$')
         self.result_re = re.compile (r'^(PASS|XPASS|FAIL|XFAIL|UNRESOLVED'
                                      r'|WARNING|ERROR|UNSUPPORTED|UNTESTED'
-                                     r'|KFAIL):\s*(\S+)')
+                                     r'|KFAIL):\s*(.+)')
         self.completed_re = re.compile (r'.* completed at (.*)')
         # Pieces of text to write at the head of the output.
         # start_line is a pair in which the first element is a datetime
@@ -123,6 +134,7 @@ class Prog:
         self.end_line = None
         # Known summary types.
         self.count_names = [
+            '# of DejaGnu errors\t\t',
             '# of expected passes\t\t',
             '# of unexpected failures\t',
             '# of unexpected successes\t',
@@ -227,6 +239,7 @@ class Prog:
         harness = None
         segment = None
         final_using = 0
+        has_warning = 0
 
         # If this is the first run for this variation, add any text before
         # the first harness to the header.
@@ -234,6 +247,10 @@ class Prog:
             segment = Segment (filename, file.tell())
             variation.header = segment
 
+        # Parse the rest of the summary (the '# of ' lines).
+        if len (variation.counts) == 0:
+            variation.counts = self.zero_counts()
+
         # Parse up until the first line of the summary.
         if num_variations == 1:
             end = '\t\t=== ' + tool.name + ' Summary ===\n'
@@ -264,18 +281,39 @@ class Prog:
             # the harness segment, so that if a run for a particular harness
             # has been split up, we can reassemble the individual segments
             # in a sensible order.
+            #
+            # dejagnu sometimes issues warnings about the testing environment
+            # before running any tests.  Treat them as part of the header
+            # rather than as a test result.
             match = self.result_re.match (line)
-            if match:
+            if match and (harness or not line.startswith ('WARNING:')):
                 if not harness:
                     self.fatal (filename, 'saw test result before harness name')
                 name = match.group (2)
                 # Ugly hack to get the right order for gfortran.
                 if name.startswith ('gfortran.dg/g77/'):
                     name = 'h' + name
-                key = (name, len (harness.results))
-                harness.results.append ((key, line))
-                if not first_key and sort_logs:
-                    first_key = key
+                # If we have a time out warning, make sure it appears
+                # before the following testcase diagnostic: we insert
+                # the testname before 'program' so that sort faces a
+                # list of testnames.
+                if line.startswith ('WARNING: program timed out'):
+                  has_warning = 1
+                else:
+                  if has_warning == 1:
+                      key = (name, len (harness.results))
+                      myline = 'WARNING: %s program timed out.\n' % name
+                      harness.results.append ((key, myline))
+                      has_warning = 0
+                  key = (name, len (harness.results))
+                  harness.results.append ((key, line))
+                  if not first_key and sort_logs:
+                      first_key = key
+                if line.startswith ('ERROR: (DejaGnu)'):
+                    for i in range (len (self.count_names)):
+                        if 'DejaGnu errors' in self.count_names[i]:
+                            variation.counts[i] += 1
+                            break
 
             # 'Using ...' lines are only interesting in a header.  Splitting
             # the test up into parallel runs leads to more 'Using ...' lines
@@ -294,9 +332,6 @@ class Prog:
             segment.lines -= final_using
             harness.add_segment (first_key, segment)
 
-        # Parse the rest of the summary (the '# of ' lines).
-        if len (variation.counts) == 0:
-            variation.counts = self.zero_counts()
         while True:
             before = file.tell()
             line = file.readline()
@@ -455,7 +490,7 @@ class Prog:
 
     # Output a segment of text.
     def output_segment (self, segment):
-        with open (segment.filename, 'r') as file:
+        with safe_open (segment.filename) as file:
             file.seek (segment.start)
             for i in range (segment.lines):
                 sys.stdout.write (file.readline())
@@ -476,18 +511,11 @@ class Prog:
     # with a summary at the end.
     def output_variation (self, tool, variation):
         self.output_segment (variation.header)
-        for harness in sorted (variation.harnesses.values()):
+        for harness in sorted (variation.harnesses.values(),
+                               key = attrgetter ('name')):
             sys.stdout.write ('Running ' + harness.name + ' ...\n')
             if self.do_sum:
-                # Keep the original test result order if there was only
-                # one segment for this harness.  This is needed for
-                # unsorted.exp, which has unusual test names.  Otherwise
-                # sort the tests by test filename.  If there are several
-                # subtests for the same test filename (such as 'compilation',
-                # 'test for excess errors', etc.) then keep the subtests
-                # in the original order.
-                if len (harness.segments) > 1:
-                    harness.results.sort()
+                harness.results.sort()
                 for (key, line) in harness.results:
                     sys.stdout.write (line)
             else:
@@ -537,7 +565,7 @@ class Prog:
         try:
             # Parse the input files.
             for filename in self.files:
-                with open (filename, 'r') as file:
+                with safe_open (filename) as file:
                     self.parse_file (filename, file)
 
             # Decide what to output.