Home | History | Annotate | Download | only in scripts
      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 
      9 import os
     10 import sys
     11 import re
     12 
     13 pat = '^([^: \t\n]+):([1-9][0-9]*):'
     14 prog = re.compile(pat)
     15 
     16 class 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 
     66 def 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 
     91 if __name__ == "__main__":
     92     main()
     93