Only maintain maps between current and previous selinux versions.

New maintenance scheme for mapping files:
Say, V is the current SELinux platform version, then at any point in time we
only maintain (V->V-1) mapping. (V->V-n) map is constructed from top (V->V-n+1)
and bottom (V-n+1->V-n) without changes to previously maintained mapping files.

Caveats:
- 26.0.cil doesn't technically represent 27.0->26.0 map, but rather
current->26.0. We'll fully migrate to the scheme with future releases.

Bug: 67510052
Test: adding new public type only requires changing the latest compat map
Change-Id: Iab5564e887ef2c8004cb493505dd56c6220c61f8
diff --git a/tests/mini_parser.py b/tests/mini_parser.py
index 9182c5d..cba9e39 100644
--- a/tests/mini_parser.py
+++ b/tests/mini_parser.py
@@ -12,6 +12,7 @@
     def __init__(self, policyFile):
         self.types = set() # types declared in mapping
         self.pubtypes = set()
+        self.expandtypeattributes = {}
         self.typeattributes = set() # attributes declared in mapping
         self.typeattributesets = {} # sets defined in mapping
         self.rTypeattributesets = {} # reverse mapping of above sets
@@ -27,6 +28,32 @@
         if m:
             self.apiLevel = m.group(1)
 
+    def unparse(self):
+        def wrapParens(stmt):
+            return "(" + stmt + ")"
+
+        def joinWrapParens(entries):
+            return wrapParens(" ".join(entries))
+
+        result = ""
+        for ty in sorted(self.types):
+            result += joinWrapParens(["type", ty]) + "\n"
+
+        for ta in sorted(self.typeattributes):
+            result += joinWrapParens(["typeattribute", ta]) + "\n"
+
+        for eta in sorted(self.expandtypeattributes.items(),
+                          key=lambda x: x[0]):
+            result += joinWrapParens(
+                    ["expandtypeattribute", wrapParens(eta[0]), eta[1]]) + "\n"
+
+        for tas in sorted(self.typeattributesets.items(), key=lambda x: x[0]):
+            result += joinWrapParens(
+                    ["typeattributeset", tas[0],
+                     joinWrapParens(sorted(tas[1]))]) + "\n"
+
+        return result
+
     def _getNextStmt(self, infile):
         parens = 0
         s = ""
@@ -55,6 +82,11 @@
         self.types.add(m.group(1))
         return
 
+    def _parseExpandtypeattribute(self, stmt):
+        m = re.match(r"expandtypeattribute\s+\((.+)\)\s+(true|false)", stmt)
+        self.expandtypeattributes[m.group(1)] = m.group(2)
+        return
+
     def _parseTypeattribute(self, stmt):
         m = re.match(r"typeattribute\s+(.+)", stmt)
         self.typeattributes.add(m.group(1))
@@ -73,7 +105,7 @@
         for t in tas:
             if self.rTypeattributesets.get(t) is None:
                 self.rTypeattributesets[t] = set()
-            self.rTypeattributesets[t].update(set(ta))
+            self.rTypeattributesets[t].update([ta])
 
         # check to see if this typeattributeset is a versioned public type
         pub = re.match(r"(\w+)_\d+_\d+", ta)
@@ -88,6 +120,8 @@
             self._parseTypeattribute(stmt)
         elif re.match(r"typeattributeset\s+.+", stmt):
             self._parseTypeattributeset(stmt)
+        elif re.match(r"expandtypeattribute\s+.+", stmt):
+            self._parseExpandtypeattribute(stmt)
         return
 
 if __name__ == '__main__':