1# common python utility routines for the Bionic tool scripts 2 3import commands 4import logging 5import os 6import string 7import sys 8 9 10def panic(msg): 11 sys.stderr.write(os.path.basename(sys.argv[0]) + ": error: ") 12 sys.stderr.write(msg) 13 sys.exit(1) 14 15 16def get_kernel_headers_dir(): 17 return os.path.join(get_android_root(), "external/kernel-headers") 18 19 20def get_kernel_headers_original_dir(): 21 return os.path.join(get_kernel_headers_dir(), "original") 22 23 24def get_kernel_headers_modified_dir(): 25 return os.path.join(get_kernel_headers_dir(), "modified") 26 27 28def get_kernel_dir(): 29 return os.path.join(get_android_root(), "bionic/libc/kernel") 30 31 32def get_android_root(): 33 if "ANDROID_BUILD_TOP" in os.environ: 34 # Verify that the current directory is in the root. 35 # If not, then print an error. 36 cwd = os.getcwd() 37 root = os.environ["ANDROID_BUILD_TOP"] 38 if len(cwd) < len(root) or not root == cwd[:len(root)]: 39 panic("Not in android tree pointed at by ANDROID_BUILD_TOP (%s)\n" % root) 40 return os.environ["ANDROID_BUILD_TOP"] 41 panic("Unable to find root of tree, did you forget to lunch a target?\n") 42 43 44class StringOutput: 45 def __init__(self): 46 self.line = "" 47 48 def write(self,msg): 49 self.line += msg 50 logging.debug("write '%s'" % msg) 51 52 def get(self): 53 return self.line 54 55 56def create_file_path(path): 57 dirs = [] 58 while 1: 59 parent = os.path.dirname(path) 60 #print "parent: %s <- %s" % (parent, path) 61 if parent == "/" or parent == "": 62 break 63 dirs.append(parent) 64 path = parent 65 66 dirs.reverse() 67 for dir in dirs: 68 #print "dir %s" % dir 69 if os.path.isdir(dir): 70 continue 71 os.mkdir(dir) 72 73 74class BatchFileUpdater: 75 """a class used to edit several files at once""" 76 def __init__(self): 77 self.old_files = set() 78 self.new_files = set() 79 self.new_data = {} 80 81 def readFile(self,path): 82 #path = os.path.realpath(path) 83 if os.path.exists(path): 84 self.old_files.add(path) 85 86 def readDir(self,path): 87 #path = os.path.realpath(path) 88 for root, dirs, files in os.walk(path): 89 for f in files: 90 dst = "%s/%s" % (root,f) 91 self.old_files.add(dst) 92 93 def editFile(self,dst,data): 94 """edit a destination file. if the file is not mapped from a source, 95 it will be added. return 0 if the file content wasn't changed, 96 1 if it was edited, or 2 if the file is new""" 97 #dst = os.path.realpath(dst) 98 result = 1 99 if os.path.exists(dst): 100 f = open(dst, "r") 101 olddata = f.read() 102 f.close() 103 if olddata == data: 104 self.old_files.remove(dst) 105 return 0 106 else: 107 result = 2 108 109 self.new_data[dst] = data 110 self.new_files.add(dst) 111 return result 112 113 def getChanges(self): 114 """determine changes, returns (adds, deletes, edits)""" 115 adds = set() 116 edits = set() 117 deletes = set() 118 119 for dst in self.new_files: 120 if not (dst in self.old_files): 121 adds.add(dst) 122 else: 123 edits.add(dst) 124 125 for dst in self.old_files: 126 if not dst in self.new_files: 127 deletes.add(dst) 128 129 return (adds, deletes, edits) 130 131 def _writeFile(self,dst): 132 if not os.path.exists(os.path.dirname(dst)): 133 create_file_path(dst) 134 f = open(dst, "w") 135 f.write(self.new_data[dst]) 136 f.close() 137 138 def updateFiles(self): 139 adds, deletes, edits = self.getChanges() 140 141 for dst in sorted(adds): 142 self._writeFile(dst) 143 144 for dst in sorted(edits): 145 self._writeFile(dst) 146 147 for dst in sorted(deletes): 148 os.remove(dst) 149 150 def updateGitFiles(self): 151 adds, deletes, edits = self.getChanges() 152 153 if adds: 154 for dst in sorted(adds): 155 self._writeFile(dst) 156 commands.getoutput("git add " + " ".join(adds)) 157 158 if deletes: 159 commands.getoutput("git rm " + " ".join(deletes)) 160 161 if edits: 162 for dst in sorted(edits): 163 self._writeFile(dst) 164 commands.getoutput("git add " + " ".join(edits)) 165