11#!/usr/bin/env python3
2+ """
3+ Author: thojkooi
4+ Description:
5+ Modified from https://github.com/acemod/ACE3/blob/master/tools/config_style_checker.py
6+ Validates that cpp, hpp, rvmat, and cfg files match the style guide.
7+ """
28
39import fnmatch
410import os
511import re
6- import ntpath
712import sys
813import argparse
14+ import logger
15+
916
1017def check_config_style (filepath ):
1118 bad_count_file = 0
19+
1220 def pushClosing (t ):
1321 closingStack .append (closing .expr )
14- closing << Literal ( closingFor [t [0 ]] )
22+ closing << Literal (closingFor [t [0 ]])
1523
1624 def popClosing ():
1725 closing << closingStack .pop ()
@@ -42,7 +50,7 @@ def popClosing():
4250 # We ignore everything inside a string
4351 isInString = False
4452 # Used to store the starting type of a string, so we can match that to the end of a string
45- inStringType = '' ;
53+ inStringType = ''
4654
4755 lastIsCurlyBrace = False
4856 checkForSemiColumn = False
@@ -55,9 +63,10 @@ def popClosing():
5563 for c in content :
5664 if (lastIsCurlyBrace ):
5765 lastIsCurlyBrace = False
58- if c == '\n ' : # Keeping track of our line numbers
59- lineNumber += 1 # so we can print accurate line number information when we detect a possible error
60- if (isInString ): # while we are in a string, we can ignore everything else, except the end of the string
66+ if c == '\n ' : # Keeping track of our line numbers
67+ # so we can print accurate line number information when we detect a possible error
68+ lineNumber += 1
69+ if (isInString ): # while we are in a string, we can ignore everything else, except the end of the string
6170 if (c == inStringType ):
6271 isInString = False
6372 # if we are not in a comment block, we will check if we are at the start of one or count the () {} and []
@@ -66,16 +75,18 @@ def popClosing():
6675 # This means we have encountered a /, so we are now checking if this is an inline comment or a comment block
6776 if (checkIfInComment ):
6877 checkIfInComment = False
69- if c == '*' : # if the next character after / is a *, we are at the start of a comment block
78+ if c == '*' : # if the next character after / is a *, we are at the start of a comment block
7079 isInCommentBlock = True
71- elif (c == '/' ): # Otherwise, will check if we are in an line comment
72- ignoreTillEndOfLine = True # and an line comment is a / followed by another / (//) We won't care about anything that comes after it
80+ elif (c == '/' ): # Otherwise, will check if we are in an line comment
81+ # and an line comment is a / followed by another / (//) We won't care about anything that comes after it
82+ ignoreTillEndOfLine = True
7383
7484 if (isInCommentBlock == False ):
75- if (ignoreTillEndOfLine ): # we are in a line comment, just continue going through the characters until we find an end of line
85+ # we are in a line comment, just continue going through the characters until we find an end of line
86+ if (ignoreTillEndOfLine ):
7687 if (c == '\n ' ):
7788 ignoreTillEndOfLine = False
78- else : # validate brackets
89+ else : # validate brackets
7990 if (c == '"' or c == "'" ):
8091 isInString = True
8192 inStringType = c
@@ -85,31 +96,39 @@ def popClosing():
8596 brackets_list .append ('(' )
8697 elif (c == ')' ):
8798 if (len (brackets_list ) > 0 and brackets_list [- 1 ] in ['{' , '[' ]):
88- print ("ERROR: Possible missing round bracket ')' detected at {0} Line number: {1}" .format (filepath ,lineNumber ))
99+ logger .log (
100+ logger .LogLevel .ERROR , "Possible missing round bracket ')' detected at {0} Line number: {1}" .format (
101+ filepath , lineNumber ))
89102 bad_count_file += 1
90103 brackets_list .append (')' )
91104 elif (c == '[' ):
92105 brackets_list .append ('[' )
93106 elif (c == ']' ):
94107 if (len (brackets_list ) > 0 and brackets_list [- 1 ] in ['{' , '(' ]):
95- print ("ERROR: Possible missing square bracket ']' detected at {0} Line number: {1}" .format (filepath ,lineNumber ))
108+ logger .log (
109+ logger .LogLevel .ERROR , "Possible missing square bracket ']' detected at {0} Line number: {1}" .format (
110+ filepath , lineNumber ))
96111 bad_count_file += 1
97112 brackets_list .append (']' )
98113 elif (c == '{' ):
99114 brackets_list .append ('{' )
100115 elif (c == '}' ):
101116 lastIsCurlyBrace = True
102117 if (len (brackets_list ) > 0 and brackets_list [- 1 ] in ['(' , '[' ]):
103- print ("ERROR: Possible missing curly brace '}}' detected at {0} Line number: {1}" .format (filepath ,lineNumber ))
118+ logger .log (
119+ logger .LogLevel .ERROR , "Possible missing curly brace '}}' detected at {0} Line number: {1}" .format (
120+ filepath , lineNumber ))
104121 bad_count_file += 1
105122 brackets_list .append ('}' )
106- elif (c == '\t ' ):
107- print ("ERROR: Tab detected at {0} Line number: {1}" .format (filepath ,lineNumber ))
123+ elif (c == '\t ' ):
124+ logger .log (
125+ logger .LogLevel .ERROR , "Tab detected at {0} Line number: {1}" .format (
126+ filepath , lineNumber ))
108127 bad_count_file += 1
109128
110- else : # Look for the end of our comment block
129+ else : # Look for the end of our comment block
111130 if (c == '*' ):
112- checkIfNextIsClosingBlock = True ;
131+ checkIfNextIsClosingBlock = True
113132 elif (checkIfNextIsClosingBlock ):
114133 if (c == '/' ):
115134 isInCommentBlock = False
@@ -118,70 +137,73 @@ def popClosing():
118137 indexOfCharacter += 1
119138
120139 if brackets_list .count ('[' ) != brackets_list .count (']' ):
121- print ( " ERROR: A possible missing square bracket [ or ] in file {0 } [ = {1} ] = {2}" . format ( filepath , brackets_list .count ('[' ), brackets_list .count (']' )) )
140+ logger . log ( logger . LogLevel . ERROR , f" A possible missing square bracket [ or ] in file { filepath } [ = { brackets_list .count ('[' )} ] = { brackets_list .count (']' )} " )
122141 bad_count_file += 1
123142 if brackets_list .count ('(' ) != brackets_list .count (')' ):
124- print ( " ERROR: A possible missing round bracket ( or ) in file {0} ( = {1} ) = {2}" . format ( filepath , brackets_list .count ('(' ), brackets_list .count (')' )) )
143+ logger . log ( logger . LogLevel . ERROR , f" A possible missing square bracket ( or ) in file { filepath } [ = { brackets_list .count ('(' )} ] = { brackets_list .count (')' )} " )
125144 bad_count_file += 1
126145 if brackets_list .count ('{' ) != brackets_list .count ('}' ):
127- print ( "ERROR: A possible missing curly brace {{ or }} in file {0} {{ = {1} }} = {2}" .format (filepath ,brackets_list .count ('{' ),brackets_list .count ('}' )))
146+ logger . log ( " A possible missing curly brace {{ or }} in file {0} {{ = {1} }} = {2}" .format (filepath ,brackets_list .count ('{' ),brackets_list .count ('}' )))
128147 bad_count_file += 1
129148
130149 file .seek (0 )
131150 for lineNumber , line in enumerate (file .readlines ()):
132151 if reIsClass .match (line ):
133152 if reBadColon .match (line ):
134- print (f"WARNING: bad class colon { filepath } Line number: { lineNumber + 1 } " )
135- # bad_count_file += 1
153+ logger .log (
154+ logger .LogLevel .WARN , f"Bad class colon { filepath } Line number: { lineNumber + 1 } " )
155+
156+ bad_count_file += 1
136157 if reIsClassInherit .match (line ):
137158 if not reSpaceAfterColon .match (line ):
138- print (f"WARNING: bad class missing space after colon { filepath } Line number: { lineNumber + 1 } " )
159+ logger .log (
160+ logger .LogLevel .WARN , f"Bad class missing space after colon { filepath } Line number: { lineNumber + 1 } " )
139161 if reIsClassBody .match (line ):
140162 if not reSpaceBeforeCurly .match (line ):
141- print (f"WARNING: bad class inherit missing space before curly braces { filepath } Line number: { lineNumber + 1 } " )
163+ logger .log (
164+ logger .LogLevel .WARN , f"Bad class inherit missing space before curly braces { filepath } Line number: { lineNumber + 1 } " )
142165 if not reClassSingleLine .match (line ):
143- print (f"WARNING: bad class braces placement { filepath } Line number: { lineNumber + 1 } " )
144- # bad_count_file += 1
166+ logger .log (
167+ logger .LogLevel .WARN , f"Bad class braces placement { filepath } Line number: { lineNumber + 1 } " )
168+ bad_count_file += 1
145169
146170 return bad_count_file
147171
148- def main ():
149172
150- print ("Validating Config Style" )
173+ def main ():
174+ logger .log (logger .LogLevel .INFO , "Validating config style" )
151175
152176 sqf_list = []
153177 bad_count = 0
154178
155- parser = argparse .ArgumentParser ()
156- parser .add_argument ('-m' ,'--module' , help = 'only search specified module addon folder' , required = False , default = "" )
157- args = parser .parse_args ()
158-
159179 for folder in ['addons' , 'optionals' ]:
160180 # Allow running from root directory as well as from inside the tools directory
161181 rootDir = "../" + folder
162182 if (os .path .exists (folder )):
163183 rootDir = folder
164184
165- for root , dirnames , filenames in os .walk (rootDir + '/' + args . module ):
166- for filename in fnmatch .filter (filenames , '*.cpp' ):
167- sqf_list .append (os .path .join (root , filename ))
168- for filename in fnmatch .filter (filenames , '*.hpp' ):
169- sqf_list .append (os .path .join (root , filename ))
170- for filename in fnmatch .filter (filenames , '*.rvmat' ):
171- sqf_list .append (os .path .join (root , filename ))
172- for filename in fnmatch .filter (filenames , '*.cfg' ):
173- sqf_list .append (os .path .join (root , filename ))
185+ for root , dirnames , filenames in os .walk (rootDir ):
186+ for filename in fnmatch .filter (filenames , '*.cpp' ):
187+ sqf_list .append (os .path .join (root , filename ))
188+ for filename in fnmatch .filter (filenames , '*.hpp' ):
189+ sqf_list .append (os .path .join (root , filename ))
190+ for filename in fnmatch .filter (filenames , '*.rvmat' ):
191+ sqf_list .append (os .path .join (root , filename ))
192+ for filename in fnmatch .filter (filenames , '*.cfg' ):
193+ sqf_list .append (os .path .join (root , filename ))
174194
175195 for filename in sqf_list :
176196 bad_count = bad_count + check_config_style (filename )
177197
178- print ("------\n Checked {0} files\n Errors detected: {1}" .format (len (sqf_list ), bad_count ))
198+ logger .log (logger .LogLevel .INFO ,
199+ f"Checked { len (sqf_list )} files, errors detected: { bad_count } " )
179200 if (bad_count == 0 ):
180- print ( "Config validation PASSED" )
201+ logger . log ( logger . LogLevel . INFO , "Config validation PASSED" )
181202 else :
182- print ( "Config validation FAILED" )
203+ logger . log ( logger . LogLevel . ERROR , "Config validation FAILED" )
183204
184205 return bad_count
185206
207+
186208if __name__ == "__main__" :
187209 sys .exit (main ())
0 commit comments