github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/tools/diffrange (about) 1 #!/usr/bin/env python 2 3 # Copyright 2016 Google Inc. All Rights Reserved. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 """Convert a unified diff into a list of modified files and line numbers.""" 18 19 import sys 20 21 22 class _LineBuffer(object): 23 """Iterator over lines in a file supporting one-step rewind.""" 24 25 def __init__(self, f): 26 self._f = f 27 self._prev = None 28 self._next = None 29 30 def __iter__(self): 31 return self 32 33 def next(self): 34 if self._next is not None: 35 cur = self._next 36 else: 37 cur = self._f.readline() 38 if not cur: 39 raise StopIteration 40 self._next = None 41 self._prev = cur 42 return cur 43 44 def Rewind(self): 45 assert self._prev is not None 46 self._next = self._prev 47 self._prev = None 48 49 50 def _ReadHunks(buf): 51 for line in buf: 52 if not line.startswith('@@'): 53 break 54 base = int(line.split()[2].split(',')[0]) 55 for offset in _ReadHunkBody(buf): 56 yield base + offset 57 58 59 def _ReadHunkBody(buf): 60 n = 0 61 for line in buf: 62 prefix = line[0] 63 if prefix == ' ': 64 n += 1 65 elif prefix == '+': 66 yield n 67 n += 1 68 elif prefix != '-' or line.startswith('---'): 69 buf.Rewind() 70 break 71 72 73 def main(): 74 buf = _LineBuffer(sys.stdin) 75 for line in buf: 76 if line.startswith('+++'): 77 filename = line.split()[1] 78 for n in _ReadHunks(buf): 79 print '{}:{}'.format(filename, n) 80 81 82 if __name__ == '__main__': 83 main()