1655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng# common python utility routines for the Bionic tool scripts 2655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 3655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengimport commands 4655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengimport logging 5655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengimport os 6655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengimport string 7655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengimport sys 8655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 9655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 10655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef panic(msg): 11655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng sys.stderr.write(os.path.basename(sys.argv[0]) + ": error: ") 12655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng sys.stderr.write(msg) 13655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng sys.exit(1) 14655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 15655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 16655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef get_kernel_headers_dir(): 17655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng return os.path.join(get_android_root(), "external/kernel-headers") 18655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 19655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 20655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef get_kernel_headers_original_dir(): 21655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng return os.path.join(get_kernel_headers_dir(), "original") 22655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 23655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 24655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef get_kernel_headers_modified_dir(): 25655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng return os.path.join(get_kernel_headers_dir(), "modified") 26655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 27655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 28655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef get_kernel_dir(): 29655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng return os.path.join(get_android_root(), "bionic/libc/kernel") 30655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 31655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 32655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef get_android_root(): 33655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng if "ANDROID_BUILD_TOP" in os.environ: 34655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng # Verify that the current directory is in the root. 35655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng # If not, then print an error. 36655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng cwd = os.getcwd() 37655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng root = os.environ["ANDROID_BUILD_TOP"] 38655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng if len(cwd) < len(root) or not root == cwd[:len(root)]: 39655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng panic("Not in android tree pointed at by ANDROID_BUILD_TOP (%s)\n" % root) 40d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao return os.environ["ANDROID_BUILD_TOP"] 41d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao panic("Unable to find root of tree, did you forget to lunch a target?\n") 42d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao 43d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao 44655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengclass StringOutput: 45655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng def __init__(self): 46655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng self.line = "" 47d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao 48d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao def write(self,msg): 49655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng self.line += msg 50655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng logging.debug("write '%s'" % msg) 51655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 52d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao def get(self): 53d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao return self.line 54d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao 55655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 56655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Chengdef create_file_path(path): 57655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng dirs = [] 58d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao while 1: 59d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao parent = os.path.dirname(path) 60d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao #print "parent: %s <- %s" % (parent, path) 61d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao if parent == "/" or parent == "": 62d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao break 63d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao dirs.append(parent) 64655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng path = parent 65655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 6605d08e9716b5974d6ed08973f44930804890b902Christopher Ferris dirs.reverse() 6705d08e9716b5974d6ed08973f44930804890b902Christopher Ferris for dir in dirs: 6805d08e9716b5974d6ed08973f44930804890b902Christopher Ferris #print "dir %s" % dir 69655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng if os.path.isdir(dir): 70655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng continue 71655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng os.mkdir(dir) 72d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao 73d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao 74d7db594b8d1dab36b711bd887a9dd21675c87243Tao Baoclass BatchFileUpdater: 75d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao """a class used to edit several files at once""" 76d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao def __init__(self): 77d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao self.old_files = set() 78d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao self.new_files = set() 79d7db594b8d1dab36b711bd887a9dd21675c87243Tao Bao self.new_data = {} 80655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 81655a7c081f83b8351ed5f11a6c6accd9458293a8Ben Cheng 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