Mercurial > codeOptimizer
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:28b636105ed6 |
|---|---|
| 1 import subprocess, re | |
| 2 | |
| 3 def tryCompileFile(file, compiler, flags): | |
| 4 cmd = compiler + " -x c++ -o /dev/null " + flags + " -c " + file | |
| 5 devnull = open('/dev/null', 'w') | |
| 6 p = subprocess.Popen(cmd, stdin=subprocess.PIPE, | |
| 7 stdout=devnull, stderr=None, shell=True) | |
| 8 s = p.wait() | |
| 9 devnull.close() | |
| 10 return s == 0 | |
| 11 | |
| 12 def tryCompileBuffer(buffer, compiler, flags): | |
| 13 cmd = compiler + " -x c++ -o /dev/null " + flags + " -c -" | |
| 14 devnull = open('/dev/null', 'w') | |
| 15 p = subprocess.Popen(cmd, stdin=subprocess.PIPE, | |
| 16 stdout=devnull, stderr=devnull, shell=True) | |
| 17 p.stdin.write(buffer) | |
| 18 p.stdin.close() | |
| 19 s = p.wait() | |
| 20 devnull.close() | |
| 21 return s == 0 | |
| 22 | |
| 23 | |
| 24 | |
| 25 class Compilable: | |
| 26 def __init__(self, path): | |
| 27 self.path = path | |
| 28 self.flags = '' | |
| 29 self.lines = None | |
| 30 | |
| 31 def setFlags(self, flags): | |
| 32 self.flags = flags | |
| 33 | |
| 34 def worksWithoutModifications(self): | |
| 35 return tryCompileFile(self.path, 'g++', self.flags) | |
| 36 | |
| 37 def activeBuffer(self): | |
| 38 self.loadFile() | |
| 39 str = '' | |
| 40 for i in range(len(self.lines)): | |
| 41 if not i in self.replace: | |
| 42 str += self.lines[i] | |
| 43 else: | |
| 44 str += self.replace[i] | |
| 45 return str | |
| 46 | |
| 47 def works(self): | |
| 48 return tryCompileBuffer(self.activeBuffer(), 'g++', self.flags) | |
| 49 | |
| 50 def deactivateLine(self, i): | |
| 51 self.replace[i] = "\n" | |
| 52 | |
| 53 def activateLine(self, i): | |
| 54 del self.replace[i] | |
| 55 | |
| 56 def loadFile(self): | |
| 57 if self.lines == None: | |
| 58 f = open(self.path, 'r') | |
| 59 self.lines = f.readlines() | |
| 60 f.close() | |
| 61 self.replace = {} | |
| 62 | |
| 63 def includeLines(self): | |
| 64 self.loadFile() | |
| 65 pattern = '^\s*#include ' | |
| 66 prog = re.compile(pattern) | |
| 67 res = [] | |
| 68 for i in range(len(self.lines)): | |
| 69 if prog.match(self.lines[i].rstrip()): | |
| 70 res.append(i) | |
| 71 return res | |
| 72 | |
| 73 def removeRemovableIncludes(self): | |
| 74 l = self.includeLines() | |
| 75 retVal = [] | |
| 76 for n in l: | |
| 77 self.deactivateLine(n) | |
| 78 print 'Trying to compile ' + self.path + ' without ' + self.getPathname(self.lines[n]) | |
| 79 if self.works(): | |
| 80 retVal.append(n) | |
| 81 else: | |
| 82 self.activateLine(n) | |
| 83 | |
| 84 return retVal | |
| 85 | |
| 86 @staticmethod | |
| 87 def getPathname(str): | |
| 88 pattern = '^\s*#include ["<]([^">]+)[">]' | |
| 89 prog = re.compile(pattern) | |
| 90 m = prog.search(str) | |
| 91 include = m.group(1) | |
| 92 return include | |
| 93 | |
| 94 | |
| 95 @staticmethod | |
| 96 def getClassname(str): | |
| 97 include = Compilable.getPathname(str) | |
| 98 | |
| 99 pattern = '[^/]+$' | |
| 100 prog = re.compile(pattern) | |
| 101 m = prog.search(include) | |
| 102 filename = m.group(0) | |
| 103 | |
| 104 pattern = '^[^.]+' | |
| 105 prog = re.compile(pattern) | |
| 106 m = prog.search(filename) | |
| 107 basename = m.group(0) | |
| 108 | |
| 109 return basename | |
| 110 | |
| 111 def replaceIncludes(self): | |
| 112 l = self.includeLines() | |
| 113 retVal = [] | |
| 114 for n in l: | |
| 115 if n not in self.replace: | |
| 116 rstring = 'class ' + self.getClassname(self.lines[n]) + ';\n' | |
| 117 self.replace[n] = rstring | |
| 118 if self.works(): | |
| 119 retVal.append(n) | |
| 120 else: | |
| 121 self.activateLine(n) | |
| 122 return retVal | |
| 123 | |
| 124 def dependencies(self): | |
| 125 lines = self.includeLines() | |
| 126 retVal = [] | |
| 127 for line in lines: | |
| 128 retVal.append(self.getPathname(self.lines[line])) | |
| 129 return retVal | |
| 130 | |
| 131 | |
| 132 def __repr__(self): | |
| 133 return self.path |
