]> rtime.felk.cvut.cz Git - omk.git/commitdiff
Development continues :)
authorMichal Sojka <sojkam1@fel.cvut.cz>
Wed, 10 May 2006 19:25:00 +0000 (19:25 +0000)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Wed, 10 May 2006 19:25:00 +0000 (19:25 +0000)
darcs-hash:20060510192546-f2ef6-ed0082ef8ab8eea3f44130adcd417ffe5c387f21.gz

omkbuild.py
test.py

index f0b8a7cbbd2012eecfb76b3ad332221ca872a67b..ed08875e7c4628d3218e1cf8499dd79a0a8e19d8 100755 (executable)
 #!/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@<snippet file name><EOL>. 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 = "<Snippet: %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 7983481ae8d41c326606586c66423d11665eb735..576eadb29ea1e324ad8bff23392a94b32119aacd 100755 (executable)
--- 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()
+