15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import glob 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_option import GetOption, Option, ParseOptions 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_outfile import IDLOutFile 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLDiff 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLDiff is a tool for comparing sets of IDL generated header files 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# with the standard checked in headers. It does this by capturing the 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# output of the standard diff tool, parsing it into separate changes, then 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ignoring changes that are know to be safe, such as adding or removing 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# blank lines, etc... 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('gen', 'IDL generated files', default='hdir') 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('src', 'Original ".h" files', default='../c') 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('halt', 'Stop if a difference is found') 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('diff', 'Directory holding acceptable diffs', default='diff') 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('ok', 'Write out the diff file.') 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Change 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A Change object contains the previous lines, new news and change type. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Change(object): 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, mode, was, now): 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.mode = mode 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.was = was 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.now = now 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Dump(self): 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.was: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'Adding %s' % self.mode 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif not self.now: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'Missing %s' % self.mode 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'Modifying %s' % self.mode 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in self.was: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'src: >>%s<<' % line 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in self.now: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'gen: >>%s<<' % line 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsCopyright 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if this change is only a one line change in the copyright notice 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# such as non-matching years. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsCopyright(change): 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(change.now) != 1 or len(change.was) != 1: return False 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if 'Copyright (c)' not in change.now[0]: return False 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if 'Copyright (c)' not in change.was[0]: return False 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsBlankComment 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if this change only removes a blank line from a comment 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsBlankComment(change): 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if change.now: return False 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(change.was) != 1: return False 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if change.was[0].strip() != '*': return False 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsBlank 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if this change only adds or removes blank lines 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsBlank(change): 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in change.now: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line: return False 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in change.was: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line: return False 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsCppComment 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if this change only going from C++ to C style 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsToCppComment(change): 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not len(change.now) or len(change.now) != len(change.was): 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for index in range(len(change.now)): 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was = change.was[index].strip() 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if was[:2] != '//': 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was = was[2:].strip() 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = change.now[index].strip() 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if now[:2] != '/*': 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = now[2:-2].strip() 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if now != was: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsMergeComment(change): 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(change.was) != 1: return False 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if change.was[0].strip() != '*': return False 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in change.now: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stripped = line.strip() 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stripped != '*' and stripped[:2] != '/*' and stripped[-2:] != '*/': 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsSpacing 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if this change is only different in the way 'words' are spaced 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# such as in an enum: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ENUM_XXX = 1, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ENUM_XYY_Y = 2, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# vs 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ENUM_XXX = 1, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ENUM_XYY_Y = 2, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsSpacing(change): 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(change.now) != len(change.was): return False 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in range(len(change.now)): 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Also ignore right side comments 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = change.was[i] 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offs = line.find('//') 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offs == -1: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offs = line.find('/*') 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offs >-1: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = line[:offs-1] 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) words1 = change.now[i].split() 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) words2 = line.split() 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if words1 != words2: return False 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsInclude 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if change has extra includes 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsInclude(change): 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in change.was: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line.strip().find('struct'): return False 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in change.now: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line and '#include' not in line: return False 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IsCppComment 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if the change is only missing C++ comments 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def IsCppComment(change): 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(change.now): return False 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in change.was: 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = line.strip() 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[:2] != '//': return False 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ValidChange 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return True if none of the changes does not patch an above "bogus" change. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ValidChange(change): 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsToCppComment(change): return False 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsCopyright(change): return False 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsBlankComment(change): return False 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsMergeComment(change): return False 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsBlank(change): return False 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsSpacing(change): return False 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsInclude(change): return False 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if IsCppComment(change): return False 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Swapped 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check if the combination of last + next change signals they are both 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# invalid such as swap of line around an invalid block. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Swapped(last, next): 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not last.now and not next.was and len(last.was) == len(next.now): 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt = len(last.was) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in range(cnt): 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match = True 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for j in range(cnt): 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if last.was[j] != next.now[(i + j) % cnt]: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match = False 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if match: return True 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not last.was and not next.now and len(last.now) == len(next.was): 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt = len(last.now) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in range(cnt): 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match = True 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for j in range(cnt): 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if last.now[i] != next.was[(i + j) % cnt]: 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match = False 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if match: return True 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def FilterLinesIn(output): 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was = [] 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = [] 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter = [] 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for index in range(len(output)): 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter.append(False) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = output[index] 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(line) < 2: continue 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[0] == '<': 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[2:].strip() == '': continue 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was.append((index, line[2:])) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif line[0] == '>': 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[2:].strip() == '': continue 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now.append((index, line[2:])) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for windex, wline in was: 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for nindex, nline in now: 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filter[nindex]: continue 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filter[windex]: continue 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if wline == nline: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter[nindex] = True 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter[windex] = True 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if GetOption('verbose'): 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Found %d, %d >>%s<<" % (windex + 1, nindex + 1, wline) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = [] 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for index in range(len(output)): 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not filter[index]: 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append(output[index]) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return out 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# GetChanges 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Parse the output into discrete change blocks. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GetChanges(output): 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Split on lines, adding an END marker to simply add logic 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines = output.split('\n') 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines = FilterLinesIn(lines) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines.append('END') 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes = [] 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was = [] 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = [] 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode = '' 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = None 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in lines: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# print "LINE=%s" % line 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not line: continue 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif line[0] == '<': 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[2:].strip() == '': continue 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Ignore prototypes 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(line) > 10: 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) words = line[2:].split() 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(words) == 2 and words[1][-1] == ';': 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if words[0] == 'struct' or words[0] == 'union': 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was.append(line[2:]) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif line[0] == '>': 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[2:].strip() == '': continue 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[2:10] == '#include': continue 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now.append(line[2:]) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif line[0] == '-': 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change = Change(line, was, now) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was = [] 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = [] 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ValidChange(change): 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes.append(change) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line == 'END': 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilterChanges(changes) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def FilterChanges(changes): 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(changes) < 2: return changes 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = [] 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter = [False for change in changes] 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for cur in range(len(changes)): 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for cmp in range(cur+1, len(changes)): 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filter[cmp]: 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if Swapped(changes[cur], changes[cmp]): 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter[cur] = True 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter[cmp] = True 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for cur in range(len(changes)): 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filter[cur]: continue 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append(changes[cur]) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return out 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(args): 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = ParseOptions(args) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not filenames: 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gendir = os.path.join(GetOption('gen'), '*.h') 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = sorted(glob.glob(gendir)) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srcdir = os.path.join(GetOption('src'), '*.h') 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srcs = sorted(glob.glob(srcdir)) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for name in srcs: 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = os.path.split(name)[1] 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = os.path.join(GetOption('gen'), name) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if name not in filenames: 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'Missing: %s' % name 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for filename in filenames: 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gen = filename 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filename = filename[len(GetOption('gen')) + 1:] 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src = os.path.join(GetOption('src'), filename) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) diff = os.path.join(GetOption('diff'), filename) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = subprocess.Popen(['diff', src, gen], stdout=subprocess.PIPE) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output, errors = p.communicate() 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input = open(diff, 'rt').read() 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except: 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input = '' 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if input != output: 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes = GetChanges(output) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changes = [] 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if changes: 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "\n\nDelta between:\n src=%s\n gen=%s\n" % (src, gen) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for change in changes: 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change.Dump() 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'Done with %s\n\n' % src 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if GetOption('ok'): 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open(diff, 'wt').write(output) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if GetOption('halt'): 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "\nSAME:\n src=%s\n gen=%s" % (src, gen) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if input: print ' ** Matched expected diff. **' 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print '\n' 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(Main(sys.argv[1:])) 355