• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /usr/bin/env python
2
3# Update a bunch of files according to a script.
4# The input file contains lines of the form <filename>:<lineno>:<text>,
5# meaning that the given line of the given file is to be replaced
6# by the given text.  This is useful for performing global substitutions
7# on grep output:
8
9import os
10import sys
11import re
12
13pat = '^([^: \t\n]+):([1-9][0-9]*):'
14prog = re.compile(pat)
15
16class FileObj:
17    def __init__(self, filename):
18        self.filename = filename
19        self.changed = 0
20        try:
21            self.lines = open(filename, 'r').readlines()
22        except IOError, msg:
23            print '*** Can\'t open "%s":' % filename, msg
24            self.lines = None
25            return
26        print 'diffing', self.filename
27
28    def finish(self):
29        if not self.changed:
30            print 'no changes to', self.filename
31            return
32        try:
33            os.rename(self.filename, self.filename + '~')
34            fp = open(self.filename, 'w')
35        except (os.error, IOError), msg:
36            print '*** Can\'t rewrite "%s":' % self.filename, msg
37            return
38        print 'writing', self.filename
39        for line in self.lines:
40            fp.write(line)
41        fp.close()
42        self.changed = 0
43
44    def process(self, lineno, rest):
45        if self.lines is None:
46            print '(not processed): %s:%s:%s' % (
47                      self.filename, lineno, rest),
48            return
49        i = eval(lineno) - 1
50        if not 0 <= i < len(self.lines):
51            print '*** Line number out of range: %s:%s:%s' % (
52                      self.filename, lineno, rest),
53            return
54        if self.lines[i] == rest:
55            print '(no change): %s:%s:%s' % (
56                      self.filename, lineno, rest),
57            return
58        if not self.changed:
59            self.changed = 1
60        print '%sc%s' % (lineno, lineno)
61        print '<', self.lines[i],
62        print '---'
63        self.lines[i] = rest
64        print '>', self.lines[i],
65
66def main():
67    if sys.argv[1:]:
68        try:
69            fp = open(sys.argv[1], 'r')
70        except IOError, msg:
71            print 'Can\'t open "%s":' % sys.argv[1], msg
72            sys.exit(1)
73    else:
74        fp = sys.stdin
75    curfile = None
76    while 1:
77        line = fp.readline()
78        if not line:
79            if curfile: curfile.finish()
80            break
81        n = prog.match(line)
82        if n < 0:
83            print 'Funny line:', line,
84            continue
85        filename, lineno = prog.group(1, 2)
86        if not curfile or filename <> curfile.filename:
87            if curfile: curfile.finish()
88            curfile = FileObj(filename)
89        curfile.process(lineno, line[n:])
90
91if __name__ == "__main__":
92    main()
93