@@ -46,99 +46,110 @@ def checkDictionaries(name):
4646
4747 return missingDict
4848
49- #Setup the options
50- from argparse import ArgumentParser , ArgumentDefaultsHelpFormatter
51- oparser = ArgumentParser (formatter_class = ArgumentDefaultsHelpFormatter )
52- oparser .add_argument ("-d" ,"--check_dictionaries" , dest = "checkdict" ,action = "store_true" ,default = False ,
53- help = "check that all required dictionaries are loaded" )
54- oparser .add_argument ("-l" ,"--lib" , dest = "library" , type = str ,
55- help = "specify the library to load. If not set classes are found using the PluginManager" )
56- oparser .add_argument ("-x" ,"--xml_file" , dest = "xmlfile" ,default = "./classes_def.xml" , type = str ,
57- help = "the classes_def.xml file to read" )
58- oparser .add_argument ("-g" ,"--generate_new" ,dest = "generate" , action = "store_true" ,default = False ,
59- help = "instead of issuing errors, generate a new classes_def.xml file." )
60-
61- options = oparser .parse_args ()
62-
63- ClassesDefUtils .initROOT (options .library )
64- if options .library is None and options .checkdict :
65- print ("Dictionary checks require a specific library" )
66-
67- missingDict = 0
68-
69- ClassesDefUtils .initCheckClass ()
70-
71- try :
72- p = ClassesDefUtils .XmlParser (options .xmlfile )
73- except RuntimeError as e :
74- print (f"Parsing { options .xmlfile } failed: { e } " )
75- sys .exit (1 )
76- foundErrors = dict ()
77- for name ,info in p .classes .items ():
78- errorCode ,rootClassVersion ,classChecksum = ClassesDefUtils .checkClass (name ,info [ClassesDefUtils .XmlParser .classVersionIndex ],info [ClassesDefUtils .XmlParser .versionsToChecksumIndex ])
79- if errorCode != ClassesDefUtils .noError :
80- foundErrors [name ]= (errorCode ,classChecksum ,rootClassVersion )
81- if options .checkdict :
82- missingDict += checkDictionaries (name )
83-
84- foundRootDoesNotMatchError = False
85- originalToNormalizedNames = dict ()
86- for name ,retValues in foundErrors .items ():
87- origName = p .classes [name ][ClassesDefUtils .XmlParser .originalNameIndex ]
88- originalToNormalizedNames [origName ]= name
89- code = retValues [0 ]
90- classVersion = p .classes [name ][ClassesDefUtils .XmlParser .classVersionIndex ]
91- classChecksum = retValues [1 ]
92- rootClassVersion = retValues [2 ]
93- if code == ClassesDefUtils .errorRootDoesNotMatchClassDef :
94- foundRootDoesNotMatchError = True
95- print ("error: for class '" + name + "' ROOT says the ClassVersion is " + str (rootClassVersion )+ " but classes_def.xml says it is " + str (classVersion )+ ". Are you sure everything compiled correctly?" )
96- elif code == ClassesDefUtils .errorMustUpdateClassVersion and not options .generate :
97- print ("error: class '" + name + "' has a different checksum for ClassVersion " + str (classVersion )+ ". Increment ClassVersion to " + str (classVersion + 1 )+ " and assign it to checksum " + str (classChecksum ))
98- elif not options .generate :
99- print ("error:class '" + name + "' needs to include the following as part of its 'class' declaration" )
100- print (' <version ClassVersion="' + str (classVersion )+ '" checksum="' + str (classChecksum )+ '"/>' )
101-
102-
103- if options .generate and not foundRootDoesNotMatchError and not missingDict :
104- f = open (options .xmlfile )
105- outFile = open ('classes_def.xml.generated' ,'w' )
106- out = ''
107- for l in f .readlines ():
108- newLine = l
109- if - 1 != l .find ('<class' ) and - 1 != l .find ('ClassVersion' ):
110- splitArgs = l .split ('"' )
111- name = splitArgs [1 ]
112- normName = originalToNormalizedNames .get (name ,None )
113- if normName is not None :
114- indent = l .find ('<' )
115- #this is a class with a problem
116- classVersion = p .classes [normName ][XmlParser .classVersionIndex ]
117- code ,checksum ,rootClassVersion = foundErrors [normName ]
118- hasNoSubElements = (- 1 != l .find ('/>' ))
119- if code == ClassesDefUtils .errorMustUpdateClassVersion :
120- classVersion += 1
121- parts = splitArgs [:]
122- indexToClassVersion = 0
123- for pt in parts :
124- indexToClassVersion += 1
125- if - 1 != pt .find ('ClassVersion' ):
126- break
127- parts [indexToClassVersion ]= str (classVersion )
128- newLine = '"' .join (parts )
129-
130- if hasNoSubElements :
131- newLine = newLine .replace ('/' ,'' )
132- out += newLine
133- newLine = ' ' * indent + ' <version ClassVersion="' + str (classVersion )+ '" checksum="' + str (checksum )+ '"/>\n '
134- if hasNoSubElements :
135- out += newLine
136- newLine = ' ' * indent + '</class>\n '
137- out += newLine
138-
139- outFile .writelines (out )
140-
141- if (len (foundErrors )> 0 and not options .generate ) or (options .generate and foundRootDoesNotMatchError ) or missingDict :
142- import sys
143- sys .exit (1 )
49+ def checkClassDefinitions (classes , checkdict ):
50+ missingDict = 0
51+ foundErrors = dict ()
52+ for name ,info in classes .items ():
53+ errorCode ,rootClassVersion ,classChecksum = ClassesDefUtils .checkClass (name ,info [ClassesDefUtils .XmlParser .classVersionIndex ],info [ClassesDefUtils .XmlParser .versionsToChecksumIndex ])
54+ if errorCode != ClassesDefUtils .noError :
55+ foundErrors [name ]= (errorCode ,classChecksum ,rootClassVersion )
56+ if checkdict :
57+ missingDict += checkDictionaries (name )
58+ return (missingDict , foundErrors )
59+
60+ def checkErrors (foundErrors , classes , generate ):
61+ foundRootDoesNotMatchError = False
62+ originalToNormalizedNames = dict ()
63+ for name ,retValues in foundErrors .items ():
64+ origName = classes [name ][ClassesDefUtils .XmlParser .originalNameIndex ]
65+ originalToNormalizedNames [origName ]= name
66+ code = retValues [0 ]
67+ classVersion = classes [name ][ClassesDefUtils .XmlParser .classVersionIndex ]
68+ classChecksum = retValues [1 ]
69+ rootClassVersion = retValues [2 ]
70+ if code == ClassesDefUtils .errorRootDoesNotMatchClassDef :
71+ foundRootDoesNotMatchError = True
72+ print ("error: for class '" + name + "' ROOT says the ClassVersion is " + str (rootClassVersion )+ " but classes_def.xml says it is " + str (classVersion )+ ". Are you sure everything compiled correctly?" )
73+ elif code == ClassesDefUtils .errorMustUpdateClassVersion and not generate :
74+ print ("error: class '" + name + "' has a different checksum for ClassVersion " + str (classVersion )+ ". Increment ClassVersion to " + str (classVersion + 1 )+ " and assign it to checksum " + str (classChecksum ))
75+ elif not generate :
76+ print ("error:class '" + name + "' needs to include the following as part of its 'class' declaration" )
77+ print (' <version ClassVersion="' + str (classVersion )+ '" checksum="' + str (classChecksum )+ '"/>' )
78+ return (foundRootDoesNotMatchError , originalToNormalizedNames )
79+
80+
81+ def generate (oldfile , newfile , originalToNormalizedNames , classes , foundErrors ):
82+ with open (oldfile ) as f , open (newfile , 'w' ) as outFile :
83+ out = ''
84+ for l in f .readlines ():
85+ newLine = l
86+ if - 1 != l .find ('<class' ) and - 1 != l .find ('ClassVersion' ):
87+ splitArgs = l .split ('"' )
88+ name = splitArgs [1 ]
89+ normName = originalToNormalizedNames .get (name ,None )
90+ if normName is not None :
91+ indent = l .find ('<' )
92+ #this is a class with a problem
93+ classVersion = classes [normName ][ClassesDefUtils .XmlParser .classVersionIndex ]
94+ code ,checksum ,rootClassVersion = foundErrors [normName ]
95+ hasNoSubElements = (- 1 != l .find ('/>' ))
96+ if code == ClassesDefUtils .errorMustUpdateClassVersion :
97+ classVersion += 1
98+ parts = splitArgs [:]
99+ indexToClassVersion = 0
100+ for pt in parts :
101+ indexToClassVersion += 1
102+ if - 1 != pt .find ('ClassVersion' ):
103+ break
104+ parts [indexToClassVersion ]= str (classVersion )
105+ newLine = '"' .join (parts )
106+
107+ if hasNoSubElements :
108+ newLine = newLine .replace ('/' ,'' )
109+ out += newLine
110+ newLine = ' ' * indent + ' <version ClassVersion="' + str (classVersion )+ '" checksum="' + str (checksum )+ '"/>\n '
111+ if hasNoSubElements :
112+ out += newLine
113+ newLine = ' ' * indent + '</class>\n '
114+ out += newLine
115+
116+ outFile .writelines (out )
117+
118+ def main (args ):
119+ ClassesDefUtils .initROOT (args .library )
120+ if args .library is None and args .checkdict :
121+ print ("Dictionary checks require a specific library" )
122+ ClassesDefUtils .initCheckClass ()
123+
124+ try :
125+ p = ClassesDefUtils .XmlParser (args .xmlfile )
126+ except RuntimeError as e :
127+ print (f"Parsing { args .xmlfile } failed: { e } " )
128+ return (1 )
129+
130+ (missingDict , foundErrors ) = checkClassDefinitions (p .classes , args .checkdict )
131+ (foundRootDoesNotMatchError , originalToNormalizedNames ) = checkErrors (foundErrors , p .classes , args .generate )
132+
133+ if (len (foundErrors )> 0 and not args .generate ) or (args .generate and foundRootDoesNotMatchError ) or missingDict :
134+ return 1
135+
136+ if args .generate :
137+ generate (args .xmlfile , 'classes_def.xml.generated' , originalToNormalizedNames , p .classes , foundErrors )
138+
139+ return 0
140+
141+ if __name__ == "__main__" :
142+ from argparse import ArgumentParser , ArgumentDefaultsHelpFormatter
143+ parser = ArgumentParser (formatter_class = ArgumentDefaultsHelpFormatter )
144+ parser .add_argument ("-d" ,"--check_dictionaries" , dest = "checkdict" ,action = "store_true" ,default = False ,
145+ help = "check that all required dictionaries are loaded" )
146+ parser .add_argument ("-l" ,"--lib" , dest = "library" , type = str ,
147+ help = "specify the library to load. If not set classes are found using the PluginManager" )
148+ parser .add_argument ("-x" ,"--xml_file" , dest = "xmlfile" ,default = "./classes_def.xml" , type = str ,
149+ help = "the classes_def.xml file to read" )
150+ parser .add_argument ("-g" ,"--generate_new" ,dest = "generate" , action = "store_true" ,default = False ,
151+ help = "instead of issuing errors, generate a new classes_def.xml file." )
152+
153+ args = parser .parse_args ()
154+ sys .exit (main (args ))
144155
0 commit comments