From 00eecee14fc528a068a6e239e8351313ee3b449d Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Wed, 10 May 2006 19:25:00 +0000 Subject: [PATCH] Development continues :) darcs-hash:20060510192546-f2ef6-ed0082ef8ab8eea3f44130adcd417ffe5c387f21.gz --- omkbuild.py | 198 ++++++++++++++++++++++++++++++++++++++++++---------- test.py | 11 ++- 2 files changed, 173 insertions(+), 36 deletions(-) diff --git a/omkbuild.py b/omkbuild.py index f0b8a7c..ed08875 100755 --- a/omkbuild.py +++ b/omkbuild.py @@ -1,52 +1,109 @@ #!/usr/bin/env python +""" +This script has two main functions: + + 1) Combine several snippets to form Makefile.rules file + 2) Split Makefile.rules file to the originnal snippets + +Snippet syntax: + + snippet ::= legal? documentation rules + + legal ::= comment* empty-comment empty-comment + documentation := comment* + rules ::= text + + comment ::= '#' text + empty-comment ::= '#' + text ::= [^#] ... + + Makefile.rules policies: + + * All the parts of the Makefile.rules are ordered in the same order + as they are in snippets i.e. copyrights, documentations and rules. + + * On the first line of each part of the Makefile.rules, there is + special mart of the form #OMK@. This mark + is used for splitting Makefile.rules back to the original + snippets. + +""" from optparse import OptionParser import os import sys import string +import re class Snippet: - - def __init__(self, fname): + 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 = [] - self.read(fname) - - def read(self, fname): + if fname: self.readFromFile(fname) + + def readFromFile(self, fname): + """Loads snippet from file.""" self.name = fname f = open(fname, "r") - current = self.legal + + self.readLines(f.readlines()) + + f.close + + def readLines(self, lines): + """Parses the snippet given in the list and stores it in + self.""" + currentPart = self.legal counter = 0 - for line in f: - if current == self.legal: + + for line in lines: + if currentPart == self.legal: if line.strip() == "#": counter += 1 - else: - if counter == 2: current = self.doc - counter = 0 - if line[0] != "#": current = self.code - - current.append(line) + else: counter = 0 + if counter == 2: currentPart = self.doc + if line[0] != "#": currentPart = self.code + + currentPart.append(line) if not self.doc: self.doc = self.legal self.legal = [] - - f.close + + def asLines(self): + lines = [] + for type in ['legal', 'doc', 'code']: + for line in self.__dict__[type]: + lines.append(line) + return lines def __str__(self): - s = "Snippet: %s\n" % self.name - s += " Legal: %d lines\n" % len(self.legal) - s += " Doc: %d lines\n" % len(self.doc) - s += " Code: %d lines\n" % len(self.code) + s = "" + lines = self.asLines() + for l in lines: s += l return s + def __repr__(self): + s = "" % self.name + return s + + def __cmp__(self, other): + ret = self.name.__cmp__(other.name) + if ret != 0: return ret + ret = self.legal.__cmp__(other.legal) + if ret != 0: return ret + ret = self.doc.__cmp__(other.doc) + if ret != 0: return ret + ret = self.code.__cmp__(other.code) + return ret def parseCommandLine(): parser = OptionParser(usage = """ %prog [-o FILE] snippet1 snippet2 ... build Makefile.rules from snippets - %prog --split Makfile.rules + %prog [-o - ] -s Makfile.rules """) parser.add_option("-s", "--split", action="store", dest="split", default=False, metavar="RULES", @@ -57,32 +114,103 @@ def parseCommandLine(): (options, args) = parser.parse_args() return options, args -def splitRules(rules): - pass +def splitToSnippets(rules): + """Split rules to the original snippets. The output is dictinary + of lists of lines""" -def buildRules(snippets, output): - if output: - f = open(output, "w+") - else: - f = sys.stdout + 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() - parts = [] + 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 snip in snippets: - parts.append(Snippet(snip)) + 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 snip in parts: + for s in snippets: + snip = snippets[s] if len(snip.__dict__[type]) == 0: continue firstLine = string.rstrip(snip.__dict__[type][0]) - f.write(firstLine.ljust(60)+" #@omk@%s\n"%snip.name) - f.writelines(snip.__dict__[type][1:]) + 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: + sys.exit(1) + + + if output: f = open(output,"w+") + else: + f = sys.stdout + + f.writelines(rules) + f.close() +def splitRules(rulesFN, output): + pass + def main(): (options, args) = parseCommandLine() if options.split: - splitRules(options.split) + splitRules(options.split, options.output) else: buildRules(args, options.output) diff --git a/test.py b/test.py index 7983481..576eadb 100755 --- a/test.py +++ b/test.py @@ -2,7 +2,16 @@ import omkbuild import sys +import os -sys.argv = ['./omkbuild.py', 'test/test1.rules', 'test/test2.rules', 'test/test3.rules'] +os.chdir("test"); +sys.argv = ['./omkbuild.py', '--output=Makefile.rules', + 'test1.rules', 'test2.rules', 'test3.rules'] omkbuild.main() + +os.system("cat Makefile.rules") + +# sys.argv = ['./omkbuild.py', '--split=Makefile.rules', '-o -'] +# omkbuild.main() + -- 2.39.2