From e7c82b193c34c04fb7ca7a7dcb465b9b83e910bd Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Wed, 10 May 2006 22:47:00 +0000 Subject: [PATCH] Almost final version of omkbuild.py darcs-hash:20060510224710-f2ef6-3baf59200bd2cbb2b18e054ed90fb51bb3fc7e66.gz --- omkbuild.py | 273 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 169 insertions(+), 104 deletions(-) diff --git a/omkbuild.py b/omkbuild.py index ed08875..5dc7c3a 100755 --- a/omkbuild.py +++ b/omkbuild.py @@ -35,17 +35,40 @@ import sys import string import re +class LineList(list): + """List of text lines""" + def getDiff(self, other): + s = '' + for i in range(len(self)): + if self[i] != other[i]: + s += (" Line %d differs!\n" % i) + s += " -"+self[i].rstrip() + "\n" + s += " +"+other[i].rstrip() + "\n" + break + return s + + def __str__(self): + s = '' + for l in self: s += l + return s + + def loadFromFile(self, fname): + """Loads itself from file.""" + f = open(fname, "r") + self.expand(f.readlines()) + f.close + class Snippet: def __init__(self, fname = None): """Initializes the snippet and if fname is given, reads it from file""" self.name = "" - self.legal = [] - self.doc = [] - self.code = [] - if fname: self.readFromFile(fname) + self.legal = LineList() + self.doc = LineList() + self.code = LineList() + if fname: self.loadFromFile(fname) - def readFromFile(self, fname): + def loadFromFile(self, fname): """Loads snippet from file.""" self.name = fname f = open(fname, "r") @@ -55,8 +78,7 @@ class Snippet: f.close def readLines(self, lines): - """Parses the snippet given in the list and stores it in - self.""" + """Parses the snippet given as a list and stores it in itself.""" currentPart = self.legal counter = 0 @@ -71,35 +93,134 @@ class Snippet: if not self.doc: self.doc = self.legal - self.legal = [] + self.legal = LineList() - def asLines(self): - lines = [] + def asLinesList(self): + lines = LineList() for type in ['legal', 'doc', 'code']: for line in self.__dict__[type]: lines.append(line) return lines def __str__(self): - s = "" - lines = self.asLines() - for l in lines: s += l - return s + return str(self.asLinesList()) def __repr__(self): s = "" % self.name return s def __cmp__(self, other): - ret = self.name.__cmp__(other.name) + ret = cmp(self.name, other.name) if ret != 0: return ret - ret = self.legal.__cmp__(other.legal) + ret = cmp(self.legal, other.legal) if ret != 0: return ret - ret = self.doc.__cmp__(other.doc) + ret = cmp(self.doc, other.doc) if ret != 0: return ret - ret = self.code.__cmp__(other.code) + ret = cmp(self.code, other.code) return ret + def __getitem__(self, key): + return { + 'legal': self.legal, + 'doc' : self.doc, + 'code' : self.code + }[key] + + def getDiff(self, other): + return self.asLinesList().getDiff(other.asLinesList()) + +class Snippets: + """Collection of snippets, where snippets can be accessed + individually by name (like dictionary) or sequentionaly in the + order they were added.""" + def __init__(self): + self._snippets = dict() + self._order = list() + + def __iadd__(self, snippet): + assert isinstance(snippet, Snippet) + self._snippets[snippet.name] = snippet + self._order += [snippet] + return self + + def __getitem__(self, key): + return self._snippets[key] + + def __contains__(self, item): + return item in self._snippets + + def __iter__(self): + return iter(self._order) + + def __cmp__(self, other): + return cmp(self._snippets, other._snippets) + + def loadFromFiles(self, fnames): + """Reads the snippets from several files and adds them to itself.""" + for fn in fnames: + self += Snippet(fn) + + def loadFromDict(self, snipDict): + """Adds snippets to itself from dictionary of LineLists.""" + for s in snipDict: + snip = Snippet() + snip.name = s + snip.readLines(snipDict[s]) + self += snip + + def getDiff(self, other): + assert isinstance(other, Snippets) + s = '' + for snip in self: + if (snip != other[snip.name]): + s += "Snippet %s:\n" % snip.name + s += snip.getDiff(other[snip.name]) + return s + +class MakefileRules(LineList): + def __init__(self): + self.snippets = Snippets() + self.rules = LineList() + + def combine(self): + """Combine self.snippets and produces self.rules""" + self.rules = LineList() + + for type in ['legal', 'doc', 'code']: + for snip in self.snippets: + lines = snip[type] + if len(lines) == 0: continue + firstLine = string.rstrip(lines[0]) + self.rules += [firstLine.ljust(60)+" #OMK@%s\n"%snip.name] + self.rules += lines[1:] + #self.rules += ['a'] # test error + + def split(self): + """Split self.rules to the original snippets in self.snippets.""" + self.snippets = Snippets() + snipDict = self._getSnipDicts() + self.snippets.loadFromDict(snipDict) + + def _getSnipDicts(self): + """Split self.rules to the original snippets, which are + returened as dictionary of LineLists.""" + snipBegin = re.compile("^(.*)#OMK@(.*)$") + snipDict = dict() + currentLinesList = None + + for line in self.rules: + match = snipBegin.match(line) + if match: + line = match.group(1).rstrip() + "\n" + snipName = match.group(2) + if not snipName in snipDict: + snipDict[snipName] = LineList() + currentLinesList = snipDict[snipName] + + currentLinesList.append(line); + return snipDict + + def parseCommandLine(): parser = OptionParser(usage = """ %prog [-o FILE] snippet1 snippet2 ... build Makefile.rules from snippets @@ -114,98 +235,42 @@ def parseCommandLine(): (options, args) = parser.parse_args() return options, args -def splitToSnippets(rules): - """Split rules to the original snippets. The output is dictinary - of lists of lines""" - - snipBegin = re.compile("^(.*)#OMK@(.*)$") - snipDict = dict() - currentLinesList = None - - for line in rules: - match = snipBegin.match(line) - if match: - line = match.group(1).rstrip() + "\n" - snipName = match.group(2) - if not snipName in snipDict: - snipDict[snipName] = [] - currentLinesList = snipDict[snipName] - - currentLinesList.append(line); - return snipDict - -def convertSnipDict(snipDict): - """Takes dictionary of snippets, where each snippet is a lists of - lines, as the input argument and returns dictionary of snippets objects""" - outDict = dict() - - for s in snipDict: - snip = Snippet() - snip.name = s - snip.readLines(snipDict[s]) - outDict[s] = snip - return outDict - -def readSnippets(fnames): - """Reads the snippets from several files and retuns them as a - dictionaly indexed by file name.""" - snipDict = dict() - - for fn in fnames: - snipDict[fn] = Snippet(fn) - - return snipDict - - -def combineRules(snippets): - """Combine all snippents from the snippets dictionary to one list - of lines.""" - - rules = list() - - for type in ['legal', 'doc', 'code']: - for s in snippets: - snip = snippets[s] - if len(snip.__dict__[type]) == 0: continue - firstLine = string.rstrip(snip.__dict__[type][0]) - rules.append(firstLine.ljust(60)+" #OMK@%s\n"%snip.name) - rules.extend(snip.__dict__[type][1:]); - return rules - -def assertSameSnippets(d1, d2): - theSame = d1==d2 - if not theSame: - # Generate an error message - for s in d1: - if (d1[s] != d2[s]): - sys.stderr.write("Consistency error: ") - s1 = d1[s] - s2 = d2[s] - for i in range(len(s1)): - if s1[i] != s2[i]: - sys.stderr.write("snippet %s, line %d differs!\n") - - return theSame - def buildRules(fnames, output): - snipDict = readSnippets(fnames) - rules = combineRules(snipDict) - snipDict2 = convertSnipDict(splitToSnippets(rules)) - - if assertSameSnippets(snipDict, snipDict2) == False: + rules = MakefileRules() + rules.snippets.loadFromFiles(fnames) + rules.combine() + + rulesCheck = MakefileRules() + rulesCheck.rules = rules.rules + rulesCheck.split() + + if rules.snippets != rulesCheck.snippets: + sys.stderr.write("Consistency error:\n") + diff = rules.snippets.getDiff(rulesCheck.snippets) + sys.stderr.write(diff) sys.exit(1) - if output: f = open(output,"w+") - else: - f = sys.stdout - - f.writelines(rules) - + else: f = sys.stdout + f.writelines(rules.rules) f.close() def splitRules(rulesFN, output): - pass + rules = MakefileRules() + rules.rules.loadFromFile(rulesFN) + rules.split() + + rulesCheck = MakefileRules() + rulesCheck.snippets = rules.snippets + rulesCheck.combine() + + if rules.rules != rulesCheck.rules: + sys.stderr.write("Consistency error:\n") + diff = rules.rules.getDiff(rulesCheck.rules) + sys.stderr.write(diff) + sys.exit(1) + + #TODO: Store snippets to files def main(): (options, args) = parseCommandLine() @@ -215,4 +280,4 @@ def main(): buildRules(args, options.output) -if __name__ == "__main__": main() +if __name__ == "__main__": main() -- 2.39.2