|
1 | 1 | import sys |
| 2 | +import unicodedata |
| 3 | +import re |
2 | 4 | from glob import * |
3 | 5 |
|
4 | 6 | state = 0 |
5 | 7 |
|
6 | 8 | for file in glob("*.*"): |
7 | | - if(file != "test_cases.py"): |
8 | | - with open(file, "rt") as fin: |
9 | | - i = 0 |
10 | | - for line in fin: |
11 | | - i = i + 1 |
12 | | - |
13 | | - # Test case 1 is checking if there are illegal tabulators in the code |
14 | | - if line.find("\t") != -1: |
15 | | - print(file + " in line " + str(i) + ": not permitted tab found") |
| 9 | + with open(file, "rt") as fin: |
| 10 | + i = 0 |
| 11 | + isEnum = False |
| 12 | + enumName = "" |
| 13 | + noMessage = 0 |
| 14 | + noComment = 0 |
| 15 | + |
| 16 | + for line in fin: |
| 17 | + i = i + 1 |
| 18 | + |
| 19 | + # -------------------------------------------------------------- |
| 20 | + # Test case 1 is checking if there are illegal tabulators in the code |
| 21 | + if line.find("\t") != -1: |
| 22 | + print(file + " in line " + str(i) + ": not permitted tab found") |
| 23 | + state = 1 |
| 24 | + |
| 25 | + # -------------------------------------------------------------- |
| 26 | + # Test case 2 is checking if there is an "Umlaut" etc. |
| 27 | + if (sys.version_info >= (3, 0)): |
| 28 | + if line != unicodedata.normalize('NFKD', line).encode('ASCII', 'ignore').decode(): |
| 29 | + print(file + " in line " + str(i) + ": a none ASCII char is present") |
| 30 | + state = 1 |
| 31 | + else: |
| 32 | + if line != unicodedata.normalize('NFKD', unicode(line, 'ISO-8859-1')).encode('ASCII', 'ignore'): |
| 33 | + print(file + " in line " + str(i) + ": a none ASCII char is present") |
16 | 34 | state = 1 |
17 | 35 |
|
18 | | - # Test case 2 is checking if there are more than the two allowed '/' |
| 36 | + if file.find(".proto") != -1: |
| 37 | + # -------------------------------------------------------------- |
| 38 | + # Test case 3 is checking if there are more than the two allowed '/' |
19 | 39 | if line.find("///") != -1: |
20 | 40 | print(file + " in line " + str(i) + ": not permitted use of '///' ") |
21 | 41 | state = 1 |
22 | 42 |
|
| 43 | + # -------------------------------------------------------------- |
| 44 | + # Test case 4 is checking if there is an other type of comment |
| 45 | + if line.find("/*") != -1: |
| 46 | + print(file + " in line " + str(i) + ": not permitted use of '/*' ") |
| 47 | + state = 1 |
| 48 | + |
| 49 | + # -------------------------------------------------------------- |
| 50 | + # Test case 5 is checking if there is an other type of comment |
| 51 | + if line.find("*/") != -1: |
| 52 | + print(file + " in line " + str(i) + ": not permitted use of '*/' ") |
| 53 | + state = 1 |
| 54 | + |
| 55 | + # -------------------------------------------------------------- |
| 56 | + |
| 57 | + # Search for comment ("//") and add one more slash character ("/") to the comment |
| 58 | + # block to make Doxygen detect it. |
| 59 | + matchComment = re.search("//", line) |
| 60 | + if matchComment is not None: |
| 61 | + statement = line[:matchComment.start()] |
| 62 | + else: |
| 63 | + statement = line |
| 64 | + |
| 65 | + # -------------------------------------------------------------- |
| 66 | + # Test case 6-8 camelcase for enums and check enum name? |
| 67 | + |
| 68 | + # . |
| 69 | + if isEnum is True: |
| 70 | + matchName = re.search(r"\b\w[\S:]+\b", statement) |
| 71 | + if matchName is not None: |
| 72 | + checkName = statement[matchName.start():matchName.end()] |
| 73 | + # Test case 6: Check correct name |
| 74 | + if checkName.find(enumName) != 0: |
| 75 | + print(file + " in line " + str(i) + ": enum type wrong. '"+checkName+"' should start with '"+enumName+"'") |
| 76 | + state = 1 |
| 77 | + # Test case 7: Check upper case |
| 78 | + elif checkName != checkName.upper(): |
| 79 | + print(file + " in line " + str(i) + ": enum type wrong. '"+checkName+"' should use upper case") |
| 80 | + state = 1 |
| 81 | + |
| 82 | + # Search for "enum". |
| 83 | + matchEnum = re.search(r"\benum\b", statement) |
| 84 | + if matchEnum is not None: |
| 85 | + isEnum = True |
| 86 | + endOfLine = statement[matchEnum.end():] |
| 87 | + matchName = re.search(r"\b\w[\S]*\b", endOfLine) |
| 88 | + if matchName is not None: |
| 89 | + # Test case 8: Check name - no special char |
| 90 | + matchNameConv = re.search(r"\b[A-Z][a-zA-Z0-9]*\b",endOfLine[matchName.start():matchName.end()]) |
| 91 | + if matchNameConv is None: |
| 92 | + print(file + " in line " + str(i) + ": enum name wrong. '"+endOfLine[matchName.start():matchName.end()]+"'") |
| 93 | + state = 1 |
| 94 | + enumName = convert(endOfLine[matchName.start():matchName.end()])+"_" |
| 95 | + |
| 96 | + # Search for a closing brace. |
| 97 | + matchClosingBrace = re.search("}", statement) |
| 98 | + if isEnum is True and matchClosingBrace is not None: |
| 99 | + isEnum = False |
| 100 | + enumName = "" |
| 101 | + |
| 102 | + def convert(name): |
| 103 | + s1 = re.sub(r'(.)([A-Z][a-z]+)', r'\1_\2', name) |
| 104 | + return re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', s1).upper() |
| 105 | + |
| 106 | + # -------------------------------------------------------------- |
| 107 | + # Test case 9 is checking if there is '__' |
| 108 | + if line.find("__") != -1: |
| 109 | + print(file + " in line " + str(i) + ": not permitted use of '__' ") |
| 110 | + state = 1 |
| 111 | + |
| 112 | + # -------------------------------------------------------------- |
| 113 | + # Test case 10-12 check message name, field type and field name |
| 114 | + # |
| 115 | + # Check (nested) messages |
| 116 | + |
| 117 | + if isEnum is False: |
| 118 | + # Check if not inside an enum. |
| 119 | + |
| 120 | + # Search for "message". |
| 121 | + matchMessage = re.search(r"\bmessage\b", statement) |
| 122 | + if matchMessage is not None: |
| 123 | + # a new message or a new nested message |
| 124 | + noMessage += 1 |
| 125 | + endOfLine = statement[matchMessage.end():] |
| 126 | + matchName = re.search(r"\b\w[\S]*\b", endOfLine) |
| 127 | + if matchName is not None: |
| 128 | + # Test case 10: Check name - no special char - |
| 129 | + # start with a capital letter |
| 130 | + matchNameConv = re.search(r"\b[A-Z][a-zA-Z0-9]*\b",endOfLine[matchName.start():matchName.end()]) |
| 131 | + if matchNameConv is None: |
| 132 | + print(file + " in line " + str(i) + ": message name wrong. '"+endOfLine[matchName.start():matchName.end()]+"'") |
| 133 | + state = 1 |
| 134 | + else: |
| 135 | + # Check field names |
| 136 | + if noMessage > 0: |
| 137 | + matchName = re.search(r"\b\w[\S]*\b\s*=", statement) |
| 138 | + if matchName is not None: |
| 139 | + checkName = statement[matchName.start():matchName.end()-1] |
| 140 | + # Test case 11: Check lowercase letters for field names |
| 141 | + if checkName != checkName.lower(): |
| 142 | + print(file + " in line " + str(i) + ": field name wrong. '"+checkName+"' should use lower case") |
| 143 | + state = 1 |
| 144 | + # Check field message type (remove field name) |
| 145 | + type = statement.replace(checkName, "") |
| 146 | + matchName = re.search(r"\b\w[\S\.]*\s*=", type) |
| 147 | + if matchName is not None: |
| 148 | + checkType = " "+type[matchName.start():matchName.end()-1]+" " |
| 149 | + # Test case 12: Check nested message type |
| 150 | + matchNameConv = re.search(r"[ ][a-zA-Z][a-zA-Z0-9]*([\.][A-Z][a-zA-Z0-9]*)*[ ]",checkType) |
| 151 | + if matchNameConv is None: |
| 152 | + print(file + " in line " + str(i) + ": field message type wrong. Check: '"+checkType+"'") |
| 153 | + state = 1 |
| 154 | + |
| 155 | + # Search for a closing brace. |
| 156 | + matchClosingBrace = re.search("}", statement) |
| 157 | + if noMessage > 0 and matchClosingBrace is not None: |
| 158 | + noMessage -= 1 |
| 159 | + |
| 160 | + # -------------------------------------------------------------- |
| 161 | + # Test case 13 is checking if comment is min. 2 lines |
| 162 | + if line.find("//") != -1: |
| 163 | + noComment += 1; |
| 164 | + else: |
| 165 | + if noComment == 1: |
| 166 | + print(file + " in line " + str(i-1) + ": short comment - min. 2 lines.") |
| 167 | + state = 1 |
| 168 | + noComment = 0 |
| 169 | + |
| 170 | + # -------------------------------------------------------------- |
| 171 | + |
| 172 | + |
23 | 173 | sys.exit(state) |
| 174 | + |
0 commit comments