e6ddfc55c8
Change-Id: I91ca466d1b6f8a39da50ce61acebc268d0daab3a
267 lines
7.1 KiB
Python
267 lines
7.1 KiB
Python
# common python utility routines for the Bionic tool scripts
|
|
|
|
import sys, os, commands, string, commands
|
|
|
|
# basic debugging trace support
|
|
# call D_setlevel to set the verbosity level
|
|
# and D(), D2(), D3(), D4() to add traces
|
|
#
|
|
verbose = 0
|
|
|
|
def panic(msg):
|
|
sys.stderr.write( find_program_name() + ": error: " )
|
|
sys.stderr.write( msg )
|
|
sys.exit(1)
|
|
|
|
def D(msg):
|
|
global verbose
|
|
if verbose > 0:
|
|
print msg
|
|
|
|
def D2(msg):
|
|
global verbose
|
|
if verbose >= 2:
|
|
print msg
|
|
|
|
def D3(msg):
|
|
global verbose
|
|
if verbose >= 3:
|
|
print msg
|
|
|
|
def D4(msg):
|
|
global verbose
|
|
if verbose >= 4:
|
|
print msg
|
|
|
|
def D_setlevel(level):
|
|
global verbose
|
|
verbose = level
|
|
|
|
|
|
# other stuff
|
|
#
|
|
#
|
|
def find_program_name():
|
|
return os.path.basename(sys.argv[0])
|
|
|
|
def find_program_dir():
|
|
return os.path.dirname(sys.argv[0])
|
|
|
|
def find_file_from_upwards(from_path,target_file):
|
|
"""find a file in the current directory or its parents. if 'from_path' is None,
|
|
seach from the current program's directory"""
|
|
path = from_path
|
|
if path == None:
|
|
path = os.path.realpath(sys.argv[0])
|
|
path = os.path.dirname(path)
|
|
D("this script seems to be located in: %s" % path)
|
|
|
|
while 1:
|
|
D("probing "+path)
|
|
if path == "":
|
|
file = target_file
|
|
else:
|
|
file = path + "/" + target_file
|
|
|
|
if os.path.isfile(file):
|
|
D("found %s in %s" % (target_file, path))
|
|
return file
|
|
|
|
if path == "":
|
|
return None
|
|
|
|
path = os.path.dirname(path)
|
|
|
|
|
|
class StringOutput:
|
|
def __init__(self):
|
|
self.line = ""
|
|
|
|
def write(self,msg):
|
|
self.line += msg
|
|
D2("write '%s'" % msg)
|
|
|
|
def get(self):
|
|
return self.line
|
|
|
|
|
|
def create_file_path(path):
|
|
dirs = []
|
|
while 1:
|
|
parent = os.path.dirname(path)
|
|
#print "parent: %s <- %s" % (parent, path)
|
|
if parent == "/" or parent == "":
|
|
break
|
|
dirs.append(parent)
|
|
path = parent
|
|
|
|
dirs.reverse()
|
|
for dir in dirs:
|
|
#print "dir %s" % dir
|
|
if os.path.isdir(dir):
|
|
continue
|
|
os.mkdir(dir)
|
|
|
|
def walk_source_files(paths,callback,args,excludes=[]):
|
|
"""recursively walk a list of paths and files, only keeping the source files in directories"""
|
|
for path in paths:
|
|
if len(path) > 0 and path[0] == '@':
|
|
# this is the name of another file, include it and parse it
|
|
path = path[1:]
|
|
if os.path.exists(path):
|
|
for line in open(path):
|
|
if len(line) > 0 and line[-1] == '\n':
|
|
line = line[:-1]
|
|
walk_source_files([line],callback,args,excludes)
|
|
continue
|
|
if not os.path.isdir(path):
|
|
callback(path,args)
|
|
else:
|
|
for root, dirs, files in os.walk(path):
|
|
#print "w-- %s (ex: %s)" % (repr((root,dirs)), repr(excludes))
|
|
if len(excludes):
|
|
for d in dirs[:]:
|
|
if os.path.join(root,d) in excludes:
|
|
dirs.remove(d)
|
|
for f in files:
|
|
r, ext = os.path.splitext(f)
|
|
if ext in [ ".h", ".c", ".cpp", ".S" ]:
|
|
callback( "%s/%s" % (root,f), args )
|
|
|
|
def cleanup_dir(path):
|
|
"""create a directory if needed, and ensure that it is totally empty
|
|
by removing any existing content in it"""
|
|
if not os.path.exists(path):
|
|
os.mkdir(path)
|
|
else:
|
|
for root, dirs, files in os.walk(path, topdown=False):
|
|
if root.endswith("kernel_headers/"):
|
|
# skip 'kernel_headers'
|
|
continue
|
|
for name in files:
|
|
os.remove(os.path.join(root, name))
|
|
for name in dirs:
|
|
os.rmdir(os.path.join(root, name))
|
|
|
|
def update_file( path, newdata ):
|
|
"""update a file on disk, only if its content has changed"""
|
|
if os.path.exists( path ):
|
|
try:
|
|
f = open( path, "r" )
|
|
olddata = f.read()
|
|
f.close()
|
|
except:
|
|
D("update_file: cannot read existing file '%s'" % path)
|
|
return 0
|
|
|
|
if oldata == newdata:
|
|
D2("update_file: no change to file '%s'" % path )
|
|
return 0
|
|
|
|
update = 1
|
|
else:
|
|
try:
|
|
create_file_path(path)
|
|
except:
|
|
D("update_file: cannot create path to '%s'" % path)
|
|
return 0
|
|
|
|
f = open( path, "w" )
|
|
f.write( newdata )
|
|
f.close()
|
|
|
|
return 1
|
|
|
|
|
|
class BatchFileUpdater:
|
|
"""a class used to edit several files at once"""
|
|
def __init__(self):
|
|
self.old_files = set()
|
|
self.new_files = set()
|
|
self.new_data = {}
|
|
|
|
def readFile(self,path):
|
|
#path = os.path.realpath(path)
|
|
if os.path.exists(path):
|
|
self.old_files.add(path)
|
|
|
|
def readDir(self,path):
|
|
#path = os.path.realpath(path)
|
|
for root, dirs, files in os.walk(path):
|
|
for f in files:
|
|
dst = "%s/%s" % (root,f)
|
|
self.old_files.add(dst)
|
|
|
|
def editFile(self,dst,data):
|
|
"""edit a destination file. if the file is not mapped from a source,
|
|
it will be added. return 0 if the file content wasn't changed,
|
|
1 if it was edited, or 2 if the file is new"""
|
|
#dst = os.path.realpath(dst)
|
|
result = 1
|
|
if os.path.exists(dst):
|
|
f = open(dst, "r")
|
|
olddata = f.read()
|
|
f.close()
|
|
if olddata == data:
|
|
self.old_files.remove(dst)
|
|
return 0
|
|
else:
|
|
result = 2
|
|
|
|
self.new_data[dst] = data
|
|
self.new_files.add(dst)
|
|
return result
|
|
|
|
def getChanges(self):
|
|
"""determine changes, returns (adds, deletes, edits)"""
|
|
adds = set()
|
|
edits = set()
|
|
deletes = set()
|
|
|
|
for dst in self.new_files:
|
|
if not (dst in self.old_files):
|
|
adds.add(dst)
|
|
else:
|
|
edits.add(dst)
|
|
|
|
for dst in self.old_files:
|
|
if not dst in self.new_files:
|
|
deletes.add(dst)
|
|
|
|
return (adds, deletes, edits)
|
|
|
|
def _writeFile(self,dst):
|
|
if not os.path.exists(os.path.dirname(dst)):
|
|
create_file_path(dst)
|
|
f = open(dst, "w")
|
|
f.write(self.new_data[dst])
|
|
f.close()
|
|
|
|
def updateFiles(self):
|
|
adds, deletes, edits = self.getChanges()
|
|
|
|
for dst in sorted(adds):
|
|
self._writeFile(dst)
|
|
|
|
for dst in sorted(edits):
|
|
self._writeFile(dst)
|
|
|
|
for dst in sorted(deletes):
|
|
os.remove(dst)
|
|
|
|
def updateGitFiles(self):
|
|
adds, deletes, edits = self.getChanges()
|
|
|
|
if adds:
|
|
for dst in sorted(adds):
|
|
self._writeFile(dst)
|
|
commands.getoutput("git add " + " ".join(adds))
|
|
|
|
if deletes:
|
|
commands.getoutput("git rm " + " ".join(deletes))
|
|
|
|
if edits:
|
|
for dst in sorted(edits):
|
|
self._writeFile(dst)
|
|
commands.getoutput("git add " + " ".join(edits))
|