+def _get_source_path(path):
+ cache = _get_build_path('CMakeCache.txt')
+ for line in open(cache, 'rt'):
+ if line.startswith('CMAKE_HOME_DIRECTORY:INTERNAL='):
+ _, source_root = line.strip().split('=', 1)
+ return os.path.join(source_root, path)
+ return None
+
+
+class TraceChecker:
+
+ def __init__(self, srcStream, refFileName, verbose=False):
+ self.srcStream = srcStream
+ self.refFileName = refFileName
+ if refFileName:
+ self.refStream = open(refFileName, 'rt')
+ else:
+ self.refStream = None
+ self.verbose = verbose
+ self.doubleBuffer = False
+ self.callNo = 0
+ self.refLine = ''
+ self.images = []
+ self.states = []
+
+ call_re = re.compile(r'^([0-9]+) (\w+)\(')
+
+ def check(self):
+
+ swapbuffers = 0
+ flushes = 0
+
+ srcLines = []
+ self.consumeRefLine()
+ for line in self.srcStream:
+ line = line.rstrip()
+ if self.verbose:
+ sys.stdout.write(line + '\n')
+ mo = self.call_re.match(line)
+ if mo:
+ self.call_no = int(mo.group(1))
+ function_name = mo.group(2)
+ if function_name.find('SwapBuffers') != -1 or \
+ line.find('kCGLPFADoubleBuffer') != -1:
+ swapbuffers += 1
+ if function_name in ('glFlush', 'glFinish'):
+ flushes += 1
+ srcLine = line[mo.start(2):]
+ else:
+ srcLine = line
+ if self.refLine:
+ if srcLine == self.refLine:
+ self.consumeRefLine()
+ srcLines = []
+ else:
+ srcLines.append(srcLine)
+
+ if self.refLine:
+ if srcLines:
+ fail('missing call `%s` (found `%s`)' % (self.refLine, srcLines[0]))
+ else:
+ fail('missing call %s' % self.refLine)
+
+ if swapbuffers:
+ self.doubleBuffer = True
+ else:
+ self.doubleBuffer = False
+
+ def consumeRefLine(self):
+ if not self.refStream:
+ self.refLine = ''
+ return
+
+ while True:
+ line = self.refStream.readline()
+ if not line:
+ break
+ line = line.rstrip()
+ if line.startswith('#'):
+ self.handlePragma(line)
+ else:
+ break
+ self.refLine = line
+
+ def handlePragma(self, line):
+ pragma, rest = line.split(None, 1)
+ if pragma == '#image':
+ imageFileName = self.getAbsPath(rest)
+ self.images.append((self.callNo, imageFileName))
+ elif pragma == '#state':
+ stateFileName = self.getAbsPath(rest)
+ self.states.append((self.callNo, stateFileName))
+ else:
+ assert False
+
+ def getAbsPath(self, path):
+ '''Get the absolute from a path relative to the reference filename'''
+ return os.path.abspath(os.path.join(os.path.dirname(self.refFileName), path))
+
+