<s> from glob import glob <EOL> import os <EOL> from os import listdir <EOL> import os . path <EOL> import re <EOL> from tempfile import mktemp <EOL> def _escapeRegexChars ( txt , <EOL> escapeRE = re . compile ( r'<STR_LIT>' ) ) : <EOL> return escapeRE . sub ( r'<STR_LIT>' , txt ) <EOL> def findFiles ( * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> return FileFinder ( * args , ** kw ) . files ( ) <EOL> def replaceStrInFiles ( files , theStr , repl ) : <EOL> """<STR_LIT>""" <EOL> pattern = _escapeRegexChars ( theStr ) <EOL> return FindAndReplace ( files , pattern , repl ) . results ( ) <EOL> def replaceRegexInFiles ( files , pattern , repl ) : <EOL> """<STR_LIT>""" <EOL> return FindAndReplace ( files , pattern , repl ) . results ( ) <EOL> class FileFinder : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , rootPath , <EOL> globPatterns = ( '<STR_LIT:*>' , ) , <EOL> ignoreBasenames = ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ignoreDirs = ( ) , <EOL> ) : <EOL> self . _rootPath = rootPath <EOL> self . _globPatterns = globPatterns <EOL> self . _ignoreBasenames = ignoreBasenames <EOL> self . _ignoreDirs = ignoreDirs <EOL> self . _files = [ ] <EOL> self . walkDirTree ( rootPath ) <EOL> def walkDirTree ( self , dir = '<STR_LIT:.>' , <EOL> listdir = os . listdir , <EOL> isdir = os . path . isdir , <EOL> join = os . path . join , <EOL> ) : <EOL> """<STR_LIT>""" <EOL> processDir = self . processDir <EOL> filterDir = self . filterDir <EOL> pendingDirs = [ dir ] <EOL> addDir = pendingDirs . append <EOL> getDir = pendingDirs . pop <EOL> while pendingDirs : <EOL> dir = getDir ( ) <EOL> processDir ( dir ) <EOL> for baseName in listdir ( dir ) : <EOL> fullPath = join ( dir , baseName ) <EOL> if isdir ( fullPath ) : <EOL> if filterDir ( baseName , fullPath ) : <EOL> addDir ( fullPath ) <EOL> def filterDir ( self , baseName , fullPath ) : <EOL> """<STR_LIT>""" <EOL> return not ( baseName in self . _ignoreBasenames or <EOL> fullPath in self . _ignoreDirs ) <EOL> def processDir ( self , dir , glob = glob ) : <EOL> extend = self . _files . extend <EOL> for pattern in self . _globPatterns : <EOL> extend ( glob ( os . path . join ( dir , pattern ) ) ) <EOL> def files ( self ) : <EOL> return self . _files <EOL> class _GenSubberFunc : <EOL> """<STR_LIT>""" <EOL> backrefRE = re . compile ( r'<STR_LIT>' ) <EOL> groupRE = re . compile ( r'<STR_LIT>' ) <EOL> def __init__ ( self , replaceStr ) : <EOL> self . _src = replaceStr <EOL> self . _pos = <NUM_LIT:0> <EOL> self . _codeChunks = [ ] <EOL> self . parse ( ) <EOL> def src ( self ) : <EOL> return self . _src <EOL> def pos ( self ) : <EOL> return self . _pos <EOL> def setPos ( self , pos ) : <EOL> self . _pos = pos <EOL> def atEnd ( self ) : <EOL> return self . _pos >= len ( self . _src ) <EOL> def advance ( self , offset = <NUM_LIT:1> ) : <EOL> self . _pos += offset <EOL> def readTo ( self , to , start = None ) : <EOL> if start == None : <EOL> start = self . _pos <EOL> self . _pos = to <EOL> if self . atEnd ( ) : <EOL> return self . _src [ start : ] <EOL> else : <EOL> return self . _src [ start : to ] <EOL> def matchBackref ( self ) : <EOL> return self . backrefRE . match ( self . src ( ) , self . pos ( ) ) <EOL> def getBackref ( self ) : <EOL> m = self . matchBackref ( ) <EOL> self . setPos ( m . end ( ) ) <EOL> return m . group ( <NUM_LIT:1> ) <EOL> def matchGroup ( self ) : <EOL> return self . groupRE . match ( self . src ( ) , self . pos ( ) ) <EOL> def getGroup ( self ) : <EOL> m = self . matchGroup ( ) <EOL> self . setPos ( m . end ( ) ) <EOL> return m . group ( <NUM_LIT:1> ) <EOL> def parse ( self ) : <EOL> while not self . atEnd ( ) : <EOL> if self . matchBackref ( ) : <EOL> self . eatBackref ( ) <EOL> elif self . matchGroup ( ) : <EOL> self . eatGroup ( ) <EOL> else : <EOL> self . eatStrConst ( ) <EOL> def eatStrConst ( self ) : <EOL> startPos = self . pos ( ) <EOL> while not self . atEnd ( ) : <EOL> if self . matchBackref ( ) or self . matchGroup ( ) : <EOL> break <EOL> else : <EOL> self . advance ( ) <EOL> strConst = self . readTo ( self . pos ( ) , start = startPos ) <EOL> self . addChunk ( repr ( strConst ) ) <EOL> def eatBackref ( self ) : <EOL> self . addChunk ( '<STR_LIT>' + self . getBackref ( ) + '<STR_LIT:)>' ) <EOL> def eatGroup ( self ) : <EOL> self . addChunk ( '<STR_LIT>' + self . getGroup ( ) + '<STR_LIT>' ) <EOL> def addChunk ( self , chunk ) : <EOL> self . _codeChunks . append ( chunk ) <EOL> def codeBody ( self ) : <EOL> return '<STR_LIT:U+002CU+0020>' . join ( self . _codeChunks ) <EOL> def code ( self ) : <EOL> return "<STR_LIT>" % ( self . codeBody ( ) ) <EOL> def subberFunc ( self ) : <EOL> exec ( self . code ( ) ) <EOL> return subber <EOL> class FindAndReplace : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , files , patternOrRE , replacement , <EOL> recordResults = True ) : <EOL> if isinstance ( patternOrRE , basestring ) : <EOL> self . _regex = re . compile ( patternOrRE ) <EOL> else : <EOL> self . _regex = patternOrRE <EOL> if isinstance ( replacement , basestring ) : <EOL> self . _subber = _GenSubberFunc ( replacement ) . subberFunc ( ) <EOL> else : <EOL> self . _subber = replacement <EOL> self . _pattern = pattern = self . _regex . pattern <EOL> self . _files = files <EOL> self . _results = { } <EOL> self . _recordResults = recordResults <EOL> self . _usePgrep = False <EOL> if ( os . popen3 ( '<STR_LIT>' ) [ <NUM_LIT:2> ] . read ( ) ) . startswith ( '<STR_LIT>' ) : <EOL> tmpFile = mktemp ( ) <EOL> open ( tmpFile , '<STR_LIT:w>' ) . write ( '<STR_LIT:#>' ) <EOL> if not ( os . popen3 ( '<STR_LIT>' + pattern + '<STR_LIT>' + tmpFile ) [ <NUM_LIT:2> ] . read ( ) ) : <EOL> self . _usePgrep = True <EOL> os . remove ( tmpFile ) <EOL> self . _run ( ) <EOL> def results ( self ) : <EOL> return self . _results <EOL> def _run ( self ) : <EOL> regex = self . _regex <EOL> subber = self . _subDispatcher <EOL> usePgrep = self . _usePgrep <EOL> pattern = self . _pattern <EOL> for file in self . _files : <EOL> if not os . path . isfile ( file ) : <EOL> continue <EOL> self . _currFile = file <EOL> found = False <EOL> if '<STR_LIT>' in locals ( ) : <EOL> del orig <EOL> if self . _usePgrep : <EOL> if os . popen ( '<STR_LIT>' + pattern + '<STR_LIT>' + file ) . read ( ) : <EOL> found = True <EOL> else : <EOL> orig = open ( file ) . read ( ) <EOL> if regex . search ( orig ) : <EOL> found = True <EOL> if found : <EOL> if '<STR_LIT>' not in locals ( ) : <EOL> orig = open ( file ) . read ( ) <EOL> new = regex . sub ( subber , orig ) <EOL> open ( file , '<STR_LIT:w>' ) . write ( new ) <EOL> def _subDispatcher ( self , match ) : <EOL> if self . _recordResults : <EOL> if self . _currFile not in self . _results : <EOL> res = self . _results [ self . _currFile ] = { } <EOL> res [ '<STR_LIT:count>' ] = <NUM_LIT:0> <EOL> res [ '<STR_LIT>' ] = [ ] <EOL> else : <EOL> res = self . _results [ self . _currFile ] <EOL> res [ '<STR_LIT:count>' ] += <NUM_LIT:1> <EOL> res [ '<STR_LIT>' ] . append ( { '<STR_LIT>' : match . group ( ) , <EOL> '<STR_LIT:start>' : match . start ( ) , <EOL> '<STR_LIT:end>' : match . end ( ) , <EOL> } <EOL> ) <EOL> return self . _subber ( match ) <EOL> class SourceFileStats : <EOL> """<STR_LIT:U+0020>""" <EOL> _fileStats = None <EOL> def __init__ ( self , files ) : <EOL> self . _fileStats = stats = { } <EOL> for file in files : <EOL> stats [ file ] = self . getFileStats ( file ) <EOL> def rawStats ( self ) : <EOL> return self . _fileStats <EOL> def summary ( self ) : <EOL> codeLines = <NUM_LIT:0> <EOL> blankLines = <NUM_LIT:0> <EOL> commentLines = <NUM_LIT:0> <EOL> totalLines = <NUM_LIT:0> <EOL> for fileStats in self . rawStats ( ) . values ( ) : <EOL> codeLines += fileStats [ '<STR_LIT>' ] <EOL> blankLines += fileStats [ '<STR_LIT>' ] <EOL> commentLines += fileStats [ '<STR_LIT>' ] <EOL> totalLines += fileStats [ '<STR_LIT>' ] <EOL> stats = { '<STR_LIT>' : codeLines , <EOL> '<STR_LIT>' : blankLines , <EOL> '<STR_LIT>' : commentLines , <EOL> '<STR_LIT>' : totalLines , <EOL> } <EOL> return stats <EOL> def printStats ( self ) : <EOL> pass <EOL> def getFileStats ( self , fileName ) : <EOL> codeLines = <NUM_LIT:0> <EOL> blankLines = <NUM_LIT:0> <EOL> commentLines = <NUM_LIT:0> <EOL> commentLineRe = re . compile ( r'<STR_LIT>' ) <EOL> blankLineRe = re . compile ( '<STR_LIT>' ) <EOL> lines = open ( fileName ) . read ( ) . splitlines ( ) <EOL> totalLines = len ( lines ) <EOL> for line in lines : <EOL> if commentLineRe . match ( line ) : <EOL> commentLines += <NUM_LIT:1> <EOL> elif blankLineRe . match ( line ) : <EOL> blankLines += <NUM_LIT:1> <EOL> else : <EOL> codeLines += <NUM_LIT:1> <EOL> stats = { '<STR_LIT>' : codeLines , <EOL> '<STR_LIT>' : blankLines , <EOL> '<STR_LIT>' : commentLines , <EOL> '<STR_LIT>' : totalLines , <EOL> } <EOL> return stats </s>
