@@ -139,7 +139,7 @@ label.checkBtn > input {
139139
140140table.summaryTable td { padding: 0 5px 0 5px; }
141141
142- .statHeader, .severityHeader {
142+ .statHeader, .severityHeader, .classificationHeader {
143143 font-weight: bold;
144144}
145145
@@ -201,7 +201,7 @@ table.summaryTable td { padding: 0 5px 0 5px; }
201201 padding-right: 6px;
202202}
203203
204- .id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered {
204+ .id-filtered, .severity-filtered, .classification-filtered, . file-filtered, .tool-filtered, .text-filtered {
205205 visibility: collapse;
206206}
207207"""
@@ -278,7 +278,18 @@ HTML_HEAD = """
278278
279279 updateFileRows();
280280 }
281+
282+ function toggleClassification(cb) {
283+ cb.parentElement.classList.toggle("unchecked", !cb.checked);
284+ var elements = document.querySelectorAll(".class_" + cb.id);
285+
286+ for (var i = 0, len = elements.length; i < len; i++) {
287+ elements[i].classList.toggle("classification-filtered", !cb.checked);
288+ }
281289
290+ updateFileRows();
291+ }
292+
282293 function toggleTool(cb) {
283294 cb.parentElement.classList.toggle("unchecked", !cb.checked);
284295
@@ -340,7 +351,7 @@ HTML_HEAD = """
340351 var elements = document.querySelectorAll(".fileEntry");
341352
342353 for (var i = 0, len = elements.length; i < len; i++) {
343- var visible = elements[i].querySelector(".issue:not(.id-filtered):not(.severity-filtered):not(.tool-filtered):not(.text-filtered)");
354+ var visible = elements[i].querySelector(".issue:not(.id-filtered):not(.severity-filtered):not(.classification-filtered):not(. tool-filtered):not(.text-filtered)");
344355 elements[i].classList.toggle("file-filtered", !visible);
345356 }
346357 }
@@ -399,20 +410,27 @@ def html_escape(text):
399410
400411def filter_button (enabled_filters , id , function ):
401412 enabled = enabled_filters .get (id , False )
413+ if not id :
414+ id = 'None'
402415 return '\n <label class="checkBtn%s"><input type="checkbox" onclick="%s(this)" id="%s"%s/>%s</label>' \
403416 % (' disabled' if not enabled else '' , function , id , 'checked' if enabled else 'disabled' , id )
404417
405418def filter_bar (enabled ):
419+ severity_bar = '' .join ([filter_button (enabled , severity , 'toggleSeverity' ) for severity in ['error' , 'warning' , 'portability' , 'performance' , 'style' , 'information' ]]) + '\n | '
420+ classification_bar = '' .join ([filter_button (enabled , _class , 'toggleClassification' ) for _class in ['Mandatory' , 'Required' , 'Advisory' , 'Document' , 'Disapplied' , 'L1' ,'L2' ,'L3' ,'' ]]) + '\n | '
421+ if "checked/>" not in severity_bar :
422+ severity_bar = ''
423+ if "checked/>" not in classification_bar :
424+ classification_bar = ''
406425 return '' .join ([
407426 ' <div id="filters">\n '
408- ,'' . join ([ filter_button ( enabled , severity , 'toggleSeverity' ) for severity in [ 'error' , 'warning' , 'portability' , 'performance' , 'style' , 'information' ]])
409- ,' \n | '
427+ ,severity_bar
428+ , classification_bar
410429 ,'' .join ([filter_button (enabled , tool , 'toggleTool' ) for tool in ['cppcheck' , 'clang-tidy' ]])
411430 ,'\n | '
412431 ,'\n <label class="severityHeader">File: <input type="search" oninput="filterFile(this.value)"/></label>'
413432 ,'\n <label class="severityHeader">Filter: <input type="search" oninput="filterText(this.value)"/></label>'
414433 ,'\n </div>\n ' ])
415-
416434def git_blame (errors , path , file , blame_options ):
417435 last_line = errors [- 1 ]['line' ]
418436 if last_line == 0 :
@@ -471,14 +489,20 @@ def blame_lookup(blame_data, line):
471489 return next ((data for start , end , data in blame_data if line >= start and line < end ), {})
472490
473491
474- def tr_str (td_th , line , id , cwe , severity , message , timestamp , author , author_mail , date , add_author , tr_class = None , htmlfile = None , message_class = None ):
492+ def tr_str (td_th , line , id , cwe , severity , classification , guideline , message , timestamp , author , author_mail , date , add_author , tr_class = None , htmlfile = None , message_class = None ):
475493 ret = ''
494+ items = [id , cwe ]
495+ if severity :
496+ items .append (severity )
497+ if classification :
498+ items .extend ([classification , guideline ])
476499 if htmlfile :
477500 ret += '<%s><a href="%s#line-%d">%d</a></%s>' % (td_th , htmlfile , line , line , td_th )
478- for item in ( id , cwe , severity ) :
501+ for item in items :
479502 ret += '<%s>%s</%s>' % (td_th , item , td_th )
480503 else :
481- for item in (line , id , cwe , severity ):
504+ items .insert (0 ,line )
505+ for item in items :
482506 ret += '<%s>%s</%s>' % (td_th , item , td_th )
483507 if message_class :
484508 message_attribute = ' class="%s"' % message_class
@@ -561,6 +585,7 @@ class CppCheckHandler(XmlContentHandler):
561585 self .version = '1'
562586 self .versionCppcheck = ''
563587 self .timestamp = ''
588+ self .report_type = False
564589
565590 def startElement (self , name , attributes ):
566591 if name == 'results' :
@@ -574,7 +599,10 @@ class CppCheckHandler(XmlContentHandler):
574599 def handleVersion1 (self , name , attributes ):
575600 if name != 'error' :
576601 return
577-
602+ att_class = attributes .get ('classification' , '' )
603+ att_guide = attributes .get ('guideline' , '' )
604+ if att_class and not self .report_type :
605+ self .report_type = True
578606 self .errors .append ({
579607 'file' : attributes .get ('file' , '' ),
580608 'line' : int (attributes .get ('line' , 0 )),
@@ -584,6 +612,8 @@ class CppCheckHandler(XmlContentHandler):
584612 }],
585613 'id' : attributes ['id' ],
586614 'severity' : attributes ['severity' ],
615+ 'classification' : att_class ,
616+ 'guideline' : att_guide ,
587617 'timestamp' : self .timestamp ,
588618 'msg' : attributes ['msg' ]
589619 })
@@ -592,12 +622,18 @@ class CppCheckHandler(XmlContentHandler):
592622 if name == 'cppcheck' :
593623 self .versionCppcheck = attributes ['version' ]
594624 if name == 'error' :
625+ att_class = attributes .get ('classification' , '' )
626+ att_guide = attributes .get ('guideline' , '' )
627+ if att_class and not self .report_type :
628+ self .report_type = True
595629 error = {
596630 'locations' : [],
597631 'file' : '' ,
598632 'line' : 0 ,
599633 'id' : attributes ['id' ],
634+ 'classification' : att_class ,
600635 'severity' : attributes ['severity' ],
636+ 'guideline' : att_guide ,
601637 'timestamp' : self .timestamp ,
602638 'msg' : attributes ['msg' ],
603639 'verbose' : attributes .get ('verbose' )
@@ -623,7 +659,6 @@ class CppCheckHandler(XmlContentHandler):
623659 'line' : line ,
624660 'info' : attributes .get ('info' )
625661 })
626-
627662def main () -> None :
628663 # Configure all the options this little utility is using.
629664 parser = argparse .ArgumentParser ()
@@ -751,6 +786,8 @@ def main() -> None:
751786 if location .get ('info' ):
752787 newError ['msg' ] = location ['info' ]
753788 newError ['severity' ] = 'information'
789+ newError ['classification' ] = ''
790+ newError ['guideline' ] = ''
754791 del newError ['verbose' ]
755792
756793 errors .append (newError )
@@ -832,7 +869,12 @@ def main() -> None:
832869 for filename , data in sorted (files .items ()):
833870 for error in data ['errors' ]:
834871 stats .append (error ['id' ]) # get the stats
835- filter_enabled [error ['severity' ]] = True
872+ if contentHandler .report_type :
873+ filter_enabled [error ['severity' ]] = False
874+ filter_enabled [error ['classification' ]] = True
875+ else :
876+ filter_enabled [error ['severity' ]] = True
877+ filter_enabled [error ['classification' ]] = False
836878 filter_enabled ['clang-tidy' if error ['id' ].startswith ('clang-tidy-' ) else 'cppcheck' ] = True
837879 stats_count += 1
838880
@@ -877,9 +919,15 @@ def main() -> None:
877919 output_file .write (HTML_MENU_END .replace ("content" , "content_index" , 1 ))
878920
879921 output_file .write ('\n <table class=\" summaryTable\" >' )
880- output_file .write (
881- '\n %s' %
882- tr_str ('th' , 'Line' , 'Id' , 'CWE' , 'Severity' , 'Message' , 'Timestamp' , 'Author' , 'Author mail' , 'Date (DD/MM/YYYY)' , add_author = add_author_information ))
922+ if contentHandler .report_type :
923+ output_file .write (
924+ '\n %s' %
925+ tr_str ('th' , 'Line' , 'Id' , 'CWE' , '' , 'Classification' , 'Guideline' , 'Message' , 'Timestamp' ,
926+ 'Author' , 'Author mail' , 'Date (DD/MM/YYYY)' , add_author = add_author_information ))
927+ else :
928+ output_file .write (
929+ '\n %s' %
930+ tr_str ('th' , 'Line' , 'Id' , 'CWE' , 'Severity' , '' , '' , 'Message' , 'Timestamp' , 'Author' , 'Author mail' , 'Date (DD/MM/YYYY)' , add_author = add_author_information ))
883931
884932 for filename , data in sorted (files .items ()):
885933 file_error = filename in decode_errors or filename .endswith ('*' )
@@ -916,13 +964,20 @@ def main() -> None:
916964 message_class = error ['severity' ]
917965
918966 line = error ["line" ] if is_file else ""
919-
967+ _severity = error .get ('severity' , '' )
968+ _classification = error .get ('classification' , '' )
969+ _guideline = error .get ('guideline' , '' )
970+ if contentHandler .report_type :
971+ _severity = ''
972+ if not _classification :
973+ _classification = 'None'
974+ _guideline = 'None'
920975 output_file .write (
921976 '\n %s' %
922- tr_str ('td' , line , error ["id" ], cwe_url , error [ "severity" ] , error ["msg" ], error ["timestamp" ],
977+ tr_str ('td' , line , error ["id" ], cwe_url , _severity , _classification , _guideline , error ["msg" ], error ["timestamp" ],
923978 git_blame_dict .get ('author' , 'Unknown' ), git_blame_dict .get ('author-mail' , '---' ),
924979 git_blame_dict .get ('author-time' , '---' ),
925- tr_class = to_css_selector (error ["id" ]) + ' sev_' + error [ "severity" ] + ' issue' ,
980+ tr_class = to_css_selector (error ["id" ]) + ' sev_' + _severity + ' class_' + _classification + ' issue' ,
926981 message_class = message_class ,
927982 add_author = add_author_information ,
928983 htmlfile = htmlfile ))
0 commit comments