Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env python
      2 import sys
      3 import os
      4 
      5 class FileContextsNode:
      6     path = None
      7     fileType = None
      8     context = None
      9     Type = None
     10     meta = None
     11     stemLen = None
     12     strLen = None
     13     Type = None
     14     def __init__(self, path, fileType, context, meta, stemLen, strLen):
     15         self.path = path
     16         self.fileType = fileType
     17         self.context = context
     18         self.meta = meta
     19         self.stemLen = stemLen
     20         self.strlen = strLen
     21         self.Type = context.split(":")[2]
     22 
     23 metaChars = frozenset(['.', '^', '$', '?', '*', '+', '|', '[', '(', '{'])
     24 escapedMetaChars = frozenset(['\.', '\^', '\$', '\?', '\*', '\+', '\|', '\[', '\(', '\{'])
     25 
     26 def getStemLen(path):
     27     global metaChars
     28     stemLen = 0
     29     i = 0
     30     while i < len(path):
     31         if path[i] == "\\":
     32             i += 1
     33         elif path[i] in metaChars:
     34             break
     35         stemLen += 1
     36         i += 1
     37     return stemLen
     38 
     39 
     40 def getIsMeta(path):
     41     global metaChars
     42     global escapedMetaChars
     43     metaCharsCount = 0
     44     escapedMetaCharsCount = 0
     45     for c in metaChars:
     46         if c in path:
     47             metaCharsCount += 1
     48     for c in escapedMetaChars:
     49         if c in path:
     50             escapedMetaCharsCount += 1
     51     return metaCharsCount > escapedMetaCharsCount
     52 
     53 def CreateNode(line):
     54     global metaChars
     55     if (len(line) == 0) or (line[0] == '#'):
     56         return None
     57 
     58     split = line.split()
     59     path = split[0].strip()
     60     context = split[-1].strip()
     61     fileType = None
     62     if len(split) == 3:
     63         fileType = split[1].strip()
     64     meta = getIsMeta(path)
     65     stemLen = getStemLen(path)
     66     strLen = len(path.replace("\\", ""))
     67 
     68     return FileContextsNode(path, fileType, context, meta, stemLen, strLen)
     69 
     70 def ReadFileContexts(files):
     71     fc = []
     72     for f in files:
     73         fd = open(f)
     74         for line in fd:
     75             node = CreateNode(line.strip())
     76             if node != None:
     77                 fc.append(node)
     78     return fc
     79 
     80 # Comparator function for list.sort() based off of fc_sort.c
     81 # Compares two FileContextNodes a and b and returns 1 if a is more
     82 # specific or -1 if b is more specific.
     83 def compare(a, b):
     84     # The regex without metachars is more specific
     85     if a.meta and not b.meta:
     86         return -1
     87     if b.meta and not a.meta:
     88         return 1
     89 
     90     # The regex with longer stemlen (regex before any meta characters) is more specific.
     91     if a.stemLen < b.stemLen:
     92         return -1
     93     if b.stemLen < a.stemLen:
     94         return 1
     95 
     96     # The regex with longer string length is more specific
     97     if a.strLen < b.strLen:
     98         return -1
     99     if b.strLen < a.strLen:
    100         return 1
    101 
    102     # A regex with a fileType defined (e.g. file, dir) is more specific.
    103     if a.fileType is None and b.fileType is not None:
    104         return -1
    105     if b.fileType is None and a.fileType is not None:
    106         return 1
    107 
    108     # Regexes are equally specific.
    109     return 0
    110 
    111 def FcSort(files):
    112     for f in files:
    113         if not os.path.exists(f):
    114             sys.exit("Error: File_contexts file " + f + " does not exist\n")
    115 
    116     Fc = ReadFileContexts(files)
    117     Fc.sort(cmp=compare)
    118 
    119     return Fc
    120 
    121 if __name__ == '__main__':
    122     if len(sys.argv) < 2:
    123         sys.exit("Usage: fc_sort.py <file_contexts 1> <file_contexts 2> <file_contexts 3>")
    124 
    125     FcSorted = FcSort(sys.argv[1:])
    126