]> git.cworth.org Git - apitrace-tests/blobdiff - tracematch.py
Be more lenient with shader matching.
[apitrace-tests] / tracematch.py
index 68949b16ce35fad0d6ee37c1ee0ad94125255ede..45228bfd250fbd94c676e21526ae133b83075caf 100755 (executable)
@@ -112,6 +112,27 @@ class ApproxMatcher(Matcher):
         return repr(self.refValue)
 
 
+class StringMatcher(Matcher):
+
+    def __init__(self, refValue):
+        self.refValue = refValue
+
+    def isShaderDisassembly(self, value):
+        return value.find('// Generated by Microsoft (R) D3D Shader Disassembler\n') != -1
+
+    def normalizeShaderDisassembly(self, value):
+        # Unfortunately slightly different disassemblers produce different output
+        return '\n'.join([line.strip() for line in value.split('\n') if line.strip() and not line.startswith('//')])
+
+    def match(self, value, mo):
+        if self.isShaderDisassembly(self.refValue) and self.isShaderDisassembly(value):
+            return self.normalizeShaderDisassembly(self.refValue) == self.normalizeShaderDisassembly(value)
+        return self.refValue == value
+
+    def __str__(self):
+        return repr(self.refValue)
+
+
 class BitmaskMatcher(Matcher):
 
     def __init__(self, refElements):
@@ -398,6 +419,9 @@ class Lexer:
             self.col = ((self.col - 1)//self.tabsize + 1)*self.tabsize + 1
             pos = tabpos + 1
         self.col += len(text) - pos
+    
+    def filter(self, type, text):
+        return type, text
 
 
 class Parser:
@@ -430,7 +454,7 @@ class Parser:
 
 #######################################################################
 
-ID, NUMBER, HEXNUM, STRING, WILDCARD, PRAGMA, LPAREN, RPAREN, LCURLY, RCURLY, COMMA, AMP, EQUAL, PLUS, VERT, BLOB = xrange(16)
+ID, NUMBER, HEXNUM, STRING, WILDCARD, LPAREN, RPAREN, LCURLY, RCURLY, COMMA, AMP, EQUAL, PLUS, VERT, BLOB = xrange(15)
 
 
 class CallScanner(Scanner):
@@ -440,6 +464,9 @@ class CallScanner(Scanner):
         # whitespace
         (SKIP, r'[ \t\f\r\n\v]+', False),
 
+        # comments
+        (SKIP, r'//[^\r\n]*', False),
+
         # Alphanumeric IDs
         (ID, r'[a-zA-Z_][a-zA-Z0-9_]*(?:::[a-zA-Z_][a-zA-Z0-9_]*)?', True),
 
@@ -454,9 +481,6 @@ class CallScanner(Scanner):
         
         # Wildcard
         (WILDCARD, r'<[^>]*>', False),
-        
-        # Pragma
-        (PRAGMA, r'#[^\r\n]*', False),
     ]
 
     # symbol table
@@ -486,16 +510,9 @@ class CallLexer(Lexer):
         if type == STRING:
             text = text[1:-1]
 
-            # line continuations
-            text = text.replace('\\\r\n', '')
-            text = text.replace('\\\r', '')
-            text = text.replace('\\\n', '')
-            
             # quotes
             text = text.replace('\\"', '"')
 
-            type = ID
-
         return type, text
 
 
@@ -510,15 +527,8 @@ class TraceParser(Parser):
 
     def parse(self):
         while not self.eof():
-            self.parse_element()
-        return TraceMatcher(self.calls)
-
-    def parse_element(self):
-        if self.lookahead.type == PRAGMA:
-            token = self.consume()
-            self.handlePragma(token.text)
-        else:
             self.parse_call()
+        return TraceMatcher(self.calls)
 
     def parse_call(self):
         if self.lookahead.type == NUMBER:
@@ -552,13 +562,14 @@ class TraceParser(Parser):
     def parse_opt_pair(self):
         '''Parse an optional `name = value` pair.'''
         if self.match(ID):
-            name = self.consume(ID).text
+            token = self.consume(ID)
             if self.match(EQUAL):
                 self.consume(EQUAL)
+                name = token.text
                 value = self.parse_value()
             else:
-                value = name
                 name = None
+                value = self.handleID(token.text)
         else:
             name = None
             value = self.parse_value()
@@ -605,11 +616,12 @@ class TraceParser(Parser):
             return self.handleString(value)
         elif self.match(NUMBER):
             token = self.consume()
-            if '.' in token.text:
+            try:
+                value = int(token.text)
+            except ValueError:
                 value = float(token.text)
                 return self.handleFloat(value)
             else:
-                value = int(token.text)
                 return self.handleInt(value)
         elif self.match(HEXNUM):
             token = self.consume()
@@ -686,14 +698,11 @@ class TraceParser(Parser):
     def handleCall(self, callNo, functionName, args, ret):
         raise NotImplementedError
 
-    def handlePragma(self, line):
-        raise NotImplementedError
-
 
 class RefTraceParser(TraceParser):
 
-    def __init__(self, stream):
-        TraceParser.__init__(self, stream)
+    def __init__(self, fileName):
+        TraceParser.__init__(self, open(fileName, 'rt'))
         self.calls = []
 
     def parse(self):
@@ -710,7 +719,7 @@ class RefTraceParser(TraceParser):
         return ApproxMatcher(value)
 
     def handleString(self, value):
-        return LiteralMatcher(value)
+        return StringMatcher(value)
 
     def handleBitmask(self, value):
         return BitmaskMatcher(value)
@@ -730,9 +739,6 @@ class RefTraceParser(TraceParser):
     def handleCall(self, callNo, functionName, args, ret):
         call = CallMatcher(callNo, functionName, args, ret)
         self.calls.append(call)
-    
-    def handlePragma(self, line):
-        pass
 
 
 class SrcTraceParser(TraceParser):
@@ -792,8 +798,7 @@ def main():
 
     refFileName, srcFileName = args
 
-    refStream = open(refFileName, 'rt')
-    refParser = RefTraceParser(refStream)
+    refParser = RefTraceParser(refFileName)
     refTrace = refParser.parse()
     if options.verbose:
         sys.stdout.write('// Reference\n')
@@ -801,8 +806,8 @@ def main():
         sys.stdout.write('\n')
 
     if srcFileName.endswith('.trace'):
-        cmd = [options.apitrace, 'dump', '--color=never', srcFileName]
-        p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+        cmd = [options.apitrace, 'dump', '--verbose', '--color=never', srcFileName]
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
         srcStream = p.stdout
     else:
         srcStream = open(srcFileName, 'rt')