update.py 2.69 KB
Newer Older
1
#! /usr/bin/env python
Guido van Rossum's avatar
Guido van Rossum committed
2 3 4 5 6

# Update a bunch of files according to a script.
# The input file contains lines of the form <filename>:<lineno>:<text>,
# meaning that the given line of the given file is to be replaced
# by the given text.  This is useful for performing global substitutions
7
# on grep output:
Guido van Rossum's avatar
Guido van Rossum committed
8 9 10

import os
import sys
11
import re
Guido van Rossum's avatar
Guido van Rossum committed
12

13 14
pat = '^([^: \t\n]+):([1-9][0-9]*):'
prog = re.compile(pat)
Guido van Rossum's avatar
Guido van Rossum committed
15 16

class FileObj:
17 18 19 20 21 22 23 24 25 26
    def __init__(self, filename):
        self.filename = filename
        self.changed = 0
        try:
            self.lines = open(filename, 'r').readlines()
        except IOError, msg:
            print '*** Can\'t open "%s":' % filename, msg
            self.lines = None
            return
        print 'diffing', self.filename
Guido van Rossum's avatar
Guido van Rossum committed
27

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
    def finish(self):
        if not self.changed:
            print 'no changes to', self.filename
            return
        try:
            os.rename(self.filename, self.filename + '~')
            fp = open(self.filename, 'w')
        except (os.error, IOError), msg:
            print '*** Can\'t rewrite "%s":' % self.filename, msg
            return
        print 'writing', self.filename
        for line in self.lines:
            fp.write(line)
        fp.close()
        self.changed = 0
Guido van Rossum's avatar
Guido van Rossum committed
43

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
    def process(self, lineno, rest):
        if self.lines is None:
            print '(not processed): %s:%s:%s' % (
                      self.filename, lineno, rest),
            return
        i = eval(lineno) - 1
        if not 0 <= i < len(self.lines):
            print '*** Line number out of range: %s:%s:%s' % (
                      self.filename, lineno, rest),
            return
        if self.lines[i] == rest:
            print '(no change): %s:%s:%s' % (
                      self.filename, lineno, rest),
            return
        if not self.changed:
            self.changed = 1
        print '%sc%s' % (lineno, lineno)
        print '<', self.lines[i],
        print '---'
        self.lines[i] = rest
        print '>', self.lines[i],
Guido van Rossum's avatar
Guido van Rossum committed
65 66

def main():
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    if sys.argv[1:]:
        try:
            fp = open(sys.argv[1], 'r')
        except IOError, msg:
            print 'Can\'t open "%s":' % sys.argv[1], msg
            sys.exit(1)
    else:
        fp = sys.stdin
    curfile = None
    while 1:
        line = fp.readline()
        if not line:
            if curfile: curfile.finish()
            break
        n = prog.match(line)
        if n < 0:
            print 'Funny line:', line,
            continue
        filename, lineno = prog.group(1, 2)
        if not curfile or filename <> curfile.filename:
            if curfile: curfile.finish()
            curfile = FileObj(filename)
        curfile.process(lineno, line[n:])
Guido van Rossum's avatar
Guido van Rossum committed
90

91 92
if __name__ == "__main__":
    main()