Mercurial > codeOptimizer
diff Compilable.py @ 0:28b636105ed6
Working version of codeOptimizer.
-Still needs to implement more finegrained control per file basis.
-CXXFLAGS are hardcoded.
| author | Tom Fredrik Blenning Klaussen <bfg@blenning.no> |
|---|---|
| date | Sat, 15 Sep 2012 20:34:39 +0200 |
| parents | |
| children | a1224150b8f6 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Compilable.py Sat Sep 15 20:34:39 2012 +0200 @@ -0,0 +1,133 @@ +import subprocess, re + +def tryCompileFile(file, compiler, flags): + cmd = compiler + " -x c++ -o /dev/null " + flags + " -c " + file + devnull = open('/dev/null', 'w') + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, + stdout=devnull, stderr=None, shell=True) + s = p.wait() + devnull.close() + return s == 0 + +def tryCompileBuffer(buffer, compiler, flags): + cmd = compiler + " -x c++ -o /dev/null " + flags + " -c -" + devnull = open('/dev/null', 'w') + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, + stdout=devnull, stderr=devnull, shell=True) + p.stdin.write(buffer) + p.stdin.close() + s = p.wait() + devnull.close() + return s == 0 + + + +class Compilable: + def __init__(self, path): + self.path = path + self.flags = '' + self.lines = None + + def setFlags(self, flags): + self.flags = flags + + def worksWithoutModifications(self): + return tryCompileFile(self.path, 'g++', self.flags) + + def activeBuffer(self): + self.loadFile() + str = '' + for i in range(len(self.lines)): + if not i in self.replace: + str += self.lines[i] + else: + str += self.replace[i] + return str + + def works(self): + return tryCompileBuffer(self.activeBuffer(), 'g++', self.flags) + + def deactivateLine(self, i): + self.replace[i] = "\n" + + def activateLine(self, i): + del self.replace[i] + + def loadFile(self): + if self.lines == None: + f = open(self.path, 'r') + self.lines = f.readlines() + f.close() + self.replace = {} + + def includeLines(self): + self.loadFile() + pattern = '^\s*#include ' + prog = re.compile(pattern) + res = [] + for i in range(len(self.lines)): + if prog.match(self.lines[i].rstrip()): + res.append(i) + return res + + def removeRemovableIncludes(self): + l = self.includeLines() + retVal = [] + for n in l: + self.deactivateLine(n) + print 'Trying to compile ' + self.path + ' without ' + self.getPathname(self.lines[n]) + if self.works(): + retVal.append(n) + else: + self.activateLine(n) + + return retVal + + @staticmethod + def getPathname(str): + pattern = '^\s*#include ["<]([^">]+)[">]' + prog = re.compile(pattern) + m = prog.search(str) + include = m.group(1) + return include + + + @staticmethod + def getClassname(str): + include = Compilable.getPathname(str) + + pattern = '[^/]+$' + prog = re.compile(pattern) + m = prog.search(include) + filename = m.group(0) + + pattern = '^[^.]+' + prog = re.compile(pattern) + m = prog.search(filename) + basename = m.group(0) + + return basename + + def replaceIncludes(self): + l = self.includeLines() + retVal = [] + for n in l: + if n not in self.replace: + rstring = 'class ' + self.getClassname(self.lines[n]) + ';\n' + self.replace[n] = rstring + if self.works(): + retVal.append(n) + else: + self.activateLine(n) + return retVal + + def dependencies(self): + lines = self.includeLines() + retVal = [] + for line in lines: + retVal.append(self.getPathname(self.lines[line])) + return retVal + + + def __repr__(self): + return self.path
